From 36f093a10da09496c3ef5a706cd494a4e2a9b9bd Mon Sep 17 00:00:00 2001 From: protolambda Date: Wed, 28 Aug 2024 10:14:11 -0600 Subject: [PATCH 001/264] op-chain-ops/script: cleanup and improve console logging (#11629) --- op-chain-ops/script/cheatcodes_environment.go | 5 - op-chain-ops/script/console.go | 235 +++++- op-chain-ops/script/console2_gen.go | 750 +++++++++--------- op-chain-ops/script/console_test.go | 28 +- op-chain-ops/script/consolegen/main.go | 1 - op-chain-ops/script/prank.go | 11 +- op-chain-ops/script/script_test.go | 4 +- 7 files changed, 640 insertions(+), 394 deletions(-) diff --git a/op-chain-ops/script/cheatcodes_environment.go b/op-chain-ops/script/cheatcodes_environment.go index 2299a3e1a05b..92baa429010e 100644 --- a/op-chain-ops/script/cheatcodes_environment.go +++ b/op-chain-ops/script/cheatcodes_environment.go @@ -183,31 +183,26 @@ func (c *CheatCodesPrecompile) Coinbase(addr common.Address) { // Broadcast_afc98040 implements https://book.getfoundry.sh/cheatcodes/broadcast func (c *CheatCodesPrecompile) Broadcast_afc98040() error { - c.h.log.Info("broadcasting next call") return c.h.Prank(nil, nil, false, true) } // Broadcast_e6962cdb implements https://book.getfoundry.sh/cheatcodes/broadcast func (c *CheatCodesPrecompile) Broadcast_e6962cdb(who common.Address) error { - c.h.log.Info("broadcasting next call", "who", who) return c.h.Prank(&who, nil, false, true) } // StartBroadcast_7fb5297f implements https://book.getfoundry.sh/cheatcodes/start-broadcast func (c *CheatCodesPrecompile) StartBroadcast_7fb5297f() error { - c.h.log.Info("starting repeat-broadcast") return c.h.Prank(nil, nil, true, true) } // StartBroadcast_7fec2a8d implements https://book.getfoundry.sh/cheatcodes/start-broadcast func (c *CheatCodesPrecompile) StartBroadcast_7fec2a8d(who common.Address) error { - c.h.log.Info("starting repeat-broadcast", "who", who) return c.h.Prank(&who, nil, true, true) } // StopBroadcast implements https://book.getfoundry.sh/cheatcodes/stop-broadcast func (c *CheatCodesPrecompile) StopBroadcast() error { - c.h.log.Info("stopping repeat-broadcast") return c.h.StopPrank(true) } diff --git a/op-chain-ops/script/console.go b/op-chain-ops/script/console.go index c9283b464ba5..b3bba1ed0ff2 100644 --- a/op-chain-ops/script/console.go +++ b/op-chain-ops/script/console.go @@ -1,20 +1,247 @@ package script import ( + "bytes" + "fmt" + "math/big" + "reflect" + "strconv" + "strings" + "text/scanner" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/log" ) +//go:generate go run ./consolegen --abi-txt=console2.txt --out=console2_gen.go + type ConsolePrecompile struct { logger log.Logger sender func() common.Address } -func (c *ConsolePrecompile) log(ctx ...any) { +func (c *ConsolePrecompile) log(args ...any) { sender := c.sender() + logger := c.logger.With("sender", sender) + if len(args) == 0 { + logger.Info("") + return + } + if msg, ok := args[0].(string); ok { // if starting with a string, use it as message. And format with args if needed. + logger.Info(consoleFormat(msg, args[1:]...)) + return + } else { + logger.Info(consoleFormat("", args...)) + } +} - // Log the sender, since the self-address is always equal to the ConsoleAddr - c.logger.With("sender", sender).Info("console", ctx...) +type stringFormat struct{} +type numberFormat struct{} +type objectFormat struct{} +type integerFormat struct{} +type exponentialFormat struct { + precision int } +type hexadecimalFormat struct{} -//go:generate go run ./consolegen --abi-txt=console2.txt --out=console2_gen.go +func formatBigInt(x *big.Int, precision int) string { + if precision < 0 { + precision = len(new(big.Int).Abs(x).String()) - 1 + return formatBigIntFixedPrecision(x, uint(precision)) + fmt.Sprintf("e%d", precision) + } + return formatBigIntFixedPrecision(x, uint(precision)) +} + +func formatBigIntFixedPrecision(x *big.Int, precision uint) string { + prec := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(precision)), nil) + integer, remainder := new(big.Int).QuoRem(x, prec, new(big.Int)) + if remainder.Sign() != 0 { + decimal := fmt.Sprintf("%0"+fmt.Sprintf("%d", precision)+"d", + new(big.Int).Abs(remainder)) + decimal = strings.TrimRight(decimal, "0") + return fmt.Sprintf("%d.%s", integer, decimal) + } else { + return fmt.Sprintf("%d", integer) + } +} + +// formatValue formats a value v following the given format-spec. +func formatValue(v any, spec any) string { + switch x := v.(type) { + case string: + switch spec.(type) { + case stringFormat: + return x + case objectFormat: + return fmt.Sprintf("'%s'", v) + default: + return "NaN" + } + case bool: + switch spec.(type) { + case stringFormat: + return fmt.Sprintf("%v", x) + case objectFormat: + return fmt.Sprintf("'%v'", x) + case numberFormat: + if x { + return "1" + } + return "0" + default: + return "NaN" + } + case *big.Int: + switch s := spec.(type) { + case stringFormat, objectFormat, numberFormat, integerFormat: + return fmt.Sprintf("%d", x) + case exponentialFormat: + return formatBigInt(x, s.precision) + case hexadecimalFormat: + return (*hexutil.Big)(x).String() + default: + return fmt.Sprintf("%d", x) + } + case *ABIInt256: + switch s := spec.(type) { + case stringFormat, objectFormat, numberFormat, integerFormat: + return fmt.Sprintf("%d", (*big.Int)(x)) + case exponentialFormat: + return formatBigInt((*big.Int)(x), s.precision) + case hexadecimalFormat: + return (*hexutil.Big)(x).String() + default: + return fmt.Sprintf("%d", (*big.Int)(x)) + } + case common.Address: + switch spec.(type) { + case stringFormat, hexadecimalFormat: + return x.String() + case objectFormat: + return fmt.Sprintf("'%s'", x) + default: + return "NaN" + } + default: + if typ := reflect.TypeOf(v); (typ.Kind() == reflect.Array || typ.Kind() == reflect.Slice) && + typ.Elem().Kind() == reflect.Uint8 { + switch spec.(type) { + case stringFormat, hexadecimalFormat: + return fmt.Sprintf("0x%x", v) + case objectFormat: + return fmt.Sprintf("'0x%x'", v) + default: + return "NaN" + } + } + return fmt.Sprintf("%v", v) + } +} + +// consoleFormat emulates the foundry-flavor of printf, to format console.log data. +func consoleFormat(fmtMsg string, values ...any) string { + var sc scanner.Scanner + sc.Init(bytes.NewReader([]byte(fmtMsg))) + // default scanner settings are for Go source code parsing. Reset all of that. + sc.Whitespace = 0 + sc.Mode = 0 + sc.IsIdentRune = func(ch rune, i int) bool { + return false + } + + nextValue := func() (v any, ok bool) { + if len(values) > 0 { + v = values[0] + values = values[1:] + return v, true + } + return nil, false + } + + // Parses a format-spec from a string sequence (excl. the % prefix) + // Returns the spec (if any), and the consumed characters (to abort with / fall back to) + formatSpecFromChars := func() (spec any, consumed string) { + fmtChar := sc.Scan() + switch fmtChar { + case 's': + return stringFormat{}, "s" + case 'd': + return numberFormat{}, "d" + case 'i': + return integerFormat{}, "i" + case 'o': + return objectFormat{}, "o" + case 'e': + return exponentialFormat{precision: -1}, "e" + case 'x': + return hexadecimalFormat{}, "x" + case scanner.EOF: + return nil, "" + default: + for ; fmtChar != scanner.EOF; fmtChar = sc.Scan() { + if fmtChar == 'e' { + precision, err := strconv.ParseUint(consumed, 10, 16) + consumed += "e" + if err != nil { + return nil, consumed + } + return exponentialFormat{precision: int(precision)}, consumed + } + consumed += string(fmtChar) + if !strings.ContainsRune("0123456789", fmtChar) { + return nil, consumed + } + } + return nil, consumed + } + } + + expectFmt := false + var out strings.Builder + for sc.Peek() != scanner.EOF { + if expectFmt { + expectFmt = false + spec, consumed := formatSpecFromChars() + if spec != nil { + value, ok := nextValue() + if ok { + out.WriteString(formatValue(value, spec)) + } else { + // rather than panic with an .expect() like foundry, + // just log the original format string + out.WriteRune('%') + out.WriteString(consumed) + } + } else { + // on parser failure, write '%' and consumed characters + out.WriteRune('%') + out.WriteString(consumed) + } + } else { + tok := sc.Scan() + if tok == '%' { + next := sc.Peek() + switch next { + case '%': // %% formats as "%" + out.WriteRune('%') + case scanner.EOF: + out.WriteRune(tok) + default: + expectFmt = true + } + } else { + out.WriteRune(tok) + } + } + } + + // for all remaining values, append them to the output + for _, v := range values { + if out.Len() > 0 { + out.WriteRune(' ') + } + out.WriteString(formatValue(v, stringFormat{})) + } + return out.String() +} diff --git a/op-chain-ops/script/console2_gen.go b/op-chain-ops/script/console2_gen.go index 9430a9441cce..f8b8aecf7497 100644 --- a/op-chain-ops/script/console2_gen.go +++ b/op-chain-ops/script/console2_gen.go @@ -13,1502 +13,1502 @@ func (c *ConsolePrecompile) Log_51973ec9() { } func (c *ConsolePrecompile) Log_665bf134(p0 common.Address, p1 common.Address, p2 common.Address, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_0e378994(p0 common.Address, p1 common.Address, p2 common.Address, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_018c84c2(p0 common.Address, p1 common.Address, p2 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_f808da20(p0 common.Address, p1 common.Address, p2 common.Address, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_94250d77(p0 common.Address, p1 common.Address, p2 common.Address, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_9f1bc36e(p0 common.Address, p1 common.Address, p2 bool, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_2cd4134a(p0 common.Address, p1 common.Address, p2 bool, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_f2a66286(p0 common.Address, p1 common.Address, p2 bool) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_aa6540c8(p0 common.Address, p1 common.Address, p2 bool, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_3971e78c(p0 common.Address, p1 common.Address, p2 bool, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_daf0d4aa(p0 common.Address, p1 common.Address) { - c.log("p0", p0, "p1", p1) + c.log(p0, p1) } func (c *ConsolePrecompile) Log_8f736d16(p0 common.Address, p1 common.Address, p2 string, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_6f1a594e(p0 common.Address, p1 common.Address, p2 string, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_007150be(p0 common.Address, p1 common.Address, p2 string) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_21bdaf25(p0 common.Address, p1 common.Address, p2 string, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_ef1cefe7(p0 common.Address, p1 common.Address, p2 string, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_8da6def5(p0 common.Address, p1 common.Address, p2 *big.Int, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_9b4254e2(p0 common.Address, p1 common.Address, p2 *big.Int, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_17fe6185(p0 common.Address, p1 common.Address, p2 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_fdb4f990(p0 common.Address, p1 common.Address, p2 *big.Int, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_be553481(p0 common.Address, p1 common.Address, p2 *big.Int, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_660375dd(p0 common.Address, p1 bool, p2 common.Address, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_a6f50b0f(p0 common.Address, p1 bool, p2 common.Address, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_f11699ed(p0 common.Address, p1 bool, p2 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_2dd778e6(p0 common.Address, p1 bool, p2 common.Address, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_a75c59de(p0 common.Address, p1 bool, p2 common.Address, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_cf394485(p0 common.Address, p1 bool, p2 bool, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_cac43479(p0 common.Address, p1 bool, p2 bool, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_eb830c92(p0 common.Address, p1 bool, p2 bool) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_dfc4a2e8(p0 common.Address, p1 bool, p2 bool, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_8c4e5de6(p0 common.Address, p1 bool, p2 bool, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_75b605d3(p0 common.Address, p1 bool) { - c.log("p0", p0, "p1", p1) + c.log(p0, p1) } func (c *ConsolePrecompile) Log_19fd4956(p0 common.Address, p1 bool, p2 string, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_50ad461d(p0 common.Address, p1 bool, p2 string, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_212255cc(p0 common.Address, p1 bool, p2 string) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_475c5c33(p0 common.Address, p1 bool, p2 string, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_80e6a20b(p0 common.Address, p1 bool, p2 string, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_ccf790a1(p0 common.Address, p1 bool, p2 *big.Int, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_c4643e20(p0 common.Address, p1 bool, p2 *big.Int, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_9c4f99fb(p0 common.Address, p1 bool, p2 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_0aa6cfad(p0 common.Address, p1 bool, p2 *big.Int, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_386ff5f4(p0 common.Address, p1 bool, p2 *big.Int, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_2c2ecbc2(p0 common.Address) { - c.log("p0", p0) + c.log(p0) } func (c *ConsolePrecompile) Log_0d36fa20(p0 common.Address, p1 string, p2 common.Address, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_0df12b76(p0 common.Address, p1 string, p2 common.Address, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_f08744e8(p0 common.Address, p1 string, p2 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_f7e36245(p0 common.Address, p1 string, p2 common.Address, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_457fe3cf(p0 common.Address, p1 string, p2 common.Address, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_205871c2(p0 common.Address, p1 string, p2 bool, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_5f1d5c9f(p0 common.Address, p1 string, p2 bool, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_cf020fb1(p0 common.Address, p1 string, p2 bool) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_bc0b61fe(p0 common.Address, p1 string, p2 bool, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_515e38b6(p0 common.Address, p1 string, p2 bool, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_759f86bb(p0 common.Address, p1 string) { - c.log("p0", p0, "p1", p1) + c.log(p0, p1) } func (c *ConsolePrecompile) Log_a04e2f87(p0 common.Address, p1 string, p2 string, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_35a5071f(p0 common.Address, p1 string, p2 string, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_fb772265(p0 common.Address, p1 string, p2 string) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_5d02c50b(p0 common.Address, p1 string, p2 string, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_159f8927(p0 common.Address, p1 string, p2 string, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_63183678(p0 common.Address, p1 string, p2 *big.Int, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_0ef7e050(p0 common.Address, p1 string, p2 *big.Int, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_67dd6ff1(p0 common.Address, p1 string, p2 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_448830a8(p0 common.Address, p1 string, p2 *big.Int, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_1dc8e1b8(p0 common.Address, p1 string, p2 *big.Int, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_478d1c62(p0 common.Address, p1 *big.Int, p2 common.Address, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_a1bcc9b3(p0 common.Address, p1 *big.Int, p2 common.Address, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_7bc0d848(p0 common.Address, p1 *big.Int, p2 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_1da986ea(p0 common.Address, p1 *big.Int, p2 common.Address, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_100f650e(p0 common.Address, p1 *big.Int, p2 common.Address, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_a31bfdcc(p0 common.Address, p1 *big.Int, p2 bool, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_3bf5e537(p0 common.Address, p1 *big.Int, p2 bool, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_678209a8(p0 common.Address, p1 *big.Int, p2 bool) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_c5ad85f9(p0 common.Address, p1 *big.Int, p2 bool, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_22f6b999(p0 common.Address, p1 *big.Int, p2 bool, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_8309e8a8(p0 common.Address, p1 *big.Int) { - c.log("p0", p0, "p1", p1) + c.log(p0, p1) } func (c *ConsolePrecompile) Log_5c430d47(p0 common.Address, p1 *big.Int, p2 string, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_cf18105c(p0 common.Address, p1 *big.Int, p2 string, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_a1f2e8aa(p0 common.Address, p1 *big.Int, p2 string) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_88a8c406(p0 common.Address, p1 *big.Int, p2 string, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_bf01f891(p0 common.Address, p1 *big.Int, p2 string, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_20e3984d(p0 common.Address, p1 *big.Int, p2 *big.Int, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_66f1bc67(p0 common.Address, p1 *big.Int, p2 *big.Int, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_b69bcaf6(p0 common.Address, p1 *big.Int, p2 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_4a28c017(p0 common.Address, p1 *big.Int, p2 *big.Int, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_34f0e636(p0 common.Address, p1 *big.Int, p2 *big.Int, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_1d14d001(p0 bool, p1 common.Address, p2 common.Address, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_46600be0(p0 bool, p1 common.Address, p2 common.Address, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_d2763667(p0 bool, p1 common.Address, p2 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_d812a167(p0 bool, p1 common.Address, p2 common.Address, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_0c66d1be(p0 bool, p1 common.Address, p2 common.Address, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_1c41a336(p0 bool, p1 common.Address, p2 bool, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_6a9c478b(p0 bool, p1 common.Address, p2 bool, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_18c9c746(p0 bool, p1 common.Address, p2 bool) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_4a66cb34(p0 bool, p1 common.Address, p2 bool, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_07831502(p0 bool, p1 common.Address, p2 bool, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_853c4849(p0 bool, p1 common.Address) { - c.log("p0", p0, "p1", p1) + c.log(p0, p1) } func (c *ConsolePrecompile) Log_6f7c603e(p0 bool, p1 common.Address, p2 string, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_e2bfd60b(p0 bool, p1 common.Address, p2 string, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_de9a9270(p0 bool, p1 common.Address, p2 string) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_a73c1db6(p0 bool, p1 common.Address, p2 string, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_c21f64c7(p0 bool, p1 common.Address, p2 string, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_136b05dd(p0 bool, p1 common.Address, p2 *big.Int, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_d6019f1c(p0 bool, p1 common.Address, p2 *big.Int, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_5f7b9afb(p0 bool, p1 common.Address, p2 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_51f09ff8(p0 bool, p1 common.Address, p2 *big.Int, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_7bf181a1(p0 bool, p1 common.Address, p2 *big.Int, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_f4880ea4(p0 bool, p1 bool, p2 common.Address, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_c0a302d8(p0 bool, p1 bool, p2 common.Address, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_1078f68d(p0 bool, p1 bool, p2 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_a0a47963(p0 bool, p1 bool, p2 common.Address, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_4c123d57(p0 bool, p1 bool, p2 common.Address, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_8c329b1a(p0 bool, p1 bool, p2 bool, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_3b2a5ce0(p0 bool, p1 bool, p2 bool, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_50709698(p0 bool, p1 bool, p2 bool) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_2ae408d4(p0 bool, p1 bool, p2 bool, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_6d7045c1(p0 bool, p1 bool, p2 bool, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_2a110e83(p0 bool, p1 bool) { - c.log("p0", p0, "p1", p1) + c.log(p0, p1) } func (c *ConsolePrecompile) Log_f9ad2b89(p0 bool, p1 bool, p2 string, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_b857163a(p0 bool, p1 bool, p2 string, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_2555fa46(p0 bool, p1 bool, p2 string) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_6d1e8751(p0 bool, p1 bool, p2 string, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_e3a9ca2f(p0 bool, p1 bool, p2 string, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_54a7a9a0(p0 bool, p1 bool, p2 *big.Int, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_619e4d0e(p0 bool, p1 bool, p2 *big.Int, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_12f21602(p0 bool, p1 bool, p2 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_7dd4d0e0(p0 bool, p1 bool, p2 *big.Int, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_0bb00eab(p0 bool, p1 bool, p2 *big.Int, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_32458eed(p0 bool) { - c.log("p0", p0) + c.log(p0) } func (c *ConsolePrecompile) Log_2b2b18dc(p0 bool, p1 string, p2 common.Address, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_6dd434ca(p0 bool, p1 string, p2 common.Address, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_9591b953(p0 bool, p1 string, p2 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_12d6c788(p0 bool, p1 string, p2 common.Address, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_a5cada94(p0 bool, p1 string, p2 common.Address, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_538e06ab(p0 bool, p1 string, p2 bool, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_dc5e935b(p0 bool, p1 string, p2 bool, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_dbb4c247(p0 bool, p1 string, p2 bool) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_483d0416(p0 bool, p1 string, p2 bool, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_1606a393(p0 bool, p1 string, p2 bool, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_8feac525(p0 bool, p1 string) { - c.log("p0", p0, "p1", p1) + c.log(p0, p1) } func (c *ConsolePrecompile) Log_97d394d8(p0 bool, p1 string, p2 string, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_1e4b87e5(p0 bool, p1 string, p2 string, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_b076847f(p0 bool, p1 string, p2 string) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_1762e32a(p0 bool, p1 string, p2 string, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_7be0c3eb(p0 bool, p1 string, p2 string, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_1596a1ce(p0 bool, p1 string, p2 *big.Int, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_6b0e5d53(p0 bool, p1 string, p2 *big.Int, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_1093ee11(p0 bool, p1 string, p2 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_1ad96de6(p0 bool, p1 string, p2 *big.Int, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_28863fcb(p0 bool, p1 string, p2 *big.Int, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_26f560a8(p0 bool, p1 *big.Int, p2 common.Address, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_b4c314ff(p0 bool, p1 *big.Int, p2 common.Address, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_088ef9d2(p0 bool, p1 *big.Int, p2 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_1bb3b09a(p0 bool, p1 *big.Int, p2 common.Address, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_1537dc87(p0 bool, p1 *big.Int, p2 common.Address, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_9acd3616(p0 bool, p1 *big.Int, p2 bool, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_ceb5f4d7(p0 bool, p1 *big.Int, p2 bool, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_e8defba9(p0 bool, p1 *big.Int, p2 bool) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_9143dbb1(p0 bool, p1 *big.Int, p2 bool, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_7f9bbca2(p0 bool, p1 *big.Int, p2 bool, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_399174d3(p0 bool, p1 *big.Int) { - c.log("p0", p0, "p1", p1) + c.log(p0, p1) } func (c *ConsolePrecompile) Log_fedd1fff(p0 bool, p1 *big.Int, p2 string, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_e5e70b2b(p0 bool, p1 *big.Int, p2 string, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_c3fc3970(p0 bool, p1 *big.Int, p2 string) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_f5bc2249(p0 bool, p1 *big.Int, p2 string, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_6a1199e2(p0 bool, p1 *big.Int, p2 string, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_00dd87b9(p0 bool, p1 *big.Int, p2 *big.Int, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_be984353(p0 bool, p1 *big.Int, p2 *big.Int, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_37103367(p0 bool, p1 *big.Int, p2 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_8e69fb5d(p0 bool, p1 *big.Int, p2 *big.Int, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_374bb4b2(p0 bool, p1 *big.Int, p2 *big.Int, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_013d178b(p0 [10]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_04004a2e(p0 [11]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_86a06abd(p0 [12]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_94529e34(p0 [13]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_9266f07f(p0 [14]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_da9574e0(p0 [15]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_665c6104(p0 [16]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_339f673a(p0 [17]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_c4d23d9a(p0 [18]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_5e6b5a33(p0 [19]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_6e18a128(p0 [1]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_5188e3e9(p0 [20]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_e9da3560(p0 [21]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_d5fae89c(p0 [22]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_aba1cf0d(p0 [23]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_f1b35b34(p0 [24]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_0b84bc58(p0 [25]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_f8b149f1(p0 [26]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_3a3757dd(p0 [27]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_c82aeaee(p0 [28]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_4b69c3d5(p0 [29]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_e9b62296(p0 [2]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_ee12c4ed(p0 [30]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_c2854d92(p0 [31]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_27b7cf85(p0 [32]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_2d834926(p0 [3]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_e05f48d1(p0 [4]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_a684808d(p0 [5]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_ae84a591(p0 [6]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_4ed57e28(p0 [7]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_4f84252e(p0 [8]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_90bd8cd0(p0 [9]byte) { - c.log("p0", hexutil.Bytes(p0[:])) + c.log(hexutil.Bytes(p0[:])) } func (c *ConsolePrecompile) Log_0be77f56(p0 hexutil.Bytes) { - c.log("p0", p0) + c.log(p0) } func (c *ConsolePrecompile) Log_2d5b6cb9(p0 *ABIInt256) { - c.log("p0", (*big.Int)(p0)) + c.log((*big.Int)(p0)) } func (c *ConsolePrecompile) Log_ed8f28f6(p0 string, p1 common.Address, p2 common.Address, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_b59dbd60(p0 string, p1 common.Address, p2 common.Address, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_fcec75e0(p0 string, p1 common.Address, p2 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_800a1c67(p0 string, p1 common.Address, p2 common.Address, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_8ef3f399(p0 string, p1 common.Address, p2 common.Address, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_223603bd(p0 string, p1 common.Address, p2 bool, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_79884c2b(p0 string, p1 common.Address, p2 bool, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_c91d5ed4(p0 string, p1 common.Address, p2 bool) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_0454c079(p0 string, p1 common.Address, p2 bool, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_3e9f866a(p0 string, p1 common.Address, p2 bool, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_319af333(p0 string, p1 common.Address) { - c.log("p0", p0, "p1", p1) + c.log(p0, p1) } func (c *ConsolePrecompile) Log_aabc9a31(p0 string, p1 common.Address, p2 string, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_5f15d28c(p0 string, p1 common.Address, p2 string, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_e0e9ad4f(p0 string, p1 common.Address, p2 string) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_245986f2(p0 string, p1 common.Address, p2 string, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_91d1112e(p0 string, p1 common.Address, p2 string, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_63fb8bc5(p0 string, p1 common.Address, p2 *big.Int, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_fc4845f0(p0 string, p1 common.Address, p2 *big.Int, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_0d26b925(p0 string, p1 common.Address, p2 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_5a477632(p0 string, p1 common.Address, p2 *big.Int, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_f8f51b1e(p0 string, p1 common.Address, p2 *big.Int, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_33e9dd1d(p0 string, p1 bool, p2 common.Address, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_958c28c6(p0 string, p1 bool, p2 common.Address, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_932bbb38(p0 string, p1 bool, p2 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_2d8e33a4(p0 string, p1 bool, p2 common.Address, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_5d08bb05(p0 string, p1 bool, p2 common.Address, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_7190a529(p0 string, p1 bool, p2 bool, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_895af8c5(p0 string, p1 bool, p2 bool, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_850b7ad6(p0 string, p1 bool, p2 bool) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_9d22d5dd(p0 string, p1 bool, p2 bool, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_8e3f78a9(p0 string, p1 bool, p2 bool, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_c3b55635(p0 string, p1 bool) { - c.log("p0", p0, "p1", p1) + c.log(p0, p1) } func (c *ConsolePrecompile) Log_e0625b29(p0 string, p1 bool, p2 string, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_3f8a701d(p0 string, p1 bool, p2 string, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_e298f47d(p0 string, p1 bool, p2 string) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_a826caeb(p0 string, p1 bool, p2 string, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_24f91465(p0 string, p1 bool, p2 string, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_935e09bf(p0 string, p1 bool, p2 *big.Int, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_8af7cf8a(p0 string, p1 bool, p2 *big.Int, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_c95958d6(p0 string, p1 bool, p2 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_742d6ee7(p0 string, p1 bool, p2 *big.Int, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_64b5bb67(p0 string, p1 bool, p2 *big.Int, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_3ca6268e(p0 string, p1 *ABIInt256) { - c.log("p0", p0, "p1", (*big.Int)(p1)) + c.log(p0, (*big.Int)(p1)) } func (c *ConsolePrecompile) Log_41304fac(p0 string) { - c.log("p0", p0) + c.log(p0) } func (c *ConsolePrecompile) Log_439c7bef(p0 string, p1 string, p2 common.Address, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_5ccd4e37(p0 string, p1 string, p2 common.Address, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_95ed0195(p0 string, p1 string, p2 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_eb1bff80(p0 string, p1 string, p2 common.Address, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_7cc3c607(p0 string, p1 string, p2 common.Address, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_c371c7db(p0 string, p1 string, p2 bool, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_40785869(p0 string, p1 string, p2 bool, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_b0e0f9b5(p0 string, p1 string, p2 bool) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_5e84b0ea(p0 string, p1 string, p2 bool, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_d6aefad2(p0 string, p1 string, p2 bool, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_4b5c4277(p0 string, p1 string) { - c.log("p0", p0, "p1", p1) + c.log(p0, p1) } func (c *ConsolePrecompile) Log_6d572f44(p0 string, p1 string, p2 string, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_2c1754ed(p0 string, p1 string, p2 string, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_2ced7cef(p0 string, p1 string, p2 string) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_de68f20a(p0 string, p1 string, p2 string, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_8eafb02b(p0 string, p1 string, p2 string, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_1023f7b2(p0 string, p1 string, p2 *big.Int, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_c3a8a654(p0 string, p1 string, p2 *big.Int, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_5821efa1(p0 string, p1 string, p2 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_5d1a971a(p0 string, p1 string, p2 *big.Int, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_f45d7d2c(p0 string, p1 string, p2 *big.Int, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_5ea2b7ae(p0 string, p1 *big.Int, p2 common.Address, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_82112a42(p0 string, p1 *big.Int, p2 common.Address, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_1c7ec448(p0 string, p1 *big.Int, p2 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_9ffb2f93(p0 string, p1 *big.Int, p2 common.Address, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_4f04fdc6(p0 string, p1 *big.Int, p2 common.Address, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_e0e95b98(p0 string, p1 *big.Int, p2 bool, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_354c36d6(p0 string, p1 *big.Int, p2 bool, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_ca7733b1(p0 string, p1 *big.Int, p2 bool) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_abf73a98(p0 string, p1 *big.Int, p2 bool, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_e41b6f6f(p0 string, p1 *big.Int, p2 bool, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_b60e72cc(p0 string, p1 *big.Int) { - c.log("p0", p0, "p1", p1) + c.log(p0, p1) } func (c *ConsolePrecompile) Log_7c4632a4(p0 string, p1 *big.Int, p2 string, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_7d24491d(p0 string, p1 *big.Int, p2 string, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_5970e089(p0 string, p1 *big.Int, p2 string) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_5ab84e1f(p0 string, p1 *big.Int, p2 string, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_c67ea9d1(p0 string, p1 *big.Int, p2 string, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_e21de278(p0 string, p1 *big.Int, p2 *big.Int, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_7626db92(p0 string, p1 *big.Int, p2 *big.Int, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_ca47c4eb(p0 string, p1 *big.Int, p2 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_854b3496(p0 string, p1 *big.Int, p2 *big.Int, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_a7a87853(p0 string, p1 *big.Int, p2 *big.Int, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_2488b414(p0 *big.Int, p1 common.Address, p2 common.Address, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_091ffaf5(p0 *big.Int, p1 common.Address, p2 common.Address, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_bcfd9be0(p0 *big.Int, p1 common.Address, p2 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_031c6f73(p0 *big.Int, p1 common.Address, p2 common.Address, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_736efbb6(p0 *big.Int, p1 common.Address, p2 common.Address, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_ef72c513(p0 *big.Int, p1 common.Address, p2 bool, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_e351140f(p0 *big.Int, p1 common.Address, p2 bool, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_9b6ec042(p0 *big.Int, p1 common.Address, p2 bool) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_90fb06aa(p0 *big.Int, p1 common.Address, p2 bool, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_5abd992a(p0 *big.Int, p1 common.Address, p2 bool, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_69276c86(p0 *big.Int, p1 common.Address) { - c.log("p0", p0, "p1", p1) + c.log(p0, p1) } func (c *ConsolePrecompile) Log_9cba8fff(p0 *big.Int, p1 common.Address, p2 string, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_cc32ab07(p0 *big.Int, p1 common.Address, p2 string, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_63cb41f9(p0 *big.Int, p1 common.Address, p2 string) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_3e128ca3(p0 *big.Int, p1 common.Address, p2 string, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_46826b5d(p0 *big.Int, p1 common.Address, p2 string, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_15c127b5(p0 *big.Int, p1 common.Address, p2 *big.Int, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_5f743a7c(p0 *big.Int, p1 common.Address, p2 *big.Int, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_5a9b5ed5(p0 *big.Int, p1 common.Address, p2 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_ddb06521(p0 *big.Int, p1 common.Address, p2 *big.Int, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_0c9cd9c1(p0 *big.Int, p1 common.Address, p2 *big.Int, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_a1ef4cbb(p0 *big.Int, p1 bool, p2 common.Address, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_454d54a5(p0 *big.Int, p1 bool, p2 common.Address, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_35085f7b(p0 *big.Int, p1 bool, p2 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_ade052c7(p0 *big.Int, p1 bool, p2 common.Address, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_078287f5(p0 *big.Int, p1 bool, p2 common.Address, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_69640b59(p0 *big.Int, p1 bool, p2 bool, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_b6f577a1(p0 *big.Int, p1 bool, p2 bool, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_20718650(p0 *big.Int, p1 bool, p2 bool) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_dddb9561(p0 *big.Int, p1 bool, p2 bool, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_7464ce23(p0 *big.Int, p1 bool, p2 bool, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_1c9d7eb3(p0 *big.Int, p1 bool) { - c.log("p0", p0, "p1", p1) + c.log(p0, p1) } func (c *ConsolePrecompile) Log_ef529018(p0 *big.Int, p1 bool, p2 string, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_eb928d7f(p0 *big.Int, p1 bool, p2 string, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_85775021(p0 *big.Int, p1 bool, p2 string) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_68c8b8bd(p0 *big.Int, p1 bool, p2 string, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_2c1d0746(p0 *big.Int, p1 bool, p2 string, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_88cb6041(p0 *big.Int, p1 bool, p2 *big.Int, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_91a02e2a(p0 *big.Int, p1 bool, p2 *big.Int, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_20098014(p0 *big.Int, p1 bool, p2 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_de03e774(p0 *big.Int, p1 bool, p2 *big.Int, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_c6acc7a8(p0 *big.Int, p1 bool, p2 *big.Int, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_f82c50f1(p0 *big.Int) { - c.log("p0", p0) + c.log(p0) } func (c *ConsolePrecompile) Log_6168ed61(p0 *big.Int, p1 string, p2 common.Address, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_90c30a56(p0 *big.Int, p1 string, p2 common.Address, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_7afac959(p0 *big.Int, p1 string, p2 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_9c3adfa1(p0 *big.Int, p1 string, p2 common.Address, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_e8d3018d(p0 *big.Int, p1 string, p2 common.Address, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_ae2ec581(p0 *big.Int, p1 string, p2 bool, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_ba535d9c(p0 *big.Int, p1 string, p2 bool, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_4ceda75a(p0 *big.Int, p1 string, p2 bool) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_d2d423cd(p0 *big.Int, p1 string, p2 bool, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_cf009880(p0 *big.Int, p1 string, p2 bool, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_643fd0df(p0 *big.Int, p1 string) { - c.log("p0", p0, "p1", p1) + c.log(p0, p1) } func (c *ConsolePrecompile) Log_d583c602(p0 *big.Int, p1 string, p2 string, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_b3a6b6bd(p0 *big.Int, p1 string, p2 string, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_b115611f(p0 *big.Int, p1 string, p2 string) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_21ad0683(p0 *big.Int, p1 string, p2 string, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_b028c9bd(p0 *big.Int, p1 string, p2 string, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_3b2279b4(p0 *big.Int, p1 string, p2 *big.Int, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_691a8f74(p0 *big.Int, p1 string, p2 *big.Int, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_37aa7d4c(p0 *big.Int, p1 string, p2 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_b7b914ca(p0 *big.Int, p1 string, p2 *big.Int, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_82c25b74(p0 *big.Int, p1 string, p2 *big.Int, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_56a5d1b1(p0 *big.Int, p1 *big.Int, p2 common.Address, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_15cac476(p0 *big.Int, p1 *big.Int, p2 common.Address, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_5c96b331(p0 *big.Int, p1 *big.Int, p2 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_6cde40b8(p0 *big.Int, p1 *big.Int, p2 common.Address, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_88f6e4b2(p0 *big.Int, p1 *big.Int, p2 common.Address, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_9a816a83(p0 *big.Int, p1 *big.Int, p2 bool, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_ab085ae6(p0 *big.Int, p1 *big.Int, p2 bool, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_4766da72(p0 *big.Int, p1 *big.Int, p2 bool) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_a5b4fc99(p0 *big.Int, p1 *big.Int, p2 bool, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_eb7f6fd2(p0 *big.Int, p1 *big.Int, p2 bool, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_f666715a(p0 *big.Int, p1 *big.Int) { - c.log("p0", p0, "p1", p1) + c.log(p0, p1) } func (c *ConsolePrecompile) Log_42d21db7(p0 *big.Int, p1 *big.Int, p2 string, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_7af6ab25(p0 *big.Int, p1 *big.Int, p2 string, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_71d04af2(p0 *big.Int, p1 *big.Int, p2 string) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_27d8afd2(p0 *big.Int, p1 *big.Int, p2 string, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_5da297eb(p0 *big.Int, p1 *big.Int, p2 string, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_fa8185af(p0 *big.Int, p1 *big.Int, p2 *big.Int, p3 common.Address) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_c598d185(p0 *big.Int, p1 *big.Int, p2 *big.Int, p3 bool) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_d1ed7a3c(p0 *big.Int, p1 *big.Int, p2 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2) + c.log(p0, p1, p2) } func (c *ConsolePrecompile) Log_59cfcbe3(p0 *big.Int, p1 *big.Int, p2 *big.Int, p3 string) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } func (c *ConsolePrecompile) Log_193fb800(p0 *big.Int, p1 *big.Int, p2 *big.Int, p3 *big.Int) { - c.log("p0", p0, "p1", p1, "p2", p2, "p3", p3) + c.log(p0, p1, p2, p3) } diff --git a/op-chain-ops/script/console_test.go b/op-chain-ops/script/console_test.go index bfce8e6148d4..d67f5efc0f5f 100644 --- a/op-chain-ops/script/console_test.go +++ b/op-chain-ops/script/console_test.go @@ -1,15 +1,16 @@ package script import ( + "fmt" "log/slog" + "math/big" "math/rand" // nosemgrep "testing" - "github.com/stretchr/testify/require" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testutils" @@ -50,8 +51,25 @@ func TestConsole(t *testing.T) { }) } - require.NotNil(t, captLog.FindLog(testlog.NewMessageFilter("console"))) - require.NotNil(t, captLog.FindLog(testlog.NewAttributesFilter("p0", alice.String()))) - require.NotNil(t, captLog.FindLog(testlog.NewAttributesFilter("p1", bob.String()))) + require.NotNil(t, captLog.FindLog(testlog.NewMessageFilter(fmt.Sprintf("%s %s", alice, bob)))) require.NotNil(t, captLog.FindLog(testlog.NewAttributesFilter("sender", sender.String()))) } + +func TestFormatter(t *testing.T) { + got := consoleFormat("hello %d world %x example %3e", + big.NewInt(3), big.NewInt(0xc0ffee), big.NewInt(42), big.NewInt(123)) + require.Equal(t, "hello 3 world 0xc0ffee example 0.042 123", got) + require.Equal(t, "4.2", consoleFormat("%8e", big.NewInt(420000000))) + require.Equal(t, "foo true bar false", consoleFormat("foo %s bar %s", true, false)) + require.Equal(t, "foo 1 bar 0", consoleFormat("foo %d bar %d", true, false)) + require.Equal(t, "sender: "+DefaultSenderAddr.String(), + consoleFormat("sender: %s", DefaultSenderAddr)) + require.Equal(t, "long 0.000000000000000042 number", consoleFormat("long %18e number", big.NewInt(42))) + require.Equal(t, "long 4200.000000000000000003 number", consoleFormat("long %18e number", + new(big.Int).Add(new(big.Int).Mul( + big.NewInt(42), + new(big.Int).Exp(big.NewInt(10), big.NewInt(20), nil), + ), big.NewInt(3)))) + require.Equal(t, "1.23456e5", consoleFormat("%e", big.NewInt(123456))) + require.Equal(t, "-1.23456e5", consoleFormat("%e", (*ABIInt256)(big.NewInt(-123456)))) +} diff --git a/op-chain-ops/script/consolegen/main.go b/op-chain-ops/script/consolegen/main.go index bc20869eda13..9a3140d52f45 100644 --- a/op-chain-ops/script/consolegen/main.go +++ b/op-chain-ops/script/consolegen/main.go @@ -71,7 +71,6 @@ import ( if p == "" { continue } - out.WriteString(fmt.Sprintf(`"p%d", `, i)) out.WriteString(prettyArg(fmt.Sprintf("p%d", i), p)) if i != len(params)-1 { out.WriteString(", ") diff --git a/op-chain-ops/script/prank.go b/op-chain-ops/script/prank.go index e60548e0f41a..816c59033690 100644 --- a/op-chain-ops/script/prank.go +++ b/op-chain-ops/script/prank.go @@ -78,7 +78,11 @@ func (h *Host) Prank(msgSender *common.Address, txOrigin *common.Address, repeat return errors.New("you have an active prank; broadcasting and pranks are not compatible") } } - h.log.Warn("prank", "sender", msgSender) + if broadcast { + h.log.Debug("starting broadcast", "sender", msgSender, "repeat", repeat) + } else { + h.log.Debug("starting prank", "sender", msgSender, "repeat", repeat) + } cf.Prank = &Prank{ Sender: msgSender, Origin: txOrigin, @@ -108,6 +112,11 @@ func (h *Host) StopPrank(broadcast bool) error { if !cf.Prank.Broadcast && broadcast { return errors.New("no broadcast in progress to stop") } + if broadcast { + h.log.Debug("stopping broadcast") + } else { + h.log.Debug("stopping prank") + } cf.Prank = nil return nil } diff --git a/op-chain-ops/script/script_test.go b/op-chain-ops/script/script_test.go index 15e69933a3c8..c0c69a26fefc 100644 --- a/op-chain-ops/script/script_test.go +++ b/op-chain-ops/script/script_test.go @@ -29,9 +29,7 @@ func TestScript(t *testing.T) { input := bytes4("run()") returnData, _, err := h.Call(scriptContext.Sender, addr, input[:], DefaultFoundryGasLimit, uint256.NewInt(0)) require.NoError(t, err, "call failed: %x", string(returnData)) - require.NotNil(t, captLog.FindLog( - testlog.NewAttributesFilter("p0", "sender nonce"), - testlog.NewAttributesFilter("p1", "1"))) + require.NotNil(t, captLog.FindLog(testlog.NewMessageFilter("sender nonce 1"))) require.NoError(t, h.cheatcodes.Precompile.DumpState("noop")) // and a second time, to see if we can revisit the host state. From 0dcccf6aa828810b179e06dfff2e56df142ed7ed Mon Sep 17 00:00:00 2001 From: Inphi Date: Wed, 28 Aug 2024 22:26:43 -0400 Subject: [PATCH 002/264] cannon: Fix stack patching (#11632) * cannon: Fix stack patching And add `memprofilerate=0` to envp * Update cannon/mipsevm/program/patch.go Co-authored-by: protolambda * cleanup argv/envp string ptrs * nit * fix envar name * Update cannon/mipsevm/program/patch.go Co-authored-by: mbaxter * align op-program arg0 --------- Co-authored-by: protolambda Co-authored-by: mbaxter --- cannon/mipsevm/program/patch.go | 34 +++++++++++-------- cannon/mipsevm/tests/evm_common_test.go | 44 +++++++++++++++++++++++++ cannon/testdata/example/entry/go.mod | 3 ++ cannon/testdata/example/entry/main.go | 30 +++++++++++++++++ 4 files changed, 97 insertions(+), 14 deletions(-) create mode 100644 cannon/testdata/example/entry/go.mod create mode 100644 cannon/testdata/example/entry/main.go diff --git a/cannon/mipsevm/program/patch.go b/cannon/mipsevm/program/patch.go index 52a262fee585..46b75a69ff1c 100644 --- a/cannon/mipsevm/program/patch.go +++ b/cannon/mipsevm/program/patch.go @@ -47,16 +47,11 @@ func PatchGo(f *elf.File, st mipsevm.FPVMState) error { })); err != nil { return fmt.Errorf("failed to patch Go runtime.gcenable: %w", err) } - case "runtime.MemProfileRate": - if err := st.GetMemory().SetMemoryRange(uint32(s.Value), bytes.NewReader(make([]byte, 4))); err != nil { // disable mem profiling, to avoid a lot of unnecessary floating point ops - return err - } } } return nil } -// TODO(cp-903) Consider setting envar "GODEBUG=memprofilerate=0" for go programs to disable memprofiling, instead of patching it out in PatchGo() func PatchStack(st mipsevm.FPVMState) error { // setup stack pointer sp := uint32(0x7f_ff_d0_00) @@ -73,16 +68,27 @@ func PatchStack(st mipsevm.FPVMState) error { } // init argc, argv, aux on stack - storeMem(sp+4*1, 0x42) // argc = 0 (argument count) - storeMem(sp+4*2, 0x35) // argv[n] = 0 (terminating argv) - storeMem(sp+4*3, 0) // envp[term] = 0 (no env vars) - storeMem(sp+4*4, 6) // auxv[0] = _AT_PAGESZ = 6 (key) - storeMem(sp+4*5, 4096) // auxv[1] = page size of 4 KiB (value) - (== minPhysPageSize) - storeMem(sp+4*6, 25) // auxv[2] = AT_RANDOM - storeMem(sp+4*7, sp+4*9) // auxv[3] = address of 16 bytes containing random value - storeMem(sp+4*8, 0) // auxv[term] = 0 + storeMem(sp+4*0, 1) // argc = 1 (argument count) + storeMem(sp+4*1, sp+4*21) // argv[0] + storeMem(sp+4*2, 0) // argv[1] = terminating + storeMem(sp+4*3, sp+4*14) // envp[0] = x (offset to first env var) + storeMem(sp+4*4, 0) // envp[1] = terminating + storeMem(sp+4*5, 6) // auxv[0] = _AT_PAGESZ = 6 (key) + storeMem(sp+4*6, 4096) // auxv[1] = page size of 4 KiB (value) - (== minPhysPageSize) + storeMem(sp+4*7, 25) // auxv[2] = AT_RANDOM + storeMem(sp+4*8, sp+4*10) // auxv[3] = address of 16 bytes containing random value + storeMem(sp+4*9, 0) // auxv[term] = 0 + + _ = st.GetMemory().SetMemoryRange(sp+4*10, bytes.NewReader([]byte("4;byfairdiceroll"))) // 16 bytes of "randomness" + + // append 4 extra zero bytes to end at 4-byte alignment + envar := append([]byte("GODEBUG=memprofilerate=0"), 0x0, 0x0, 0x0, 0x0) + _ = st.GetMemory().SetMemoryRange(sp+4*14, bytes.NewReader(envar)) - _ = st.GetMemory().SetMemoryRange(sp+4*9, bytes.NewReader([]byte("4;byfairdiceroll"))) // 16 bytes of "randomness" + // 24 bytes for GODEBUG=memprofilerate=0 + 4 null bytes + // Then append program name + 2 null bytes for 4-byte alignment + programName := append([]byte("op-program"), 0x0, 0x0) + _ = st.GetMemory().SetMemoryRange(sp+4*21, bytes.NewReader(programName)) return nil } diff --git a/cannon/mipsevm/tests/evm_common_test.go b/cannon/mipsevm/tests/evm_common_test.go index 8294cb12c3df..445ed5031d2d 100644 --- a/cannon/mipsevm/tests/evm_common_test.go +++ b/cannon/mipsevm/tests/evm_common_test.go @@ -591,3 +591,47 @@ func TestClaimEVM(t *testing.T) { }) } } + +func TestEntryEVM(t *testing.T) { + var tracer *tracing.Hooks // no-tracer by default, but see test_util.MarkdownTracer + versions := GetMipsVersionTestCases(t) + + for _, v := range versions { + t.Run(v.Name, func(t *testing.T) { + evm := testutil.NewMIPSEVM(v.Contracts) + evm.SetTracer(tracer) + testutil.LogStepFailureAtCleanup(t, evm) + + var stdOutBuf, stdErrBuf bytes.Buffer + elfFile := "../../testdata/example/bin/entry.elf" + goVm := v.ElfVMFactory(t, elfFile, nil, io.MultiWriter(&stdOutBuf, os.Stdout), io.MultiWriter(&stdErrBuf, os.Stderr), testutil.CreateLogger()) + state := goVm.GetState() + + start := time.Now() + for i := 0; i < 400_000; i++ { + curStep := goVm.GetState().GetStep() + if goVm.GetState().GetExited() { + break + } + insn := state.GetMemory().GetMemory(state.GetPC()) + if i%10_000 == 0 { // avoid spamming test logs, we are executing many steps + t.Logf("step: %4d pc: 0x%08x insn: 0x%08x", state.GetStep(), state.GetPC(), insn) + } + + stepWitness, err := goVm.Step(true) + require.NoError(t, err) + evmPost := evm.Step(t, stepWitness, curStep, v.StateHashFn) + // verify the post-state matches. + goPost, _ := goVm.GetState().EncodeWitness() + require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), + "mipsevm produced different state than EVM") + } + end := time.Now() + delta := end.Sub(start) + t.Logf("test took %s, %d instructions, %s per instruction", delta, state.GetStep(), delta/time.Duration(state.GetStep())) + + require.True(t, state.GetExited(), "must complete program") + require.Equal(t, uint8(0), state.GetExitCode(), "exit with 0") + }) + } +} diff --git a/cannon/testdata/example/entry/go.mod b/cannon/testdata/example/entry/go.mod new file mode 100644 index 000000000000..2e4d29124f54 --- /dev/null +++ b/cannon/testdata/example/entry/go.mod @@ -0,0 +1,3 @@ +module entry + +go 1.21 diff --git a/cannon/testdata/example/entry/main.go b/cannon/testdata/example/entry/main.go new file mode 100644 index 000000000000..78866f88abeb --- /dev/null +++ b/cannon/testdata/example/entry/main.go @@ -0,0 +1,30 @@ +package main + +import ( + "os" + "runtime" +) + +func main() { + if len(os.Args) != 1 { + panic("expected 1 arg") + } + if os.Args[0] != "op-program" { + panic("unexpected arg0") + } + + var memProfileRate bool + env := os.Environ() + for _, env := range env { + if env != "GODEBUG=memprofilerate=0" { + panic("invalid envar") + } + memProfileRate = true + } + if !memProfileRate { + panic("memProfileRate env is not set") + } + if runtime.MemProfileRate != 0 { + panic("runtime.MemProfileRate is non-zero") + } +} From aebf669c108240298e14bd0e29068a18e0b0a52e Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Wed, 28 Aug 2024 23:41:10 -0600 Subject: [PATCH 003/264] Archive contract artifacts (#11626) To demonstrate how we can make our deployments more modular, this PR proposes archiving smart contract artifacts as tarballs that get uploaded to GCS. This allows deployment tools to use precompiled artifacts rather than generating them on-the fly. The archives are named after the hash of all Solidity files in the contracts-bedrock folder, including those in `lib/`, plus some additional metadata files like `foundry.toml` and `semver-lock.json`. See `calculate-checksum.sh` for details on how the algorithm works. I'm open to feedback around what should make up the checksum. Since the atifacts are content-addressable, this PR also updates the CI pipeline to download the artifacts from GCS prior to running `pnpm monorepo`. When the Solidity codebase doesn't change, this allows the `pnpm monorepo` job to skip compiling Solidity altogether. While this won't work as well when we're actively modifying the Solidity codebase, since the hash will change, it does provide a modest speedup in CI. --- .circleci/config.yml | 27 ++++++++++ .../scripts/ops/calculate-checksum.sh | 25 +++++++++ .../scripts/ops/publish-artifacts.sh | 54 +++++++++++++++++++ .../scripts/ops/pull-artifacts.sh | 41 ++++++++++++++ 4 files changed, 147 insertions(+) create mode 100644 packages/contracts-bedrock/scripts/ops/calculate-checksum.sh create mode 100644 packages/contracts-bedrock/scripts/ops/publish-artifacts.sh create mode 100644 packages/contracts-bedrock/scripts/ops/pull-artifacts.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 5917b7f91d01..82b3119acc8b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -194,6 +194,10 @@ jobs: - run: name: print forge version command: forge --version + - run: + name: Pull artifacts + command: bash scripts/ops/pull-artifacts.sh + working_directory: packages/contracts-bedrock - run: name: Build contracts environment: @@ -1461,6 +1465,24 @@ jobs: working_directory: ./packages/contracts-bedrock - notify-failures-on-develop + publish-contract-artifacts: + docker: + - image: <> + resource_class: medium + steps: + - gcp-cli/install + - gcp-oidc-authenticate: + gcp_cred_config_file_path: /root/gcp_cred_config.json + oidc_token_file_path: /root/oidc_token.json + service_account_email: GCP_SERVICE_CONTRACTS_ACCOUNT_EMAIL + - checkout + - attach_workspace: { at: "." } + - install-contracts-dependencies + - run: + name: Publish artifacts + command: bash scripts/ops/publish-artifacts.sh + working_directory: packages/contracts-bedrock + workflows: main: when: @@ -1475,6 +1497,11 @@ workflows: jobs: - pnpm-monorepo: name: pnpm-monorepo + - publish-contract-artifacts: + requires: + - pnpm-monorepo + context: + - oplabs-gcr-release - contracts-bedrock-tests - contracts-bedrock-coverage - contracts-bedrock-checks: diff --git a/packages/contracts-bedrock/scripts/ops/calculate-checksum.sh b/packages/contracts-bedrock/scripts/ops/calculate-checksum.sh new file mode 100644 index 000000000000..6278e37ffa74 --- /dev/null +++ b/packages/contracts-bedrock/scripts/ops/calculate-checksum.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +set -euo pipefail + +echoerr() { + echo "$@" 1>&2 +} + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +CONTRACTS_DIR="$SCRIPT_DIR/../.." + +cd "$CONTRACTS_DIR" + +echoerr "> Calculating contracts checksum..." + +find . -type f -name '*.sol' -exec sha256sum {} + > manifest.txt +sha256sum semver-lock.json >> manifest.txt +sha256sum foundry.toml >> manifest.txt +# need to specify the locale to ensure consistent sorting across platforms +LC_ALL=C sort -o manifest.txt manifest.txt +checksum=$(sha256sum manifest.txt | awk '{print $1}') +rm manifest.txt +echoerr "> Done." + +echo -n "$checksum" \ No newline at end of file diff --git a/packages/contracts-bedrock/scripts/ops/publish-artifacts.sh b/packages/contracts-bedrock/scripts/ops/publish-artifacts.sh new file mode 100644 index 000000000000..309b2d818eda --- /dev/null +++ b/packages/contracts-bedrock/scripts/ops/publish-artifacts.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +set -euo pipefail + +echoerr() { + echo "$@" 1>&2 +} + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +CONTRACTS_DIR="$SCRIPT_DIR/../.." +DEPLOY_BUCKET="oplabs-contract-artifacts" + +cd "$CONTRACTS_DIR" + +# ensure that artifacts exists and is non-empty +if [ ! -d "forge-artifacts" ] || [ -z "$(ls -A forge-artifacts)" ]; then + echoerr "> No forge-artifacts directory found." + exit 1 +fi + +if [ ! -d "artifacts" ] || [ -z "$(ls -A artifacts)" ]; then + echoerr "> No artifacts directory found." + exit 1 +fi + +checksum=$(bash scripts/ops/calculate-checksum.sh) + +echoerr "> Checking for existing artifacts..." +exists=$(curl -s -o /dev/null --fail -LI "https://storage.googleapis.com/$DEPLOY_BUCKET/artifacts-v1-$checksum.tar.gz" || echo "fail") + +if [ "$exists" != "fail" ]; then + echoerr "> Existing artifacts found, nothing to do." + exit 0 +fi + +echoerr "> Archiving artifacts..." +archive_name="artifacts-v1-$checksum.tar.gz" + +# use gtar on darwin +if [[ "$OSTYPE" == "darwin"* ]]; then + tar="gtar" +else + tar="tar" +fi + +"$tar" -czf "$archive_name" artifacts forge-artifacts cache +du -sh "$archive_name" | awk '{$1=$1};1' # trim leading whitespace +echoerr "> Done." + +echoerr "> Uploading artifacts to GCS..." +gcloud storage cp "$archive_name" "gs://$DEPLOY_BUCKET/$archive_name" +echoerr "> Done." + +rm "$archive_name" \ No newline at end of file diff --git a/packages/contracts-bedrock/scripts/ops/pull-artifacts.sh b/packages/contracts-bedrock/scripts/ops/pull-artifacts.sh new file mode 100644 index 000000000000..f119b087f38c --- /dev/null +++ b/packages/contracts-bedrock/scripts/ops/pull-artifacts.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +set -euo pipefail + +echoerr() { + echo "$@" 1>&2 +} + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +CONTRACTS_DIR="$SCRIPT_DIR/../.." + +cd "$CONTRACTS_DIR" + +checksum=$(bash scripts/ops/calculate-checksum.sh) +archive_name="artifacts-v1-$checksum.tar.gz" + +echoerr "> Checking for existing artifacts..." +exists=$(curl -s -o /dev/null --fail -LI "https://storage.googleapis.com/oplabs-contract-artifacts/$archive_name" || echo "fail") + +if [ "$exists" == "fail" ]; then + echoerr "> No existing artifacts found, exiting." + exit 0 +fi + +echoerr "> Cleaning up existing artifacts..." +rm -rf artifacts +rm -rf forge-artifacts +rm -rf cache +echoerr "> Done." + +echoerr "> Found existing artifacts. Downloading..." +curl -o "$archive_name" "https://storage.googleapis.com/oplabs-contract-artifacts/$archive_name" +echoerr "> Done." + +echoerr "> Extracting existing artifacts..." +tar -xzvf "$archive_name" +echoerr "> Done." + +echoerr "> Cleaning up." +rm "$archive_name" +echoerr "> Done." \ No newline at end of file From e53a86aca813aad18914a3fa4b3ad9c4f2599c3f Mon Sep 17 00:00:00 2001 From: mbaxter Date: Thu, 29 Aug 2024 10:25:42 -0400 Subject: [PATCH 004/264] cannon: Add MTCannon-specific differential tests (#11605) * cannon: Implement multithreaded clone fuzz test * cannon: Add more clone evm tests * cannon: Add evm test for GetTID syscall * cannon: Add evm test for SysExit * cannon: Add evm test for popping exited threads from the stack * cannon: Fix futex wait handling, add evm test * cannon: Add evm test for handling waiting thread * cannon: Add test utils for defining / validating MTState expectations * cannon: Add tests for futex wake, wake traversal * cannon: Add test for SysYield * cannon: Add SysOpen test, todos * cannon: Add test for SchedQuantum preemption, fix inconsistency * cannon: Add tests for noop, unsupported syscalls * cannon: Remove duplicate constants * cannon: Add tests for unsupported futex ops * cannon: Group traversal tests, fix TestEVM_WakeupTraversalStep * cannon: Add tests for nanosleep * cannon: Add additional testcase for wakeup traversal * cannon: Tweak futex wake tests * cannon: Update mt fuzz test to use new test utils * cannon: Rename contructor method for consistency * cannon: Add some simple tests for ExpectedMTState util * cannon: Add another validation test * cannon: Move syscall lists to tests where they're used * cannon: Add comment * cannon: Extract some evm test helpers * cannon: Cleanup - use require.Equalf for formatting * cannon: Rename test util to AssertEVMReverts * cannon: Add GetThreadStacks helper * cannon: Add a few more traversal tests --- cannon/mipsevm/exec/mips_syscalls.go | 2 +- cannon/mipsevm/multithreaded/mips.go | 8 +- cannon/mipsevm/multithreaded/state.go | 2 +- .../multithreaded/testutil/expectations.go | 203 ++++ .../testutil/expectations_test.go | 179 ++++ .../multithreaded/testutil/mutators.go | 87 ++ .../mipsevm/multithreaded/testutil/state.go | 73 +- .../mipsevm/multithreaded/testutil/thread.go | 166 ++++ .../mipsevm/singlethreaded/testutil/state.go | 24 +- cannon/mipsevm/tests/evm_common_test.go | 66 +- .../mipsevm/tests/evm_multithreaded_test.go | 906 +++++++++++++++++- cannon/mipsevm/tests/fuzz_evm_common_test.go | 73 +- .../tests/fuzz_evm_multithreaded_test.go | 59 +- .../tests/fuzz_evm_singlethreaded_test.go | 2 +- cannon/mipsevm/testutil/mips.go | 33 + cannon/mipsevm/testutil/rand.go | 53 + cannon/mipsevm/testutil/state.go | 68 +- packages/contracts-bedrock/semver-lock.json | 4 +- .../contracts-bedrock/src/cannon/MIPS2.sol | 14 +- .../src/cannon/libraries/MIPSSyscalls.sol | 5 +- .../contracts-bedrock/test/cannon/MIPS2.t.sol | 2 +- 21 files changed, 1748 insertions(+), 281 deletions(-) create mode 100644 cannon/mipsevm/multithreaded/testutil/expectations.go create mode 100644 cannon/mipsevm/multithreaded/testutil/expectations_test.go create mode 100644 cannon/mipsevm/multithreaded/testutil/mutators.go create mode 100644 cannon/mipsevm/multithreaded/testutil/thread.go create mode 100644 cannon/mipsevm/testutil/rand.go diff --git a/cannon/mipsevm/exec/mips_syscalls.go b/cannon/mipsevm/exec/mips_syscalls.go index af205ab5f46a..d2f49f279573 100644 --- a/cannon/mipsevm/exec/mips_syscalls.go +++ b/cannon/mipsevm/exec/mips_syscalls.go @@ -15,7 +15,6 @@ import ( // Syscall codes const ( SysMmap = 4090 - SysMunmap = 4091 SysBrk = 4045 SysClone = 4120 SysExitGroup = 4246 @@ -32,6 +31,7 @@ const ( // Noop Syscall codes const ( + SysMunmap = 4091 SysGetAffinity = 4240 SysMadvise = 4218 SysRtSigprocmask = 4195 diff --git a/cannon/mipsevm/multithreaded/mips.go b/cannon/mipsevm/multithreaded/mips.go index 7949bbe6c771..8f7b594fcab8 100644 --- a/cannon/mipsevm/multithreaded/mips.go +++ b/cannon/mipsevm/multithreaded/mips.go @@ -102,13 +102,13 @@ func (m *InstrumentedState) handleSyscall() error { // args: a0 = addr, a1 = op, a2 = val, a3 = timeout switch a1 { case exec.FutexWaitPrivate: - thread.FutexAddr = a0 m.memoryTracker.TrackMemAccess(a0) mem := m.state.Memory.GetMemory(a0) if mem != a2 { v0 = exec.SysErrorSignal v1 = exec.MipsEAGAIN } else { + thread.FutexAddr = a0 thread.FutexVal = a2 if a3 == 0 { thread.FutexTimeoutStep = exec.FutexNoTimeout @@ -242,11 +242,11 @@ func (m *InstrumentedState) mipsStep() error { if m.state.StepsSinceLastContextSwitch >= exec.SchedQuantum { // Force a context switch as this thread has been active too long - if m.state.threadCount() > 1 { + if m.state.ThreadCount() > 1 { // Log if we're hitting our context switch limit - only matters if we have > 1 thread if m.log.Enabled(context.Background(), log.LevelTrace) { msg := fmt.Sprintf("Thread has reached maximum execution steps (%v) - preempting.", exec.SchedQuantum) - m.log.Trace(msg, "threadId", thread.ThreadId, "threadCount", m.state.threadCount(), "pc", thread.Cpu.PC) + m.log.Trace(msg, "threadId", thread.ThreadId, "threadCount", m.state.ThreadCount(), "pc", thread.Cpu.PC) } } m.preemptThread(thread) @@ -339,5 +339,5 @@ func (m *InstrumentedState) popThread() { } func (m *InstrumentedState) lastThreadRemaining() bool { - return m.state.threadCount() == 1 + return m.state.ThreadCount() == 1 } diff --git a/cannon/mipsevm/multithreaded/state.go b/cannon/mipsevm/multithreaded/state.go index 6602357747bf..17d54c241a5e 100644 --- a/cannon/mipsevm/multithreaded/state.go +++ b/cannon/mipsevm/multithreaded/state.go @@ -215,7 +215,7 @@ func (s *State) EncodeThreadProof() []byte { return out } -func (s *State) threadCount() int { +func (s *State) ThreadCount() int { return len(s.LeftThreadStack) + len(s.RightThreadStack) } diff --git a/cannon/mipsevm/multithreaded/testutil/expectations.go b/cannon/mipsevm/multithreaded/testutil/expectations.go new file mode 100644 index 000000000000..f2e1bbb200f0 --- /dev/null +++ b/cannon/mipsevm/multithreaded/testutil/expectations.go @@ -0,0 +1,203 @@ +package testutil + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/stretchr/testify/require" + + "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" +) + +// ExpectedMTState is a test utility that basically stores a copy of a state that can be explicitly mutated +// to define an expected post-state. The post-state is then validated with ExpectedMTState.Validate(t, postState) +type ExpectedMTState struct { + PreimageKey common.Hash + PreimageOffset uint32 + Heap uint32 + ExitCode uint8 + Exited bool + Step uint64 + LastHint hexutil.Bytes + MemoryRoot common.Hash + // Threading-related expectations + StepsSinceLastContextSwitch uint64 + Wakeup uint32 + TraverseRight bool + NextThreadId uint32 + ThreadCount int + RightStackSize int + LeftStackSize int + prestateActiveThreadId uint32 + prestateActiveThreadOrig ExpectedThreadState // Cached for internal use + ActiveThreadId uint32 + threadExpectations map[uint32]*ExpectedThreadState +} + +type ExpectedThreadState struct { + ThreadId uint32 + ExitCode uint8 + Exited bool + FutexAddr uint32 + FutexVal uint32 + FutexTimeoutStep uint64 + PC uint32 + NextPC uint32 + HI uint32 + LO uint32 + Registers [32]uint32 + Dropped bool +} + +func NewExpectedMTState(fromState *multithreaded.State) *ExpectedMTState { + currentThread := fromState.GetCurrentThread() + + expectedThreads := make(map[uint32]*ExpectedThreadState) + for _, t := range GetAllThreads(fromState) { + expectedThreads[t.ThreadId] = newExpectedThreadState(t) + } + + return &ExpectedMTState{ + // General Fields + PreimageKey: fromState.GetPreimageKey(), + PreimageOffset: fromState.GetPreimageOffset(), + Heap: fromState.GetHeap(), + ExitCode: fromState.GetExitCode(), + Exited: fromState.GetExited(), + Step: fromState.GetStep(), + LastHint: fromState.GetLastHint(), + MemoryRoot: fromState.GetMemory().MerkleRoot(), + // Thread-related global fields + StepsSinceLastContextSwitch: fromState.StepsSinceLastContextSwitch, + Wakeup: fromState.Wakeup, + TraverseRight: fromState.TraverseRight, + NextThreadId: fromState.NextThreadId, + ThreadCount: fromState.ThreadCount(), + RightStackSize: len(fromState.RightThreadStack), + LeftStackSize: len(fromState.LeftThreadStack), + // ThreadState expectations + prestateActiveThreadId: currentThread.ThreadId, + prestateActiveThreadOrig: *newExpectedThreadState(currentThread), // Cache prestate thread for internal use + ActiveThreadId: currentThread.ThreadId, + threadExpectations: expectedThreads, + } +} + +func newExpectedThreadState(fromThread *multithreaded.ThreadState) *ExpectedThreadState { + return &ExpectedThreadState{ + ThreadId: fromThread.ThreadId, + ExitCode: fromThread.ExitCode, + Exited: fromThread.Exited, + FutexAddr: fromThread.FutexAddr, + FutexVal: fromThread.FutexVal, + FutexTimeoutStep: fromThread.FutexTimeoutStep, + PC: fromThread.Cpu.PC, + NextPC: fromThread.Cpu.NextPC, + HI: fromThread.Cpu.HI, + LO: fromThread.Cpu.LO, + Registers: fromThread.Registers, + Dropped: false, + } +} + +func (e *ExpectedMTState) ExpectStep() { + // Set some standard expectations for a normal step + e.Step += 1 + e.PrestateActiveThread().PC += 4 + e.PrestateActiveThread().NextPC += 4 + e.StepsSinceLastContextSwitch += 1 +} + +func (e *ExpectedMTState) ExpectPreemption(preState *multithreaded.State) { + e.ActiveThreadId = FindNextThread(preState).ThreadId + e.StepsSinceLastContextSwitch = 0 + if preState.TraverseRight { + e.TraverseRight = e.RightStackSize > 1 + e.RightStackSize -= 1 + e.LeftStackSize += 1 + } else { + e.TraverseRight = e.LeftStackSize == 1 + e.LeftStackSize -= 1 + e.RightStackSize += 1 + } +} + +func (e *ExpectedMTState) ExpectNewThread() *ExpectedThreadState { + newThreadId := e.NextThreadId + e.NextThreadId += 1 + e.ThreadCount += 1 + + // Clone expectations from prestate active thread's original state (bf changing any expectations) + newThread := &ExpectedThreadState{} + *newThread = e.prestateActiveThreadOrig + + newThread.ThreadId = newThreadId + e.threadExpectations[newThreadId] = newThread + + return newThread +} + +func (e *ExpectedMTState) ActiveThread() *ExpectedThreadState { + return e.threadExpectations[e.ActiveThreadId] +} + +func (e *ExpectedMTState) PrestateActiveThread() *ExpectedThreadState { + return e.threadExpectations[e.prestateActiveThreadId] +} + +func (e *ExpectedMTState) Thread(threadId uint32) *ExpectedThreadState { + return e.threadExpectations[threadId] +} + +func (e *ExpectedMTState) Validate(t require.TestingT, actualState *multithreaded.State) { + require.Equalf(t, e.PreimageKey, actualState.GetPreimageKey(), "Expect preimageKey = %v", e.PreimageKey) + require.Equalf(t, e.PreimageOffset, actualState.GetPreimageOffset(), "Expect preimageOffset = %v", e.PreimageOffset) + require.Equalf(t, e.Heap, actualState.GetHeap(), "Expect heap = 0x%x", e.Heap) + require.Equalf(t, e.ExitCode, actualState.GetExitCode(), "Expect exitCode = 0x%x", e.ExitCode) + require.Equalf(t, e.Exited, actualState.GetExited(), "Expect exited = %v", e.Exited) + require.Equalf(t, e.Step, actualState.GetStep(), "Expect step = %d", e.Step) + require.Equalf(t, e.LastHint, actualState.GetLastHint(), "Expect lastHint = %v", e.LastHint) + require.Equalf(t, e.MemoryRoot, common.Hash(actualState.GetMemory().MerkleRoot()), "Expect memory root = %v", e.MemoryRoot) + // Thread-related global fields + require.Equalf(t, e.StepsSinceLastContextSwitch, actualState.StepsSinceLastContextSwitch, "Expect StepsSinceLastContextSwitch = %v", e.StepsSinceLastContextSwitch) + require.Equalf(t, e.Wakeup, actualState.Wakeup, "Expect Wakeup = %v", e.Wakeup) + require.Equalf(t, e.TraverseRight, actualState.TraverseRight, "Expect TraverseRight = %v", e.TraverseRight) + require.Equalf(t, e.NextThreadId, actualState.NextThreadId, "Expect NextThreadId = %v", e.NextThreadId) + require.Equalf(t, e.ThreadCount, actualState.ThreadCount(), "Expect thread count = %v", e.ThreadCount) + require.Equalf(t, e.RightStackSize, len(actualState.RightThreadStack), "Expect right stack size = %v", e.RightStackSize) + require.Equalf(t, e.LeftStackSize, len(actualState.LeftThreadStack), "Expect right stack size = %v", e.LeftStackSize) + + // Check active thread + activeThread := actualState.GetCurrentThread() + require.Equal(t, e.ActiveThreadId, activeThread.ThreadId) + // Check all threads + expectedThreadCount := 0 + for tid, exp := range e.threadExpectations { + actualThread := FindThread(actualState, tid) + isActive := tid == activeThread.ThreadId + if exp.Dropped { + require.Nil(t, actualThread, "Thread %v should have been dropped", tid) + } else { + require.NotNil(t, actualThread, "Could not find thread matching expected thread with id %v", tid) + e.validateThread(t, exp, actualThread, isActive) + expectedThreadCount++ + } + } + require.Equal(t, expectedThreadCount, actualState.ThreadCount(), "Thread expectations do not match thread count") +} + +func (e *ExpectedMTState) validateThread(t require.TestingT, et *ExpectedThreadState, actual *multithreaded.ThreadState, isActive bool) { + threadInfo := fmt.Sprintf("tid = %v, active = %v", actual.ThreadId, isActive) + require.Equalf(t, et.ThreadId, actual.ThreadId, "Expect ThreadId = 0x%x (%v)", et.ThreadId, threadInfo) + require.Equalf(t, et.PC, actual.Cpu.PC, "Expect PC = 0x%x (%v)", et.PC, threadInfo) + require.Equalf(t, et.NextPC, actual.Cpu.NextPC, "Expect nextPC = 0x%x (%v)", et.NextPC, threadInfo) + require.Equalf(t, et.HI, actual.Cpu.HI, "Expect HI = 0x%x (%v)", et.HI, threadInfo) + require.Equalf(t, et.LO, actual.Cpu.LO, "Expect LO = 0x%x (%v)", et.LO, threadInfo) + require.Equalf(t, et.Registers, actual.Registers, "Expect registers to match (%v)", threadInfo) + require.Equalf(t, et.ExitCode, actual.ExitCode, "Expect exitCode = %v (%v)", et.ExitCode, threadInfo) + require.Equalf(t, et.Exited, actual.Exited, "Expect exited = %v (%v)", et.Exited, threadInfo) + require.Equalf(t, et.FutexAddr, actual.FutexAddr, "Expect futexAddr = %v (%v)", et.FutexAddr, threadInfo) + require.Equalf(t, et.FutexVal, actual.FutexVal, "Expect futexVal = %v (%v)", et.FutexVal, threadInfo) + require.Equalf(t, et.FutexTimeoutStep, actual.FutexTimeoutStep, "Expect futexTimeoutStep = %v (%v)", et.FutexTimeoutStep, threadInfo) +} diff --git a/cannon/mipsevm/multithreaded/testutil/expectations_test.go b/cannon/mipsevm/multithreaded/testutil/expectations_test.go new file mode 100644 index 000000000000..15cba8b00469 --- /dev/null +++ b/cannon/mipsevm/multithreaded/testutil/expectations_test.go @@ -0,0 +1,179 @@ +package testutil + +import ( + "fmt" + "testing" + + //"github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" +) + +type ExpectationMutator func(e *ExpectedMTState, st *multithreaded.State) + +func TestValidate_shouldCatchMutations(t *testing.T) { + states := []*multithreaded.State{ + RandomState(0), + RandomState(1), + RandomState(2), + } + var emptyHash [32]byte + someThread := RandomThread(123) + + cases := []struct { + name string + mut ExpectationMutator + }{ + {name: "PreimageKey", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.PreimageKey = emptyHash }}, + {name: "PreimageOffset", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.PreimageOffset += 1 }}, + {name: "Heap", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.Heap += 1 }}, + {name: "ExitCode", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.ExitCode += 1 }}, + {name: "Exited", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.Exited = !e.Exited }}, + {name: "Step", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.Step += 1 }}, + {name: "LastHint", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.LastHint = []byte{7, 8, 9, 10} }}, + {name: "MemoryRoot", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.MemoryRoot = emptyHash }}, + {name: "StepsSinceLastContextSwitch", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.StepsSinceLastContextSwitch += 1 }}, + {name: "Wakeup", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.Wakeup += 1 }}, + {name: "TraverseRight", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.TraverseRight = !e.TraverseRight }}, + {name: "NextThreadId", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.NextThreadId += 1 }}, + {name: "ThreadCount", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.ThreadCount += 1 }}, + {name: "RightStackSize", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.RightStackSize += 1 }}, + {name: "LeftStackSize", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.LeftStackSize += 1 }}, + {name: "ActiveThreadId", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.ActiveThreadId += 1 }}, + {name: "Empty thread expectations", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations = map[uint32]*ExpectedThreadState{} + }}, + {name: "Mismatched thread expectations", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations = map[uint32]*ExpectedThreadState{someThread.ThreadId: newExpectedThreadState(someThread)} + }}, + {name: "Active threadId", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[st.GetCurrentThread().ThreadId].ThreadId += 1 + }}, + {name: "Active thread exitCode", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[st.GetCurrentThread().ThreadId].ExitCode += 1 + }}, + {name: "Active thread exited", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[st.GetCurrentThread().ThreadId].Exited = !st.GetCurrentThread().Exited + }}, + {name: "Active thread futexAddr", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[st.GetCurrentThread().ThreadId].FutexAddr += 1 + }}, + {name: "Active thread futexVal", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[st.GetCurrentThread().ThreadId].FutexVal += 1 + }}, + {name: "Active thread FutexTimeoutStep", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[st.GetCurrentThread().ThreadId].FutexTimeoutStep += 1 + }}, + {name: "Active thread PC", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[st.GetCurrentThread().ThreadId].PC += 1 + }}, + {name: "Active thread NextPC", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[st.GetCurrentThread().ThreadId].NextPC += 1 + }}, + {name: "Active thread HI", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[st.GetCurrentThread().ThreadId].HI += 1 + }}, + {name: "Active thread LO", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[st.GetCurrentThread().ThreadId].LO += 1 + }}, + {name: "Active thread Registers", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[st.GetCurrentThread().ThreadId].Registers[0] += 1 + }}, + {name: "Active thread dropped", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[st.GetCurrentThread().ThreadId].Dropped = true + }}, + {name: "Inactive threadId", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[FindNextThread(st).ThreadId].ThreadId += 1 + }}, + {name: "Inactive thread exitCode", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[FindNextThread(st).ThreadId].ExitCode += 1 + }}, + {name: "Inactive thread exited", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[FindNextThread(st).ThreadId].Exited = !FindNextThread(st).Exited + }}, + {name: "Inactive thread futexAddr", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[FindNextThread(st).ThreadId].FutexAddr += 1 + }}, + {name: "Inactive thread futexVal", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[FindNextThread(st).ThreadId].FutexVal += 1 + }}, + {name: "Inactive thread FutexTimeoutStep", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[FindNextThread(st).ThreadId].FutexTimeoutStep += 1 + }}, + {name: "Inactive thread PC", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[FindNextThread(st).ThreadId].PC += 1 + }}, + {name: "Inactive thread NextPC", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[FindNextThread(st).ThreadId].NextPC += 1 + }}, + {name: "Inactive thread HI", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[FindNextThread(st).ThreadId].HI += 1 + }}, + {name: "Inactive thread LO", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[FindNextThread(st).ThreadId].LO += 1 + }}, + {name: "Inactive thread Registers", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[FindNextThread(st).ThreadId].Registers[0] += 1 + }}, + {name: "Inactive thread dropped", mut: func(e *ExpectedMTState, st *multithreaded.State) { + e.threadExpectations[FindNextThread(st).ThreadId].Dropped = true + }}, + } + for _, c := range cases { + for i, state := range states { + testName := fmt.Sprintf("%v (state #%v)", c.name, i) + t.Run(testName, func(t *testing.T) { + expected := NewExpectedMTState(state) + c.mut(expected, state) + + // We should detect the change and fail + mockT := &MockTestingT{} + expected.Validate(mockT, state) + mockT.RequireFailed(t) + }) + } + + } +} + +func TestValidate_shouldPassUnchangedExpectations(t *testing.T) { + states := []*multithreaded.State{ + RandomState(0), + RandomState(1), + RandomState(2), + } + + for i, state := range states { + testName := fmt.Sprintf("State #%v", i) + t.Run(testName, func(t *testing.T) { + expected := NewExpectedMTState(state) + + mockT := &MockTestingT{} + expected.Validate(mockT, state) + mockT.RequireNoFailure(t) + }) + } +} + +type MockTestingT struct { + errCount int +} + +var _ require.TestingT = (*MockTestingT)(nil) + +func (m *MockTestingT) Errorf(format string, args ...interface{}) { + m.errCount += 1 +} + +func (m *MockTestingT) FailNow() { + m.errCount += 1 +} + +func (m *MockTestingT) RequireFailed(t require.TestingT) { + require.Greater(t, m.errCount, 0, "Should have tracked a failure") +} + +func (m *MockTestingT) RequireNoFailure(t require.TestingT) { + require.Equal(t, m.errCount, 0, "Should not have tracked a failure") +} diff --git a/cannon/mipsevm/multithreaded/testutil/mutators.go b/cannon/mipsevm/multithreaded/testutil/mutators.go new file mode 100644 index 000000000000..30a97691609e --- /dev/null +++ b/cannon/mipsevm/multithreaded/testutil/mutators.go @@ -0,0 +1,87 @@ +package testutil + +import ( + "math/rand" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + + "github.com/ethereum-optimism/optimism/cannon/mipsevm/exec" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/testutil" +) + +type StateMutatorMultiThreaded struct { + state *multithreaded.State +} + +var _ testutil.StateMutator = (*StateMutatorMultiThreaded)(nil) + +func NewStateMutatorMultiThreaded(state *multithreaded.State) testutil.StateMutator { + return &StateMutatorMultiThreaded{state: state} +} + +func (m *StateMutatorMultiThreaded) Randomize(randSeed int64) { + r := rand.New(rand.NewSource(randSeed)) + + step := testutil.RandStep(r) + + m.state.PreimageKey = testutil.RandHash(r) + m.state.PreimageOffset = r.Uint32() + m.state.Heap = r.Uint32() + m.state.Step = step + m.state.LastHint = testutil.RandHint(r) + m.state.StepsSinceLastContextSwitch = uint64(r.Intn(exec.SchedQuantum)) + + // Randomize threads + activeStackThreads := r.Intn(2) + 1 + inactiveStackThreads := r.Intn(3) + traverseRight := r.Intn(2) == 1 + SetupThreads(randSeed+1, m.state, traverseRight, activeStackThreads, inactiveStackThreads) +} + +func (m *StateMutatorMultiThreaded) SetHI(val uint32) { + m.state.GetCurrentThread().Cpu.HI = val +} + +func (m *StateMutatorMultiThreaded) SetLO(val uint32) { + m.state.GetCurrentThread().Cpu.LO = val +} + +func (m *StateMutatorMultiThreaded) SetExitCode(val uint8) { + m.state.ExitCode = val +} + +func (m *StateMutatorMultiThreaded) SetExited(val bool) { + m.state.Exited = val +} + +func (m *StateMutatorMultiThreaded) SetPC(val uint32) { + thread := m.state.GetCurrentThread() + thread.Cpu.PC = val +} + +func (m *StateMutatorMultiThreaded) SetHeap(val uint32) { + m.state.Heap = val +} + +func (m *StateMutatorMultiThreaded) SetNextPC(val uint32) { + thread := m.state.GetCurrentThread() + thread.Cpu.NextPC = val +} + +func (m *StateMutatorMultiThreaded) SetLastHint(val hexutil.Bytes) { + m.state.LastHint = val +} + +func (m *StateMutatorMultiThreaded) SetPreimageKey(val common.Hash) { + m.state.PreimageKey = val +} + +func (m *StateMutatorMultiThreaded) SetPreimageOffset(val uint32) { + m.state.PreimageOffset = val +} + +func (m *StateMutatorMultiThreaded) SetStep(val uint64) { + m.state.Step = val +} diff --git a/cannon/mipsevm/multithreaded/testutil/state.go b/cannon/mipsevm/multithreaded/testutil/state.go index d7896005eafd..b240c95c0bba 100644 --- a/cannon/mipsevm/multithreaded/testutil/state.go +++ b/cannon/mipsevm/multithreaded/testutil/state.go @@ -1,69 +1,24 @@ package testutil import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/stretchr/testify/require" + "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/testutil" ) -type StateMutatorMultiThreaded struct { - state *multithreaded.State +func GetMtState(t require.TestingT, vm mipsevm.FPVM) *multithreaded.State { + state := vm.GetState() + mtState, ok := state.(*multithreaded.State) + if !ok { + require.Fail(t, "Failed to cast FPVMState to multithreaded State type") + } + return mtState } -var _ testutil.StateMutator = (*StateMutatorMultiThreaded)(nil) - -func NewStateMutatorMultiThreaded(state *multithreaded.State) testutil.StateMutator { - return &StateMutatorMultiThreaded{state: state} -} - -func (m *StateMutatorMultiThreaded) SetHI(val uint32) { - m.state.GetCurrentThread().Cpu.HI = val -} - -func (m *StateMutatorMultiThreaded) SetLO(val uint32) { - m.state.GetCurrentThread().Cpu.LO = val -} - -func (m *StateMutatorMultiThreaded) SetExitCode(val uint8) { - m.state.ExitCode = val -} - -func (m *StateMutatorMultiThreaded) SetExited(val bool) { - m.state.Exited = val -} - -func (m *StateMutatorMultiThreaded) SetPC(val uint32) { - thread := m.state.GetCurrentThread() - thread.Cpu.PC = val -} - -func (m *StateMutatorMultiThreaded) SetHeap(val uint32) { - m.state.Heap = val -} - -func (m *StateMutatorMultiThreaded) SetNextPC(val uint32) { - thread := m.state.GetCurrentThread() - thread.Cpu.NextPC = val -} - -func (m *StateMutatorMultiThreaded) SetLastHint(val hexutil.Bytes) { - m.state.LastHint = val -} - -func (m *StateMutatorMultiThreaded) SetPreimageKey(val common.Hash) { - m.state.PreimageKey = val -} - -func (m *StateMutatorMultiThreaded) SetPreimageOffset(val uint32) { - m.state.PreimageOffset = val -} - -func (m *StateMutatorMultiThreaded) SetStep(val uint64) { - m.state.Step = val -} - -func (m *StateMutatorMultiThreaded) GetRegistersRef() *[32]uint32 { - return m.state.GetRegistersRef() +func RandomState(seed int) *multithreaded.State { + state := multithreaded.CreateEmptyState() + mut := StateMutatorMultiThreaded{state} + mut.Randomize(int64(seed)) + return state } diff --git a/cannon/mipsevm/multithreaded/testutil/thread.go b/cannon/mipsevm/multithreaded/testutil/thread.go new file mode 100644 index 000000000000..217ab94e8185 --- /dev/null +++ b/cannon/mipsevm/multithreaded/testutil/thread.go @@ -0,0 +1,166 @@ +package testutil + +import ( + "math/rand" + + "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/testutil" +) + +func RandomThread(randSeed int64) *multithreaded.ThreadState { + r := rand.New(rand.NewSource(randSeed)) + thread := multithreaded.CreateEmptyThread() + + pc := testutil.RandPC(r) + + thread.Registers = *testutil.RandRegisters(r) + thread.Cpu.PC = pc + thread.Cpu.NextPC = pc + 4 + thread.Cpu.HI = r.Uint32() + thread.Cpu.LO = r.Uint32() + + return thread +} + +func InitializeSingleThread(randSeed int, state *multithreaded.State, traverseRight bool) { + singleThread := RandomThread(int64(randSeed)) + + state.NextThreadId = singleThread.ThreadId + 1 + state.TraverseRight = traverseRight + if traverseRight { + state.RightThreadStack = []*multithreaded.ThreadState{singleThread} + state.LeftThreadStack = []*multithreaded.ThreadState{} + } else { + state.RightThreadStack = []*multithreaded.ThreadState{} + state.LeftThreadStack = []*multithreaded.ThreadState{singleThread} + } +} + +func SetupThreads(randomSeed int64, state *multithreaded.State, traverseRight bool, activeStackSize, otherStackSize int) { + var activeStack, otherStack []*multithreaded.ThreadState + + tid := uint32(0) + for i := 0; i < activeStackSize; i++ { + thread := RandomThread(randomSeed + int64(i)) + thread.ThreadId = tid + activeStack = append(activeStack, thread) + tid++ + } + + for i := 0; i < otherStackSize; i++ { + thread := RandomThread(randomSeed + int64(i+activeStackSize)) + thread.ThreadId = tid + otherStack = append(otherStack, thread) + tid++ + } + + state.NextThreadId = tid + state.TraverseRight = traverseRight + if traverseRight { + state.RightThreadStack = activeStack + state.LeftThreadStack = otherStack + } else { + state.LeftThreadStack = activeStack + state.RightThreadStack = otherStack + } +} + +type ThreadIterator struct { + left []*multithreaded.ThreadState + right []*multithreaded.ThreadState + traverseRight bool +} + +func NewThreadIterator(state *multithreaded.State) ThreadIterator { + return ThreadIterator{ + left: state.LeftThreadStack, + right: state.RightThreadStack, + traverseRight: state.TraverseRight, + } +} + +func (i *ThreadIterator) currentThread() *multithreaded.ThreadState { + var currentThread *multithreaded.ThreadState + if i.traverseRight { + currentThread = i.right[len(i.right)-1] + } else { + currentThread = i.left[len(i.left)-1] + } + return currentThread +} + +func (i *ThreadIterator) Next() *multithreaded.ThreadState { + rightLen := len(i.right) + leftLen := len(i.left) + activeThread := i.currentThread() + + if i.traverseRight { + i.right = i.right[:rightLen-1] + i.left = append(i.left, activeThread) + i.traverseRight = len(i.right) > 0 + } else { + i.left = i.left[:leftLen-1] + i.right = append(i.right, activeThread) + i.traverseRight = len(i.left) == 0 + } + + return i.currentThread() +} + +// FindNextThread Finds the next thread in line according to thread traversal logic +func FindNextThread(state *multithreaded.State) *multithreaded.ThreadState { + it := NewThreadIterator(state) + return it.Next() +} + +type ThreadFilter func(thread *multithreaded.ThreadState) bool + +func FindNextThreadFiltered(state *multithreaded.State, filter ThreadFilter) *multithreaded.ThreadState { + it := NewThreadIterator(state) + + // Worst case - walk all the way left, then all the way back right + // Example w 3 threads: 1,2,3,3,2,1,0 -> 7 steps to find thread 0 + maxIterations := state.ThreadCount()*2 + 1 + for i := 0; i < maxIterations; i++ { + next := it.Next() + if filter(next) { + return next + } + } + + return nil +} + +func FindNextThreadExcluding(state *multithreaded.State, threadId uint32) *multithreaded.ThreadState { + return FindNextThreadFiltered(state, func(t *multithreaded.ThreadState) bool { + return t.ThreadId != threadId + }) +} + +func FindThread(state *multithreaded.State, threadId uint32) *multithreaded.ThreadState { + for _, t := range GetAllThreads(state) { + if t.ThreadId == threadId { + return t + } + } + return nil +} + +func GetAllThreads(state *multithreaded.State) []*multithreaded.ThreadState { + allThreads := make([]*multithreaded.ThreadState, 0, state.ThreadCount()) + allThreads = append(allThreads, state.RightThreadStack[:]...) + allThreads = append(allThreads, state.LeftThreadStack[:]...) + + return allThreads +} + +func GetThreadStacks(state *multithreaded.State) (activeStack, inactiveStack []*multithreaded.ThreadState) { + if state.TraverseRight { + activeStack = state.RightThreadStack + inactiveStack = state.LeftThreadStack + } else { + activeStack = state.LeftThreadStack + inactiveStack = state.RightThreadStack + } + return activeStack, inactiveStack +} diff --git a/cannon/mipsevm/singlethreaded/testutil/state.go b/cannon/mipsevm/singlethreaded/testutil/state.go index 9d8909eee772..f09b56175af9 100644 --- a/cannon/mipsevm/singlethreaded/testutil/state.go +++ b/cannon/mipsevm/singlethreaded/testutil/state.go @@ -1,6 +1,8 @@ package testutil import ( + "math/rand" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -12,6 +14,24 @@ type StateMutatorSingleThreaded struct { state *singlethreaded.State } +func (m *StateMutatorSingleThreaded) Randomize(randSeed int64) { + r := rand.New(rand.NewSource(randSeed)) + + pc := testutil.RandPC(r) + step := testutil.RandStep(r) + + m.state.PreimageKey = testutil.RandHash(r) + m.state.PreimageOffset = r.Uint32() + m.state.Cpu.PC = pc + m.state.Cpu.NextPC = pc + 4 + m.state.Cpu.HI = r.Uint32() + m.state.Cpu.LO = r.Uint32() + m.state.Heap = r.Uint32() + m.state.Step = step + m.state.LastHint = testutil.RandHint(r) + m.state.Registers = *testutil.RandRegisters(r) +} + var _ testutil.StateMutator = (*StateMutatorSingleThreaded)(nil) func NewStateMutatorSingleThreaded(state *singlethreaded.State) testutil.StateMutator { @@ -61,7 +81,3 @@ func (m *StateMutatorSingleThreaded) SetPreimageOffset(val uint32) { func (m *StateMutatorSingleThreaded) SetStep(val uint64) { m.state.Step = val } - -func (m *StateMutatorSingleThreaded) GetRegistersRef() *[32]uint32 { - return m.state.GetRegistersRef() -} diff --git a/cannon/mipsevm/tests/evm_common_test.go b/cannon/mipsevm/tests/evm_common_test.go index 445ed5031d2d..063c63c83c6c 100644 --- a/cannon/mipsevm/tests/evm_common_test.go +++ b/cannon/mipsevm/tests/evm_common_test.go @@ -10,13 +10,10 @@ import ( "testing" "time" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/tracing" - "github.com/ethereum/go-ethereum/core/vm" "github.com/stretchr/testify/require" - "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/cannon/mipsevm/exec" "github.com/ethereum-optimism/optimism/cannon/mipsevm/memory" "github.com/ethereum-optimism/optimism/cannon/mipsevm/program" @@ -143,10 +140,10 @@ func TestEVMSingleStep(t *testing.T) { goVm := v.VMFactory(nil, os.Stdout, os.Stderr, testutil.CreateLogger(), testutil.WithRandomization(int64(i)), testutil.WithPC(tt.pc), testutil.WithNextPC(tt.nextPC)) state := goVm.GetState() state.GetMemory().SetMemory(tt.pc, tt.insn) - curStep := state.GetStep() + step := state.GetStep() // Setup expectations - expected := testutil.CreateExpectedState(state) + expected := testutil.NewExpectedState(state) expected.Step += 1 expected.PC = state.GetCpu().NextPC expected.NextPC = tt.expectNextPC @@ -159,15 +156,7 @@ func TestEVMSingleStep(t *testing.T) { // Check expectations expected.Validate(t, state) - - evm := testutil.NewMIPSEVM(v.Contracts) - evm.SetTracer(tracer) - testutil.LogStepFailureAtCleanup(t, evm) - - evmPost := evm.Step(t, stepWitness, curStep, v.StateHashFn) - goPost, _ := goVm.GetState().EncodeWitness() - require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), - "mipsevm produced different state than EVM") + testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, tracer) }) } } @@ -209,7 +198,7 @@ func TestEVM_MMap(t *testing.T) { state.GetRegistersRef()[5] = c.size step := state.GetStep() - expected := testutil.CreateExpectedState(state) + expected := testutil.NewExpectedState(state) expected.Step += 1 expected.PC = state.GetCpu().NextPC expected.NextPC = state.GetCpu().NextPC + 4 @@ -232,15 +221,7 @@ func TestEVM_MMap(t *testing.T) { // Check expectations expected.Validate(t, state) - - evm := testutil.NewMIPSEVM(v.Contracts) - evm.SetTracer(tracer) - testutil.LogStepFailureAtCleanup(t, evm) - - evmPost := evm.Step(t, stepWitness, step, v.StateHashFn) - goPost, _ := goVm.GetState().EncodeWitness() - require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), - "mipsevm produced different state than EVM") + testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, tracer) }) } } @@ -420,9 +401,9 @@ func TestEVMSysWriteHint(t *testing.T) { err := state.GetMemory().SetMemoryRange(uint32(tt.memOffset), bytes.NewReader(tt.hintData)) require.NoError(t, err) state.GetMemory().SetMemory(state.GetPC(), insn) - curStep := state.GetStep() + step := state.GetStep() - expected := testutil.CreateExpectedState(state) + expected := testutil.NewExpectedState(state) expected.Step += 1 expected.PC = state.GetCpu().NextPC expected.NextPC = state.GetCpu().NextPC + 4 @@ -435,15 +416,7 @@ func TestEVMSysWriteHint(t *testing.T) { expected.Validate(t, state) require.Equal(t, tt.expectedHints, oracle.Hints()) - - evm := testutil.NewMIPSEVM(v.Contracts) - evm.SetTracer(tracer) - testutil.LogStepFailureAtCleanup(t, evm) - - evmPost := evm.Step(t, stepWitness, curStep, v.StateHashFn) - goPost, _ := goVm.GetState().EncodeWitness() - require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), - "mipsevm produced different state than EVM") + testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, tracer) }) } } @@ -451,7 +424,6 @@ func TestEVMSysWriteHint(t *testing.T) { func TestEVMFault(t *testing.T) { var tracer *tracing.Hooks // no-tracer by default, but see test_util.MarkdownTracer - sender := common.Address{0x13, 0x37} versions := GetMipsVersionTestCases(t) cases := []struct { @@ -468,9 +440,6 @@ func TestEVMFault(t *testing.T) { for _, tt := range cases { testName := fmt.Sprintf("%v (%v)", tt.name, v.Name) t.Run(testName, func(t *testing.T) { - env, evmState := testutil.NewEVMEnv(v.Contracts) - env.Config.Tracer = tracer - goVm := v.VMFactory(nil, os.Stdout, os.Stderr, testutil.CreateLogger(), testutil.WithNextPC(tt.nextPC)) state := goVm.GetState() state.GetMemory().SetMemory(0, tt.insn) @@ -478,20 +447,7 @@ func TestEVMFault(t *testing.T) { state.GetRegistersRef()[31] = testutil.EndAddr require.Panics(t, func() { _, _ = goVm.Step(true) }) - - insnProof := state.GetMemory().MerkleProof(0) - encodedWitness, _ := state.EncodeWitness() - stepWitness := &mipsevm.StepWitness{ - State: encodedWitness, - ProofData: insnProof[:], - } - input := testutil.EncodeStepInput(t, stepWitness, mipsevm.LocalContext{}, v.Contracts.Artifacts.MIPS) - startingGas := uint64(30_000_000) - - _, _, err := env.Call(vm.AccountRef(sender), v.Contracts.Addresses.MIPS, input, startingGas, common.U2560) - require.EqualValues(t, err, vm.ErrExecutionReverted) - logs := evmState.Logs() - require.Equal(t, 0, len(logs)) + testutil.AssertEVMReverts(t, state, v.Contracts, tracer) }) } } @@ -514,7 +470,7 @@ func TestHelloEVM(t *testing.T) { start := time.Now() for i := 0; i < 400_000; i++ { - curStep := goVm.GetState().GetStep() + step := goVm.GetState().GetStep() if goVm.GetState().GetExited() { break } @@ -525,7 +481,7 @@ func TestHelloEVM(t *testing.T) { stepWitness, err := goVm.Step(true) require.NoError(t, err) - evmPost := evm.Step(t, stepWitness, curStep, v.StateHashFn) + evmPost := evm.Step(t, stepWitness, step, v.StateHashFn) // verify the post-state matches. // TODO: maybe more readable to decode the evmPost state, and do attribute-wise comparison. goPost, _ := goVm.GetState().EncodeWitness() diff --git a/cannon/mipsevm/tests/evm_multithreaded_test.go b/cannon/mipsevm/tests/evm_multithreaded_test.go index 32d90b74211c..ebd5dc904e28 100644 --- a/cannon/mipsevm/tests/evm_multithreaded_test.go +++ b/cannon/mipsevm/tests/evm_multithreaded_test.go @@ -1,20 +1,24 @@ package tests import ( + "fmt" "os" + "slices" "testing" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/tracing" "github.com/stretchr/testify/require" + "golang.org/x/exp/maps" "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/cannon/mipsevm/exec" "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" + mttestutil "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded/testutil" "github.com/ethereum-optimism/optimism/cannon/mipsevm/testutil" ) -func TestEVM_CloneFlags(t *testing.T) { +func TestEVM_SysClone_FlagHandling(t *testing.T) { contracts := testutil.TestContractsSetup(t, testutil.MipsMultithreaded) var tracer *tracing.Hooks @@ -34,27 +38,32 @@ func TestEVM_CloneFlags(t *testing.T) { {"multiple unsupported flags", exec.CloneUntraced | exec.CloneParentSettid, false}, } - const insn = uint32(0x00_00_00_0C) // syscall instruction - for _, tt := range cases { - t.Run(tt.name, func(t *testing.T) { + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { state := multithreaded.CreateEmptyState() - state.Memory.SetMemory(state.GetPC(), insn) + state.Memory.SetMemory(state.GetPC(), syscallInsn) state.GetRegistersRef()[2] = exec.SysClone // Set syscall number - state.GetRegistersRef()[4] = tt.flags // Set first argument + state.GetRegistersRef()[4] = c.flags // Set first argument curStep := state.Step var err error var stepWitness *mipsevm.StepWitness us := multithreaded.NewInstrumentedState(state, nil, os.Stdout, os.Stderr, nil) - if !tt.valid { + if !c.valid { // The VM should exit stepWitness, err = us.Step(true) require.NoError(t, err) + require.Equal(t, curStep+1, state.GetStep()) require.Equal(t, true, us.GetState().GetExited()) require.Equal(t, uint8(mipsevm.VMStatusPanic), us.GetState().GetExitCode()) + require.Equal(t, 1, state.ThreadCount()) } else { stepWitness, err = us.Step(true) require.NoError(t, err) + require.Equal(t, curStep+1, state.GetStep()) + require.Equal(t, false, us.GetState().GetExited()) + require.Equal(t, uint8(0), us.GetState().GetExitCode()) + require.Equal(t, 2, state.ThreadCount()) } evm := testutil.NewMIPSEVM(contracts) @@ -68,3 +77,886 @@ func TestEVM_CloneFlags(t *testing.T) { }) } } + +func TestEVM_SysClone_Successful(t *testing.T) { + var tracer *tracing.Hooks + cases := []struct { + name string + traverseRight bool + }{ + {"traverse left", false}, + {"traverse right", true}, + } + + for i, c := range cases { + t.Run(c.name, func(t *testing.T) { + stackPtr := uint32(100) + + goVm, state, contracts := setup(t, i) + mttestutil.InitializeSingleThread(i*333, state, c.traverseRight) + state.Memory.SetMemory(state.GetPC(), syscallInsn) + state.GetRegistersRef()[2] = exec.SysClone // the syscall number + state.GetRegistersRef()[4] = exec.ValidCloneFlags // a0 - first argument, clone flags + state.GetRegistersRef()[5] = stackPtr // a1 - the stack pointer + step := state.GetStep() + + // Sanity-check assumptions + require.Equal(t, uint32(1), state.NextThreadId) + + // Setup expectations + expected := mttestutil.NewExpectedMTState(state) + expected.Step += 1 + expectedNewThread := expected.ExpectNewThread() + expected.ActiveThreadId = expectedNewThread.ThreadId + expected.StepsSinceLastContextSwitch = 0 + if c.traverseRight { + expected.RightStackSize += 1 + } else { + expected.LeftStackSize += 1 + } + // Original thread expectations + expected.PrestateActiveThread().PC = state.GetCpu().NextPC + expected.PrestateActiveThread().NextPC = state.GetCpu().NextPC + 4 + expected.PrestateActiveThread().Registers[2] = 1 + expected.PrestateActiveThread().Registers[7] = 0 + // New thread expectations + expectedNewThread.PC = state.GetCpu().NextPC + expectedNewThread.NextPC = state.GetCpu().NextPC + 4 + expectedNewThread.ThreadId = 1 + expectedNewThread.Registers[2] = 0 + expectedNewThread.Registers[7] = 0 + expectedNewThread.Registers[29] = stackPtr + + var err error + var stepWitness *mipsevm.StepWitness + stepWitness, err = goVm.Step(true) + require.NoError(t, err) + + expected.Validate(t, state) + activeStack, inactiveStack := mttestutil.GetThreadStacks(state) + require.Equal(t, 2, len(activeStack)) + require.Equal(t, 0, len(inactiveStack)) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) + }) + } +} + +func TestEVM_SysGetTID(t *testing.T) { + var tracer *tracing.Hooks + cases := []struct { + name string + threadId uint32 + }{ + {"zero", 0}, + {"non-zero", 11}, + } + + for i, c := range cases { + t.Run(c.name, func(t *testing.T) { + goVm, state, contracts := setup(t, i*789) + mttestutil.InitializeSingleThread(i*789, state, false) + + state.GetCurrentThread().ThreadId = c.threadId + state.Memory.SetMemory(state.GetPC(), syscallInsn) + state.GetRegistersRef()[2] = exec.SysGetTID // Set syscall number + step := state.Step + + // Set up post-state expectations + expected := mttestutil.NewExpectedMTState(state) + expected.ExpectStep() + expected.ActiveThread().Registers[2] = c.threadId + expected.ActiveThread().Registers[7] = 0 + + // State transition + var err error + var stepWitness *mipsevm.StepWitness + stepWitness, err = goVm.Step(true) + require.NoError(t, err) + + // Validate post-state + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) + }) + } +} + +func TestEVM_SysExit(t *testing.T) { + var tracer *tracing.Hooks + cases := []struct { + name string + threadCount int + shouldExitGlobally bool + }{ + // If we exit the last thread, the whole process should exit + {name: "one thread", threadCount: 1, shouldExitGlobally: true}, + {name: "two threads ", threadCount: 2}, + {name: "three threads ", threadCount: 3}, + } + + for i, c := range cases { + t.Run(c.name, func(t *testing.T) { + exitCode := uint8(3) + + goVm, state, contracts := setup(t, i*133) + mttestutil.SetupThreads(int64(i*1111), state, i%2 == 0, c.threadCount, 0) + + state.Memory.SetMemory(state.GetPC(), syscallInsn) + state.GetRegistersRef()[2] = exec.SysExit // Set syscall number + state.GetRegistersRef()[4] = uint32(exitCode) // The first argument (exit code) + step := state.Step + + // Set up expectations + expected := mttestutil.NewExpectedMTState(state) + expected.Step += 1 + expected.StepsSinceLastContextSwitch += 1 + expected.ActiveThread().Exited = true + expected.ActiveThread().ExitCode = exitCode + if c.shouldExitGlobally { + expected.Exited = true + expected.ExitCode = exitCode + } + + // State transition + var err error + var stepWitness *mipsevm.StepWitness + stepWitness, err = goVm.Step(true) + require.NoError(t, err) + + // Validate post-state + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) + }) + } +} + +func TestEVM_PopExitedThread(t *testing.T) { + var tracer *tracing.Hooks + cases := []struct { + name string + traverseRight bool + activeStackThreadCount int + expectTraverseRightPostState bool + }{ + {name: "traverse right", traverseRight: true, activeStackThreadCount: 2, expectTraverseRightPostState: true}, + {name: "traverse right, switch directions", traverseRight: true, activeStackThreadCount: 1, expectTraverseRightPostState: false}, + {name: "traverse left", traverseRight: false, activeStackThreadCount: 2, expectTraverseRightPostState: false}, + {name: "traverse left, switch directions", traverseRight: false, activeStackThreadCount: 1, expectTraverseRightPostState: true}, + } + + for i, c := range cases { + t.Run(c.name, func(t *testing.T) { + goVm, state, contracts := setup(t, i*133) + mttestutil.SetupThreads(int64(i*222), state, c.traverseRight, c.activeStackThreadCount, 1) + step := state.Step + + // Setup thread to be dropped + threadToPop := state.GetCurrentThread() + threadToPop.Exited = true + threadToPop.ExitCode = 1 + + // Set up expectations + expected := mttestutil.NewExpectedMTState(state) + expected.Step += 1 + expected.ActiveThreadId = mttestutil.FindNextThreadExcluding(state, threadToPop.ThreadId).ThreadId + expected.StepsSinceLastContextSwitch = 0 + expected.ThreadCount -= 1 + expected.TraverseRight = c.expectTraverseRightPostState + expected.Thread(threadToPop.ThreadId).Dropped = true + if c.traverseRight { + expected.RightStackSize -= 1 + } else { + expected.LeftStackSize -= 1 + } + + // State transition + var err error + var stepWitness *mipsevm.StepWitness + stepWitness, err = goVm.Step(true) + require.NoError(t, err) + + // Validate post-state + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) + }) + } +} + +func TestEVM_SysFutex_WaitPrivate(t *testing.T) { + var tracer *tracing.Hooks + cases := []struct { + name string + address uint32 + targetValue uint32 + actualValue uint32 + timeout uint32 + shouldFail bool + shouldSetTimeout bool + }{ + {name: "successful wait, no timeout", address: 0x1234, targetValue: 0x01, actualValue: 0x01}, + {name: "memory mismatch, no timeout", address: 0x1200, targetValue: 0x01, actualValue: 0x02, shouldFail: true}, + {name: "successful wait w timeout", address: 0x1234, targetValue: 0x01, actualValue: 0x01, timeout: 1000000, shouldSetTimeout: true}, + {name: "memory mismatch w timeout", address: 0x1200, targetValue: 0x01, actualValue: 0x02, timeout: 2000000, shouldFail: true}, + } + + for i, c := range cases { + t.Run(c.name, func(t *testing.T) { + goVm, state, contracts := setup(t, i*1234) + step := state.GetStep() + + state.Memory.SetMemory(state.GetPC(), syscallInsn) + state.Memory.SetMemory(c.address, c.actualValue) + state.GetRegistersRef()[2] = exec.SysFutex // Set syscall number + state.GetRegistersRef()[4] = c.address + state.GetRegistersRef()[5] = exec.FutexWaitPrivate + state.GetRegistersRef()[6] = c.targetValue + state.GetRegistersRef()[7] = c.timeout + + // Setup expectations + expected := mttestutil.NewExpectedMTState(state) + expected.Step += 1 + expected.StepsSinceLastContextSwitch += 1 + if c.shouldFail { + expected.ActiveThread().PC = state.GetCpu().NextPC + expected.ActiveThread().NextPC = state.GetCpu().NextPC + 4 + expected.ActiveThread().Registers[2] = exec.SysErrorSignal + expected.ActiveThread().Registers[7] = exec.MipsEAGAIN + } else { + // PC and return registers should not update on success, updates happen when wait completes + expected.ActiveThread().FutexAddr = c.address + expected.ActiveThread().FutexVal = c.targetValue + expected.ActiveThread().FutexTimeoutStep = exec.FutexNoTimeout + if c.shouldSetTimeout { + expected.ActiveThread().FutexTimeoutStep = step + exec.FutexTimeoutSteps + 1 + } + } + + // State transition + var err error + var stepWitness *mipsevm.StepWitness + stepWitness, err = goVm.Step(true) + require.NoError(t, err) + + // Validate post-state + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) + }) + } +} + +func TestEVM_SysFutex_WakePrivate(t *testing.T) { + var tracer *tracing.Hooks + cases := []struct { + name string + address uint32 + activeThreadCount int + inactiveThreadCount int + traverseRight bool + expectTraverseRight bool + }{ + {name: "Traverse right", address: 0x6789, activeThreadCount: 2, inactiveThreadCount: 1, traverseRight: true}, + {name: "Traverse right, no left threads", address: 0x6789, activeThreadCount: 2, inactiveThreadCount: 0, traverseRight: true}, + {name: "Traverse right, single thread", address: 0x6789, activeThreadCount: 1, inactiveThreadCount: 0, traverseRight: true}, + {name: "Traverse left", address: 0x6789, activeThreadCount: 2, inactiveThreadCount: 1, traverseRight: false}, + {name: "Traverse left, switch directions", address: 0x6789, activeThreadCount: 1, inactiveThreadCount: 1, traverseRight: false, expectTraverseRight: true}, + {name: "Traverse left, single thread", address: 0x6789, activeThreadCount: 1, inactiveThreadCount: 0, traverseRight: false, expectTraverseRight: true}, + } + + for i, c := range cases { + t.Run(c.name, func(t *testing.T) { + goVm, state, contracts := setup(t, i*1122) + mttestutil.SetupThreads(int64(i*2244), state, c.traverseRight, c.activeThreadCount, c.inactiveThreadCount) + step := state.Step + + state.Memory.SetMemory(state.GetPC(), syscallInsn) + state.GetRegistersRef()[2] = exec.SysFutex // Set syscall number + state.GetRegistersRef()[4] = c.address + state.GetRegistersRef()[5] = exec.FutexWakePrivate + + // Set up post-state expectations + expected := mttestutil.NewExpectedMTState(state) + expected.ExpectStep() + expected.ActiveThread().Registers[2] = 0 + expected.ActiveThread().Registers[7] = 0 + expected.Wakeup = c.address + expected.ExpectPreemption(state) + expected.TraverseRight = c.expectTraverseRight + if c.traverseRight != c.expectTraverseRight { + // If we preempt the current thread and then switch directions, the same + // thread will remain active + expected.ActiveThreadId = state.GetCurrentThread().ThreadId + } + + // State transition + var err error + var stepWitness *mipsevm.StepWitness + stepWitness, err = goVm.Step(true) + require.NoError(t, err) + + // Validate post-state + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) + }) + } +} + +func TestEVM_SysFutex_UnsupportedOp(t *testing.T) { + var tracer *tracing.Hooks + + // From: https://github.com/torvalds/linux/blob/5be63fc19fcaa4c236b307420483578a56986a37/include/uapi/linux/futex.h + const FUTEX_PRIVATE_FLAG = 128 + const FUTEX_WAIT = 0 + const FUTEX_WAKE = 1 + const FUTEX_FD = 2 + const FUTEX_REQUEUE = 3 + const FUTEX_CMP_REQUEUE = 4 + const FUTEX_WAKE_OP = 5 + const FUTEX_LOCK_PI = 6 + const FUTEX_UNLOCK_PI = 7 + const FUTEX_TRYLOCK_PI = 8 + const FUTEX_WAIT_BITSET = 9 + const FUTEX_WAKE_BITSET = 10 + const FUTEX_WAIT_REQUEUE_PI = 11 + const FUTEX_CMP_REQUEUE_PI = 12 + const FUTEX_LOCK_PI2 = 13 + + unsupportedFutexOps := map[string]uint32{ + "FUTEX_WAIT": FUTEX_WAIT, + "FUTEX_WAKE": FUTEX_WAKE, + "FUTEX_FD": FUTEX_FD, + "FUTEX_REQUEUE": FUTEX_REQUEUE, + "FUTEX_CMP_REQUEUE": FUTEX_CMP_REQUEUE, + "FUTEX_WAKE_OP": FUTEX_WAKE_OP, + "FUTEX_LOCK_PI": FUTEX_LOCK_PI, + "FUTEX_UNLOCK_PI": FUTEX_UNLOCK_PI, + "FUTEX_TRYLOCK_PI": FUTEX_TRYLOCK_PI, + "FUTEX_WAIT_BITSET": FUTEX_WAIT_BITSET, + "FUTEX_WAKE_BITSET": FUTEX_WAKE_BITSET, + "FUTEX_WAIT_REQUEUE_PI": FUTEX_WAIT_REQUEUE_PI, + "FUTEX_CMP_REQUEUE_PI": FUTEX_CMP_REQUEUE_PI, + "FUTEX_LOCK_PI2": FUTEX_LOCK_PI2, + "FUTEX_REQUEUE_PRIVATE": (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG), + "FUTEX_CMP_REQUEUE_PRIVATE": (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG), + "FUTEX_WAKE_OP_PRIVATE": (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG), + "FUTEX_LOCK_PI_PRIVATE": (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG), + "FUTEX_LOCK_PI2_PRIVATE": (FUTEX_LOCK_PI2 | FUTEX_PRIVATE_FLAG), + "FUTEX_UNLOCK_PI_PRIVATE": (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG), + "FUTEX_TRYLOCK_PI_PRIVATE": (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG), + "FUTEX_WAIT_BITSET_PRIVATE": (FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG), + "FUTEX_WAKE_BITSET_PRIVATE": (FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG), + "FUTEX_WAIT_REQUEUE_PI_PRIVATE": (FUTEX_WAIT_REQUEUE_PI | FUTEX_PRIVATE_FLAG), + "FUTEX_CMP_REQUEUE_PI_PRIVATE": (FUTEX_CMP_REQUEUE_PI | FUTEX_PRIVATE_FLAG), + } + + for name, op := range unsupportedFutexOps { + t.Run(name, func(t *testing.T) { + goVm, state, contracts := setup(t, int(op)) + step := state.GetStep() + + state.Memory.SetMemory(state.GetPC(), syscallInsn) + state.GetRegistersRef()[2] = exec.SysFutex // Set syscall number + state.GetRegistersRef()[5] = op + + // Setup expectations + expected := mttestutil.NewExpectedMTState(state) + expected.Step += 1 + expected.StepsSinceLastContextSwitch += 1 + expected.ActiveThread().PC = state.GetCpu().NextPC + expected.ActiveThread().NextPC = state.GetCpu().NextPC + 4 + expected.ActiveThread().Registers[2] = exec.SysErrorSignal + expected.ActiveThread().Registers[7] = exec.MipsEINVAL + + // State transition + var err error + var stepWitness *mipsevm.StepWitness + stepWitness, err = goVm.Step(true) + require.NoError(t, err) + + // Validate post-state + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) + }) + } +} + +func TestEVM_SysYield(t *testing.T) { + runPreemptSyscall(t, "SysSchedYield", exec.SysSchedYield) +} + +func TestEVM_SysNanosleep(t *testing.T) { + runPreemptSyscall(t, "SysNanosleep", exec.SysNanosleep) +} + +func runPreemptSyscall(t *testing.T, syscallName string, syscallNum uint32) { + var tracer *tracing.Hooks + cases := []struct { + name string + traverseRight bool + activeThreads int + inactiveThreads int + }{ + {name: "Last active thread", activeThreads: 1, inactiveThreads: 2}, + {name: "Only thread", activeThreads: 1, inactiveThreads: 0}, + {name: "Do not change directions", activeThreads: 2, inactiveThreads: 2}, + {name: "Do not change directions", activeThreads: 3, inactiveThreads: 0}, + } + + for i, c := range cases { + for _, traverseRight := range []bool{true, false} { + testName := fmt.Sprintf("%v: %v (traverseRight = %v)", syscallName, c.name, traverseRight) + t.Run(testName, func(t *testing.T) { + goVm, state, contracts := setup(t, i*789) + mttestutil.SetupThreads(int64(i*3259), state, traverseRight, c.activeThreads, c.inactiveThreads) + + state.Memory.SetMemory(state.GetPC(), syscallInsn) + state.GetRegistersRef()[2] = syscallNum // Set syscall number + step := state.Step + + // Set up post-state expectations + expected := mttestutil.NewExpectedMTState(state) + expected.ExpectStep() + expected.ExpectPreemption(state) + expected.PrestateActiveThread().Registers[2] = 0 + expected.PrestateActiveThread().Registers[7] = 0 + + // State transition + var err error + var stepWitness *mipsevm.StepWitness + stepWitness, err = goVm.Step(true) + require.NoError(t, err) + + // Validate post-state + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) + }) + } + } +} + +func TestEVM_SysOpen(t *testing.T) { + var tracer *tracing.Hooks + + goVm, state, contracts := setup(t, 5512) + + state.Memory.SetMemory(state.GetPC(), syscallInsn) + state.GetRegistersRef()[2] = exec.SysOpen // Set syscall number + step := state.Step + + // Set up post-state expectations + expected := mttestutil.NewExpectedMTState(state) + expected.ExpectStep() + expected.ActiveThread().Registers[2] = exec.SysErrorSignal + expected.ActiveThread().Registers[7] = exec.MipsEBADF + + // State transition + var err error + var stepWitness *mipsevm.StepWitness + stepWitness, err = goVm.Step(true) + require.NoError(t, err) + + // Validate post-state + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) +} + +var NoopSyscalls = map[string]uint32{ + "SysGetAffinity": 4240, + "SysMadvise": 4218, + "SysRtSigprocmask": 4195, + "SysSigaltstack": 4206, + "SysRtSigaction": 4194, + "SysPrlimit64": 4338, + "SysClose": 4006, + "SysPread64": 4200, + "SysFstat64": 4215, + "SysOpenAt": 4288, + "SysReadlink": 4085, + "SysReadlinkAt": 4298, + "SysIoctl": 4054, + "SysEpollCreate1": 4326, + "SysPipe2": 4328, + "SysEpollCtl": 4249, + "SysEpollPwait": 4313, + "SysGetRandom": 4353, + "SysUname": 4122, + "SysStat64": 4213, + "SysGetuid": 4024, + "SysGetgid": 4047, + "SysLlseek": 4140, + "SysMinCore": 4217, + "SysTgkill": 4266, + "SysMunmap": 4091, + "SysSetITimer": 4104, + "SysTimerCreate": 4257, + "SysTimerSetTime": 4258, + "SysTimerDelete": 4261, + "SysClockGetTime": 4263, +} + +func TestEVM_NoopSyscall(t *testing.T) { + var tracer *tracing.Hooks + for noopName, noopVal := range NoopSyscalls { + t.Run(noopName, func(t *testing.T) { + goVm, state, contracts := setup(t, int(noopVal)) + + state.Memory.SetMemory(state.GetPC(), syscallInsn) + state.GetRegistersRef()[2] = noopVal // Set syscall number + step := state.Step + + // Set up post-state expectations + expected := mttestutil.NewExpectedMTState(state) + expected.ExpectStep() + expected.ActiveThread().Registers[2] = 0 + expected.ActiveThread().Registers[7] = 0 + + // State transition + var err error + var stepWitness *mipsevm.StepWitness + stepWitness, err = goVm.Step(true) + require.NoError(t, err) + + // Validate post-state + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) + }) + + } +} + +func TestEVM_UnsupportedSyscall(t *testing.T) { + var tracer *tracing.Hooks + + var NoopSyscallNums = maps.Values(NoopSyscalls) + var SupportedSyscalls = []uint32{exec.SysMmap, exec.SysBrk, exec.SysClone, exec.SysExitGroup, exec.SysRead, exec.SysWrite, exec.SysFcntl, exec.SysExit, exec.SysSchedYield, exec.SysGetTID, exec.SysFutex, exec.SysOpen, exec.SysNanosleep} + unsupportedSyscalls := make([]uint32, 0, 400) + for i := 4000; i < 4400; i++ { + candidate := uint32(i) + if slices.Contains(SupportedSyscalls, candidate) || slices.Contains(NoopSyscallNums, candidate) { + continue + } + unsupportedSyscalls = append(unsupportedSyscalls, candidate) + } + + for i, syscallNum := range unsupportedSyscalls { + testName := fmt.Sprintf("Unsupported syscallNum %v", syscallNum) + t.Run(testName, func(t *testing.T) { + goVm, state, contracts := setup(t, i*3434) + // Setup basic getThreadId syscall instruction + state.Memory.SetMemory(state.GetPC(), syscallInsn) + state.GetRegistersRef()[2] = syscallNum + + // Set up post-state expectations + require.Panics(t, func() { _, _ = goVm.Step(true) }) + testutil.AssertEVMReverts(t, state, contracts, tracer) + }) + } +} + +func TestEVM_NormalTraversalStep_HandleWaitingThread(t *testing.T) { + var tracer *tracing.Hooks + cases := []struct { + name string + step uint64 + activeStackSize int + otherStackSize int + futexAddr uint32 + targetValue uint32 + actualValue uint32 + timeoutStep uint64 + shouldWakeup bool + shouldTimeout bool + }{ + {name: "Preempt, no timeout #1", step: 100, activeStackSize: 1, otherStackSize: 0, futexAddr: 0x100, targetValue: 0x01, actualValue: 0x01, timeoutStep: exec.FutexNoTimeout}, + {name: "Preempt, no timeout #2", step: 100, activeStackSize: 1, otherStackSize: 1, futexAddr: 0x100, targetValue: 0x01, actualValue: 0x01, timeoutStep: exec.FutexNoTimeout}, + {name: "Preempt, no timeout #3", step: 100, activeStackSize: 2, otherStackSize: 1, futexAddr: 0x100, targetValue: 0x01, actualValue: 0x01, timeoutStep: exec.FutexNoTimeout}, + {name: "Preempt, with timeout #1", step: 100, activeStackSize: 2, otherStackSize: 1, futexAddr: 0x100, targetValue: 0x01, actualValue: 0x01, timeoutStep: 101}, + {name: "Preempt, with timeout #2", step: 100, activeStackSize: 1, otherStackSize: 1, futexAddr: 0x100, targetValue: 0x01, actualValue: 0x01, timeoutStep: 150}, + {name: "Wakeup, no timeout #1", step: 100, activeStackSize: 1, otherStackSize: 0, futexAddr: 0x100, targetValue: 0x01, actualValue: 0x02, timeoutStep: exec.FutexNoTimeout, shouldWakeup: true}, + {name: "Wakeup, no timeout #2", step: 100, activeStackSize: 2, otherStackSize: 1, futexAddr: 0x100, targetValue: 0x01, actualValue: 0x02, timeoutStep: exec.FutexNoTimeout, shouldWakeup: true}, + {name: "Wakeup with timeout #1", step: 100, activeStackSize: 2, otherStackSize: 1, futexAddr: 0x100, targetValue: 0x01, actualValue: 0x02, timeoutStep: 100, shouldWakeup: true, shouldTimeout: true}, + {name: "Wakeup with timeout #2", step: 100, activeStackSize: 2, otherStackSize: 1, futexAddr: 0x100, targetValue: 0x02, actualValue: 0x02, timeoutStep: 100, shouldWakeup: true, shouldTimeout: true}, + {name: "Wakeup with timeout #3", step: 100, activeStackSize: 2, otherStackSize: 1, futexAddr: 0x100, targetValue: 0x02, actualValue: 0x02, timeoutStep: 50, shouldWakeup: true, shouldTimeout: true}, + } + + for _, c := range cases { + for i, traverseRight := range []bool{true, false} { + testName := fmt.Sprintf("%v (traverseRight=%v)", c.name, traverseRight) + t.Run(testName, func(t *testing.T) { + // Sanity check + if !c.shouldWakeup && c.shouldTimeout { + require.Fail(t, "Invalid test case - cannot expect a timeout with no wakeup") + } + + goVm, state, contracts := setup(t, i) + mttestutil.SetupThreads(int64(i*101), state, traverseRight, c.activeStackSize, c.otherStackSize) + state.Step = c.step + + activeThread := state.GetCurrentThread() + activeThread.FutexAddr = c.futexAddr + activeThread.FutexVal = c.targetValue + activeThread.FutexTimeoutStep = c.timeoutStep + state.GetMemory().SetMemory(c.futexAddr, c.actualValue) + + // Set up post-state expectations + expected := mttestutil.NewExpectedMTState(state) + expected.Step += 1 + if c.shouldWakeup { + expected.ActiveThread().FutexAddr = exec.FutexEmptyAddr + expected.ActiveThread().FutexVal = 0 + expected.ActiveThread().FutexTimeoutStep = 0 + // PC and return registers are updated onWaitComplete + expected.ActiveThread().PC = state.GetCpu().NextPC + expected.ActiveThread().NextPC = state.GetCpu().NextPC + 4 + if c.shouldTimeout { + expected.ActiveThread().Registers[2] = exec.SysErrorSignal + expected.ActiveThread().Registers[7] = exec.MipsETIMEDOUT + } else { + expected.ActiveThread().Registers[2] = 0 + expected.ActiveThread().Registers[7] = 0 + } + } else { + expected.ExpectPreemption(state) + } + + // State transition + var err error + var stepWitness *mipsevm.StepWitness + stepWitness, err = goVm.Step(true) + require.NoError(t, err) + + // Validate post-state + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, c.step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) + }) + + } + } +} + +func TestEVM_NormalTraversal_Full(t *testing.T) { + var tracer *tracing.Hooks + cases := []struct { + name string + threadCount int + }{ + {"1 thread", 1}, + {"2 threads", 2}, + {"3 threads", 3}, + } + + for i, c := range cases { + for _, traverseRight := range []bool{true, false} { + testName := fmt.Sprintf("%v (traverseRight = %v)", c.name, traverseRight) + t.Run(testName, func(t *testing.T) { + // Setup + goVm, state, contracts := setup(t, i*789) + mttestutil.SetupThreads(int64(i*2947), state, traverseRight, c.threadCount, 0) + // Put threads into a waiting state so that we just traverse through them + for _, thread := range mttestutil.GetAllThreads(state) { + thread.FutexAddr = 0x04 + thread.FutexTimeoutStep = exec.FutexNoTimeout + } + step := state.Step + + initialState := mttestutil.NewExpectedMTState(state) + + // Loop through all the threads to get back to the starting state + iterations := c.threadCount * 2 + for i := 0; i < iterations; i++ { + // Set up post-state expectations + expected := mttestutil.NewExpectedMTState(state) + expected.Step += 1 + expected.ExpectPreemption(state) + + // State transition + var err error + var stepWitness *mipsevm.StepWitness + stepWitness, err = goVm.Step(true) + require.NoError(t, err) + + // Validate post-state + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) + } + + // We should be back to the original state with only a few modifications + initialState.Step += uint64(iterations) + initialState.StepsSinceLastContextSwitch = 0 + initialState.Validate(t, state) + }) + } + } +} + +func TestEVM_WakeupTraversalStep(t *testing.T) { + wakeupAddr := uint32(0x1234) + wakeupVal := uint32(0x999) + var tracer *tracing.Hooks + cases := []struct { + name string + futexAddr uint32 + targetVal uint32 + traverseRight bool + activeStackSize int + otherStackSize int + shouldClearWakeup bool + shouldPreempt bool + }{ + {name: "Matching addr, not wakeable, first thread", futexAddr: wakeupAddr, targetVal: wakeupVal, traverseRight: false, activeStackSize: 3, otherStackSize: 0, shouldClearWakeup: true}, + {name: "Matching addr, wakeable, first thread", futexAddr: wakeupAddr, targetVal: wakeupVal + 1, traverseRight: false, activeStackSize: 3, otherStackSize: 0, shouldClearWakeup: true}, + {name: "Matching addr, not wakeable, last thread", futexAddr: wakeupAddr, targetVal: wakeupVal, traverseRight: true, activeStackSize: 1, otherStackSize: 2, shouldClearWakeup: true}, + {name: "Matching addr, wakeable, last thread", futexAddr: wakeupAddr, targetVal: wakeupVal + 1, traverseRight: true, activeStackSize: 1, otherStackSize: 2, shouldClearWakeup: true}, + {name: "Matching addr, not wakeable, intermediate thread", futexAddr: wakeupAddr, targetVal: wakeupVal, traverseRight: false, activeStackSize: 2, otherStackSize: 2, shouldClearWakeup: true}, + {name: "Matching addr, wakeable, intermediate thread", futexAddr: wakeupAddr, targetVal: wakeupVal + 1, traverseRight: true, activeStackSize: 2, otherStackSize: 2, shouldClearWakeup: true}, + {name: "Mismatched addr, last thread", futexAddr: wakeupAddr + 4, traverseRight: true, activeStackSize: 1, otherStackSize: 2, shouldPreempt: true, shouldClearWakeup: true}, + {name: "Mismatched addr", futexAddr: wakeupAddr + 4, traverseRight: true, activeStackSize: 2, otherStackSize: 2, shouldPreempt: true}, + {name: "Mismatched addr", futexAddr: wakeupAddr + 4, traverseRight: false, activeStackSize: 2, otherStackSize: 0, shouldPreempt: true}, + {name: "Mismatched addr", futexAddr: wakeupAddr + 4, traverseRight: false, activeStackSize: 1, otherStackSize: 0, shouldPreempt: true}, + {name: "Non-waiting thread", futexAddr: exec.FutexEmptyAddr, traverseRight: false, activeStackSize: 1, otherStackSize: 0, shouldPreempt: true}, + {name: "Non-waiting thread", futexAddr: exec.FutexEmptyAddr, traverseRight: true, activeStackSize: 2, otherStackSize: 1, shouldPreempt: true}, + {name: "Non-waiting thread, last thread", futexAddr: exec.FutexEmptyAddr, traverseRight: true, activeStackSize: 1, otherStackSize: 1, shouldPreempt: true, shouldClearWakeup: true}, + } + + for i, c := range cases { + t.Run(c.name, func(t *testing.T) { + goVm, state, contracts := setup(t, i*2000) + mttestutil.SetupThreads(int64(i*101), state, c.traverseRight, c.activeStackSize, c.otherStackSize) + step := state.Step + + state.Wakeup = wakeupAddr + state.GetMemory().SetMemory(wakeupAddr, wakeupVal) + activeThread := state.GetCurrentThread() + activeThread.FutexAddr = c.futexAddr + activeThread.FutexVal = c.targetVal + activeThread.FutexTimeoutStep = exec.FutexNoTimeout + + // Set up post-state expectations + expected := mttestutil.NewExpectedMTState(state) + expected.Step += 1 + if c.shouldClearWakeup { + expected.Wakeup = exec.FutexEmptyAddr + } + if c.shouldPreempt { + // Just preempt the current thread + expected.ExpectPreemption(state) + } + + // State transition + var err error + var stepWitness *mipsevm.StepWitness + stepWitness, err = goVm.Step(true) + require.NoError(t, err) + + // Validate post-state + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) + }) + } +} + +func TestEVM_WakeupTraversal_Full(t *testing.T) { + var tracer *tracing.Hooks + cases := []struct { + name string + threadCount int + }{ + {"1 thread", 1}, + {"2 threads", 2}, + {"3 threads", 3}, + } + for i, c := range cases { + t.Run(c.name, func(t *testing.T) { + // Setup + goVm, state, contracts := setup(t, i*789) + mttestutil.SetupThreads(int64(i*2947), state, false, c.threadCount, 0) + state.Wakeup = 0x08 + step := state.Step + + initialState := mttestutil.NewExpectedMTState(state) + + // Loop through all the threads to get back to the starting state + iterations := c.threadCount * 2 + for i := 0; i < iterations; i++ { + // Set up post-state expectations + expected := mttestutil.NewExpectedMTState(state) + expected.Step += 1 + expected.ExpectPreemption(state) + + // State transition + var err error + var stepWitness *mipsevm.StepWitness + stepWitness, err = goVm.Step(true) + require.NoError(t, err) + + // We should clear the wakeup on the last step + if i == iterations-1 { + expected.Wakeup = exec.FutexEmptyAddr + } + + // Validate post-state + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) + } + + // We should be back to the original state with only a few modifications + initialState.Step += uint64(iterations) + initialState.StepsSinceLastContextSwitch = 0 + initialState.Wakeup = exec.FutexEmptyAddr + initialState.Validate(t, state) + }) + } +} + +func TestEVM_SchedQuantumThreshold(t *testing.T) { + var tracer *tracing.Hooks + cases := []struct { + name string + stepsSinceLastContextSwitch uint64 + shouldPreempt bool + }{ + {name: "just under threshold", stepsSinceLastContextSwitch: exec.SchedQuantum - 1}, + {name: "at threshold", stepsSinceLastContextSwitch: exec.SchedQuantum, shouldPreempt: true}, + {name: "beyond threshold", stepsSinceLastContextSwitch: exec.SchedQuantum + 1, shouldPreempt: true}, + } + + for i, c := range cases { + t.Run(c.name, func(t *testing.T) { + goVm, state, contracts := setup(t, i*789) + // Setup basic getThreadId syscall instruction + state.Memory.SetMemory(state.GetPC(), syscallInsn) + state.GetRegistersRef()[2] = exec.SysGetTID // Set syscall number + state.StepsSinceLastContextSwitch = c.stepsSinceLastContextSwitch + step := state.Step + + // Set up post-state expectations + expected := mttestutil.NewExpectedMTState(state) + if c.shouldPreempt { + expected.Step += 1 + expected.ExpectPreemption(state) + } else { + // Otherwise just expect a normal step + expected.ExpectStep() + expected.ActiveThread().Registers[2] = state.GetCurrentThread().ThreadId + expected.ActiveThread().Registers[7] = 0 + } + + // State transition + var err error + var stepWitness *mipsevm.StepWitness + stepWitness, err = goVm.Step(true) + require.NoError(t, err) + + // Validate post-state + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) + }) + } +} + +func setup(t require.TestingT, randomSeed int) (mipsevm.FPVM, *multithreaded.State, *testutil.ContractMetadata) { + v := GetMultiThreadedTestCase(t) + vm := v.VMFactory(nil, os.Stdout, os.Stderr, testutil.CreateLogger(), testutil.WithRandomization(int64(randomSeed))) + state := mttestutil.GetMtState(t, vm) + + return vm, state, v.Contracts + +} diff --git a/cannon/mipsevm/tests/fuzz_evm_common_test.go b/cannon/mipsevm/tests/fuzz_evm_common_test.go index e96aa54d0aa4..2f68706b60d3 100644 --- a/cannon/mipsevm/tests/fuzz_evm_common_test.go +++ b/cannon/mipsevm/tests/fuzz_evm_common_test.go @@ -6,7 +6,6 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/require" @@ -30,7 +29,7 @@ func FuzzStateSyscallBrk(f *testing.F) { state.GetMemory().SetMemory(state.GetPC(), syscallInsn) step := state.GetStep() - expected := testutil.CreateExpectedState(state) + expected := testutil.NewExpectedState(state) expected.Step += 1 expected.PC = state.GetCpu().NextPC expected.NextPC = state.GetCpu().NextPC + 4 @@ -42,12 +41,7 @@ func FuzzStateSyscallBrk(f *testing.F) { require.False(t, stepWitness.HasPreimage()) expected.Validate(t, state) - - evm := testutil.NewMIPSEVM(v.Contracts) - evmPost := evm.Step(t, stepWitness, step, v.StateHashFn) - goPost, _ := goVm.GetState().EncodeWitness() - require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), - "mipsevm produced different state than EVM") + testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, nil) }) } }) @@ -74,7 +68,7 @@ func FuzzStateSyscallMmap(f *testing.F) { state.GetRegistersRef()[5] = siz state.GetMemory().SetMemory(state.GetPC(), syscallInsn) - expected := testutil.CreateExpectedState(state) + expected := testutil.NewExpectedState(state) expected.Step += 1 expected.PC = state.GetCpu().NextPC expected.NextPC = state.GetCpu().NextPC + 4 @@ -102,12 +96,7 @@ func FuzzStateSyscallMmap(f *testing.F) { require.False(t, stepWitness.HasPreimage()) expected.Validate(t, state) - - evm := testutil.NewMIPSEVM(v.Contracts) - evmPost := evm.Step(t, stepWitness, step, v.StateHashFn) - goPost, _ := goVm.GetState().EncodeWitness() - require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), - "mipsevm produced different state than EVM") + testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, nil) }) } }) @@ -126,7 +115,7 @@ func FuzzStateSyscallExitGroup(f *testing.F) { state.GetMemory().SetMemory(state.GetPC(), syscallInsn) step := state.GetStep() - expected := testutil.CreateExpectedState(state) + expected := testutil.NewExpectedState(state) expected.Step += 1 expected.Exited = true expected.ExitCode = exitCode @@ -136,12 +125,7 @@ func FuzzStateSyscallExitGroup(f *testing.F) { require.False(t, stepWitness.HasPreimage()) expected.Validate(t, state) - - evm := testutil.NewMIPSEVM(v.Contracts) - evmPost := evm.Step(t, stepWitness, step, v.StateHashFn) - goPost, _ := goVm.GetState().EncodeWitness() - require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), - "mipsevm produced different state than EVM") + testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, nil) }) } }) @@ -161,7 +145,7 @@ func FuzzStateSyscallFcntl(f *testing.F) { state.GetMemory().SetMemory(state.GetPC(), syscallInsn) step := state.GetStep() - expected := testutil.CreateExpectedState(state) + expected := testutil.NewExpectedState(state) expected.Step += 1 expected.PC = state.GetCpu().NextPC expected.NextPC = state.GetCpu().NextPC + 4 @@ -187,12 +171,7 @@ func FuzzStateSyscallFcntl(f *testing.F) { require.False(t, stepWitness.HasPreimage()) expected.Validate(t, state) - - evm := testutil.NewMIPSEVM(v.Contracts) - evmPost := evm.Step(t, stepWitness, step, v.StateHashFn) - goPost, _ := goVm.GetState().EncodeWitness() - require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), - "mipsevm produced different state than EVM") + testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, nil) }) } }) @@ -217,7 +196,7 @@ func FuzzStateHintRead(f *testing.F) { state.GetMemory().SetMemory(state.GetPC(), syscallInsn) step := state.GetStep() - expected := testutil.CreateExpectedState(state) + expected := testutil.NewExpectedState(state) expected.Step += 1 expected.PC = state.GetCpu().NextPC expected.NextPC = state.GetCpu().NextPC + 4 @@ -229,12 +208,7 @@ func FuzzStateHintRead(f *testing.F) { require.False(t, stepWitness.HasPreimage()) expected.Validate(t, state) - - evm := testutil.NewMIPSEVM(v.Contracts) - evmPost := evm.Step(t, stepWitness, step, v.StateHashFn) - goPost, _ := goVm.GetState().EncodeWitness() - require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), - "mipsevm produced different state than EVM") + testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, nil) }) } }) @@ -273,7 +247,7 @@ func FuzzStatePreimageRead(f *testing.F) { writeLen = preimageDataLen - preimageOffset } - expected := testutil.CreateExpectedState(state) + expected := testutil.NewExpectedState(state) expected.Step += 1 expected.PC = state.GetCpu().NextPC expected.NextPC = state.GetCpu().NextPC + 4 @@ -292,12 +266,7 @@ func FuzzStatePreimageRead(f *testing.F) { // modify memory - it's possible we just write the leading zero bytes of the length prefix require.Equal(t, expected.MemoryRoot, common.Hash(state.GetMemory().MerkleRoot())) } - - evm := testutil.NewMIPSEVM(v.Contracts) - evmPost := evm.Step(t, stepWitness, step, v.StateHashFn) - goPost, _ := goVm.GetState().EncodeWitness() - require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), - "mipsevm produced different state than EVM") + testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, nil) }) } }) @@ -329,7 +298,7 @@ func FuzzStateHintWrite(f *testing.F) { // Set instruction state.GetMemory().SetMemory(state.GetPC(), syscallInsn) - expected := testutil.CreateExpectedState(state) + expected := testutil.NewExpectedState(state) expected.Step += 1 expected.PC = state.GetCpu().NextPC expected.NextPC = state.GetCpu().NextPC + 4 @@ -342,12 +311,7 @@ func FuzzStateHintWrite(f *testing.F) { // TODO(cp-983) - validate expected hints expected.Validate(t, state, testutil.SkipHintValidation) - - evm := testutil.NewMIPSEVM(v.Contracts) - evmPost := evm.Step(t, stepWitness, step, v.StateHashFn) - goPost, _ := goVm.GetState().EncodeWitness() - require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), - "mipsevm produced different state than EVM") + testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, nil) }) } }) @@ -377,7 +341,7 @@ func FuzzStatePreimageWrite(f *testing.F) { count = sz } - expected := testutil.CreateExpectedState(state) + expected := testutil.NewExpectedState(state) expected.Step += 1 expected.PC = state.GetCpu().NextPC expected.NextPC = state.GetCpu().NextPC + 4 @@ -391,12 +355,7 @@ func FuzzStatePreimageWrite(f *testing.F) { // TODO(cp-983) - validate preimage key expected.Validate(t, state, testutil.SkipPreimageKeyValidation) - - evm := testutil.NewMIPSEVM(v.Contracts) - evmPost := evm.Step(t, stepWitness, step, v.StateHashFn) - goPost, _ := goVm.GetState().EncodeWitness() - require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), - "mipsevm produced different state than EVM") + testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, nil) }) } }) diff --git a/cannon/mipsevm/tests/fuzz_evm_multithreaded_test.go b/cannon/mipsevm/tests/fuzz_evm_multithreaded_test.go index 2b8224b10725..828f9c558739 100644 --- a/cannon/mipsevm/tests/fuzz_evm_multithreaded_test.go +++ b/cannon/mipsevm/tests/fuzz_evm_multithreaded_test.go @@ -4,44 +4,63 @@ import ( "os" "testing" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/stretchr/testify/require" "github.com/ethereum-optimism/optimism/cannon/mipsevm/exec" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" + mttestutil "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded/testutil" "github.com/ethereum-optimism/optimism/cannon/mipsevm/testutil" ) -// TODO func FuzzStateSyscallCloneMT(f *testing.F) { v := GetMultiThreadedTestCase(f) - // t.Skip is causing linting check to fail, disable for now - //nolint:staticcheck - f.Fuzz(func(t *testing.T, seed int64) { - // TODO(cp-903) Customize test for multi-threaded vm - t.Skip("TODO - customize this test for MTCannon") + f.Fuzz(func(t *testing.T, nextThreadId, stackPtr uint32, seed int64) { goVm := v.VMFactory(nil, os.Stdout, os.Stderr, testutil.CreateLogger(), testutil.WithRandomization(seed)) - state := goVm.GetState() - state.GetRegistersRef()[2] = exec.SysClone + state := mttestutil.GetMtState(t, goVm) + // Update existing threads to avoid collision with nextThreadId + if mttestutil.FindThread(state, nextThreadId) != nil { + for i, t := range mttestutil.GetAllThreads(state) { + t.ThreadId = nextThreadId - uint32(i+1) + } + } + + // Setup + state.NextThreadId = nextThreadId state.GetMemory().SetMemory(state.GetPC(), syscallInsn) + state.GetRegistersRef()[2] = exec.SysClone + state.GetRegistersRef()[4] = exec.ValidCloneFlags + state.GetRegistersRef()[5] = stackPtr step := state.GetStep() - expected := testutil.CreateExpectedState(state) + // Set up expectations + expected := mttestutil.NewExpectedMTState(state) expected.Step += 1 - expected.PC = state.GetCpu().NextPC - expected.NextPC = state.GetCpu().NextPC + 4 - expected.Registers[2] = 0x1 - expected.Registers[7] = 0 + // Set original thread expectations + expected.PrestateActiveThread().PC = state.GetCpu().NextPC + expected.PrestateActiveThread().NextPC = state.GetCpu().NextPC + 4 + expected.PrestateActiveThread().Registers[2] = nextThreadId + expected.PrestateActiveThread().Registers[7] = 0 + // Set expectations for new, cloned thread + expected.ActiveThreadId = nextThreadId + epxectedNewThread := expected.ExpectNewThread() + epxectedNewThread.PC = state.GetCpu().NextPC + epxectedNewThread.NextPC = state.GetCpu().NextPC + 4 + epxectedNewThread.Registers[2] = 0 + epxectedNewThread.Registers[7] = 0 + epxectedNewThread.Registers[29] = stackPtr + expected.NextThreadId = nextThreadId + 1 + expected.StepsSinceLastContextSwitch = 0 + if state.TraverseRight { + expected.RightStackSize += 1 + } else { + expected.LeftStackSize += 1 + } stepWitness, err := goVm.Step(true) require.NoError(t, err) require.False(t, stepWitness.HasPreimage()) expected.Validate(t, state) - - evm := testutil.NewMIPSEVM(v.Contracts) - evmPost := evm.Step(t, stepWitness, step, v.StateHashFn) - goPost, _ := goVm.GetState().EncodeWitness() - require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), - "mipsevm produced different state than EVM") + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), v.Contracts, nil) }) } diff --git a/cannon/mipsevm/tests/fuzz_evm_singlethreaded_test.go b/cannon/mipsevm/tests/fuzz_evm_singlethreaded_test.go index be5c995d352c..cc30c0040196 100644 --- a/cannon/mipsevm/tests/fuzz_evm_singlethreaded_test.go +++ b/cannon/mipsevm/tests/fuzz_evm_singlethreaded_test.go @@ -20,7 +20,7 @@ func FuzzStateSyscallCloneST(f *testing.F) { state.GetMemory().SetMemory(state.GetPC(), syscallInsn) step := state.GetStep() - expected := testutil.CreateExpectedState(state) + expected := testutil.NewExpectedState(state) expected.Step += 1 expected.PC = state.GetCpu().NextPC expected.NextPC = state.GetCpu().NextPC + 4 diff --git a/cannon/mipsevm/testutil/mips.go b/cannon/mipsevm/testutil/mips.go index 39d8fbed0b46..f596e0e4de7b 100644 --- a/cannon/mipsevm/testutil/mips.go +++ b/cannon/mipsevm/testutil/mips.go @@ -9,6 +9,7 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/vm" @@ -151,3 +152,35 @@ func LogStepFailureAtCleanup(t *testing.T, mipsEvm *MIPSEVM) { } }) } + +// ValidateEVM runs a single evm step and validates against an FPVM poststate +func ValidateEVM(t *testing.T, stepWitness *mipsevm.StepWitness, step uint64, goVm mipsevm.FPVM, hashFn mipsevm.HashFn, contracts *ContractMetadata, tracer *tracing.Hooks) { + evm := NewMIPSEVM(contracts) + evm.SetTracer(tracer) + LogStepFailureAtCleanup(t, evm) + + evmPost := evm.Step(t, stepWitness, step, hashFn) + goPost, _ := goVm.GetState().EncodeWitness() + require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), + "mipsevm produced different state than EVM") +} + +// AssertEVMReverts runs a single evm step from an FPVM prestate and asserts that the VM panics +func AssertEVMReverts(t *testing.T, state mipsevm.FPVMState, contracts *ContractMetadata, tracer *tracing.Hooks) { + insnProof := state.GetMemory().MerkleProof(state.GetPC()) + encodedWitness, _ := state.EncodeWitness() + stepWitness := &mipsevm.StepWitness{ + State: encodedWitness, + ProofData: insnProof[:], + } + input := EncodeStepInput(t, stepWitness, mipsevm.LocalContext{}, contracts.Artifacts.MIPS) + startingGas := uint64(30_000_000) + + env, evmState := NewEVMEnv(contracts) + env.Config.Tracer = tracer + sender := common.Address{0x13, 0x37} + _, _, err := env.Call(vm.AccountRef(sender), contracts.Addresses.MIPS, input, startingGas, common.U2560) + require.EqualValues(t, err, vm.ErrExecutionReverted) + logs := evmState.Logs() + require.Equal(t, 0, len(logs)) +} diff --git a/cannon/mipsevm/testutil/rand.go b/cannon/mipsevm/testutil/rand.go new file mode 100644 index 000000000000..2364c7ad5e92 --- /dev/null +++ b/cannon/mipsevm/testutil/rand.go @@ -0,0 +1,53 @@ +package testutil + +import ( + "math/rand" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func RandHash(r *rand.Rand) common.Hash { + var bytes [32]byte + _, err := r.Read(bytes[:]) + if err != nil { + panic(err) + } + return bytes +} + +func RandHint(r *rand.Rand) []byte { + count := r.Intn(10) + + bytes := make([]byte, count) + _, err := r.Read(bytes[:]) + if err != nil { + panic(err) + } + return bytes +} + +func RandRegisters(r *rand.Rand) *[32]uint32 { + registers := new([32]uint32) + for i := 0; i < 32; i++ { + registers[i] = r.Uint32() + } + return registers +} + +func RandomBytes(t require.TestingT, seed int64, length uint32) []byte { + r := rand.New(rand.NewSource(seed)) + randBytes := make([]byte, length) + if _, err := r.Read(randBytes); err != nil { + require.NoError(t, err) + } + return randBytes +} + +func RandPC(r *rand.Rand) uint32 { + return AlignPC(r.Uint32()) +} + +func RandStep(r *rand.Rand) uint64 { + return BoundStep(r.Uint64()) +} diff --git a/cannon/mipsevm/testutil/state.go b/cannon/mipsevm/testutil/state.go index da0c9d1657ee..3b912c8dd067 100644 --- a/cannon/mipsevm/testutil/state.go +++ b/cannon/mipsevm/testutil/state.go @@ -2,7 +2,6 @@ package testutil import ( "fmt" - "math/rand" "slices" "testing" @@ -31,7 +30,7 @@ type StateMutator interface { SetExited(val bool) SetStep(val uint64) SetLastHint(val hexutil.Bytes) - GetRegistersRef() *[32]uint32 + Randomize(randSeed int64) } type StateOption func(state StateMutator) @@ -80,36 +79,26 @@ func WithStep(step uint64) StateOption { func WithRandomization(seed int64) StateOption { return func(mut StateMutator) { - RandomizeState(seed, mut) + mut.Randomize(seed) } } -func RandomizeState(seed int64, mut StateMutator) { - r := rand.New(rand.NewSource(seed)) - +func AlignPC(pc uint32) uint32 { // Memory-align random pc and leave room for nextPC - pc := r.Uint32() & 0xFF_FF_FF_FC // Align address + pc = pc & 0xFF_FF_FF_FC // Align address if pc >= 0xFF_FF_FF_FC { // Leave room to set and then increment nextPC pc = 0xFF_FF_FF_FC - 8 } + return pc +} - // Set random step, but leave room to increment - step := r.Uint64() +func BoundStep(step uint64) uint64 { + // Leave room to increment step at least once if step == ^uint64(0) { step -= 1 } - - mut.SetPreimageKey(randHash(r)) - mut.SetPreimageOffset(r.Uint32()) - mut.SetPC(pc) - mut.SetNextPC(pc + 4) - mut.SetHI(r.Uint32()) - mut.SetLO(r.Uint32()) - mut.SetHeap(r.Uint32()) - mut.SetStep(step) - mut.SetLastHint(randHint(r)) - *mut.GetRegistersRef() = *randRegisters(r) + return step } type ExpectedState struct { @@ -128,7 +117,7 @@ type ExpectedState struct { MemoryRoot common.Hash } -func CreateExpectedState(fromState mipsevm.FPVMState) *ExpectedState { +func NewExpectedState(fromState mipsevm.FPVMState) *ExpectedState { return &ExpectedState{ PreimageKey: fromState.GetPreimageKey(), PreimageOffset: fromState.GetPreimageOffset(), @@ -176,40 +165,3 @@ func (e *ExpectedState) Validate(t testing.TB, actualState mipsevm.FPVMState, fl require.Equal(t, e.MemoryRoot, common.Hash(actualState.GetMemory().MerkleRoot()), fmt.Sprintf("Expect memory root = %v", e.MemoryRoot)) } } - -func randHash(r *rand.Rand) common.Hash { - var bytes [32]byte - _, err := r.Read(bytes[:]) - if err != nil { - panic(err) - } - return bytes -} - -func randHint(r *rand.Rand) []byte { - count := r.Intn(10) - - bytes := make([]byte, count) - _, err := r.Read(bytes[:]) - if err != nil { - panic(err) - } - return bytes -} - -func randRegisters(r *rand.Rand) *[32]uint32 { - registers := new([32]uint32) - for i := 0; i < 32; i++ { - registers[i] = r.Uint32() - } - return registers -} - -func RandomBytes(t require.TestingT, seed int64, length uint32) []byte { - r := rand.New(rand.NewSource(seed)) - randBytes := make([]byte, length) - if _, err := r.Read(randBytes); err != nil { - require.NoError(t, err) - } - return randBytes -} diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index c9fe50d36c6e..59def1ae86cf 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -148,8 +148,8 @@ "sourceCodeHash": "0xb6e219e8c2d81d75c48a1459907609e9096fe032a7447c88cd3e0d134752ac8e" }, "src/cannon/MIPS2.sol": { - "initCodeHash": "0xbb425bd1c3cad13a77f5c9676b577606e2f8f320687739f529b257a042f58d85", - "sourceCodeHash": "0xe66f19942947f53ccd658b94c1ef6db39e947419d4ec7436067c6cc44452ff73" + "initCodeHash": "0x36b7c32cf9eba05e6db44910a25c800b801c075f8e053eca9515c6e0e4d8a902", + "sourceCodeHash": "0xa307c44a2d67bc84e75f4b7341345ed236da2e63c1f3f442416f14cd262126bf" }, "src/cannon/PreimageOracle.sol": { "initCodeHash": "0xce7a1c3265e457a05d17b6d1a2ef93c4639caac3733c9cf88bfd192eae2c5788", diff --git a/packages/contracts-bedrock/src/cannon/MIPS2.sol b/packages/contracts-bedrock/src/cannon/MIPS2.sol index 142af042b99a..a1bcea86edb8 100644 --- a/packages/contracts-bedrock/src/cannon/MIPS2.sol +++ b/packages/contracts-bedrock/src/cannon/MIPS2.sol @@ -51,8 +51,8 @@ contract MIPS2 is ISemver { } /// @notice The semantic version of the MIPS2 contract. - /// @custom:semver 1.0.0-beta.4 - string public constant version = "1.0.0-beta.4"; + /// @custom:semver 1.0.0-beta.5 + string public constant version = "1.0.0-beta.5"; /// @notice The preimage oracle contract. IPreimageOracle internal immutable ORACLE; @@ -202,7 +202,7 @@ contract MIPS2 is ISemver { } } - if (state.stepsSinceLastContextSwitch == sys.SCHED_QUANTUM) { + if (state.stepsSinceLastContextSwitch >= sys.SCHED_QUANTUM) { preemptThread(state, thread); return outputState(); } @@ -338,7 +338,6 @@ contract MIPS2 is ISemver { } else if (syscall_no == sys.SYS_FUTEX) { // args: a0 = addr, a1 = op, a2 = val, a3 = timeout if (a1 == sys.FUTEX_WAIT_PRIVATE) { - thread.futexAddr = a0; uint32 mem = MIPSMemory.readMem( state.memRoot, a0 & 0xFFffFFfc, MIPSMemory.memoryProofOffset(MEM_PROOF_OFFSET, 1) ); @@ -346,6 +345,7 @@ contract MIPS2 is ISemver { v0 = sys.SYS_ERROR_SIGNAL; v1 = sys.EAGAIN; } else { + thread.futexAddr = a0; thread.futexVal = a2; thread.futexTimeoutStep = a3 == 0 ? sys.FUTEX_NO_TIMEOUT : state.step + sys.FUTEX_TIMEOUT_STEPS; // Leave cpu scalars as-is. This instruction will be completed by `onWaitComplete` @@ -381,9 +381,9 @@ contract MIPS2 is ISemver { } else if (syscall_no == sys.SYS_OPEN) { v0 = sys.SYS_ERROR_SIGNAL; v1 = sys.EBADF; - } else if (syscall_no == sys.SYS_CLOCK_GETTIME) { + } else if (syscall_no == sys.SYS_MUNMAP) { // ignored - } else if (syscall_no == sys.SYS_GET_AFFINITY) { + } else if (syscall_no == sys.SYS_GETAFFINITY) { // ignored } else if (syscall_no == sys.SYS_MADVISE) { // ignored @@ -443,8 +443,6 @@ contract MIPS2 is ISemver { // ignored } else if (syscall_no == sys.SYS_CLOCKGETTIME) { // ignored - } else if (syscall_no == sys.SYS_MUNMAP) { - // ignored } else { revert("MIPS2: unimplemented syscall"); } diff --git a/packages/contracts-bedrock/src/cannon/libraries/MIPSSyscalls.sol b/packages/contracts-bedrock/src/cannon/libraries/MIPSSyscalls.sol index f12f9b789a23..0576dbc7ae2c 100644 --- a/packages/contracts-bedrock/src/cannon/libraries/MIPSSyscalls.sol +++ b/packages/contracts-bedrock/src/cannon/libraries/MIPSSyscalls.sol @@ -42,8 +42,7 @@ library MIPSSyscalls { uint32 internal constant SYS_OPEN = 4005; uint32 internal constant SYS_NANOSLEEP = 4166; // unused syscalls - uint32 internal constant SYS_CLOCK_GETTIME = 4263; - uint32 internal constant SYS_GET_AFFINITY = 4240; + uint32 internal constant SYS_MUNMAP = 4091; uint32 internal constant SYS_GETAFFINITY = 4240; uint32 internal constant SYS_MADVISE = 4218; uint32 internal constant SYS_RTSIGPROCMASK = 4195; @@ -69,13 +68,13 @@ library MIPSSyscalls { uint32 internal constant SYS_LLSEEK = 4140; uint32 internal constant SYS_MINCORE = 4217; uint32 internal constant SYS_TGKILL = 4266; + // profiling-related syscalls - ignored uint32 internal constant SYS_SETITIMER = 4104; uint32 internal constant SYS_TIMERCREATE = 4257; uint32 internal constant SYS_TIMERSETTIME = 4258; uint32 internal constant SYS_TIMERDELETE = 4261; uint32 internal constant SYS_CLOCKGETTIME = 4263; - uint32 internal constant SYS_MUNMAP = 4091; uint32 internal constant FD_STDIN = 0; uint32 internal constant FD_STDOUT = 1; diff --git a/packages/contracts-bedrock/test/cannon/MIPS2.t.sol b/packages/contracts-bedrock/test/cannon/MIPS2.t.sol index 30d6899caad6..dc377dcea8fa 100644 --- a/packages/contracts-bedrock/test/cannon/MIPS2.t.sol +++ b/packages/contracts-bedrock/test/cannon/MIPS2.t.sol @@ -435,7 +435,7 @@ contract MIPS2_Test is CommonTest { MIPS2.ThreadState memory expectThread = copyThread(thread); expectThread.pc = thread.nextPC; expectThread.nextPC = thread.nextPC + 4; - expectThread.futexAddr = futexAddr; + expectThread.futexAddr = sys.FUTEX_EMPTY_ADDR; expectThread.registers[2] = sys.SYS_ERROR_SIGNAL; expectThread.registers[7] = sys.EAGAIN; // errno threading.replaceCurrent(expectThread); From c7b91ab24fdbe83c43a8e716962186863606cef9 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Fri, 30 Aug 2024 01:55:32 +1000 Subject: [PATCH 005/264] Conductor and sequencer p2p refactoring (#11455) * Shutdown sequencer before stopping p2p * Check p2p isn't also disabled Co-authored-by: Sebastian Stammler * Remove missed time.Sleep * Fix up use of SetupP2P.Disabled * Revert error check after RPC boundary * Add comment about context for StopSequencer * Add Config.p2pEnabled * op-node: Make Config.P2PEnabled public --------- Co-authored-by: Sebastian Stammler --- op-chain-ops/script/console2_gen.go | 1 - op-conductor/conductor/service.go | 36 ++++-- op-e2e/setup.go | 2 +- op-node/node/config.go | 4 + op-node/node/node.go | 62 +++++++--- op-node/p2p/config.go | 1 + op-node/p2p/node.go | 172 ++++++++++++++++------------ 7 files changed, 176 insertions(+), 102 deletions(-) diff --git a/op-chain-ops/script/console2_gen.go b/op-chain-ops/script/console2_gen.go index f8b8aecf7497..0c6dcc44f462 100644 --- a/op-chain-ops/script/console2_gen.go +++ b/op-chain-ops/script/console2_gen.go @@ -1511,4 +1511,3 @@ func (c *ConsolePrecompile) Log_59cfcbe3(p0 *big.Int, p1 *big.Int, p2 *big.Int, func (c *ConsolePrecompile) Log_193fb800(p0 *big.Int, p1 *big.Int, p2 *big.Int, p3 *big.Int) { c.log(p0, p1, p2, p3) } - diff --git a/op-conductor/conductor/service.go b/op-conductor/conductor/service.go index a1ccef871538..2a39193c6bcc 100644 --- a/op-conductor/conductor/service.go +++ b/op-conductor/conductor/service.go @@ -647,9 +647,12 @@ func (oc *OpConductor) action() { oc.log.Debug("exiting action with status and error", "status", status, "err", err) if err != nil { - oc.log.Error("failed to execute step, queueing another one to retry", "err", err, "status", status) - time.Sleep(oc.retryBackoff()) - oc.queueAction() + select { + case <-oc.shutdownCtx.Done(): + case <-time.After(oc.retryBackoff()): + oc.log.Error("failed to execute step, queueing another one to retry", "err", err, "status", status) + oc.queueAction() + } return } @@ -683,18 +686,33 @@ func (oc *OpConductor) transferLeader() error { } func (oc *OpConductor) stopSequencer() error { - oc.log.Info("stopping sequencer", "server", oc.cons.ServerID(), "leader", oc.leader.Load(), "healthy", oc.healthy.Load(), "active", oc.seqActive.Load()) - - _, err := oc.ctrl.StopSequencer(context.Background()) - if err != nil { + oc.log.Info( + "stopping sequencer", + "server", oc.cons.ServerID(), + "leader", oc.leader.Load(), + "healthy", oc.healthy.Load(), + "active", oc.seqActive.Load()) + + // Quoting (@zhwrd): StopSequencer is called after conductor loses leadership. In the event that + // the StopSequencer call fails, it actually has little real consequences because the sequencer + // cant produce a block and gossip / commit it to the raft log (requires leadership). Once + // conductor comes back up it will check its leader and sequencer state and attempt to stop the + // sequencer again. So it is "okay" to fail to stop a sequencer, the state will eventually be + // rectified and we won't have two active sequencers that are actually producing blocks. + // + // To that end we allow to cancel the StopSequencer call if we're shutting down. + latestHead, err := oc.ctrl.StopSequencer(oc.shutdownCtx) + if err == nil { + // None of the consensus state should have changed here so don't log it again. + oc.log.Info("stopped sequencer", "latestHead", latestHead) + } else { if strings.Contains(err.Error(), driver.ErrSequencerAlreadyStopped.Error()) { - oc.log.Warn("sequencer already stopped.", "err", err) + oc.log.Warn("sequencer already stopped", "err", err) } else { return errors.Wrap(err, "failed to stop sequencer") } } oc.metrics.RecordStopSequencer(err == nil) - oc.seqActive.Store(false) return nil } diff --git a/op-e2e/setup.go b/op-e2e/setup.go index c0168b7d207d..cd07e081d0dd 100644 --- a/op-e2e/setup.go +++ b/op-e2e/setup.go @@ -415,7 +415,7 @@ func (sys *System) Close() { } for name, node := range sys.RollupNodes { - if err := node.Stop(postCtx); err != nil && !errors.Is(err, rollupNode.ErrAlreadyClosed) { + if err := node.Stop(postCtx); err != nil && !errors.Is(err, rollupNode.ErrAlreadyClosed) && !errors.Is(err, postCtx.Err()) { combinedErr = errors.Join(combinedErr, fmt.Errorf("stop rollup node %v: %w", name, err)) } } diff --git a/op-node/node/config.go b/op-node/node/config.go index 5ca724d905c6..6b7be8f268fd 100644 --- a/op-node/node/config.go +++ b/op-node/node/config.go @@ -172,3 +172,7 @@ func (cfg *Config) Check() error { } return nil } + +func (cfg *Config) P2PEnabled() bool { + return cfg.P2P != nil && !cfg.P2P.Disabled() +} diff --git a/op-node/node/node.go b/op-node/node/node.go index a4fd3e8db08f..0f174c7a372c 100644 --- a/op-node/node/node.go +++ b/op-node/node/node.go @@ -8,6 +8,8 @@ import ( "sync/atomic" "time" + "github.com/ethereum-optimism/optimism/op-node/rollup/sequencing" + "github.com/hashicorp/go-multierror" "github.com/libp2p/go-libp2p/core/peer" @@ -40,6 +42,8 @@ type closableSafeDB interface { } type OpNode struct { + // Retain the config to test for active features rather than test for runtime state. + cfg *Config log log.Logger appVersion string metrics *metrics.Metrics @@ -93,6 +97,7 @@ func New(ctx context.Context, cfg *Config, log log.Logger, appVersion string, m } n := &OpNode{ + cfg: cfg, log: log, appVersion: appVersion, metrics: m, @@ -134,7 +139,7 @@ func (n *OpNode) init(ctx context.Context, cfg *Config) error { if err := n.initP2PSigner(ctx, cfg); err != nil { return fmt.Errorf("failed to init the P2P signer: %w", err) } - if err := n.initP2P(ctx, cfg); err != nil { + if err := n.initP2P(cfg); err != nil { return fmt.Errorf("failed to init the P2P stack: %w", err) } // Only expose the server at the end, ensuring all RPC backend components are initialized. @@ -407,7 +412,7 @@ func (n *OpNode) initRPCServer(cfg *Config) error { if err != nil { return err } - if n.p2pNode != nil { + if n.p2pEnabled() { server.EnableP2P(p2p.NewP2PAPIBackend(n.p2pNode, n.log, n.metrics)) } if cfg.RPC.EnableAdmin { @@ -454,14 +459,20 @@ func (n *OpNode) initPProf(cfg *Config) error { return nil } -func (n *OpNode) initP2P(ctx context.Context, cfg *Config) error { - if cfg.P2P != nil { +func (n *OpNode) p2pEnabled() bool { + return n.cfg.P2PEnabled() +} + +func (n *OpNode) initP2P(cfg *Config) (err error) { + if n.p2pNode != nil { + panic("p2p node already initialized") + } + if n.p2pEnabled() { // TODO(protocol-quest/97): Use EL Sync instead of CL Alt sync for fetching missing blocks in the payload queue. - p2pNode, err := p2p.NewNodeP2P(n.resourcesCtx, &cfg.Rollup, n.log, cfg.P2P, n, n.l2Source, n.runCfg, n.metrics, false) - if err != nil || p2pNode == nil { - return err + n.p2pNode, err = p2p.NewNodeP2P(n.resourcesCtx, &cfg.Rollup, n.log, cfg.P2P, n, n.l2Source, n.runCfg, n.metrics, false) + if err != nil { + return } - n.p2pNode = p2pNode if n.p2pNode.Dv5Udp() != nil { go n.p2pNode.DiscoveryProcess(n.resourcesCtx, n.log, &cfg.Rollup, cfg.P2P.TargetPeers()) } @@ -469,15 +480,14 @@ func (n *OpNode) initP2P(ctx context.Context, cfg *Config) error { return nil } -func (n *OpNode) initP2PSigner(ctx context.Context, cfg *Config) error { +func (n *OpNode) initP2PSigner(ctx context.Context, cfg *Config) (err error) { // the p2p signer setup is optional if cfg.P2PSigner == nil { - return nil + return } // p2pSigner may still be nil, the signer setup may not create any signer, the signer is optional - var err error n.p2pSigner, err = cfg.P2PSigner.SetupSigner(ctx) - return err + return } func (n *OpNode) Start(ctx context.Context) error { @@ -533,7 +543,7 @@ func (n *OpNode) PublishL2Payload(ctx context.Context, envelope *eth.ExecutionPa n.tracer.OnPublishL2Payload(ctx, envelope) // publish to p2p, if we are running p2p at all - if n.p2pNode != nil { + if n.p2pEnabled() { payload := envelope.ExecutionPayload if n.p2pSigner == nil { return fmt.Errorf("node has no p2p signer, payload %s cannot be published", payload.ID()) @@ -547,7 +557,7 @@ func (n *OpNode) PublishL2Payload(ctx context.Context, envelope *eth.ExecutionPa func (n *OpNode) OnUnsafeL2Payload(ctx context.Context, from peer.ID, envelope *eth.ExecutionPayloadEnvelope) error { // ignore if it's from ourselves - if n.p2pNode != nil && from == n.p2pNode.Host().ID() { + if n.p2pEnabled() && from == n.p2pNode.Host().ID() { return nil } @@ -568,9 +578,13 @@ func (n *OpNode) OnUnsafeL2Payload(ctx context.Context, from peer.ID, envelope * } func (n *OpNode) RequestL2Range(ctx context.Context, start, end eth.L2BlockRef) error { - if n.p2pNode != nil && n.p2pNode.AltSyncEnabled() { + if n.p2pEnabled() && n.p2pNode.AltSyncEnabled() { if unixTimeStale(start.Time, 12*time.Hour) { - n.log.Debug("ignoring request to sync L2 range, timestamp is too old for p2p", "start", start, "end", end, "start_time", start.Time) + n.log.Debug( + "ignoring request to sync L2 range, timestamp is too old for p2p", + "start", start, + "end", end, + "start_time", start.Time) return nil } return n.p2pNode.RequestL2Range(ctx, start, end) @@ -606,10 +620,26 @@ func (n *OpNode) Stop(ctx context.Context) error { result = multierror.Append(result, fmt.Errorf("failed to close RPC server: %w", err)) } } + + // Stop sequencer and report last hash. l2Driver can be nil if we're cleaning up a failed init. + if n.l2Driver != nil { + latestHead, err := n.l2Driver.StopSequencer(ctx) + switch { + case errors.Is(err, sequencing.ErrSequencerNotEnabled): + case errors.Is(err, driver.ErrSequencerAlreadyStopped): + n.log.Info("stopping node: sequencer already stopped", "latestHead", latestHead) + case err == nil: + n.log.Info("stopped sequencer", "latestHead", latestHead) + default: + result = multierror.Append(result, fmt.Errorf("error stopping sequencer: %w", err)) + } + } if n.p2pNode != nil { if err := n.p2pNode.Close(); err != nil { result = multierror.Append(result, fmt.Errorf("failed to close p2p node: %w", err)) } + // Prevent further use of p2p. + n.p2pNode = nil } if n.p2pSigner != nil { if err := n.p2pSigner.Close(); err != nil { diff --git a/op-node/p2p/config.go b/op-node/p2p/config.go index 94b75a95de26..ee21ba20fc39 100644 --- a/op-node/p2p/config.go +++ b/op-node/p2p/config.go @@ -48,6 +48,7 @@ type HostMetrics interface { // SetupP2P provides a host and discovery service for usage in the rollup node. type SetupP2P interface { Check() error + // Looks like this was started to prevent partially inited p2p. Disabled() bool // Host creates a libp2p host service. Returns nil, nil if p2p is disabled. Host(log log.Logger, reporter metrics.Reporter, metrics HostMetrics) (host.Host, error) diff --git a/op-node/p2p/node.go b/op-node/p2p/node.go index 4c88556ddd9c..70f7dbc67c0b 100644 --- a/op-node/p2p/node.go +++ b/op-node/p2p/node.go @@ -52,10 +52,23 @@ type NodeP2P struct { // NewNodeP2P creates a new p2p node, and returns a reference to it. If the p2p is disabled, it returns nil. // If metrics are configured, a bandwidth monitor will be spawned in a goroutine. -func NewNodeP2P(resourcesCtx context.Context, rollupCfg *rollup.Config, log log.Logger, setup SetupP2P, gossipIn GossipIn, l2Chain L2Chain, runCfg GossipRuntimeConfig, metrics metrics.Metricer, elSyncEnabled bool) (*NodeP2P, error) { +func NewNodeP2P( + resourcesCtx context.Context, + rollupCfg *rollup.Config, + log log.Logger, + setup SetupP2P, + gossipIn GossipIn, + l2Chain L2Chain, + runCfg GossipRuntimeConfig, + metrics metrics.Metricer, + elSyncEnabled bool, +) (*NodeP2P, error) { if setup == nil { return nil, errors.New("p2p node cannot be created without setup") } + if setup.Disabled() { + return nil, errors.New("SetupP2P.Disabled is true") + } var n NodeP2P if err := n.init(resourcesCtx, rollupCfg, log, setup, gossipIn, l2Chain, runCfg, metrics, elSyncEnabled); err != nil { closeErr := n.Close() @@ -65,12 +78,24 @@ func NewNodeP2P(resourcesCtx context.Context, rollupCfg *rollup.Config, log log. return nil, err } if n.host == nil { - return nil, nil + // See prior comment about n.host optionality: + // TODO(CLI-4016): host is not optional, NodeP2P as a whole is. + panic("host is not optional if p2p is enabled") } return &n, nil } -func (n *NodeP2P) init(resourcesCtx context.Context, rollupCfg *rollup.Config, log log.Logger, setup SetupP2P, gossipIn GossipIn, l2Chain L2Chain, runCfg GossipRuntimeConfig, metrics metrics.Metricer, elSyncEnabled bool) error { +func (n *NodeP2P) init( + resourcesCtx context.Context, + rollupCfg *rollup.Config, + log log.Logger, + setup SetupP2P, + gossipIn GossipIn, + l2Chain L2Chain, + runCfg GossipRuntimeConfig, + metrics metrics.Metricer, + elSyncEnabled bool, +) error { bwc := p2pmetrics.NewBandwidthCounter() n.log = log @@ -85,86 +110,83 @@ func (n *NodeP2P) init(resourcesCtx context.Context, rollupCfg *rollup.Config, l return fmt.Errorf("failed to start p2p host: %w", err) } - // TODO(CLI-4016): host is not optional, NodeP2P as a whole is. This if statement is wrong - if n.host != nil { - // Enable extra features, if any. During testing we don't setup the most advanced host all the time. - if extra, ok := n.host.(ExtraHostFeatures); ok { - n.gater = extra.ConnectionGater() - n.connMgr = extra.ConnectionManager() - } - eps, ok := n.host.Peerstore().(store.ExtendedPeerstore) - if !ok { - return fmt.Errorf("cannot init without extended peerstore: %w", err) - } - n.store = eps - scoreParams := setup.PeerScoringParams() + // Enable extra features, if any. During testing we don't setup the most advanced host all the time. + if extra, ok := n.host.(ExtraHostFeatures); ok { + n.gater = extra.ConnectionGater() + n.connMgr = extra.ConnectionManager() + } + eps, ok := n.host.Peerstore().(store.ExtendedPeerstore) + if !ok { + return fmt.Errorf("cannot init without extended peerstore: %w", err) + } + n.store = eps + scoreParams := setup.PeerScoringParams() - if scoreParams != nil { - n.appScorer = newPeerApplicationScorer(resourcesCtx, log, clock.SystemClock, &scoreParams.ApplicationScoring, eps, n.host.Network().Peers) - } else { - n.appScorer = &NoopApplicationScorer{} - } - // Activate the P2P req-resp sync if enabled by feature-flag. - if setup.ReqRespSyncEnabled() && !elSyncEnabled { - n.syncCl = NewSyncClient(log, rollupCfg, n.host, gossipIn.OnUnsafeL2Payload, metrics, n.appScorer) - n.host.Network().Notify(&network.NotifyBundle{ - ConnectedF: func(nw network.Network, conn network.Conn) { - n.syncCl.AddPeer(conn.RemotePeer()) - }, - DisconnectedF: func(nw network.Network, conn network.Conn) { - // only when no connection is available, we can remove the peer - if nw.Connectedness(conn.RemotePeer()) == network.NotConnected { - n.syncCl.RemovePeer(conn.RemotePeer()) - } - }, - }) - n.syncCl.Start() - // the host may already be connected to peers, add them all to the sync client - for _, peerID := range n.host.Network().Peers() { - n.syncCl.AddPeer(peerID) - } - if l2Chain != nil { // Only enable serving side of req-resp sync if we have a data-source, to make minimal P2P testing easy - n.syncSrv = NewReqRespServer(rollupCfg, l2Chain, metrics) - // register the sync protocol with libp2p host - payloadByNumber := MakeStreamHandler(resourcesCtx, log.New("serve", "payloads_by_number"), n.syncSrv.HandleSyncRequest) - n.host.SetStreamHandler(PayloadByNumberProtocolID(rollupCfg.L2ChainID), payloadByNumber) - } + if scoreParams != nil { + n.appScorer = newPeerApplicationScorer(resourcesCtx, log, clock.SystemClock, &scoreParams.ApplicationScoring, eps, n.host.Network().Peers) + } else { + n.appScorer = &NoopApplicationScorer{} + } + // Activate the P2P req-resp sync if enabled by feature-flag. + if setup.ReqRespSyncEnabled() && !elSyncEnabled { + n.syncCl = NewSyncClient(log, rollupCfg, n.host, gossipIn.OnUnsafeL2Payload, metrics, n.appScorer) + n.host.Network().Notify(&network.NotifyBundle{ + ConnectedF: func(nw network.Network, conn network.Conn) { + n.syncCl.AddPeer(conn.RemotePeer()) + }, + DisconnectedF: func(nw network.Network, conn network.Conn) { + // only when no connection is available, we can remove the peer + if nw.Connectedness(conn.RemotePeer()) == network.NotConnected { + n.syncCl.RemovePeer(conn.RemotePeer()) + } + }, + }) + n.syncCl.Start() + // the host may already be connected to peers, add them all to the sync client + for _, peerID := range n.host.Network().Peers() { + n.syncCl.AddPeer(peerID) } - n.scorer = NewScorer(rollupCfg, eps, metrics, n.appScorer, log) - // notify of any new connections/streams/etc. - n.host.Network().Notify(NewNetworkNotifier(log, metrics)) - // note: the IDDelta functionality was removed from libP2P, and no longer needs to be explicitly disabled. - n.gs, err = NewGossipSub(resourcesCtx, n.host, rollupCfg, setup, n.scorer, metrics, log) - if err != nil { - return fmt.Errorf("failed to start gossipsub router: %w", err) + if l2Chain != nil { // Only enable serving side of req-resp sync if we have a data-source, to make minimal P2P testing easy + n.syncSrv = NewReqRespServer(rollupCfg, l2Chain, metrics) + // register the sync protocol with libp2p host + payloadByNumber := MakeStreamHandler(resourcesCtx, log.New("serve", "payloads_by_number"), n.syncSrv.HandleSyncRequest) + n.host.SetStreamHandler(PayloadByNumberProtocolID(rollupCfg.L2ChainID), payloadByNumber) } - n.gsOut, err = JoinGossip(n.host.ID(), n.gs, log, rollupCfg, runCfg, gossipIn) - if err != nil { - return fmt.Errorf("failed to join blocks gossip topic: %w", err) - } - log.Info("started p2p host", "addrs", n.host.Addrs(), "peerID", n.host.ID().String()) + } + n.scorer = NewScorer(rollupCfg, eps, metrics, n.appScorer, log) + // notify of any new connections/streams/etc. + n.host.Network().Notify(NewNetworkNotifier(log, metrics)) + // note: the IDDelta functionality was removed from libP2P, and no longer needs to be explicitly disabled. + n.gs, err = NewGossipSub(resourcesCtx, n.host, rollupCfg, setup, n.scorer, metrics, log) + if err != nil { + return fmt.Errorf("failed to start gossipsub router: %w", err) + } + n.gsOut, err = JoinGossip(n.host.ID(), n.gs, log, rollupCfg, runCfg, gossipIn) + if err != nil { + return fmt.Errorf("failed to join blocks gossip topic: %w", err) + } + log.Info("started p2p host", "addrs", n.host.Addrs(), "peerID", n.host.ID().String()) - tcpPort, err := FindActiveTCPPort(n.host) - if err != nil { - log.Warn("failed to find what TCP port p2p is binded to", "err", err) - } + tcpPort, err := FindActiveTCPPort(n.host) + if err != nil { + log.Warn("failed to find what TCP port p2p is binded to", "err", err) + } - // All nil if disabled. - n.dv5Local, n.dv5Udp, err = setup.Discovery(log.New("p2p", "discv5"), rollupCfg, tcpPort) - if err != nil { - return fmt.Errorf("failed to start discv5: %w", err) - } + // All nil if disabled. + n.dv5Local, n.dv5Udp, err = setup.Discovery(log.New("p2p", "discv5"), rollupCfg, tcpPort) + if err != nil { + return fmt.Errorf("failed to start discv5: %w", err) + } - if metrics != nil { - go metrics.RecordBandwidth(resourcesCtx, bwc) - } + if metrics != nil { + go metrics.RecordBandwidth(resourcesCtx, bwc) + } - if setup.BanPeers() { - n.peerMonitor = monitor.NewPeerMonitor(resourcesCtx, log, clock.SystemClock, n, setup.BanThreshold(), setup.BanDuration()) - n.peerMonitor.Start() - } - n.appScorer.start() + if setup.BanPeers() { + n.peerMonitor = monitor.NewPeerMonitor(resourcesCtx, log, clock.SystemClock, n, setup.BanThreshold(), setup.BanDuration()) + n.peerMonitor.Start() } + n.appScorer.start() return nil } From 323e688d93c3ec4c67d39349c23dcd239af2fbdc Mon Sep 17 00:00:00 2001 From: AgusDuha <81362284+agusduha@users.noreply.github.com> Date: Thu, 29 Aug 2024 13:17:41 -0300 Subject: [PATCH 006/264] test: fix standard bridge interop tests (#11668) * test: fix L2 standard bridge interop tests * test: mock factory implementation instead of proxy --- .../contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol b/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol index 812ab36deed0..d60ceb264a73 100644 --- a/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol +++ b/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol @@ -29,6 +29,10 @@ contract L2StandardBridgeInterop_Test is Bridge_Initializer { function setUp() public virtual override { super.enableInterop(); super.setUp(); + + // TODO: Remove it once the `OptimismSuperchainERC20Factory` is added to predeploys. + // Ensure OPTIMISM_SUPERCHAIN_ERC20_FACTORY's code is not empty. + vm.etch(Predeploys.predeployToCodeNamespace(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY), address(this).code); } /// @notice Helper function to setup a mock and expect a call to it. From 7373ce7615b3607b328ad22672b1adb3c7cf3701 Mon Sep 17 00:00:00 2001 From: Roberto Bayardo Date: Thu, 29 Aug 2024 09:37:52 -0700 Subject: [PATCH 007/264] - make state publishing loop abort if the txpool state is not good (#11633) - protect txpool state vars with a mutex so they can be automically updated to avoid potential race condition --- op-batcher/batcher/driver.go | 66 ++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 21 deletions(-) diff --git a/op-batcher/batcher/driver.go b/op-batcher/batcher/driver.go index 39ebf2f25b24..0af4c86ca40a 100644 --- a/op-batcher/batcher/driver.go +++ b/op-batcher/batcher/driver.go @@ -8,7 +8,6 @@ import ( "math/big" _ "net/http/pprof" "sync" - "sync/atomic" "time" altda "github.com/ethereum-optimism/optimism/op-alt-da" @@ -83,6 +82,10 @@ type BatchSubmitter struct { mutex sync.Mutex running bool + txpoolMutex sync.Mutex // guards txpoolState and txpoolBlockedBlob + txpoolState int + txpoolBlockedBlob bool + // lastStoredBlock is the last block loaded into `state`. If it is empty it should be set to the l2 safe head. lastStoredBlock eth.BlockID lastL1Tip eth.L1BlockRef @@ -289,7 +292,7 @@ const ( // send a cancellation transaction. // TxpoolCancelPending -> TxpoolGood: // happens once the cancel transaction completes, whether successfully or in error. - TxpoolGood int32 = iota + TxpoolGood int = iota TxpoolBlocked TxpoolCancelPending ) @@ -304,23 +307,25 @@ func (l *BatchSubmitter) loop() { receiptLoopDone := make(chan struct{}) defer close(receiptLoopDone) // shut down receipt loop - var ( - txpoolState atomic.Int32 - txpoolBlockedBlob bool - ) - txpoolState.Store(TxpoolGood) + l.txpoolMutex.Lock() + l.txpoolState = TxpoolGood + l.txpoolMutex.Unlock() go func() { for { select { case r := <-receiptsCh: - if errors.Is(r.Err, txpool.ErrAlreadyReserved) && txpoolState.CompareAndSwap(TxpoolGood, TxpoolBlocked) { - txpoolBlockedBlob = r.ID.isBlob - l.Log.Info("incompatible tx in txpool") - } else if r.ID.isCancel && txpoolState.CompareAndSwap(TxpoolCancelPending, TxpoolGood) { + l.txpoolMutex.Lock() + if errors.Is(r.Err, txpool.ErrAlreadyReserved) && l.txpoolState == TxpoolGood { + l.txpoolState = TxpoolBlocked + l.txpoolBlockedBlob = r.ID.isBlob + l.Log.Info("incompatible tx in txpool", "is_blob", r.ID.isBlob) + } else if r.ID.isCancel && l.txpoolState == TxpoolCancelPending { // Set state to TxpoolGood even if the cancellation transaction ended in error // since the stuck transaction could have cleared while we were waiting. + l.txpoolState = TxpoolGood l.Log.Info("txpool may no longer be blocked", "err", r.Err) } + l.txpoolMutex.Unlock() l.Log.Info("Handling receipt", "id", r.ID) l.handleReceipt(r) case <-receiptLoopDone: @@ -345,13 +350,7 @@ func (l *BatchSubmitter) loop() { for { select { case <-ticker.C: - if txpoolState.CompareAndSwap(TxpoolBlocked, TxpoolCancelPending) { - // txpoolState is set to Blocked only if Send() is returning - // ErrAlreadyReserved. In this case, the TxMgr nonce should be reset to nil, - // allowing us to send a cancellation transaction. - l.cancelBlockingTx(queue, receiptsCh, txpoolBlockedBlob) - } - if txpoolState.Load() != TxpoolGood { + if !l.checkTxpool(queue, receiptsCh) { continue } if err := l.loadBlocksIntoState(l.shutdownCtx); errors.Is(err, ErrReorg) { @@ -433,7 +432,12 @@ func (l *BatchSubmitter) publishStateToL1(queue *txmgr.Queue[txRef], receiptsCh l.Log.Info("Txmgr is closed, aborting state publishing") return } + if !l.checkTxpool(queue, receiptsCh) { + l.Log.Info("txpool state is not good, aborting state publishing") + return + } err := l.publishTxToL1(l.killCtx, queue, receiptsCh) + if err != nil { if err != io.EOF { l.Log.Error("Error publishing tx to l1", "err", err) @@ -545,10 +549,11 @@ func (l *BatchSubmitter) cancelBlockingTx(queue *txmgr.Queue[txRef], receiptsCh panic(err) // this error should not happen } l.Log.Warn("sending a cancellation transaction to unblock txpool", "blocked_blob", isBlockedBlob) - l.queueTx(txData{}, true, candidate, queue, receiptsCh) + l.sendTx(txData{}, true, candidate, queue, receiptsCh) } // sendTransaction creates & queues for sending a transaction to the batch inbox address with the given `txData`. +// This call will block if the txmgr queue is at the max-pending limit. // The method will block if the queue's MaxPendingTransactions is exceeded. func (l *BatchSubmitter) sendTransaction(ctx context.Context, txdata txData, queue *txmgr.Queue[txRef], receiptsCh chan txmgr.TxReceipt[txRef]) error { var err error @@ -585,11 +590,13 @@ func (l *BatchSubmitter) sendTransaction(ctx context.Context, txdata txData, que candidate = l.calldataTxCandidate(data) } - l.queueTx(txdata, false, candidate, queue, receiptsCh) + l.sendTx(txdata, false, candidate, queue, receiptsCh) return nil } -func (l *BatchSubmitter) queueTx(txdata txData, isCancel bool, candidate *txmgr.TxCandidate, queue *txmgr.Queue[txRef], receiptsCh chan txmgr.TxReceipt[txRef]) { +// sendTx uses the txmgr queue to send the given transaction candidate after setting its +// gaslimit. It will block if the txmgr queue has reached its MaxPendingTransactions limit. +func (l *BatchSubmitter) sendTx(txdata txData, isCancel bool, candidate *txmgr.TxCandidate, queue *txmgr.Queue[txRef], receiptsCh chan txmgr.TxReceipt[txRef]) { intrinsicGas, err := core.IntrinsicGas(candidate.TxData, nil, false, true, true, false) if err != nil { // we log instead of return an error here because txmgr can do its own gas estimation @@ -665,6 +672,23 @@ func (l *BatchSubmitter) l1Tip(ctx context.Context) (eth.L1BlockRef, error) { return eth.InfoToL1BlockRef(eth.HeaderBlockInfo(head)), nil } +func (l *BatchSubmitter) checkTxpool(queue *txmgr.Queue[txRef], receiptsCh chan txmgr.TxReceipt[txRef]) bool { + l.txpoolMutex.Lock() + if l.txpoolState == TxpoolBlocked { + // txpoolState is set to Blocked only if Send() is returning + // ErrAlreadyReserved. In this case, the TxMgr nonce should be reset to nil, + // allowing us to send a cancellation transaction. + l.txpoolState = TxpoolCancelPending + isBlob := l.txpoolBlockedBlob + l.txpoolMutex.Unlock() + l.cancelBlockingTx(queue, receiptsCh, isBlob) + return false + } + r := l.txpoolState == TxpoolGood + l.txpoolMutex.Unlock() + return r +} + func logFields(xs ...any) (fs []any) { for _, x := range xs { switch v := x.(type) { From db8154b098cc417099f13c2b4722f593753833c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 17:48:46 -0600 Subject: [PATCH 008/264] dependabot(gomod): bump github.com/hashicorp/raft from 1.7.0 to 1.7.1 (#11670) Bumps [github.com/hashicorp/raft](https://github.com/hashicorp/raft) from 1.7.0 to 1.7.1. - [Release notes](https://github.com/hashicorp/raft/releases) - [Changelog](https://github.com/hashicorp/raft/blob/main/CHANGELOG.md) - [Commits](https://github.com/hashicorp/raft/compare/v1.7.0...v1.7.1) --- updated-dependencies: - dependency-name: github.com/hashicorp/raft dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index e8a150cb6a1d..95845e360db8 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/google/gofuzz v1.2.1-0.20220503160820-4a35382e8fc8 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/golang-lru/v2 v2.0.7 - github.com/hashicorp/raft v1.7.0 + github.com/hashicorp/raft v1.7.1 github.com/hashicorp/raft-boltdb/v2 v2.3.0 github.com/holiman/uint256 v1.3.1 github.com/ipfs/go-datastore v0.6.0 @@ -113,7 +113,7 @@ require ( github.com/hashicorp/go-bexpr v0.1.11 // indirect github.com/hashicorp/go-hclog v1.6.2 // indirect github.com/hashicorp/go-immutable-radix v1.0.0 // indirect - github.com/hashicorp/go-msgpack/v2 v2.1.1 // indirect + github.com/hashicorp/go-msgpack/v2 v2.1.2 // indirect github.com/hashicorp/golang-lru v0.5.0 // indirect github.com/hashicorp/golang-lru/arc/v2 v2.0.7 // indirect github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e // indirect diff --git a/go.sum b/go.sum index 0c661e610830..fcbc2cc0172e 100644 --- a/go.sum +++ b/go.sum @@ -321,8 +321,8 @@ github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxB github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-msgpack/v2 v2.1.1 h1:xQEY9yB2wnHitoSzk/B9UjXWRQ67QKu5AOm8aFp8N3I= -github.com/hashicorp/go-msgpack/v2 v2.1.1/go.mod h1:upybraOAblm4S7rx0+jeNy+CWWhzywQsSRV5033mMu4= +github.com/hashicorp/go-msgpack/v2 v2.1.2 h1:4Ee8FTp834e+ewB71RDrQ0VKpyFdrKOjvYtnQ/ltVj0= +github.com/hashicorp/go-msgpack/v2 v2.1.2/go.mod h1:upybraOAblm4S7rx0+jeNy+CWWhzywQsSRV5033mMu4= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= @@ -335,8 +335,8 @@ github.com/hashicorp/golang-lru/arc/v2 v2.0.7/go.mod h1:Pe7gBlGdc8clY5LJ0LpJXMt5 github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/raft v1.1.0/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM= -github.com/hashicorp/raft v1.7.0 h1:4u24Qn6lQ6uwziM++UgsyiT64Q8GyRn43CV41qPiz1o= -github.com/hashicorp/raft v1.7.0/go.mod h1:N1sKh6Vn47mrWvEArQgILTyng8GoDRNYlgKyK7PMjs0= +github.com/hashicorp/raft v1.7.1 h1:ytxsNx4baHsRZrhUcbt3+79zc4ly8qm7pi0393pSchY= +github.com/hashicorp/raft v1.7.1/go.mod h1:hUeiEwQQR/Nk2iKDD0dkEhklSsu3jcAcqvPzPoZSAEM= github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e h1:SK4y8oR4ZMHPvwVHryKI88kJPJda4UyWYvG5A6iEQxc= github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e/go.mod h1:EMz/UIuG93P0MBeHh6CbXQAEe8ckVJLZjhD17lBzK5Q= github.com/hashicorp/raft-boltdb/v2 v2.3.0 h1:fPpQR1iGEVYjZ2OELvUHX600VAK5qmdnDEv3eXOwZUA= From d520441b008833d8ee8ee69bbe2e8158366279d0 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Fri, 30 Aug 2024 11:16:49 +1000 Subject: [PATCH 009/264] Use context interrupts consistently in more places (#11511) * Use context interrupts consistently in more places * Fix CI lint errors (cherry picked from commit 0410b7e448e063fa9e30295fbe423ff1c0171d12) * op-service/ctxinterrupt: address review comments --------- Co-authored-by: protolambda --- cannon/main.go | 16 +--- op-alt-da/cmd/daserver/entrypoint.go | 6 +- op-alt-da/cmd/daserver/main.go | 4 +- op-batcher/cmd/main.go | 4 +- op-bootnode/bootnode/entrypoint.go | 6 +- op-chain-ops/cmd/check-ecotone/main.go | 4 +- op-chain-ops/cmd/check-fjord/main.go | 4 +- op-chain-ops/cmd/op-simulate/main.go | 4 +- op-challenger/cmd/main.go | 4 +- op-challenger/cmd/utils.go | 4 +- op-conductor/cmd/main.go | 4 +- op-conductor/consensus/raft_fsm.go | 2 +- op-dispute-mon/cmd/main.go | 4 +- op-e2e/external_geth/main.go | 3 +- op-node/cmd/main.go | 4 +- op-proposer/cmd/main.go | 6 +- op-service/cliapp/lifecycle.go | 35 ++----- op-service/cliapp/lifecycle_test.go | 15 ++- op-service/ctxinterrupt/context.go | 29 ++++++ op-service/ctxinterrupt/context_test.go | 19 ++++ op-service/ctxinterrupt/doc.go | 3 + op-service/ctxinterrupt/funcs.go | 55 +++++++++++ op-service/ctxinterrupt/signal-waiter.go | 50 ++++++++++ op-service/ctxinterrupt/waiter.go | 38 ++++++++ op-service/opio/interrupts.go | 114 ----------------------- op-service/util.go | 38 +++----- op-supervisor/cmd/main.go | 4 +- op-wheel/commands.go | 4 +- op-wheel/engine/engine.go | 11 ++- 29 files changed, 273 insertions(+), 221 deletions(-) create mode 100644 op-service/ctxinterrupt/context.go create mode 100644 op-service/ctxinterrupt/context_test.go create mode 100644 op-service/ctxinterrupt/doc.go create mode 100644 op-service/ctxinterrupt/funcs.go create mode 100644 op-service/ctxinterrupt/signal-waiter.go create mode 100644 op-service/ctxinterrupt/waiter.go delete mode 100644 op-service/opio/interrupts.go diff --git a/cannon/main.go b/cannon/main.go index 769c1da0b6fe..176ce315708f 100644 --- a/cannon/main.go +++ b/cannon/main.go @@ -5,9 +5,8 @@ import ( "errors" "fmt" "os" - "os/signal" - "syscall" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" "github.com/urfave/cli/v2" "github.com/ethereum-optimism/optimism/cannon/cmd" @@ -23,18 +22,7 @@ func main() { cmd.WitnessCommand, cmd.RunCommand, } - ctx, cancel := context.WithCancel(context.Background()) - - c := make(chan os.Signal, 1) - signal.Notify(c, syscall.SIGINT, syscall.SIGTERM) - go func() { - for { - <-c - cancel() - fmt.Println("\r\nExiting...") - } - }() - + ctx := ctxinterrupt.WithSignalWaiterMain(context.Background()) err := app.RunContext(ctx, os.Args) if err != nil { if errors.Is(err, ctx.Err()) { diff --git a/op-alt-da/cmd/daserver/entrypoint.go b/op-alt-da/cmd/daserver/entrypoint.go index 96cc9fe48db1..32ff7d29f651 100644 --- a/op-alt-da/cmd/daserver/entrypoint.go +++ b/op-alt-da/cmd/daserver/entrypoint.go @@ -6,8 +6,8 @@ import ( "github.com/urfave/cli/v2" altda "github.com/ethereum-optimism/optimism/op-alt-da" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" oplog "github.com/ethereum-optimism/optimism/op-service/log" - "github.com/ethereum-optimism/optimism/op-service/opio" ) func StartDAServer(cliCtx *cli.Context) error { @@ -55,7 +55,5 @@ func StartDAServer(cliCtx *cli.Context) error { } }() - opio.BlockOnInterrupts() - - return nil + return ctxinterrupt.Wait(cliCtx.Context) } diff --git a/op-alt-da/cmd/daserver/main.go b/op-alt-da/cmd/daserver/main.go index f45c63ffebef..3ed37bd05321 100644 --- a/op-alt-da/cmd/daserver/main.go +++ b/op-alt-da/cmd/daserver/main.go @@ -9,8 +9,8 @@ import ( opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/cliapp" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" oplog "github.com/ethereum-optimism/optimism/op-service/log" - "github.com/ethereum-optimism/optimism/op-service/opio" ) var Version = "v0.0.1" @@ -26,7 +26,7 @@ func main() { app.Description = "Service for storing AltDA inputs" app.Action = StartDAServer - ctx := opio.WithInterruptBlocker(context.Background()) + ctx := ctxinterrupt.WithSignalWaiterMain(context.Background()) err := app.RunContext(ctx, os.Args) if err != nil { log.Crit("Application failed", "message", err) diff --git a/op-batcher/cmd/main.go b/op-batcher/cmd/main.go index 91e032ff36b4..82472006da27 100644 --- a/op-batcher/cmd/main.go +++ b/op-batcher/cmd/main.go @@ -11,9 +11,9 @@ import ( "github.com/ethereum-optimism/optimism/op-batcher/metrics" opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/cliapp" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" oplog "github.com/ethereum-optimism/optimism/op-service/log" "github.com/ethereum-optimism/optimism/op-service/metrics/doc" - "github.com/ethereum-optimism/optimism/op-service/opio" "github.com/ethereum/go-ethereum/log" ) @@ -40,7 +40,7 @@ func main() { }, } - ctx := opio.WithInterruptBlocker(context.Background()) + ctx := ctxinterrupt.WithSignalWaiterMain(context.Background()) err := app.RunContext(ctx, os.Args) if err != nil { log.Crit("Application failed", "message", err) diff --git a/op-bootnode/bootnode/entrypoint.go b/op-bootnode/bootnode/entrypoint.go index 0dcf356fa1f3..0c33383c70c7 100644 --- a/op-bootnode/bootnode/entrypoint.go +++ b/op-bootnode/bootnode/entrypoint.go @@ -17,10 +17,10 @@ import ( "github.com/ethereum-optimism/optimism/op-node/p2p" p2pcli "github.com/ethereum-optimism/optimism/op-node/p2p/cli" "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" "github.com/ethereum-optimism/optimism/op-service/eth" oplog "github.com/ethereum-optimism/optimism/op-service/log" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" - "github.com/ethereum-optimism/optimism/op-service/opio" oprpc "github.com/ethereum-optimism/optimism/op-service/rpc" ) @@ -116,9 +116,7 @@ func Main(cliCtx *cli.Context) error { m.RecordUp() } - opio.BlockOnInterrupts() - - return nil + return ctxinterrupt.Wait(ctx) } // validateConfig ensures the minimal config required to run a bootnode diff --git a/op-chain-ops/cmd/check-ecotone/main.go b/op-chain-ops/cmd/check-ecotone/main.go index 2f46f03d29d0..58a11e9ce1ad 100644 --- a/op-chain-ops/cmd/check-ecotone/main.go +++ b/op-chain-ops/cmd/check-ecotone/main.go @@ -32,10 +32,10 @@ import ( op_service "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/cliapp" "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" "github.com/ethereum-optimism/optimism/op-service/dial" "github.com/ethereum-optimism/optimism/op-service/eth" oplog "github.com/ethereum-optimism/optimism/op-service/log" - "github.com/ethereum-optimism/optimism/op-service/opio" "github.com/ethereum-optimism/optimism/op-service/predeploys" "github.com/ethereum-optimism/optimism/op-service/retry" "github.com/ethereum-optimism/optimism/op-service/sources" @@ -168,7 +168,7 @@ func makeCommandAction(fn CheckAction) func(c *cli.Context) error { logCfg := oplog.ReadCLIConfig(c) logger := oplog.NewLogger(c.App.Writer, logCfg) - c.Context = opio.CancelOnInterrupt(c.Context) + c.Context = ctxinterrupt.WithCancelOnInterrupt(c.Context) l1Cl, err := ethclient.DialContext(c.Context, c.String(EndpointL1.Name)) if err != nil { return fmt.Errorf("failed to dial L1 RPC: %w", err) diff --git a/op-chain-ops/cmd/check-fjord/main.go b/op-chain-ops/cmd/check-fjord/main.go index 5a2ef66fbcb9..c63cc43493f5 100644 --- a/op-chain-ops/cmd/check-fjord/main.go +++ b/op-chain-ops/cmd/check-fjord/main.go @@ -9,8 +9,8 @@ import ( "github.com/ethereum-optimism/optimism/op-chain-ops/cmd/check-fjord/checks" op_service "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/cliapp" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" oplog "github.com/ethereum-optimism/optimism/op-service/log" - "github.com/ethereum-optimism/optimism/op-service/opio" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" "github.com/urfave/cli/v2" @@ -54,7 +54,7 @@ func makeCommandAction(fn CheckAction) func(c *cli.Context) error { logCfg := oplog.ReadCLIConfig(c) logger := oplog.NewLogger(c.App.Writer, logCfg) - c.Context = opio.CancelOnInterrupt(c.Context) + c.Context = ctxinterrupt.WithCancelOnInterrupt(c.Context) l2Cl, err := ethclient.DialContext(c.Context, c.String(EndpointL2.Name)) if err != nil { return fmt.Errorf("failed to dial L2 RPC: %w", err) diff --git a/op-chain-ops/cmd/op-simulate/main.go b/op-chain-ops/cmd/op-simulate/main.go index 83aab8714218..8b0986e4554f 100644 --- a/op-chain-ops/cmd/op-simulate/main.go +++ b/op-chain-ops/cmd/op-simulate/main.go @@ -33,8 +33,8 @@ import ( op_service "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/cliapp" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" oplog "github.com/ethereum-optimism/optimism/op-service/log" - "github.com/ethereum-optimism/optimism/op-service/opio" ) var EnvPrefix = "OP_SIMULATE" @@ -82,7 +82,7 @@ func main() { } func mainAction(c *cli.Context) error { - ctx := opio.CancelOnInterrupt(c.Context) + ctx := ctxinterrupt.WithCancelOnInterrupt(c.Context) logCfg := oplog.ReadCLIConfig(c) logger := oplog.NewLogger(c.App.Writer, logCfg) diff --git a/op-challenger/cmd/main.go b/op-challenger/cmd/main.go index 50d842592ab5..dda1fa641757 100644 --- a/op-challenger/cmd/main.go +++ b/op-challenger/cmd/main.go @@ -15,8 +15,8 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/version" opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/cliapp" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" oplog "github.com/ethereum-optimism/optimism/op-service/log" - "github.com/ethereum-optimism/optimism/op-service/opio" ) var ( @@ -29,7 +29,7 @@ var VersionWithMeta = opservice.FormatVersion(version.Version, GitCommit, GitDat func main() { args := os.Args - ctx := opio.WithInterruptBlocker(context.Background()) + ctx := ctxinterrupt.WithSignalWaiterMain(context.Background()) if err := run(ctx, args, func(ctx context.Context, l log.Logger, config *config.Config) (cliapp.Lifecycle, error) { return challenger.Main(ctx, l, config, metrics.NewMetrics()) }); err != nil { diff --git a/op-challenger/cmd/utils.go b/op-challenger/cmd/utils.go index 110f1dddd641..82c35f7fa0f5 100644 --- a/op-challenger/cmd/utils.go +++ b/op-challenger/cmd/utils.go @@ -7,8 +7,8 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/flags" contractMetrics "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics" opservice "github.com/ethereum-optimism/optimism/op-service" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" "github.com/ethereum-optimism/optimism/op-service/dial" - "github.com/ethereum-optimism/optimism/op-service/opio" "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics" @@ -20,7 +20,7 @@ type ContractCreator[T any] func(context.Context, contractMetrics.ContractMetric func Interruptible(action cli.ActionFunc) cli.ActionFunc { return func(ctx *cli.Context) error { - ctx.Context = opio.CancelOnInterrupt(ctx.Context) + ctx.Context = ctxinterrupt.WithCancelOnInterrupt(ctx.Context) return action(ctx) } } diff --git a/op-conductor/cmd/main.go b/op-conductor/cmd/main.go index 508ffe220df0..3497e85f7917 100644 --- a/op-conductor/cmd/main.go +++ b/op-conductor/cmd/main.go @@ -12,8 +12,8 @@ import ( "github.com/ethereum-optimism/optimism/op-conductor/flags" opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/cliapp" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" oplog "github.com/ethereum-optimism/optimism/op-service/log" - "github.com/ethereum-optimism/optimism/op-service/opio" ) var ( @@ -34,7 +34,7 @@ func main() { app.Action = cliapp.LifecycleCmd(OpConductorMain) app.Commands = []*cli.Command{} - ctx := opio.WithInterruptBlocker(context.Background()) + ctx := ctxinterrupt.WithSignalWaiterMain(context.Background()) err := app.RunContext(ctx, os.Args) if err != nil { log.Crit("Application failed", "message", err) diff --git a/op-conductor/consensus/raft_fsm.go b/op-conductor/consensus/raft_fsm.go index 31631d2c91e6..28c85c36d904 100644 --- a/op-conductor/consensus/raft_fsm.go +++ b/op-conductor/consensus/raft_fsm.go @@ -29,7 +29,7 @@ func NewUnsafeHeadTracker(log log.Logger) *unsafeHeadTracker { // Apply implements raft.FSM, it applies the latest change (latest unsafe head payload) to FSM. func (t *unsafeHeadTracker) Apply(l *raft.Log) interface{} { - if l.Data == nil || len(l.Data) == 0 { + if len(l.Data) == 0 { return fmt.Errorf("log data is nil or empty") } diff --git a/op-dispute-mon/cmd/main.go b/op-dispute-mon/cmd/main.go index 4b2c1f46bd17..619fad23592e 100644 --- a/op-dispute-mon/cmd/main.go +++ b/op-dispute-mon/cmd/main.go @@ -14,8 +14,8 @@ import ( "github.com/ethereum-optimism/optimism/op-dispute-mon/version" opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/cliapp" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" oplog "github.com/ethereum-optimism/optimism/op-service/log" - "github.com/ethereum-optimism/optimism/op-service/opio" ) var ( @@ -28,7 +28,7 @@ var VersionWithMeta = opservice.FormatVersion(version.Version, GitCommit, GitDat func main() { args := os.Args - ctx := opio.WithInterruptBlocker(context.Background()) + ctx := ctxinterrupt.WithSignalWaiterMain(context.Background()) if err := run(ctx, args, monitor.Main); err != nil { log.Crit("Application failed", "err", err) } diff --git a/op-e2e/external_geth/main.go b/op-e2e/external_geth/main.go index c97061d868ff..c8921b9b3ece 100644 --- a/op-e2e/external_geth/main.go +++ b/op-e2e/external_geth/main.go @@ -73,7 +73,8 @@ func run(configPath string) error { fmt.Printf("================== op-geth shim awaiting termination ==========================\n") sigs := make(chan os.Signal, 1) - signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) + defer signal.Stop(sigs) + signal.Notify(sigs, os.Interrupt, syscall.SIGTERM) select { case <-sigs: diff --git a/op-node/cmd/main.go b/op-node/cmd/main.go index adb3d3aeb636..8f6688b51cbf 100644 --- a/op-node/cmd/main.go +++ b/op-node/cmd/main.go @@ -20,9 +20,9 @@ import ( "github.com/ethereum-optimism/optimism/op-node/version" opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/cliapp" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" oplog "github.com/ethereum-optimism/optimism/op-service/log" "github.com/ethereum-optimism/optimism/op-service/metrics/doc" - "github.com/ethereum-optimism/optimism/op-service/opio" ) var ( @@ -64,7 +64,7 @@ func main() { }, } - ctx := opio.WithInterruptBlocker(context.Background()) + ctx := ctxinterrupt.WithSignalWaiterMain(context.Background()) err := app.RunContext(ctx, os.Args) if err != nil { log.Crit("Application failed", "message", err) diff --git a/op-proposer/cmd/main.go b/op-proposer/cmd/main.go index bdfc730b4bf3..cbb21fb28516 100644 --- a/op-proposer/cmd/main.go +++ b/op-proposer/cmd/main.go @@ -1,8 +1,11 @@ package main import ( + "context" "os" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" + opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/urfave/cli/v2" @@ -38,7 +41,8 @@ func main() { }, } - err := app.Run(os.Args) + ctx := ctxinterrupt.WithSignalWaiterMain(context.Background()) + err := app.RunContext(ctx, os.Args) if err != nil { log.Crit("Application failed", "message", err) } diff --git a/op-service/cliapp/lifecycle.go b/op-service/cliapp/lifecycle.go index 2154c025645d..a1f134979134 100644 --- a/op-service/cliapp/lifecycle.go +++ b/op-service/cliapp/lifecycle.go @@ -7,7 +7,7 @@ import ( "github.com/urfave/cli/v2" - "github.com/ethereum-optimism/optimism/op-service/opio" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" ) type Lifecycle interface { @@ -29,36 +29,26 @@ type Lifecycle interface { // a shutdown when the Stop context is not expired. type LifecycleAction func(ctx *cli.Context, close context.CancelCauseFunc) (Lifecycle, error) -var interruptErr = errors.New("interrupt signal") - // LifecycleCmd turns a LifecycleAction into an CLI action, -// by instrumenting it with CLI context and signal based termination. -// The signals are caught with the opio.BlockFn attached to the context, if any. -// If no block function is provided, it adds default interrupt handling. +// by instrumenting it with CLI context and signal based cancellation. +// The signals are caught with the ctxinterrupt.waiter attached to the context, or default +// interrupt signal handling if not already provided. // The app may continue to run post-processing until fully shutting down. // The user can force an early shut-down during post-processing by sending a second interruption signal. func LifecycleCmd(fn LifecycleAction) cli.ActionFunc { return func(ctx *cli.Context) error { - hostCtx := ctx.Context - blockOnInterrupt := opio.BlockerFromContext(hostCtx) - if blockOnInterrupt == nil { // add default interrupt blocker to context if none is set. - hostCtx = opio.WithInterruptBlocker(hostCtx) - blockOnInterrupt = opio.BlockerFromContext(hostCtx) - } - appCtx, appCancel := context.WithCancelCause(hostCtx) + hostCtx, stop := ctxinterrupt.WithSignalWaiter(ctx.Context) + defer stop() + appCtx, appCancel := context.WithCancelCause(ctxinterrupt.WithCancelOnInterrupt(hostCtx)) + // This is updated so the fn callback cli.Context uses the appCtx we just made. ctx.Context = appCtx - go func() { - blockOnInterrupt(appCtx) - appCancel(interruptErr) - }() - appLifecycle, err := fn(ctx, appCancel) if err != nil { // join errors to include context cause (nil errors are dropped) return errors.Join( fmt.Errorf("failed to setup: %w", err), - context.Cause(appCtx), + context.Cause(ctx.Context), ) } @@ -75,15 +65,10 @@ func LifecycleCmd(fn LifecycleAction) cli.ActionFunc { // Graceful stop context. // This allows the service to idle before shutdown, if halted. User may interrupt. - stopCtx, stopCancel := context.WithCancelCause(hostCtx) - go func() { - blockOnInterrupt(stopCtx) - stopCancel(interruptErr) - }() + stopCtx := ctxinterrupt.WithCancelOnInterrupt(hostCtx) // Execute graceful stop. stopErr := appLifecycle.Stop(stopCtx) - stopCancel(nil) // note: Stop implementation may choose to suppress a context error, // if it handles it well (e.g. stop idling after a halt). if stopErr != nil { diff --git a/op-service/cliapp/lifecycle_test.go b/op-service/cliapp/lifecycle_test.go index 4c421a35493e..d9ffd086ed73 100644 --- a/op-service/cliapp/lifecycle_test.go +++ b/op-service/cliapp/lifecycle_test.go @@ -9,9 +9,11 @@ import ( "github.com/stretchr/testify/require" "github.com/urfave/cli/v2" - "github.com/ethereum-optimism/optimism/op-service/opio" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" ) +var mockInterruptErr = errors.New("mock interrupt") + type fakeLifecycle struct { startCh, stopCh chan error stopped bool @@ -85,11 +87,14 @@ func TestLifecycleCmd(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), time.Minute) // puppeteer system signal interrupts by hooking up the test signal channel as "blocker" for the app to use. - ctx = opio.WithBlocker(ctx, func(ctx context.Context) { + ctx = ctxinterrupt.WithWaiterFunc(ctx, func(ctx context.Context) (interrupt, ctxErr error) { select { case <-ctx.Done(): + ctxErr = context.Cause(ctx) case <-signalCh: + interrupt = mockInterruptErr } + return }) t.Cleanup(cancel) @@ -124,7 +129,7 @@ func TestLifecycleCmd(t *testing.T) { signalCh, _, _, _, resultCh, _ := appSetup(t) signalCh <- struct{}{} res := <-resultCh - require.ErrorIs(t, res, interruptErr) + require.ErrorIs(t, res, mockInterruptErr) require.ErrorContains(t, res, "failed to setup") }) t.Run("failed init", func(t *testing.T) { @@ -142,7 +147,7 @@ func TestLifecycleCmd(t *testing.T) { require.False(t, app.Stopped()) signalCh <- struct{}{} res := <-resultCh - require.ErrorIs(t, res, interruptErr) + require.ErrorIs(t, res, mockInterruptErr) require.ErrorContains(t, res, "failed to start") require.True(t, app.Stopped()) }) @@ -178,7 +183,7 @@ func TestLifecycleCmd(t *testing.T) { signalCh <- struct{}{} // start graceful shutdown signalCh <- struct{}{} // interrupt before the shutdown process is allowed to complete res := <-resultCh - require.ErrorIs(t, res, interruptErr) + require.ErrorIs(t, res, mockInterruptErr) require.ErrorContains(t, res, "failed to stop") require.True(t, app.Stopped()) // still fully closes, interrupts only accelerate shutdown where possible. }) diff --git a/op-service/ctxinterrupt/context.go b/op-service/ctxinterrupt/context.go new file mode 100644 index 000000000000..d7e7446d0dc3 --- /dev/null +++ b/op-service/ctxinterrupt/context.go @@ -0,0 +1,29 @@ +package ctxinterrupt + +import ( + "context" +) + +// Newtyping empty struct prevents collision with other empty struct keys in the Context. +type interruptWaiterContextKeyType struct{} + +var waiterContextKey = interruptWaiterContextKeyType{} + +// WithInterruptWaiter overrides the interrupt waiter value, e.g. to insert a function that mocks +// interrupt signals for testing CLI shutdown without actual process signals. +func WithWaiterFunc(ctx context.Context, fn WaiterFunc) context.Context { + return withInterruptWaiter(ctx, fn) +} + +func withInterruptWaiter(ctx context.Context, value waiter) context.Context { + return context.WithValue(ctx, waiterContextKey, value) +} + +// contextInterruptWaiter returns a interruptWaiter that blocks on interrupts when called. +func contextInterruptWaiter(ctx context.Context) waiter { + v := ctx.Value(waiterContextKey) + if v == nil { + return nil + } + return v.(waiter) +} diff --git a/op-service/ctxinterrupt/context_test.go b/op-service/ctxinterrupt/context_test.go new file mode 100644 index 000000000000..c853a3c5f7c6 --- /dev/null +++ b/op-service/ctxinterrupt/context_test.go @@ -0,0 +1,19 @@ +package ctxinterrupt + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestContextKeyIsUnique(t *testing.T) { + ass := require.New(t) + ctx := context.Background() + ass.Nil(ctx.Value(waiterContextKey)) + ctx = context.WithValue(ctx, waiterContextKey, 1) + ass.Equal(ctx.Value(waiterContextKey), 1) + ctx = context.WithValue(ctx, waiterContextKey, 2) + ass.Equal(ctx.Value(waiterContextKey), 2) + ass.Nil(ctx.Value(struct{}{})) +} diff --git a/op-service/ctxinterrupt/doc.go b/op-service/ctxinterrupt/doc.go new file mode 100644 index 000000000000..4846d544eba8 --- /dev/null +++ b/op-service/ctxinterrupt/doc.go @@ -0,0 +1,3 @@ +// Implements interrupts: events that normally signal intent to cancel a Context, but may be +// repeated to encourage closure of new Contexts used to clean up resources. +package ctxinterrupt diff --git a/op-service/ctxinterrupt/funcs.go b/op-service/ctxinterrupt/funcs.go new file mode 100644 index 000000000000..90ab19e19df1 --- /dev/null +++ b/op-service/ctxinterrupt/funcs.go @@ -0,0 +1,55 @@ +package ctxinterrupt + +import ( + "context" +) + +// Wait blocks until an interrupt is received, defaulting to interrupting on the default +// signals if no interrupt blocker is present in the Context. Returns nil if an interrupt occurs, +// else the Context error when it's done. +func Wait(ctx context.Context) error { + iw := contextInterruptWaiter(ctx) + if iw == nil { + catcher := newSignalWaiter() + defer catcher.Stop() + iw = catcher + } + return iw.waitForInterrupt(ctx).CtxError +} + +// WithSignalWaiter attaches an interrupt signal handler to the context which continues to receive +// signals after every wait, and also prevents the interrupt signals being handled before we're +// ready to wait for them. This helps functions wait on individual consecutive interrupts. +func WithSignalWaiter(ctx context.Context) (_ context.Context, stop func()) { + if ctx.Value(waiterContextKey) != nil { // already has an interrupt waiter + return ctx, func() {} + } + catcher := newSignalWaiter() + return withInterruptWaiter(ctx, catcher), catcher.Stop +} + +// WithSignalWaiterMain returns a Context with a signal interrupt blocker and leaks the destructor. Intended for use in +// main functions where we exit right after using the returned context anyway. +func WithSignalWaiterMain(ctx context.Context) context.Context { + ctx, _ = WithSignalWaiter(ctx) + return ctx +} + +// WithCancelOnInterrupt returns a Context that is cancelled when Wait returns on the waiter in ctx. +// If there's no waiter, the default interrupt signals are used: In this case the signal hooking is +// not stopped until the original ctx is cancelled. +func WithCancelOnInterrupt(ctx context.Context) context.Context { + interruptWaiter := contextInterruptWaiter(ctx) + ctx, cancel := context.WithCancelCause(ctx) + stop := func() {} + if interruptWaiter == nil { + catcher := newSignalWaiter() + stop = catcher.Stop + interruptWaiter = catcher + } + go func() { + defer stop() + cancel(interruptWaiter.waitForInterrupt(ctx).Cause()) + }() + return ctx +} diff --git a/op-service/ctxinterrupt/signal-waiter.go b/op-service/ctxinterrupt/signal-waiter.go new file mode 100644 index 000000000000..a37dde7a981b --- /dev/null +++ b/op-service/ctxinterrupt/signal-waiter.go @@ -0,0 +1,50 @@ +package ctxinterrupt + +import ( + "context" + "fmt" + "os" + "os/signal" + "syscall" +) + +// defaultSignals is a set of default interrupt signals. +var defaultSignals = []os.Signal{ + // Let's not catch SIGQUIT as it's expected to terminate with a stack trace in Go. os.Kill + // should not/cannot be caught on most systems. + os.Interrupt, + syscall.SIGTERM, +} + +type signalWaiter struct { + incoming chan os.Signal +} + +func newSignalWaiter() signalWaiter { + catcher := signalWaiter{ + // Buffer, in case we are slow to act on older signals, + // but still want to handle repeat-signals as special case (e.g. to force shutdown) + incoming: make(chan os.Signal, 10), + } + signal.Notify(catcher.incoming, defaultSignals...) + return catcher +} + +func (me signalWaiter) Stop() { + signal.Stop(me.incoming) +} + +// Block blocks until either an interrupt signal is received, or the context is cancelled. +// No error is returned on interrupt. +func (me signalWaiter) waitForInterrupt(ctx context.Context) waitResult { + select { + case signalValue, ok := <-me.incoming: + if !ok { + // Signal channels are not closed. + panic("signal channel closed") + } + return waitResult{Interrupt: fmt.Errorf("received interrupt signal %v", signalValue)} + case <-ctx.Done(): + return waitResult{CtxError: context.Cause(ctx)} + } +} diff --git a/op-service/ctxinterrupt/waiter.go b/op-service/ctxinterrupt/waiter.go new file mode 100644 index 000000000000..4e32a84b0a44 --- /dev/null +++ b/op-service/ctxinterrupt/waiter.go @@ -0,0 +1,38 @@ +package ctxinterrupt + +import ( + "context" + "fmt" +) + +// waiter describes a value that can wait for interrupts and context cancellation at the same time. +type waiter interface { + waitForInterrupt(ctx context.Context) waitResult +} + +// Waits for an interrupt or context cancellation. ctxErr should be the context.Cause of ctx when it +// is done. interrupt is only inspected if ctxErr is nil, and is not required to be set. +type WaiterFunc func(ctx context.Context) (interrupt, ctxErr error) + +func (me WaiterFunc) waitForInterrupt(ctx context.Context) (res waitResult) { + res.Interrupt, res.CtxError = me(ctx) + return +} + +// Either CtxError is not nil and is set to the context error cause, or the wait was interrupted. +type waitResult struct { + // Not required to be non-nil on an interrupt. + Interrupt error + // Maybe set this using context.Cause. + CtxError error +} + +func (me waitResult) Cause() error { + if me.CtxError != nil { + return me.CtxError + } + if me.Interrupt != nil { + return fmt.Errorf("interrupted: %w", me.Interrupt) + } + return nil +} diff --git a/op-service/opio/interrupts.go b/op-service/opio/interrupts.go deleted file mode 100644 index cd1b8485791d..000000000000 --- a/op-service/opio/interrupts.go +++ /dev/null @@ -1,114 +0,0 @@ -package opio - -import ( - "context" - "os" - "os/signal" - "syscall" -) - -// DefaultInterruptSignals is a set of default interrupt signals. -var DefaultInterruptSignals = []os.Signal{ - os.Interrupt, - os.Kill, - syscall.SIGTERM, - syscall.SIGQUIT, -} - -// BlockOnInterrupts blocks until a SIGTERM is received. -// Passing in signals will override the default signals. -func BlockOnInterrupts(signals ...os.Signal) { - if len(signals) == 0 { - signals = DefaultInterruptSignals - } - interruptChannel := make(chan os.Signal, 1) - signal.Notify(interruptChannel, signals...) - <-interruptChannel -} - -// BlockOnInterruptsContext blocks until a SIGTERM is received. -// Passing in signals will override the default signals. -// The function will stop blocking if the context is closed. -func BlockOnInterruptsContext(ctx context.Context, signals ...os.Signal) { - if len(signals) == 0 { - signals = DefaultInterruptSignals - } - interruptChannel := make(chan os.Signal, 1) - signal.Notify(interruptChannel, signals...) - select { - case <-interruptChannel: - case <-ctx.Done(): - signal.Stop(interruptChannel) - } -} - -type interruptContextKeyType struct{} - -var blockerContextKey = interruptContextKeyType{} - -type interruptCatcher struct { - incoming chan os.Signal -} - -// Block blocks until either an interrupt signal is received, or the context is cancelled. -// No error is returned on interrupt. -func (c *interruptCatcher) Block(ctx context.Context) { - select { - case <-c.incoming: - case <-ctx.Done(): - } -} - -// WithInterruptBlocker attaches an interrupt handler to the context, -// which continues to receive signals after every block. -// This helps functions block on individual consecutive interrupts. -func WithInterruptBlocker(ctx context.Context) context.Context { - if ctx.Value(blockerContextKey) != nil { // already has an interrupt handler - return ctx - } - catcher := &interruptCatcher{ - incoming: make(chan os.Signal, 10), - } - signal.Notify(catcher.incoming, DefaultInterruptSignals...) - - return context.WithValue(ctx, blockerContextKey, BlockFn(catcher.Block)) -} - -// WithBlocker overrides the interrupt blocker value, -// e.g. to insert a block-function for testing CLI shutdown without actual process signals. -func WithBlocker(ctx context.Context, fn BlockFn) context.Context { - return context.WithValue(ctx, blockerContextKey, fn) -} - -// BlockFn simply blocks until the implementation of the blocker interrupts it, or till the given context is cancelled. -type BlockFn func(ctx context.Context) - -// BlockerFromContext returns a BlockFn that blocks on interrupts when called. -func BlockerFromContext(ctx context.Context) BlockFn { - v := ctx.Value(blockerContextKey) - if v == nil { - return nil - } - return v.(BlockFn) -} - -// CancelOnInterrupt cancels the given context on interrupt. -// If a BlockFn is attached to the context, this is used as interrupt-blocking. -// If not, then the context blocks on a manually handled interrupt signal. -func CancelOnInterrupt(ctx context.Context) context.Context { - inner, cancel := context.WithCancel(ctx) - - blockOnInterrupt := BlockerFromContext(ctx) - if blockOnInterrupt == nil { - blockOnInterrupt = func(ctx context.Context) { - BlockOnInterruptsContext(ctx) // default signals - } - } - - go func() { - blockOnInterrupt(ctx) - cancel() - }() - - return inner -} diff --git a/op-service/util.go b/op-service/util.go index 0a51147fd7d8..e9dae2ec033f 100644 --- a/op-service/util.go +++ b/op-service/util.go @@ -5,13 +5,13 @@ import ( "errors" "fmt" "os" - "os/signal" "path/filepath" "reflect" "strings" - "syscall" "time" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" "github.com/urfave/cli/v2" @@ -86,37 +86,27 @@ func ParseAddress(address string) (common.Address, error) { return common.Address{}, fmt.Errorf("invalid address: %v", address) } -// CloseAction runs the function in the background, until it finishes or until it is closed by the user with an interrupt. -func CloseAction(fn func(ctx context.Context, shutdown <-chan struct{}) error) error { - stopped := make(chan error, 1) - shutdown := make(chan struct{}, 1) - - ctx, cancel := context.WithCancel(context.Background()) +// CloseAction runs the function in the background, until it finishes or until it is closed by the +// user with an interrupt. +func CloseAction(ctx context.Context, fn func(ctx context.Context) error) error { + ctx, stop := ctxinterrupt.WithSignalWaiter(ctx) + defer stop() + finished := make(chan error, 1) go func() { - stopped <- fn(ctx, shutdown) + finished <- fn(ctx) }() - doneCh := make(chan os.Signal, 1) - signal.Notify(doneCh, []os.Signal{ - os.Interrupt, - os.Kill, - syscall.SIGTERM, - syscall.SIGQUIT, - }...) - select { - case <-doneCh: - cancel() - shutdown <- struct{}{} - + case <-ctx.Done(): + // Stop catching interrupts. + stop() select { - case err := <-stopped: + case err := <-finished: return err case <-time.After(time.Second * 10): return errors.New("command action is unresponsive for more than 10 seconds... shutting down") } - case err := <-stopped: - cancel() + case err := <-finished: return err } } diff --git a/op-supervisor/cmd/main.go b/op-supervisor/cmd/main.go index 01444e01b925..8e306bf9009d 100644 --- a/op-supervisor/cmd/main.go +++ b/op-supervisor/cmd/main.go @@ -11,9 +11,9 @@ import ( opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/cliapp" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" oplog "github.com/ethereum-optimism/optimism/op-service/log" "github.com/ethereum-optimism/optimism/op-service/metrics/doc" - "github.com/ethereum-optimism/optimism/op-service/opio" "github.com/ethereum-optimism/optimism/op-supervisor/flags" "github.com/ethereum-optimism/optimism/op-supervisor/metrics" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor" @@ -26,7 +26,7 @@ var ( ) func main() { - ctx := opio.WithInterruptBlocker(context.Background()) + ctx := ctxinterrupt.WithSignalWaiterMain(context.Background()) err := run(ctx, os.Args, fromConfig) if err != nil { log.Crit("Application failed", "message", err) diff --git a/op-wheel/commands.go b/op-wheel/commands.go index 5a643b7ec12d..521578a34cb6 100644 --- a/op-wheel/commands.go +++ b/op-wheel/commands.go @@ -504,7 +504,7 @@ var ( metricsCfg := opmetrics.ReadCLIConfig(ctx) - return opservice.CloseAction(func(ctx context.Context, shutdown <-chan struct{}) error { + return opservice.CloseAction(ctx.Context, func(ctx context.Context) error { registry := opmetrics.NewRegistry() metrics := engine.NewMetrics("wheel", registry) if metricsCfg.Enabled { @@ -519,7 +519,7 @@ var ( } }() } - return engine.Auto(ctx, metrics, client, l, shutdown, settings) + return engine.Auto(ctx, metrics, client, l, settings) }) }), } diff --git a/op-wheel/engine/engine.go b/op-wheel/engine/engine.go index 8518a48031b0..8a00e212b3ca 100644 --- a/op-wheel/engine/engine.go +++ b/op-wheel/engine/engine.go @@ -189,7 +189,13 @@ func newPayloadAttributes(evp sources.EngineVersionProvider, timestamp uint64, p return pa } -func Auto(ctx context.Context, metrics Metricer, client *sources.EngineAPIClient, log log.Logger, shutdown <-chan struct{}, settings *BlockBuildingSettings) error { +func Auto( + ctx context.Context, + metrics Metricer, + client *sources.EngineAPIClient, + log log.Logger, + settings *BlockBuildingSettings, +) error { ticker := time.NewTicker(time.Millisecond * 100) defer ticker.Stop() @@ -197,9 +203,6 @@ func Auto(ctx context.Context, metrics Metricer, client *sources.EngineAPIClient var buildErr error for { select { - case <-shutdown: - log.Info("shutting down") - return nil case <-ctx.Done(): log.Info("context closed", "err", ctx.Err()) return ctx.Err() From f370113e8de436ad2af5dd093b45366bc8ab352f Mon Sep 17 00:00:00 2001 From: AgusDuha <81362284+agusduha@users.noreply.github.com> Date: Fri, 30 Aug 2024 17:35:38 -0300 Subject: [PATCH 010/264] test: fix superchain erc20 invariants (#11688) --------- Co-authored-by: 0xDiscotech <131301107+0xDiscotech@users.noreply.github.com> --- .../invariant-docs/OptimismSuperchainERC20.md | 4 ++-- .../test/invariants/OptimismSuperchainERC20.t.sol | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/invariant-docs/OptimismSuperchainERC20.md b/packages/contracts-bedrock/invariant-docs/OptimismSuperchainERC20.md index 0e3150624da5..13d03f304d45 100644 --- a/packages/contracts-bedrock/invariant-docs/OptimismSuperchainERC20.md +++ b/packages/contracts-bedrock/invariant-docs/OptimismSuperchainERC20.md @@ -1,10 +1,10 @@ # `OptimismSuperchainERC20` Invariants ## Calls to sendERC20 should always succeed as long as the actor has enough balance. Actor's balance should also not increase out of nowhere but instead should decrease by the amount sent. -**Test:** [`OptimismSuperchainERC20.t.sol#L194`](../test/invariants/OptimismSuperchainERC20.t.sol#L194) +**Test:** [`OptimismSuperchainERC20.t.sol#L196`](../test/invariants/OptimismSuperchainERC20.t.sol#L196) ## Calls to relayERC20 should always succeeds when a message is received from another chain. Actor's balance should only increase by the amount relayed. -**Test:** [`OptimismSuperchainERC20.t.sol#L212`](../test/invariants/OptimismSuperchainERC20.t.sol#L212) +**Test:** [`OptimismSuperchainERC20.t.sol#L214`](../test/invariants/OptimismSuperchainERC20.t.sol#L214) diff --git a/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20.t.sol b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20.t.sol index 028a0124e6ca..70081560c59f 100644 --- a/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20.t.sol +++ b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20.t.sol @@ -62,6 +62,8 @@ contract OptimismSuperchainERC20_User is StdUtils { return; } + if (_chainId == block.chainid) return; + // Bound send amount to our ERC20 balance. _amount = bound(_amount, 0, superchainERC20.balanceOf(address(this))); From 814c9de7d8cda1b9eaf11ffbc1f6191090b63269 Mon Sep 17 00:00:00 2001 From: AgusDuha <81362284+agusduha@users.noreply.github.com> Date: Fri, 30 Aug 2024 18:34:40 -0300 Subject: [PATCH 011/264] feat: add createX preinstall (#29) (#11618) * feat: add createX preinstall * feat: change name from CreateXDeployer to CreateX --- packages/contracts-bedrock/scripts/L2Genesis.s.sol | 1 + packages/contracts-bedrock/src/libraries/Preinstalls.sol | 8 ++++++++ packages/contracts-bedrock/test/L2Genesis.t.sol | 2 +- packages/contracts-bedrock/test/Preinstalls.t.sol | 4 ++++ packages/contracts-bedrock/test/setup/Setup.sol | 1 + 5 files changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/scripts/L2Genesis.s.sol b/packages/contracts-bedrock/scripts/L2Genesis.s.sol index 7d4568653936..ba2c5e4bf4f4 100644 --- a/packages/contracts-bedrock/scripts/L2Genesis.s.sol +++ b/packages/contracts-bedrock/scripts/L2Genesis.s.sol @@ -525,6 +525,7 @@ contract L2Genesis is Deployer { _setPreinstallCode(Preinstalls.SenderCreator_v070); // ERC 4337 v0.7.0 _setPreinstallCode(Preinstalls.EntryPoint_v070); // ERC 4337 v0.7.0 _setPreinstallCode(Preinstalls.BeaconBlockRoots); + _setPreinstallCode(Preinstalls.CreateX); // 4788 sender nonce must be incremented, since it's part of later upgrade-transactions. // For the upgrade-tx to not create a contract that conflicts with an already-existing copy, // the nonce must be bumped. diff --git a/packages/contracts-bedrock/src/libraries/Preinstalls.sol b/packages/contracts-bedrock/src/libraries/Preinstalls.sol index 327b34c0abf4..db886f57f10a 100644 --- a/packages/contracts-bedrock/src/libraries/Preinstalls.sol +++ b/packages/contracts-bedrock/src/libraries/Preinstalls.sol @@ -44,6 +44,9 @@ library Preinstalls { /// @notice Address of the EntryPoint_v070 predeploy. address internal constant EntryPoint_v070 = 0x0000000071727De22E5E9d8BAf0edAc6f37da032; + /// @notice Address of the CreateX predeploy. + address internal constant CreateX = 0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed; + /// @notice Address of beacon block roots contract, introduced in the Cancun upgrade. /// See BEACON_ROOTS_ADDRESS in EIP-4788. /// This contract is introduced in L2 through an Ecotone upgrade transaction, if not already in genesis. @@ -99,6 +102,9 @@ library Preinstalls { bytes internal constant EntryPoint_v070Code = hex"60806040526004361015610024575b361561001957600080fd5b61002233612748565b005b60003560e01c806242dc5314611b0057806301ffc9a7146119ae5780630396cb60146116765780630bd28e3b146115fa5780631b2e01b814611566578063205c2878146113d157806322cdde4c1461136b57806335567e1a146112b35780635287ce12146111a557806370a0823114611140578063765e827f14610e82578063850aaf6214610dc35780639b249f6914610c74578063b760faf914610c3a578063bb9fe6bf14610a68578063c23a5cea146107c4578063dbed18e0146101a15763fc7e286d0361000e573461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5773ffffffffffffffffffffffffffffffffffffffff61013a61229f565b16600052600060205260a0604060002065ffffffffffff6001825492015460405192835260ff8116151560208401526dffffffffffffffffffffffffffff8160081c16604084015263ffffffff8160781c16606084015260981c166080820152f35b600080fd5b3461019c576101af36612317565b906101b86129bd565b60009160005b82811061056f57506101d08493612588565b6000805b8481106102fc5750507fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000809360005b81811061024757610240868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2613ba7565b6001600255005b6102a261025582848a612796565b73ffffffffffffffffffffffffffffffffffffffff6102766020830161282a565b167f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a2806127d6565b906000915b8083106102b957505050600101610209565b909194976102f36102ed6001926102e78c8b6102e0826102da8e8b8d61269d565b9261265a565b5191613597565b90612409565b99612416565b950191906102a7565b6020610309828789612796565b61031f61031682806127d6565b9390920161282a565b9160009273ffffffffffffffffffffffffffffffffffffffff8091165b8285106103505750505050506001016101d4565b909192939561037f83610378610366848c61265a565b516103728b898b61269d565b856129f6565b9290613dd7565b9116840361050a576104a5576103958491613dd7565b9116610440576103b5576103aa600191612416565b96019392919061033c565b60a487604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f65000000000000000000000000000000000000000000000000000000000000006084820152fd5b608488604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413334207369676e6174757265206572726f720000000000000000000000006064820152fd5b608488604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601760448201527f414132322065787069726564206f72206e6f74206475650000000000000000006064820152fd5b608489604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413234207369676e6174757265206572726f720000000000000000000000006064820152fd5b61057a818487612796565b9361058585806127d6565b919095602073ffffffffffffffffffffffffffffffffffffffff6105aa82840161282a565b1697600192838a1461076657896105da575b5050505060019293949550906105d191612409565b939291016101be565b8060406105e892019061284b565b918a3b1561019c57929391906040519485937f2dd8113300000000000000000000000000000000000000000000000000000000855288604486016040600488015252606490818601918a60051b8701019680936000915b8c83106106e657505050505050838392610684927ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8560009803016024860152612709565b03818a5afa90816106d7575b506106c657602486604051907f86a9f7500000000000000000000000000000000000000000000000000000000082526004820152fd5b93945084936105d1600189806105bc565b6106e0906121bd565b88610690565b91939596977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c908a9294969a0301865288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee18336030181121561019c57836107538793858394016128ec565b9a0196019301909189979695949261063f565b606483604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b3461019c576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c576107fc61229f565b33600052600082526001604060002001908154916dffffffffffffffffffffffffffff8360081c16928315610a0a5765ffffffffffff8160981c1680156109ac57421061094e5760009373ffffffffffffffffffffffffffffffffffffffff859485947fffffffffffffff000000000000000000000000000000000000000000000000ff86951690556040517fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda33391806108da8786836020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b0390a2165af16108e8612450565b50156108f057005b606490604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b606485604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b606486604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b606485604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b3461019c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c573360005260006020526001604060002001805463ffffffff8160781c16908115610bdc5760ff1615610b7e5765ffffffffffff908142160191818311610b4f5780547fffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff001678ffffffffffff00000000000000000000000000000000000000609885901b161790556040519116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a2005b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c57610022610c6f61229f565b612748565b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760043567ffffffffffffffff811161019c576020610cc8610d1b9236906004016122c2565b919073ffffffffffffffffffffffffffffffffffffffff9260405194859283927f570e1a360000000000000000000000000000000000000000000000000000000084528560048501526024840191612709565b03816000857f000000000000000000000000efc2c1444ebcc4db75e7613d20c6a62ff67a167c165af1908115610db757602492600092610d86575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b610da991925060203d602011610db0575b610da181836121ed565b8101906126dd565b9083610d56565b503d610d97565b6040513d6000823e3d90fd5b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c57610dfa61229f565b60243567ffffffffffffffff811161019c57600091610e1e839236906004016122c2565b90816040519283928337810184815203915af4610e39612450565b90610e7e6040519283927f99410554000000000000000000000000000000000000000000000000000000008452151560048401526040602484015260448301906123c6565b0390fd5b3461019c57610e9036612317565b610e9b9291926129bd565b610ea483612588565b60005b848110610f1c57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000915b858310610eec576102408585613ba7565b909193600190610f12610f0087898761269d565b610f0a888661265a565b519088613597565b0194019190610edb565b610f47610f40610f2e8385979561265a565b51610f3a84898761269d565b846129f6565b9190613dd7565b73ffffffffffffffffffffffffffffffffffffffff929183166110db5761107657610f7190613dd7565b911661101157610f8657600101929092610ea7565b60a490604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f65000000000000000000000000000000000000000000000000000000000000006084820152fd5b608482604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413334207369676e6174757265206572726f720000000000000000000000006064820152fd5b608483604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601760448201527f414132322065787069726564206f72206e6f74206475650000000000000000006064820152fd5b608484604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601460448201527f41413234207369676e6174757265206572726f720000000000000000000000006064820152fd5b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5773ffffffffffffffffffffffffffffffffffffffff61118c61229f565b1660005260006020526020604060002054604051908152f35b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5773ffffffffffffffffffffffffffffffffffffffff6111f161229f565b6000608060405161120181612155565b828152826020820152826040820152826060820152015216600052600060205260a06040600020608060405161123681612155565b6001835493848352015490602081019060ff8316151582526dffffffffffffffffffffffffffff60408201818560081c16815263ffffffff936060840193858760781c16855265ffffffffffff978891019660981c1686526040519788525115156020880152511660408601525116606084015251166080820152f35b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760206112ec61229f565b73ffffffffffffffffffffffffffffffffffffffff6113096122f0565b911660005260018252604060002077ffffffffffffffffffffffffffffffffffffffffffffffff821660005282526040600020547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b3461019c577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60208136011261019c576004359067ffffffffffffffff821161019c5761012090823603011261019c576113c9602091600401612480565b604051908152f35b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5761140861229f565b60243590336000526000602052604060002090815491828411611508576000808573ffffffffffffffffffffffffffffffffffffffff8295839561144c848a612443565b90556040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af16114a2612450565b50156114aa57005b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b3461019c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5761159d61229f565b73ffffffffffffffffffffffffffffffffffffffff6115ba6122f0565b9116600052600160205277ffffffffffffffffffffffffffffffffffffffffffffffff604060002091166000526020526020604060002054604051908152f35b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760043577ffffffffffffffffffffffffffffffffffffffffffffffff811680910361019c5733600052600160205260406000209060005260205260406000206116728154612416565b9055005b6020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5760043563ffffffff9182821680920361019c5733600052600081526040600020928215611950576001840154908160781c1683106118f2576116f86dffffffffffffffffffffffffffff9182349160081c16612409565b93841561189457818511611836579065ffffffffffff61180592546040519061172082612155565b8152848101926001845260408201908816815260608201878152600160808401936000855233600052600089526040600020905181550194511515917fffffffffffffffffffffffffff0000000000000000000000000000000000000060ff72ffffffff0000000000000000000000000000006effffffffffffffffffffffffffff008954945160081b16945160781b1694169116171717835551167fffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffff78ffffffffffff0000000000000000000000000000000000000083549260981b169116179055565b6040519283528201527fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c0160403392a2005b606483604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b606483604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b606482604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b606482604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b3461019c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c576004357fffffffff00000000000000000000000000000000000000000000000000000000811680910361019c57807f60fc6b6e0000000000000000000000000000000000000000000000000000000060209214908115611ad6575b8115611aac575b8115611a82575b8115611a58575b506040519015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501482611a4d565b7f3e84f0210000000000000000000000000000000000000000000000000000000081149150611a46565b7fcf28ef970000000000000000000000000000000000000000000000000000000081149150611a3f565b7f915074d80000000000000000000000000000000000000000000000000000000081149150611a38565b3461019c576102007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261019c5767ffffffffffffffff60043581811161019c573660238201121561019c57611b62903690602481600401359101612268565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101c0811261019c5761014060405191611b9e83612155565b1261019c5760405192611bb0846121a0565b60243573ffffffffffffffffffffffffffffffffffffffff8116810361019c578452602093604435858201526064356040820152608435606082015260a435608082015260c43560a082015260e43560c08201526101043573ffffffffffffffffffffffffffffffffffffffff8116810361019c5760e08201526101243561010082015261014435610120820152825261016435848301526101843560408301526101a43560608301526101c43560808301526101e43590811161019c57611c7c9036906004016122c2565b905a3033036120f7578351606081015195603f5a0260061c61271060a0840151890101116120ce5760009681519182611ff0575b5050505090611cca915a9003608085015101923691612268565b925a90600094845193611cdc85613ccc565b9173ffffffffffffffffffffffffffffffffffffffff60e0870151168015600014611ea957505073ffffffffffffffffffffffffffffffffffffffff855116935b5a9003019360a06060820151910151016080860151850390818111611e95575b50508302604085015192818410600014611dce5750506003811015611da157600203611d79576113c99293508093611d7481613d65565b613cf6565b5050507fdeadaa51000000000000000000000000000000000000000000000000000000008152fd5b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526021600452fd5b81611dde92979396940390613c98565b506003841015611e6857507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f60808683015192519473ffffffffffffffffffffffffffffffffffffffff865116948873ffffffffffffffffffffffffffffffffffffffff60e0890151169701519160405192835215898301528760408301526060820152a46113c9565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526021600452fd5b6064919003600a0204909301928780611d3d565b8095918051611eba575b5050611d1d565b6003861015611fc1576002860315611eb35760a088015190823b1561019c57600091611f2491836040519586809581947f7c627b210000000000000000000000000000000000000000000000000000000083528d60048401526080602484015260848301906123c6565b8b8b0260448301528b60648301520393f19081611fad575b50611fa65787893d610800808211611f9e575b506040519282828501016040528184528284013e610e7e6040519283927fad7954bc000000000000000000000000000000000000000000000000000000008452600484015260248301906123c6565b905083611f4f565b8980611eb3565b611fb89199506121bd565b6000978a611f3c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91600092918380938c73ffffffffffffffffffffffffffffffffffffffff885116910192f115612023575b808080611cb0565b611cca929195503d6108008082116120c6575b5060405190888183010160405280825260008983013e805161205f575b5050600194909161201b565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20188870151918973ffffffffffffffffffffffffffffffffffffffff8551169401516120bc604051928392835260408d84015260408301906123c6565b0390a38680612053565b905088612036565b877fdeaddead000000000000000000000000000000000000000000000000000000006000526000fd5b606486604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b60a0810190811067ffffffffffffffff82111761217157604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610140810190811067ffffffffffffffff82111761217157604052565b67ffffffffffffffff811161217157604052565b6060810190811067ffffffffffffffff82111761217157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761217157604052565b67ffffffffffffffff811161217157601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b9291926122748261222e565b9161228260405193846121ed565b82948184528183011161019c578281602093846000960137010152565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361019c57565b9181601f8401121561019c5782359167ffffffffffffffff831161019c576020838186019501011161019c57565b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361019c57565b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc83011261019c5760043567ffffffffffffffff9283821161019c578060238301121561019c57816004013593841161019c5760248460051b8301011161019c57602401919060243573ffffffffffffffffffffffffffffffffffffffff8116810361019c5790565b60005b8381106123b65750506000910152565b81810151838201526020016123a6565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602093612402815180928187528780880191016123a3565b0116010190565b91908201809211610b4f57565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610b4f5760010190565b91908203918211610b4f57565b3d1561247b573d906124618261222e565b9161246f60405193846121ed565b82523d6000602084013e565b606090565b604061248e8183018361284b565b90818351918237206124a3606084018461284b565b90818451918237209260c06124bb60e083018361284b565b908186519182372091845195602087019473ffffffffffffffffffffffffffffffffffffffff833516865260208301358789015260608801526080870152608081013560a087015260a081013582870152013560e08501526101009081850152835261012083019167ffffffffffffffff918484108385111761217157838252845190206101408501908152306101608601524661018086015260608452936101a00191821183831017612171575251902090565b67ffffffffffffffff81116121715760051b60200190565b9061259282612570565b6040906125a260405191826121ed565b8381527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06125d08295612570565b019160005b8381106125e25750505050565b60209082516125f081612155565b83516125fb816121a0565b600081526000849181838201528187820152816060818184015260809282848201528260a08201528260c08201528260e082015282610100820152826101208201528652818587015281898701528501528301528286010152016125d5565b805182101561266e5760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b919081101561266e5760051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee18136030182121561019c570190565b9081602091031261019c575173ffffffffffffffffffffffffffffffffffffffff8116810361019c5790565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b7f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4602073ffffffffffffffffffffffffffffffffffffffff61278a3485613c98565b936040519485521692a2565b919081101561266e5760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18136030182121561019c570190565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561019c570180359067ffffffffffffffff821161019c57602001918160051b3603831361019c57565b3573ffffffffffffffffffffffffffffffffffffffff8116810361019c5790565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561019c570180359067ffffffffffffffff821161019c5760200191813603831361019c57565b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561019c57016020813591019167ffffffffffffffff821161019c57813603831361019c57565b61012091813573ffffffffffffffffffffffffffffffffffffffff811680910361019c576129626129476129ba9561299b93855260208601356020860152612937604087018761289c565b9091806040880152860191612709565b612954606086018661289c565b908583036060870152612709565b6080840135608084015260a084013560a084015260c084013560c084015261298d60e085018561289c565b9084830360e0860152612709565b916129ac610100918281019061289c565b929091818503910152612709565b90565b60028054146129cc5760028055565b60046040517f3ee5aeb5000000000000000000000000000000000000000000000000000000008152fd5b926000905a93805194843573ffffffffffffffffffffffffffffffffffffffff811680910361019c5786526020850135602087015260808501356fffffffffffffffffffffffffffffffff90818116606089015260801c604088015260a086013560c088015260c086013590811661010088015260801c610120870152612a8060e086018661284b565b801561357b576034811061351d578060141161019c578060241161019c5760341161019c57602481013560801c60a0880152601481013560801c60808801523560601c60e08701525b612ad285612480565b60208301526040860151946effffffffffffffffffffffffffffff8660c08901511760608901511760808901511760a0890151176101008901511761012089015117116134bf57604087015160608801510160808801510160a08801510160c0880151016101008801510296835173ffffffffffffffffffffffffffffffffffffffff81511690612b66604085018561284b565b806131e4575b505060e0015173ffffffffffffffffffffffffffffffffffffffff1690600082156131ac575b6020612bd7918b828a01516000868a604051978896879586937f19822f7c00000000000000000000000000000000000000000000000000000000855260048501613db5565b0393f160009181613178575b50612c8b573d8c610800808311612c83575b50604051916020818401016040528083526000602084013e610e7e6040519283927f65c8fd4d000000000000000000000000000000000000000000000000000000008452600484015260606024840152600d60648401527f4141323320726576657274656400000000000000000000000000000000000000608484015260a0604484015260a48301906123c6565b915082612bf5565b9a92939495969798999a91156130f2575b509773ffffffffffffffffffffffffffffffffffffffff835116602084015190600052600160205260406000208160401c60005260205267ffffffffffffffff604060002091825492612cee84612416565b9055160361308d575a8503116130285773ffffffffffffffffffffffffffffffffffffffff60e0606093015116612d42575b509060a09184959697986040608096015260608601520135905a900301910152565b969550505a9683519773ffffffffffffffffffffffffffffffffffffffff60e08a01511680600052600060205260406000208054848110612fc3576080612dcd9a9b9c600093878094039055015192602089015183604051809d819582947f52b7512c0000000000000000000000000000000000000000000000000000000084528c60048501613db5565b039286f1978860009160009a612f36575b50612e86573d8b610800808311612e7e575b50604051916020818401016040528083526000602084013e610e7e6040519283927f65c8fd4d000000000000000000000000000000000000000000000000000000008452600484015260606024840152600d60648401527f4141333320726576657274656400000000000000000000000000000000000000608484015260a0604484015260a48301906123c6565b915082612df0565b9991929394959697989998925a900311612eab57509096959094939291906080612d20565b60a490604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602760448201527f41413336206f766572207061796d6173746572566572696669636174696f6e4760648201527f61734c696d6974000000000000000000000000000000000000000000000000006084820152fd5b915098503d90816000823e612f4b82826121ed565b604081838101031261019c5780519067ffffffffffffffff821161019c57828101601f83830101121561019c578181015191612f868361222e565b93612f9460405195866121ed565b838552820160208483850101011161019c57602092612fba9184808701918501016123a3565b01519838612dde565b60848b604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601e60448201527f41413331207061796d6173746572206465706f73697420746f6f206c6f7700006064820152fd5b608490604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601e60448201527f41413236206f76657220766572696669636174696f6e4761734c696d697400006064820152fd5b608482604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601a60448201527f4141323520696e76616c6964206163636f756e74206e6f6e63650000000000006064820152fd5b600052600060205260406000208054808c11613113578b9003905538612c9c565b608484604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152fd5b9091506020813d6020116131a4575b81613194602093836121ed565b8101031261019c57519038612be3565b3d9150613187565b508060005260006020526040600020548a81116000146131d75750612bd7602060005b915050612b92565b6020612bd7918c036131cf565b833b61345a57604088510151602060405180927f570e1a360000000000000000000000000000000000000000000000000000000082528260048301528160008161323260248201898b612709565b039273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000efc2c1444ebcc4db75e7613d20c6a62ff67a167c1690f1908115610db75760009161343b575b5073ffffffffffffffffffffffffffffffffffffffff811680156133d6578503613371573b1561330c5760141161019c5773ffffffffffffffffffffffffffffffffffffffff9183887fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d604060e0958787602086015195510151168251913560601c82526020820152a391612b6c565b60848d604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152fd5b60848e604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152602060448201527f4141313420696e6974436f6465206d7573742072657475726e2073656e6465726064820152fd5b60848f604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601b60448201527f4141313320696e6974436f6465206661696c6564206f72204f4f4700000000006064820152fd5b613454915060203d602011610db057610da181836121ed565b3861327c565b60848d604051907f220266b6000000000000000000000000000000000000000000000000000000008252600482015260406024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b5050600060e087015260006080870152600060a0870152612ac9565b9092915a906060810151916040928351967fffffffff00000000000000000000000000000000000000000000000000000000886135d7606084018461284b565b600060038211613b9f575b7f8dd7712f0000000000000000000000000000000000000000000000000000000094168403613a445750505061379d6000926136b292602088015161363a8a5193849360208501528b602485015260648401906128ec565b90604483015203906136727fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0928381018352826121ed565b61379189519485927e42dc5300000000000000000000000000000000000000000000000000000000602085015261020060248501526102248401906123c6565b613760604484018b60806101a091805173ffffffffffffffffffffffffffffffffffffffff808251168652602082015160208701526040820151604087015260608201516060870152838201518487015260a082015160a087015260c082015160c087015260e08201511660e0860152610100808201519086015261012080910151908501526020810151610140850152604081015161016085015260608101516101808501520151910152565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83820301610204840152876123c6565b039081018352826121ed565b6020918183809351910182305af1600051988652156137bf575b505050505050565b909192939495965060003d8214613a3a575b7fdeaddead00000000000000000000000000000000000000000000000000000000810361385b57608487878051917f220266b600000000000000000000000000000000000000000000000000000000835260048301526024820152600f60448201527f41413935206f7574206f662067617300000000000000000000000000000000006064820152fd5b7fdeadaa510000000000000000000000000000000000000000000000000000000091929395949650146000146138c55750506138a961389e6138b8935a90612443565b608085015190612409565b9083015183611d748295613d65565b905b3880808080806137b7565b909261395290828601518651907ff62676f440ff169a3a9afdbf812e89e7f95975ee8e5c31214ffdef631c5f479273ffffffffffffffffffffffffffffffffffffffff9580878551169401516139483d610800808211613a32575b508a519084818301018c5280825260008583013e8a805194859485528401528a8301906123c6565b0390a35a90612443565b916139636080860193845190612409565b926000905a94829488519761397789613ccc565b948260e08b0151168015600014613a1857505050875116955b5a9003019560a06060820151910151019051860390818111613a04575b5050840290850151928184106000146139de57505080611e68575090816139d89293611d7481613d65565b906138ba565b6139ee9082849397950390613c98565b50611e68575090826139ff92613cf6565b6139d8565b6064919003600a02049094019338806139ad565b90919892509751613a2a575b50613990565b955038613a24565b905038613920565b8181803e516137d1565b613b97945082935090613a8c917e42dc53000000000000000000000000000000000000000000000000000000006020613b6b9501526102006024860152610224850191612709565b613b3a604484018860806101a091805173ffffffffffffffffffffffffffffffffffffffff808251168652602082015160208701526040820151604087015260608201516060870152838201518487015260a082015160a087015260c082015160c087015260e08201511660e0860152610100808201519086015261012080910151908501526020810151610140850152604081015161016085015260608101516101808501520151910152565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83820301610204840152846123c6565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081018952886121ed565b60008761379d565b5081356135e2565b73ffffffffffffffffffffffffffffffffffffffff168015613c3a57600080809381935af1613bd4612450565b5015613bdc57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b73ffffffffffffffffffffffffffffffffffffffff166000526000602052613cc66040600020918254612409565b80915590565b610120610100820151910151808214613cf257480180821015613ced575090565b905090565b5090565b9190917f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f6080602083015192519473ffffffffffffffffffffffffffffffffffffffff946020868851169660e089015116970151916040519283526000602084015260408301526060820152a4565b60208101519051907f67b4fa9642f42120bf031f3051d1824b0fe25627945b27b8a6a65d5761d5482e60208073ffffffffffffffffffffffffffffffffffffffff855116940151604051908152a3565b613dcd604092959493956060835260608301906128ec565b9460208201520152565b8015613e6457600060408051613dec816121d1565b828152826020820152015273ffffffffffffffffffffffffffffffffffffffff811690604065ffffffffffff91828160a01c16908115613e5c575b60d01c92825191613e37836121d1565b8583528460208401521691829101524211908115613e5457509091565b905042109091565b839150613e27565b5060009060009056fea2646970667358221220b094fd69f04977ae9458e5ba422d01cd2d20dbcfca0992ff37f19aa07deec25464736f6c63430008170033"; + bytes internal constant CreateXCode = + hex"60806040526004361061018a5760003560e01c806381503da1116100d6578063d323826a1161007f578063e96deee411610059578063e96deee414610395578063f5745aba146103a8578063f9664498146103bb57600080fd5b8063d323826a1461034f578063ddda0acb1461036f578063e437252a1461038257600080fd5b80639c36a286116100b05780639c36a28614610316578063a7db93f214610329578063c3fe107b1461033c57600080fd5b806381503da1146102d0578063890c283b146102e357806398e810771461030357600080fd5b80632f990e3f116101385780636cec2536116101125780636cec25361461027d57806374637a7a1461029d5780637f565360146102bd57600080fd5b80632f990e3f1461023757806331a7c8c81461024a57806342d654fc1461025d57600080fd5b806327fe18221161016957806327fe1822146101f15780632852527a1461020457806328ddd0461461021757600080fd5b8062d84acb1461018f57806326307668146101cb57806326a32fc7146101de575b600080fd5b6101a261019d366004612915565b6103ce565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6101a26101d9366004612994565b6103e6565b6101a26101ec3660046129db565b610452565b6101a26101ff3660046129db565b6104de565b6101a2610212366004612a39565b610539565b34801561022357600080fd5b506101a2610232366004612a90565b6106fe565b6101a2610245366004612aa9565b61072a565b6101a2610258366004612aa9565b6107bb565b34801561026957600080fd5b506101a2610278366004612b1e565b6107c9565b34801561028957600080fd5b506101a2610298366004612a90565b610823565b3480156102a957600080fd5b506101a26102b8366004612b4a565b61084f565b6101a26102cb3660046129db565b611162565b6101a26102de366004612b74565b6111e8565b3480156102ef57600080fd5b506101a26102fe366004612bac565b611276565b6101a2610311366004612bce565b6112a3565b6101a2610324366004612994565b611505565b6101a2610337366004612c49565b6116f1565b6101a261034a366004612aa9565b611964565b34801561035b57600080fd5b506101a261036a366004612cd9565b6119ed565b6101a261037d366004612c49565b611a17565b6101a2610390366004612bce565b611e0c565b6101a26103a3366004612915565b611e95565b6101a26103b6366004612bce565b611ea4565b6101a26103c9366004612b74565b611f2d565b60006103dd8585858533611a17565b95945050505050565b6000806103f2846120db565b90508083516020850134f59150610408826123d3565b604051819073ffffffffffffffffffffffffffffffffffffffff8416907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a35092915050565b60006104d86104d260408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b836103e6565b92915050565b600081516020830134f090506104f3816123d3565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a2919050565b600080610545856120db565b905060008460601b90506040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528160148201527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006028820152826037826000f593505073ffffffffffffffffffffffffffffffffffffffff8316610635576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed1660048201526024015b60405180910390fd5b604051829073ffffffffffffffffffffffffffffffffffffffff8516907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a36000808473ffffffffffffffffffffffffffffffffffffffff1634876040516106a19190612d29565b60006040518083038185875af1925050503d80600081146106de576040519150601f19603f3d011682016040523d82523d6000602084013e6106e3565b606091505b50915091506106f382828961247d565b505050509392505050565b60006104d87f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed8361084f565b60006107b36107aa60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b85858533611a17565b949350505050565b60006107b3848484336112a3565b60006040518260005260ff600b53836020527f21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f6040526055600b20601452806040525061d694600052600160345350506017601e20919050565b60006104d8827f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed6107c9565b600060607f9400000000000000000000000000000000000000000000000000000000000000610887600167ffffffffffffffff612d45565b67ffffffffffffffff16841115610902576040517f3c55ab3b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b836000036109c7576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f800000000000000000000000000000000000000000000000000000000000000060368201526037015b6040516020818303038152906040529150611152565b607f8411610a60576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527fff0000000000000000000000000000000000000000000000000000000000000080831660218301527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b16602283015260f886901b1660368201526037016109b1565b60ff8411610b1f576040517fd70000000000000000000000000000000000000000000000000000000000000060208201527fff0000000000000000000000000000000000000000000000000000000000000080831660218301527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b1660228301527f8100000000000000000000000000000000000000000000000000000000000000603683015260f886901b1660378201526038016109b1565b61ffff8411610bff576040517fd80000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f820000000000000000000000000000000000000000000000000000000000000060368201527fffff00000000000000000000000000000000000000000000000000000000000060f086901b1660378201526039016109b1565b62ffffff8411610ce0576040517fd90000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f830000000000000000000000000000000000000000000000000000000000000060368201527fffffff000000000000000000000000000000000000000000000000000000000060e886901b166037820152603a016109b1565b63ffffffff8411610dc2576040517fda0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f840000000000000000000000000000000000000000000000000000000000000060368201527fffffffff0000000000000000000000000000000000000000000000000000000060e086901b166037820152603b016109b1565b64ffffffffff8411610ea5576040517fdb0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f850000000000000000000000000000000000000000000000000000000000000060368201527fffffffffff00000000000000000000000000000000000000000000000000000060d886901b166037820152603c016109b1565b65ffffffffffff8411610f89576040517fdc0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f860000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffff000000000000000000000000000000000000000000000000000060d086901b166037820152603d016109b1565b66ffffffffffffff841161106e576040517fdd0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f870000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffffff0000000000000000000000000000000000000000000000000060c886901b166037820152603e016109b1565b6040517fde0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f880000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffffffff00000000000000000000000000000000000000000000000060c086901b166037820152603f0160405160208183030381529060405291505b5080516020909101209392505050565b60006104d86111e260408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b83611505565b600061126f61126860408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b8484610539565b9392505050565b600061126f83837f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed6119ed565b60008451602086018451f090506112b9816123d3565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a26000808273ffffffffffffffffffffffffffffffffffffffff168560200151876040516113279190612d29565b60006040518083038185875af1925050503d8060008114611364576040519150601f19603f3d011682016040523d82523d6000602084013e611369565b606091505b5091509150816113c9577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed1631156114fb578373ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed73ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d8060008114611495576040519150601f19603f3d011682016040523d82523d6000602084013e61149a565b606091505b509092509050816114fb577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b5050949350505050565b600080611511846120db565b905060006040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f30000000000000000000000000000000081525090506000828251602084016000f5905073ffffffffffffffffffffffffffffffffffffffff81166115e0576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b604051839073ffffffffffffffffffffffffffffffffffffffff8316907f2feea65dd4e9f9cbd86b74b7734210c59a1b2981b5b137bd0ee3e208200c906790600090a361162c83610823565b935060008173ffffffffffffffffffffffffffffffffffffffff1634876040516116569190612d29565b60006040518083038185875af1925050503d8060008114611693576040519150601f19603f3d011682016040523d82523d6000602084013e611698565b606091505b505090506116a681866124ff565b60405173ffffffffffffffffffffffffffffffffffffffff8616907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a25050505092915050565b6000806116fd876120db565b9050808651602088018651f59150611714826123d3565b604051819073ffffffffffffffffffffffffffffffffffffffff8416907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a36000808373ffffffffffffffffffffffffffffffffffffffff168660200151886040516117849190612d29565b60006040518083038185875af1925050503d80600081146117c1576040519150601f19603f3d011682016040523d82523d6000602084013e6117c6565b606091505b509150915081611826577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed163115611958578473ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed73ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d80600081146118f2576040519150601f19603f3d011682016040523d82523d6000602084013e6118f7565b606091505b50909250905081611958577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b50505095945050505050565b60006107b36119e460408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b858585336116f1565b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b600080611a23876120db565b905060006040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f30000000000000000000000000000000081525090506000828251602084016000f5905073ffffffffffffffffffffffffffffffffffffffff8116611af2576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b604051839073ffffffffffffffffffffffffffffffffffffffff8316907f2feea65dd4e9f9cbd86b74b7734210c59a1b2981b5b137bd0ee3e208200c906790600090a3611b3e83610823565b935060008173ffffffffffffffffffffffffffffffffffffffff1687600001518a604051611b6c9190612d29565b60006040518083038185875af1925050503d8060008114611ba9576040519150601f19603f3d011682016040523d82523d6000602084013e611bae565b606091505b50509050611bbc81866124ff565b60405173ffffffffffffffffffffffffffffffffffffffff8616907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a260608573ffffffffffffffffffffffffffffffffffffffff1688602001518a604051611c299190612d29565b60006040518083038185875af1925050503d8060008114611c66576040519150601f19603f3d011682016040523d82523d6000602084013e611c6b565b606091505b50909250905081611ccc577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed163115611dfe578673ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed73ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d8060008114611d98576040519150601f19603f3d011682016040523d82523d6000602084013e611d9d565b606091505b50909250905081611dfe577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b505050505095945050505050565b60006103dd611e8c60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b868686866116f1565b60006103dd85858585336116f1565b60006103dd611f2460408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b86868686611a17565b6000808360601b90506040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528160148201527f5af43d82803e903d91602b57fd5bf3000000000000000000000000000000000060288201526037816000f092505073ffffffffffffffffffffffffffffffffffffffff8216612016576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b60405173ffffffffffffffffffffffffffffffffffffffff8316907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a26000808373ffffffffffffffffffffffffffffffffffffffff1634866040516120809190612d29565b60006040518083038185875af1925050503d80600081146120bd576040519150601f19603f3d011682016040523d82523d6000602084013e6120c2565b606091505b50915091506120d282828861247d565b50505092915050565b60008060006120e9846125b3565b9092509050600082600281111561210257612102612e02565b1480156121205750600081600281111561211e5761211e612e02565b145b1561215e57604080513360208201524691810191909152606081018590526080016040516020818303038152906040528051906020012092506123cc565b600082600281111561217257612172612e02565b1480156121905750600181600281111561218e5761218e612e02565b145b156121b0576121a9338560009182526020526040902090565b92506123cc565b60008260028111156121c4576121c4612e02565b03612233576040517f13b3a2a100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b600182600281111561224757612247612e02565b1480156122655750600081600281111561226357612263612e02565b145b1561227e576121a9468560009182526020526040902090565b600182600281111561229257612292612e02565b1480156122b0575060028160028111156122ae576122ae612e02565b145b1561231f576040517f13b3a2a100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b61239a60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b84036123a657836123c9565b604080516020810186905201604051602081830303815290604052805190602001205b92505b5050919050565b73ffffffffffffffffffffffffffffffffffffffff8116158061240b575073ffffffffffffffffffffffffffffffffffffffff81163b155b1561247a576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b50565b82158061249f575073ffffffffffffffffffffffffffffffffffffffff81163b155b156124fa577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed826040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b505050565b811580612520575073ffffffffffffffffffffffffffffffffffffffff8116155b80612540575073ffffffffffffffffffffffffffffffffffffffff81163b155b156125af576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b5050565b600080606083901c3314801561261057508260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000145b1561262057506000905080915091565b606083901c3314801561265a57507fff00000000000000000000000000000000000000000000000000000000000000601484901a60f81b16155b1561266b5750600090506001915091565b33606084901c036126825750600090506002915091565b606083901c1580156126db57508260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000145b156126ec5750600190506000915091565b606083901c15801561272557507fff00000000000000000000000000000000000000000000000000000000000000601484901a60f81b16155b1561273557506001905080915091565b606083901c61274a5750600190506002915091565b8260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000036127a55750600290506000915091565b8260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166000036127e15750600290506001915091565b506002905080915091565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261282c57600080fd5b813567ffffffffffffffff80821115612847576128476127ec565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561288d5761288d6127ec565b816040528381528660208588010111156128a657600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000604082840312156128d857600080fd5b6040516040810181811067ffffffffffffffff821117156128fb576128fb6127ec565b604052823581526020928301359281019290925250919050565b60008060008060a0858703121561292b57600080fd5b84359350602085013567ffffffffffffffff8082111561294a57600080fd5b6129568883890161281b565b9450604087013591508082111561296c57600080fd5b506129798782880161281b565b92505061298986606087016128c6565b905092959194509250565b600080604083850312156129a757600080fd5b82359150602083013567ffffffffffffffff8111156129c557600080fd5b6129d18582860161281b565b9150509250929050565b6000602082840312156129ed57600080fd5b813567ffffffffffffffff811115612a0457600080fd5b6107b38482850161281b565b803573ffffffffffffffffffffffffffffffffffffffff81168114612a3457600080fd5b919050565b600080600060608486031215612a4e57600080fd5b83359250612a5e60208501612a10565b9150604084013567ffffffffffffffff811115612a7a57600080fd5b612a868682870161281b565b9150509250925092565b600060208284031215612aa257600080fd5b5035919050565b600080600060808486031215612abe57600080fd5b833567ffffffffffffffff80821115612ad657600080fd5b612ae28783880161281b565b94506020860135915080821115612af857600080fd5b50612b058682870161281b565b925050612b1585604086016128c6565b90509250925092565b60008060408385031215612b3157600080fd5b82359150612b4160208401612a10565b90509250929050565b60008060408385031215612b5d57600080fd5b612b6683612a10565b946020939093013593505050565b60008060408385031215612b8757600080fd5b612b9083612a10565b9150602083013567ffffffffffffffff8111156129c557600080fd5b60008060408385031215612bbf57600080fd5b50508035926020909101359150565b60008060008060a08587031215612be457600080fd5b843567ffffffffffffffff80821115612bfc57600080fd5b612c088883890161281b565b95506020870135915080821115612c1e57600080fd5b50612c2b8782880161281b565b935050612c3b86604087016128c6565b915061298960808601612a10565b600080600080600060c08688031215612c6157600080fd5b85359450602086013567ffffffffffffffff80821115612c8057600080fd5b612c8c89838a0161281b565b95506040880135915080821115612ca257600080fd5b50612caf8882890161281b565b935050612cbf87606088016128c6565b9150612ccd60a08701612a10565b90509295509295909350565b600080600060608486031215612cee57600080fd5b8335925060208401359150612b1560408501612a10565b60005b83811015612d20578181015183820152602001612d08565b50506000910152565b60008251612d3b818460208701612d05565b9190910192915050565b67ffffffffffffffff828116828216039080821115612d8d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5092915050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260008251806040840152612dcf816060850160208701612d05565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c6343000817000a"; + bytes internal constant BeaconBlockRootsCode = hex"3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500"; @@ -118,6 +124,7 @@ library Preinstalls { if (_addr == Permit2) return getPermit2Code(_chainID); if (_addr == BeaconBlockRoots) return BeaconBlockRootsCode; + if (_addr == CreateX) return CreateXCode; revert("Preinstalls: unknown preinstall"); } @@ -138,6 +145,7 @@ library Preinstalls { if (_addr == SenderCreator_v070) return "SenderCreator_v070"; if (_addr == EntryPoint_v070) return "EntryPoint_v070"; if (_addr == BeaconBlockRoots) return "BeaconBlockRoots"; + if (_addr == CreateX) return "CreateX"; revert("Preinstalls: unnamed preinstall"); } diff --git a/packages/contracts-bedrock/test/L2Genesis.t.sol b/packages/contracts-bedrock/test/L2Genesis.t.sol index 23c457da6a2f..be5cc0c50edf 100644 --- a/packages/contracts-bedrock/test/L2Genesis.t.sol +++ b/packages/contracts-bedrock/test/L2Genesis.t.sol @@ -188,7 +188,7 @@ contract L2GenesisTest is Test { expected += 2048 - 2; // predeploy proxies expected += 21; // predeploy implementations (excl. legacy erc20-style eth and legacy message sender) expected += 256; // precompiles - expected += 12; // preinstalls + expected += 13; // preinstalls expected += 1; // 4788 deployer account // 16 prefunded dev accounts are excluded assertEq(expected, getJSONKeyCount(_path), "key count check"); diff --git a/packages/contracts-bedrock/test/Preinstalls.t.sol b/packages/contracts-bedrock/test/Preinstalls.t.sol index eca9a063b21c..a0da8c5e32cc 100644 --- a/packages/contracts-bedrock/test/Preinstalls.t.sol +++ b/packages/contracts-bedrock/test/Preinstalls.t.sol @@ -118,4 +118,8 @@ contract PreinstallsTest is CommonTest { assertPreinstall(Preinstalls.BeaconBlockRoots, Preinstalls.BeaconBlockRootsCode); assertEq(vm.getNonce(Preinstalls.BeaconBlockRootsSender), 1, "4788 sender must have nonce=1"); } + + function test_preinstall_createX_succeeds() external view { + assertPreinstall(Preinstalls.CreateX, Preinstalls.CreateXCode); + } } diff --git a/packages/contracts-bedrock/test/setup/Setup.sol b/packages/contracts-bedrock/test/setup/Setup.sol index 0dfb6bd47f24..325281f890df 100644 --- a/packages/contracts-bedrock/test/setup/Setup.sol +++ b/packages/contracts-bedrock/test/setup/Setup.sol @@ -233,6 +233,7 @@ contract Setup { labelPreinstall(Preinstalls.SenderCreator_v070); labelPreinstall(Preinstalls.EntryPoint_v070); labelPreinstall(Preinstalls.BeaconBlockRoots); + labelPreinstall(Preinstalls.CreateX); console.log("Setup: completed L2 genesis"); } From 3e68cf018d8b9b474e918def32a56d1dbf028d83 Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Fri, 30 Aug 2024 15:35:34 -0600 Subject: [PATCH 012/264] Update contracts publish job to use env vars rather than contexts (#11687) Contexts are scoped to a specific GitHub user group, which doesn't work with the GitHub merge queue or OSS contributors. This PR updates the packaging job to use raw project-level env vars instead (which are not user-scoped), and to only run on commits to `develop`. --- .circleci/config.yml | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 82b3119acc8b..ed4a77f196ec 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -35,6 +35,9 @@ parameters: docker_publish_dispatch: type: boolean default: false + publish_contract_artifacts_dispatch: + type: boolean + default: false orbs: go: circleci/go@1.8.0 @@ -1474,10 +1477,20 @@ jobs: - gcp-oidc-authenticate: gcp_cred_config_file_path: /root/gcp_cred_config.json oidc_token_file_path: /root/oidc_token.json - service_account_email: GCP_SERVICE_CONTRACTS_ACCOUNT_EMAIL + project_id: GCP_TOOLS_ARTIFACTS_PROJECT_ID + service_account_email: GCP_CONTRACTS_PUBLISHER_SERVICE_ACCOUNT_EMAIL - checkout - - attach_workspace: { at: "." } - install-contracts-dependencies + - run: + name: Pull artifacts + command: bash scripts/ops/pull-artifacts.sh + working_directory: packages/contracts-bedrock + - run: + name: Build contracts + environment: + FOUNDRY_PROFILE: ci + command: just build + working_directory: packages/contracts-bedrock - run: name: Publish artifacts command: bash scripts/ops/publish-artifacts.sh @@ -1497,11 +1510,6 @@ workflows: jobs: - pnpm-monorepo: name: pnpm-monorepo - - publish-contract-artifacts: - requires: - - pnpm-monorepo - context: - - oplabs-gcr-release - contracts-bedrock-tests - contracts-bedrock-coverage - contracts-bedrock-checks: @@ -1955,6 +1963,14 @@ workflows: - slack - oplabs-fpp-nodes + develop-publish-contract-artifacts: + when: + or: + - equal: [ "develop", <> ] + - equal: [ true, <> ] + jobs: + - publish-contract-artifacts + develop-fault-proofs: when: and: From 18f64536b8ec6540fd80ea2e43214b0f6b6a0023 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Sat, 31 Aug 2024 10:44:55 +1000 Subject: [PATCH 013/264] op-program: Prune L1 blocks after advancing origin (#11530) * op-program: Retry pruning L1 blocks when advancing origin to include the parent L1 origin Add e2e test to reproduce corner case when deploying a chain at L1 genesis. * Trim once, after any new origin is added. * Add unit test. * Add action test * Review feedback. * Improve test assertion --- op-e2e/actions/batch_queue_test.go | 98 +++++++++++++++++++++ op-e2e/e2eutils/disputegame/claim_helper.go | 5 ++ op-e2e/faultproofs/output_cannon_test.go | 42 +++++++++ op-node/rollup/derive/batch_queue.go | 30 +++---- op-node/rollup/derive/batch_queue_test.go | 62 +++++++++++++ 5 files changed, 222 insertions(+), 15 deletions(-) create mode 100644 op-e2e/actions/batch_queue_test.go diff --git a/op-e2e/actions/batch_queue_test.go b/op-e2e/actions/batch_queue_test.go new file mode 100644 index 000000000000..40ff0a2da2af --- /dev/null +++ b/op-e2e/actions/batch_queue_test.go @@ -0,0 +1,98 @@ +package actions + +import ( + "testing" + + altda "github.com/ethereum-optimism/optimism/op-alt-da" + batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-node/node/safedb" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +// TestDeriveChainFromNearL1Genesis tests a corner case where when the derivation pipeline starts, the +// safe head has an L1 origin of block 1. The derivation then starts with pipeline origin of L1 genesis, +// just one block prior to the origin of the safe head. +// This is a regression test, previously the pipeline encountered got stuck in a reset loop with the error: +// buffered L1 chain epoch %s in batch queue does not match safe head origin %s +func TestDeriveChainFromNearL1Genesis(gt *testing.T) { + t := NewDefaultTesting(gt) + p := &e2eutils.TestParams{ + MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) + SequencerWindowSize: 24, + ChannelTimeout: 20, + L1BlockTime: 12, + } + dp := e2eutils.MakeDeployParams(t, p) + // do not activate Delta hardfork for verifier + applyDeltaTimeOffset(dp, nil) + sd := e2eutils.Setup(t, dp, defaultAlloc) + logger := testlog.Logger(t, log.LevelInfo) + miner, seqEngine, sequencer := setupSequencerTest(t, sd, logger) + + miner.ActEmptyBlock(t) + require.EqualValues(gt, 1, miner.l1Chain.CurrentBlock().Number.Uint64()) + + ref, err := derive.L2BlockToBlockRef(sequencer.rollupCfg, seqEngine.l2Chain.Genesis()) + require.NoError(gt, err) + require.EqualValues(gt, 0, ref.L1Origin.Number) + + sequencer.ActL1HeadSignal(t) + sequencer.ActBuildToL1Head(t) + l2BlockNum := seqEngine.l2Chain.CurrentBlock().Number.Uint64() + ref, err = derive.L2BlockToBlockRef(sequencer.rollupCfg, seqEngine.l2Chain.GetBlockByNumber(l2BlockNum)) + require.NoError(gt, err) + require.EqualValues(gt, 1, ref.L1Origin.Number) + + miner.ActEmptyBlock(t) + + rollupSeqCl := sequencer.RollupClient() + // Force batcher to submit SingularBatches to L1. + batcher := NewL2Batcher(logger, sd.RollupCfg, &BatcherCfg{ + MinL1TxSize: 0, + MaxL1TxSize: 128_000, + BatcherKey: dp.Secrets.Batcher, + DataAvailabilityType: batcherFlags.CalldataType, + }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) + + batcher.ActSubmitAll(t) + require.EqualValues(gt, l2BlockNum, batcher.l2BufferedBlock.Number) + + // confirm batch on L1 + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + bl := miner.l1Chain.CurrentBlock() + logger.Info("Produced L1 block with batch", + "num", miner.l1Chain.CurrentBlock().Number.Uint64(), + "txs", len(miner.l1Chain.GetBlockByHash(bl.Hash()).Transactions())) + + // Process batches so safe head updates + sequencer.ActL1HeadSignal(t) + sequencer.ActL2PipelineFull(t) + require.EqualValues(gt, l2BlockNum, seqEngine.l2Chain.CurrentSafeBlock().Number.Uint64()) + + // Finalize L1 and process so L2 finalized updates + miner.ActL1Safe(t, miner.l1Chain.CurrentBlock().Number.Uint64()) + miner.ActL1Finalize(t, miner.l1Chain.CurrentBlock().Number.Uint64()) + sequencer.ActL1SafeSignal(t) + sequencer.ActL1FinalizedSignal(t) + sequencer.ActL2PipelineFull(t) + require.EqualValues(gt, l2BlockNum, seqEngine.l2Chain.CurrentFinalBlock().Number.Uint64()) + + // Create a new verifier using the existing engine so it already has the safe and finalized heads set. + // This is the same situation as if op-node restarted at this point. + l2Cl, err := sources.NewEngineClient(seqEngine.RPCClient(), logger, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) + require.NoError(gt, err) + verifier := NewL2Verifier(t, logger, sequencer.l1, miner.BlobStore(), altda.Disabled, l2Cl, sequencer.rollupCfg, sequencer.syncCfg, safedb.Disabled) + verifier.ActL2PipelineFull(t) // Should not get stuck in a reset loop forever + require.EqualValues(gt, l2BlockNum, seqEngine.l2Chain.CurrentSafeBlock().Number.Uint64()) + require.EqualValues(gt, l2BlockNum, seqEngine.l2Chain.CurrentFinalBlock().Number.Uint64()) + syncStatus := verifier.syncStatus.SyncStatus() + require.EqualValues(gt, l2BlockNum, syncStatus.SafeL2.Number) + require.EqualValues(gt, l2BlockNum, syncStatus.FinalizedL2.Number) +} diff --git a/op-e2e/e2eutils/disputegame/claim_helper.go b/op-e2e/e2eutils/disputegame/claim_helper.go index 4eb9c420cc03..a3abf2b79e79 100644 --- a/op-e2e/e2eutils/disputegame/claim_helper.go +++ b/op-e2e/e2eutils/disputegame/claim_helper.go @@ -6,6 +6,7 @@ import ( "slices" "time" + "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum/go-ethereum/common" @@ -98,6 +99,10 @@ func (c *ClaimHelper) RequireCorrectOutputRoot(ctx context.Context) { c.require.Equalf(expected, c.claim, "Should have correct output root in claim %v and position %v", c.Index, c.Position) } +func (c *ClaimHelper) RequireInvalidStatusCode() { + c.require.Equal(byte(mipsevm.VMStatusInvalid), c.claim[0], "should have had invalid status code") +} + func (c *ClaimHelper) Attack(ctx context.Context, value common.Hash, opts ...MoveOpt) *ClaimHelper { c.game.Attack(ctx, c.Index, value, opts...) return c.WaitForCounterClaim(ctx) diff --git a/op-e2e/faultproofs/output_cannon_test.go b/op-e2e/faultproofs/output_cannon_test.go index 797ed2bcd43c..c5ac078df932 100644 --- a/op-e2e/faultproofs/output_cannon_test.go +++ b/op-e2e/faultproofs/output_cannon_test.go @@ -910,3 +910,45 @@ func TestOutputCannonHonestSafeTraceExtension_InvalidRoot(t *testing.T) { game.LogGameData(ctx) require.EqualValues(t, gameTypes.GameStatusChallengerWon, game.Status(ctx)) } + +func TestAgreeFirstBlockWithOriginOf1(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + + ctx := context.Background() + sys, _ := StartFaultDisputeSystem(t) + t.Cleanup(sys.Close) + + rollupClient := sys.RollupClient("sequencer") + blockNum := uint64(0) + limit := uint64(100) + for ; blockNum <= limit; blockNum++ { + require.NoError(t, wait.ForBlock(ctx, sys.NodeClient("sequencer"), blockNum)) + output, err := rollupClient.OutputAtBlock(ctx, blockNum) + require.NoError(t, err) + if output.BlockRef.L1Origin.Number == 1 { + break + } + } + require.Less(t, blockNum, limit) + + // Create a dispute game with a dishonest claim @ L2 block #4 + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + // Make the agreed block the first one with L1 origin of block 1 so the claim is blockNum+1 + game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", blockNum+1, common.Hash{0xCA, 0xFE}) + require.NotNil(t, game) + outputRootClaim := game.DisputeLastBlock(ctx) + game.LogGameData(ctx) + + honestChallenger := game.StartChallenger(ctx, "HonestActor", challenger.WithPrivKey(sys.Cfg.Secrets.Alice)) + + // Wait for the honest challenger to dispute the outputRootClaim. This creates a root of an execution game that we challenge by coercing + // a step at a preimage trace index. + outputRootClaim = outputRootClaim.WaitForCounterClaim(ctx) + game.LogGameData(ctx) + + // Should claim output root is invalid, but actually panics. + outputRootClaim.RequireInvalidStatusCode() + // The above method already verified the image was uploaded and step called successfully + // So we don't waste time resolving the game - that's tested elsewhere. + require.NoError(t, honestChallenger.Close()) +} diff --git a/op-node/rollup/derive/batch_queue.go b/op-node/rollup/derive/batch_queue.go index 3dbfe20d305d..4ca49907c7de 100644 --- a/op-node/rollup/derive/batch_queue.go +++ b/op-node/rollup/derive/batch_queue.go @@ -109,21 +109,6 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, parent eth.L2BlockRef) (*Si } } - // If the epoch is advanced, update bq.l1Blocks - // Advancing epoch must be done after the pipeline successfully apply the entire span batch to the chain. - // Because the span batch can be reverted during processing the batch, then we must preserve existing l1Blocks - // to verify the epochs of the next candidate batch. - if len(bq.l1Blocks) > 0 && parent.L1Origin.Number > bq.l1Blocks[0].Number { - for i, l1Block := range bq.l1Blocks { - if parent.L1Origin.Number == l1Block.Number { - bq.l1Blocks = bq.l1Blocks[i:] - bq.log.Debug("Advancing internal L1 blocks", "next_epoch", bq.l1Blocks[0].ID(), "next_epoch_time", bq.l1Blocks[0].Time) - break - } - } - // If we can't find the origin of parent block, we have to advance bq.origin. - } - // Note: We use the origin that we will have to determine if it's behind. This is important // because it's the future origin that gets saved into the l1Blocks array. // We always update the origin of this stage if it is not the same so after the update code @@ -146,6 +131,21 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, parent eth.L2BlockRef) (*Si bq.log.Info("Advancing bq origin", "origin", bq.origin, "originBehind", originBehind) } + // If the epoch is advanced, update bq.l1Blocks + // Advancing epoch must be done after the pipeline successfully apply the entire span batch to the chain. + // Because the span batch can be reverted during processing the batch, then we must preserve existing l1Blocks + // to verify the epochs of the next candidate batch. + if len(bq.l1Blocks) > 0 && parent.L1Origin.Number > bq.l1Blocks[0].Number { + for i, l1Block := range bq.l1Blocks { + if parent.L1Origin.Number == l1Block.Number { + bq.l1Blocks = bq.l1Blocks[i:] + bq.log.Debug("Advancing internal L1 blocks", "next_epoch", bq.l1Blocks[0].ID(), "next_epoch_time", bq.l1Blocks[0].Time) + break + } + } + // If we can't find the origin of parent block, we have to advance bq.origin. + } + // Load more data into the batch queue outOfData := false if batch, err := bq.prev.NextBatch(ctx); err == io.EOF { diff --git a/op-node/rollup/derive/batch_queue_test.go b/op-node/rollup/derive/batch_queue_test.go index 6712ae15a680..f047f0a7d4fe 100644 --- a/op-node/rollup/derive/batch_queue_test.go +++ b/op-node/rollup/derive/batch_queue_test.go @@ -147,6 +147,7 @@ func TestBatchQueue(t *testing.T) { {"BatchQueueMissing", BatchQueueMissing}, {"BatchQueueAdvancedEpoch", BatchQueueAdvancedEpoch}, {"BatchQueueShuffle", BatchQueueShuffle}, + {"BatchQueueResetOneBlockBeforeOrigin", BatchQueueResetOneBlockBeforeOrigin}, } for _, test := range tests { test := test @@ -224,6 +225,67 @@ func BatchQueueNewOrigin(t *testing.T, batchType int) { require.Equal(t, l1[2], bq.origin) } +// BatchQueueResetOneBlockBeforeOrigin tests that the batch queue properly +// prunes the l1Block recorded as part of a reset when the starting origin +// is exactly one block prior to the safe head origin. +func BatchQueueResetOneBlockBeforeOrigin(t *testing.T, batchType int) { + log := testlog.Logger(t, log.LevelTrace) + l1 := L1Chain([]uint64{10, 15, 20, 25}) + safeHead := eth.L2BlockRef{ + Hash: mockHash(10, 2), + Number: 0, + ParentHash: common.Hash{}, + Time: 20, + L1Origin: l1[1].ID(), + SequenceNumber: 0, + } + cfg := &rollup.Config{ + Genesis: rollup.Genesis{ + L2Time: 10, + }, + BlockTime: 2, + MaxSequencerDrift: 600, + SeqWindowSize: 2, + DeltaTime: getDeltaTime(batchType), + } + + input := &fakeBatchQueueInput{ + batches: []Batch{nil}, + errors: []error{io.EOF}, + origin: l1[0], + } + + bq := NewBatchQueue(log, cfg, input, nil) + _ = bq.Reset(context.Background(), l1[0], eth.SystemConfig{}) + require.Equal(t, []eth.L1BlockRef{l1[0]}, bq.l1Blocks) + + // Prev Origin: 0; Safehead Origin: 1; Internal Origin: 0 + // Should return no data but keep the same origin + data, _, err := bq.NextBatch(context.Background(), safeHead) + require.Nil(t, data) + require.Equal(t, io.EOF, err) + require.Equal(t, []eth.L1BlockRef{l1[0]}, bq.l1Blocks) + require.Equal(t, l1[0], bq.origin) + + // Prev Origin: 1; Safehead Origin: 1; Internal Origin: 0 + // Should record new l1 origin in l1blocks, prune block 0 and advance internal origin + input.origin = l1[1] + data, _, err = bq.NextBatch(context.Background(), safeHead) + require.Nil(t, data) + require.Equalf(t, io.EOF, err, "expected io.EOF but got %v", err) + require.Equal(t, []eth.L1BlockRef{l1[1]}, bq.l1Blocks) + require.Equal(t, l1[1], bq.origin) + + // Prev Origin: 2; Safehead Origin: 1; Internal Origin: 1 + // Should add to l1Blocks + advance internal origin + input.origin = l1[2] + data, _, err = bq.NextBatch(context.Background(), safeHead) + require.Nil(t, data) + require.Equal(t, io.EOF, err) + require.Equal(t, []eth.L1BlockRef{l1[1], l1[2]}, bq.l1Blocks) + require.Equal(t, l1[2], bq.origin) +} + // BatchQueueEager adds a bunch of contiguous batches and asserts that // enough calls to `NextBatch` return all of those batches. func BatchQueueEager(t *testing.T, batchType int) { From 96ecb2ec4963e9193b9702bc293e51aeabda00a5 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Fri, 30 Aug 2024 19:20:10 -0600 Subject: [PATCH 014/264] npmrc: delete (#11699) There is no longer any JS in the monorepo, we can remove the `.npmrc` as its no longer used --- .npmrc | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 .npmrc diff --git a/.npmrc b/.npmrc deleted file mode 100644 index abbc18350ff4..000000000000 --- a/.npmrc +++ /dev/null @@ -1,4 +0,0 @@ -# run prefoo scripts -# npm and yarn support this as a default pnpm defaults to false -enable-pre-post-scripts=true -lockfile=true From c198a893f2e34f619f943fb8279f919f5a2c3045 Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Fri, 30 Aug 2024 19:28:13 -0600 Subject: [PATCH 015/264] Increase executor size on contract publisher (#11701) --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ed4a77f196ec..fd5a05d3658a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1471,7 +1471,7 @@ jobs: publish-contract-artifacts: docker: - image: <> - resource_class: medium + resource_class: xlarge steps: - gcp-cli/install - gcp-oidc-authenticate: From 8ab4d3d8e20f69464d9f5191c110b63f4d5a3df6 Mon Sep 17 00:00:00 2001 From: clabby Date: Sun, 1 Sep 2024 23:15:50 -0400 Subject: [PATCH 016/264] feat(op-program): Use `PebbleDB` for `DiskKV` (#11705) * feat(op-program): Use `PebbleDB` for `DiskKV` * close db * fix `testFaultProofProgramScenario` tests * switch to snappy compression https://github.com/cockroachdb/pebble/issues/3434 * fix tempdir * update compat release * defer k/v until preimage server and hinter have both exited --- op-e2e/system_fpp_test.go | 3 ++ op-program/host/host.go | 11 +++- op-program/host/kvstore/disk.go | 89 ++++++++++++-------------------- op-program/host/kvstore/kv.go | 3 ++ op-program/host/kvstore/mem.go | 4 ++ op-program/scripts/run-compat.sh | 2 +- 6 files changed, 52 insertions(+), 60 deletions(-) diff --git a/op-e2e/system_fpp_test.go b/op-e2e/system_fpp_test.go index c3598880b0cf..50b4b779f75e 100644 --- a/op-e2e/system_fpp_test.go +++ b/op-e2e/system_fpp_test.go @@ -86,6 +86,7 @@ func applySpanBatchActivation(active bool, dp *genesis.DeployConfig) { // - update the state root via a tx // - run program func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool, spanBatchActivated bool) { + t.Helper() InitParallel(t) ctx := context.Background() @@ -186,6 +187,7 @@ func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool, spanBatchActi } func testVerifyL2OutputRoot(t *testing.T, detached bool, spanBatchActivated bool) { + t.Helper() InitParallel(t) ctx := context.Background() @@ -278,6 +280,7 @@ type FaultProofProgramTestScenario struct { // testFaultProofProgramScenario runs the fault proof program in several contexts, given a test scenario. func testFaultProofProgramScenario(t *testing.T, ctx context.Context, sys *System, s *FaultProofProgramTestScenario) { preimageDir := t.TempDir() + fppConfig := oppconf.NewConfig(sys.RollupConfig, sys.L2GenesisCfg.Config, s.L1Head, s.L2Head, s.L2OutputRoot, common.Hash(s.L2Claim), s.L2ClaimBlockNumber) fppConfig.L1URL = sys.NodeEndpoint("l1").RPC() fppConfig.L2URL = sys.NodeEndpoint("sequencer").RPC() diff --git a/op-program/host/host.go b/op-program/host/host.go index ddffde7ee513..582df9bf94af 100644 --- a/op-program/host/host.go +++ b/op-program/host/host.go @@ -122,6 +122,10 @@ func FaultProofProgram(ctx context.Context, logger log.Logger, cfg *config.Confi func PreimageServer(ctx context.Context, logger log.Logger, cfg *config.Config, preimageChannel preimage.FileChannel, hintChannel preimage.FileChannel) error { var serverDone chan error var hinterDone chan error + logger.Info("Starting preimage server") + var kv kvstore.KV + + // Close the preimage/hint channels, and then kv store once the server and hinter have exited. defer func() { preimageChannel.Close() hintChannel.Close() @@ -133,9 +137,12 @@ func PreimageServer(ctx context.Context, logger log.Logger, cfg *config.Config, // Wait for hinter to complete <-hinterDone } + + if kv != nil { + kv.Close() + } }() - logger.Info("Starting preimage server") - var kv kvstore.KV + if cfg.DataDir == "" { logger.Info("Using in-memory storage") kv = kvstore.NewMemKV() diff --git a/op-program/host/kvstore/disk.go b/op-program/host/kvstore/disk.go index 0f6bd19068ae..f2fe96402bbe 100644 --- a/op-program/host/kvstore/disk.go +++ b/op-program/host/kvstore/disk.go @@ -1,93 +1,68 @@ package kvstore import ( - "encoding/hex" "errors" "fmt" - "io" - "os" - "path" + "runtime" "sync" + "github.com/cockroachdb/pebble" "github.com/ethereum/go-ethereum/common" ) -// read/write mode for user/group/other, not executable. -const diskPermission = 0666 - -// DiskKV is a disk-backed key-value store, every key-value pair is a hex-encoded .txt file, with the value as content. +// DiskKV is a disk-backed key-value store, with PebbleDB as the underlying DBMS. // DiskKV is safe for concurrent use with a single DiskKV instance. -// DiskKV is safe for concurrent use between different DiskKV instances of the same disk directory as long as the -// file system supports atomic renames. type DiskKV struct { sync.RWMutex - path string + db *pebble.DB } // NewDiskKV creates a DiskKV that puts/gets pre-images as files in the given directory path. // The path must exist, or subsequent Put/Get calls will error when it does not. func NewDiskKV(path string) *DiskKV { - return &DiskKV{path: path} -} + opts := &pebble.Options{ + Cache: pebble.NewCache(int64(32 * 1024 * 1024)), + MaxConcurrentCompactions: runtime.NumCPU, + Levels: []pebble.LevelOptions{ + {Compression: pebble.SnappyCompression}, + }, + } + db, err := pebble.Open(path, opts) + if err != nil { + panic(fmt.Errorf("failed to open pebbledb at %s: %w", path, err)) + } -func (d *DiskKV) pathKey(k common.Hash) string { - return path.Join(d.path, k.String()+".txt") + return &DiskKV{db: db} } func (d *DiskKV) Put(k common.Hash, v []byte) error { d.Lock() defer d.Unlock() - f, err := openTempFile(d.path, k.String()+".txt.*") - if err != nil { - return fmt.Errorf("failed to open temp file for pre-image %s: %w", k, err) - } - defer os.Remove(f.Name()) // Clean up the temp file if it doesn't actually get moved into place - if _, err := f.Write([]byte(hex.EncodeToString(v))); err != nil { - _ = f.Close() - return fmt.Errorf("failed to write pre-image %s to disk: %w", k, err) - } - if err := f.Close(); err != nil { - return fmt.Errorf("failed to close temp pre-image %s file: %w", k, err) - } - - targetFile := d.pathKey(k) - if err := os.Rename(f.Name(), targetFile); err != nil { - return fmt.Errorf("failed to move temp dir %v to final destination %v: %w", f.Name(), targetFile, err) - } - return nil -} - -func openTempFile(dir string, nameTemplate string) (*os.File, error) { - f, err := os.CreateTemp(dir, nameTemplate) - // Directory has been deleted out from underneath us. Recreate it. - if errors.Is(err, os.ErrNotExist) { - if mkdirErr := os.MkdirAll(dir, 0777); mkdirErr != nil { - return nil, errors.Join(fmt.Errorf("failed to create directory %v: %w", dir, mkdirErr), err) - } - f, err = os.CreateTemp(dir, nameTemplate) - } - if err != nil { - return nil, err - } - return f, nil + return d.db.Set(k.Bytes(), v, pebble.NoSync) } func (d *DiskKV) Get(k common.Hash) ([]byte, error) { d.RLock() defer d.RUnlock() - f, err := os.OpenFile(d.pathKey(k), os.O_RDONLY, diskPermission) + + dat, closer, err := d.db.Get(k.Bytes()) if err != nil { - if errors.Is(err, os.ErrNotExist) { + if errors.Is(err, pebble.ErrNotFound) { return nil, ErrNotFound } - return nil, fmt.Errorf("failed to open pre-image file %s: %w", k, err) - } - defer f.Close() // fine to ignore closing error here - dat, err := io.ReadAll(f) - if err != nil { - return nil, fmt.Errorf("failed to read pre-image from file %s: %w", k, err) + return nil, err } - return hex.DecodeString(string(dat)) + ret := make([]byte, len(dat)) + copy(ret, dat) + closer.Close() + return ret, nil +} + +func (d *DiskKV) Close() error { + d.Lock() + defer d.Unlock() + + return d.db.Close() } var _ KV = (*DiskKV)(nil) diff --git a/op-program/host/kvstore/kv.go b/op-program/host/kvstore/kv.go index e75dcd699d9f..054230950d0b 100644 --- a/op-program/host/kvstore/kv.go +++ b/op-program/host/kvstore/kv.go @@ -19,4 +19,7 @@ type KV interface { // It returns ErrNotFound when the pre-image cannot be found. // KV store implementations may return additional errors specific to the KV storage. Get(k common.Hash) ([]byte, error) + + // Closes the KV store. + Close() error } diff --git a/op-program/host/kvstore/mem.go b/op-program/host/kvstore/mem.go index 9af540e235fa..0c3b950b7e9c 100644 --- a/op-program/host/kvstore/mem.go +++ b/op-program/host/kvstore/mem.go @@ -37,3 +37,7 @@ func (m *MemKV) Get(k common.Hash) ([]byte, error) { } return slices.Clone(v), nil } + +func (m *MemKV) Close() error { + return nil +} diff --git a/op-program/scripts/run-compat.sh b/op-program/scripts/run-compat.sh index ed853a8d980b..296387ac5d0e 100755 --- a/op-program/scripts/run-compat.sh +++ b/op-program/scripts/run-compat.sh @@ -5,7 +5,7 @@ SCRIPTS_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) COMPAT_DIR="${SCRIPTS_DIR}/../temp/compat" TESTNAME="${1?Must specify compat file to run}" -BASEURL="${2:-https://github.com/ethereum-optimism/chain-test-data/releases/download/2024-08-02}" +BASEURL="${2:-https://github.com/ethereum-optimism/chain-test-data/releases/download/2024-09-01}" URL="${BASEURL}/${TESTNAME}.tar.bz" From 4c211faa909c70ce90ea34cc6fbed663d62f1d67 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Mon, 2 Sep 2024 14:49:17 +1000 Subject: [PATCH 017/264] Revert "feat(op-program): Use `PebbleDB` for `DiskKV` (#11705)" (#11707) This reverts commit 8ab4d3d8e20f69464d9f5191c110b63f4d5a3df6. --- op-e2e/system_fpp_test.go | 3 -- op-program/host/host.go | 11 +--- op-program/host/kvstore/disk.go | 89 ++++++++++++++++++++------------ op-program/host/kvstore/kv.go | 3 -- op-program/host/kvstore/mem.go | 4 -- op-program/scripts/run-compat.sh | 2 +- 6 files changed, 60 insertions(+), 52 deletions(-) diff --git a/op-e2e/system_fpp_test.go b/op-e2e/system_fpp_test.go index 50b4b779f75e..c3598880b0cf 100644 --- a/op-e2e/system_fpp_test.go +++ b/op-e2e/system_fpp_test.go @@ -86,7 +86,6 @@ func applySpanBatchActivation(active bool, dp *genesis.DeployConfig) { // - update the state root via a tx // - run program func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool, spanBatchActivated bool) { - t.Helper() InitParallel(t) ctx := context.Background() @@ -187,7 +186,6 @@ func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool, spanBatchActi } func testVerifyL2OutputRoot(t *testing.T, detached bool, spanBatchActivated bool) { - t.Helper() InitParallel(t) ctx := context.Background() @@ -280,7 +278,6 @@ type FaultProofProgramTestScenario struct { // testFaultProofProgramScenario runs the fault proof program in several contexts, given a test scenario. func testFaultProofProgramScenario(t *testing.T, ctx context.Context, sys *System, s *FaultProofProgramTestScenario) { preimageDir := t.TempDir() - fppConfig := oppconf.NewConfig(sys.RollupConfig, sys.L2GenesisCfg.Config, s.L1Head, s.L2Head, s.L2OutputRoot, common.Hash(s.L2Claim), s.L2ClaimBlockNumber) fppConfig.L1URL = sys.NodeEndpoint("l1").RPC() fppConfig.L2URL = sys.NodeEndpoint("sequencer").RPC() diff --git a/op-program/host/host.go b/op-program/host/host.go index 582df9bf94af..ddffde7ee513 100644 --- a/op-program/host/host.go +++ b/op-program/host/host.go @@ -122,10 +122,6 @@ func FaultProofProgram(ctx context.Context, logger log.Logger, cfg *config.Confi func PreimageServer(ctx context.Context, logger log.Logger, cfg *config.Config, preimageChannel preimage.FileChannel, hintChannel preimage.FileChannel) error { var serverDone chan error var hinterDone chan error - logger.Info("Starting preimage server") - var kv kvstore.KV - - // Close the preimage/hint channels, and then kv store once the server and hinter have exited. defer func() { preimageChannel.Close() hintChannel.Close() @@ -137,12 +133,9 @@ func PreimageServer(ctx context.Context, logger log.Logger, cfg *config.Config, // Wait for hinter to complete <-hinterDone } - - if kv != nil { - kv.Close() - } }() - + logger.Info("Starting preimage server") + var kv kvstore.KV if cfg.DataDir == "" { logger.Info("Using in-memory storage") kv = kvstore.NewMemKV() diff --git a/op-program/host/kvstore/disk.go b/op-program/host/kvstore/disk.go index f2fe96402bbe..0f6bd19068ae 100644 --- a/op-program/host/kvstore/disk.go +++ b/op-program/host/kvstore/disk.go @@ -1,68 +1,93 @@ package kvstore import ( + "encoding/hex" "errors" "fmt" - "runtime" + "io" + "os" + "path" "sync" - "github.com/cockroachdb/pebble" "github.com/ethereum/go-ethereum/common" ) -// DiskKV is a disk-backed key-value store, with PebbleDB as the underlying DBMS. +// read/write mode for user/group/other, not executable. +const diskPermission = 0666 + +// DiskKV is a disk-backed key-value store, every key-value pair is a hex-encoded .txt file, with the value as content. // DiskKV is safe for concurrent use with a single DiskKV instance. +// DiskKV is safe for concurrent use between different DiskKV instances of the same disk directory as long as the +// file system supports atomic renames. type DiskKV struct { sync.RWMutex - db *pebble.DB + path string } // NewDiskKV creates a DiskKV that puts/gets pre-images as files in the given directory path. // The path must exist, or subsequent Put/Get calls will error when it does not. func NewDiskKV(path string) *DiskKV { - opts := &pebble.Options{ - Cache: pebble.NewCache(int64(32 * 1024 * 1024)), - MaxConcurrentCompactions: runtime.NumCPU, - Levels: []pebble.LevelOptions{ - {Compression: pebble.SnappyCompression}, - }, - } - db, err := pebble.Open(path, opts) - if err != nil { - panic(fmt.Errorf("failed to open pebbledb at %s: %w", path, err)) - } + return &DiskKV{path: path} +} - return &DiskKV{db: db} +func (d *DiskKV) pathKey(k common.Hash) string { + return path.Join(d.path, k.String()+".txt") } func (d *DiskKV) Put(k common.Hash, v []byte) error { d.Lock() defer d.Unlock() - return d.db.Set(k.Bytes(), v, pebble.NoSync) + f, err := openTempFile(d.path, k.String()+".txt.*") + if err != nil { + return fmt.Errorf("failed to open temp file for pre-image %s: %w", k, err) + } + defer os.Remove(f.Name()) // Clean up the temp file if it doesn't actually get moved into place + if _, err := f.Write([]byte(hex.EncodeToString(v))); err != nil { + _ = f.Close() + return fmt.Errorf("failed to write pre-image %s to disk: %w", k, err) + } + if err := f.Close(); err != nil { + return fmt.Errorf("failed to close temp pre-image %s file: %w", k, err) + } + + targetFile := d.pathKey(k) + if err := os.Rename(f.Name(), targetFile); err != nil { + return fmt.Errorf("failed to move temp dir %v to final destination %v: %w", f.Name(), targetFile, err) + } + return nil +} + +func openTempFile(dir string, nameTemplate string) (*os.File, error) { + f, err := os.CreateTemp(dir, nameTemplate) + // Directory has been deleted out from underneath us. Recreate it. + if errors.Is(err, os.ErrNotExist) { + if mkdirErr := os.MkdirAll(dir, 0777); mkdirErr != nil { + return nil, errors.Join(fmt.Errorf("failed to create directory %v: %w", dir, mkdirErr), err) + } + f, err = os.CreateTemp(dir, nameTemplate) + } + if err != nil { + return nil, err + } + return f, nil } func (d *DiskKV) Get(k common.Hash) ([]byte, error) { d.RLock() defer d.RUnlock() - - dat, closer, err := d.db.Get(k.Bytes()) + f, err := os.OpenFile(d.pathKey(k), os.O_RDONLY, diskPermission) if err != nil { - if errors.Is(err, pebble.ErrNotFound) { + if errors.Is(err, os.ErrNotExist) { return nil, ErrNotFound } - return nil, err + return nil, fmt.Errorf("failed to open pre-image file %s: %w", k, err) } - ret := make([]byte, len(dat)) - copy(ret, dat) - closer.Close() - return ret, nil -} - -func (d *DiskKV) Close() error { - d.Lock() - defer d.Unlock() - - return d.db.Close() + defer f.Close() // fine to ignore closing error here + dat, err := io.ReadAll(f) + if err != nil { + return nil, fmt.Errorf("failed to read pre-image from file %s: %w", k, err) + } + return hex.DecodeString(string(dat)) } var _ KV = (*DiskKV)(nil) diff --git a/op-program/host/kvstore/kv.go b/op-program/host/kvstore/kv.go index 054230950d0b..e75dcd699d9f 100644 --- a/op-program/host/kvstore/kv.go +++ b/op-program/host/kvstore/kv.go @@ -19,7 +19,4 @@ type KV interface { // It returns ErrNotFound when the pre-image cannot be found. // KV store implementations may return additional errors specific to the KV storage. Get(k common.Hash) ([]byte, error) - - // Closes the KV store. - Close() error } diff --git a/op-program/host/kvstore/mem.go b/op-program/host/kvstore/mem.go index 0c3b950b7e9c..9af540e235fa 100644 --- a/op-program/host/kvstore/mem.go +++ b/op-program/host/kvstore/mem.go @@ -37,7 +37,3 @@ func (m *MemKV) Get(k common.Hash) ([]byte, error) { } return slices.Clone(v), nil } - -func (m *MemKV) Close() error { - return nil -} diff --git a/op-program/scripts/run-compat.sh b/op-program/scripts/run-compat.sh index 296387ac5d0e..ed853a8d980b 100755 --- a/op-program/scripts/run-compat.sh +++ b/op-program/scripts/run-compat.sh @@ -5,7 +5,7 @@ SCRIPTS_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) COMPAT_DIR="${SCRIPTS_DIR}/../temp/compat" TESTNAME="${1?Must specify compat file to run}" -BASEURL="${2:-https://github.com/ethereum-optimism/chain-test-data/releases/download/2024-09-01}" +BASEURL="${2:-https://github.com/ethereum-optimism/chain-test-data/releases/download/2024-08-02}" URL="${BASEURL}/${TESTNAME}.tar.bz" From 9452aa66dc7a2e0deb63bca4bf5c7cfc35c3211c Mon Sep 17 00:00:00 2001 From: Roberto Bayardo Date: Mon, 2 Sep 2024 10:21:30 -0700 Subject: [PATCH 018/264] op-service/txmgr: multiple fixes / improvements (#11614) * - make immediate nonce-too-low error abort send (since it could never succeed otherwise) - make txmgr resubmit a transaction when fee bumping fails in case it has been dropped from the mempool - only bump fees when they really should be bumped - set txmgr overall default send timeout of 10 minutes. It was infinite, which led to permanently stuck transaction in combination with the other bugs fixed in this PR. * Update op-service/txmgr/txmgr_test.go --------- Co-authored-by: Sebastian Stammler --- op-service/txmgr/cli.go | 2 +- op-service/txmgr/send_state.go | 7 ++ op-service/txmgr/send_state_test.go | 12 +++ op-service/txmgr/txmgr.go | 111 ++++++++++++++-------------- op-service/txmgr/txmgr_test.go | 95 +++++++++++++++++++++--- 5 files changed, 158 insertions(+), 69 deletions(-) diff --git a/op-service/txmgr/cli.go b/op-service/txmgr/cli.go index d07319866332..fe65b6dd126e 100644 --- a/op-service/txmgr/cli.go +++ b/op-service/txmgr/cli.go @@ -79,7 +79,7 @@ var ( MinBaseFeeGwei: 1.0, ResubmissionTimeout: 48 * time.Second, NetworkTimeout: 10 * time.Second, - TxSendTimeout: 0 * time.Second, + TxSendTimeout: 10 * time.Minute, TxNotInMempoolTimeout: 2 * time.Minute, ReceiptQueryInterval: 12 * time.Second, } diff --git a/op-service/txmgr/send_state.go b/op-service/txmgr/send_state.go index fd64f7dd8396..38e691fc78f8 100644 --- a/op-service/txmgr/send_state.go +++ b/op-service/txmgr/send_state.go @@ -37,6 +37,9 @@ type SendState struct { // Whether any attempt to send the tx resulted in ErrAlreadyReserved alreadyReserved bool + // Whether we should bump fees before trying to publish the tx again + bumpFees bool + // Miscellaneous tracking bumpCount int // number of times we have bumped the gas price } @@ -120,6 +123,10 @@ func (s *SendState) CriticalError() error { case s.nonceTooLowCount >= s.safeAbortNonceTooLowCount: // we have exceeded the nonce too low count return core.ErrNonceTooLow + case s.successFullPublishCount == 0 && s.nonceTooLowCount > 0: + // A nonce too low error before successfully publishing any transaction means the tx will + // need a different nonce, which we can force by returning error. + return core.ErrNonceTooLow case s.successFullPublishCount == 0 && s.now().After(s.txInMempoolDeadline): // unable to get the tx into the mempool in the allotted time return ErrMempoolDeadlineExpired diff --git a/op-service/txmgr/send_state_test.go b/op-service/txmgr/send_state_test.go index 20bfe155ed97..d48db5fd1514 100644 --- a/op-service/txmgr/send_state_test.go +++ b/op-service/txmgr/send_state_test.go @@ -58,11 +58,21 @@ func TestSendStateNoAbortAfterProcessOtherError(t *testing.T) { require.Nil(t, sendState.CriticalError()) } +// TestSendStateAbortSafelyAfterNonceTooLowButNoTxMined asserts that we will abort after the very +// first none-too-low error if a tx hasn't yet been published. +func TestSendStateAbortSafelyAfterNonceTooLowNoTxPublished(t *testing.T) { + sendState := newSendState() + + sendState.ProcessSendError(core.ErrNonceTooLow) + require.ErrorIs(t, sendState.CriticalError(), core.ErrNonceTooLow) +} + // TestSendStateAbortSafelyAfterNonceTooLowButNoTxMined asserts that we will // abort after the safe abort interval has elapsed if we haven't mined a tx. func TestSendStateAbortSafelyAfterNonceTooLowButNoTxMined(t *testing.T) { sendState := newSendState() + sendState.ProcessSendError(nil) sendState.ProcessSendError(core.ErrNonceTooLow) require.Nil(t, sendState.CriticalError()) sendState.ProcessSendError(core.ErrNonceTooLow) @@ -90,6 +100,7 @@ func TestSendStateMiningTxCancelsAbort(t *testing.T) { func TestSendStateReorgingTxResetsAbort(t *testing.T) { sendState := newSendState() + sendState.ProcessSendError(nil) sendState.ProcessSendError(core.ErrNonceTooLow) sendState.ProcessSendError(core.ErrNonceTooLow) sendState.TxMined(testHash) @@ -120,6 +131,7 @@ func TestSendStateNoAbortEvenIfNonceTooLowAfterTxMined(t *testing.T) { func TestSendStateSafeAbortIfNonceTooLowPersistsAfterUnmine(t *testing.T) { sendState := newSendState() + sendState.ProcessSendError(nil) sendState.TxMined(testHash) sendState.TxNotMined(testHash) sendState.ProcessSendError(core.ErrNonceTooLow) diff --git a/op-service/txmgr/txmgr.go b/op-service/txmgr/txmgr.go index 49a76aa7e5bb..1093d7220957 100644 --- a/op-service/txmgr/txmgr.go +++ b/op-service/txmgr/txmgr.go @@ -53,8 +53,8 @@ var ( type TxManager interface { // Send is used to create & send a transaction. It will handle increasing // the gas price & ensuring that the transaction remains in the transaction pool. - // It can be stopped by cancelling the provided context; however, the transaction - // may be included on L1 even if the context is cancelled. + // It can be stopped by canceling the provided context; however, the transaction + // may be included on L1 even if the context is canceled. // // NOTE: Send can be called concurrently, the nonce will be managed internally. // @@ -470,44 +470,33 @@ func (m *SimpleTxManager) sendTx(ctx context.Context, tx *types.Transaction) (*t sendState := NewSendState(m.cfg.SafeAbortNonceTooLowCount, m.cfg.TxNotInMempoolTimeout) receiptChan := make(chan *types.Receipt, 1) - publishAndWait := func(tx *types.Transaction, bumpFees bool) *types.Transaction { - wg.Add(1) - tx, published := m.publishTx(ctx, tx, sendState, bumpFees) - if published { - go func() { - defer wg.Done() - m.waitForTx(ctx, tx, sendState, receiptChan) - }() - } else { - wg.Done() - } - return tx - } - - // Immediately publish a transaction before starting the resubmission loop - tx = publishAndWait(tx, false) - resubmissionTimeout := m.GetBumpFeeRetryTime() ticker := time.NewTicker(resubmissionTimeout) defer ticker.Stop() for { + if !sendState.IsWaitingForConfirmation() { + if m.closed.Load() { + // the tx manager closed and no txs are waiting to be confirmed, give up + m.txLogger(tx, false).Warn("TxManager closed, aborting transaction submission") + return nil, ErrClosed + } + var published bool + if tx, published = m.publishTx(ctx, tx, sendState); published { + wg.Add(1) + go func() { + defer wg.Done() + m.waitForTx(ctx, tx, sendState, receiptChan) + }() + } + } if err := sendState.CriticalError(); err != nil { m.txLogger(tx, false).Warn("Aborting transaction submission", "err", err) return nil, fmt.Errorf("aborted tx send due to critical error: %w", err) } + select { case <-ticker.C: - // Don't resubmit a transaction if it has been mined, but we are waiting for the conf depth. - if sendState.IsWaitingForConfirmation() { - continue - } - // if the tx manager closed while we were waiting for the tx, give up - if m.closed.Load() { - m.txLogger(tx, false).Warn("TxManager closed, aborting transaction submission") - return nil, ErrClosed - } - tx = publishAndWait(tx, true) case <-ctx.Done(): return nil, ctx.Err() @@ -523,34 +512,34 @@ func (m *SimpleTxManager) sendTx(ctx context.Context, tx *types.Transaction) (*t // publishTx publishes the transaction to the transaction pool. If it receives any underpriced errors // it will bump the fees and retry. // Returns the latest fee bumped tx, and a boolean indicating whether the tx was sent or not -func (m *SimpleTxManager) publishTx(ctx context.Context, tx *types.Transaction, sendState *SendState, bumpFeesImmediately bool) (*types.Transaction, bool) { +func (m *SimpleTxManager) publishTx(ctx context.Context, tx *types.Transaction, sendState *SendState) (*types.Transaction, bool) { l := m.txLogger(tx, true) l.Info("Publishing transaction", "tx", tx.Hash()) for { - // if the tx manager closed, give up without bumping fees or retrying - if m.closed.Load() { - l.Warn("TxManager closed, aborting transaction submission") - return tx, false - } - if bumpFeesImmediately { - newTx, err := m.increaseGasPrice(ctx, tx) - if err != nil { - l.Error("unable to increase gas", "err", err) + if sendState.bumpFees { + if newTx, err := m.increaseGasPrice(ctx, tx); err != nil { + l.Warn("unable to increase gas, will try to re-publish the tx", "err", err) m.metr.TxPublished("bump_failed") - return tx, false + // Even if we are unable to bump fees, we must still resubmit the transaction + // because a previously successfully published tx can get dropped from the + // mempool. If we don't try to resubmit it to either force a failure (eg. from + // nonce to low errors) or get it back into the mempool, we can end up waiting on + // it to get mined indefinitely. + } else { + if sendState.IsWaitingForConfirmation() { + // A previously published tx might get mined during the increaseGasPrice call + // above, in which case we can abort trying to replace it with a higher fee tx. + return tx, false + } + sendState.bumpCount++ + tx = newTx + l = m.txLogger(tx, true) + // Disable bumping fees again until the new transaction is successfully published, + // or we immediately get another underpriced error. + sendState.bumpFees = false } - tx = newTx - sendState.bumpCount++ - l = m.txLogger(tx, true) - } - bumpFeesImmediately = true // bump fees next loop - - if sendState.IsWaitingForConfirmation() { - // there is a chance the previous tx goes into "waiting for confirmation" state - // during the increaseGasPrice call; continue waiting rather than resubmit the tx - return tx, false } cCtx, cancel := context.WithTimeout(ctx, m.cfg.NetworkTimeout) @@ -561,6 +550,9 @@ func (m *SimpleTxManager) publishTx(ctx context.Context, tx *types.Transaction, if err == nil { m.metr.TxPublished("") l.Info("Transaction successfully published", "tx", tx.Hash()) + // Tx made it into the mempool, so we'll need a fee bump if we end up trying to replace + // it with another publish attempt. + sendState.bumpFees = true return tx, true } @@ -575,26 +567,33 @@ func (m *SimpleTxManager) publishTx(ctx context.Context, tx *types.Transaction, m.metr.TxPublished("nonce_too_low") case errStringMatch(err, context.Canceled): m.metr.RPCError() - l.Warn("transaction send cancelled", "err", err) - m.metr.TxPublished("context_cancelled") + l.Warn("transaction send canceled", "err", err) + m.metr.TxPublished("context_canceled") case errStringMatch(err, txpool.ErrAlreadyKnown): l.Warn("resubmitted already known transaction", "err", err) m.metr.TxPublished("tx_already_known") case errStringMatch(err, txpool.ErrReplaceUnderpriced): l.Warn("transaction replacement is underpriced", "err", err) m.metr.TxPublished("tx_replacement_underpriced") - continue // retry with fee bump + // retry tx with fee bump, unless we already just tried to bump them + if !sendState.bumpFees { + sendState.bumpFees = true + continue + } case errStringMatch(err, txpool.ErrUnderpriced): l.Warn("transaction is underpriced", "err", err) m.metr.TxPublished("tx_underpriced") - continue // retry with fee bump + // retry tx with fee bump, unless we already just tried to bump them + if !sendState.bumpFees { + sendState.bumpFees = true + continue + } default: m.metr.RPCError() l.Error("unable to publish transaction", "err", err) m.metr.TxPublished("unknown_error") } - // on non-underpriced error return immediately; will retry on next resubmission timeout return tx, false } } @@ -617,7 +616,7 @@ func (m *SimpleTxManager) waitForTx(ctx context.Context, tx *types.Transaction, } } -// waitMined waits for the transaction to be mined or for the context to be cancelled. +// waitMined waits for the transaction to be mined or for the context to be canceled. func (m *SimpleTxManager) waitMined(ctx context.Context, tx *types.Transaction, sendState *SendState) (*types.Receipt, error) { txHash := tx.Hash() queryTicker := time.NewTicker(m.cfg.ReceiptQueryInterval) diff --git a/op-service/txmgr/txmgr_test.go b/op-service/txmgr/txmgr_test.go index e06ecaf98e4f..c5cf4bca40e5 100644 --- a/op-service/txmgr/txmgr_test.go +++ b/op-service/txmgr/txmgr_test.go @@ -389,7 +389,7 @@ func TestTxMgrNeverConfirmCancel(t *testing.T) { } h.backend.setTxSender(sendTx) - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() receipt, err := h.mgr.sendTx(ctx, tx) @@ -397,6 +397,37 @@ func TestTxMgrNeverConfirmCancel(t *testing.T) { require.Nil(t, receipt) } +// TestTxMgrTxSendTimeout tests that the TxSendTimeout is respected when trying to send a +// transaction, even if NetworkTimeout expires first. +func TestTxMgrTxSendTimeout(t *testing.T) { + t.Parallel() + + conf := configWithNumConfs(1) + conf.TxSendTimeout = 3 * time.Second + conf.NetworkTimeout = 1 * time.Second + + h := newTestHarnessWithConfig(t, conf) + + txCandidate := h.createTxCandidate() + sendCount := 0 + sendTx := func(ctx context.Context, tx *types.Transaction) error { + sendCount++ + <-ctx.Done() + return context.DeadlineExceeded + } + h.backend.setTxSender(sendTx) + + ctx, cancel := context.WithTimeout(context.Background(), time.Hour) + defer cancel() + + receipt, err := h.mgr.send(ctx, txCandidate) + require.ErrorIs(t, err, context.DeadlineExceeded) + // Because network timeout is much shorter than send timeout, we should see multiple send attempts + // before the overall send fails. + require.Greater(t, sendCount, 1) + require.Nil(t, receipt) +} + // TestAlreadyReserved tests that AlreadyReserved error results in immediate abort of transaction // sending. func TestAlreadyReserved(t *testing.T) { @@ -664,7 +695,7 @@ func TestTxMgr_SigningFails(t *testing.T) { // TestTxMgrOnlyOnePublicationSucceeds asserts that the tx manager will return a // receipt so long as at least one of the publications is able to succeed with a -// simulated rpc failure. +// simulated failure. func TestTxMgrOnlyOnePublicationSucceeds(t *testing.T) { t.Parallel() @@ -679,7 +710,7 @@ func TestTxMgrOnlyOnePublicationSucceeds(t *testing.T) { sendTx := func(ctx context.Context, tx *types.Transaction) error { // Fail all but the final attempt. if !h.gasPricer.shouldMine(tx.GasFeeCap()) { - return errRpcFailure + return txpool.ErrUnderpriced } txHash := tx.Hash() @@ -699,7 +730,7 @@ func TestTxMgrOnlyOnePublicationSucceeds(t *testing.T) { // TestTxMgrConfirmsMinGasPriceAfterBumping delays the mining of the initial tx // with the minimum gas price, and asserts that its receipt is returned even -// though if the gas price has been bumped in other goroutines. +// if the gas price has been bumped in other goroutines. func TestTxMgrConfirmsMinGasPriceAfterBumping(t *testing.T) { t.Parallel() @@ -731,6 +762,47 @@ func TestTxMgrConfirmsMinGasPriceAfterBumping(t *testing.T) { require.Equal(t, h.gasPricer.expGasFeeCap().Uint64(), receipt.GasUsed) } +// TestTxMgrRetriesUnbumpableTx tests that a tx whose fees cannot be bumped will still be +// re-published in case it had been dropped from the mempool. +func TestTxMgrRetriesUnbumpableTx(t *testing.T) { + t.Parallel() + + cfg := configWithNumConfs(1) + cfg.FeeLimitMultiplier.Store(1) // don't allow fees to be bumped over the suggested values + h := newTestHarnessWithConfig(t, cfg) + + // Make the fees unbumpable by starting with fees that will be WAY over the suggested values + gasTipCap, gasFeeCap, _ := h.gasPricer.feesForEpoch(100) + txToSend := types.NewTx(&types.DynamicFeeTx{ + GasTipCap: gasTipCap, + GasFeeCap: gasFeeCap, + }) + + sameTxPublishAttempts := 0 + sendTx := func(ctx context.Context, tx *types.Transaction) error { + // delay mining so several retries should be triggered + if tx.Hash().Cmp(txToSend.Hash()) == 0 { + sameTxPublishAttempts++ + } + if h.gasPricer.shouldMine(tx.GasFeeCap()) { + // delay mining to give it enough time for ~3 retries + time.AfterFunc(3*time.Second, func() { + txHash := tx.Hash() + h.backend.mine(&txHash, tx.GasFeeCap(), nil) + }) + } + return nil + } + h.backend.setTxSender(sendTx) + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + receipt, err := h.mgr.sendTx(ctx, txToSend) + require.NoError(t, err) + require.NotNil(t, receipt) + require.Greater(t, sameTxPublishAttempts, 1, "expected the original tx to be retried at least once") +} + // TestTxMgrDoesntAbortNonceTooLowAfterMiningTx func TestTxMgrDoesntAbortNonceTooLowAfterMiningTx(t *testing.T) { t.Parallel() @@ -796,21 +868,21 @@ func TestWaitMinedReturnsReceiptOnFirstSuccess(t *testing.T) { require.Equal(t, receipt.TxHash, txHash) } -// TestWaitMinedCanBeCanceled ensures that waitMined exits of the passed context +// TestWaitMinedCanBeCanceled ensures that waitMined exits if the passed context // is canceled before a receipt is found. func TestWaitMinedCanBeCanceled(t *testing.T) { t.Parallel() h := newTestHarness(t) - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() // Create an unimined tx. tx := types.NewTx(&types.LegacyTx{}) receipt, err := h.mgr.waitMined(ctx, tx, NewSendState(10, time.Hour)) - require.Equal(t, err, context.DeadlineExceeded) + require.ErrorIs(t, err, context.DeadlineExceeded) require.Nil(t, receipt) } @@ -831,7 +903,7 @@ func TestWaitMinedMultipleConfs(t *testing.T) { h.backend.mine(&txHash, new(big.Int), nil) receipt, err := h.mgr.waitMined(ctx, tx, NewSendState(10, time.Hour)) - require.Equal(t, err, context.DeadlineExceeded) + require.ErrorIs(t, err, context.DeadlineExceeded) require.Nil(t, receipt) ctx, cancel = context.WithTimeout(context.Background(), time.Second) @@ -1360,7 +1432,6 @@ func TestMinFees(t *testing.T) { // TestClose ensures that the tx manager will refuse new work and cancel any in progress func TestClose(t *testing.T) { conf := configWithNumConfs(1) - conf.SafeAbortNonceTooLowCount = 100 h := newTestHarnessWithConfig(t, conf) sendingSignal := make(chan struct{}) @@ -1382,7 +1453,7 @@ func TestClose(t *testing.T) { h.backend.mine(&txHash, tx.GasFeeCap(), big.NewInt(1)) } else { time.Sleep(10 * time.Millisecond) - err = core.ErrNonceTooLow + err = errRpcFailure } return } @@ -1412,7 +1483,7 @@ func TestClose(t *testing.T) { _, err = h.mgr.Send(ctx, TxCandidate{ To: &common.Address{}, }) - require.ErrorIs(t, ErrClosed, err) + require.ErrorIs(t, err, ErrClosed) // confirm that the tx was canceled before it retried to completion require.Less(t, called, retries) require.True(t, h.mgr.closed.Load()) @@ -1423,7 +1494,7 @@ func TestClose(t *testing.T) { _, err = h.mgr.Send(ctx, TxCandidate{ To: &common.Address{}, }) - require.ErrorIs(t, ErrClosed, err) + require.ErrorIs(t, err, ErrClosed) // confirm that the tx was canceled before it ever made it to the backend require.Equal(t, 0, called) } From 42085ce945bc727707b9d51c8e90e142b05f721e Mon Sep 17 00:00:00 2001 From: clabby Date: Mon, 2 Sep 2024 17:21:55 -0400 Subject: [PATCH 019/264] chore(op-service): Remove `reth` receipts source (#11706) --- .circleci/config.yml | 43 - op-node/flags/flags.go | 8 - op-node/node/config.go | 3 - op-node/node/node.go | 3 - op-node/service.go | 1 - op-service/rethdb-reader/.gitignore | 8 - op-service/rethdb-reader/Cargo.lock | 4909 ----------------- op-service/rethdb-reader/Cargo.toml | 26 - op-service/rethdb-reader/Makefile | 8 - op-service/rethdb-reader/README.md | 113 - op-service/rethdb-reader/headgen.sh | 16 - op-service/rethdb-reader/rustfmt.toml | 11 - op-service/rethdb-reader/src/db.rs | 59 - op-service/rethdb-reader/src/lib.rs | 47 - op-service/rethdb-reader/src/receipts.rs | 334 -- op-service/rethdb-reader/testdata/block.rlp | Bin 8833 -> 0 bytes .../rethdb-reader/testdata/receipts.json | 12 - op-service/sources/eth_client.go | 19 +- op-service/sources/reth_db.go | 125 - op-service/sources/reth_db_stub.go | 15 - op-service/sources/reth_db_test.go | 45 - 21 files changed, 3 insertions(+), 5802 deletions(-) delete mode 100644 op-service/rethdb-reader/.gitignore delete mode 100644 op-service/rethdb-reader/Cargo.lock delete mode 100644 op-service/rethdb-reader/Cargo.toml delete mode 100644 op-service/rethdb-reader/Makefile delete mode 100644 op-service/rethdb-reader/README.md delete mode 100755 op-service/rethdb-reader/headgen.sh delete mode 100644 op-service/rethdb-reader/rustfmt.toml delete mode 100644 op-service/rethdb-reader/src/db.rs delete mode 100644 op-service/rethdb-reader/src/lib.rs delete mode 100644 op-service/rethdb-reader/src/receipts.rs delete mode 100644 op-service/rethdb-reader/testdata/block.rlp delete mode 100644 op-service/rethdb-reader/testdata/receipts.json delete mode 100644 op-service/sources/reth_db.go delete mode 100644 op-service/sources/reth_db_stub.go delete mode 100644 op-service/sources/reth_db_test.go diff --git a/.circleci/config.yml b/.circleci/config.yml index fd5a05d3658a..bb9794cb4562 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1313,45 +1313,6 @@ jobs: paths: - "/go/pkg/mod" - op-service-rethdb-tests: - docker: - - image: <> - steps: - - checkout - - check-changed: - patterns: op-service,op-node - - restore_cache: - name: Restore Go modules cache - key: gomod-{{ checksum "go.sum" }} - - run: - name: Cargo fmt + clippy - command: | - cargo +nightly fmt -- --check - cargo +nightly clippy --all --all-features -- -D warnings - working_directory: op-service/rethdb-reader - - run: - name: Generate testdata db - command: cargo test - working_directory: op-service/rethdb-reader - - run: - name: Build dylib - command: cargo build --release - working_directory: op-service/rethdb-reader - - run: - name: Update LD_LIBRARY_PATH - command: echo 'export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:/root/project/op-service/rethdb-reader/target/release"' >> $BASH_ENV - - run: - name: Run op-service RethDB tests - command: | - gotestsum --format=standard-verbose --junitfile=/tmp/test-results/op-service.xml \ - -- -parallel=8 -coverpkg=github.com/ethereum-optimism/optimism/... -coverprofile=coverage.out \ - -run TestRethDB -tags rethdb -v - working_directory: op-service/sources - # TODO(CLI-148): Fix codecov - #- run: - #name: upload coverage - #command: codecov --verbose --clean --flags bedrock-rethdb-go-tests - bedrock-go-tests: # just a helper, that depends on all the actual test jobs docker: # Use a smaller base image to avoid pulling the huge ci-builder @@ -1622,9 +1583,6 @@ workflows: requires: - pnpm-monorepo - cannon-prestate - - op-service-rethdb-tests: - requires: - - go-mod-download - op-program-compat: requires: - op-program-tests @@ -1647,7 +1605,6 @@ workflows: - op-program-compat - op-service-tests - op-supervisor-tests - - op-service-rethdb-tests - op-e2e-HTTP-tests - op-e2e-fault-proof-tests - op-e2e-action-tests diff --git a/op-node/flags/flags.go b/op-node/flags/flags.go index 6ea12000cc37..b3af25d66143 100644 --- a/op-node/flags/flags.go +++ b/op-node/flags/flags.go @@ -157,13 +157,6 @@ var ( }(), Category: L1RPCCategory, } - L1RethDBPath = &cli.StringFlag{ - Name: "l1.rethdb", - Usage: "The L1 RethDB path, used to fetch receipts for L1 blocks.", - EnvVars: prefixEnvVars("L1_RETHDB"), - Hidden: true, - Category: L1RPCCategory, - } L1RPCMaxConcurrency = &cli.IntFlag{ Name: "l1.max-concurrency", Usage: "Maximum number of concurrent RPC requests to make to the L1 RPC provider.", @@ -413,7 +406,6 @@ var optionalFlags = []cli.Flag{ HeartbeatURLFlag, RollupHalt, RollupLoadProtocolVersions, - L1RethDBPath, ConductorEnabledFlag, ConductorRpcFlag, ConductorRpcTimeoutFlag, diff --git a/op-node/node/config.go b/op-node/node/config.go index 6b7be8f268fd..d52da967f14a 100644 --- a/op-node/node/config.go +++ b/op-node/node/config.go @@ -65,9 +65,6 @@ type Config struct { // Cancel to request a premature shutdown of the node itself, e.g. when halting. This may be nil. Cancel context.CancelCauseFunc - // [OPTIONAL] The reth DB path to read receipts from - RethDBPath string - // Conductor is used to determine this node is the leader sequencer. ConductorEnabled bool ConductorRpc string diff --git a/op-node/node/node.go b/op-node/node/node.go index 0f174c7a372c..c60121f7d168 100644 --- a/op-node/node/node.go +++ b/op-node/node/node.go @@ -172,9 +172,6 @@ func (n *OpNode) initL1(ctx context.Context, cfg *Config) error { return fmt.Errorf("failed to get L1 RPC client: %w", err) } - // Set the RethDB path in the EthClientConfig, if there is one configured. - rpcCfg.EthClientConfig.RethDBPath = cfg.RethDBPath - n.l1Source, err = sources.NewL1Client( client.NewInstrumentedRPC(l1Node, &n.metrics.RPCMetrics.RPCClientMetrics), n.log, n.metrics.L1SourceCache, rpcCfg) if err != nil { diff --git a/op-node/service.go b/op-node/service.go index cae25afd381f..723c6febb321 100644 --- a/op-node/service.go +++ b/op-node/service.go @@ -106,7 +106,6 @@ func NewConfig(ctx *cli.Context, log log.Logger) (*node.Config, error) { SafeDBPath: ctx.String(flags.SafeDBPath.Name), Sync: *syncConfig, RollupHalt: haltOption, - RethDBPath: ctx.String(flags.L1RethDBPath.Name), ConductorEnabled: ctx.Bool(flags.ConductorEnabledFlag.Name), ConductorRpc: ctx.String(flags.ConductorRpcFlag.Name), diff --git a/op-service/rethdb-reader/.gitignore b/op-service/rethdb-reader/.gitignore deleted file mode 100644 index 360eaff0efc3..000000000000 --- a/op-service/rethdb-reader/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Target -target/ - -# Bindings -rdb.h - -# Testdata DB -testdata/db diff --git a/op-service/rethdb-reader/Cargo.lock b/op-service/rethdb-reader/Cargo.lock deleted file mode 100644 index 0b66063c3372..000000000000 --- a/op-service/rethdb-reader/Cargo.lock +++ /dev/null @@ -1,4909 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "aead" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" -dependencies = [ - "generic-array", -] - -[[package]] -name = "aes" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" -dependencies = [ - "cfg-if", - "cipher 0.3.0", - "cpufeatures", - "ctr 0.8.0", - "opaque-debug", -] - -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher 0.4.4", - "cpufeatures", -] - -[[package]] -name = "aes-gcm" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc3be92e19a7ef47457b8e6f90707e12b6ac5d20c6f3866584fa3be0787d839f" -dependencies = [ - "aead", - "aes 0.7.5", - "cipher 0.3.0", - "ctr 0.7.0", - "ghash", - "subtle", -] - -[[package]] -name = "ahash" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b79b82693f705137f8fb9b37871d99e4f9a7df12b917eed79c3d3954830a60b" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "aho-corasick" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" -dependencies = [ - "memchr", -] - -[[package]] -name = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - -[[package]] -name = "alloy-chains" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe92bd1fb0c96e938f9f2284618028e5f4dc3d719cac32631ed51e1b86a06895" -dependencies = [ - "alloy-rlp", - "arbitrary", - "num_enum", - "proptest", - "serde", - "strum", -] - -[[package]] -name = "alloy-eips" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e" -dependencies = [ - "alloy-primitives", - "alloy-rlp", - "thiserror", -] - -[[package]] -name = "alloy-genesis" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e" -dependencies = [ - "alloy-primitives", - "alloy-rpc-types", - "serde", -] - -[[package]] -name = "alloy-primitives" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef197eb250c64962003cb08b90b17f0882c192f4a6f2f544809d424fd7cb0e7d" -dependencies = [ - "alloy-rlp", - "bytes", - "cfg-if", - "const-hex", - "derive_more", - "getrandom 0.2.12", - "hex-literal", - "itoa", - "k256", - "keccak-asm", - "proptest", - "rand 0.8.5", - "ruint", - "serde", - "tiny-keccak", -] - -[[package]] -name = "alloy-rlp" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d58d9f5da7b40e9bfff0b7e7816700be4019db97d4b6359fe7f94a9e22e42ac" -dependencies = [ - "alloy-rlp-derive", - "arrayvec", - "bytes", -] - -[[package]] -name = "alloy-rlp-derive" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a047897373be4bbb0224c1afdabca92648dc57a9c9ef6e7b0be3aff7a859c83" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "alloy-rpc-engine-types" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e" -dependencies = [ - "alloy-primitives", - "alloy-rlp", - "alloy-rpc-types", - "jsonrpsee-types", - "serde", - "thiserror", -] - -[[package]] -name = "alloy-rpc-trace-types" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e" -dependencies = [ - "alloy-primitives", - "alloy-rpc-types", - "serde", - "serde_json", -] - -[[package]] -name = "alloy-rpc-types" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e" -dependencies = [ - "alloy-primitives", - "alloy-rlp", - "itertools 0.12.1", - "jsonrpsee-types", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "alloy-sol-macro" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e92100dee7fd1e44abbe0ef6607f18758cf0ad4e483f4c65ff5c8d85428a6d" -dependencies = [ - "const-hex", - "dunce", - "heck", - "indexmap 2.2.3", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.52", - "syn-solidity", - "tiny-keccak", -] - -[[package]] -name = "alloy-sol-types" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e7c6a8c492b1d6a4f92a8fc6a13cf39473978dd7d459d7221969ce5a73d97cd" -dependencies = [ - "alloy-primitives", - "alloy-sol-macro", - "const-hex", - "serde", -] - -[[package]] -name = "alloy-trie" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9e1498416f7e7f09af8061970e14936846b6271e153aa5ba539a22a7eb414d" -dependencies = [ - "alloy-primitives", - "alloy-rlp", - "derive_more", - "hashbrown 0.14.3", - "nybbles", - "serde", - "smallvec", - "tracing", -] - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anstream" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" - -[[package]] -name = "anstyle-parse" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" -dependencies = [ - "anstyle", - "windows-sys 0.52.0", -] - -[[package]] -name = "anyhow" -version = "1.0.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" - -[[package]] -name = "aquamarine" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21cc1548309245035eb18aa7f0967da6bc65587005170c56e6ef2788a4cf3f4e" -dependencies = [ - "include_dir", - "itertools 0.10.5", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "arbitrary" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" - -[[package]] -name = "ark-ff" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" -dependencies = [ - "ark-ff-asm 0.3.0", - "ark-ff-macros 0.3.0", - "ark-serialize 0.3.0", - "ark-std 0.3.0", - "derivative", - "num-bigint", - "num-traits", - "paste", - "rustc_version 0.3.3", - "zeroize", -] - -[[package]] -name = "ark-ff" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" -dependencies = [ - "ark-ff-asm 0.4.2", - "ark-ff-macros 0.4.2", - "ark-serialize 0.4.2", - "ark-std 0.4.0", - "derivative", - "digest 0.10.7", - "itertools 0.10.5", - "num-bigint", - "num-traits", - "paste", - "rustc_version 0.4.0", - "zeroize", -] - -[[package]] -name = "ark-ff-asm" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" -dependencies = [ - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-ff-asm" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" -dependencies = [ - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-ff-macros" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" -dependencies = [ - "num-bigint", - "num-traits", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-ff-macros" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" -dependencies = [ - "num-bigint", - "num-traits", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-serialize" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" -dependencies = [ - "ark-std 0.3.0", - "digest 0.9.0", -] - -[[package]] -name = "ark-serialize" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" -dependencies = [ - "ark-std 0.4.0", - "digest 0.10.7", - "num-bigint", -] - -[[package]] -name = "ark-std" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" -dependencies = [ - "num-traits", - "rand 0.8.5", -] - -[[package]] -name = "ark-std" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" -dependencies = [ - "num-traits", - "rand 0.8.5", -] - -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - -[[package]] -name = "async-trait" -version = "0.1.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "attohttpc" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9a9bf8b79a749ee0b911b91b671cc2b6c670bdbc7e3dfd537576ddc94bb2a2" -dependencies = [ - "http", - "log", - "url", -] - -[[package]] -name = "aurora-engine-modexp" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfacad86e9e138fca0670949eb8ed4ffdf73a55bded8887efe0863cd1a3a6f70" -dependencies = [ - "hex", - "num", -] - -[[package]] -name = "auto_impl" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "backtrace" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "base64ct" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" - -[[package]] -name = "beef" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" -dependencies = [ - "serde", -] - -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bindgen" -version = "0.69.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" -dependencies = [ - "bitflags 2.4.2", - "cexpr", - "clang-sys", - "itertools 0.12.1", - "lazy_static", - "lazycell", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.52", -] - -[[package]] -name = "binout" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b60b1af88a588fca5fe424ae7d735bc52814f80ff57614f57043cc4e2024f2ea" - -[[package]] -name = "bit-set" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" -dependencies = [ - "serde", -] - -[[package]] -name = "bitm" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31b9ea263f0faf826a1c9de0e8bf8f32f5986c05f5e3abcf6bcde74616009586" -dependencies = [ - "dyn_size_of", -] - -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "serde", - "tap", - "wyz", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-padding" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" -dependencies = [ - "generic-array", -] - -[[package]] -name = "blst" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" -dependencies = [ - "cc", - "glob", - "threadpool", - "zeroize", -] - -[[package]] -name = "bumpalo" -version = "3.15.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b" - -[[package]] -name = "byte-slice-cast" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" -dependencies = [ - "serde", -] - -[[package]] -name = "c-kzg" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94a4bc5367b6284358d2a6a6a1dc2d92ec4b86034561c3b9d3341909752fd848" -dependencies = [ - "blst", - "cc", - "glob", - "hex", - "libc", - "serde", -] - -[[package]] -name = "cc" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "jobserver", - "libc", -] - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "serde", - "wasm-bindgen", - "windows-targets 0.52.4", -] - -[[package]] -name = "cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" -dependencies = [ - "generic-array", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - -[[package]] -name = "clang-sys" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "clap" -version = "4.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim 0.11.0", -] - -[[package]] -name = "clap_derive" -version = "4.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "clap_lex" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" - -[[package]] -name = "codecs-derive" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "convert_case 0.6.0", - "parity-scale-codec", - "proc-macro2", - "quote", - "serde", - "syn 2.0.52", -] - -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - -[[package]] -name = "const-hex" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbd12d49ab0eaf8193ba9175e45f56bbc2e4b27d57b8cfe62aa47942a46b9a9" -dependencies = [ - "cfg-if", - "cpufeatures", - "hex", - "proptest", - "serde", -] - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "convert_case" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" - -[[package]] -name = "cpufeatures" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" -dependencies = [ - "libc", -] - -[[package]] -name = "crc" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" -dependencies = [ - "crc-catalog", -] - -[[package]] -name = "crc-catalog" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" - -[[package]] -name = "crossbeam-channel" -version = "0.5.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-bigint" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "ctr" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a232f92a03f37dd7d7dd2adc67166c77e9cd88de5b019b9a9eecfaeaf7bfd481" -dependencies = [ - "cipher 0.3.0", -] - -[[package]] -name = "ctr" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" -dependencies = [ - "cipher 0.3.0", -] - -[[package]] -name = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher 0.4.4", -] - -[[package]] -name = "cuckoofilter" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b810a8449931679f64cd7eef1bbd0fa315801b6d5d9cdc1ace2804d6529eee18" -dependencies = [ - "byteorder", - "fnv", - "rand 0.7.3", - "serde", - "serde_bytes", - "serde_derive", -] - -[[package]] -name = "curve25519-dalek" -version = "4.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" -dependencies = [ - "cfg-if", - "cpufeatures", - "curve25519-dalek-derive", - "digest 0.10.7", - "fiat-crypto", - "rustc_version 0.4.0", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "darling" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" -dependencies = [ - "darling_core 0.10.2", - "darling_macro 0.10.2", -] - -[[package]] -name = "darling" -version = "0.20.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" -dependencies = [ - "darling_core 0.20.8", - "darling_macro 0.20.8", -] - -[[package]] -name = "darling_core" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.9.3", - "syn 1.0.109", -] - -[[package]] -name = "darling_core" -version = "0.20.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.10.0", - "syn 2.0.52", -] - -[[package]] -name = "darling_macro" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" -dependencies = [ - "darling_core 0.10.2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "darling_macro" -version = "0.20.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" -dependencies = [ - "darling_core 0.20.8", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "dashmap" -version = "5.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" -dependencies = [ - "cfg-if", - "hashbrown 0.14.3", - "lock_api", - "once_cell", - "parking_lot_core 0.9.9", -] - -[[package]] -name = "data-encoding" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" - -[[package]] -name = "delay_map" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4355c25cbf99edcb6b4a0e906f6bdc6956eda149e84455bea49696429b2f8e8" -dependencies = [ - "futures", - "tokio-util", -] - -[[package]] -name = "der" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" -dependencies = [ - "const-oid", - "zeroize", -] - -[[package]] -name = "deranged" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" -dependencies = [ - "powerfmt", - "serde", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "derive_builder" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2658621297f2cf68762a6f7dc0bb7e1ff2cfd6583daef8ee0fed6f7ec468ec0" -dependencies = [ - "darling 0.10.2", - "derive_builder_core", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "derive_builder_core" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2791ea3e372c8495c0bc2033991d76b512cd799d07491fbd6890124db9458bef" -dependencies = [ - "darling 0.10.2", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "derive_more" -version = "0.99.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" -dependencies = [ - "convert_case 0.4.0", - "proc-macro2", - "quote", - "rustc_version 0.4.0", - "syn 1.0.109", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", - "subtle", -] - -[[package]] -name = "discv5" -version = "0.3.1" -source = "git+https://github.com/sigp/discv5?rev=f289bbd4c57d499bb1bdb393af3c249600a1c662#f289bbd4c57d499bb1bdb393af3c249600a1c662" -dependencies = [ - "aes 0.7.5", - "aes-gcm", - "arrayvec", - "delay_map", - "enr", - "fnv", - "futures", - "hashlink", - "hex", - "hkdf", - "lazy_static", - "lru", - "more-asserts", - "parking_lot 0.11.2", - "rand 0.8.5", - "rlp", - "smallvec", - "socket2 0.4.10", - "tokio", - "tracing", - "tracing-subscriber", - "uint", - "zeroize", -] - -[[package]] -name = "dns-lookup" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53ecafc952c4528d9b51a458d1a8904b81783feff9fde08ab6ed2545ff396872" -dependencies = [ - "cfg-if", - "libc", - "socket2 0.4.10", - "winapi", -] - -[[package]] -name = "dunce" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" - -[[package]] -name = "dyn_size_of" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d4f78a40b1ec35bf8cafdaaf607ba2f773c366b0b3bda48937cacd7a8d5134" - -[[package]] -name = "ecdsa" -version = "0.16.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" -dependencies = [ - "der", - "digest 0.10.7", - "elliptic-curve", - "rfc6979", - "signature", - "spki", -] - -[[package]] -name = "ed25519" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" -dependencies = [ - "pkcs8", - "signature", -] - -[[package]] -name = "ed25519-dalek" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" -dependencies = [ - "curve25519-dalek", - "ed25519", - "rand_core 0.6.4", - "serde", - "sha2", - "subtle", - "zeroize", -] - -[[package]] -name = "educe" -version = "0.4.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f0042ff8246a363dbe77d2ceedb073339e85a804b9a47636c6e016a9a32c05f" -dependencies = [ - "enum-ordinalize", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "either" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" - -[[package]] -name = "elliptic-curve" -version = "0.13.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" -dependencies = [ - "base16ct", - "crypto-bigint", - "digest 0.10.7", - "ff", - "generic-array", - "group", - "pkcs8", - "rand_core 0.6.4", - "sec1", - "subtle", - "zeroize", -] - -[[package]] -name = "endian-type" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" - -[[package]] -name = "enr" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe81b5c06ecfdbc71dd845216f225f53b62a10cb8a16c946836a3467f701d05b" -dependencies = [ - "base64", - "bytes", - "ed25519-dalek", - "hex", - "k256", - "log", - "rand 0.8.5", - "rlp", - "secp256k1 0.27.0", - "serde", - "sha3", - "zeroize", -] - -[[package]] -name = "enum-as-inner" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "570d109b813e904becc80d8d5da38376818a143348413f7149f1340fe04754d4" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "enum-ordinalize" -version = "3.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf1fa3f06bbff1ea5b1a9c7b14aa992a39657db60a2759457328d7e058f49ee" -dependencies = [ - "num-bigint", - "num-traits", - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "enumn" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "errno" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "eyre" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" -dependencies = [ - "indenter", - "once_cell", -] - -[[package]] -name = "fastrand" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" - -[[package]] -name = "fastrlp" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" -dependencies = [ - "arrayvec", - "auto_impl", - "bytes", -] - -[[package]] -name = "ff" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "fiat-crypto" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1676f435fc1dadde4d03e43f5d62b259e1ce5f40bd4ffb21db2b42ebe59c1382" - -[[package]] -name = "fixed-hash" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" -dependencies = [ - "byteorder", - "rand 0.8.5", - "rustc-hex", - "static_assertions", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "futures" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - -[[package]] -name = "futures-task" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-util" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", -] - -[[package]] -name = "ghash" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" -dependencies = [ - "opaque-debug", - "polyval", -] - -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap 2.2.3", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" -dependencies = [ - "ahash", - "allocator-api2", - "serde", -] - -[[package]] -name = "hashlink" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" -dependencies = [ - "hashbrown 0.14.3", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "hermit-abi" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379dada1584ad501b383485dd706b8afb7a70fcbc7f4da7d780638a5a6124a60" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -dependencies = [ - "serde", -] - -[[package]] -name = "hex-literal" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" - -[[package]] -name = "hkdf" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" -dependencies = [ - "hmac", -] - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "http" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "hyper" -version = "0.14.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2 0.4.10", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-system-resolver" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eea26c5d0b6ab9d72219f65000af310f042a740926f7b2fa3553e774036e2e7" -dependencies = [ - "derive_builder", - "dns-lookup", - "hyper", - "tokio", - "tower-service", - "tracing", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "igd-next" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "064d90fec10d541084e7b39ead8875a5a80d9114a2b18791565253bae25f49e4" -dependencies = [ - "async-trait", - "attohttpc", - "bytes", - "futures", - "http", - "hyper", - "log", - "rand 0.8.5", - "tokio", - "url", - "xmltree", -] - -[[package]] -name = "impl-codec" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" -dependencies = [ - "parity-scale-codec", -] - -[[package]] -name = "impl-trait-for-tuples" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "include_dir" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e" -dependencies = [ - "include_dir_macros", -] - -[[package]] -name = "include_dir_macros" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f" -dependencies = [ - "proc-macro2", - "quote", -] - -[[package]] -name = "indenter" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", -] - -[[package]] -name = "indexmap" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" -dependencies = [ - "equivalent", - "hashbrown 0.14.3", - "serde", -] - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "block-padding", - "generic-array", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "ipnet" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" - -[[package]] -name = "jobserver" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" -dependencies = [ - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "jsonrpsee-types" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be0be325642e850ed0bdff426674d2e66b2b7117c9be23a7caef68a2902b7d9" -dependencies = [ - "anyhow", - "beef", - "serde", - "serde_json", - "thiserror", - "tracing", -] - -[[package]] -name = "k256" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" -dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "once_cell", - "sha2", - "signature", -] - -[[package]] -name = "keccak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" -dependencies = [ - "cpufeatures", -] - -[[package]] -name = "keccak-asm" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb8515fff80ed850aea4a1595f2e519c003e2a00a82fe168ebf5269196caf444" -dependencies = [ - "digest 0.10.7", - "sha3-asm", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -dependencies = [ - "spin", -] - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "libc" -version = "0.2.153" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" - -[[package]] -name = "libffi" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce826c243048e3d5cec441799724de52e2d42f820468431fc3fceee2341871e2" -dependencies = [ - "libc", - "libffi-sys", -] - -[[package]] -name = "libffi-sys" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36115160c57e8529781b4183c2bb51fdc1f6d6d1ed345591d84be7703befb3c" -dependencies = [ - "cc", -] - -[[package]] -name = "libloading" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - -[[package]] -name = "libm" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" - -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - -[[package]] -name = "linked_hash_set" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47186c6da4d81ca383c7c47c1bfc80f4b95f4720514d860a5407aaf4233f9588" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" - -[[package]] -name = "lock_api" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" - -[[package]] -name = "lru" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" -dependencies = [ - "hashbrown 0.14.3", -] - -[[package]] -name = "lz4_flex" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "912b45c753ff5f7f5208307e8ace7d2a2e30d024e26d3509f3dce546c044ce15" - -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata 0.1.10", -] - -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - -[[package]] -name = "memchr" -version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" - -[[package]] -name = "memmap2" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6" -dependencies = [ - "libc", -] - -[[package]] -name = "metrics" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fde3af1a009ed76a778cb84fdef9e7dbbdf5775ae3e4cc1f434a6a307f6f76c5" -dependencies = [ - "ahash", - "metrics-macros", - "portable-atomic", -] - -[[package]] -name = "metrics-macros" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b4faf00617defe497754acde3024865bc143d44a86799b24e191ecff91354f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -dependencies = [ - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", -] - -[[package]] -name = "modular-bitfield" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a53d79ba8304ac1c4f9eb3b9d281f21f7be9d4626f72ce7df4ad8fbde4f38a74" -dependencies = [ - "modular-bitfield-impl", - "static_assertions", -] - -[[package]] -name = "modular-bitfield-impl" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a7d5f7076603ebc68de2dc6a650ec331a062a13abaa346975be747bbfa4b789" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "more-asserts" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fafa6961cabd9c63bcd77a45d7e3b7f3b552b70417831fb0f56db717e72407e" - -[[package]] -name = "nibble_vec" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" -dependencies = [ - "smallvec", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - -[[package]] -name = "num" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" -dependencies = [ - "num-bigint", - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits", -] - -[[package]] -name = "num-bigint" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-complex" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" -dependencies = [ - "autocfg", - "num-bigint", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" -dependencies = [ - "autocfg", - "libm", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "num_enum" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" -dependencies = [ - "num_enum_derive", -] - -[[package]] -name = "num_enum_derive" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" -dependencies = [ - "proc-macro-crate 3.1.0", - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "nybbles" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95f06be0417d97f81fe4e5c86d7d01b392655a9cac9c19a848aa033e18937b23" -dependencies = [ - "alloy-rlp", - "const-hex", - "proptest", - "serde", - "smallvec", -] - -[[package]] -name = "object" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "page_size" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "parity-scale-codec" -version = "3.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" -dependencies = [ - "arrayvec", - "bitvec", - "byte-slice-cast", - "bytes", - "impl-trait-for-tuples", - "parity-scale-codec-derive", - "serde", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "3.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" -dependencies = [ - "proc-macro-crate 2.0.0", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core 0.9.9", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.4.1", - "smallvec", - "windows-targets 0.48.5", -] - -[[package]] -name = "paste" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pest" -version = "2.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546" -dependencies = [ - "memchr", - "thiserror", - "ucd-trie", -] - -[[package]] -name = "ph" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b7b74d575d7c11fb653fae69688be5206cafc1ead33c01ce61ac7f36eae45b" -dependencies = [ - "binout", - "bitm", - "dyn_size_of", - "rayon", - "wyhash", -] - -[[package]] -name = "pin-project" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "pkg-config" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" - -[[package]] -name = "polyval" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" -dependencies = [ - "cfg-if", - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "portable-atomic" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "primitive-types" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" -dependencies = [ - "fixed-hash", - "impl-codec", - "uint", -] - -[[package]] -name = "proc-macro-crate" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" -dependencies = [ - "toml_edit 0.20.7", -] - -[[package]] -name = "proc-macro-crate" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" -dependencies = [ - "toml_edit 0.21.1", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "proptest" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" -dependencies = [ - "bit-set", - "bit-vec", - "bitflags 2.4.2", - "lazy_static", - "num-traits", - "rand 0.8.5", - "rand_chacha 0.3.1", - "rand_xorshift", - "regex-syntax 0.8.2", - "rusty-fork", - "tempfile", - "unarray", -] - -[[package]] -name = "public-ip" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4c40db5262d93298c363a299f8bc1b3a956a78eecddba3bc0e58b76e2f419a" -dependencies = [ - "dns-lookup", - "futures-core", - "futures-util", - "http", - "hyper", - "hyper-system-resolver", - "pin-project-lite", - "thiserror", - "tokio", - "tracing", - "tracing-futures", - "trust-dns-client", - "trust-dns-proto", -] - -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - -[[package]] -name = "quote" -version = "1.0.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "radix_trie" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" -dependencies = [ - "endian-type", - "nibble_vec", -] - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.12", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_xorshift" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" -dependencies = [ - "rand_core 0.6.4", -] - -[[package]] -name = "rayon" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "regex" -version = "1.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata 0.4.5", - "regex-syntax 0.8.2", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", -] - -[[package]] -name = "regex-automata" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax 0.8.2", -] - -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" - -[[package]] -name = "reth-blockchain-tree" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "aquamarine", - "linked_hash_set", - "lru", - "metrics", - "parking_lot 0.12.1", - "reth-db", - "reth-interfaces", - "reth-metrics", - "reth-primitives", - "reth-provider", - "reth-stages", - "reth-trie", - "tokio", - "tracing", -] - -[[package]] -name = "reth-codecs" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "alloy-primitives", - "bytes", - "codecs-derive", -] - -[[package]] -name = "reth-consensus-common" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "alloy-chains", - "cfg-if", - "reth-interfaces", - "reth-primitives", - "reth-provider", -] - -[[package]] -name = "reth-db" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "bytes", - "derive_more", - "eyre", - "metrics", - "modular-bitfield", - "once_cell", - "page_size", - "parity-scale-codec", - "parking_lot 0.12.1", - "paste", - "reth-codecs", - "reth-interfaces", - "reth-libmdbx", - "reth-metrics", - "reth-nippy-jar", - "reth-primitives", - "reth-tracing", - "rustc-hash", - "serde", - "strum", - "thiserror", -] - -[[package]] -name = "reth-discv4" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "alloy-rlp", - "discv5", - "enr", - "generic-array", - "parking_lot 0.12.1", - "reth-net-common", - "reth-net-nat", - "reth-primitives", - "rlp", - "secp256k1 0.27.0", - "serde", - "thiserror", - "tokio", - "tokio-stream", - "tracing", -] - -[[package]] -name = "reth-ecies" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "aes 0.8.4", - "alloy-rlp", - "block-padding", - "byteorder", - "cipher 0.4.4", - "ctr 0.9.2", - "digest 0.10.7", - "educe", - "futures", - "generic-array", - "hmac", - "pin-project", - "rand 0.8.5", - "reth-net-common", - "reth-primitives", - "secp256k1 0.27.0", - "sha2", - "sha3", - "thiserror", - "tokio", - "tokio-stream", - "tokio-util", - "tracing", - "typenum", -] - -[[package]] -name = "reth-eth-wire" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "alloy-chains", - "alloy-rlp", - "bytes", - "derive_more", - "futures", - "metrics", - "pin-project", - "reth-codecs", - "reth-discv4", - "reth-ecies", - "reth-metrics", - "reth-primitives", - "serde", - "snap", - "thiserror", - "tokio", - "tokio-stream", - "tokio-util", - "tracing", -] - -[[package]] -name = "reth-ethereum-forks" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "alloy-chains", - "alloy-primitives", - "alloy-rlp", - "crc", - "serde", - "thiserror", -] - -[[package]] -name = "reth-interfaces" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "auto_impl", - "futures", - "reth-eth-wire", - "reth-network-api", - "reth-nippy-jar", - "reth-primitives", - "reth-rpc-types", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "reth-libmdbx" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "bitflags 2.4.2", - "byteorder", - "dashmap", - "derive_more", - "indexmap 2.2.3", - "libc", - "libffi", - "parking_lot 0.12.1", - "reth-mdbx-sys", - "thiserror", - "tracing", -] - -[[package]] -name = "reth-mdbx-sys" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "bindgen", - "cc", - "libc", -] - -[[package]] -name = "reth-metrics" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "futures", - "metrics", - "reth-metrics-derive", - "tokio", - "tokio-util", -] - -[[package]] -name = "reth-metrics-derive" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "once_cell", - "proc-macro2", - "quote", - "regex", - "syn 2.0.52", -] - -[[package]] -name = "reth-net-common" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "pin-project", - "reth-primitives", - "tokio", -] - -[[package]] -name = "reth-net-nat" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "igd-next", - "pin-project-lite", - "public-ip", - "serde_with", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "reth-network-api" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "alloy-chains", - "async-trait", - "reth-discv4", - "reth-eth-wire", - "reth-primitives", - "reth-rpc-types", - "serde", - "thiserror", - "tokio", -] - -[[package]] -name = "reth-nippy-jar" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "anyhow", - "bincode", - "cuckoofilter", - "derive_more", - "lz4_flex", - "memmap2", - "ph", - "serde", - "sucds 0.8.1", - "thiserror", - "tracing", - "zstd", -] - -[[package]] -name = "reth-node-api" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "reth-primitives", - "reth-rpc-types", - "revm", - "revm-primitives", - "serde", - "thiserror", -] - -[[package]] -name = "reth-primitives" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "alloy-chains", - "alloy-eips", - "alloy-genesis", - "alloy-primitives", - "alloy-rlp", - "alloy-trie", - "byteorder", - "bytes", - "c-kzg", - "cfg-if", - "derive_more", - "itertools 0.12.1", - "modular-bitfield", - "num_enum", - "nybbles", - "once_cell", - "rayon", - "reth-codecs", - "reth-ethereum-forks", - "reth-rpc-types", - "revm", - "revm-primitives", - "secp256k1 0.27.0", - "serde", - "serde_json", - "sha2", - "strum", - "sucds 0.6.0", - "tempfile", - "thiserror", - "tracing", - "zstd", -] - -[[package]] -name = "reth-provider" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "auto_impl", - "dashmap", - "itertools 0.12.1", - "metrics", - "parking_lot 0.12.1", - "pin-project", - "rayon", - "reth-db", - "reth-interfaces", - "reth-metrics", - "reth-nippy-jar", - "reth-node-api", - "reth-primitives", - "reth-trie", - "revm", - "strum", - "tokio", - "tokio-stream", - "tracing", -] - -[[package]] -name = "reth-revm" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "reth-consensus-common", - "reth-interfaces", - "reth-node-api", - "reth-primitives", - "reth-provider", - "revm", - "revm-inspectors", - "tracing", -] - -[[package]] -name = "reth-rpc-types" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "alloy-primitives", - "alloy-rlp", - "alloy-rpc-engine-types", - "alloy-rpc-trace-types", - "alloy-rpc-types", - "bytes", - "itertools 0.12.1", - "jsonrpsee-types", - "secp256k1 0.27.0", - "serde", - "serde_json", - "serde_with", - "thiserror", - "url", -] - -[[package]] -name = "reth-stages" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "aquamarine", - "auto_impl", - "futures-util", - "itertools 0.12.1", - "metrics", - "num-traits", - "pin-project", - "rayon", - "reth-codecs", - "reth-db", - "reth-interfaces", - "reth-metrics", - "reth-primitives", - "reth-provider", - "reth-tokio-util", - "reth-trie", - "revm", - "serde", - "thiserror", - "tokio", - "tokio-stream", - "tracing", -] - -[[package]] -name = "reth-tokio-util" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "tokio", - "tokio-stream", -] - -[[package]] -name = "reth-tracing" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "clap", - "eyre", - "rolling-file", - "tracing", - "tracing-appender", - "tracing-journald", - "tracing-logfmt", - "tracing-subscriber", -] - -[[package]] -name = "reth-trie" -version = "0.1.0-alpha.21" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" -dependencies = [ - "alloy-chains", - "alloy-rlp", - "auto_impl", - "derive_more", - "reth-db", - "reth-interfaces", - "reth-primitives", - "revm", - "thiserror", - "tracing", -] - -[[package]] -name = "rethdb-reader" -version = "0.1.0" -dependencies = [ - "alloy-rlp", - "anyhow", - "reth-blockchain-tree", - "reth-db", - "reth-primitives", - "reth-provider", - "reth-revm", - "reth-rpc-types", - "serde", - "serde_json", -] - -[[package]] -name = "revm" -version = "6.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d35316fc02d99e42831356c71e882f5d385c77b78f64a44ae82f2f9a4b8b72f" -dependencies = [ - "auto_impl", - "cfg-if", - "revm-interpreter", - "revm-precompile", - "serde", - "serde_json", -] - -[[package]] -name = "revm-inspectors" -version = "0.1.0" -source = "git+https://github.com/paradigmxyz/evm-inspectors?rev=75a187b#75a187ba967a29b30af2e5e848073c755068da06" -dependencies = [ - "alloy-primitives", - "alloy-rpc-trace-types", - "alloy-rpc-types", - "alloy-sol-types", - "anstyle", - "colorchoice", - "revm", -] - -[[package]] -name = "revm-interpreter" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fa10c2dc1e8f4934bdc763a2c09371bcec29e50c22e55e3eb325ee0cba09064" -dependencies = [ - "revm-primitives", - "serde", -] - -[[package]] -name = "revm-precompile" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db828d49d329560a70809d9d1fa0c74695edb49f50c5332db3eb24483076deac" -dependencies = [ - "aurora-engine-modexp", - "c-kzg", - "k256", - "once_cell", - "revm-primitives", - "ripemd", - "secp256k1 0.28.2", - "sha2", - "substrate-bn", -] - -[[package]] -name = "revm-primitives" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fecd125aad58e135e2ca5771ed6e4e7b1f05fa3a64e0dfb9cc643b7a800a8435" -dependencies = [ - "alloy-primitives", - "auto_impl", - "bitflags 2.4.2", - "bitvec", - "c-kzg", - "cfg-if", - "derive_more", - "enumn", - "hashbrown 0.14.3", - "hex", - "once_cell", - "serde", -] - -[[package]] -name = "rfc6979" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" -dependencies = [ - "hmac", - "subtle", -] - -[[package]] -name = "ripemd" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "rlp" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" -dependencies = [ - "bytes", - "rustc-hex", -] - -[[package]] -name = "rolling-file" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8395b4f860856b740f20a296ea2cd4d823e81a2658cf05ef61be22916026a906" -dependencies = [ - "chrono", -] - -[[package]] -name = "ruint" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b1d9521f889713d1221270fdd63370feca7e5c71a18745343402fa86e4f04f" -dependencies = [ - "alloy-rlp", - "ark-ff 0.3.0", - "ark-ff 0.4.2", - "bytes", - "fastrlp", - "num-bigint", - "num-traits", - "parity-scale-codec", - "primitive-types", - "proptest", - "rand 0.8.5", - "rlp", - "ruint-macro", - "serde", - "valuable", - "zeroize", -] - -[[package]] -name = "ruint-macro" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f86854cf50259291520509879a5c294c3c9a4c334e9ff65071c51e42ef1e2343" - -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc-hex" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" - -[[package]] -name = "rustc_version" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" -dependencies = [ - "semver 0.11.0", -] - -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver 1.0.22", -] - -[[package]] -name = "rustix" -version = "0.38.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" -dependencies = [ - "bitflags 2.4.2", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustversion" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" - -[[package]] -name = "rusty-fork" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" -dependencies = [ - "fnv", - "quick-error", - "tempfile", - "wait-timeout", -] - -[[package]] -name = "ryu" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "sec1" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" -dependencies = [ - "base16ct", - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - -[[package]] -name = "secp256k1" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" -dependencies = [ - "rand 0.8.5", - "secp256k1-sys 0.8.1", - "serde", -] - -[[package]] -name = "secp256k1" -version = "0.28.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24b59d129cdadea20aea4fb2352fa053712e5d713eee47d700cd4b2bc002f10" -dependencies = [ - "secp256k1-sys 0.9.2", -] - -[[package]] -name = "secp256k1-sys" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" -dependencies = [ - "cc", -] - -[[package]] -name = "secp256k1-sys" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d1746aae42c19d583c3c1a8c646bfad910498e2051c551a7f2e3c0c9fbb7eb" -dependencies = [ - "cc", -] - -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" - -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - -[[package]] -name = "serde" -version = "1.0.197" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_bytes" -version = "0.11.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.197" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "serde_json" -version = "1.0.114" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" -dependencies = [ - "indexmap 2.2.3", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_with" -version = "3.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15d167997bd841ec232f5b2b8e0e26606df2e7caa4c31b95ea9ca52b200bd270" -dependencies = [ - "base64", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.2.3", - "serde", - "serde_derive", - "serde_json", - "serde_with_macros", - "time", -] - -[[package]] -name = "serde_with_macros" -version = "3.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "865f9743393e638991566a8b7a479043c2c8da94a33e0a31f18214c9cae0a64d" -dependencies = [ - "darling 0.20.8", - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest 0.10.7", - "keccak", -] - -[[package]] -name = "sha3-asm" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac61da6b35ad76b195eb4771210f947734321a8d81d7738e1580d953bc7a15e" -dependencies = [ - "cc", - "cfg-if", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", -] - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" -dependencies = [ - "serde", -] - -[[package]] -name = "snap" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" - -[[package]] -name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "socket2" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "strsim" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "strsim" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" - -[[package]] -name = "strum" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "723b93e8addf9aa965ebe2d11da6d7540fa2283fcea14b3371ff055f7ba13f5f" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a3417fc93d76740d974a01654a09777cb500428cc874ca9f45edfe0c4d4cd18" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.52", -] - -[[package]] -name = "substrate-bn" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b5bbfa79abbae15dd642ea8176a21a635ff3c00059961d1ea27ad04e5b441c" -dependencies = [ - "byteorder", - "crunchy", - "lazy_static", - "rand 0.8.5", - "rustc-hex", -] - -[[package]] -name = "subtle" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" - -[[package]] -name = "sucds" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64accd20141dfbef67ad83c51d588146cff7810616e1bda35a975be369059533" -dependencies = [ - "anyhow", -] - -[[package]] -name = "sucds" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53d46182afe6ed822a94c54a532dc0d59691a8f49226bdc4596529ca864cdd6" -dependencies = [ - "anyhow", - "num-traits", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn-solidity" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e656cbcef8a77543b5accbd76f60f9e0bc4be364b0aba4263a6f313f8a355511" -dependencies = [ - "paste", - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "tempfile" -version = "3.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" -dependencies = [ - "cfg-if", - "fastrand", - "rustix", - "windows-sys 0.52.0", -] - -[[package]] -name = "thiserror" -version = "1.0.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "thread_local" -version = "1.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" -dependencies = [ - "cfg-if", - "once_cell", -] - -[[package]] -name = "threadpool" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" -dependencies = [ - "num_cpus", -] - -[[package]] -name = "time" -version = "0.3.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" -dependencies = [ - "deranged", - "itoa", - "num-conv", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" - -[[package]] -name = "time-macros" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", - "parking_lot 0.12.1", - "pin-project-lite", - "signal-hook-registry", - "socket2 0.5.6", - "tokio-macros", - "windows-sys 0.48.0", -] - -[[package]] -name = "tokio-macros" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "tokio-stream" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", - "tokio-util", -] - -[[package]] -name = "tokio-util" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "slab", - "tokio", - "tracing", -] - -[[package]] -name = "toml_datetime" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" - -[[package]] -name = "toml_edit" -version = "0.20.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" -dependencies = [ - "indexmap 2.2.3", - "toml_datetime", - "winnow", -] - -[[package]] -name = "toml_edit" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" -dependencies = [ - "indexmap 2.2.3", - "toml_datetime", - "winnow", -] - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-appender" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" -dependencies = [ - "crossbeam-channel", - "thiserror", - "time", - "tracing-subscriber", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "futures", - "futures-task", - "pin-project", - "tracing", -] - -[[package]] -name = "tracing-journald" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba316a74e8fc3c3896a850dba2375928a9fa171b085ecddfc7c054d39970f3fd" -dependencies = [ - "libc", - "tracing-core", - "tracing-subscriber", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-logfmt" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84bab42e40ace4e4ff19c92023ee1dbc1510db60976828fbbdc6994852c7d065" -dependencies = [ - "time", - "tracing", - "tracing-core", - "tracing-subscriber", -] - -[[package]] -name = "tracing-serde" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" -dependencies = [ - "serde", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "serde", - "serde_json", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", - "tracing-serde", -] - -[[package]] -name = "trust-dns-client" -version = "0.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b4ef9b9bde0559b78a4abb00339143750085f05e5a453efb7b8bef1061f09dc" -dependencies = [ - "cfg-if", - "data-encoding", - "futures-channel", - "futures-util", - "lazy_static", - "log", - "radix_trie", - "rand 0.8.5", - "thiserror", - "time", - "tokio", - "trust-dns-proto", -] - -[[package]] -name = "trust-dns-proto" -version = "0.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca94d4e9feb6a181c690c4040d7a24ef34018d8313ac5044a61d21222ae24e31" -dependencies = [ - "async-trait", - "cfg-if", - "data-encoding", - "enum-as-inner", - "futures-channel", - "futures-io", - "futures-util", - "idna 0.2.3", - "ipnet", - "lazy_static", - "log", - "rand 0.8.5", - "smallvec", - "thiserror", - "tinyvec", - "tokio", - "url", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "ucd-trie" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" - -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - -[[package]] -name = "unarray" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-segmentation" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" - -[[package]] -name = "universal-hash" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "url" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" -dependencies = [ - "form_urlencoded", - "idna 0.5.0", - "percent-encoding", -] - -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "wait-timeout" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" -dependencies = [ - "libc", -] - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.52", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.4", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.4", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" -dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" - -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - -[[package]] -name = "wyhash" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf6e163c25e3fac820b4b453185ea2dea3b6a3e0a721d4d23d75bd33734c295" -dependencies = [ - "rand_core 0.6.4", -] - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "xml-rs" -version = "0.8.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" - -[[package]] -name = "xmltree" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb" -dependencies = [ - "xml-rs", -] - -[[package]] -name = "zerocopy" -version = "0.7.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "zeroize" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "zstd" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "6.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" -dependencies = [ - "libc", - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" -dependencies = [ - "cc", - "pkg-config", -] diff --git a/op-service/rethdb-reader/Cargo.toml b/op-service/rethdb-reader/Cargo.toml deleted file mode 100644 index 16bbc7325b7f..000000000000 --- a/op-service/rethdb-reader/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "rethdb-reader" -description = "A simple library for reading data through Reth's DB abstractions." -version = "0.1.0" -edition = "2021" - -[lib] -name = "rethdbreader" -crate-type = ["cdylib"] - -[dependencies] -# reth -reth-primitives = { git = "https://github.com/paradigmxyz/reth.git", rev = "e0c220e" } -reth-provider = { git = "https://github.com/paradigmxyz/reth.git", rev = "e0c220e" } -reth-db = { git = "https://github.com/paradigmxyz/reth.git", rev = "e0c220e" } -reth-rpc-types = { git = "https://github.com/paradigmxyz/reth.git", rev = "e0c220e" } -reth-blockchain-tree = { git = "https://github.com/paradigmxyz/reth.git", rev = "e0c220e" } - -# misc -serde = "1.0.197" -serde_json = "1.0.114" -anyhow = "1.0.80" - -[dev-dependencies] -reth-revm = { git = "https://github.com/paradigmxyz/reth.git", rev = "e0c220e" } -alloy-rlp = "0.3.4" diff --git a/op-service/rethdb-reader/Makefile b/op-service/rethdb-reader/Makefile deleted file mode 100644 index 6e9037bdfe5b..000000000000 --- a/op-service/rethdb-reader/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -.PHONY: testdata -testdata: - mkdir -p testdata - @echo "Fetching block RLP and receipts for block #18,663,292 from ethereum mainnet" - cast rpc debug_getRawBlock 0x11CC77C | jq -r | xxd -r -p > testdata/block.rlp - cast rpc debug_getRawReceipts 0x11CC77C | jq -r > testdata/receipts.json - @echo "Done. Generating testdata DB & testing integrity..." - cargo test diff --git a/op-service/rethdb-reader/README.md b/op-service/rethdb-reader/README.md deleted file mode 100644 index 9f760f978015..000000000000 --- a/op-service/rethdb-reader/README.md +++ /dev/null @@ -1,113 +0,0 @@ -# `rethdb-reader` - -A dylib to be accessed via FFI in `op-service`'s `sources` package for reading information -directly from the `reth` database. - -## Developing - -**Building** - -To build the dylib, you must first have the [Rust Toolchain][rust-toolchain] installed. - -```sh -cargo build --release -``` - -**Docs** - -Documentation is available via rustdoc. - -```sh -cargo doc --open -``` - -**Linting** - -```sh -cargo +nightly fmt -- && cargo +nightly clippy --all --all-features -- -D warnings -``` - -**Generating `testdata`** - -The testdata block and `reth` database can be generated by running the `testdata` make directive: - -```sh -ETH_RPC_URL="" make testdata -``` - -**Generating the C header** - -To generate the C header, first install `cbindgen` via `cargo install cbindgen --force`. Then, run the generation script: - -```sh -./headgen.sh -``` - -### C Header - -The C header below is generated by `cbindgen`, and it is the interface that consumers of the dylib use to call its exported -functions. Currently, the only exported functions pertain to reading fully hydrated block receipts from the database. - -```c -#include -#include -#include -#include - -/** - * A [ReceiptsResult] is a wrapper around a JSON string containing serialized [TransactionReceipt]s - * as well as an error status that is compatible with FFI. - * - * # Safety - * - When the `error` field is false, the `data` pointer is guaranteed to be valid. - * - When the `error` field is true, the `data` pointer is guaranteed to be null. - */ -typedef struct ReceiptsResult { - uint32_t *data; - uintptr_t data_len; - bool error; -} ReceiptsResult; - -/** - * A [OpenDBResult] is a wrapper of DB instance [BlockchainProvider] - * as well as an error status that is compatible with FFI. - * - * # Safety - * - When the `error` field is false, the `data` pointer is guaranteed to be valid. - * - When the `error` field is true, the `data` pointer is guaranteed to be null. - */ -typedef struct OpenDBResult { - const void *data; - bool error; -} OpenDBResult; - -/** - * Read the receipts for a blockhash from the RETH database directly. - * - * # Safety - * - All possible nil pointer dereferences are checked, and the function will return a failing - * [ReceiptsResult] if any are found. - */ -struct ReceiptsResult rdb_read_receipts(const uint8_t *block_hash, - uintptr_t block_hash_len, - const void *db_instance); - -/** - * Free a string that was allocated in Rust and passed to C. - * - * # Safety - * - All possible nil pointer dereferences are checked. - */ -void rdb_free_string(char *string); - -/** - * Open a DB instance and return. - * - * # Safety - * - All possible nil pointer dereferences are checked, and the function will return a failing - * [OpenDBResult] if any are found. - */ -struct OpenDBResult open_db_read_only(const char *db_path); -``` - -[rust-toolchain]: https://rustup.rs/ diff --git a/op-service/rethdb-reader/headgen.sh b/op-service/rethdb-reader/headgen.sh deleted file mode 100755 index e7f7daf676d4..000000000000 --- a/op-service/rethdb-reader/headgen.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -set -e - -# Generate rdb.h -cbindgen --crate rethdb-reader --output rdb.h -l C - -# Process README.md to replace the content within the specified code block -awk ' - BEGIN { in_code_block=0; } - /^```c/ { in_code_block=1; print; next; } - /^```/ && in_code_block { in_code_block=0; while ((getline line < "rdb.h") > 0) print line; } - !in_code_block { print; } -' README.md > README.tmp && mv README.tmp README.md - -echo "Generated C header successfully" diff --git a/op-service/rethdb-reader/rustfmt.toml b/op-service/rethdb-reader/rustfmt.toml deleted file mode 100644 index 68c3c93033d4..000000000000 --- a/op-service/rethdb-reader/rustfmt.toml +++ /dev/null @@ -1,11 +0,0 @@ -reorder_imports = true -imports_granularity = "Crate" -use_small_heuristics = "Max" -comment_width = 100 -wrap_comments = true -binop_separator = "Back" -trailing_comma = "Vertical" -trailing_semicolon = false -use_field_init_shorthand = true -format_code_in_doc_comments = true -doc_comment_code_block_width = 100 diff --git a/op-service/rethdb-reader/src/db.rs b/op-service/rethdb-reader/src/db.rs deleted file mode 100644 index 8d1840fbdea0..000000000000 --- a/op-service/rethdb-reader/src/db.rs +++ /dev/null @@ -1,59 +0,0 @@ -use anyhow::{anyhow, Result}; -use reth_blockchain_tree::noop::NoopBlockchainTree; -use reth_db::{mdbx::DatabaseArguments, open_db_read_only}; -use reth_primitives::MAINNET; -use reth_provider::{providers::BlockchainProvider, ProviderFactory}; -use std::{ - ffi::{c_char, c_void}, - path::Path, -}; - -/// A [OpenDBResult] is a wrapper of DB instance [BlockchainProvider] -/// as well as an error status that is compatible with FFI. -/// -/// # Safety -/// - When the `error` field is false, the `data` pointer is guaranteed to be valid. -/// - When the `error` field is true, the `data` pointer is guaranteed to be null. -#[repr(C)] -pub struct OpenDBResult { - pub(crate) data: *const c_void, - pub(crate) error: bool, -} - -impl OpenDBResult { - /// Constructs a successful [OpenDBResult] from a DB instance. - pub fn success(data: *const c_void) -> Self { - Self { data, error: false } - } - - /// Constructs a failing [OpenDBResult] with a null pointer to the data. - pub fn fail() -> Self { - Self { data: std::ptr::null_mut(), error: true } - } -} - -/// Open and return a DB instance. -/// -/// # Safety -/// - All possible nil pointer dereferences are checked, and the function will return a failing -/// [OpenDBResult] if any are found. -#[inline(always)] -pub(crate) unsafe fn open_db_read_only_inner(db_path: *const c_char) -> Result { - // Convert the *const c_char to a Rust &str - let db_path_str = { - if db_path.is_null() { - anyhow::bail!("db path pointer is null"); - } - std::ffi::CStr::from_ptr(db_path) - } - .to_str()?; - - let db = open_db_read_only(Path::new(db_path_str), DatabaseArguments::default()) - .map_err(|e| anyhow!(e))?; - let factory = ProviderFactory::new(db, MAINNET.clone()); - - // Create a read-only BlockChainProvider - let provider = Box::new(BlockchainProvider::new(factory, NoopBlockchainTree::default())?); - let res = OpenDBResult::success(Box::into_raw(provider) as *const c_void); - Ok(res) -} diff --git a/op-service/rethdb-reader/src/lib.rs b/op-service/rethdb-reader/src/lib.rs deleted file mode 100644 index 4aa785608081..000000000000 --- a/op-service/rethdb-reader/src/lib.rs +++ /dev/null @@ -1,47 +0,0 @@ -#![doc = include_str!("../README.md")] - -use db::{open_db_read_only_inner, OpenDBResult}; -use receipts::{read_receipts_inner, ReceiptsResult}; -use std::ffi::c_void; - -use std::os::raw::c_char; - -mod db; -mod receipts; - -/// Read the receipts for a blockhash from the RETH database directly. -/// -/// # Safety -/// - All possible nil pointer dereferences are checked, and the function will return a failing -/// [ReceiptsResult] if any are found. -#[no_mangle] -pub unsafe extern "C" fn rdb_read_receipts( - block_hash: *const u8, - block_hash_len: usize, - db_instance: *const c_void, -) -> ReceiptsResult { - read_receipts_inner(block_hash, block_hash_len, db_instance).unwrap_or(ReceiptsResult::fail()) -} - -/// Free a string that was allocated in Rust and passed to C. -/// -/// # Safety -/// - All possible nil pointer dereferences are checked. -#[no_mangle] -pub unsafe extern "C" fn rdb_free_string(string: *mut c_char) { - // Convert the raw pointer back to a CString and let it go out of scope, - // which will deallocate the memory. - if !string.is_null() { - let _ = std::ffi::CString::from_raw(string); - } -} - -/// Open a DB instance and return. -/// -/// # Safety -/// - All possible nil pointer dereferences are checked, and the function will return a failing -/// [OpenDBResult] if any are found. -#[no_mangle] -pub unsafe extern "C" fn open_db_read_only(db_path: *const c_char) -> OpenDBResult { - open_db_read_only_inner(db_path).unwrap_or(OpenDBResult::fail()) -} diff --git a/op-service/rethdb-reader/src/receipts.rs b/op-service/rethdb-reader/src/receipts.rs deleted file mode 100644 index 0dea66689b5f..000000000000 --- a/op-service/rethdb-reader/src/receipts.rs +++ /dev/null @@ -1,334 +0,0 @@ -//! This module contains the logic for reading a block's fully hydrated receipts directly from the -//! [reth] database. - -use anyhow::{anyhow, Result}; -use reth_blockchain_tree::noop::NoopBlockchainTree; -use reth_db::DatabaseEnv; -use reth_primitives::{ - BlockHashOrNumber, Receipt, TransactionKind, TransactionMeta, TransactionSigned, U128, U256, - U64, -}; -use reth_provider::{providers::BlockchainProvider, BlockReader, ReceiptProvider}; -use reth_rpc_types::{Log, TransactionReceipt}; -use std::ffi::c_void; - -/// A [ReceiptsResult] is a wrapper around a JSON string containing serialized [TransactionReceipt]s -/// as well as an error status that is compatible with FFI. -/// -/// # Safety -/// - When the `error` field is false, the `data` pointer is guaranteed to be valid. -/// - When the `error` field is true, the `data` pointer is guaranteed to be null. -#[repr(C)] -pub struct ReceiptsResult { - data: *mut char, - data_len: usize, - error: bool, -} - -impl ReceiptsResult { - /// Constructs a successful [ReceiptsResult] from a JSON string. - pub fn success(data: *mut char, data_len: usize) -> Self { - Self { data, data_len, error: false } - } - - /// Constructs a failing [ReceiptsResult] with a null pointer to the data. - pub fn fail() -> Self { - Self { data: std::ptr::null_mut(), data_len: 0, error: true } - } -} - -/// Read the receipts for a blockhash from the RETH database directly. -/// -/// # Safety -/// - All possible nil pointer dereferences are checked, and the function will return a failing -/// [ReceiptsResult] if any are found. -#[inline(always)] -pub(crate) unsafe fn read_receipts_inner( - block_hash: *const u8, - block_hash_len: usize, - db_instance: *const c_void, -) -> Result { - // Convert the raw pointer and length back to a Rust slice - let block_hash: [u8; 32] = { - if block_hash.is_null() { - anyhow::bail!("block_hash pointer is null"); - } - std::slice::from_raw_parts(block_hash, block_hash_len) - } - .try_into()?; - - // Create a read-only BlockChainProvider - let provider = &*(db_instance as *const BlockchainProvider); - // Fetch the block and the receipts within it - let block = - provider.block_by_hash(block_hash.into())?.ok_or(anyhow!("Failed to fetch block"))?; - let receipts = provider - .receipts_by_block(BlockHashOrNumber::Hash(block_hash.into()))? - .ok_or(anyhow!("Failed to fetch block receipts"))?; - - let block_number = block.number; - let base_fee = block.base_fee_per_gas; - let block_hash = block.hash_slow(); - let receipts = block - .body - .into_iter() - .zip(receipts.clone()) - .enumerate() - .map(|(idx, (tx, receipt))| { - let meta = TransactionMeta { - tx_hash: tx.hash, - index: idx as u64, - block_hash, - block_number, - base_fee, - excess_blob_gas: None, - }; - build_transaction_receipt_with_block_receipts(tx, meta, receipt, &receipts) - }) - .collect::>>() - .ok_or(anyhow!("Failed to build receipts"))?; - - // Convert the receipts to JSON for transport - let mut receipts_json = serde_json::to_string(&receipts)?; - - // Create a ReceiptsResult with a pointer to the json-ified receipts - let res = ReceiptsResult::success(receipts_json.as_mut_ptr() as *mut char, receipts_json.len()); - - // Forget the `receipts_json` string so that its memory isn't freed by the - // borrow checker at the end of this scope - std::mem::forget(receipts_json); // Prevent Rust from freeing the memory - - Ok(res) -} - -/// Builds a hydrated [TransactionReceipt] from information in the passed transaction, -/// receipt, and block receipts. -/// -/// Returns [None] if the transaction's sender could not be recovered from the signature. -#[inline(always)] -fn build_transaction_receipt_with_block_receipts( - tx: TransactionSigned, - meta: TransactionMeta, - receipt: Receipt, - all_receipts: &[Receipt], -) -> Option { - let transaction = tx.clone().into_ecrecovered()?; - - // get the previous transaction cumulative gas used - let gas_used = if meta.index == 0 { - receipt.cumulative_gas_used - } else { - let prev_tx_idx = (meta.index - 1) as usize; - all_receipts - .get(prev_tx_idx) - .map(|prev_receipt| receipt.cumulative_gas_used - prev_receipt.cumulative_gas_used) - .unwrap_or_default() - }; - - let mut res_receipt = TransactionReceipt { - transaction_hash: Some(meta.tx_hash), - transaction_index: U64::from(meta.index), - block_hash: Some(meta.block_hash), - block_number: Some(U256::from(meta.block_number)), - from: transaction.signer(), - to: None, - cumulative_gas_used: U256::from(receipt.cumulative_gas_used), - gas_used: Some(U256::from(gas_used)), - contract_address: None, - logs: Vec::with_capacity(receipt.logs.len()), - effective_gas_price: U128::from(transaction.effective_gas_price(meta.base_fee)), - transaction_type: tx.transaction.tx_type().into(), - // TODO pre-byzantium receipts have a post-transaction state root - state_root: None, - logs_bloom: receipt.bloom_slow(), - status_code: if receipt.success { Some(U64::from(1)) } else { Some(U64::from(0)) }, - - // EIP-4844 fields - blob_gas_price: None, - blob_gas_used: None, - - // Other: - other: Default::default(), - }; - - match tx.transaction.kind() { - TransactionKind::Create => { - res_receipt.contract_address = - Some(transaction.signer().create(tx.transaction.nonce())); - } - TransactionKind::Call(addr) => { - res_receipt.to = Some(*addr); - } - } - - // get number of logs in the block - let mut num_logs = 0; - for prev_receipt in all_receipts.iter().take(meta.index as usize) { - num_logs += prev_receipt.logs.len(); - } - - for (tx_log_idx, log) in receipt.logs.into_iter().enumerate() { - let rpclog = Log { - address: log.address, - topics: log.topics, - data: log.data, - block_hash: Some(meta.block_hash), - block_number: Some(U256::from(meta.block_number)), - transaction_hash: Some(meta.tx_hash), - transaction_index: Some(U256::from(meta.index)), - log_index: Some(U256::from(num_logs + tx_log_idx)), - removed: false, - }; - res_receipt.logs.push(rpclog); - } - - Some(res_receipt) -} - -#[cfg(test)] -mod test { - use super::*; - use alloy_rlp::Decodable; - use reth_db::{database::Database, mdbx::DatabaseArguments}; - use reth_primitives::{ - address, b256, bloom, hex, Address, Block, Bytes, ReceiptWithBloom, Receipts, - SealedBlockWithSenders, MAINNET, U8, - }; - use reth_provider::{BlockWriter, BundleStateWithReceipts, DatabaseProvider}; - use reth_revm::revm::db::BundleState; - use std::{ - ffi::{c_char, CString}, - fs::File, - path::Path, - }; - - #[inline] - fn dummy_block_with_receipts() -> Result<(Block, Vec)> { - // To generate testdata (block 18,663,292 on Ethereum Mainnet): - // 1. BLOCK RLP: `cast rpc debug_getRawBlock 0x11CC77C | jq -r | xxd -r -p > - // testdata/block.rlp` - // 2. RECEIPTS RLP: `cast rpc debug_getRawReceipts 0x11CC77C | jq -r > - // testdata/receipts.json` - let block_rlp = include_bytes!("../testdata/block.rlp"); - let block = Block::decode(&mut block_rlp.as_ref())?; - - let receipt_rlp: Vec> = serde_json::from_str(include_str!( - "../testdata/receipts.json" - )) - .map(|v: Vec| { - v.into_iter().map(|s| hex::decode(s)).collect::>, _>>() - })??; - let receipts = receipt_rlp - .iter() - .map(|r| ReceiptWithBloom::decode(&mut r.as_slice()).map(|r| r.receipt)) - .collect::, _>>()?; - - Ok((block, receipts)) - } - - #[inline] - fn open_receipts_testdata_db() -> Result<()> { - if File::open("testdata/db").is_ok() { - return Ok(()); - } - - // Open a RW handle to the MDBX database - let db = reth_db::init_db(Path::new("testdata/db"), DatabaseArguments::default()) - .map_err(|e| anyhow!(e))?; - let pr = DatabaseProvider::new_rw(db.tx_mut()?, MAINNET.clone()); - - // Grab the dummy block and receipts - let (mut block, receipts) = dummy_block_with_receipts()?; - - // Patch: The block's current state root expects the rest of the chain history to be in the - // DB; manually override it. Otherwise, the DatabaseProvider will fail to commit the - // block. - block.header.state_root = reth_primitives::constants::EMPTY_ROOT_HASH; - - // Fetch the block number and tx senders for bundle state creation. - let block_number = block.header.number; - let senders = block - .body - .iter() - .map(|tx| tx.recover_signer()) - .collect::>>() - .ok_or(anyhow!("Failed to recover signers"))?; - - // Commit the bundle state to the database - pr.append_blocks_with_state( - vec![SealedBlockWithSenders { block: block.seal_slow(), senders }], - BundleStateWithReceipts::new( - BundleState::default(), - Receipts::from_block_receipt(receipts), - block_number, - ), - Default::default(), - Default::default(), - None, - )?; - pr.commit()?; - - Ok(()) - } - - #[test] - fn fetch_receipts() { - open_receipts_testdata_db().unwrap(); - unsafe { - let res = crate::open_db_read_only( - CString::new("testdata/db").unwrap().into_raw() as *const c_char - ); - assert_eq!(res.error, false); - - let mut block_hash = - b256!("6a229123d607c2232a8b0bdd36f90745945d05181018e64e60ff2b93ab6b52e5"); - let receipts_res = - super::read_receipts_inner(block_hash.as_mut_ptr(), 32, res.data).unwrap(); - - let receipts_data = - std::slice::from_raw_parts(receipts_res.data as *const u8, receipts_res.data_len); - let receipt = { - let mut receipts: Vec = - serde_json::from_slice(receipts_data).unwrap(); - receipts.remove(0) - }; - - // Check the first receipt in the block for validity - assert_eq!(receipt.transaction_type, U8::from(2)); - assert_eq!(receipt.status_code, Some(U64::from(1))); - assert_eq!(receipt.cumulative_gas_used, U256::from(115_316)); - assert_eq!(receipt.logs_bloom, bloom!("00200000000000000000000080001000000000000000000000000000000000000000000000000000000000000000100002000100080000000000000000000000000000000000000000000008000000200000000400000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000400000000000001000000000000000100000000080000004000000000000000000000000000000000000002000000000000000000000000000000000000000006000000000000000000000000000000000000001000000000000000000000200000000000000100000000020000000000000000000000000000000010")); - assert_eq!( - receipt.logs[0].address, - address!("c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2") - ); - assert_eq!( - receipt.logs[0].topics[0], - b256!("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef") - ); - assert_eq!( - receipt.logs[0].topics[1], - b256!("00000000000000000000000000000000003b3cc22af3ae1eac0440bcee416b40") - ); - assert_eq!( - receipt.logs[0].data, - Bytes::from_static( - hex!("00000000000000000000000000000000000000000000000008a30cd230000000") - .as_slice() - ) - ); - assert_eq!(receipt.from, address!("41d3ab85aafed2ef9e644cb7d3bbca2fc4d8cac8")); - assert_eq!(receipt.to, Some(address!("00000000003b3cc22af3ae1eac0440bcee416b40"))); - assert_eq!( - receipt.transaction_hash, - Some(b256!("88b2d153a4e893ba91ac235325c44b1aa0c802fcb42657701e1a73e1c675f7ca")) - ); - - assert_eq!(receipt.block_number, Some(U256::from(18_663_292))); - assert_eq!(receipt.block_hash, Some(block_hash)); - assert_eq!(receipt.transaction_index, U64::from(0)); - - crate::rdb_free_string(receipts_res.data as *mut c_char); - } - } -} diff --git a/op-service/rethdb-reader/testdata/block.rlp b/op-service/rethdb-reader/testdata/block.rlp deleted file mode 100644 index 978ba6be01b47513229903acd998776e17a37f00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8833 zcmcgx2{=@3`#)!leb17m7~5NDk)^k6P1X>VtS^RSEA&RPCB`yHL<~i$(`G44gec0s zl!PoA&Uo+QSy-JOVPoP z1#c@phhSSSOU&__8k+If%_`^+-{5-g_c`8y);AiCysoqHze6Z=E^2HOda*`Zm>A{7 zGjUC09^00nOH33Ok9+0mdt2?*j?{|&7RN?|+#x78I4!<)W4pUjJ-cJh1Ixp%Iv!X# zlg~9?I^_d{T?gtRwuMifiQ*AqDtAPb9USQoOx5pf5dEeiwa{)mWpduC7TWl#+ukC) z%D%bw30t?+$!+usT?+~(Wz8Q<{X8&56ZjGk0K@e&4t1P`vEQhE+7a5!xUN^ z4Lg`c1kgt@VE{ZgfP%S57=uwJK$;0=F!1FJGZTPig4Gy25kLb6m|zmX;_Uz|EcjlS z*syR!Kyt}L1H2&I7+ix1i`QC&FiR~0sKv%XI5r-x4{)LJD6u6Li&_KVL4W~{02dbc zgMmLx03KE`EM~Fjzy%8numHfdcpE4{9EAneU;tPJpa{HhXcTO4fk4=z28Ka27d{MJ zR~HZlHdNt5`KAtqIXa~L8Efx&$lKA={^Suihb@15Izy)|uG6`6?;RTE#XhxtP9`N? zGTkejRAX-Zw9Y`juf`#AG1_7wFiQG=0-+hpGF_WO)}tdazRm}8>QxQ(>_2Oyl;N1^ zQ?qA9G)|D$PnXd7pvZJ5zz{QSJb{Us#h@Y-1xOK>qNu1=%1q~oWTCO8pLV-q@x?m8 zoNJKutya|tzqQu<#Cra4mx{GMajAa1n;W{~ePbD;U_nvT5Lp0ASe>2_AE#%ffU~KUQbS&K61c9 z;D&4}wBu+~w*~In+mt)(Qhqzj7{BqBo3NSCy*`?k#Zx2L5N8$gKV?} zOtb_Hv;>S~u!h*eT7TfU<&dyFPQ*NoRWZhNtBVa8%%)YBgO-41>%6og@X!))LHyR0 znwtck&k0#uzY*E={_dbgYQb*Pk69JvEUw2M3BIEh0f6k^RrqnQE1QToF1`-icGjqxLk}qIVwnd1OTfSPDtveBvEc3p}x+;Y8Y2z)vL~cY4I}@vEXMD8&x(4 z@1T_=Gc5rt9`ZJ+AWWATb$;X<6r1mk-&=cq&(7(+be{!3tG7IV$f^!GW~JRyE!mpu z^w>(Ptl;y7hh>xL0Urtzs_|WrJ!9X|5)g+XgMWd+;bHW%{Q!YEwhnR&rPBx@ZmFYx z!B8l&$5ptzOGJ=FfMi>l{&w~;3;`g)mXth zi4Nw;hW+gvcXLkD2lLF zNZ3zOyS_it%Bmyr=HM2N?u7S(4+dtSZNda62mV0aVfj-zZ%TbGwW2qZdl-R%?c6-K zTpyac6gQ$s4e-LIL$J9=?!glr%g`Hkhk{R3sjP06;PUE*loQgbLU|u6ZFsSZ=Z6>* zckNID;JZO7`xmezMPA}*Gx8n}2D-E_$TR{;+FzU8UIg#U%Zq@l1foWz?+w$3;0`)R z8>DQ?*fG-K$g(Tv$w18=$0-I?B-@ITiq2=veZ8C@<-sTfjJt>|=>MBb^8D zSIeclA}BFt%aFu%j6FlL_Js6Fp6Rus>@Yjq84D0u`Mi-1u=XcS6!>G6*e{8zRc(0c-q z1I3f!OGrC>85jfPP&y!dNuOGbz#66ZlE3lzrDNH5i5KZu26nqT^)BKfmlab#_$;LD z5d{(xxYl!E(ui@3IMPU8#IseLOEVIz3%TlB&bHaI5@+?3Vi$3OM}_pXQs`FKQtvh* zZ?B2ak&O*%!5d`2cqer{a>;xcjw+p zX`j{{o0*%PX4%_=G-nyQIolK}Zgt+AgSffNwa&8$Xdh(P=WhRWyYgJs=k;9dxrSI> zQ2}EB%l9KaUe!MZZ|p<&VLk%D1}+e3Q$w8nJeb9&{pHdvtTGG0Al)(qp!mLV90qvc zlfsW8$YZ`y{L=|h7+e;r;mX~GJ%peC5Pkn9)6ab&a&vR9G5M5l;!_k`jO&vAqMSq@ z(hmttPPL|%OWC!4-P$H#Q^w*NZ(#Ro)8x=5wj}xB>IQ8x7)nIy9x~_(@p;}J@5>jw z%E))9I5J^6$YP%{@^C{cilSZBB)B?tD3NoAdcVMW$q^b@YN4=i%cuksZMaZb&>lpD6?fY|Lv zZr?5!FJ7Dc^sm6)Q*IMOiei}bB6T27(~qQ7r~ql_@p_we8xq+}?LsE{uACoe)~Tr1 zav_a%7{>Ol^GczWBme~@i51WC`E9^VFl&h6wg!X<96RW%Z+-Tup17UA`jKAf(gmYj zjEjO+ppB?%u%(<-;N<=0M;Qqx7XHXTA$P$Q?#F7hOlI>AD!#f!h$cIP>0#bi2F(VP^YMurEPYu z4Yr-Z+qcykK9&(oy3#d}dlK4R(-(eT@Y}Gde&59HPPwrRF)LT-Sif|zXn}R*lz}A_ z*I|Y~#g}o!bNg2d|5ruCj-;1rjc=}}xAhjTBc!uBKrT*hW64<>xld+-bOhEPw)+b@ z1wMGkJSrno=9KeB z{E?5#hoN--Cq}{ILJtCV?C@qqqjZ28NN?UueY=sLU4nP!bTdRhy1!hWw|jO#V4xf; z5;0Vjx7(*AGg)nm?IG`noF`?VtdE{bmm`=)ZN%0*IQ~xbx^t4hX=Dp7z_%jKi2eN_ z7u>Z-OC#;B{a>7?|NnhYDkUQA8l+paLem^M0IdjUS^^MKxBVb_+pu~l=WU2lz3{6bhs32HZrj8X$bP%Z?N3F{zy67>yl z1w+vVM#LVAGXuCkuT1Dg<*fO;va$bbt2}=scv#!lCJF#bz-rL`Esgyf=mSJ>@ss!#`Hlw@8)ap>T!Nw5*C} zVYuR+%I5|>)#Cor4weIgWL}YV%}3b_=ON9~>2*yGP6jc1{!;nq)@~YpIXOVy^_}I0 z<_#U=@n?(3D8mpi`u_$F-G>Ckfdjwh9X!4;*-e?y<@VX`Q5^+u)@@ShdK^!+J(^QA zD0x~p)maLf>FrS-9gjZOZyrwvGSO-^V}8`^9TU?R*CAVFjN9CI8dT zx)-!(L9$X!K%w?0_KN|Y*y;7AUtmRk#sD;$cc|2I;X|I|f>ivY>He@42fklIz%H%v z2)|oiy&&hmT!&Tzv<^ATkr1qZF(CjcNZ@Ri{?!LE+?}YdVZo_7Chkj*>KGa6_m)R? z==DpNnLbl-}ah$tI(|t0`nHcR)DHB%&{G^XzAM}@iMew_^d=MR$-;9G7 zB(_KD&Y^TXXyQ4!*V$`Y;x|4|?Y+29B8a7#eKHXqS6Wf+MY9O$QbJft2f?;Qz+7w&P@cScG>dVA>HA`r0lk}(#m=xoG4wzQMdWCN>+`$_+l+)T>8DAt^Y8@+fLAN za=X7C{am12clO5O8FaM*C%wKINAzvHzmYHNi?t#@-ysrx_hk%w=fgv(RbBri5h;qX=k#p-y0Sl&Pc}X1;-bRxbGj@=^glwhW~ULQ)H(*AM(@WS(GZI3yJdo2|5 z58<0-ybHtin8vLkJ0+w=wXXIQJ@WVi62BJqRG0lZLG@~jly*>c&NjY=?tDa2I=_NFHD)akpSaMb+u+(IL=@gP2J-W0_NQ zz==#~Gw8SC4Feeh&o2ckhc%H@1C^#Mi7H^x8LA@Iz$H;7EQ+Ekiu$%Bs)9vlsfwUBDAMl#mYybcN diff --git a/op-service/rethdb-reader/testdata/receipts.json b/op-service/rethdb-reader/testdata/receipts.json deleted file mode 100644 index aef76b0c2eb8..000000000000 --- a/op-service/rethdb-reader/testdata/receipts.json +++ /dev/null @@ -1,12 +0,0 @@ -[ - "0xb903c202f903be018301c274b9010000200000000000000000000080001000000000000000000000000000000000000000000000000000000000000000100002000100080000000000000000000000000000000000000000000008000000200000000400000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000400000000000001000000000000000100000000080000004000000000000000000000000000000000000002000000000000000000000000000000000000000006000000000000000000000000000000000000001000000000000000000000200000000000000100000000020000000000000000000000000000000010f902b3f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000000000000003b3cc22af3ae1eac0440bcee416b40a00000000000000000000000005c1694c8168668c11777909c79142dc9d992788fa000000000000000000000000000000000000000000000000008a30cd230000000f89b94d10bc8517059e51b625e1e57a60b348d552f685df863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000005c1694c8168668c11777909c79142dc9d992788fa000000000000000000000000000000000003b3cc22af3ae1eac0440bcee416b40a000000000000000000000000000000000000000000000000000007921e915b684f879945c1694c8168668c11777909c79142dc9d992788fe1a01c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1b840000000000000000000000000000000000000000000000001129c9861392306df000000000000000000000000000000000000000000000000000e9d834abd9cdff8fc945c1694c8168668c11777909c79142dc9d992788ff863a0d78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822a000000000000000000000000000000000003b3cc22af3ae1eac0440bcee416b40a000000000000000000000000000000000003b3cc22af3ae1eac0440bcee416b40b88000000000000000000000000000000000000000000000000008a30cd2300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007921e915b684", - "0xb9043e02f9043a0183042135b9010000200000000000000000000080001000100000000000000000000000000000000000000000000000000000000000100002000000080000000000000000010000000000000000010000000008000000200000000400100000000000008000000000000000000000000000000000000000000000000000000000000010000000000000000400000000000001000000000000000101000000080000004000000000000000000000000000000000000002000000000000000000000000000000000000000002000000000000000000000000000000000000001000000000000000000000200000000000008000000000020000000000000000400000000000000010f9032ff87a94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f842a0e1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109ca00000000000000000000000002ec705d306b51e486b1bc0d6ebee708e0661add1a00000000000000000000000000000000000000000000000000bd0c7ca01c48000f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000002ec705d306b51e486b1bc0d6ebee708e0661add1a00000000000000000000000005c1694c8168668c11777909c79142dc9d992788fa00000000000000000000000000000000000000000000000000bd0c7ca01c48000f89b94d10bc8517059e51b625e1e57a60b348d552f685df863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000005c1694c8168668c11777909c79142dc9d992788fa00000000000000000000000001f3c8f19ab956457994de1d50eb0ae7d057f77f8a0000000000000000000000000000000000000000000000000000099e622c10336f879945c1694c8168668c11777909c79142dc9d992788fe1a01c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1b8400000000000000000000000000000000000000000000000011e6d602b3ae786df000000000000000000000000000000000000000000000000000e039d27fc99a9f8fc945c1694c8168668c11777909c79142dc9d992788ff863a0d78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822a00000000000000000000000002ec705d306b51e486b1bc0d6ebee708e0661add1a00000000000000000000000001f3c8f19ab956457994de1d50eb0ae7d057f77f8b8800000000000000000000000000000000000000000000000000bd0c7ca01c4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000099e622c10336", - "0xb903c202f903be018305b26fb9010000200000000000000000000080001000000000000000000000000000000000000000000000000000000000000000100002000100080000000000000000000000000000000000000000000008000000200000000400000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000400000000000001000000000000000100000000080000004000000000000000000000000000000000000002000000000000000000000000000000000000000006000000000000000000000000000000000000001000000000000000000000200000000000000100000000020000000000000000000000000000000010f902b3f89b94d10bc8517059e51b625e1e57a60b348d552f685df863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000000000000003b3cc22af3ae1eac0440bcee416b40a00000000000000000000000005c1694c8168668c11777909c79142dc9d992788fa000000000000000000000000000000000000000000000000000007921e99216a0f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000005c1694c8168668c11777909c79142dc9d992788fa000000000000000000000000000000000003b3cc22af3ae1eac0440bcee416b40a00000000000000000000000000000000000000000000000000953f38350000000f879945c1694c8168668c11777909c79142dc9d992788fe1a01c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1b84000000000000000000000000000000000000000000000000115196ca7eae786df000000000000000000000000000000000000000000000000000e7cbf118eb049f8fc945c1694c8168668c11777909c79142dc9d992788ff863a0d78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822a000000000000000000000000000000000003b3cc22af3ae1eac0440bcee416b40a000000000000000000000000000000000003b3cc22af3ae1eac0440bcee416b40b880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007921e99216a00000000000000000000000000000000000000000000000000953f383500000000000000000000000000000000000000000000000000000000000000000000000", - "0xb90bdf02f90bdb01830b2215b9010000200000002000000000000080000000000000000000000001010000000004000000000000000000420000000000010002000000080020002000000000200800000000000000080800000008000000200090000000000000080000408040000000000000000000000008084000000000000000000000000010010050000800000800800000000000000000000000000000000000000000080000004000100000020100000000000000100080000004000000000000020000000000000000000000400002000000000000000000000000000000000000001000000000002000400012200000800000020404000000000000020000008000000000000000000010f90ad0f89b941111111254eeb25477b68fb85ed929f73a960582f842a0b9ed0243fdf00f0545c63a0af8850c090d86bb46682baec4bf3c496814fe4f02a000000000000000000000000058c1c6a484ef2d6b0f8d93b2dbeb72f3c3e9ceb5b8402511106c0eade4c289445ac7275a89e6e088cc2cb5e313a42712b2987c2fb8d30000000000000000000000000000000000000000000000000000000000000001f89b94dac17f958d2ee523a2206206994597c13d831ec7f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000058c1c6a484ef2d6b0f8d93b2dbeb72f3c3e9ceb5a0000000000000000000000000d1742b3c4fbb096990c8950fa635aec75b30781aa000000000000000000000000000000000000000000000000000000002f0174a58f89b94fe67a4450907459c3e1fff623aa927dd4e28c67af863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000a050f7adc241afa59ad5f343eaf4faf5f30a4cdba0000000000000000000000000d1742b3c4fbb096990c8950fa635aec75b30781aa000000000000000000000000000000000000000000000143c3719a34f04e020edf89b94dac17f958d2ee523a2206206994597c13d831ec7f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000d1742b3c4fbb096990c8950fa635aec75b30781aa000000000000000000000000006da0fd433c1a5d7a4faa01111c044910a184553a000000000000000000000000000000000000000000000000000000000da1b3bf5f89b94dac17f958d2ee523a2206206994597c13d831ec7f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000d1742b3c4fbb096990c8950fa635aec75b30781aa00000000000000000000000000d4a11d5eeaac28ec3f61d100daf4d40471f1852a00000000000000000000000000000000000000000000000000000000215fc0e63f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000006da0fd433c1a5d7a4faa01111c044910a184553a0000000000000000000000000a050f7adc241afa59ad5f343eaf4faf5f30a4cdba00000000000000000000000000000000000000000000000001913572822ee731ff8799406da0fd433c1a5d7a4faa01111c044910a184553e1a01c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1b8400000000000000000000000000000000000000000000000b3986c20be3ddb96f70000000000000000000000000000000000000000000000000000061647f821daf8fc9406da0fd433c1a5d7a4faa01111c044910a184553f863a0d78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822a0000000000000000000000000d1742b3c4fbb096990c8950fa635aec75b30781aa0000000000000000000000000a050f7adc241afa59ad5f343eaf4faf5f30a4cdbb880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000da1b3bf50000000000000000000000000000000000000000000000001913572822ee731f0000000000000000000000000000000000000000000000000000000000000000f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000000d4a11d5eeaac28ec3f61d100daf4d40471f1852a0000000000000000000000000a050f7adc241afa59ad5f343eaf4faf5f30a4cdba00000000000000000000000000000000000000000000000003d5ec06d1b711bcff879940d4a11d5eeaac28ec3f61d100daf4d40471f1852e1a01c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1b8400000000000000000000000000000000000000000000004724d25b9c0c67a0c7800000000000000000000000000000000000000000000000000002694ca870b04f8fc940d4a11d5eeaac28ec3f61d100daf4d40471f1852f863a0d78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822a0000000000000000000000000d1742b3c4fbb096990c8950fa635aec75b30781aa0000000000000000000000000a050f7adc241afa59ad5f343eaf4faf5f30a4cdbb88000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000215fc0e630000000000000000000000000000000000000000000000003d5ec06d1b711bcf0000000000000000000000000000000000000000000000000000000000000000f9011c94a050f7adc241afa59ad5f343eaf4faf5f30a4cdbf863a0c42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67a0000000000000000000000000d1742b3c4fbb096990c8950fa635aec75b30781aa0000000000000000000000000d1742b3c4fbb096990c8950fa635aec75b30781ab8a0000000000000000000000000000000000000000000000000567217953e5f8eeeffffffffffffffffffffffffffffffffffffffffffffebc3c8e65cb0fb1fdf13000000000000000000000000000000000000007b89284efd1b25e6f5f0dcbf2e000000000000000000000000000000000000000000000aa86d459fd0c59c2a59000000000000000000000000000000000000000000000000000000000001784ff89b94fe67a4450907459c3e1fff623aa927dd4e28c67af863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000d1742b3c4fbb096990c8950fa635aec75b30781aa0000000000000000000000000a88800cd213da5ae406ce248380802bd53b47647a0000000000000000000000000000000000000000000001375a0d26e739f71f370f89b94fe67a4450907459c3e1fff623aa927dd4e28c67af863a08c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a0000000000000000000000000a88800cd213da5ae406ce248380802bd53b47647a00000000000000000000000001111111254eeb25477b68fb85ed929f73a960582a0000000000000000000000000000000000000000000001375a0d26e739f71f370f89b94fe67a4450907459c3e1fff623aa927dd4e28c67af863a08c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a0000000000000000000000000a88800cd213da5ae406ce248380802bd53b47647a00000000000000000000000001111111254eeb25477b68fb85ed929f73a960582a00000000000000000000000000000000000000000000000000000000000000000f89b94fe67a4450907459c3e1fff623aa927dd4e28c67af863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000a88800cd213da5ae406ce248380802bd53b47647a000000000000000000000000058c1c6a484ef2d6b0f8d93b2dbeb72f3c3e9ceb5a0000000000000000000000000000000000000000000001375a0d26e739f71f370", - "0xb905cf02f905cb01830e0902b9010000200000008020000000000280004000000000000000000000000000000000000000200000000000000000200080000002000000080000000000000800000000000000000000000100000008040000200004000000000000000000008000004000000000000000000000000000000400240000000000000004000010000000000000000000000000000001010000000200000001000000080000004000000400002000000000004002020000000000000000000000000000002000000000000000000002000000000000000000000040000000000000001000000000000000000000200000000000000000000000000000000001000400400000000080010000f904c0f87a94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f842a0e1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109ca0000000000000000000000000db5889e35e379ef0498aae126fc2cce1fbd23216a000000000000000000000000000000000000000000000000001617eb90b26c000f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000db5889e35e379ef0498aae126fc2cce1fbd23216a0000000000000000000000000e090e0518ea17607a01e9286522655808c3f8919a000000000000000000000000000000000000000000000000001617eb90b26c000f89b94f83e0399fd7ef1c9c1a3dbc0a4d586edc3c8d125f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000e090e0518ea17607a01e9286522655808c3f8919a0000000000000000000000000faa04b4d06297dca749c2ac7783211638de3e491a000000000000000000000000000000000000000000000019d0da576764721e7e7f87994e090e0518ea17607a01e9286522655808c3f8919e1a01c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1b8400000000000000000000000000000000000000000000000001e6d6c84d2f7cd2b00000000000000000000000000000000000000000000220ae8d75c1df124f53df8fc94e090e0518ea17607a01e9286522655808c3f8919f863a0d78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822a0000000000000000000000000c6265979793435b496e28e61af1500c22c3ba277a0000000000000000000000000faa04b4d06297dca749c2ac7783211638de3e491b88000000000000000000000000000000000000000000000000001617eb90b26c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019d0da576764721e7e7f87994db5889e35e379ef0498aae126fc2cce1fbd23216e1a06cb8c9cbcedb37b7d125170f5d929dbbdb3203c8fd4d60356b496fa31f77fd00b8400000000000000000000000000000000000000000000000000001c4793ec69800000000000000000000000000000000000000000000000000000000000000008ef87994db5889e35e379ef0498aae126fc2cce1fbd23216e1a00c2a2f565c7774c59e49ef6b3c255329f4d254147e06e724d3a8569bb7bd21adb8400000000000000000000000000000000000000000000000000001c4793ec69800000000000000000000000000faa04b4d06297dca749c2ac7783211638de3e491f89994db5889e35e379ef0498aae126fc2cce1fbd23216e1a09f849d23f4955d98202378ea318f2b0c7533695d3c9fb2a3931f0f919fa8c420b86000000000000000000000000000000000000000000000000001617eb90b26c00000000000000000000000000000000000000000000000019d0da576764721e7e700000000000000000000000000000000000000000000019d0da576764721e7e7", - "0xf905cb0183105d5cb90100000000000180a0000004000000004000000000000001000000000000002200000000000000000000080200200000000002000000080020000000000800000000000000000000000900000008040000000000000000400000000000000000004000000000000000000000000000000400240000000000040000000010000804000000000000000000000080010000000000000000000000008000000000000480000000000000004002000000000000000000000000000000000000000000008000000002080000000000000000000000000000000000000000000002000000000000200000000000000000000000000000000000000000000000000000010000f904c0f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000009e31efffe1e016f514f774f43d91a85ebbc11564a0000000000000000000000000db5889e35e379ef0498aae126fc2cce1fbd23216a00000000000000000000000000000000000000000000000000e803e90becaf29bf89b949dd5f5dae94633760b3125a7490ecb4571d09a42f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000087033ad96757ecd730aa1652b1a7dabcc5ffb182a00000000000000000000000009e31efffe1e016f514f774f43d91a85ebbc11564a0000000000000000000000000000000000000000000acb37f48fe24c23d1833c6f9011c949e31efffe1e016f514f774f43d91a85ebbc11564f863a0c42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67a0000000000000000000000000db5889e35e379ef0498aae126fc2cce1fbd23216a0000000000000000000000000db5889e35e379ef0498aae126fc2cce1fbd23216b8a0000000000000000000000000000000000000000000acb37f48fe24c23d1833c6fffffffffffffffffffffffffffffffffffffffffffffffff17fc16f41350d65000000000000000000000000000000000000000000049c65546ad3eed1521a58000000000000000000000000000000000000000000009404a8bb774136003dadfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd14eff87a94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f842a07fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65a0000000000000000000000000db5889e35e379ef0498aae126fc2cce1fbd23216a00000000000000000000000000000000000000000000000000e803e90becaf29bf87994db5889e35e379ef0498aae126fc2cce1fbd23216e1a06cb8c9cbcedb37b7d125170f5d929dbbdb3203c8fd4d60356b496fa31f77fd00b84000000000000000000000000000000000000000000000000000128fac3e64dad00000000000000000000000000000000000000000000000000000000000000012f87994db5889e35e379ef0498aae126fc2cce1fbd23216e1a00c2a2f565c7774c59e49ef6b3c255329f4d254147e06e724d3a8569bb7bd21adb84000000000000000000000000000000000000000000000000000128fac3e64dad000000000000000000000000087033ad96757ecd730aa1652b1a7dabcc5ffb182f89994db5889e35e379ef0498aae126fc2cce1fbd23216e1a09f849d23f4955d98202378ea318f2b0c7533695d3c9fb2a3931f0f919fa8c420b860000000000000000000000000000000000000000000acb37f48fe24c23d1833c60000000000000000000000000000000000000000000000000e803e90becaf29b0000000000000000000000000000000000000000000000000e803e90becaf29bf85894db5889e35e379ef0498aae126fc2cce1fbd23216e1a0522881958b3c4a6fc0840ad3b7fb947b881edc28c004245a62541647422ade97a00000000000000000000000000000000000000000000000000e803e90becaf29b", - "0xb903e402f903e00183128fdcb9010000000000010000000000000000000000000000000000010000000000040000000000000000000000000008000000000002000000080020000000000000000000000000000000000808000008000000000000000000410000000000000000000000000000000000000000040000000000000000000000040000000010000800000000000000000000200000000000000000000000010000000000000000000000000000000000200000000000010000000000000000000000002000000008000000000002000000000000080000000000000000000000000000000002000000000000200000000000000010000000000000000000000000000000000000000000f902d5f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000088e6a0c2ddd26feeb64f039a2c41296fcb3f5640a00000000000000000000000008e30dead12d19228cf9cdc984f237f0ad00df195a000000000000000000000000000000000000000000000000000b5762b8f483dbff89b94a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000f706190050f8c7d62021d5ba52871640ea9fd3fea000000000000000000000000088e6a0c2ddd26feeb64f039a2c41296fcb3f5640a0000000000000000000000000000000000000000000000000000000000629852ff9011c9488e6a0c2ddd26feeb64f039a2c41296fcb3f5640f863a0c42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67a00000000000000000000000008e30dead12d19228cf9cdc984f237f0ad00df195a00000000000000000000000008e30dead12d19228cf9cdc984f237f0ad00df195b8a0000000000000000000000000000000000000000000000000000000000629852fffffffffffffffffffffffffffffffffffffffffffffffffff4a89d470b7c24100000000000000000000000000000000000056d8c2fe7c57e75b18c386394ff90000000000000000000000000000000000000000000000016397a5e7cf05707c0000000000000000000000000000000000000000000000000000000000030e04f87a94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f842a07fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65a00000000000000000000000008e30dead12d19228cf9cdc984f237f0ad00df195a000000000000000000000000000000000000000000000000000b5762b8f483dbf", - "0xb901ab02f901a701831345f7b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000200000000000000000000000004000000000008000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000080000000000000008000000000000000000000000000000000000000000000000100000000000000000000010000000000000000000000001000000000000000000000000000000000000f89df89b9496add417293a49e80f024734e96cfd8b355bcc14f863a08c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a0000000000000000000000000af56ec1d3a54e9d05fbe2bc158219a810890dc77a0000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "0xb9053d02f90539018315a059b9010000210000000000100000100080000000000000000000000080000000000000000000000000000000000000000000000002010000080000000000000000080000000020080000800000000008000000208000000000400000000000000020000000000000000000000000000000000000000000000000040000000010000000000040004000000000000000000000000000000000000000080000004000000000000000000000000000000000000000000400000000080000000000000008000000000002000000000000000000000000000400400000101000000002000202000000200000000000000000000001000000001000000000000000000000000400f9042ef8fd94000000000022d473030f116ddee9f6b43ac78ba3f884a0c6a377bfc4eb120024a8ac08eef205be16b817020812c73223e81d1bdb9708eca0000000000000000000000000af56ec1d3a54e9d05fbe2bc158219a810890dc77a000000000000000000000000096add417293a49e80f024734e96cfd8b355bcc14a00000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fadb860000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000658c27210000000000000000000000000000000000000000000000000000000000000000f89b9496add417293a49e80f024734e96cfd8b355bcc14f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000af56ec1d3a54e9d05fbe2bc158219a810890dc77a00000000000000000000000000bee64a7c035fa2f69b9a6cad5d761de038ecb02a000000000000000000000000000000000000000000000000c83b84b800fe98c96f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000000bee64a7c035fa2f69b9a6cad5d761de038ecb02a00000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fada000000000000000000000000000000000000000000000000001e7841cb75e9302f879940bee64a7c035fa2f69b9a6cad5d761de038ecb02e1a01c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1b840000000000000000000000000000000000000000000004581511bfd43276c16b400000000000000000000000000000000000000000000000a99e131364ae486cff8fc940bee64a7c035fa2f69b9a6cad5d761de038ecb02f863a0d78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822a00000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fada00000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fadb88000000000000000000000000000000000000000000000000c83b84b800fe98c960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e7841cb75e9302f87a94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f842a07fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65a00000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fada000000000000000000000000000000000000000000000000001e7841cb75e9302", - "0xb9010d02f90109018315f261b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0" -] diff --git a/op-service/sources/eth_client.go b/op-service/sources/eth_client.go index faf10e7803a2..149a0c08abab 100644 --- a/op-service/sources/eth_client.go +++ b/op-service/sources/eth_client.go @@ -11,6 +11,7 @@ package sources import ( "context" + "errors" "fmt" "math/big" "time" @@ -62,11 +63,6 @@ type EthClientConfig struct { // till we re-attempt the user-preferred methods. // If this is 0 then the client does not fall back to less optimal but available methods. MethodResetDuration time.Duration - - // [OPTIONAL] The reth DB path to fetch receipts from. - // If it is specified, the rethdb receipts fetcher will be used - // and the RPC configuration parameters don't need to be set. - RethDBPath string } func (c *EthClientConfig) Check() error { @@ -82,15 +78,6 @@ func (c *EthClientConfig) Check() error { if c.PayloadsCacheSize < 0 { return fmt.Errorf("invalid payloads cache size: %d", c.PayloadsCacheSize) } - if c.RethDBPath != "" { - if buildRethdb { - // If the rethdb path is set, we use the rethdb receipts fetcher and skip creating - // an RCP receipts fetcher, so below rpc config parameters don't need to be checked. - return nil - } else { - return fmt.Errorf("rethdb path specified, but built without rethdb support") - } - } if c.MaxConcurrentRequests < 1 { return fmt.Errorf("expected at least 1 concurrent request, but max is %d", c.MaxConcurrentRequests) } @@ -136,9 +123,9 @@ func NewEthClient(client client.RPC, log log.Logger, metrics caching.Metrics, co } client = LimitRPC(client, config.MaxConcurrentRequests) - recProvider := newRecProviderFromConfig(client, log, metrics, config) + recProvider := newRPCRecProviderFromConfig(client, log, metrics, config) if recProvider.isInnerNil() { - return nil, fmt.Errorf("failed to open RethDB") + return nil, errors.New("failed to establish receipts provider") } return &EthClient{ client: client, diff --git a/op-service/sources/reth_db.go b/op-service/sources/reth_db.go deleted file mode 100644 index aff8d491c0c6..000000000000 --- a/op-service/sources/reth_db.go +++ /dev/null @@ -1,125 +0,0 @@ -//go:build rethdb - -package sources - -import ( - "context" - "encoding/json" - "fmt" - "unsafe" - - "github.com/ethereum-optimism/optimism/op-service/client" - "github.com/ethereum-optimism/optimism/op-service/eth" - "github.com/ethereum-optimism/optimism/op-service/sources/caching" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" -) - -/* -#cgo LDFLAGS: -L../rethdb-reader/target/release -lrethdbreader -#include -#include -#include -#include - -typedef struct { - char* data; - size_t data_len; - bool error; -} ReceiptsResult; - -typedef struct OpenDBResult { - const void *data; - bool error; -} OpenDBResult; - -extern ReceiptsResult rdb_read_receipts(const uint8_t* block_hash, size_t block_hash_len, const void *db_instance); -extern void rdb_free_string(char* string); -extern OpenDBResult open_db_read_only(const char *db_path); -*/ -import "C" - -// FetchRethReceipts fetches the receipts for the given block hash directly from the Reth Database -// and populates the given results slice pointer with the receipts that were found. -func FetchRethReceipts(db unsafe.Pointer, blockHash *common.Hash) (types.Receipts, error) { - if blockHash == nil { - return nil, fmt.Errorf("Must provide a block hash to fetch receipts for.") - } - - // Convert the block hash to a C byte array and defer its deallocation - cBlockHash := C.CBytes(blockHash[:]) - defer C.free(cBlockHash) - - // Call the C function to fetch the receipts from the Reth Database - receiptsResult := C.rdb_read_receipts((*C.uint8_t)(cBlockHash), C.size_t(len(blockHash)), db) - - if receiptsResult.error { - return nil, fmt.Errorf("Error fetching receipts from Reth Database.") - } - - // Free the memory allocated by the C code - defer C.rdb_free_string(receiptsResult.data) - - // Convert the returned JSON string to Go string and parse it - receiptsJSON := C.GoStringN(receiptsResult.data, C.int(receiptsResult.data_len)) - var receipts types.Receipts - if err := json.Unmarshal([]byte(receiptsJSON), &receipts); err != nil { - return nil, err - } - - return receipts, nil -} - -func OpenDBReadOnly(dbPath string) (db unsafe.Pointer, err error) { - // Convert the db path to a C string and defer its deallocation - cDbPath := C.CString(dbPath) - defer C.free(unsafe.Pointer(cDbPath)) - - // Call the C function to fetch the receipts from the Reth Database - openDBResult := C.open_db_read_only(cDbPath) - - if openDBResult.error { - return nil, fmt.Errorf("failed to open RethDB") - } - - return openDBResult.data, nil -} - -type RethDBReceiptsFetcher struct { - dbInstance unsafe.Pointer -} - -var _ ReceiptsProvider = (*RethDBReceiptsFetcher)(nil) - -// NewRethDBReceiptsFetcher opens a RethDB for reading receipts. It returns nil if it was unable to open the database -func NewRethDBReceiptsFetcher(dbPath string) *RethDBReceiptsFetcher { - db, err := OpenDBReadOnly(dbPath) - if err != nil { - return nil - } - return &RethDBReceiptsFetcher{ - dbInstance: db, - } -} - -func (f *RethDBReceiptsFetcher) FetchReceipts(ctx context.Context, block eth.BlockInfo, txHashes []common.Hash) (types.Receipts, error) { - if f.dbInstance == nil { - return nil, fmt.Errorf("Reth dbInstance is nil") - } - hash := block.Hash() - return FetchRethReceipts(f.dbInstance, &hash) -} - -func NewCachingRethDBReceiptsFetcher(dbPath string, m caching.Metrics, cacheSize int) *CachingReceiptsProvider { - return NewCachingReceiptsProvider(NewRethDBReceiptsFetcher(dbPath), m, cacheSize) -} - -const buildRethdb = true - -func newRecProviderFromConfig(client client.RPC, log log.Logger, metrics caching.Metrics, config *EthClientConfig) *CachingReceiptsProvider { - if dbPath := config.RethDBPath; dbPath != "" { - return NewCachingRethDBReceiptsFetcher(dbPath, metrics, config.ReceiptsCacheSize) - } - return newRPCRecProviderFromConfig(client, log, metrics, config) -} diff --git a/op-service/sources/reth_db_stub.go b/op-service/sources/reth_db_stub.go deleted file mode 100644 index 2ddc9c545168..000000000000 --- a/op-service/sources/reth_db_stub.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build !rethdb - -package sources - -import ( - "github.com/ethereum-optimism/optimism/op-service/client" - "github.com/ethereum-optimism/optimism/op-service/sources/caching" - "github.com/ethereum/go-ethereum/log" -) - -const buildRethdb = false - -func newRecProviderFromConfig(client client.RPC, log log.Logger, metrics caching.Metrics, config *EthClientConfig) *CachingReceiptsProvider { - return newRPCRecProviderFromConfig(client, log, metrics, config) -} diff --git a/op-service/sources/reth_db_test.go b/op-service/sources/reth_db_test.go deleted file mode 100644 index d52042c439f2..000000000000 --- a/op-service/sources/reth_db_test.go +++ /dev/null @@ -1,45 +0,0 @@ -//go:build rethdb - -package sources - -import ( - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/stretchr/testify/require" -) - -func TestRethDBReceiptsLoad(t *testing.T) { - t.Parallel() - - // ETH Mainnet block #18,663,292 - // - // https://etherscan.io/tx/0x88b2d153a4e893ba91ac235325c44b1aa0c802fcb42657701e1a73e1c675f7ca - // - // NOTE: The block hash differs from the live block due to a state root mismatch. In order to generate - // a testdata database with only this block in it, the state root of the block was modified. - // Old State Root: 0xaf81a692d228d56d35c80d65aeba59636b4671403054f6c57446c0e3e4d951c8 - // New State Root (Empty MPT): 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 - blockHash := common.HexToHash("0x6a229123d607c2232a8b0bdd36f90745945d05181018e64e60ff2b93ab6b52e5") - fetcher := NewRethDBReceiptsFetcher("../rethdb-reader/testdata/db") - require.NotNil(t, fetcher.dbInstance) - res, err := FetchRethReceipts(fetcher.dbInstance, &blockHash) - require.NoError(t, err) - - receipt := (*types.Receipt)(res[0]) - require.Equal(t, receipt.Type, uint8(2)) - require.Equal(t, receipt.Status, uint64(1)) - require.Equal(t, receipt.CumulativeGasUsed, uint64(115_316)) - require.Equal(t, receipt.Bloom, types.BytesToBloom(common.FromHex("00200000000000000000000080001000000000000000000000000000000000000000000000000000000000000000100002000100080000000000000000000000000000000000000000000008000000200000000400000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000400000000000001000000000000000100000000080000004000000000000000000000000000000000000002000000000000000000000000000000000000000006000000000000000000000000000000000000001000000000000000000000200000000000000100000000020000000000000000000000000000000010"))) - require.Equal(t, receipt.Logs[0].Address, common.HexToAddress("c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2")) - require.Equal(t, receipt.Logs[0].Topics[0], common.HexToHash("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef")) - require.Equal(t, receipt.Logs[0].Topics[1], common.HexToHash("00000000000000000000000000000000003b3cc22af3ae1eac0440bcee416b40")) - require.Equal(t, receipt.Logs[0].Data, common.FromHex("00000000000000000000000000000000000000000000000008a30cd230000000")) - require.Equal(t, receipt.TxHash, common.HexToHash("0x88b2d153a4e893ba91ac235325c44b1aa0c802fcb42657701e1a73e1c675f7ca")) - - require.Equal(t, receipt.BlockHash, blockHash) - require.Equal(t, receipt.BlockNumber, big.NewInt(18_663_292)) - require.Equal(t, receipt.TransactionIndex, uint(0)) -} From 375b9766bdf4678253932beae8234cc52f1f46ee Mon Sep 17 00:00:00 2001 From: Samuel Laferriere Date: Mon, 2 Sep 2024 22:39:48 -0700 Subject: [PATCH 020/264] fix: op-challenger move.go cli command wasn't cancellable (#11716) --- op-challenger/cmd/move.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/op-challenger/cmd/move.go b/op-challenger/cmd/move.go index 3bc80ae1882a..cf460d691f3b 100644 --- a/op-challenger/cmd/move.go +++ b/op-challenger/cmd/move.go @@ -1,7 +1,6 @@ package main import ( - "context" "fmt" "github.com/ethereum-optimism/optimism/op-challenger/flags" @@ -70,7 +69,7 @@ func Move(ctx *cli.Context) error { return fmt.Errorf("either attack or defense flag must be set") } - rct, err := txMgr.Send(context.Background(), tx) + rct, err := txMgr.Send(ctx.Context, tx) if err != nil { return fmt.Errorf("failed to send tx: %w", err) } From 957e13dd504fb336a4be40fb5dd0d8ba0276be34 Mon Sep 17 00:00:00 2001 From: Matt Solomon Date: Tue, 3 Sep 2024 14:31:05 -0700 Subject: [PATCH 021/264] feat: add ERC-5202 Blueprint library with initial tests (#11700) https://eips.ethereum.org/EIPS/eip-5202 --- .../src/libraries/Blueprint.sol | 120 ++++++++++++++++++ .../test/libraries/Blueprint.t.sol | 46 +++++++ 2 files changed, 166 insertions(+) create mode 100644 packages/contracts-bedrock/src/libraries/Blueprint.sol create mode 100644 packages/contracts-bedrock/test/libraries/Blueprint.t.sol diff --git a/packages/contracts-bedrock/src/libraries/Blueprint.sol b/packages/contracts-bedrock/src/libraries/Blueprint.sol new file mode 100644 index 000000000000..84e41346775a --- /dev/null +++ b/packages/contracts-bedrock/src/libraries/Blueprint.sol @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @notice Methods for working with ERC-5202 blueprint contracts. +/// https://eips.ethereum.org/EIPS/eip-5202 +library Blueprint { + /// @notice The structure of a blueprint contract per ERC-5202. + struct Preamble { + uint8 ercVersion; + bytes preambleData; + bytes initcode; + } + + /// @notice Thrown when converting a bytes array to a uint256 and the bytes array is too long. + error BytesArrayTooLong(); + + /// @notice Throw when contract deployment fails. + error DeploymentFailed(); + + /// @notice Thrown when parsing a blueprint preamble and the resulting initcode is empty. + error EmptyInitcode(); + + /// @notice Thrown when parsing a blueprint preamble and the bytecode does not contain the expected prefix bytes. + error NotABlueprint(); + + /// @notice Thrown when parsing a blueprint preamble and the reserved bits are set. + error ReservedBitsSet(); + + /// @notice Thrown when parsing a blueprint preamble and the preamble data is not empty. + /// We do not use the preamble data, so it's expected to be empty. + error UnexpectedPreambleData(); + + /// @notice Thrown during deployment if the ERC version is not supported. + error UnsupportedERCVersion(uint8 version); + + /// @notice Takes the desired initcode for a blueprint as a parameter, and returns EVM code + /// which will deploy a corresponding blueprint contract (with no data section). Based on the + /// reference implementation in https://eips.ethereum.org/EIPS/eip-5202. + function blueprintDeployerBytecode(bytes memory _initcode) internal pure returns (bytes memory) { + bytes memory blueprintPreamble = hex"FE7100"; // ERC-5202 preamble. + bytes memory blueprintBytecode = bytes.concat(blueprintPreamble, _initcode); + + // The length of the deployed code in bytes. + bytes2 lenBytes = bytes2(uint16(blueprintBytecode.length)); + + // Copy to memory and `RETURN` it per EVM creation semantics. + // PUSH2 RETURNDATASIZE DUP2 PUSH1 10 RETURNDATASIZE CODECOPY RETURN + bytes memory deployBytecode = bytes.concat(hex"61", lenBytes, hex"3d81600a3d39f3"); + + return bytes.concat(deployBytecode, blueprintBytecode); + } + + /// @notice Given bytecode as a sequence of bytes, parse the blueprint preamble and deconstruct + /// the bytecode into the ERC version, preamble data and initcode. Reverts if the bytecode is + /// not a valid blueprint contract according to ERC-5202. + function parseBlueprintPreamble(bytes memory _bytecode) internal pure returns (Preamble memory) { + if (_bytecode.length < 2 || _bytecode[0] != 0xFE || _bytecode[1] != 0x71) { + revert NotABlueprint(); + } + + uint8 ercVersion = uint8(_bytecode[2] & 0xFC) >> 2; + uint8 nLengthBytes = uint8(_bytecode[2] & 0x03); + if (nLengthBytes == 0x03) revert ReservedBitsSet(); + + uint256 dataLength = 0; + if (nLengthBytes > 0) { + bytes memory lengthBytes = new bytes(nLengthBytes); + for (uint256 i = 0; i < nLengthBytes; i++) { + lengthBytes[i] = _bytecode[3 + i]; + } + dataLength = bytesToUint(lengthBytes); + } + + bytes memory preambleData = new bytes(dataLength); + if (nLengthBytes != 0) { + uint256 dataStart = 3 + nLengthBytes; + for (uint256 i = 0; i < dataLength; i++) { + preambleData[i] = _bytecode[dataStart + i]; + } + } + + uint256 initcodeStart = 3 + nLengthBytes + dataLength; + bytes memory initcode = new bytes(_bytecode.length - initcodeStart); + for (uint256 i = 0; i < initcode.length; i++) { + initcode[i] = _bytecode[initcodeStart + i]; + } + if (initcode.length == 0) revert EmptyInitcode(); + + return Preamble(ercVersion, preambleData, initcode); + } + + /// @notice Parses the code at the given `_target` as a blueprint and deploys the resulting initcode + /// with the given `_data` appended, i.e. `_data` is the ABI-encoded constructor arguments. + function deployFrom(address _target, bytes32 _salt, bytes memory _data) internal returns (address newContract_) { + Preamble memory preamble = parseBlueprintPreamble(address(_target).code); + if (preamble.ercVersion != 0) revert UnsupportedERCVersion(preamble.ercVersion); + if (preamble.preambleData.length != 0) revert UnexpectedPreambleData(); + + bytes memory initcode = bytes.concat(preamble.initcode, _data); + assembly ("memory-safe") { + newContract_ := create2(0, add(initcode, 0x20), mload(initcode), _salt) + } + if (newContract_ == address(0)) revert DeploymentFailed(); + } + + /// @notice Parses the code at the given `_target` as a blueprint and deploys the resulting initcode. + function deployFrom(address _target, bytes32 _salt) internal returns (address) { + return deployFrom(_target, _salt, new bytes(0)); + } + + /// @notice Convert a bytes array to a uint256. + function bytesToUint(bytes memory _b) internal pure returns (uint256) { + if (_b.length > 32) revert BytesArrayTooLong(); + uint256 number; + for (uint256 i = 0; i < _b.length; i++) { + number = number + uint256(uint8(_b[i])) * (2 ** (8 * (_b.length - (i + 1)))); + } + return number; + } +} diff --git a/packages/contracts-bedrock/test/libraries/Blueprint.t.sol b/packages/contracts-bedrock/test/libraries/Blueprint.t.sol new file mode 100644 index 000000000000..419e68f95666 --- /dev/null +++ b/packages/contracts-bedrock/test/libraries/Blueprint.t.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Test } from "forge-std/Test.sol"; +import { Blueprint } from "src/libraries/Blueprint.sol"; + +contract Blueprint_Test is Test { + // TODO add tests that things revert if an address has no code. + + function test_roundtrip_succeeds(bytes memory _initcode) public { + vm.assume(_initcode.length > 0); + + // Convert the initcode to match the ERC-5202 blueprint format. + bytes memory blueprintInitcode = Blueprint.blueprintDeployerBytecode(_initcode); + + // Deploy the blueprint. + address blueprintAddress; + assembly ("memory-safe") { + blueprintAddress := create2(0, add(blueprintInitcode, 0x20), mload(blueprintInitcode), 0) + } + require(blueprintAddress != address(0), "DeployImplementations: create2 failed"); + + // Read the blueprint code from the deployed code. + bytes memory blueprintCode = address(blueprintAddress).code; + + // Parse the blueprint preamble. + Blueprint.Preamble memory preamble = Blueprint.parseBlueprintPreamble(blueprintCode); + assertEq(preamble.ercVersion, 0, "100"); + assertEq(preamble.preambleData, hex"", "200"); + assertEq(preamble.initcode, _initcode, "300"); + } + + function test_bytesToUint_succeeds() public pure { + // These test cases (and the logic for bytesToUint) are taken from forge-std. + assertEq(3, Blueprint.bytesToUint(hex"03")); + assertEq(2, Blueprint.bytesToUint(hex"02")); + assertEq(255, Blueprint.bytesToUint(hex"ff")); + assertEq(29625, Blueprint.bytesToUint(hex"73b9")); + + // Additional test cases. + assertEq(0, Blueprint.bytesToUint(hex"")); + assertEq(0, Blueprint.bytesToUint(hex"00")); + assertEq(14545064521499334880, Blueprint.bytesToUint(hex"c9da731e871ad8e0")); + assertEq(type(uint256).max, Blueprint.bytesToUint(bytes.concat(bytes32(type(uint256).max)))); + } +} From 5b907dc8eaece83e98cd17974380eecaad706b87 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Wed, 4 Sep 2024 09:02:18 +1000 Subject: [PATCH 022/264] chore: Fix lint error (#11714) golangci-lint v1.60.2 seems to report a new error when performing a nil check and length != 0 on maps. We're not using this version in CI yet but fix the error to simplify the code and provide for a future upgrade. --- op-chain-ops/genesis/layer_one.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op-chain-ops/genesis/layer_one.go b/op-chain-ops/genesis/layer_one.go index e7d569276496..7178cccebb94 100644 --- a/op-chain-ops/genesis/layer_one.go +++ b/op-chain-ops/genesis/layer_one.go @@ -31,7 +31,7 @@ func BuildL1DeveloperGenesis(config *DeployConfig, dump *foundry.ForgeAllocs, l1 return nil, fmt.Errorf("cannot create L1 developer genesis: %w", err) } - if genesis.Alloc != nil && len(genesis.Alloc) != 0 { + if len(genesis.Alloc) != 0 { panic("Did not expect NewL1Genesis to generate non-empty state") // sanity check for dev purposes. } // copy, for safety when the dump is reused (like in e2e testing) From 669a0fb22a0d282470356e55ecae39da3d159f74 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Tue, 3 Sep 2024 19:49:25 -0400 Subject: [PATCH 023/264] maint: no kontrol summaries in PRs (#11725) Removes the need for kontrol summaries to be generated at PR time. Summaries will now be generated during run-kontrol.sh instead. --- .circleci/config.yml | 9 + packages/contracts-bedrock/justfile | 24 +- .../checks/check-kontrol-deployment.sh | 27 + .../scripts/checks/check-snapshots.sh | 9 +- .../snapshots/state-diff/.gitkeep | 0 .../snapshots/state-diff/Kontrol-31337.json | 20331 ---------------- .../deployment/DeploymentSummary.t.sol | 254 - .../DeploymentSummaryFaultProofs.t.sol | 77 - 8 files changed, 61 insertions(+), 20670 deletions(-) create mode 100755 packages/contracts-bedrock/scripts/checks/check-kontrol-deployment.sh create mode 100644 packages/contracts-bedrock/snapshots/state-diff/.gitkeep delete mode 100644 packages/contracts-bedrock/snapshots/state-diff/Kontrol-31337.json delete mode 100644 packages/contracts-bedrock/test/kontrol/deployment/DeploymentSummary.t.sol delete mode 100644 packages/contracts-bedrock/test/kontrol/deployment/DeploymentSummaryFaultProofs.t.sol diff --git a/.circleci/config.yml b/.circleci/config.yml index bb9794cb4562..6ef7dff3d7ba 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -615,6 +615,11 @@ jobs: command: | just snapshots-check || echo "export SNAPSHOTS_STATUS=1" >> "$BASH_ENV" working_directory: packages/contracts-bedrock + - run: + name: kontrol deployment + command: | + just kontrol-deployment-check || echo "export KONTROL_DEPLOYMENT_STATUS=1" >> "$BASH_ENV" + working_directory: packages/contracts-bedrock - run: name: size check command: | @@ -653,6 +658,10 @@ jobs: echo "Snapshots check failed, see job output for details." FAILED=1 fi + if [[ "$KONTROL_DEPLOYMENT_STATUS" -ne 0 ]]; then + echo "Kontrol deployment check failed, see job output for details." + FAILED=1 + fi if [[ "$SIZE_CHECK" -ne 0 ]]; then echo "Contract(s) exceed size limit, see job output for details." FAILED=1 diff --git a/packages/contracts-bedrock/justfile b/packages/contracts-bedrock/justfile index 45cdd14cfae0..58c5d3b0b93d 100644 --- a/packages/contracts-bedrock/justfile +++ b/packages/contracts-bedrock/justfile @@ -19,7 +19,11 @@ autogen-invariant-docs: test: build-go-ffi forge test -test-kontrol: +# Run Kontrol tests and build all dependencies. +test-kontrol: build-go-ffi build kontrol-summary-full test-kontrol-no-build + +# Run Kontrol tests without dependencies. +test-kontrol-no-build: ./test/kontrol/scripts/run-kontrol.sh script test-rerun: build-go-ffi @@ -48,18 +52,32 @@ gas-snapshot: build-go-ffi gas-snapshot-no-build gas-snapshot-check: build-go-ffi forge snapshot --match-contract GasBenchMark --check +# Check that the Kontrol deployment script has not changed. +kontrol-deployment-check: + ./scripts/checks/check-kontrol-deployment.sh + +# Generates default Kontrol summary. kontrol-summary: ./test/kontrol/scripts/make-summary-deployment.sh +# Generates fault proofs Kontrol summary. kontrol-summary-fp: KONTROL_FP_DEPLOYMENT=true ./test/kontrol/scripts/make-summary-deployment.sh +# Generates all Kontrol summaries (default and FP). +kontrol-summary-full: kontrol-summary kontrol-summary-fp + +# Generates ABI snapshots for contracts. snapshots-abi-storage: go run ./scripts/autogen/generate-snapshots . -snapshots: build snapshots-no-build +# Generates core snapshots without building contracts. Currently just an alias for +# snapshots-abi-storage because we no longer run Kontrol snapshots here. Run +# kontrol-summary-full to build the Kontrol summaries if necessary. +snapshots-no-build: snapshots-abi-storage -snapshots-no-build: snapshots-abi-storage kontrol-summary-fp kontrol-summary +# Builds contracts and then generates core snapshots. +snapshots: build snapshots-no-build snapshots-check: ./scripts/checks/check-snapshots.sh diff --git a/packages/contracts-bedrock/scripts/checks/check-kontrol-deployment.sh b/packages/contracts-bedrock/scripts/checks/check-kontrol-deployment.sh new file mode 100755 index 000000000000..bfa78ae35a70 --- /dev/null +++ b/packages/contracts-bedrock/scripts/checks/check-kontrol-deployment.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +set -euo pipefail + +# This script checks if the KontrolDeployment.sol file has changed. Removal of +# the DeploymentSummary.t.sol test file means that our primary risk vector for +# KontrolDeployment.sol is an *accidental* change to the file. Changes must +# therefore be explicitly acknowledged by bumping the hash below. + +# Get relevant directories +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +CONTRACTS_BASE=$(dirname "$(dirname "$SCRIPT_DIR")") + +# Generate the SHA-512 hash using OpenSSL (very portable) +generated_hash=$(openssl dgst -sha512 "${CONTRACTS_BASE}/test/kontrol/deployment/KontrolDeployment.sol" | awk '{print $2}') + +# Define the known hash +known_hash="1664d9c22266b55b43086fa03c0e9d0447b092abc86cba79b86ad36c49167062c2b58a78757a20a5fd257d307599edce8f8f604cc6b2ee86715144015a8c977d" + +# Compare the generated hash with the known hash +if [ "$generated_hash" = "$known_hash" ]; then + echo "KontrolDeployment.sol matches the known hash." +else + echo "KontrolDeployment.sol does not match the known hash. Please update the known hash." + echo "Old hash: $known_hash" + echo "New hash: $generated_hash" + exit 1 +fi diff --git a/packages/contracts-bedrock/scripts/checks/check-snapshots.sh b/packages/contracts-bedrock/scripts/checks/check-snapshots.sh index dca296ee8390..de23be7fe299 100755 --- a/packages/contracts-bedrock/scripts/checks/check-snapshots.sh +++ b/packages/contracts-bedrock/scripts/checks/check-snapshots.sh @@ -1,13 +1,12 @@ #!/usr/bin/env bash - set -euo pipefail # Generate the snapshots just snapshots -# Check if the generated `snapshots` or `test/kontrol` files are different from the committed versions -if git diff --exit-code snapshots test/kontrol > /dev/null; then - [ -z "$(git ls-files --others --exclude-standard snapshots test/kontrol)" ] || exit 1 +# Check if the generated `snapshots` files are different from the committed versions +if git diff --exit-code snapshots > /dev/null; then + [ -z "$(git ls-files --others --exclude-standard snapshots)" ] || exit 1 else - exit 1 + exit 1 fi diff --git a/packages/contracts-bedrock/snapshots/state-diff/.gitkeep b/packages/contracts-bedrock/snapshots/state-diff/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/contracts-bedrock/snapshots/state-diff/Kontrol-31337.json b/packages/contracts-bedrock/snapshots/state-diff/Kontrol-31337.json deleted file mode 100644 index bc3a2be8e193..000000000000 --- a/packages/contracts-bedrock/snapshots/state-diff/Kontrol-31337.json +++ /dev/null @@ -1,20331 +0,0 @@ -{ - "accountAccesses": [ - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": false, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xA8452Ec99ce0C64f20701dB7dD3abDb607c00496", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x608060405234801561001057600080fd5b50610ba2806100206000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c806361b69abd1161005057806361b69abd146100dc578063addacc0f146100ef578063d18af54d146100f757600080fd5b80631688f0b9146100775780632500510e146100b457806353e5d935146100c7575b600080fd5b61008a61008536600461070e565b61010a565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61008a6100c2366004610767565b610192565b6100cf610272565b6040516100ab919061086c565b61008a6100ea366004610886565b6102ba565b6100cf61037d565b61008a6101053660046108d6565b61038f565b60006101178484846104ab565b83519091501561013b5760008060008551602087016000865af10361013b57600080fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8084168252861660208201527f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e235910160405180910390a19392505050565b60006101d68585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508792506104ab915050565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606083901b166020820152909150603401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526102699160040161086c565b60405180910390fd5b606060405180602001610284906105f6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000826040516102c9906105f6565b73ffffffffffffffffffffffffffffffffffffffff9091168152602001604051809103906000f080158015610302573d6000803e3d6000fd5b508251909150156103275760008060008451602086016000865af10361032757600080fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201527f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e235910160405180910390a192915050565b60606040518060200161028490610603565b60008083836040516020016103d392919091825260601b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602082015260340190565b6040516020818303038152906040528051906020012060001c90506103f986868361010a565b915073ffffffffffffffffffffffffffffffffffffffff8316156104a2576040517f1e52b51800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690631e52b5189061046f9085908a908a908a90600401610942565b600060405180830381600087803b15801561048957600080fd5b505af115801561049d573d6000803e3d6000fd5b505050505b50949350505050565b6000808380519060200120836040516020016104d1929190918252602082015260400190565b6040516020818303038152906040528051906020012090506000604051806020016104fb906105f6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f909101166040819052610553919073ffffffffffffffffffffffffffffffffffffffff89169060200161098c565b6040516020818303038152906040529050818151826020016000f5925073ffffffffffffffffffffffffffffffffffffffff83166105ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f437265617465322063616c6c206661696c6564000000000000000000000000006044820152606401610269565b50509392505050565b61016f806109af83390190565b607880610b1e83390190565b73ffffffffffffffffffffffffffffffffffffffff8116811461063157600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261067457600080fd5b813567ffffffffffffffff8082111561068f5761068f610634565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156106d5576106d5610634565b816040528381528660208588010111156106ee57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561072357600080fd5b833561072e8161060f565b9250602084013567ffffffffffffffff81111561074a57600080fd5b61075686828701610663565b925050604084013590509250925092565b6000806000806060858703121561077d57600080fd5b84356107888161060f565b9350602085013567ffffffffffffffff808211156107a557600080fd5b818701915087601f8301126107b957600080fd5b8135818111156107c857600080fd5b8860208285010111156107da57600080fd5b95986020929092019750949560400135945092505050565b60005b8381101561080d5781810151838201526020016107f5565b8381111561081c576000848401525b50505050565b6000815180845261083a8160208601602086016107f2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061087f6020830184610822565b9392505050565b6000806040838503121561089957600080fd5b82356108a48161060f565b9150602083013567ffffffffffffffff8111156108c057600080fd5b6108cc85828601610663565b9150509250929050565b600080600080608085870312156108ec57600080fd5b84356108f78161060f565b9350602085013567ffffffffffffffff81111561091357600080fd5b61091f87828801610663565b9350506040850135915060608501356109378161060f565b939692955090935050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152506080604083015261097b6080830185610822565b905082606083015295945050505050565b6000835161099e8184602088016107f2565b919091019182525060200191905056fe608060405234801561001057600080fd5b5060405161016f38038061016f83398101604081905261002f916100b9565b6001600160a01b0381166100945760405162461bcd60e51b815260206004820152602260248201527f496e76616c69642073696e676c65746f6e20616464726573732070726f766964604482015261195960f21b606482015260840160405180910390fd5b600080546001600160a01b0319166001600160a01b03929092169190911790556100e9565b6000602082840312156100cb57600080fd5b81516001600160a01b03811681146100e257600080fd5b9392505050565b6078806100f76000396000f3fe6080604052600073ffffffffffffffffffffffffffffffffffffffff8154167fa619486e00000000000000000000000000000000000000000000000000000000823503604d57808252602082f35b3682833781823684845af490503d82833e806066573d82fd5b503d81f3fea164736f6c634300080f000a6080604052600073ffffffffffffffffffffffffffffffffffffffff8154167fa619486e00000000000000000000000000000000000000000000000000000000823503604d57808252602082f35b3682833781823684845af490503d82833e806066573d82fd5b503d81f3fea164736f6c634300080f000aa164736f6c634300080f000a", - "deployedCode": "0x608060405234801561001057600080fd5b50600436106100725760003560e01c806361b69abd1161005057806361b69abd146100dc578063addacc0f146100ef578063d18af54d146100f757600080fd5b80631688f0b9146100775780632500510e146100b457806353e5d935146100c7575b600080fd5b61008a61008536600461070e565b61010a565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61008a6100c2366004610767565b610192565b6100cf610272565b6040516100ab919061086c565b61008a6100ea366004610886565b6102ba565b6100cf61037d565b61008a6101053660046108d6565b61038f565b60006101178484846104ab565b83519091501561013b5760008060008551602087016000865af10361013b57600080fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8084168252861660208201527f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e235910160405180910390a19392505050565b60006101d68585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508792506104ab915050565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606083901b166020820152909150603401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526102699160040161086c565b60405180910390fd5b606060405180602001610284906105f6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000826040516102c9906105f6565b73ffffffffffffffffffffffffffffffffffffffff9091168152602001604051809103906000f080158015610302573d6000803e3d6000fd5b508251909150156103275760008060008451602086016000865af10361032757600080fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201527f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e235910160405180910390a192915050565b60606040518060200161028490610603565b60008083836040516020016103d392919091825260601b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602082015260340190565b6040516020818303038152906040528051906020012060001c90506103f986868361010a565b915073ffffffffffffffffffffffffffffffffffffffff8316156104a2576040517f1e52b51800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690631e52b5189061046f9085908a908a908a90600401610942565b600060405180830381600087803b15801561048957600080fd5b505af115801561049d573d6000803e3d6000fd5b505050505b50949350505050565b6000808380519060200120836040516020016104d1929190918252602082015260400190565b6040516020818303038152906040528051906020012090506000604051806020016104fb906105f6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f909101166040819052610553919073ffffffffffffffffffffffffffffffffffffffff89169060200161098c565b6040516020818303038152906040529050818151826020016000f5925073ffffffffffffffffffffffffffffffffffffffff83166105ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f437265617465322063616c6c206661696c6564000000000000000000000000006044820152606401610269565b50509392505050565b61016f806109af83390190565b607880610b1e83390190565b73ffffffffffffffffffffffffffffffffffffffff8116811461063157600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261067457600080fd5b813567ffffffffffffffff8082111561068f5761068f610634565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156106d5576106d5610634565b816040528381528660208588010111156106ee57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561072357600080fd5b833561072e8161060f565b9250602084013567ffffffffffffffff81111561074a57600080fd5b61075686828701610663565b925050604084013590509250925092565b6000806000806060858703121561077d57600080fd5b84356107888161060f565b9350602085013567ffffffffffffffff808211156107a557600080fd5b818701915087601f8301126107b957600080fd5b8135818111156107c857600080fd5b8860208285010111156107da57600080fd5b95986020929092019750949560400135945092505050565b60005b8381101561080d5781810151838201526020016107f5565b8381111561081c576000848401525b50505050565b6000815180845261083a8160208601602086016107f2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061087f6020830184610822565b9392505050565b6000806040838503121561089957600080fd5b82356108a48161060f565b9150602083013567ffffffffffffffff8111156108c057600080fd5b6108cc85828601610663565b9150509250929050565b600080600080608085870312156108ec57600080fd5b84356108f78161060f565b9350602085013567ffffffffffffffff81111561091357600080fd5b61091f87828801610663565b9350506040850135915060608501356109378161060f565b939692955090935050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152506080604083015261097b6080830185610822565b905082606083015295945050505050565b6000835161099e8184602088016107f2565b919091019182525060200191905056fe608060405234801561001057600080fd5b5060405161016f38038061016f83398101604081905261002f916100b9565b6001600160a01b0381166100945760405162461bcd60e51b815260206004820152602260248201527f496e76616c69642073696e676c65746f6e20616464726573732070726f766964604482015261195960f21b606482015260840160405180910390fd5b600080546001600160a01b0319166001600160a01b03929092169190911790556100e9565b6000602082840312156100cb57600080fd5b81516001600160a01b03811681146100e257600080fd5b9392505050565b6078806100f76000396000f3fe6080604052600073ffffffffffffffffffffffffffffffffffffffff8154167fa619486e00000000000000000000000000000000000000000000000000000000823503604d57808252602082f35b3682833781823684845af490503d82833e806066573d82fd5b503d81f3fea164736f6c634300080f000a6080604052600073ffffffffffffffffffffffffffffffffffffffff8154167fa619486e00000000000000000000000000000000000000000000000000000000823503604d57808252602082f35b3682833781823684845af490503d82833e806066573d82fd5b503d81f3fea164736f6c634300080f000aa164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": false, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x608060405234801561001057600080fd5b506001600455613fb6806100256000396000f3fe6080604052600436106101dc5760003560e01c8063affed0e011610102578063e19a9dd911610095578063f08a032311610064578063f08a032314610620578063f698da2514610640578063f8dc5dd9146106a7578063ffa1ad74146106c757610218565b8063e19a9dd9146105ab578063e318b52b146105cb578063e75235b8146105eb578063e86637db1461060057610218565b8063cc2f8452116100d1578063cc2f84521461051d578063d4d9bdcd1461054b578063d8d11f781461056b578063e009cfde1461058b57610218565b8063affed0e0146104a7578063b4faba09146104bd578063b63e800d146104dd578063c4ca3a9c146104fd57610218565b80635624b25b1161017a5780636a761202116101495780636a7612021461041a5780637d8329741461042d578063934f3a1114610465578063a0e67e2b1461048557610218565b80635624b25b146103805780635ae6bd37146103ad578063610b5925146103da578063694e80c3146103fa57610218565b80632f54bf6e116101b65780632f54bf6e146102f55780633408e47014610315578063468721a7146103325780635229073f1461035257610218565b80630d582f131461027e57806312fb68e0146102a05780632d9ad53d146102c057610218565b366102185760405134815233907f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d9060200160405180910390a2005b34801561022457600080fd5b507f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d580548061024f57005b36600080373360601b365260008060143601600080855af190503d6000803e80610278573d6000fd5b503d6000f35b34801561028a57600080fd5b5061029e6102993660046132ce565b610710565b005b3480156102ac57600080fd5b5061029e6102bb3660046133d4565b610966565b3480156102cc57600080fd5b506102e06102db366004613449565b610fbb565b60405190151581526020015b60405180910390f35b34801561030157600080fd5b506102e0610310366004613449565b611010565b34801561032157600080fd5b50465b6040519081526020016102ec565b34801561033e57600080fd5b506102e061034d366004613475565b611062565b34801561035e57600080fd5b5061037261036d366004613475565b611178565b6040516102ec92919061354a565b34801561038c57600080fd5b506103a061039b366004613565565b6111ae565b6040516102ec9190613587565b3480156103b957600080fd5b506103246103c836600461359a565b60076020526000908152604090205481565b3480156103e657600080fd5b5061029e6103f5366004613449565b611234565b34801561040657600080fd5b5061029e61041536600461359a565b611426565b6102e06104283660046135fc565b61153a565b34801561043957600080fd5b506103246104483660046132ce565b600860209081526000928352604080842090915290825290205481565b34801561047157600080fd5b5061029e6104803660046136d5565b611934565b34801561049157600080fd5b5061049a6119b0565b6040516102ec9190613793565b3480156104b357600080fd5b5061032460055481565b3480156104c957600080fd5b5061029e6104d83660046137a6565b611ac8565b3480156104e957600080fd5b5061029e6104f83660046137f6565b611aeb565b34801561050957600080fd5b506103246105183660046138eb565b611c26565b34801561052957600080fd5b5061053d6105383660046132ce565b611cf8565b6040516102ec92919061395c565b34801561055757600080fd5b5061029e61056636600461359a565b611e26565b34801561057757600080fd5b50610324610586366004613994565b611efa565b34801561059757600080fd5b5061029e6105a6366004613a55565b611f27565b3480156105b757600080fd5b5061029e6105c6366004613449565b612106565b3480156105d757600080fd5b5061029e6105e6366004613a8e565b612178565b3480156105f757600080fd5b50600454610324565b34801561060c57600080fd5b506103a061061b366004613994565b612504565b34801561062c57600080fd5b5061029e61063b366004613449565b61269d565b34801561064c57600080fd5b5061032460007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a794692184660408051602081019390935282015230606082015260800160405160208183030381529060405280519060200120905090565b3480156106b357600080fd5b5061029e6106c2366004613ad9565b612713565b3480156106d357600080fd5b506103a06040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b6107186129a5565b73ffffffffffffffffffffffffffffffffffffffff821615801590610754575073ffffffffffffffffffffffffffffffffffffffff8216600114155b8015610776575073ffffffffffffffffffffffffffffffffffffffff82163014155b6107e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600260205260409020541615610870576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303400000000000000000000000000000000000000000000000000000060448201526064016107d8565b60026020527fe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0805473ffffffffffffffffffffffffffffffffffffffff8481166000818152604081208054939094167fffffffffffffffffffffffff00000000000000000000000000000000000000009384161790935560018352835490911617909155600380549161090283613b49565b909155505060405173ffffffffffffffffffffffffffffffffffffffff831681527f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea269060200160405180910390a180600454146109625761096281611426565b5050565b610971816041612a10565b825110156109db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323000000000000000000000000000000000000000000000000000000060448201526064016107d8565b6000808060008060005b86811015610faf576041818102890160208101516040820151919092015160ff16955090935091506000849003610cbc579193508391610a26876041612a10565b821015610a8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323100000000000000000000000000000000000000000000000000000060448201526064016107d8565b8751610a9c836020612a4c565b1115610b04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323200000000000000000000000000000000000000000000000000000060448201526064016107d8565b602082890181015189519091610b27908390610b21908790612a4c565b90612a4c565b1115610b8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323300000000000000000000000000000000000000000000000000000060448201526064016107d8565b6040517f20c13b0b000000000000000000000000000000000000000000000000000000008082528a85016020019173ffffffffffffffffffffffffffffffffffffffff8916906320c13b0b90610beb908f908690600401613b81565b602060405180830381865afa158015610c08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2c9190613ba6565b7fffffffff000000000000000000000000000000000000000000000000000000001614610cb5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323400000000000000000000000000000000000000000000000000000060448201526064016107d8565b5050610eaf565b8360ff16600103610d8a5791935083913373ffffffffffffffffffffffffffffffffffffffff84161480610d1f575073ffffffffffffffffffffffffffffffffffffffff851660009081526008602090815260408083208d845290915290205415155b610d85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323500000000000000000000000000000000000000000000000000000060448201526064016107d8565b610eaf565b601e8460ff161115610e4f576040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018b9052600190605c0160405160208183030381529060405280519060200120600486610def9190613be8565b6040805160008152602081018083529390935260ff90911690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015610e3e573d6000803e3d6000fd5b505050602060405103519450610eaf565b6040805160008152602081018083528c905260ff861691810191909152606081018490526080810183905260019060a0016020604051602081039080840390855afa158015610ea2573d6000803e3d6000fd5b5050506020604051035194505b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16118015610f10575073ffffffffffffffffffffffffffffffffffffffff8581166000908152600260205260409020541615155b8015610f33575073ffffffffffffffffffffffffffffffffffffffff8516600114155b610f99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323600000000000000000000000000000000000000000000000000000060448201526064016107d8565b8495508080610fa790613b49565b9150506109e5565b50505050505050505050565b6000600173ffffffffffffffffffffffffffffffffffffffff83161480159061100a575073ffffffffffffffffffffffffffffffffffffffff8281166000908152600160205260409020541615155b92915050565b600073ffffffffffffffffffffffffffffffffffffffff821660011480159061100a57505073ffffffffffffffffffffffffffffffffffffffff90811660009081526002602052604090205416151590565b60003360011480159061109957503360009081526001602052604090205473ffffffffffffffffffffffffffffffffffffffff1615155b6110ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303400000000000000000000000000000000000000000000000000000060448201526064016107d8565b61110c858585855a612a68565b905080156111445760405133907f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb890600090a2611170565b60405133907facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37590600090a25b949350505050565b6000606061118886868686611062565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b606060006111bd836020613c0b565b67ffffffffffffffff8111156111d5576111d56132fa565b6040519080825280601f01601f1916602001820160405280156111ff576020820181803683370190505b50905060005b8381101561122c57848101546020808302840101528061122481613b49565b915050611205565b509392505050565b61123c6129a5565b73ffffffffffffffffffffffffffffffffffffffff811615801590611278575073ffffffffffffffffffffffffffffffffffffffff8116600114155b6112de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303100000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff818116600090815260016020526040902054161561136d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303200000000000000000000000000000000000000000000000000000060448201526064016107d8565b600160208181527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f805473ffffffffffffffffffffffffffffffffffffffff858116600081815260408082208054949095167fffffffffffffffffffffffff000000000000000000000000000000000000000094851617909455959095528254168417909155519182527fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844091015b60405180910390a150565b61142e6129a5565b60035481111561149a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303100000000000000000000000000000000000000000000000000000060448201526064016107d8565b6001811015611505576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303200000000000000000000000000000000000000000000000000000060448201526064016107d8565b60048190556040518181527f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c939060200161141b565b60008060006115548e8e8e8e8e8e8e8e8e8e600554612504565b60058054919250600061156683613b49565b909155505080516020820120915061157f828286611934565b5060006115aa7f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c85490565b905073ffffffffffffffffffffffffffffffffffffffff81161561164a578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b81526004016116179c9b9a99989796959493929190613cb2565b600060405180830381600087803b15801561163157600080fd5b505af1158015611645573d6000803e3d6000fd5b505050505b6116766116598a6109c4613dc8565b603f6116668c6040613c0b565b6116709190613de0565b90612aaf565b611682906101f4613dc8565b5a10156116eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313000000000000000000000000000000000000000000000000000000060448201526064016107d8565b60005a905061175c8f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e8c600014611749578e612a68565b6109c45a6117579190613e1b565b612a68565b93506117695a8290612ac6565b9050838061177657508915155b8061178057508715155b6117e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313300000000000000000000000000000000000000000000000000000060448201526064016107d8565b600088156117fe576117fb828b8b8b8b612ae1565b90505b84156118425760408051858152602081018390527f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e910160405180910390a161187c565b60408051858152602081018390527f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d23910160405180910390a15b505073ffffffffffffffffffffffffffffffffffffffff811615611923576040517f9327136800000000000000000000000000000000000000000000000000000000815260048101839052831515602482015273ffffffffffffffffffffffffffffffffffffffff821690639327136890604401600060405180830381600087803b15801561190a57600080fd5b505af115801561191e573d6000803e3d6000fd5b505050505b50509b9a5050505050505050505050565b6004548061199e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330303100000000000000000000000000000000000000000000000000000060448201526064016107d8565b6119aa84848484610966565b50505050565b6060600060035467ffffffffffffffff8111156119cf576119cf6132fa565b6040519080825280602002602001820160405280156119f8578160200160208202803683370190505b506001600090815260026020527fe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0549192509073ffffffffffffffffffffffffffffffffffffffff165b73ffffffffffffffffffffffffffffffffffffffff8116600114611ac05780838381518110611a7357611a73613e32565b73ffffffffffffffffffffffffffffffffffffffff928316602091820292909201810191909152918116600090815260029092526040909120541681611ab881613b49565b925050611a42565b509092915050565b600080825160208401855af480600052503d6020523d600060403e60403d016000fd5b611b298a8a808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508c9250612c72915050565b73ffffffffffffffffffffffffffffffffffffffff841615611b6d57611b6d847f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d555565b611bad8787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061303f92505050565b8115611bc457611bc282600060018685612ae1565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b89604051611c12959493929190613e61565b60405180910390a250505050505050505050565b6000805a9050611c6f878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525089925050505a612a68565b611c7857600080fd5b60005a611c859083613e1b565b905080604051602001611c9a91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526107d891600401613587565b606060008267ffffffffffffffff811115611d1557611d156132fa565b604051908082528060200260200182016040528015611d3e578160200160208202803683370190505b5073ffffffffffffffffffffffffffffffffffffffff80861660009081526001602052604081205492945091165b73ffffffffffffffffffffffffffffffffffffffff811615801590611da8575073ffffffffffffffffffffffffffffffffffffffff8116600114155b8015611db357508482105b15611e185780848381518110611dcb57611dcb613e32565b73ffffffffffffffffffffffffffffffffffffffff928316602091820292909201810191909152918116600090815260019092526040909120541681611e1081613b49565b925050611d6c565b908352919491935090915050565b3360009081526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16611eb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330333000000000000000000000000000000000000000000000000000000060448201526064016107d8565b336000818152600860209081526040808320858452909152808220600190555183917ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c91a350565b6000611f0f8c8c8c8c8c8c8c8c8c8c8c612504565b8051906020012090509b9a5050505050505050505050565b611f2f6129a5565b73ffffffffffffffffffffffffffffffffffffffff811615801590611f6b575073ffffffffffffffffffffffffffffffffffffffff8116600114155b611fd1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303100000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff828116600090815260016020526040902054811690821614612064576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303300000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff8181166000818152600160209081526040808320805488871685528285208054919097167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790965592849052825490941690915591519081527faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427691015b60405180910390a15050565b61210e6129a5565b7f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c881815560405173ffffffffffffffffffffffffffffffffffffffff831681527f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa2906020016120fa565b6121806129a5565b73ffffffffffffffffffffffffffffffffffffffff8116158015906121bc575073ffffffffffffffffffffffffffffffffffffffff8116600114155b80156121de575073ffffffffffffffffffffffffffffffffffffffff81163014155b612244576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff81811660009081526002602052604090205416156122d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303400000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff82161580159061230f575073ffffffffffffffffffffffffffffffffffffffff8216600114155b612375576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff838116600090815260026020526040902054811690831614612408576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303500000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff8281166000818152600260209081526040808320805487871680865283862080549289167fffffffffffffffffffffffff0000000000000000000000000000000000000000938416179055968a1685528285208054821690971790965592849052825490941690915591519081527ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf910160405180910390a160405173ffffffffffffffffffffffffffffffffffffffff821681527f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea269060200160405180910390a1505050565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d60405161253e929190613ee7565b604051908190038120612564949392918e908e908e908e908e908e908e90602001613ef7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012090507f19000000000000000000000000000000000000000000000000000000000000007f010000000000000000000000000000000000000000000000000000000000000061263860007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a794692184660408051602081019390935282015230606082015260800160405160208183030381529060405280519060200120905090565b6040517fff0000000000000000000000000000000000000000000000000000000000000093841660208201529290911660218301526022820152604281018290526062016040516020818303038152906040529150509b9a5050505050505050505050565b6126a56129a5565b6126cd817f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d555565b60405173ffffffffffffffffffffffffffffffffffffffff821681527f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b09060200161141b565b61271b6129a5565b80600160035461272b9190613e1b565b1015612793576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303100000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff8216158015906127cf575073ffffffffffffffffffffffffffffffffffffffff8216600114155b612835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600260205260409020548116908316146128c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303500000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff828116600081815260026020526040808220805488861684529183208054929095167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179094559181528254909116909155600380549161294083613f74565b909155505060405173ffffffffffffffffffffffffffffffffffffffff831681527ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf9060200160405180910390a180600454146129a0576129a081611426565b505050565b333014612a0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330333100000000000000000000000000000000000000000000000000000060448201526064016107d8565b565b600082600003612a225750600061100a565b6000612a2e8385613c0b565b905082612a3b8583613de0565b14612a4557600080fd5b9392505050565b600080612a598385613dc8565b905083811015612a4557600080fd5b60006001836001811115612a7e57612a7e613c48565b03612a96576000808551602087018986f49050612aa6565b600080855160208701888a87f190505b95945050505050565b600081831015612abf5781612a45565b5090919050565b600082821115612ad557600080fd5b60006111708385613e1b565b60008073ffffffffffffffffffffffffffffffffffffffff831615612b065782612b08565b325b905073ffffffffffffffffffffffffffffffffffffffff8416612be757612b473a8610612b35573a612b37565b855b612b418989612a4c565b90612a10565b60405190925073ffffffffffffffffffffffffffffffffffffffff82169083156108fc029084906000818181858888f19350505050612be2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313100000000000000000000000000000000000000000000000000000060448201526064016107d8565b612c68565b612bf585612b418989612a4c565b9150612c028482846131cf565b612c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313200000000000000000000000000000000000000000000000000000060448201526064016107d8565b5095945050505050565b60045415612cdc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303000000000000000000000000000000000000000000000000000000060448201526064016107d8565b8151811115612d47576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303100000000000000000000000000000000000000000000000000000060448201526064016107d8565b6001811015612db2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303200000000000000000000000000000000000000000000000000000060448201526064016107d8565b600160005b8351811015612fe7576000848281518110612dd457612dd4613e32565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015612e32575073ffffffffffffffffffffffffffffffffffffffff8116600114155b8015612e54575073ffffffffffffffffffffffffffffffffffffffff81163014155b8015612e8c57508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b612ef2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152600260205260409020541615612f81576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303400000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff928316600090815260026020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169382169390931790925580612fdf81613b49565b915050612db7565b5073ffffffffffffffffffffffffffffffffffffffff16600090815260026020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011790559051600355600455565b600160008190526020527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f5473ffffffffffffffffffffffffffffffffffffffff16156130e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303000000000000000000000000000000000000000000000000000000060448201526064016107d8565b6001600081905260208190527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f80547fffffffffffffffffffffffff000000000000000000000000000000000000000016909117905573ffffffffffffffffffffffffffffffffffffffff821615610962576131698260008360015a612a68565b610962576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330303000000000000000000000000000000000000000000000000000000060448201526064016107d8565b6040805173ffffffffffffffffffffffffffffffffffffffff841660248201526044808201849052825180830390910181526064909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001781528251600093929184919082896127105a03f13d801561327c5760208114613284576000935061328f565b81935061328f565b600051158215171593505b5050509392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146132bb57600080fd5b50565b80356132c981613299565b919050565b600080604083850312156132e157600080fd5b82356132ec81613299565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261333a57600080fd5b813567ffffffffffffffff80821115613355576133556132fa565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561339b5761339b6132fa565b816040528381528660208588010111156133b457600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080608085870312156133ea57600080fd5b84359350602085013567ffffffffffffffff8082111561340957600080fd5b61341588838901613329565b9450604087013591508082111561342b57600080fd5b5061343887828801613329565b949793965093946060013593505050565b60006020828403121561345b57600080fd5b8135612a4581613299565b8035600281106132c957600080fd5b6000806000806080858703121561348b57600080fd5b843561349681613299565b935060208501359250604085013567ffffffffffffffff8111156134b957600080fd5b6134c587828801613329565b9250506134d460608601613466565b905092959194509250565b6000815180845260005b81811015613505576020818501810151868301820152016134e9565b81811115613517576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b821515815260406020820152600061117060408301846134df565b6000806040838503121561357857600080fd5b50508035926020909101359150565b602081526000612a4560208301846134df565b6000602082840312156135ac57600080fd5b5035919050565b60008083601f8401126135c557600080fd5b50813567ffffffffffffffff8111156135dd57600080fd5b6020830191508360208285010111156135f557600080fd5b9250929050565b60008060008060008060008060008060006101408c8e03121561361e57600080fd5b6136278c6132be565b9a5060208c0135995067ffffffffffffffff8060408e0135111561364a57600080fd5b61365a8e60408f01358f016135b3565b909a50985061366b60608e01613466565b975060808d0135965060a08d0135955060c08d0135945061368e60e08e016132be565b935061369d6101008e016132be565b9250806101208e013511156136b157600080fd5b506136c38d6101208e01358e01613329565b90509295989b509295989b9093969950565b6000806000606084860312156136ea57600080fd5b83359250602084013567ffffffffffffffff8082111561370957600080fd5b61371587838801613329565b9350604086013591508082111561372b57600080fd5b5061373886828701613329565b9150509250925092565b600081518084526020808501945080840160005b8381101561378857815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613756565b509495945050505050565b602081526000612a456020830184613742565b600080604083850312156137b957600080fd5b82356137c481613299565b9150602083013567ffffffffffffffff8111156137e057600080fd5b6137ec85828601613329565b9150509250929050565b6000806000806000806000806000806101008b8d03121561381657600080fd5b8a3567ffffffffffffffff8082111561382e57600080fd5b818d0191508d601f83011261384257600080fd5b81358181111561385157600080fd5b8e60208260051b850101111561386657600080fd5b60208381019d50909b508d0135995061388160408e016132be565b985060608d013591508082111561389757600080fd5b506138a48d828e016135b3565b90975095506138b7905060808c016132be565b93506138c560a08c016132be565b925060c08b013591506138da60e08c016132be565b90509295989b9194979a5092959850565b60008060008060006080868803121561390357600080fd5b853561390e81613299565b945060208601359350604086013567ffffffffffffffff81111561393157600080fd5b61393d888289016135b3565b9094509250613950905060608701613466565b90509295509295909350565b60408152600061396f6040830185613742565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b60008060008060008060008060008060006101408c8e0312156139b657600080fd5b8b356139c181613299565b9a5060208c0135995060408c013567ffffffffffffffff8111156139e457600080fd5b6139f08e828f016135b3565b909a509850613a03905060608d01613466565b965060808c0135955060a08c0135945060c08c0135935060e08c0135613a2881613299565b92506101008c0135613a3981613299565b809250506101208c013590509295989b509295989b9093969950565b60008060408385031215613a6857600080fd5b8235613a7381613299565b91506020830135613a8381613299565b809150509250929050565b600080600060608486031215613aa357600080fd5b8335613aae81613299565b92506020840135613abe81613299565b91506040840135613ace81613299565b809150509250925092565b600080600060608486031215613aee57600080fd5b8335613af981613299565b92506020840135613b0981613299565b929592945050506040919091013590565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613b7a57613b7a613b1a565b5060010190565b604081526000613b9460408301856134df565b8281036020840152612aa681856134df565b600060208284031215613bb857600080fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114612a4557600080fd5b600060ff821660ff841680821015613c0257613c02613b1a565b90039392505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613c4357613c43613b1a565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60028110613cae577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b600061016073ffffffffffffffffffffffffffffffffffffffff8f1683528d60208401528060408401528b81840152506101808b8d828501376000818d850101527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8d01168301613d28606085018d613c77565b8a60808501528960a08501528860c0850152613d5c60e085018973ffffffffffffffffffffffffffffffffffffffff169052565b73ffffffffffffffffffffffffffffffffffffffff87166101008501528184820301610120850152613d90828201876134df565b92505050613db761014083018473ffffffffffffffffffffffffffffffffffffffff169052565b9d9c50505050505050505050505050565b60008219821115613ddb57613ddb613b1a565b500190565b600082613e16577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600082821015613e2d57613e2d613b1a565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6080808252810185905260008660a08301825b88811015613eb1578235613e8781613299565b73ffffffffffffffffffffffffffffffffffffffff16825260209283019290910190600101613e74565b506020840196909652505073ffffffffffffffffffffffffffffffffffffffff9283166040820152911660609091015292915050565b8183823760009101908152919050565b6000610160820190508c825273ffffffffffffffffffffffffffffffffffffffff808d1660208401528b60408401528a6060840152613f39608084018b613c77565b60a083019890985260c082019690965260e0810194909452918516610100840152909316610120820152610140019190915295945050505050565b600081613f8357613f83613b1a565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea164736f6c634300080f000a", - "deployedCode": "0x6080604052600436106101dc5760003560e01c8063affed0e011610102578063e19a9dd911610095578063f08a032311610064578063f08a032314610620578063f698da2514610640578063f8dc5dd9146106a7578063ffa1ad74146106c757610218565b8063e19a9dd9146105ab578063e318b52b146105cb578063e75235b8146105eb578063e86637db1461060057610218565b8063cc2f8452116100d1578063cc2f84521461051d578063d4d9bdcd1461054b578063d8d11f781461056b578063e009cfde1461058b57610218565b8063affed0e0146104a7578063b4faba09146104bd578063b63e800d146104dd578063c4ca3a9c146104fd57610218565b80635624b25b1161017a5780636a761202116101495780636a7612021461041a5780637d8329741461042d578063934f3a1114610465578063a0e67e2b1461048557610218565b80635624b25b146103805780635ae6bd37146103ad578063610b5925146103da578063694e80c3146103fa57610218565b80632f54bf6e116101b65780632f54bf6e146102f55780633408e47014610315578063468721a7146103325780635229073f1461035257610218565b80630d582f131461027e57806312fb68e0146102a05780632d9ad53d146102c057610218565b366102185760405134815233907f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d9060200160405180910390a2005b34801561022457600080fd5b507f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d580548061024f57005b36600080373360601b365260008060143601600080855af190503d6000803e80610278573d6000fd5b503d6000f35b34801561028a57600080fd5b5061029e6102993660046132ce565b610710565b005b3480156102ac57600080fd5b5061029e6102bb3660046133d4565b610966565b3480156102cc57600080fd5b506102e06102db366004613449565b610fbb565b60405190151581526020015b60405180910390f35b34801561030157600080fd5b506102e0610310366004613449565b611010565b34801561032157600080fd5b50465b6040519081526020016102ec565b34801561033e57600080fd5b506102e061034d366004613475565b611062565b34801561035e57600080fd5b5061037261036d366004613475565b611178565b6040516102ec92919061354a565b34801561038c57600080fd5b506103a061039b366004613565565b6111ae565b6040516102ec9190613587565b3480156103b957600080fd5b506103246103c836600461359a565b60076020526000908152604090205481565b3480156103e657600080fd5b5061029e6103f5366004613449565b611234565b34801561040657600080fd5b5061029e61041536600461359a565b611426565b6102e06104283660046135fc565b61153a565b34801561043957600080fd5b506103246104483660046132ce565b600860209081526000928352604080842090915290825290205481565b34801561047157600080fd5b5061029e6104803660046136d5565b611934565b34801561049157600080fd5b5061049a6119b0565b6040516102ec9190613793565b3480156104b357600080fd5b5061032460055481565b3480156104c957600080fd5b5061029e6104d83660046137a6565b611ac8565b3480156104e957600080fd5b5061029e6104f83660046137f6565b611aeb565b34801561050957600080fd5b506103246105183660046138eb565b611c26565b34801561052957600080fd5b5061053d6105383660046132ce565b611cf8565b6040516102ec92919061395c565b34801561055757600080fd5b5061029e61056636600461359a565b611e26565b34801561057757600080fd5b50610324610586366004613994565b611efa565b34801561059757600080fd5b5061029e6105a6366004613a55565b611f27565b3480156105b757600080fd5b5061029e6105c6366004613449565b612106565b3480156105d757600080fd5b5061029e6105e6366004613a8e565b612178565b3480156105f757600080fd5b50600454610324565b34801561060c57600080fd5b506103a061061b366004613994565b612504565b34801561062c57600080fd5b5061029e61063b366004613449565b61269d565b34801561064c57600080fd5b5061032460007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a794692184660408051602081019390935282015230606082015260800160405160208183030381529060405280519060200120905090565b3480156106b357600080fd5b5061029e6106c2366004613ad9565b612713565b3480156106d357600080fd5b506103a06040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b6107186129a5565b73ffffffffffffffffffffffffffffffffffffffff821615801590610754575073ffffffffffffffffffffffffffffffffffffffff8216600114155b8015610776575073ffffffffffffffffffffffffffffffffffffffff82163014155b6107e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600260205260409020541615610870576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303400000000000000000000000000000000000000000000000000000060448201526064016107d8565b60026020527fe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0805473ffffffffffffffffffffffffffffffffffffffff8481166000818152604081208054939094167fffffffffffffffffffffffff00000000000000000000000000000000000000009384161790935560018352835490911617909155600380549161090283613b49565b909155505060405173ffffffffffffffffffffffffffffffffffffffff831681527f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea269060200160405180910390a180600454146109625761096281611426565b5050565b610971816041612a10565b825110156109db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323000000000000000000000000000000000000000000000000000000060448201526064016107d8565b6000808060008060005b86811015610faf576041818102890160208101516040820151919092015160ff16955090935091506000849003610cbc579193508391610a26876041612a10565b821015610a8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323100000000000000000000000000000000000000000000000000000060448201526064016107d8565b8751610a9c836020612a4c565b1115610b04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323200000000000000000000000000000000000000000000000000000060448201526064016107d8565b602082890181015189519091610b27908390610b21908790612a4c565b90612a4c565b1115610b8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323300000000000000000000000000000000000000000000000000000060448201526064016107d8565b6040517f20c13b0b000000000000000000000000000000000000000000000000000000008082528a85016020019173ffffffffffffffffffffffffffffffffffffffff8916906320c13b0b90610beb908f908690600401613b81565b602060405180830381865afa158015610c08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2c9190613ba6565b7fffffffff000000000000000000000000000000000000000000000000000000001614610cb5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323400000000000000000000000000000000000000000000000000000060448201526064016107d8565b5050610eaf565b8360ff16600103610d8a5791935083913373ffffffffffffffffffffffffffffffffffffffff84161480610d1f575073ffffffffffffffffffffffffffffffffffffffff851660009081526008602090815260408083208d845290915290205415155b610d85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323500000000000000000000000000000000000000000000000000000060448201526064016107d8565b610eaf565b601e8460ff161115610e4f576040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018b9052600190605c0160405160208183030381529060405280519060200120600486610def9190613be8565b6040805160008152602081018083529390935260ff90911690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015610e3e573d6000803e3d6000fd5b505050602060405103519450610eaf565b6040805160008152602081018083528c905260ff861691810191909152606081018490526080810183905260019060a0016020604051602081039080840390855afa158015610ea2573d6000803e3d6000fd5b5050506020604051035194505b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16118015610f10575073ffffffffffffffffffffffffffffffffffffffff8581166000908152600260205260409020541615155b8015610f33575073ffffffffffffffffffffffffffffffffffffffff8516600114155b610f99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323600000000000000000000000000000000000000000000000000000060448201526064016107d8565b8495508080610fa790613b49565b9150506109e5565b50505050505050505050565b6000600173ffffffffffffffffffffffffffffffffffffffff83161480159061100a575073ffffffffffffffffffffffffffffffffffffffff8281166000908152600160205260409020541615155b92915050565b600073ffffffffffffffffffffffffffffffffffffffff821660011480159061100a57505073ffffffffffffffffffffffffffffffffffffffff90811660009081526002602052604090205416151590565b60003360011480159061109957503360009081526001602052604090205473ffffffffffffffffffffffffffffffffffffffff1615155b6110ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303400000000000000000000000000000000000000000000000000000060448201526064016107d8565b61110c858585855a612a68565b905080156111445760405133907f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb890600090a2611170565b60405133907facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37590600090a25b949350505050565b6000606061118886868686611062565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b606060006111bd836020613c0b565b67ffffffffffffffff8111156111d5576111d56132fa565b6040519080825280601f01601f1916602001820160405280156111ff576020820181803683370190505b50905060005b8381101561122c57848101546020808302840101528061122481613b49565b915050611205565b509392505050565b61123c6129a5565b73ffffffffffffffffffffffffffffffffffffffff811615801590611278575073ffffffffffffffffffffffffffffffffffffffff8116600114155b6112de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303100000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff818116600090815260016020526040902054161561136d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303200000000000000000000000000000000000000000000000000000060448201526064016107d8565b600160208181527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f805473ffffffffffffffffffffffffffffffffffffffff858116600081815260408082208054949095167fffffffffffffffffffffffff000000000000000000000000000000000000000094851617909455959095528254168417909155519182527fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844091015b60405180910390a150565b61142e6129a5565b60035481111561149a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303100000000000000000000000000000000000000000000000000000060448201526064016107d8565b6001811015611505576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303200000000000000000000000000000000000000000000000000000060448201526064016107d8565b60048190556040518181527f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c939060200161141b565b60008060006115548e8e8e8e8e8e8e8e8e8e600554612504565b60058054919250600061156683613b49565b909155505080516020820120915061157f828286611934565b5060006115aa7f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c85490565b905073ffffffffffffffffffffffffffffffffffffffff81161561164a578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b81526004016116179c9b9a99989796959493929190613cb2565b600060405180830381600087803b15801561163157600080fd5b505af1158015611645573d6000803e3d6000fd5b505050505b6116766116598a6109c4613dc8565b603f6116668c6040613c0b565b6116709190613de0565b90612aaf565b611682906101f4613dc8565b5a10156116eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313000000000000000000000000000000000000000000000000000000060448201526064016107d8565b60005a905061175c8f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e8c600014611749578e612a68565b6109c45a6117579190613e1b565b612a68565b93506117695a8290612ac6565b9050838061177657508915155b8061178057508715155b6117e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313300000000000000000000000000000000000000000000000000000060448201526064016107d8565b600088156117fe576117fb828b8b8b8b612ae1565b90505b84156118425760408051858152602081018390527f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e910160405180910390a161187c565b60408051858152602081018390527f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d23910160405180910390a15b505073ffffffffffffffffffffffffffffffffffffffff811615611923576040517f9327136800000000000000000000000000000000000000000000000000000000815260048101839052831515602482015273ffffffffffffffffffffffffffffffffffffffff821690639327136890604401600060405180830381600087803b15801561190a57600080fd5b505af115801561191e573d6000803e3d6000fd5b505050505b50509b9a5050505050505050505050565b6004548061199e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330303100000000000000000000000000000000000000000000000000000060448201526064016107d8565b6119aa84848484610966565b50505050565b6060600060035467ffffffffffffffff8111156119cf576119cf6132fa565b6040519080825280602002602001820160405280156119f8578160200160208202803683370190505b506001600090815260026020527fe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0549192509073ffffffffffffffffffffffffffffffffffffffff165b73ffffffffffffffffffffffffffffffffffffffff8116600114611ac05780838381518110611a7357611a73613e32565b73ffffffffffffffffffffffffffffffffffffffff928316602091820292909201810191909152918116600090815260029092526040909120541681611ab881613b49565b925050611a42565b509092915050565b600080825160208401855af480600052503d6020523d600060403e60403d016000fd5b611b298a8a808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508c9250612c72915050565b73ffffffffffffffffffffffffffffffffffffffff841615611b6d57611b6d847f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d555565b611bad8787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061303f92505050565b8115611bc457611bc282600060018685612ae1565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b89604051611c12959493929190613e61565b60405180910390a250505050505050505050565b6000805a9050611c6f878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525089925050505a612a68565b611c7857600080fd5b60005a611c859083613e1b565b905080604051602001611c9a91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526107d891600401613587565b606060008267ffffffffffffffff811115611d1557611d156132fa565b604051908082528060200260200182016040528015611d3e578160200160208202803683370190505b5073ffffffffffffffffffffffffffffffffffffffff80861660009081526001602052604081205492945091165b73ffffffffffffffffffffffffffffffffffffffff811615801590611da8575073ffffffffffffffffffffffffffffffffffffffff8116600114155b8015611db357508482105b15611e185780848381518110611dcb57611dcb613e32565b73ffffffffffffffffffffffffffffffffffffffff928316602091820292909201810191909152918116600090815260019092526040909120541681611e1081613b49565b925050611d6c565b908352919491935090915050565b3360009081526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16611eb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330333000000000000000000000000000000000000000000000000000000060448201526064016107d8565b336000818152600860209081526040808320858452909152808220600190555183917ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c91a350565b6000611f0f8c8c8c8c8c8c8c8c8c8c8c612504565b8051906020012090509b9a5050505050505050505050565b611f2f6129a5565b73ffffffffffffffffffffffffffffffffffffffff811615801590611f6b575073ffffffffffffffffffffffffffffffffffffffff8116600114155b611fd1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303100000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff828116600090815260016020526040902054811690821614612064576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303300000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff8181166000818152600160209081526040808320805488871685528285208054919097167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790965592849052825490941690915591519081527faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427691015b60405180910390a15050565b61210e6129a5565b7f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c881815560405173ffffffffffffffffffffffffffffffffffffffff831681527f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa2906020016120fa565b6121806129a5565b73ffffffffffffffffffffffffffffffffffffffff8116158015906121bc575073ffffffffffffffffffffffffffffffffffffffff8116600114155b80156121de575073ffffffffffffffffffffffffffffffffffffffff81163014155b612244576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff81811660009081526002602052604090205416156122d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303400000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff82161580159061230f575073ffffffffffffffffffffffffffffffffffffffff8216600114155b612375576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff838116600090815260026020526040902054811690831614612408576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303500000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff8281166000818152600260209081526040808320805487871680865283862080549289167fffffffffffffffffffffffff0000000000000000000000000000000000000000938416179055968a1685528285208054821690971790965592849052825490941690915591519081527ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf910160405180910390a160405173ffffffffffffffffffffffffffffffffffffffff821681527f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea269060200160405180910390a1505050565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d60405161253e929190613ee7565b604051908190038120612564949392918e908e908e908e908e908e908e90602001613ef7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012090507f19000000000000000000000000000000000000000000000000000000000000007f010000000000000000000000000000000000000000000000000000000000000061263860007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a794692184660408051602081019390935282015230606082015260800160405160208183030381529060405280519060200120905090565b6040517fff0000000000000000000000000000000000000000000000000000000000000093841660208201529290911660218301526022820152604281018290526062016040516020818303038152906040529150509b9a5050505050505050505050565b6126a56129a5565b6126cd817f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d555565b60405173ffffffffffffffffffffffffffffffffffffffff821681527f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b09060200161141b565b61271b6129a5565b80600160035461272b9190613e1b565b1015612793576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303100000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff8216158015906127cf575073ffffffffffffffffffffffffffffffffffffffff8216600114155b612835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600260205260409020548116908316146128c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303500000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff828116600081815260026020526040808220805488861684529183208054929095167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179094559181528254909116909155600380549161294083613f74565b909155505060405173ffffffffffffffffffffffffffffffffffffffff831681527ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf9060200160405180910390a180600454146129a0576129a081611426565b505050565b333014612a0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330333100000000000000000000000000000000000000000000000000000060448201526064016107d8565b565b600082600003612a225750600061100a565b6000612a2e8385613c0b565b905082612a3b8583613de0565b14612a4557600080fd5b9392505050565b600080612a598385613dc8565b905083811015612a4557600080fd5b60006001836001811115612a7e57612a7e613c48565b03612a96576000808551602087018986f49050612aa6565b600080855160208701888a87f190505b95945050505050565b600081831015612abf5781612a45565b5090919050565b600082821115612ad557600080fd5b60006111708385613e1b565b60008073ffffffffffffffffffffffffffffffffffffffff831615612b065782612b08565b325b905073ffffffffffffffffffffffffffffffffffffffff8416612be757612b473a8610612b35573a612b37565b855b612b418989612a4c565b90612a10565b60405190925073ffffffffffffffffffffffffffffffffffffffff82169083156108fc029084906000818181858888f19350505050612be2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313100000000000000000000000000000000000000000000000000000060448201526064016107d8565b612c68565b612bf585612b418989612a4c565b9150612c028482846131cf565b612c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313200000000000000000000000000000000000000000000000000000060448201526064016107d8565b5095945050505050565b60045415612cdc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303000000000000000000000000000000000000000000000000000000060448201526064016107d8565b8151811115612d47576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303100000000000000000000000000000000000000000000000000000060448201526064016107d8565b6001811015612db2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303200000000000000000000000000000000000000000000000000000060448201526064016107d8565b600160005b8351811015612fe7576000848281518110612dd457612dd4613e32565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015612e32575073ffffffffffffffffffffffffffffffffffffffff8116600114155b8015612e54575073ffffffffffffffffffffffffffffffffffffffff81163014155b8015612e8c57508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b612ef2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152600260205260409020541615612f81576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303400000000000000000000000000000000000000000000000000000060448201526064016107d8565b73ffffffffffffffffffffffffffffffffffffffff928316600090815260026020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169382169390931790925580612fdf81613b49565b915050612db7565b5073ffffffffffffffffffffffffffffffffffffffff16600090815260026020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011790559051600355600455565b600160008190526020527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f5473ffffffffffffffffffffffffffffffffffffffff16156130e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303000000000000000000000000000000000000000000000000000000060448201526064016107d8565b6001600081905260208190527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f80547fffffffffffffffffffffffff000000000000000000000000000000000000000016909117905573ffffffffffffffffffffffffffffffffffffffff821615610962576131698260008360015a612a68565b610962576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330303000000000000000000000000000000000000000000000000000000060448201526064016107d8565b6040805173ffffffffffffffffffffffffffffffffffffffff841660248201526044808201849052825180830390910181526064909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001781528251600093929184919082896127105a03f13d801561327c5760208114613284576000935061328f565b81935061328f565b600051158215171593505b5050509392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146132bb57600080fd5b50565b80356132c981613299565b919050565b600080604083850312156132e157600080fd5b82356132ec81613299565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261333a57600080fd5b813567ffffffffffffffff80821115613355576133556132fa565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561339b5761339b6132fa565b816040528381528660208588010111156133b457600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080608085870312156133ea57600080fd5b84359350602085013567ffffffffffffffff8082111561340957600080fd5b61341588838901613329565b9450604087013591508082111561342b57600080fd5b5061343887828801613329565b949793965093946060013593505050565b60006020828403121561345b57600080fd5b8135612a4581613299565b8035600281106132c957600080fd5b6000806000806080858703121561348b57600080fd5b843561349681613299565b935060208501359250604085013567ffffffffffffffff8111156134b957600080fd5b6134c587828801613329565b9250506134d460608601613466565b905092959194509250565b6000815180845260005b81811015613505576020818501810151868301820152016134e9565b81811115613517576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b821515815260406020820152600061117060408301846134df565b6000806040838503121561357857600080fd5b50508035926020909101359150565b602081526000612a4560208301846134df565b6000602082840312156135ac57600080fd5b5035919050565b60008083601f8401126135c557600080fd5b50813567ffffffffffffffff8111156135dd57600080fd5b6020830191508360208285010111156135f557600080fd5b9250929050565b60008060008060008060008060008060006101408c8e03121561361e57600080fd5b6136278c6132be565b9a5060208c0135995067ffffffffffffffff8060408e0135111561364a57600080fd5b61365a8e60408f01358f016135b3565b909a50985061366b60608e01613466565b975060808d0135965060a08d0135955060c08d0135945061368e60e08e016132be565b935061369d6101008e016132be565b9250806101208e013511156136b157600080fd5b506136c38d6101208e01358e01613329565b90509295989b509295989b9093969950565b6000806000606084860312156136ea57600080fd5b83359250602084013567ffffffffffffffff8082111561370957600080fd5b61371587838801613329565b9350604086013591508082111561372b57600080fd5b5061373886828701613329565b9150509250925092565b600081518084526020808501945080840160005b8381101561378857815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613756565b509495945050505050565b602081526000612a456020830184613742565b600080604083850312156137b957600080fd5b82356137c481613299565b9150602083013567ffffffffffffffff8111156137e057600080fd5b6137ec85828601613329565b9150509250929050565b6000806000806000806000806000806101008b8d03121561381657600080fd5b8a3567ffffffffffffffff8082111561382e57600080fd5b818d0191508d601f83011261384257600080fd5b81358181111561385157600080fd5b8e60208260051b850101111561386657600080fd5b60208381019d50909b508d0135995061388160408e016132be565b985060608d013591508082111561389757600080fd5b506138a48d828e016135b3565b90975095506138b7905060808c016132be565b93506138c560a08c016132be565b925060c08b013591506138da60e08c016132be565b90509295989b9194979a5092959850565b60008060008060006080868803121561390357600080fd5b853561390e81613299565b945060208601359350604086013567ffffffffffffffff81111561393157600080fd5b61393d888289016135b3565b9094509250613950905060608701613466565b90509295509295909350565b60408152600061396f6040830185613742565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b60008060008060008060008060008060006101408c8e0312156139b657600080fd5b8b356139c181613299565b9a5060208c0135995060408c013567ffffffffffffffff8111156139e457600080fd5b6139f08e828f016135b3565b909a509850613a03905060608d01613466565b965060808c0135955060a08c0135945060c08c0135935060e08c0135613a2881613299565b92506101008c0135613a3981613299565b809250506101208c013590509295989b509295989b9093969950565b60008060408385031215613a6857600080fd5b8235613a7381613299565b91506020830135613a8381613299565b809150509250929050565b600080600060608486031215613aa357600080fd5b8335613aae81613299565b92506020840135613abe81613299565b91506040840135613ace81613299565b809150509250925092565b600080600060608486031215613aee57600080fd5b8335613af981613299565b92506020840135613b0981613299565b929592945050506040919091013590565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613b7a57613b7a613b1a565b5060010190565b604081526000613b9460408301856134df565b8281036020840152612aa681856134df565b600060208284031215613bb857600080fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114612a4557600080fd5b600060ff821660ff841680821015613c0257613c02613b1a565b90039392505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613c4357613c43613b1a565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60028110613cae577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b600061016073ffffffffffffffffffffffffffffffffffffffff8f1683528d60208401528060408401528b81840152506101808b8d828501376000818d850101527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8d01168301613d28606085018d613c77565b8a60808501528960a08501528860c0850152613d5c60e085018973ffffffffffffffffffffffffffffffffffffffff169052565b73ffffffffffffffffffffffffffffffffffffffff87166101008501528184820301610120850152613d90828201876134df565b92505050613db761014083018473ffffffffffffffffffffffffffffffffffffffff169052565b9d9c50505050505050505050505050565b60008219821115613ddb57613ddb613b1a565b500190565b600082613e16577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600082821015613e2d57613e2d613b1a565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6080808252810185905260008660a08301825b88811015613eb1578235613e8781613299565b73ffffffffffffffffffffffffffffffffffffffff16825260209283019290910190600101613e74565b506020840196909652505073ffffffffffffffffffffffffffffffffffffffff9283166040820152911660609091015292915050565b8183823760009101908152919050565b6000610160820190508c825273ffffffffffffffffffffffffffffffffffffffff808d1660208401528b60408401528a6060840152613f39608084018b613c77565b60a083019890985260c082019690965260e0810194909452918516610100840152909316610120820152610140019190915295945050505050565b600081613f8357613f83613b1a565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xA8452Ec99ce0C64f20701dB7dD3abDb607c00496", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x1688f0b9000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3000000000000000000000000000000000000000000000000000000000000006047555c7c5eb40250af82c9713b290d445cad0893c01b18ae084f70d0b7b0d67d0000000000000000000000000000000000000000000000000000000000000164b63e800d0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0xA8452Ec99ce0C64f20701dB7dD3abDb607c00496", - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x608060405234801561001057600080fd5b5060405161016f38038061016f83398101604081905261002f916100b9565b6001600160a01b0381166100945760405162461bcd60e51b815260206004820152602260248201527f496e76616c69642073696e676c65746f6e20616464726573732070726f766964604482015261195960f21b606482015260840160405180910390fd5b600080546001600160a01b0319166001600160a01b03929092169190911790556100e9565b6000602082840312156100cb57600080fd5b81516001600160a01b03811681146100e257600080fd5b9392505050565b6078806100f76000396000f3fe6080604052600073ffffffffffffffffffffffffffffffffffffffff8154167fa619486e00000000000000000000000000000000000000000000000000000000823503604d57808252602082f35b3682833781823684845af490503d82833e806066573d82fd5b503d81f3fea164736f6c634300080f000a000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "deployedCode": "0x6080604052600073ffffffffffffffffffffffffffffffffffffffff8154167fa619486e00000000000000000000000000000000000000000000000000000000823503604d57808252602082f35b3682833781823684845af490503d82833e806066573d82fd5b503d81f3fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0xA8452Ec99ce0C64f20701dB7dD3abDb607c00496", - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xb63e800d0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f380000000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0xA8452Ec99ce0C64f20701dB7dD3abDb607c00496", - "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xb63e800d0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f380000000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x608060405234801561001057600080fd5b5061001a3361001f565b61006f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6105ef8061007e6000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80639b2ea4bd116100505780639b2ea4bd146100b9578063bf40fac1146100cc578063f2fde38b146100df57600080fd5b8063715018a61461006c5780638da5cb5b14610076575b600080fd5b6100746100f2565b005b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100746100c73660046104fa565b610106565b6100906100da366004610548565b6101d9565b6100746100ed366004610585565b610215565b6100fa6102d1565b6101046000610352565b565b61010e6102d1565b6000610119836103c7565b60008181526001602052604090819020805473ffffffffffffffffffffffffffffffffffffffff8681167fffffffffffffffffffffffff00000000000000000000000000000000000000008316179092559151929350169061017c9085906105a7565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f9416a153a346f93d95f94b064ae3f148b6460473c6e82b3f9fc2521b873fcd6c910160405180910390a250505050565b6000600160006101e8846103c7565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1692915050565b61021d6102d1565b73ffffffffffffffffffffffffffffffffffffffff81166102c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102ce81610352565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610104576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102bc565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000816040516020016103da91906105a7565b604051602081830303815290604052805190602001209050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261043757600080fd5b813567ffffffffffffffff80821115610452576104526103f7565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610498576104986103f7565b816040528381528660208588010111156104b157600080fd5b836020870160208301376000602085830101528094505050505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b919050565b6000806040838503121561050d57600080fd5b823567ffffffffffffffff81111561052457600080fd5b61053085828601610426565b92505061053f602084016104d1565b90509250929050565b60006020828403121561055a57600080fd5b813567ffffffffffffffff81111561057157600080fd5b61057d84828501610426565b949350505050565b60006020828403121561059757600080fd5b6105a0826104d1565b9392505050565b6000825160005b818110156105c857602081860181015185830152016105ae565b818111156105d7576000828501525b50919091019291505056fea164736f6c634300080f000a", - "deployedCode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c80639b2ea4bd116100505780639b2ea4bd146100b9578063bf40fac1146100cc578063f2fde38b146100df57600080fd5b8063715018a61461006c5780638da5cb5b14610076575b600080fd5b6100746100f2565b005b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100746100c73660046104fa565b610106565b6100906100da366004610548565b6101d9565b6100746100ed366004610585565b610215565b6100fa6102d1565b6101046000610352565b565b61010e6102d1565b6000610119836103c7565b60008181526001602052604090819020805473ffffffffffffffffffffffffffffffffffffffff8681167fffffffffffffffffffffffff00000000000000000000000000000000000000008316179092559151929350169061017c9085906105a7565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f9416a153a346f93d95f94b064ae3f148b6460473c6e82b3f9fc2521b873fcd6c910160405180910390a250505050565b6000600160006101e8846103c7565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1692915050565b61021d6102d1565b73ffffffffffffffffffffffffffffffffffffffff81166102c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102ce81610352565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610104576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102bc565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000816040516020016103da91906105a7565b604051602081830303815290604052805190602001209050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261043757600080fd5b813567ffffffffffffffff80821115610452576104526103f7565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610498576104986103f7565b816040528381528660208588010111156104b157600080fd5b836020870160208301376000602085830101528094505050505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b919050565b6000806040838503121561050d57600080fd5b823567ffffffffffffffff81111561052457600080fd5b61053085828601610426565b92505061053f602084016104d1565b90509250929050565b60006020828403121561055a57600080fd5b813567ffffffffffffffff81111561057157600080fd5b61057d84828501610426565b949350505050565b60006020828403121561059757600080fd5b6105a0826104d1565b9392505050565b6000825160005b818110156105c857602081860181015185830152016105ae565b818111156105d7576000828501525b50919091019291505056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "isWrite": true, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x60806040523480156200001157600080fd5b5060405162001a5f38038062001a5f8339810160408190526200003491620000a1565b6200003f3362000051565b6200004a8162000051565b50620000d3565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600060208284031215620000b457600080fd5b81516001600160a01b0381168114620000cc57600080fd5b9392505050565b61197c80620000e36000396000f3fe60806040526004361061010e5760003560e01c8063860f7cda116100a557806399a88ec411610074578063b794726211610059578063b794726214610329578063f2fde38b14610364578063f3b7dead1461038457600080fd5b806399a88ec4146102e95780639b2ea4bd1461030957600080fd5b8063860f7cda1461026b5780638d52d4a01461028b5780638da5cb5b146102ab5780639623609d146102d657600080fd5b80633ab76e9f116100e15780633ab76e9f146101cc5780636bd9f516146101f9578063715018a6146102365780637eff275e1461024b57600080fd5b80630652b57a1461011357806307c8f7b014610135578063204e1c7a14610155578063238181ae1461019f575b600080fd5b34801561011f57600080fd5b5061013361012e3660046111f9565b6103a4565b005b34801561014157600080fd5b50610133610150366004611216565b6103f3565b34801561016157600080fd5b506101756101703660046111f9565b610445565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101ab57600080fd5b506101bf6101ba3660046111f9565b61066b565b60405161019691906112ae565b3480156101d857600080fd5b506003546101759073ffffffffffffffffffffffffffffffffffffffff1681565b34801561020557600080fd5b506102296102143660046111f9565b60016020526000908152604090205460ff1681565b60405161019691906112f0565b34801561024257600080fd5b50610133610705565b34801561025757600080fd5b50610133610266366004611331565b610719565b34801561027757600080fd5b5061013361028636600461148c565b6108cc565b34801561029757600080fd5b506101336102a63660046114dc565b610903565b3480156102b757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610175565b6101336102e436600461150e565b610977565b3480156102f557600080fd5b50610133610304366004611331565b610b8e565b34801561031557600080fd5b50610133610324366004611584565b610e1e565b34801561033557600080fd5b5060035474010000000000000000000000000000000000000000900460ff166040519015158152602001610196565b34801561037057600080fd5b5061013361037f3660046111f9565b610eb4565b34801561039057600080fd5b5061017561039f3660046111f9565b610f6b565b6103ac6110e1565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6103fb6110e1565b6003805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610481576104816112c1565b036104fc578273ffffffffffffffffffffffffffffffffffffffff16635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f591906115cb565b9392505050565b6001816002811115610510576105106112c1565b03610560578273ffffffffffffffffffffffffffffffffffffffff1663aaf10f426040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6002816002811115610574576105746112c1565b036105fe5760035473ffffffffffffffffffffffffffffffffffffffff8481166000908152600260205260409081902090517fbf40fac1000000000000000000000000000000000000000000000000000000008152919092169163bf40fac1916105e19190600401611635565b602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f50726f787941646d696e3a20756e6b6e6f776e2070726f78792074797065000060448201526064015b60405180910390fd5b50919050565b60026020526000908152604090208054610684906115e8565b80601f01602080910402602001604051908101604052809291908181526020018280546106b0906115e8565b80156106fd5780601f106106d2576101008083540402835291602001916106fd565b820191906000526020600020905b8154815290600101906020018083116106e057829003601f168201915b505050505081565b61070d6110e1565b6107176000611162565b565b6107216110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff169081600281111561075d5761075d6112c1565b036107e9576040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690638f283970906024015b600060405180830381600087803b1580156107cc57600080fd5b505af11580156107e0573d6000803e3d6000fd5b50505050505050565b60018160028111156107fd576107fd6112c1565b03610856576040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528416906313af4035906024016107b2565b600281600281111561086a5761086a6112c1565b036105fe576003546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301529091169063f2fde38b906024016107b2565b505050565b6108d46110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090206108c78282611724565b61090b6110e1565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600160208190526040909120805483927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091169083600281111561096e5761096e6112c1565b02179055505050565b61097f6110e1565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604081205460ff16908160028111156109bb576109bb6112c1565b03610a81576040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851690634f1ef286903490610a16908790879060040161183e565b60006040518083038185885af1158015610a34573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610a7b9190810190611875565b50610b88565b610a8b8484610b8e565b60008473ffffffffffffffffffffffffffffffffffffffff163484604051610ab391906118ec565b60006040518083038185875af1925050503d8060008114610af0576040519150601f19603f3d011682016040523d82523d6000602084013e610af5565b606091505b5050905080610b86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f50726f787941646d696e3a2063616c6c20746f2070726f78792061667465722060448201527f75706772616465206661696c6564000000000000000000000000000000000000606482015260840161065c565b505b50505050565b610b966110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff1690816002811115610bd257610bd26112c1565b03610c2b576040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690633659cfe6906024016107b2565b6001816002811115610c3f57610c3f6112c1565b03610cbe576040517f9b0b0fda0000000000000000000000000000000000000000000000000000000081527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152841690639b0b0fda906044016107b2565b6002816002811115610cd257610cd26112c1565b03610e165773ffffffffffffffffffffffffffffffffffffffff831660009081526002602052604081208054610d07906115e8565b80601f0160208091040260200160405190810160405280929190818152602001828054610d33906115e8565b8015610d805780601f10610d5557610100808354040283529160200191610d80565b820191906000526020600020905b815481529060010190602001808311610d6357829003601f168201915b50506003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815294955073ffffffffffffffffffffffffffffffffffffffff1693639b2ea4bd9350610dde92508591508790600401611908565b600060405180830381600087803b158015610df857600080fd5b505af1158015610e0c573d6000803e3d6000fd5b5050505050505050565b6108c7611940565b610e266110e1565b6003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690639b2ea4bd90610e7e9085908590600401611908565b600060405180830381600087803b158015610e9857600080fd5b505af1158015610eac573d6000803e3d6000fd5b505050505050565b610ebc6110e1565b73ffffffffffffffffffffffffffffffffffffffff8116610f5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161065c565b610f6881611162565b50565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610fa757610fa76112c1565b03610ff7578273ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600181600281111561100b5761100b6112c1565b0361105b578273ffffffffffffffffffffffffffffffffffffffff1663893d20e86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600281600281111561106f5761106f6112c1565b036105fe57600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314610717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161065c565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f6857600080fd5b60006020828403121561120b57600080fd5b81356104f5816111d7565b60006020828403121561122857600080fd5b813580151581146104f557600080fd5b60005b8381101561125357818101518382015260200161123b565b83811115610b885750506000910152565b6000815180845261127c816020860160208601611238565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104f56020830184611264565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b602081016003831061132b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806040838503121561134457600080fd5b823561134f816111d7565b9150602083013561135f816111d7565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156113e0576113e061136a565b604052919050565b600067ffffffffffffffff8211156114025761140261136a565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600061144161143c846113e8565b611399565b905082815283838301111561145557600080fd5b828260208301376000602084830101529392505050565b600082601f83011261147d57600080fd5b6104f58383356020850161142e565b6000806040838503121561149f57600080fd5b82356114aa816111d7565b9150602083013567ffffffffffffffff8111156114c657600080fd5b6114d28582860161146c565b9150509250929050565b600080604083850312156114ef57600080fd5b82356114fa816111d7565b915060208301356003811061135f57600080fd5b60008060006060848603121561152357600080fd5b833561152e816111d7565b9250602084013561153e816111d7565b9150604084013567ffffffffffffffff81111561155a57600080fd5b8401601f8101861361156b57600080fd5b61157a8682356020840161142e565b9150509250925092565b6000806040838503121561159757600080fd5b823567ffffffffffffffff8111156115ae57600080fd5b6115ba8582860161146c565b925050602083013561135f816111d7565b6000602082840312156115dd57600080fd5b81516104f5816111d7565b600181811c908216806115fc57607f821691505b602082108103610665577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000602080835260008454611649816115e8565b8084870152604060018084166000811461166a57600181146116a2576116d0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a010195506116d0565b896000528660002060005b858110156116c85781548b82018601529083019088016116ad565b8a0184019650505b509398975050505050505050565b601f8211156108c757600081815260208120601f850160051c810160208610156117055750805b601f850160051c820191505b81811015610eac57828155600101611711565b815167ffffffffffffffff81111561173e5761173e61136a565b6117528161174c84546115e8565b846116de565b602080601f8311600181146117a5576000841561176f5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610eac565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156117f2578886015182559484019460019091019084016117d3565b508582101561182e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061186d6040830184611264565b949350505050565b60006020828403121561188757600080fd5b815167ffffffffffffffff81111561189e57600080fd5b8201601f810184136118af57600080fd5b80516118bd61143c826113e8565b8181528560208385010111156118d257600080fd5b6118e3826020830160208601611238565b95945050505050565b600082516118fe818460208701611238565b9190910192915050565b60408152600061191b6040830185611264565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfea164736f6c634300080f000a0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "deployedCode": "0x60806040526004361061010e5760003560e01c8063860f7cda116100a557806399a88ec411610074578063b794726211610059578063b794726214610329578063f2fde38b14610364578063f3b7dead1461038457600080fd5b806399a88ec4146102e95780639b2ea4bd1461030957600080fd5b8063860f7cda1461026b5780638d52d4a01461028b5780638da5cb5b146102ab5780639623609d146102d657600080fd5b80633ab76e9f116100e15780633ab76e9f146101cc5780636bd9f516146101f9578063715018a6146102365780637eff275e1461024b57600080fd5b80630652b57a1461011357806307c8f7b014610135578063204e1c7a14610155578063238181ae1461019f575b600080fd5b34801561011f57600080fd5b5061013361012e3660046111f9565b6103a4565b005b34801561014157600080fd5b50610133610150366004611216565b6103f3565b34801561016157600080fd5b506101756101703660046111f9565b610445565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101ab57600080fd5b506101bf6101ba3660046111f9565b61066b565b60405161019691906112ae565b3480156101d857600080fd5b506003546101759073ffffffffffffffffffffffffffffffffffffffff1681565b34801561020557600080fd5b506102296102143660046111f9565b60016020526000908152604090205460ff1681565b60405161019691906112f0565b34801561024257600080fd5b50610133610705565b34801561025757600080fd5b50610133610266366004611331565b610719565b34801561027757600080fd5b5061013361028636600461148c565b6108cc565b34801561029757600080fd5b506101336102a63660046114dc565b610903565b3480156102b757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610175565b6101336102e436600461150e565b610977565b3480156102f557600080fd5b50610133610304366004611331565b610b8e565b34801561031557600080fd5b50610133610324366004611584565b610e1e565b34801561033557600080fd5b5060035474010000000000000000000000000000000000000000900460ff166040519015158152602001610196565b34801561037057600080fd5b5061013361037f3660046111f9565b610eb4565b34801561039057600080fd5b5061017561039f3660046111f9565b610f6b565b6103ac6110e1565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6103fb6110e1565b6003805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610481576104816112c1565b036104fc578273ffffffffffffffffffffffffffffffffffffffff16635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f591906115cb565b9392505050565b6001816002811115610510576105106112c1565b03610560578273ffffffffffffffffffffffffffffffffffffffff1663aaf10f426040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6002816002811115610574576105746112c1565b036105fe5760035473ffffffffffffffffffffffffffffffffffffffff8481166000908152600260205260409081902090517fbf40fac1000000000000000000000000000000000000000000000000000000008152919092169163bf40fac1916105e19190600401611635565b602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f50726f787941646d696e3a20756e6b6e6f776e2070726f78792074797065000060448201526064015b60405180910390fd5b50919050565b60026020526000908152604090208054610684906115e8565b80601f01602080910402602001604051908101604052809291908181526020018280546106b0906115e8565b80156106fd5780601f106106d2576101008083540402835291602001916106fd565b820191906000526020600020905b8154815290600101906020018083116106e057829003601f168201915b505050505081565b61070d6110e1565b6107176000611162565b565b6107216110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff169081600281111561075d5761075d6112c1565b036107e9576040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690638f283970906024015b600060405180830381600087803b1580156107cc57600080fd5b505af11580156107e0573d6000803e3d6000fd5b50505050505050565b60018160028111156107fd576107fd6112c1565b03610856576040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528416906313af4035906024016107b2565b600281600281111561086a5761086a6112c1565b036105fe576003546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301529091169063f2fde38b906024016107b2565b505050565b6108d46110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090206108c78282611724565b61090b6110e1565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600160208190526040909120805483927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091169083600281111561096e5761096e6112c1565b02179055505050565b61097f6110e1565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604081205460ff16908160028111156109bb576109bb6112c1565b03610a81576040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851690634f1ef286903490610a16908790879060040161183e565b60006040518083038185885af1158015610a34573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610a7b9190810190611875565b50610b88565b610a8b8484610b8e565b60008473ffffffffffffffffffffffffffffffffffffffff163484604051610ab391906118ec565b60006040518083038185875af1925050503d8060008114610af0576040519150601f19603f3d011682016040523d82523d6000602084013e610af5565b606091505b5050905080610b86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f50726f787941646d696e3a2063616c6c20746f2070726f78792061667465722060448201527f75706772616465206661696c6564000000000000000000000000000000000000606482015260840161065c565b505b50505050565b610b966110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff1690816002811115610bd257610bd26112c1565b03610c2b576040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690633659cfe6906024016107b2565b6001816002811115610c3f57610c3f6112c1565b03610cbe576040517f9b0b0fda0000000000000000000000000000000000000000000000000000000081527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152841690639b0b0fda906044016107b2565b6002816002811115610cd257610cd26112c1565b03610e165773ffffffffffffffffffffffffffffffffffffffff831660009081526002602052604081208054610d07906115e8565b80601f0160208091040260200160405190810160405280929190818152602001828054610d33906115e8565b8015610d805780601f10610d5557610100808354040283529160200191610d80565b820191906000526020600020905b815481529060010190602001808311610d6357829003601f168201915b50506003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815294955073ffffffffffffffffffffffffffffffffffffffff1693639b2ea4bd9350610dde92508591508790600401611908565b600060405180830381600087803b158015610df857600080fd5b505af1158015610e0c573d6000803e3d6000fd5b5050505050505050565b6108c7611940565b610e266110e1565b6003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690639b2ea4bd90610e7e9085908590600401611908565b600060405180830381600087803b158015610e9857600080fd5b505af1158015610eac573d6000803e3d6000fd5b505050505050565b610ebc6110e1565b73ffffffffffffffffffffffffffffffffffffffff8116610f5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161065c565b610f6881611162565b50565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610fa757610fa76112c1565b03610ff7578273ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600181600281111561100b5761100b6112c1565b0361105b578273ffffffffffffffffffffffffffffffffffffffff1663893d20e86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600281600281111561106f5761106f6112c1565b036105fe57600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314610717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161065c565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f6857600080fd5b60006020828403121561120b57600080fd5b81356104f5816111d7565b60006020828403121561122857600080fd5b813580151581146104f557600080fd5b60005b8381101561125357818101518382015260200161123b565b83811115610b885750506000910152565b6000815180845261127c816020860160208601611238565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104f56020830184611264565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b602081016003831061132b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806040838503121561134457600080fd5b823561134f816111d7565b9150602083013561135f816111d7565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156113e0576113e061136a565b604052919050565b600067ffffffffffffffff8211156114025761140261136a565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600061144161143c846113e8565b611399565b905082815283838301111561145557600080fd5b828260208301376000602084830101529392505050565b600082601f83011261147d57600080fd5b6104f58383356020850161142e565b6000806040838503121561149f57600080fd5b82356114aa816111d7565b9150602083013567ffffffffffffffff8111156114c657600080fd5b6114d28582860161146c565b9150509250929050565b600080604083850312156114ef57600080fd5b82356114fa816111d7565b915060208301356003811061135f57600080fd5b60008060006060848603121561152357600080fd5b833561152e816111d7565b9250602084013561153e816111d7565b9150604084013567ffffffffffffffff81111561155a57600080fd5b8401601f8101861361156b57600080fd5b61157a8682356020840161142e565b9150509250925092565b6000806040838503121561159757600080fd5b823567ffffffffffffffff8111156115ae57600080fd5b6115ba8582860161146c565b925050602083013561135f816111d7565b6000602082840312156115dd57600080fd5b81516104f5816111d7565b600181811c908216806115fc57607f821691505b602082108103610665577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000602080835260008454611649816115e8565b8084870152604060018084166000811461166a57600181146116a2576116d0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a010195506116d0565b896000528660002060005b858110156116c85781548b82018601529083019088016116ad565b8a0184019650505b509398975050505050505050565b601f8211156108c757600081815260208120601f850160051c810160208610156117055750805b601f850160051c820191505b81811015610eac57828155600101611711565b815167ffffffffffffffff81111561173e5761173e61136a565b6117528161174c84546115e8565b846116de565b602080601f8311600181146117a5576000841561176f5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610eac565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156117f2578886015182559484019460019091019084016117d3565b508582101561182e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061186d6040830184611264565b949350505050565b60006020828403121561188757600080fd5b815167ffffffffffffffff81111561189e57600080fd5b8201601f810184136118af57600080fd5b80516118bd61143c826113e8565b8181528560208385010111156118d257600080fd5b6118e3826020830160208601611238565b95945050505050565b600082516118fe818460208701611238565b9190910192915050565b60408152600061191b6040830185611264565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": true, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": true, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x3ab76e9f", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x0652b57a00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": true, - "newValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x3ab76e9f", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "previousValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf2fde38b0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": true, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610300000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "deployedCode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": true, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x638627e586f5e36fe67a77519503a7c6da22f92b150d3c6055fd40bdcfe9ffd160806040523480156200001157600080fd5b506200001f60008062000025565b62000361565b600054610100900460ff1615808015620000465750600054600160ff909116105b8062000076575062000063306200019460201b620005fd1760201c565b15801562000076575060005460ff166001145b620000de5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff19166001179055801562000102576000805461ff0019166101001790555b6200010d83620001a3565b81156200014857604080518082019091526012815271125b9a5d1a585b1a5e995c881c185d5cd95960721b6020820152620001489062000248565b80156200018f576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03163b151590565b620001e9620001d460017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69620002cf565b60001b82620002cb60201b620006191760201c565b6000604080516001600160a01b03841660208201527f7b743789cff01dafdeae47739925425aab5dfd02d0c8229e4a508bcd2b9f42bb910160408051601f19818403018152908290526200023d9162000345565b60405180910390a250565b6200028f6200027960017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7620002cf565b60001b6001620002cb60201b620006191760201c565b7fc32e6d5d6d1de257f64eac19ddb1f700ba13527983849c9486b1ab007ea2838181604051620002c0919062000345565b60405180910390a150565b9055565b600082821015620002f057634e487b7160e01b600052601160045260246000fd5b500390565b6000815180845260005b818110156200031d57602081850181015186830182015201620002ff565b8181111562000330576000602083870101525b50601f01601f19169290920160200192915050565b6020815260006200035a6020830184620002f5565b9392505050565b61096b80620003716000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80635c975abb1161005b5780635c975abb146101255780636da663551461013d5780637fbf7b6a14610150578063c23a451a1461016657600080fd5b80633f4ba83a1461008d578063400ada7514610097578063452a9320146100aa57806354fd4d50146100dc575b600080fd5b61009561016e565b005b6100956100a5366004610746565b610294565b6100b261046d565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101186040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100d39190610808565b61012d6104a6565b60405190151581526020016100d3565b61009561014b366004610851565b6104d6565b6101586105a4565b6040519081526020016100d3565b6101586105d2565b61017661046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e20756e706175736500000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61026961026360017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60009055565b6040517fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d1693390600090a1565b600054610100900460ff16158080156102b45750600054600160ff909116105b806102ce5750303b1580156102ce575060005460ff166001145b61035a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161022c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156103b857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6103c18361061d565b8115610405576104056040518060400160405280601281526020017f496e697469616c697a65722070617573656400000000000000000000000000008152506106d8565b801561046857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006104a161049d60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b5490565b905090565b60006104a161049d60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b6104de61046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610598576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e2070617573650000000000000000000000000000000000000000000000606482015260840161022c565b6105a1816106d8565b50565b6105cf60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b81565b6105cf60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b61065061064b60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b829055565b60006040805173ffffffffffffffffffffffffffffffffffffffff841660208201527f7b743789cff01dafdeae47739925425aab5dfd02d0c8229e4a508bcd2b9f42bb9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526106cd91610808565b60405180910390a250565b61070c61070660017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60019055565b7fc32e6d5d6d1de257f64eac19ddb1f700ba13527983849c9486b1ab007ea283818160405161073b9190610808565b60405180910390a150565b6000806040838503121561075957600080fd5b823573ffffffffffffffffffffffffffffffffffffffff8116811461077d57600080fd5b91506020830135801515811461079257600080fd5b809150509250929050565b6000815180845260005b818110156107c3576020818501810151868301820152016107a7565b818111156107d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061081b602083018461079d565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561086357600080fd5b813567ffffffffffffffff8082111561087b57600080fd5b818401915084601f83011261088f57600080fd5b8135818111156108a1576108a1610822565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108e7576108e7610822565b8160405282815287602084870101111561090057600080fd5b826020860160208301376000928101602001929092525095945050505050565b600082821015610959577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "account": "0x068E44eB31e111028c41598E4535be7468674D0A", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x60806040523480156200001157600080fd5b506200001f60008062000025565b62000361565b600054610100900460ff1615808015620000465750600054600160ff909116105b8062000076575062000063306200019460201b620005fd1760201c565b15801562000076575060005460ff166001145b620000de5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff19166001179055801562000102576000805461ff0019166101001790555b6200010d83620001a3565b81156200014857604080518082019091526012815271125b9a5d1a585b1a5e995c881c185d5cd95960721b6020820152620001489062000248565b80156200018f576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03163b151590565b620001e9620001d460017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69620002cf565b60001b82620002cb60201b620006191760201c565b6000604080516001600160a01b03841660208201527f7b743789cff01dafdeae47739925425aab5dfd02d0c8229e4a508bcd2b9f42bb910160408051601f19818403018152908290526200023d9162000345565b60405180910390a250565b6200028f6200027960017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7620002cf565b60001b6001620002cb60201b620006191760201c565b7fc32e6d5d6d1de257f64eac19ddb1f700ba13527983849c9486b1ab007ea2838181604051620002c0919062000345565b60405180910390a150565b9055565b600082821015620002f057634e487b7160e01b600052601160045260246000fd5b500390565b6000815180845260005b818110156200031d57602081850181015186830182015201620002ff565b8181111562000330576000602083870101525b50601f01601f19169290920160200192915050565b6020815260006200035a6020830184620002f5565b9392505050565b61096b80620003716000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80635c975abb1161005b5780635c975abb146101255780636da663551461013d5780637fbf7b6a14610150578063c23a451a1461016657600080fd5b80633f4ba83a1461008d578063400ada7514610097578063452a9320146100aa57806354fd4d50146100dc575b600080fd5b61009561016e565b005b6100956100a5366004610746565b610294565b6100b261046d565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101186040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100d39190610808565b61012d6104a6565b60405190151581526020016100d3565b61009561014b366004610851565b6104d6565b6101586105a4565b6040519081526020016100d3565b6101586105d2565b61017661046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e20756e706175736500000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61026961026360017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60009055565b6040517fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d1693390600090a1565b600054610100900460ff16158080156102b45750600054600160ff909116105b806102ce5750303b1580156102ce575060005460ff166001145b61035a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161022c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156103b857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6103c18361061d565b8115610405576104056040518060400160405280601281526020017f496e697469616c697a65722070617573656400000000000000000000000000008152506106d8565b801561046857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006104a161049d60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b5490565b905090565b60006104a161049d60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b6104de61046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610598576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e2070617573650000000000000000000000000000000000000000000000606482015260840161022c565b6105a1816106d8565b50565b6105cf60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b81565b6105cf60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b61065061064b60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b829055565b60006040805173ffffffffffffffffffffffffffffffffffffffff841660208201527f7b743789cff01dafdeae47739925425aab5dfd02d0c8229e4a508bcd2b9f42bb9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526106cd91610808565b60405180910390a250565b61070c61070660017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60019055565b7fc32e6d5d6d1de257f64eac19ddb1f700ba13527983849c9486b1ab007ea283818160405161073b9190610808565b60405180910390a150565b6000806040838503121561075957600080fd5b823573ffffffffffffffffffffffffffffffffffffffff8116811461077d57600080fd5b91506020830135801515811461079257600080fd5b809150509250929050565b6000815180845260005b818110156107c3576020818501810151868301820152016107a7565b818111156107d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061081b602083018461079d565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561086357600080fd5b813567ffffffffffffffff8082111561087b57600080fd5b818401915084601f83011261088f57600080fd5b8135818111156108a1576108a1610822565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108e7576108e7610822565b8160405282815287602084870101111561090057600080fd5b826020860160208301376000928101602001929092525095945050505050565b600082821015610959577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a", - "deployedCode": "0x608060405234801561001057600080fd5b50600436106100885760003560e01c80635c975abb1161005b5780635c975abb146101255780636da663551461013d5780637fbf7b6a14610150578063c23a451a1461016657600080fd5b80633f4ba83a1461008d578063400ada7514610097578063452a9320146100aa57806354fd4d50146100dc575b600080fd5b61009561016e565b005b6100956100a5366004610746565b610294565b6100b261046d565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101186040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100d39190610808565b61012d6104a6565b60405190151581526020016100d3565b61009561014b366004610851565b6104d6565b6101586105a4565b6040519081526020016100d3565b6101586105d2565b61017661046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e20756e706175736500000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61026961026360017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60009055565b6040517fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d1693390600090a1565b600054610100900460ff16158080156102b45750600054600160ff909116105b806102ce5750303b1580156102ce575060005460ff166001145b61035a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161022c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156103b857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6103c18361061d565b8115610405576104056040518060400160405280601281526020017f496e697469616c697a65722070617573656400000000000000000000000000008152506106d8565b801561046857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006104a161049d60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b5490565b905090565b60006104a161049d60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b6104de61046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610598576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e2070617573650000000000000000000000000000000000000000000000606482015260840161022c565b6105a1816106d8565b50565b6105cf60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b81565b6105cf60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b61065061064b60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b829055565b60006040805173ffffffffffffffffffffffffffffffffffffffff841660208201527f7b743789cff01dafdeae47739925425aab5dfd02d0c8229e4a508bcd2b9f42bb9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526106cd91610808565b60405180910390a250565b61070c61070660017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60019055565b7fc32e6d5d6d1de257f64eac19ddb1f700ba13527983849c9486b1ab007ea283818160405161073b9190610808565b60405180910390a150565b6000806040838503121561075957600080fd5b823573ffffffffffffffffffffffffffffffffffffffff8116811461077d57600080fd5b91506020830135801515811461079257600080fd5b809150509250929050565b6000815180845260005b818110156107c3576020818501810151868301820152016107a7565b818111156107d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061081b602083018461079d565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561086357600080fd5b813567ffffffffffffffff8082111561087b57600080fd5b818401915084601f83011261088f57600080fd5b8135818111156108a1576108a1610822565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108e7576108e7610822565b8160405282815287602084870101111561090057600080fd5b826020860160208301376000928101602001929092525095945050505050565b600082821015610959577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x068E44eB31e111028c41598E4535be7468674D0A", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x068E44eB31e111028c41598E4535be7468674D0A", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x068E44eB31e111028c41598E4535be7468674D0A", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x068E44eB31e111028c41598E4535be7468674D0A", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x068E44eB31e111028c41598E4535be7468674D0A", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x068E44eB31e111028c41598E4535be7468674D0A", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x068E44eB31e111028c41598E4535be7468674D0A", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe68" - }, - { - "account": "0x068E44eB31e111028c41598E4535be7468674D0A", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x068E44eB31e111028c41598E4535be7468674D0A", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x068E44eB31e111028c41598E4535be7468674D0A", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x452a9320", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x068E44eB31e111028c41598E4535be7468674D0A", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe68" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xfa60f9b2", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000f" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000e49623609d0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044400ada750000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000e49623609d0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044400ada750000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" - } - ], - "value": 0 - }, - { - "accessor": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9623609d0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044400ada750000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x6bd95c70b8833b95e56b323d763e7bec801ddd693a6478a9d9eb91508b6b5689" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x4f1ef286000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000044400ada750000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": true, - "newValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x068E44eB31e111028c41598E4535be7468674D0A", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x400ada750000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc0000000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": true, - "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe68" - }, - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xfa60f9b2", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000f" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x452a9320", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": false, - "newValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", - "previousValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x068E44eB31e111028c41598E4535be7468674D0A", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x452a9320", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": false, - "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "reverted": false, - "slot": "0xd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe68" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x5c975abb", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": false, - "newValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", - "previousValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x068E44eB31e111028c41598E4535be7468674D0A", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x5c975abb", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b6" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610300000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "deployedCode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": true, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x638627e586f5e36fe67a77519503a7c6da22f92b150d3c6055fd40bdcfe9ffd160806040523480156200001157600080fd5b506200002261dead60008062000028565b6200051c565b600054610100900460ff1615808015620000495750600054600160ff909116105b8062000079575062000066306200017e60201b6200053f1760201c565b15801562000079575060005460ff166001145b620000e25760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000106576000805461ff0019166101001790555b620001106200018d565b6200011b84620001f5565b620001268362000274565b620001318262000324565b801562000178576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6001600160a01b03163b151590565b600054610100900460ff16620001e95760405162461bcd60e51b815260206004820152602b602482015260008051602062000f4f83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000d9565b620001f362000385565b565b620001ff620003ec565b6001600160a01b038116620002665760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401620000d9565b620002718162000448565b50565b620002ba620002a560017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16200049e565b60001b826200049a60201b6200055b1760201c565b600081604051602001620002d091815260200190565b60408051601f19818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051620003189190620004c4565b60405180910390a35050565b62000355620002a560017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6200049e565b6000816040516020016200036b91815260200190565b60408051601f1981840301815291905290506001620002e5565b600054610100900460ff16620003e15760405162461bcd60e51b815260206004820152602b602482015260008051602062000f4f83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000d9565b620001f33362000448565b6033546001600160a01b03163314620001f35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620000d9565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b9055565b600082821015620004bf57634e487b7160e01b600052601160045260246000fd5b500390565b600060208083528351808285015260005b81811015620004f357858101830151858201604001528201620004d5565b8181111562000506576000604083870101525b50601f01601f1916929092016040019392505050565b610a23806200052c6000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b8578063f7d12760146101cb578063ffa1ad74146101d357600080fd5b80638da5cb5b14610180578063d798b1ac146101a8578063dc8452cd146101b057600080fd5b80635fd579af116100b25780635fd579af14610152578063715018a6146101655780637a1ac61e1461016d57600080fd5b80630457d6f2146100d9578063206a8300146100ee57806354fd4d5014610109575b600080fd5b6100ec6100e73660046108c3565b6101db565b005b6100f66101ef565b6040519081526020015b60405180910390f35b6101456040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516101009190610947565b6100ec6101603660046108c3565b61021d565b6100ec61022e565b6100ec61017b36600461098a565b610242565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b6100f66103f7565b6100f6610430565b6100ec6101c63660046109bd565b610460565b6100f6610514565b6100f6600081565b6101e361055f565b6101ec816105e0565b50565b61021a60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b81565b61022561055f565b6101ec81610698565b61023661055f565b6102406000610712565b565b600054610100900460ff16158080156102625750600054600160ff909116105b8061027c5750303b15801561027c575060005460ff166001145b61030d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561036b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610373610789565b61037c84610460565b610385836105e0565b61038e82610698565b80156103f157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b600061042b61042760017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b5490565b905090565b600061042b61042760017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b61046861055f565b73ffffffffffffffffffffffffffffffffffffffff811661050b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610304565b6101ec81610712565b61021a60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610304565b61061361060e60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b829055565b60008160405160200161062891815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be8360405161068c9190610947565b60405180910390a35050565b6106c661060e60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b6000816040516020016106db91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600161065b565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16610820576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b610240600054610100900460ff166108ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b61024033610712565b6000602082840312156108d557600080fd5b5035919050565b6000815180845260005b81811015610902576020818501810151868301820152016108e6565b81811115610914576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061095a60208301846108dc565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461098557600080fd5b919050565b60008060006060848603121561099f57600080fd5b6109a884610961565b95602085013595506040909401359392505050565b6000602082840312156109cf57600080fd5b61095a82610961565b600082821015610a11577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x60806040523480156200001157600080fd5b506200002261dead60008062000028565b6200051c565b600054610100900460ff1615808015620000495750600054600160ff909116105b8062000079575062000066306200017e60201b6200053f1760201c565b15801562000079575060005460ff166001145b620000e25760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000106576000805461ff0019166101001790555b620001106200018d565b6200011b84620001f5565b620001268362000274565b620001318262000324565b801562000178576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6001600160a01b03163b151590565b600054610100900460ff16620001e95760405162461bcd60e51b815260206004820152602b602482015260008051602062000f4f83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000d9565b620001f362000385565b565b620001ff620003ec565b6001600160a01b038116620002665760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401620000d9565b620002718162000448565b50565b620002ba620002a560017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16200049e565b60001b826200049a60201b6200055b1760201c565b600081604051602001620002d091815260200190565b60408051601f19818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051620003189190620004c4565b60405180910390a35050565b62000355620002a560017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6200049e565b6000816040516020016200036b91815260200190565b60408051601f1981840301815291905290506001620002e5565b600054610100900460ff16620003e15760405162461bcd60e51b815260206004820152602b602482015260008051602062000f4f83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000d9565b620001f33362000448565b6033546001600160a01b03163314620001f35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620000d9565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b9055565b600082821015620004bf57634e487b7160e01b600052601160045260246000fd5b500390565b600060208083528351808285015260005b81811015620004f357858101830151858201604001528201620004d5565b8181111562000506576000604083870101525b50601f01601f1916929092016040019392505050565b610a23806200052c6000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b8578063f7d12760146101cb578063ffa1ad74146101d357600080fd5b80638da5cb5b14610180578063d798b1ac146101a8578063dc8452cd146101b057600080fd5b80635fd579af116100b25780635fd579af14610152578063715018a6146101655780637a1ac61e1461016d57600080fd5b80630457d6f2146100d9578063206a8300146100ee57806354fd4d5014610109575b600080fd5b6100ec6100e73660046108c3565b6101db565b005b6100f66101ef565b6040519081526020015b60405180910390f35b6101456040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516101009190610947565b6100ec6101603660046108c3565b61021d565b6100ec61022e565b6100ec61017b36600461098a565b610242565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b6100f66103f7565b6100f6610430565b6100ec6101c63660046109bd565b610460565b6100f6610514565b6100f6600081565b6101e361055f565b6101ec816105e0565b50565b61021a60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b81565b61022561055f565b6101ec81610698565b61023661055f565b6102406000610712565b565b600054610100900460ff16158080156102625750600054600160ff909116105b8061027c5750303b15801561027c575060005460ff166001145b61030d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561036b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610373610789565b61037c84610460565b610385836105e0565b61038e82610698565b80156103f157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b600061042b61042760017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b5490565b905090565b600061042b61042760017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b61046861055f565b73ffffffffffffffffffffffffffffffffffffffff811661050b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610304565b6101ec81610712565b61021a60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610304565b61061361060e60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b829055565b60008160405160200161062891815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be8360405161068c9190610947565b60405180910390a35050565b6106c661060e60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b6000816040516020016106db91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600161065b565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16610820576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b610240600054610100900460ff166108ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b61024033610712565b6000602082840312156108d557600080fd5b5035919050565b6000815180845260005b81811015610902576020818501810151868301820152016108e6565b81811115610914576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061095a60208301846108dc565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461098557600080fd5b919050565b60008060006060848603121561099f57600080fd5b6109a884610961565b95602085013595506040909401359392505050565b6000602082840312156109cf57600080fd5b61095a82610961565b600082821015610a11577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", - "deployedCode": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b8578063f7d12760146101cb578063ffa1ad74146101d357600080fd5b80638da5cb5b14610180578063d798b1ac146101a8578063dc8452cd146101b057600080fd5b80635fd579af116100b25780635fd579af14610152578063715018a6146101655780637a1ac61e1461016d57600080fd5b80630457d6f2146100d9578063206a8300146100ee57806354fd4d5014610109575b600080fd5b6100ec6100e73660046108c3565b6101db565b005b6100f66101ef565b6040519081526020015b60405180910390f35b6101456040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516101009190610947565b6100ec6101603660046108c3565b61021d565b6100ec61022e565b6100ec61017b36600461098a565b610242565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b6100f66103f7565b6100f6610430565b6100ec6101c63660046109bd565b610460565b6100f6610514565b6100f6600081565b6101e361055f565b6101ec816105e0565b50565b61021a60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b81565b61022561055f565b6101ec81610698565b61023661055f565b6102406000610712565b565b600054610100900460ff16158080156102625750600054600160ff909116105b8061027c5750303b15801561027c575060005460ff166001145b61030d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561036b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610373610789565b61037c84610460565b610385836105e0565b61038e82610698565b80156103f157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b600061042b61042760017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b5490565b905090565b600061042b61042760017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b61046861055f565b73ffffffffffffffffffffffffffffffffffffffff811661050b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610304565b6101ec81610712565b61021a60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610304565b61061361060e60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b829055565b60008160405160200161062891815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be8360405161068c9190610947565b60405180910390a35050565b6106c661060e60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b6000816040516020016106db91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600161065b565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16610820576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b610240600054610100900460ff166108ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b61024033610712565b6000602082840312156108d557600080fd5b5035919050565b6000815180845260005b81811015610902576020818501810151868301820152016108e6565b81811115610914576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061095a60208301846108dc565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461098557600080fd5b919050565b60008060006060848603121561099f57600080fd5b6109a884610961565b95602085013595506040909401359392505050565b6000602082840312156109cf57600080fd5b61095a82610961565b600082821015610a11577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "isWrite": true, - "newValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "isWrite": false, - "newValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "previousValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "isWrite": false, - "newValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "previousValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "isWrite": true, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", - "previousValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace0" - }, - { - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1a" - }, - { - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000dead", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xdc8452cd", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace0" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xd798b1ac", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1a" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xd2354f20", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000e" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x38c27159", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000003f" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x67cef446", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000040" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000001049623609d0000000000000000000000004c52a6277b1b84121b3072c0c92b6be0b7cc10f1000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000647a1ac61e0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000001049623609d0000000000000000000000004c52a6277b1b84121b3072c0c92b6be0b7cc10f1000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000647a1ac61e0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" - } - ], - "value": 0 - }, - { - "accessor": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9623609d0000000000000000000000004c52a6277b1b84121b3072c0c92b6be0b7cc10f1000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000647a1ac61e0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x72d7aa813380382c369363d977a28b043ac6e1983f989087faaa96aa4d8d4c12" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x4f1ef286000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000647a1ac61e0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": true, - "newValue": "0x000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x7a1ac61e0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": true, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": true, - "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace0" - }, - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1a" - }, - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": false, - "newValue": "0x000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f", - "previousValue": "0x000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xd2354f20", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000e" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": false, - "newValue": "0x000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f", - "previousValue": "0x000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": false, - "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x38c27159", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000003f" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xdc8452cd", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": false, - "newValue": "0x000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f", - "previousValue": "0x000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xdc8452cd", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace0" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x67cef446", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000040" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xd798b1ac", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": false, - "newValue": "0x000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f", - "previousValue": "0x000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xd798b1ac", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1a" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x08e0e2bb", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000044" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610300000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "deployedCode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": true, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610300000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "deployedCode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x608060405234801561001057600080fd5b50604051610a44380380610a4483398101604081905261002f9161005d565b610057817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b5061008d565b60006020828403121561006f57600080fd5b81516001600160a01b038116811461008657600080fd5b9392505050565b6109a88061009c6000396000f3fe60806040526004361061005e5760003560e01c8063893d20e811610043578063893d20e8146100b55780639b0b0fda146100f3578063aaf10f42146101135761006d565b806313af4035146100755780636c5d4ad0146100955761006d565b3661006d5761006b610128565b005b61006b610128565b34801561008157600080fd5b5061006b6100903660046107a2565b6103cb565b3480156100a157600080fd5b5061006b6100b036600461080e565b61045c565b3480156100c157600080fd5b506100ca610611565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ff57600080fd5b5061006b61010e3660046108dd565b6106a8565b34801561011f57600080fd5b506100ca610716565b60006101527fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb7947262000000000000000000000000000000000000000000000000000000001790529051919250600091829173ffffffffffffffffffffffffffffffffffffffff8516916101d4919061093a565b600060405180830381855afa9150503d806000811461020f576040519150601f19603f3d011682016040523d82523d6000602084013e610214565b606091505b5091509150818015610227575080516020145b156102d9576000818060200190518101906102429190610946565b905080156102d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c314368756753706c61736850726f78793a2073797374656d2069732063757260448201527f72656e746c79206265696e67207570677261646564000000000000000000000060648201526084015b60405180910390fd5b505b60006103037f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff81166103a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4c314368756753706c61736850726f78793a20696d706c656d656e746174696f60448201527f6e206973206e6f7420736574207965740000000000000000000000000000000060648201526084016102ce565b3660008037600080366000845af43d6000803e806103c5573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610424575033155b1561045457610451817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b50565b610451610128565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806104b5575033155b156104545760006104e47f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b9050803f82516020840120036104f8575050565b60405160009061052e907f600d380380600d6000396000f30000000000000000000000000000000000000090859060200161095f565b604051602081830303815290604052905060008151602083016000f084516020860120909150813f146105e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4c314368756753706c61736850726f78793a20636f646520776173206e6f742060448201527f636f72726563746c79206465706c6f796564000000000000000000000000000060648201526084016102ce565b61060b817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b50505050565b600061063b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610672575033155b1561069d57507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6106a5610128565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610701575033155b1561070a579055565b610712610128565b5050565b60006107407fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610777575033155b1561069d57507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6000602082840312156107b457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146107d857600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561082057600080fd5b813567ffffffffffffffff8082111561083857600080fd5b818401915084601f83011261084c57600080fd5b81358181111561085e5761085e6107df565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108a4576108a46107df565b816040528281528760208487010111156108bd57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600080604083850312156108f057600080fd5b50508035926020909101359150565b6000815160005b818110156109205760208185018101518683015201610906565b8181111561092f576000828601525b509290920192915050565b60006107d882846108ff565b60006020828403121561095857600080fd5b5051919050565b7fffffffffffffffffffffffffff00000000000000000000000000000000000000831681526000610993600d8301846108ff565b94935050505056fea164736f6c634300080f000a00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "deployedCode": "0x60806040526004361061005e5760003560e01c8063893d20e811610043578063893d20e8146100b55780639b0b0fda146100f3578063aaf10f42146101135761006d565b806313af4035146100755780636c5d4ad0146100955761006d565b3661006d5761006b610128565b005b61006b610128565b34801561008157600080fd5b5061006b6100903660046107a2565b6103cb565b3480156100a157600080fd5b5061006b6100b036600461080e565b61045c565b3480156100c157600080fd5b506100ca610611565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ff57600080fd5b5061006b61010e3660046108dd565b6106a8565b34801561011f57600080fd5b506100ca610716565b60006101527fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb7947262000000000000000000000000000000000000000000000000000000001790529051919250600091829173ffffffffffffffffffffffffffffffffffffffff8516916101d4919061093a565b600060405180830381855afa9150503d806000811461020f576040519150601f19603f3d011682016040523d82523d6000602084013e610214565b606091505b5091509150818015610227575080516020145b156102d9576000818060200190518101906102429190610946565b905080156102d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c314368756753706c61736850726f78793a2073797374656d2069732063757260448201527f72656e746c79206265696e67207570677261646564000000000000000000000060648201526084015b60405180910390fd5b505b60006103037f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff81166103a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4c314368756753706c61736850726f78793a20696d706c656d656e746174696f60448201527f6e206973206e6f7420736574207965740000000000000000000000000000000060648201526084016102ce565b3660008037600080366000845af43d6000803e806103c5573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610424575033155b1561045457610451817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b50565b610451610128565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806104b5575033155b156104545760006104e47f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b9050803f82516020840120036104f8575050565b60405160009061052e907f600d380380600d6000396000f30000000000000000000000000000000000000090859060200161095f565b604051602081830303815290604052905060008151602083016000f084516020860120909150813f146105e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4c314368756753706c61736850726f78793a20636f646520776173206e6f742060448201527f636f72726563746c79206465706c6f796564000000000000000000000000000060648201526084016102ce565b61060b817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b50505050565b600061063b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610672575033155b1561069d57507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6106a5610128565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610701575033155b1561070a579055565b610712610128565b5050565b60006107407fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610777575033155b1561069d57507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6000602082840312156107b457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146107d857600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561082057600080fd5b813567ffffffffffffffff8082111561083857600080fd5b818401915084601f83011261084c57600080fd5b81358181111561085e5761085e6107df565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108a4576108a46107df565b816040528281528760208487010111156108bd57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600080604083850312156108f057600080fd5b50508035926020909101359150565b6000815160005b818110156109205760208185018101518683015201610906565b8181111561092f576000828601525b509290920192915050565b60006107d882846108ff565b60006020828403121561095857600080fd5b5051919050565b7fffffffffffffffffffffffffff00000000000000000000000000000000000000831681526000610993600d8301846108ff565b94935050505056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": true, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x608060405234801561001057600080fd5b506040516105f03803806105f083398101604081905261002f91610088565b30600090815260016020908152604080832080546001600160a01b0319166001600160a01b03871617905590829052902061006a8282610203565b5050506102c2565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561009b57600080fd5b82516001600160a01b03811681146100b257600080fd5b602084810151919350906001600160401b03808211156100d157600080fd5b818601915086601f8301126100e557600080fd5b8151818111156100f7576100f7610072565b604051601f8201601f19908116603f0116810190838211818310171561011f5761011f610072565b81604052828152898684870101111561013757600080fd5b600093505b82841015610159578484018601518185018701529285019261013c565b8284111561016a5760008684830101525b8096505050505050509250929050565b600181811c9082168061018e57607f821691505b6020821081036101ae57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156101fe57600081815260208120601f850160051c810160208610156101db5750805b601f850160051c820191505b818110156101fa578281556001016101e7565b5050505b505050565b81516001600160401b0381111561021c5761021c610072565b6102308161022a845461017a565b846101b4565b602080601f831160018114610265576000841561024d5750858301515b600019600386901b1c1916600185901b1785556101fa565b600085815260208120601f198616915b8281101561029457888601518255948401946001909101908401610275565b50858210156102b25787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61031f806102d16000396000f3fe608060408181523060009081526001602090815282822054908290529181207fbf40fac1000000000000000000000000000000000000000000000000000000009093529173ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061006d9060846101e2565b602060405180830381865afa15801561008a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100ae91906102c5565b905073ffffffffffffffffffffffffffffffffffffffff8116610157576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f5265736f6c76656444656c656761746550726f78793a2074617267657420616460448201527f6472657373206d75737420626520696e697469616c697a656400000000000000606482015260840160405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff16600036604051610182929190610302565b600060405180830381855af49150503d80600081146101bd576040519150601f19603f3d011682016040523d82523d6000602084013e6101c2565b606091505b5090925090508115156001036101da57805160208201f35b805160208201fd5b600060208083526000845481600182811c91508083168061020457607f831692505b858310810361023a577f4e487b710000000000000000000000000000000000000000000000000000000085526022600452602485fd5b878601838152602001818015610257576001811461028b576102b6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616825284151560051b820196506102b6565b60008b81526020902060005b868110156102b057815484820152908501908901610297565b83019750505b50949998505050505050505050565b6000602082840312156102d757600080fd5b815173ffffffffffffffffffffffffffffffffffffffff811681146102fb57600080fd5b9392505050565b818382376000910190815291905056fea164736f6c634300080f000a00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c40000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000", - "deployedCode": "0x608060408181523060009081526001602090815282822054908290529181207fbf40fac1000000000000000000000000000000000000000000000000000000009093529173ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061006d9060846101e2565b602060405180830381865afa15801561008a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100ae91906102c5565b905073ffffffffffffffffffffffffffffffffffffffff8116610157576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f5265736f6c76656444656c656761746550726f78793a2074617267657420616460448201527f6472657373206d75737420626520696e697469616c697a656400000000000000606482015260840160405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff16600036604051610182929190610302565b600060405180830381855af49150503d80600081146101bd576040519150601f19603f3d011682016040523d82523d6000602084013e6101c2565b606091505b5090925090508115156001036101da57805160208201f35b805160208201fd5b600060208083526000845481600182811c91508083168061020457607f831692505b858310810361023a577f4e487b710000000000000000000000000000000000000000000000000000000085526022600452602485fd5b878601838152602001818015610257576001811461028b576102b6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616825284151560051b820196506102b6565b60008b81526020902060005b868110156102b057815484820152908501908901610297565b83019750505b50949998505050505050505050565b6000602082840312156102d757600080fd5b815173ffffffffffffffffffffffffffffffffffffffff811681146102fb57600080fd5b9392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x191cda7b5a8219e0cc3bb6c2b45be830e3ba520f78e119446a476c4147fcc284" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": true, - "newValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x191cda7b5a8219e0cc3bb6c2b45be830e3ba520f78e119446a476c4147fcc284" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x6822ddba83a78589c753bb747cf4919773ec1d36eeb0bb2a09d64b6d87adda0b" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": true, - "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x6822ddba83a78589c753bb747cf4919773ec1d36eeb0bb2a09d64b6d87adda0b" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610300000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "deployedCode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "isWrite": true, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610300000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "deployedCode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": true, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610300000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "deployedCode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": true, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610300000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "deployedCode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": true, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610300000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "deployedCode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": true, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610300000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "deployedCode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": true, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610300000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "deployedCode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": true, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf2fde38b00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "isWrite": true, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x638627e586f5e36fe67a77519503a7c6da22f92b150d3c6055fd40bdcfe9ffd160806040523480156200001157600080fd5b50620000206000808062000026565b6200028e565b600054600160a81b900460ff16158080156200004f57506000546001600160a01b90910460ff16105b806200008657506200006c30620001c860201b620015b71760201c565b158015620000865750600054600160a01b900460ff166001145b620000ef5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff60a01b1916600160a01b17905580156200011d576000805460ff60a81b1916600160a81b1790555b60fb80546001600160a01b038087166001600160a01b03199283161790925560fc805486841690831617905560fd80549285169290911691909117905562000179734200000000000000000000000000000000000007620001d7565b8015620001c2576000805460ff60a81b19169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6001600160a01b03163b151590565b600054600160a81b900460ff16620002465760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000e6565b60cc546001600160a01b03166200026c5760cc80546001600160a01b03191661dead1790555b60cf80546001600160a01b0319166001600160a01b0392909216919091179055565b6121a1806200029e6000396000f3fe60806040526004361061018b5760003560e01c80636425666b116100d6578063b1b1b2091161007f578063d764ad0b11610059578063d764ad0b1461049b578063db505d80146104ae578063ecc70428146104db57600080fd5b8063b1b1b2091461042b578063b28ade251461045b578063c0c53b8b1461047b57600080fd5b80638cbeeef2116100b05780638cbeeef2146102d05780639fce812c146103d0578063a4e7f8bd146103fb57600080fd5b80636425666b146103775780636e296e45146103a457806383a74074146103b957600080fd5b80633dbb202b1161013857806354fd4d501161011257806354fd4d50146102e65780635644cfdf1461033c5780635c975abb1461035257600080fd5b80633dbb202b146102935780633f827a5a146102a85780634c1d6a69146102d057600080fd5b80632828d7e8116101695780632828d7e81461022457806333d7e2bd1461023957806335e80ab31461026657600080fd5b8063028f85f7146101905780630c568498146101c35780630ff754ea146101d8575b600080fd5b34801561019c57600080fd5b506101a5601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101cf57600080fd5b506101a5603f81565b3480156101e457600080fd5b5060fc5473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ba565b34801561023057600080fd5b506101a5604081565b34801561024557600080fd5b5060fd546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561027257600080fd5b5060fb546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b6102a66102a1366004611bdd565b610540565b005b3480156102b457600080fd5b506102bd600181565b60405161ffff90911681526020016101ba565b3480156102dc57600080fd5b506101a5619c4081565b3480156102f257600080fd5b5061032f6040518060400160405280600581526020017f322e342e3000000000000000000000000000000000000000000000000000000081525081565b6040516101ba9190611caf565b34801561034857600080fd5b506101a561138881565b34801561035e57600080fd5b5061036761083d565b60405190151581526020016101ba565b34801561038357600080fd5b5060fc546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103b057600080fd5b506101ff6108d6565b3480156103c557600080fd5b506101a562030d4081565b3480156103dc57600080fd5b5060cf5473ffffffffffffffffffffffffffffffffffffffff166101ff565b34801561040757600080fd5b50610367610416366004611cc9565b60ce6020526000908152604090205460ff1681565b34801561043757600080fd5b50610367610446366004611cc9565b60cb6020526000908152604090205460ff1681565b34801561046757600080fd5b506101a5610476366004611ce2565b6109bd565b34801561048757600080fd5b506102a6610496366004611d36565b610a2b565b6102a66104a9366004611d81565b610ca2565b3480156104ba57600080fd5b5060cf546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104e757600080fd5b5061053260cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b6040519081526020016101ba565b6105486115d3565b156105e05734156105e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f642076616c7565207769746820637573746f6d2067617320746f6b656e00000060648201526084015b60405180910390fd5b60cf546107129073ffffffffffffffffffffffffffffffffffffffff166106088585856109bd565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061067460cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016106909796959493929190611e50565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611612565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561079760cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b866040516107a9959493929190611eaf565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60fb54604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156108ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d19190611efd565b905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016109a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084016105d7565b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f6109d9604063ffffffff8816611f4e565b6109e39190611f7e565b6109ee601088611f4e565b6109fb9062030d40611fcc565b610a059190611fcc565b610a0f9190611fcc565b610a199190611fcc565b610a239190611fcc565b949350505050565b6000547501000000000000000000000000000000000000000000900460ff1615808015610a76575060005460017401000000000000000000000000000000000000000090910460ff16105b80610aa85750303b158015610aa8575060005474010000000000000000000000000000000000000000900460ff166001145b610b34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016105d7565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790558015610bba57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b60fb805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560fc805486841690831617905560fd805492851692909116919091179055610c397342000000000000000000000000000000000000076116ab565b8015610c9c57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b610caa61083d565b15610d11576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f43726f7373446f6d61696e4d657373656e6765723a207061757365640000000060448201526064016105d7565b60f087901c60028110610dcc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016105d7565b8061ffff16600003610ec1576000610e1d878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506117e7915050565b600081815260cb602052604090205490915060ff1615610ebf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016105d7565b505b6000610f07898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061180692505050565b9050610f11611829565b15610f4957853414610f2557610f25611ff8565b600081815260ce602052604090205460ff1615610f4457610f44611ff8565b61109b565b3415610ffd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016105d7565b600081815260ce602052604090205460ff1661109b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016105d7565b6110a487611905565b15611157576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016105d7565b600081815260cb602052604090205460ff16156111f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016105d7565b61121785611208611388619c40611fcc565b67ffffffffffffffff1661194b565b158061123d575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561135657600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161134f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016105d7565b50506115ae565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a1617905560006113e788619c405a6113aa9190612027565b8988888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061196992505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801561149d57600082815260cb602052604090205460ff161561143a5761143a611ff8565b600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26115aa565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016115aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016105d7565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6000806115de611981565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b60fc546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c4290849061167390889083908990600090899060040161203e565b6000604051808303818588803b15801561168c57600080fd5b505af11580156116a0573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611756576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105d7565b60cc5473ffffffffffffffffffffffffffffffffffffffff166117a05760cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b60cf80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006117f585858585611a1e565b805190602001209050949350505050565b6000611816878787878787611ab7565b8051906020012090509695505050505050565b60fc5460009073ffffffffffffffffffffffffffffffffffffffff16331480156108d1575060cf5460fc54604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691639bf62d82916004808201926020929091908290030181865afa1580156118c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e99190612096565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff8216301480611945575060fc5473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000806000835160208501868989f195945050505050565b60fd54604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa1580156119f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1591906120b3565b90939092509050565b606084848484604051602401611a3794939291906120f3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b6060868686868686604051602401611ad49695949392919061213d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611b7857600080fd5b50565b60008083601f840112611b8d57600080fd5b50813567ffffffffffffffff811115611ba557600080fd5b602083019150836020828501011115611bbd57600080fd5b9250929050565b803563ffffffff81168114611bd857600080fd5b919050565b60008060008060608587031215611bf357600080fd5b8435611bfe81611b56565b9350602085013567ffffffffffffffff811115611c1a57600080fd5b611c2687828801611b7b565b9094509250611c39905060408601611bc4565b905092959194509250565b6000815180845260005b81811015611c6a57602081850181015186830182015201611c4e565b81811115611c7c576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611cc26020830184611c44565b9392505050565b600060208284031215611cdb57600080fd5b5035919050565b600080600060408486031215611cf757600080fd5b833567ffffffffffffffff811115611d0e57600080fd5b611d1a86828701611b7b565b9094509250611d2d905060208501611bc4565b90509250925092565b600080600060608486031215611d4b57600080fd5b8335611d5681611b56565b92506020840135611d6681611b56565b91506040840135611d7681611b56565b809150509250925092565b600080600080600080600060c0888a031215611d9c57600080fd5b873596506020880135611dae81611b56565b95506040880135611dbe81611b56565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611de857600080fd5b611df48a828b01611b7b565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611ea260c083018486611e07565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611edf608083018688611e07565b905083604083015263ffffffff831660608301529695505050505050565b600060208284031215611f0f57600080fd5b81518015158114611cc257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611f7557611f75611f1f565b02949350505050565b600067ffffffffffffffff80841680611fc0577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611fef57611fef611f1f565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b60008282101561203957612039611f1f565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a06080820152600061208b60a0830184611c44565b979650505050505050565b6000602082840312156120a857600080fd5b8151611cc281611b56565b600080604083850312156120c657600080fd5b82516120d181611b56565b602084015190925060ff811681146120e857600080fd5b809150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152506080604083015261212c6080830185611c44565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261218860c0830184611c44565b9897505050505050505056fea164736f6c634300080f000a", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x60806040523480156200001157600080fd5b50620000206000808062000026565b6200028e565b600054600160a81b900460ff16158080156200004f57506000546001600160a01b90910460ff16105b806200008657506200006c30620001c860201b620015b71760201c565b158015620000865750600054600160a01b900460ff166001145b620000ef5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff60a01b1916600160a01b17905580156200011d576000805460ff60a81b1916600160a81b1790555b60fb80546001600160a01b038087166001600160a01b03199283161790925560fc805486841690831617905560fd80549285169290911691909117905562000179734200000000000000000000000000000000000007620001d7565b8015620001c2576000805460ff60a81b19169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6001600160a01b03163b151590565b600054600160a81b900460ff16620002465760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000e6565b60cc546001600160a01b03166200026c5760cc80546001600160a01b03191661dead1790555b60cf80546001600160a01b0319166001600160a01b0392909216919091179055565b6121a1806200029e6000396000f3fe60806040526004361061018b5760003560e01c80636425666b116100d6578063b1b1b2091161007f578063d764ad0b11610059578063d764ad0b1461049b578063db505d80146104ae578063ecc70428146104db57600080fd5b8063b1b1b2091461042b578063b28ade251461045b578063c0c53b8b1461047b57600080fd5b80638cbeeef2116100b05780638cbeeef2146102d05780639fce812c146103d0578063a4e7f8bd146103fb57600080fd5b80636425666b146103775780636e296e45146103a457806383a74074146103b957600080fd5b80633dbb202b1161013857806354fd4d501161011257806354fd4d50146102e65780635644cfdf1461033c5780635c975abb1461035257600080fd5b80633dbb202b146102935780633f827a5a146102a85780634c1d6a69146102d057600080fd5b80632828d7e8116101695780632828d7e81461022457806333d7e2bd1461023957806335e80ab31461026657600080fd5b8063028f85f7146101905780630c568498146101c35780630ff754ea146101d8575b600080fd5b34801561019c57600080fd5b506101a5601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101cf57600080fd5b506101a5603f81565b3480156101e457600080fd5b5060fc5473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ba565b34801561023057600080fd5b506101a5604081565b34801561024557600080fd5b5060fd546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561027257600080fd5b5060fb546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b6102a66102a1366004611bdd565b610540565b005b3480156102b457600080fd5b506102bd600181565b60405161ffff90911681526020016101ba565b3480156102dc57600080fd5b506101a5619c4081565b3480156102f257600080fd5b5061032f6040518060400160405280600581526020017f322e342e3000000000000000000000000000000000000000000000000000000081525081565b6040516101ba9190611caf565b34801561034857600080fd5b506101a561138881565b34801561035e57600080fd5b5061036761083d565b60405190151581526020016101ba565b34801561038357600080fd5b5060fc546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103b057600080fd5b506101ff6108d6565b3480156103c557600080fd5b506101a562030d4081565b3480156103dc57600080fd5b5060cf5473ffffffffffffffffffffffffffffffffffffffff166101ff565b34801561040757600080fd5b50610367610416366004611cc9565b60ce6020526000908152604090205460ff1681565b34801561043757600080fd5b50610367610446366004611cc9565b60cb6020526000908152604090205460ff1681565b34801561046757600080fd5b506101a5610476366004611ce2565b6109bd565b34801561048757600080fd5b506102a6610496366004611d36565b610a2b565b6102a66104a9366004611d81565b610ca2565b3480156104ba57600080fd5b5060cf546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104e757600080fd5b5061053260cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b6040519081526020016101ba565b6105486115d3565b156105e05734156105e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f642076616c7565207769746820637573746f6d2067617320746f6b656e00000060648201526084015b60405180910390fd5b60cf546107129073ffffffffffffffffffffffffffffffffffffffff166106088585856109bd565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061067460cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016106909796959493929190611e50565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611612565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561079760cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b866040516107a9959493929190611eaf565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60fb54604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156108ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d19190611efd565b905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016109a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084016105d7565b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f6109d9604063ffffffff8816611f4e565b6109e39190611f7e565b6109ee601088611f4e565b6109fb9062030d40611fcc565b610a059190611fcc565b610a0f9190611fcc565b610a199190611fcc565b610a239190611fcc565b949350505050565b6000547501000000000000000000000000000000000000000000900460ff1615808015610a76575060005460017401000000000000000000000000000000000000000090910460ff16105b80610aa85750303b158015610aa8575060005474010000000000000000000000000000000000000000900460ff166001145b610b34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016105d7565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790558015610bba57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b60fb805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560fc805486841690831617905560fd805492851692909116919091179055610c397342000000000000000000000000000000000000076116ab565b8015610c9c57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b610caa61083d565b15610d11576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f43726f7373446f6d61696e4d657373656e6765723a207061757365640000000060448201526064016105d7565b60f087901c60028110610dcc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016105d7565b8061ffff16600003610ec1576000610e1d878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506117e7915050565b600081815260cb602052604090205490915060ff1615610ebf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016105d7565b505b6000610f07898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061180692505050565b9050610f11611829565b15610f4957853414610f2557610f25611ff8565b600081815260ce602052604090205460ff1615610f4457610f44611ff8565b61109b565b3415610ffd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016105d7565b600081815260ce602052604090205460ff1661109b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016105d7565b6110a487611905565b15611157576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016105d7565b600081815260cb602052604090205460ff16156111f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016105d7565b61121785611208611388619c40611fcc565b67ffffffffffffffff1661194b565b158061123d575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561135657600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161134f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016105d7565b50506115ae565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a1617905560006113e788619c405a6113aa9190612027565b8988888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061196992505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801561149d57600082815260cb602052604090205460ff161561143a5761143a611ff8565b600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26115aa565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016115aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016105d7565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6000806115de611981565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b60fc546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c4290849061167390889083908990600090899060040161203e565b6000604051808303818588803b15801561168c57600080fd5b505af11580156116a0573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611756576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105d7565b60cc5473ffffffffffffffffffffffffffffffffffffffff166117a05760cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b60cf80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006117f585858585611a1e565b805190602001209050949350505050565b6000611816878787878787611ab7565b8051906020012090509695505050505050565b60fc5460009073ffffffffffffffffffffffffffffffffffffffff16331480156108d1575060cf5460fc54604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691639bf62d82916004808201926020929091908290030181865afa1580156118c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e99190612096565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff8216301480611945575060fc5473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000806000835160208501868989f195945050505050565b60fd54604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa1580156119f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1591906120b3565b90939092509050565b606084848484604051602401611a3794939291906120f3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b6060868686868686604051602401611ad49695949392919061213d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611b7857600080fd5b50565b60008083601f840112611b8d57600080fd5b50813567ffffffffffffffff811115611ba557600080fd5b602083019150836020828501011115611bbd57600080fd5b9250929050565b803563ffffffff81168114611bd857600080fd5b919050565b60008060008060608587031215611bf357600080fd5b8435611bfe81611b56565b9350602085013567ffffffffffffffff811115611c1a57600080fd5b611c2687828801611b7b565b9094509250611c39905060408601611bc4565b905092959194509250565b6000815180845260005b81811015611c6a57602081850181015186830182015201611c4e565b81811115611c7c576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611cc26020830184611c44565b9392505050565b600060208284031215611cdb57600080fd5b5035919050565b600080600060408486031215611cf757600080fd5b833567ffffffffffffffff811115611d0e57600080fd5b611d1a86828701611b7b565b9094509250611d2d905060208501611bc4565b90509250925092565b600080600060608486031215611d4b57600080fd5b8335611d5681611b56565b92506020840135611d6681611b56565b91506040840135611d7681611b56565b809150509250925092565b600080600080600080600060c0888a031215611d9c57600080fd5b873596506020880135611dae81611b56565b95506040880135611dbe81611b56565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611de857600080fd5b611df48a828b01611b7b565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611ea260c083018486611e07565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611edf608083018688611e07565b905083604083015263ffffffff831660608301529695505050505050565b600060208284031215611f0f57600080fd5b81518015158114611cc257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611f7557611f75611f1f565b02949350505050565b600067ffffffffffffffff80841680611fc0577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611fef57611fef611f1f565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b60008282101561203957612039611f1f565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a06080820152600061208b60a0830184611c44565b979650505050505050565b6000602082840312156120a857600080fd5b8151611cc281611b56565b600080604083850312156120c657600080fd5b82516120d181611b56565b602084015190925060ff811681146120e857600080fd5b809150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152506080604083015261212c6080830185611c44565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261218860c0830184611c44565b9897505050505050505056fea164736f6c634300080f000a", - "deployedCode": "0x60806040526004361061018b5760003560e01c80636425666b116100d6578063b1b1b2091161007f578063d764ad0b11610059578063d764ad0b1461049b578063db505d80146104ae578063ecc70428146104db57600080fd5b8063b1b1b2091461042b578063b28ade251461045b578063c0c53b8b1461047b57600080fd5b80638cbeeef2116100b05780638cbeeef2146102d05780639fce812c146103d0578063a4e7f8bd146103fb57600080fd5b80636425666b146103775780636e296e45146103a457806383a74074146103b957600080fd5b80633dbb202b1161013857806354fd4d501161011257806354fd4d50146102e65780635644cfdf1461033c5780635c975abb1461035257600080fd5b80633dbb202b146102935780633f827a5a146102a85780634c1d6a69146102d057600080fd5b80632828d7e8116101695780632828d7e81461022457806333d7e2bd1461023957806335e80ab31461026657600080fd5b8063028f85f7146101905780630c568498146101c35780630ff754ea146101d8575b600080fd5b34801561019c57600080fd5b506101a5601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101cf57600080fd5b506101a5603f81565b3480156101e457600080fd5b5060fc5473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ba565b34801561023057600080fd5b506101a5604081565b34801561024557600080fd5b5060fd546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561027257600080fd5b5060fb546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b6102a66102a1366004611bdd565b610540565b005b3480156102b457600080fd5b506102bd600181565b60405161ffff90911681526020016101ba565b3480156102dc57600080fd5b506101a5619c4081565b3480156102f257600080fd5b5061032f6040518060400160405280600581526020017f322e342e3000000000000000000000000000000000000000000000000000000081525081565b6040516101ba9190611caf565b34801561034857600080fd5b506101a561138881565b34801561035e57600080fd5b5061036761083d565b60405190151581526020016101ba565b34801561038357600080fd5b5060fc546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103b057600080fd5b506101ff6108d6565b3480156103c557600080fd5b506101a562030d4081565b3480156103dc57600080fd5b5060cf5473ffffffffffffffffffffffffffffffffffffffff166101ff565b34801561040757600080fd5b50610367610416366004611cc9565b60ce6020526000908152604090205460ff1681565b34801561043757600080fd5b50610367610446366004611cc9565b60cb6020526000908152604090205460ff1681565b34801561046757600080fd5b506101a5610476366004611ce2565b6109bd565b34801561048757600080fd5b506102a6610496366004611d36565b610a2b565b6102a66104a9366004611d81565b610ca2565b3480156104ba57600080fd5b5060cf546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104e757600080fd5b5061053260cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b6040519081526020016101ba565b6105486115d3565b156105e05734156105e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f642076616c7565207769746820637573746f6d2067617320746f6b656e00000060648201526084015b60405180910390fd5b60cf546107129073ffffffffffffffffffffffffffffffffffffffff166106088585856109bd565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061067460cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016106909796959493929190611e50565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611612565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561079760cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b866040516107a9959493929190611eaf565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60fb54604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156108ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d19190611efd565b905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016109a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084016105d7565b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f6109d9604063ffffffff8816611f4e565b6109e39190611f7e565b6109ee601088611f4e565b6109fb9062030d40611fcc565b610a059190611fcc565b610a0f9190611fcc565b610a199190611fcc565b610a239190611fcc565b949350505050565b6000547501000000000000000000000000000000000000000000900460ff1615808015610a76575060005460017401000000000000000000000000000000000000000090910460ff16105b80610aa85750303b158015610aa8575060005474010000000000000000000000000000000000000000900460ff166001145b610b34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016105d7565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790558015610bba57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b60fb805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560fc805486841690831617905560fd805492851692909116919091179055610c397342000000000000000000000000000000000000076116ab565b8015610c9c57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b610caa61083d565b15610d11576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f43726f7373446f6d61696e4d657373656e6765723a207061757365640000000060448201526064016105d7565b60f087901c60028110610dcc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016105d7565b8061ffff16600003610ec1576000610e1d878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506117e7915050565b600081815260cb602052604090205490915060ff1615610ebf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016105d7565b505b6000610f07898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061180692505050565b9050610f11611829565b15610f4957853414610f2557610f25611ff8565b600081815260ce602052604090205460ff1615610f4457610f44611ff8565b61109b565b3415610ffd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016105d7565b600081815260ce602052604090205460ff1661109b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016105d7565b6110a487611905565b15611157576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016105d7565b600081815260cb602052604090205460ff16156111f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016105d7565b61121785611208611388619c40611fcc565b67ffffffffffffffff1661194b565b158061123d575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561135657600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161134f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016105d7565b50506115ae565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a1617905560006113e788619c405a6113aa9190612027565b8988888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061196992505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801561149d57600082815260cb602052604090205460ff161561143a5761143a611ff8565b600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26115aa565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016115aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016105d7565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6000806115de611981565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b60fc546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c4290849061167390889083908990600090899060040161203e565b6000604051808303818588803b15801561168c57600080fd5b505af11580156116a0573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611756576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105d7565b60cc5473ffffffffffffffffffffffffffffffffffffffff166117a05760cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b60cf80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006117f585858585611a1e565b805190602001209050949350505050565b6000611816878787878787611ab7565b8051906020012090509695505050505050565b60fc5460009073ffffffffffffffffffffffffffffffffffffffff16331480156108d1575060cf5460fc54604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691639bf62d82916004808201926020929091908290030181865afa1580156118c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e99190612096565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff8216301480611945575060fc5473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000806000835160208501868989f195945050505050565b60fd54604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa1580156119f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1591906120b3565b90939092509050565b606084848484604051602401611a3794939291906120f3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b6060868686868686604051602401611ad49695949392919061213d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611b7857600080fd5b50565b60008083601f840112611b8d57600080fd5b50813567ffffffffffffffff811115611ba557600080fd5b602083019150836020828501011115611bbd57600080fd5b9250929050565b803563ffffffff81168114611bd857600080fd5b919050565b60008060008060608587031215611bf357600080fd5b8435611bfe81611b56565b9350602085013567ffffffffffffffff811115611c1a57600080fd5b611c2687828801611b7b565b9094509250611c39905060408601611bc4565b905092959194509250565b6000815180845260005b81811015611c6a57602081850181015186830182015201611c4e565b81811115611c7c576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611cc26020830184611c44565b9392505050565b600060208284031215611cdb57600080fd5b5035919050565b600080600060408486031215611cf757600080fd5b833567ffffffffffffffff811115611d0e57600080fd5b611d1a86828701611b7b565b9094509250611d2d905060208501611bc4565b90509250925092565b600080600060608486031215611d4b57600080fd5b8335611d5681611b56565b92506020840135611d6681611b56565b91506040840135611d7681611b56565b809150509250925092565b600080600080600080600060c0888a031215611d9c57600080fd5b873596506020880135611dae81611b56565b95506040880135611dbe81611b56565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611de857600080fd5b611df48a828b01611b7b565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611ea260c083018486611e07565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611edf608083018688611e07565b905083604083015263ffffffff831660608301529695505050505050565b600060208284031215611f0f57600080fd5b81518015158114611cc257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611f7557611f75611f1f565b02949350505050565b600067ffffffffffffffff80841680611fc0577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611fef57611fef611f1f565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b60008282101561203957612039611f1f565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a06080820152600061208b60a0830184611c44565b979650505050505050565b6000602082840312156120a857600080fd5b8151611cc281611b56565b600080604083850312156120c657600080fd5b82516120d181611b56565b602084015190925060ff811681146120e857600080fd5b809150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152506080604083015261212c6080830185611c44565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261218860c0830184611c44565b9897505050505050505056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": true, - "newValue": "0x0000000000000000000000010000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": false, - "newValue": "0x0000000000000000000000010000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000010000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": true, - "newValue": "0x0000000000000000000001010000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000010000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000fb" - }, - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000fb" - }, - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000fc" - }, - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000fc" - }, - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000fd" - }, - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000fd" - }, - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": false, - "newValue": "0x0000000000000000000001010000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000001010000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000cc" - }, - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000cc" - }, - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": true, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000cc" - }, - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000cf" - }, - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": true, - "newValue": "0x0000000000000000000000004200000000000000000000000000000000000007", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000cf" - }, - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": false, - "newValue": "0x0000000000000000000001010000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000001010000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": true, - "newValue": "0x0000000000000000000000010000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000001010000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9fce812c", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": false, - "newValue": "0x0000000000000000000000004200000000000000000000000000000000000007", - "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000007", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000cf" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xdb505d80", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": false, - "newValue": "0x0000000000000000000000004200000000000000000000000000000000000007", - "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000007", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000cf" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x0ff754ea", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000fc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6425666b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000fc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x35e80ab3", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000fb" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x638627e586f5e36fe67a77519503a7c6da22f92b150d3c6055fd40bdcfe9ffd1608060405234801561001057600080fd5b5061001b6000610020565b610169565b600054610100900460ff16158080156100405750600054600160ff909116105b8061006b57506100593061015a60201b6105fe1760201c565b15801561006b575060005460ff166001145b6100d25760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff1916600117905580156100f5576000805461ff0019166101001790555b600180546001600160a01b0319166001600160a01b0384161790558015610156576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b03163b151590565b612146806101786000396000f3fe60806040523480156200001157600080fd5b5060043610620000935760003560e01c8063c4d66de81162000062578063c4d66de81462000175578063ce5ac90f146200018e578063e78cea9214620001a5578063ee9a31a214620001c657600080fd5b8063316b3739146200009857806354fd4d5014620000fb578063896f93d114620001475780638cf0629c146200015e575b600080fd5b620000d1620000a936600462000652565b60026020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b620001386040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b604051620000f29190620006e5565b620000d162000158366004620007dc565b620001e5565b620000d16200016f36600462000859565b620001fc565b6200018c6200018636600462000652565b6200041b565b005b620000d16200019f366004620007dc565b620005ed565b600154620000d19073ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff16620000d1565b6000620001f4848484620005ed565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff8516620002a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b600085858585604051602001620002c29493929190620008f0565b604051602081830303815290604052805190602001209050600081600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168888888860405162000312906200061a565b620003229594939291906200094a565b8190604051809103906000f590508015801562000343573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff81811660008181526002602052604080822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016948d1694851790555193945090927fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf9190a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054610100900460ff16158080156200043c5750600054600160ff909116105b80620004585750303b15801562000458575060005460ff166001145b620004e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200029e565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156200054557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790558015620005e957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6000620001f48484846012620001fc565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61178a80620009b083390190565b803573ffffffffffffffffffffffffffffffffffffffff811681146200064d57600080fd5b919050565b6000602082840312156200066557600080fd5b620006708262000628565b9392505050565b6000815180845260005b818110156200069f5760208185018101518683018201520162000681565b81811115620006b2576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600062000670602083018462000677565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200073b57600080fd5b813567ffffffffffffffff80821115620007595762000759620006fa565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620007a257620007a2620006fa565b81604052838152866020858801011115620007bc57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215620007f257600080fd5b620007fd8462000628565b9250602084013567ffffffffffffffff808211156200081b57600080fd5b620008298783880162000729565b935060408601359150808211156200084057600080fd5b506200084f8682870162000729565b9150509250925092565b600080600080608085870312156200087057600080fd5b6200087b8562000628565b9350602085013567ffffffffffffffff808211156200089957600080fd5b620008a78883890162000729565b94506040870135915080821115620008be57600080fd5b50620008cd8782880162000729565b925050606085013560ff81168114620008e557600080fd5b939692955090935050565b73ffffffffffffffffffffffffffffffffffffffff8516815260806020820152600062000921608083018662000677565b828103604084015262000935818662000677565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a060408301526200098560a083018662000677565b828103606084015262000999818662000677565b91505060ff83166080830152969550505050505056fe60e06040523480156200001157600080fd5b506040516200178a3803806200178a833981016040819052620000349162000163565b828260036200004483826200029e565b5060046200005382826200029e565b5050506001600160a01b039384166080529390921660a052505060ff1660c0526200036a565b80516001600160a01b03811681146200009157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000be57600080fd5b81516001600160401b0380821115620000db57620000db62000096565b604051601f8301601f19908116603f0116810190828211818310171562000106576200010662000096565b816040528381526020925086838588010111156200012357600080fd5b600091505b8382101562000147578582018301518183018401529082019062000128565b83821115620001595760008385830101525b9695505050505050565b600080600080600060a086880312156200017c57600080fd5b620001878662000079565b9450620001976020870162000079565b60408701519094506001600160401b0380821115620001b557600080fd5b620001c389838a01620000ac565b94506060880151915080821115620001da57600080fd5b50620001e988828901620000ac565b925050608086015160ff811681146200020157600080fd5b809150509295509295909350565b600181811c908216806200022457607f821691505b6020821081036200024557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029957600081815260208120601f850160051c81016020861015620002745750805b601f850160051c820191505b81811015620002955782815560010162000280565b5050505b505050565b81516001600160401b03811115620002ba57620002ba62000096565b620002d281620002cb84546200020f565b846200024b565b602080601f8311600181146200030a5760008415620002f15750858301515b600019600386901b1c1916600185901b17855562000295565b600085815260208120601f198616915b828110156200033b578886015182559484019460019091019084016200031a565b50858210156200035a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c0516113d4620003b6600039600061024401526000818161034b015281816103e001528181610625015261075c0152600081816101a9015261037101526113d46000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610395578063e78cea9214610349578063ee9a31a2146103db57600080fd5b8063ae1f6aaf14610349578063c01e1bd61461036f578063d6c0b2c41461036f57600080fd5b80639dc29fac116100bd5780639dc29fac14610310578063a457c2d714610323578063a9059cbb1461033657600080fd5b806370a08231146102d257806395d89b411461030857600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a36600461117d565b610402565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104f3565b60405161019b91906111c6565b61018f610213366004611262565b610585565b6002545b60405190815260200161019b565b61018f61023836600461128c565b61059d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611262565b6105c1565b61029461028f366004611262565b61060d565b005b6101f86040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61021c6102e03660046112c8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610735565b61029461031e366004611262565b610744565b61018f610331366004611262565b61085b565b61018f610344366004611262565b61092c565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c6103a33660046112e3565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104bb57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104ea57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461050290611316565b80601f016020809104026020016040519081016040528092919081815260200182805461052e90611316565b801561057b5780601f106105505761010080835404028352916020019161057b565b820191906000526020600020905b81548152906001019060200180831161055e57829003601f168201915b5050505050905090565b60003361059381858561093a565b5060019392505050565b6000336105ab858285610aee565b6105b6858585610bc5565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906105939082908690610608908790611398565b61093a565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106e18282610e78565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161072991815260200190565b60405180910390a25050565b60606004805461050290611316565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016106ce565b6108138282610f98565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161072991815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561091f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016106ce565b6105b6828686840361093a565b600033610593818585610bc5565b73ffffffffffffffffffffffffffffffffffffffff83166109dc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bbf5781811015610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106ce565b610bbf848484840361093a565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610d0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e05908490611398565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e6b91815260200190565b60405180910390a3610bbf565b73ffffffffffffffffffffffffffffffffffffffff8216610ef5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106ce565b8060026000828254610f079190611398565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f41908490611398565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff821661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156110f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812083830390556002805484929061112d9084906113b0565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610ae1565b60006020828403121561118f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146111bf57600080fd5b9392505050565b600060208083528351808285015260005b818110156111f3578581018301518582016040015282016111d7565b81811115611205576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461125d57600080fd5b919050565b6000806040838503121561127557600080fd5b61127e83611239565b946020939093013593505050565b6000806000606084860312156112a157600080fd5b6112aa84611239565b92506112b860208501611239565b9150604084013590509250925092565b6000602082840312156112da57600080fd5b6111bf82611239565b600080604083850312156112f657600080fd5b6112ff83611239565b915061130d60208401611239565b90509250929050565b600181811c9082168061132a57607f821691505b602082108103611363577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156113ab576113ab611369565b500190565b6000828210156113c2576113c2611369565b50039056fea164736f6c634300080f000aa164736f6c634300080f000a", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "account": "0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x608060405234801561001057600080fd5b5061001b6000610020565b610169565b600054610100900460ff16158080156100405750600054600160ff909116105b8061006b57506100593061015a60201b6105fe1760201c565b15801561006b575060005460ff166001145b6100d25760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff1916600117905580156100f5576000805461ff0019166101001790555b600180546001600160a01b0319166001600160a01b0384161790558015610156576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b03163b151590565b612146806101786000396000f3fe60806040523480156200001157600080fd5b5060043610620000935760003560e01c8063c4d66de81162000062578063c4d66de81462000175578063ce5ac90f146200018e578063e78cea9214620001a5578063ee9a31a214620001c657600080fd5b8063316b3739146200009857806354fd4d5014620000fb578063896f93d114620001475780638cf0629c146200015e575b600080fd5b620000d1620000a936600462000652565b60026020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b620001386040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b604051620000f29190620006e5565b620000d162000158366004620007dc565b620001e5565b620000d16200016f36600462000859565b620001fc565b6200018c6200018636600462000652565b6200041b565b005b620000d16200019f366004620007dc565b620005ed565b600154620000d19073ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff16620000d1565b6000620001f4848484620005ed565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff8516620002a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b600085858585604051602001620002c29493929190620008f0565b604051602081830303815290604052805190602001209050600081600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168888888860405162000312906200061a565b620003229594939291906200094a565b8190604051809103906000f590508015801562000343573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff81811660008181526002602052604080822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016948d1694851790555193945090927fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf9190a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054610100900460ff16158080156200043c5750600054600160ff909116105b80620004585750303b15801562000458575060005460ff166001145b620004e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200029e565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156200054557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790558015620005e957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6000620001f48484846012620001fc565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61178a80620009b083390190565b803573ffffffffffffffffffffffffffffffffffffffff811681146200064d57600080fd5b919050565b6000602082840312156200066557600080fd5b620006708262000628565b9392505050565b6000815180845260005b818110156200069f5760208185018101518683018201520162000681565b81811115620006b2576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600062000670602083018462000677565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200073b57600080fd5b813567ffffffffffffffff80821115620007595762000759620006fa565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620007a257620007a2620006fa565b81604052838152866020858801011115620007bc57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215620007f257600080fd5b620007fd8462000628565b9250602084013567ffffffffffffffff808211156200081b57600080fd5b620008298783880162000729565b935060408601359150808211156200084057600080fd5b506200084f8682870162000729565b9150509250925092565b600080600080608085870312156200087057600080fd5b6200087b8562000628565b9350602085013567ffffffffffffffff808211156200089957600080fd5b620008a78883890162000729565b94506040870135915080821115620008be57600080fd5b50620008cd8782880162000729565b925050606085013560ff81168114620008e557600080fd5b939692955090935050565b73ffffffffffffffffffffffffffffffffffffffff8516815260806020820152600062000921608083018662000677565b828103604084015262000935818662000677565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a060408301526200098560a083018662000677565b828103606084015262000999818662000677565b91505060ff83166080830152969550505050505056fe60e06040523480156200001157600080fd5b506040516200178a3803806200178a833981016040819052620000349162000163565b828260036200004483826200029e565b5060046200005382826200029e565b5050506001600160a01b039384166080529390921660a052505060ff1660c0526200036a565b80516001600160a01b03811681146200009157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000be57600080fd5b81516001600160401b0380821115620000db57620000db62000096565b604051601f8301601f19908116603f0116810190828211818310171562000106576200010662000096565b816040528381526020925086838588010111156200012357600080fd5b600091505b8382101562000147578582018301518183018401529082019062000128565b83821115620001595760008385830101525b9695505050505050565b600080600080600060a086880312156200017c57600080fd5b620001878662000079565b9450620001976020870162000079565b60408701519094506001600160401b0380821115620001b557600080fd5b620001c389838a01620000ac565b94506060880151915080821115620001da57600080fd5b50620001e988828901620000ac565b925050608086015160ff811681146200020157600080fd5b809150509295509295909350565b600181811c908216806200022457607f821691505b6020821081036200024557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029957600081815260208120601f850160051c81016020861015620002745750805b601f850160051c820191505b81811015620002955782815560010162000280565b5050505b505050565b81516001600160401b03811115620002ba57620002ba62000096565b620002d281620002cb84546200020f565b846200024b565b602080601f8311600181146200030a5760008415620002f15750858301515b600019600386901b1c1916600185901b17855562000295565b600085815260208120601f198616915b828110156200033b578886015182559484019460019091019084016200031a565b50858210156200035a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c0516113d4620003b6600039600061024401526000818161034b015281816103e001528181610625015261075c0152600081816101a9015261037101526113d46000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610395578063e78cea9214610349578063ee9a31a2146103db57600080fd5b8063ae1f6aaf14610349578063c01e1bd61461036f578063d6c0b2c41461036f57600080fd5b80639dc29fac116100bd5780639dc29fac14610310578063a457c2d714610323578063a9059cbb1461033657600080fd5b806370a08231146102d257806395d89b411461030857600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a36600461117d565b610402565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104f3565b60405161019b91906111c6565b61018f610213366004611262565b610585565b6002545b60405190815260200161019b565b61018f61023836600461128c565b61059d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611262565b6105c1565b61029461028f366004611262565b61060d565b005b6101f86040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61021c6102e03660046112c8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610735565b61029461031e366004611262565b610744565b61018f610331366004611262565b61085b565b61018f610344366004611262565b61092c565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c6103a33660046112e3565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104bb57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104ea57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461050290611316565b80601f016020809104026020016040519081016040528092919081815260200182805461052e90611316565b801561057b5780601f106105505761010080835404028352916020019161057b565b820191906000526020600020905b81548152906001019060200180831161055e57829003601f168201915b5050505050905090565b60003361059381858561093a565b5060019392505050565b6000336105ab858285610aee565b6105b6858585610bc5565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906105939082908690610608908790611398565b61093a565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106e18282610e78565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161072991815260200190565b60405180910390a25050565b60606004805461050290611316565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016106ce565b6108138282610f98565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161072991815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561091f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016106ce565b6105b6828686840361093a565b600033610593818585610bc5565b73ffffffffffffffffffffffffffffffffffffffff83166109dc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bbf5781811015610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106ce565b610bbf848484840361093a565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610d0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e05908490611398565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e6b91815260200190565b60405180910390a3610bbf565b73ffffffffffffffffffffffffffffffffffffffff8216610ef5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106ce565b8060026000828254610f079190611398565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f41908490611398565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff821661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156110f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812083830390556002805484929061112d9084906113b0565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610ae1565b60006020828403121561118f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146111bf57600080fd5b9392505050565b600060208083528351808285015260005b818110156111f3578581018301518582016040015282016111d7565b81811115611205576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461125d57600080fd5b919050565b6000806040838503121561127557600080fd5b61127e83611239565b946020939093013593505050565b6000806000606084860312156112a157600080fd5b6112aa84611239565b92506112b860208501611239565b9150604084013590509250925092565b6000602082840312156112da57600080fd5b6111bf82611239565b600080604083850312156112f657600080fd5b6112ff83611239565b915061130d60208401611239565b90509250929050565b600181811c9082168061132a57607f821691505b602082108103611363577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156113ab576113ab611369565b500190565b6000828210156113c2576113c2611369565b50039056fea164736f6c634300080f000aa164736f6c634300080f000a", - "deployedCode": "0x60806040523480156200001157600080fd5b5060043610620000935760003560e01c8063c4d66de81162000062578063c4d66de81462000175578063ce5ac90f146200018e578063e78cea9214620001a5578063ee9a31a214620001c657600080fd5b8063316b3739146200009857806354fd4d5014620000fb578063896f93d114620001475780638cf0629c146200015e575b600080fd5b620000d1620000a936600462000652565b60026020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b620001386040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b604051620000f29190620006e5565b620000d162000158366004620007dc565b620001e5565b620000d16200016f36600462000859565b620001fc565b6200018c6200018636600462000652565b6200041b565b005b620000d16200019f366004620007dc565b620005ed565b600154620000d19073ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff16620000d1565b6000620001f4848484620005ed565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff8516620002a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b600085858585604051602001620002c29493929190620008f0565b604051602081830303815290604052805190602001209050600081600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168888888860405162000312906200061a565b620003229594939291906200094a565b8190604051809103906000f590508015801562000343573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff81811660008181526002602052604080822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016948d1694851790555193945090927fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf9190a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054610100900460ff16158080156200043c5750600054600160ff909116105b80620004585750303b15801562000458575060005460ff166001145b620004e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200029e565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156200054557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790558015620005e957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6000620001f48484846012620001fc565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61178a80620009b083390190565b803573ffffffffffffffffffffffffffffffffffffffff811681146200064d57600080fd5b919050565b6000602082840312156200066557600080fd5b620006708262000628565b9392505050565b6000815180845260005b818110156200069f5760208185018101518683018201520162000681565b81811115620006b2576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600062000670602083018462000677565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200073b57600080fd5b813567ffffffffffffffff80821115620007595762000759620006fa565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620007a257620007a2620006fa565b81604052838152866020858801011115620007bc57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215620007f257600080fd5b620007fd8462000628565b9250602084013567ffffffffffffffff808211156200081b57600080fd5b620008298783880162000729565b935060408601359150808211156200084057600080fd5b506200084f8682870162000729565b9150509250925092565b600080600080608085870312156200087057600080fd5b6200087b8562000628565b9350602085013567ffffffffffffffff808211156200089957600080fd5b620008a78883890162000729565b94506040870135915080821115620008be57600080fd5b50620008cd8782880162000729565b925050606085013560ff81168114620008e557600080fd5b939692955090935050565b73ffffffffffffffffffffffffffffffffffffffff8516815260806020820152600062000921608083018662000677565b828103604084015262000935818662000677565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a060408301526200098560a083018662000677565b828103606084015262000999818662000677565b91505060ff83166080830152969550505050505056fe60e06040523480156200001157600080fd5b506040516200178a3803806200178a833981016040819052620000349162000163565b828260036200004483826200029e565b5060046200005382826200029e565b5050506001600160a01b039384166080529390921660a052505060ff1660c0526200036a565b80516001600160a01b03811681146200009157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000be57600080fd5b81516001600160401b0380821115620000db57620000db62000096565b604051601f8301601f19908116603f0116810190828211818310171562000106576200010662000096565b816040528381526020925086838588010111156200012357600080fd5b600091505b8382101562000147578582018301518183018401529082019062000128565b83821115620001595760008385830101525b9695505050505050565b600080600080600060a086880312156200017c57600080fd5b620001878662000079565b9450620001976020870162000079565b60408701519094506001600160401b0380821115620001b557600080fd5b620001c389838a01620000ac565b94506060880151915080821115620001da57600080fd5b50620001e988828901620000ac565b925050608086015160ff811681146200020157600080fd5b809150509295509295909350565b600181811c908216806200022457607f821691505b6020821081036200024557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029957600081815260208120601f850160051c81016020861015620002745750805b601f850160051c820191505b81811015620002955782815560010162000280565b5050505b505050565b81516001600160401b03811115620002ba57620002ba62000096565b620002d281620002cb84546200020f565b846200024b565b602080601f8311600181146200030a5760008415620002f15750858301515b600019600386901b1c1916600185901b17855562000295565b600085815260208120601f198616915b828110156200033b578886015182559484019460019091019084016200031a565b50858210156200035a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c0516113d4620003b6600039600061024401526000818161034b015281816103e001528181610625015261075c0152600081816101a9015261037101526113d46000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610395578063e78cea9214610349578063ee9a31a2146103db57600080fd5b8063ae1f6aaf14610349578063c01e1bd61461036f578063d6c0b2c41461036f57600080fd5b80639dc29fac116100bd5780639dc29fac14610310578063a457c2d714610323578063a9059cbb1461033657600080fd5b806370a08231146102d257806395d89b411461030857600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a36600461117d565b610402565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104f3565b60405161019b91906111c6565b61018f610213366004611262565b610585565b6002545b60405190815260200161019b565b61018f61023836600461128c565b61059d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611262565b6105c1565b61029461028f366004611262565b61060d565b005b6101f86040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61021c6102e03660046112c8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610735565b61029461031e366004611262565b610744565b61018f610331366004611262565b61085b565b61018f610344366004611262565b61092c565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c6103a33660046112e3565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104bb57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104ea57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461050290611316565b80601f016020809104026020016040519081016040528092919081815260200182805461052e90611316565b801561057b5780601f106105505761010080835404028352916020019161057b565b820191906000526020600020905b81548152906001019060200180831161055e57829003601f168201915b5050505050905090565b60003361059381858561093a565b5060019392505050565b6000336105ab858285610aee565b6105b6858585610bc5565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906105939082908690610608908790611398565b61093a565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106e18282610e78565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161072991815260200190565b60405180910390a25050565b60606004805461050290611316565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016106ce565b6108138282610f98565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161072991815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561091f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016106ce565b6105b6828686840361093a565b600033610593818585610bc5565b73ffffffffffffffffffffffffffffffffffffffff83166109dc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bbf5781811015610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106ce565b610bbf848484840361093a565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610d0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e05908490611398565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e6b91815260200190565b60405180910390a3610bbf565b73ffffffffffffffffffffffffffffffffffffffff8216610ef5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106ce565b8060026000828254610f079190611398565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f41908490611398565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff821661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156110f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812083830390556002805484929061112d9084906113b0565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610ae1565b60006020828403121561118f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146111bf57600080fd5b9392505050565b600060208083528351808285015260005b818110156111f3578581018301518582016040015282016111d7565b81811115611205576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461125d57600080fd5b919050565b6000806040838503121561127557600080fd5b61127e83611239565b946020939093013593505050565b6000806000606084860312156112a157600080fd5b6112aa84611239565b92506112b860208501611239565b9150604084013590509250925092565b6000602082840312156112da57600080fd5b6111bf82611239565b600080604083850312156112f657600080fd5b6112ff83611239565b915061130d60208401611239565b90509250929050565b600181811c9082168061132a57607f821691505b602082108103611363577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156113ab576113ab611369565b500190565b6000828210156113c2576113c2611369565b50039056fea164736f6c634300080f000aa164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - { - "account": "0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - { - "account": "0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xee9a31a2", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xe78cea92", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x493f862b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000004a" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x638627e586f5e36fe67a77519503a7c6da22f92b150d3c6055fd40bdcfe9ffd160806040523480156200001157600080fd5b506200004962000032600160008051602062003ce683398151915262001203565b60001b600019620000d160201b62000fc61760201c565b6040805160c080820183526001808352602080840182905260028486015260006060808601829052608080870183905260a0808801849052885160e081018a528481529485018490529784018390529083018290528201819052948101859052918201849052620000cb9361dead9390928392839290918391908290620000d5565b6200142c565b9055565b600054610100900460ff1615808015620000f65750600054600160ff909116105b806200012657506200011330620004e660201b62000fca1760201c565b15801562000126575060005460ff166001145b6200018f5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff191660011790558015620001b3576000805461ff0019166101001790555b620001bd620004f5565b620001c88a6200055d565b620001d387620005dc565b620001df89896200062e565b620001ea86620006f5565b620002217f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0886620000d160201b62000fc61760201c565b620002676200025260017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59862001203565b60001b84620000d160201b62000fc61760201c565b620002b16200029860017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063762001203565b60001b8360000151620000d160201b62000fc61760201c565b620002fb620002e260017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a862001203565b60001b8360200151620000d160201b62000fc61760201c565b620003456200032c60017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637762001203565b60001b8360400151620000d160201b62000fc61760201c565b6200038f6200037660017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90762001203565b60001b8360600151620000d160201b62000fc61760201c565b620003c8620003af600160008051602062003cc683398151915262001203565b60001b8360800151620000d160201b62000fc61760201c565b62000412620003f960017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d62001203565b60001b8360a00151620000d160201b62000fc61760201c565b6200041c620007f1565b60c08201516200042c9062000862565b620004378462000aeb565b6200044162000e2f565b6001600160401b0316866001600160401b03161015620004935760405162461bcd60e51b815260206004820152601f602482015260008051602062003c66833981519152604482015260640162000186565b8015620004da576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b6001600160a01b03163b151590565b600054610100900460ff16620005515760405162461bcd60e51b815260206004820152602b602482015260008051602062003ca683398151915260448201526a6e697469616c697a696e6760a81b606482015260840162000186565b6200055b62000e5c565b565b6200056762000ec3565b6001600160a01b038116620005ce5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000186565b620005d98162000f1f565b50565b60678190556040805160208082018490528251808303909101815290820190915260005b600060008051602062003c86833981519152836040516200062291906200124c565b60405180910390a35050565b60688054600160401b600160801b0319166801000000000000000063ffffffff85811691820263ffffffff60601b1916929092176c010000000000000000000000009285169290920291909117909155600160f81b602083811b67ffffffff0000000016909217176066819055606554604080519384019190915282015260009060600160408051601f1981840301815291905290506001600060008051602062003c8683398151915283604051620006e891906200124c565b60405180910390a3505050565b620006ff62000e2f565b6001600160401b0316816001600160401b03161015620007515760405162461bcd60e51b815260206004820152601f602482015260008051602062003c66833981519152604482015260640162000186565b630bebc2006001600160401b0382161115620007b05760405162461bcd60e51b815260206004820181905260248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f2068696768604482015260640162000186565b606880546001600160401b0319166001600160401b038316908117909155604080516020808201939093528151808203909301835281019052600262000600565b6200082562000811600160008051602062003ce683398151915262001203565b60001b62000f7160201b620007581760201c565b6000036200055b576200055b6200084d600160008051602062003ce683398151915262001203565b60001b43620000d160201b62000fc61760201c565b6001600160a01b038116158015906200089857506001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14155b8015620008ac5750620008aa62000f75565b155b15620005d957601260ff16816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620008f6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200091c919062001281565b60ff1614620009855760405162461bcd60e51b815260206004820152602e60248201527f53797374656d436f6e6669673a2062616420646563696d616c73206f6620676160448201526d39903830bcb4b733903a37b5b2b760911b606482015260840162000186565b600062000a05826001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015620009ca573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620009f49190810190620012c3565b62000fa960201b62000fe61760201c565b9050600062000a4c836001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620009ca573d6000803e3d6000fd5b905062000a6883601284846200104160201b620010891760201c565b62000a726200111d565b6040516371cfaa3f60e01b81526001600160a01b03858116600483015260126024830152604482018590526064820184905291909116906371cfaa3f90608401600060405180830381600087803b15801562000acd57600080fd5b505af115801562000ae2573d6000803e3d6000fd5b50505050505050565b8060a001516001600160801b0316816060015163ffffffff16111562000b7a5760405162461bcd60e51b815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d617820626173650000000000000000000000606482015260840162000186565b6001816040015160ff161162000beb5760405162461bcd60e51b815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201526e65206c6172676572207468616e203160881b606482015260840162000186565b606854608082015182516001600160401b039092169162000c0d91906200137b565b63ffffffff16111562000c525760405162461bcd60e51b815260206004820152601f602482015260008051602062003c66833981519152604482015260640162000186565b6000816020015160ff161162000cc35760405162461bcd60e51b815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201526e06965722063616e6e6f74206265203608c1b606482015260840162000186565b8051602082015163ffffffff82169160ff9091169062000ce5908290620013a6565b62000cf19190620013d8565b63ffffffff161462000d6c5760405162461bcd60e51b815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d6974000000000000000000606482015260840162000186565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff96871664ffffffffff199095169490941764010000000060ff948516021764ffffffffff60281b191665010000000000939092169290920263ffffffff60301b19161766010000000000009185169190910217600160501b600160f01b0319166a01000000000000000000009390941692909202600160701b600160f01b03191692909217600160701b6001600160801b0390921691909102179055565b60695460009062000e579063ffffffff6a010000000000000000000082048116911662001407565b905090565b600054610100900460ff1662000eb85760405162461bcd60e51b815260206004820152602b602482015260008051602062003ca683398151915260448201526a6e697469616c697a696e6760a81b606482015260840162000186565b6200055b3362000f1f565b6033546001600160a01b031633146200055b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000186565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b5490565b60008062000f826200113f565b506001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b6000602082511115620010255760405162461bcd60e51b815260206004820152603660248201527f476173506179696e67546f6b656e3a20737472696e672063616e6e6f7420626560448201527f2067726561746572207468616e20333220627974657300000000000000000000606482015260840162000186565b6200103b826200116060201b6200115b1760201c565b92915050565b6200108b62001061600160008051602062003c4683398151915262001203565b60001b856001600160a01b031660a08660ff16901b1760001b620000d160201b62000fc61760201c565b620010d1620010bc60017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d62001203565b60001b83620000d160201b62000fc61760201c565b620011176200110260017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd0576462001203565b60001b82620000d160201b62000fc61760201c565b50505050565b600062000e5762000811600160008051602062003cc683398151915262001203565b600080620011576200118a60201b620011841760201c565b90939092509050565b805160218110620011795763ec92f9a36000526004601cfd5b9081015160209190910360031b1b90565b60008080620011ae62000811600160008051602062003c4683398151915262001203565b6001600160a01b0381169350905082620011e1575073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee92601292509050565b60a081901c9150509091565b634e487b7160e01b600052601160045260246000fd5b600082821015620012185762001218620011ed565b500390565b60005b838110156200123a57818101518382015260200162001220565b83811115620011175750506000910152565b60208152600082518060208401526200126d8160408501602087016200121d565b601f01601f19169190910160400192915050565b6000602082840312156200129457600080fd5b815160ff81168114620012a657600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600060208284031215620012d657600080fd5b81516001600160401b0380821115620012ee57600080fd5b818401915084601f8301126200130357600080fd5b815181811115620013185762001318620012ad565b604051601f8201601f19908116603f01168101908382118183101715620013435762001343620012ad565b816040528281528760208487010111156200135d57600080fd5b620013708360208301602088016200121d565b979650505050505050565b600063ffffffff8083168185168083038211156200139d576200139d620011ed565b01949350505050565b600063ffffffff80841680620013cc57634e487b7160e01b600052601260045260246000fd5b92169190910492915050565b600063ffffffff80831681851681830481118215151615620013fe57620013fe620011ed565b02949350505050565b60006001600160401b038281168482168083038211156200139d576200139d620011ed565b61280a806200143c6000396000f3fe608060405234801561001057600080fd5b50600436106102de5760003560e01c8063a711986911610186578063e0e2016d116100e3578063f2fde38b11610097578063f8c68de011610071578063f8c68de0146106e2578063fd32aa0f146106ea578063ffa1ad74146106f257600080fd5b8063f2fde38b146106b2578063f45e65d8146106c5578063f68016b7146106ce57600080fd5b8063e81b2c6d116100c8578063e81b2c6d14610681578063ec7075171461068a578063f2b4e617146106aa57600080fd5b8063e0e2016d14610671578063e2a3285c1461067957600080fd5b8063c9b26f611161013a578063d84447151161011f578063d84447151461064e578063dac6e63a14610656578063db9040fa1461065e57600080fd5b8063c9b26f6114610507578063cc731b021461051a57600080fd5b8063bc49ce5f1161016b578063bc49ce5f146104c6578063bfb14fb7146104ce578063c4e8ddfa146104ff57600080fd5b8063a7119869146104ab578063b40a817c146104b357600080fd5b80634397dfef1161023f578063550fcdc9116101f35780638da5cb5b116101cd5780638da5cb5b14610472578063935f029e146104905780639b7d7f0a146104a357600080fd5b8063550fcdc91461045a5780635d73369c14610462578063715018a61461046a57600080fd5b80634add321d116102245780634add321d146103e95780634f16540b146103f157806354fd4d501461041857600080fd5b80634397dfef146103ab57806348cd4cb1146103e157600080fd5b806318d13918116102965780631fd19ee11161027b5780631fd19ee114610378578063213268491461038057806321d7fde51461039857600080fd5b806318d139181461035b57806319f5cea81461037057600080fd5b80630a49cb03116102c75780630a49cb031461032b5780630ae14b1b146103335780630c18c1621461035257600080fd5b806306c92657146102e3578063078f29cf146102fe575b600080fd5b6102eb6106fa565b6040519081526020015b60405180910390f35b610306610728565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102f5565b610306610761565b630bebc2005b60405167ffffffffffffffff90911681526020016102f5565b6102eb60655481565b61036e610369366004612241565b610791565b005b6102eb6107a5565b6103066107d0565b6103886107fa565b60405190151581526020016102f5565b61036e6103a6366004612277565b610839565b6103b361084f565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835260ff9091166020830152016102f5565b6102eb610863565b610339610893565b6102eb7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b60408051808201909152600c81527f322e332e302d626574612e32000000000000000000000000000000000000000060208201525b6040516102f59190612320565b61044d6108b9565b6102eb6108c3565b61036e6108ee565b60335473ffffffffffffffffffffffffffffffffffffffff16610306565b61036e61049e366004612333565b610902565b610306610914565b610306610944565b61036e6104c136600461236d565b610974565b6102eb610985565b6068546104ea9068010000000000000000900463ffffffff1681565b60405163ffffffff90911681526020016102f5565b6103066109b0565b61036e610515366004612388565b6109e0565b6105de6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b6040516102f59190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b61044d6109f1565b6103066109fb565b61036e61066c3660046124bb565b610a2b565b6102eb610e36565b6102eb610e61565b6102eb60675481565b6068546104ea906c01000000000000000000000000900463ffffffff1681565b610306610e8c565b61036e6106c0366004612241565b610ebc565b6102eb60665481565b6068546103399067ffffffffffffffff1681565b6102eb610f70565b6102eb610f9b565b6102eb600081565b61072560017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b81565b600061075c61075860017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b5490565b905090565b600061075c61075860017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b610799611201565b6107a281611282565b50565b61072560017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b600061075c7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b60008061080561084f565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b610841611201565b61084b828261133f565b5050565b60008061085a611184565b90939092509050565b600061075c61075860017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b60695460009061075c9063ffffffff6a0100000000000000000000820481169116612654565b606061075c61147d565b61072560017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b6108f6611201565b610900600061153e565b565b61090a611201565b61084b82826115b5565b600061075c61075860017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b600061075c61075860017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b61097c611201565b6107a28161168b565b61072560017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b600061075c61075860017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b6109e8611201565b6107a2816117e1565b606061075c611809565b600061075c61075860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b600054610100900460ff1615808015610a4b5750600054600160ff909116105b80610a655750303b158015610a65575060005460ff166001145b610af6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610b5457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b5c6118bf565b610b658a610ebc565b610b6e876117e1565b610b78898961133f565b610b818661168b565b610baa7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08869055565b610bdd610bd860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b849055565b610c11610c0b60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b83519055565b610c48610c3f60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b60208401519055565b610c7f610c7660017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b60408401519055565b610cb6610cad60017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b60608401519055565b610ced610ce460017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b60808401519055565b610d24610d1b60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b60a08401519055565b610d2c61195e565b610d398260c001516119c6565b610d4284611cd0565b610d4a610893565b67ffffffffffffffff168667ffffffffffffffff161015610dc7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b8015610e2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b61072560017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b61072560017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b600061075c61075860017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b610ec4611201565b73ffffffffffffffffffffffffffffffffffffffff8116610f67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610aed565b6107a28161153e565b61072560017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b61072560017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b9055565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600060208251111561107a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f476173506179696e67546f6b656e3a20737472696e672063616e6e6f7420626560448201527f2067726561746572207468616e203332206279746573000000000000000000006064820152608401610aed565b6110838261115b565b92915050565b6110ef6110b760017f04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec61263d565b74ff000000000000000000000000000000000000000060a086901b1673ffffffffffffffffffffffffffffffffffffffff8716179055565b61112261111d60017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d61263d565b839055565b61115561115060017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd0576461263d565b829055565b50505050565b8051602181106111735763ec92f9a36000526004601cfd5b9081015160209190910360031b1b90565b600080806111b661075860017f04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec61263d565b73ffffffffffffffffffffffffffffffffffffffff811693509050826111f5575073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee92601292509050565b60a081901c9150509091565b60335473ffffffffffffffffffffffffffffffffffffffff163314610900576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610aed565b6112ab7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060035b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be836040516113339190612320565b60405180910390a35050565b606880547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000063ffffffff8581169182027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16929092176c0100000000000000000000000092851692909202919091179091557f0100000000000000000000000000000000000000000000000000000000000000602083811b67ffffffff000000001690921717606681905560655460408051938401919091528201526000906060015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be836040516114709190612320565b60405180910390a3505050565b60606000611489611184565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff82160161150257505060408051808201909152600381527f4554480000000000000000000000000000000000000000000000000000000000602082015290565b61153861153361075860017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd0576461263d565b612144565b91505090565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b7fff00000000000000000000000000000000000000000000000000000000000000811615611665576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f53797374656d436f6e6669673a207363616c61722065786365656473206d617860448201527f2e000000000000000000000000000000000000000000000000000000000000006064820152608401610aed565b60658290556066819055604080516020810184905290810182905260009060600161140d565b611693610893565b67ffffffffffffffff168167ffffffffffffffff161015611710576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b630bebc20067ffffffffffffffff82161115611788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f20686967686044820152606401610aed565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002611302565b6067819055604080516020808201849052825180830390910181529082019091526000611302565b60606000611815611184565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff82160161188e57505060408051808201909152600581527f4574686572000000000000000000000000000000000000000000000000000000602082015290565b61153861153361075860017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d61263d565b600054610100900460ff16611956576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610aed565b610900612178565b61198c61075860017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b600003610900576109006119c160017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b439055565b73ffffffffffffffffffffffffffffffffffffffff811615801590611a15575073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14155b8015611a265750611a246107fa565b155b156107a257601260ff168173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a9f9190612680565b60ff1614611b2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f53797374656d436f6e6669673a2062616420646563696d616c73206f6620676160448201527f7320706179696e6720746f6b656e0000000000000000000000000000000000006064820152608401610aed565b6000611bca8273ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015611b7f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611bc5919081019061269d565b610fe6565b90506000611c1c8373ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611b7f573d6000803e3d6000fd5b9050611c2b8360128484611089565b611c33610761565b6040517f71cfaa3f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015260126024830152604482018590526064820184905291909116906371cfaa3f90608401600060405180830381600087803b158015611cb357600080fd5b505af1158015611cc7573d6000803e3d6000fd5b50505050505050565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff161115611d80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d6178206261736500000000000000000000006064820152608401610aed565b6001816040015160ff1611611e17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e203100000000000000000000000000000000006064820152608401610aed565b6068546080820151825167ffffffffffffffff90921691611e389190612768565b63ffffffff161115611ea6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b6000816020015160ff1611611f3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f74206265203000000000000000000000000000000000006064820152608401610aed565b8051602082015163ffffffff82169160ff90911690611f5d908290612787565b611f6791906127d1565b63ffffffff1614611ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d69740000000000000000006064820152608401610aed565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b60405160005b82811a1561215a5760010161214a565b80825260208201838152600082820152505060408101604052919050565b600054610100900460ff1661220f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610aed565b6109003361153e565b803573ffffffffffffffffffffffffffffffffffffffff8116811461223c57600080fd5b919050565b60006020828403121561225357600080fd5b61225c82612218565b9392505050565b803563ffffffff8116811461223c57600080fd5b6000806040838503121561228a57600080fd5b61229383612263565b91506122a160208401612263565b90509250929050565b60005b838110156122c55781810151838201526020016122ad565b838111156111555750506000910152565b600081518084526122ee8160208601602086016122aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061225c60208301846122d6565b6000806040838503121561234657600080fd5b50508035926020909101359150565b803567ffffffffffffffff8116811461223c57600080fd5b60006020828403121561237f57600080fd5b61225c82612355565b60006020828403121561239a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff811182821017156123f3576123f36123a1565b60405290565b60ff811681146107a257600080fd5b600060e0828403121561241a57600080fd5b60405160e0810181811067ffffffffffffffff8211171561243d5761243d6123a1565b60405290508061244c83612218565b815261245a60208401612218565b602082015261246b60408401612218565b604082015261247c60608401612218565b606082015261248d60808401612218565b608082015261249e60a08401612218565b60a08201526124af60c08401612218565b60c08201525092915050565b6000806000806000806000806000898b036102808112156124db57600080fd5b6124e48b612218565b99506124f260208c01612263565b985061250060408c01612263565b975060608b0135965061251560808c01612355565b955061252360a08c01612218565b945060c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff408201121561255557600080fd5b5061255e6123d0565b61256a60c08c01612263565b815260e08b013561257a816123f9565b60208201526101008b013561258e816123f9565b60408201526125a06101208c01612263565b60608201526125b26101408c01612263565b60808201526101608b01356fffffffffffffffffffffffffffffffff811681146125db57600080fd5b60a082015292506125ef6101808b01612218565b91506125ff8b6101a08c01612408565b90509295985092959850929598565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561264f5761264f61260e565b500390565b600067ffffffffffffffff8083168185168083038211156126775761267761260e565b01949350505050565b60006020828403121561269257600080fd5b815161225c816123f9565b6000602082840312156126af57600080fd5b815167ffffffffffffffff808211156126c757600080fd5b818401915084601f8301126126db57600080fd5b8151818111156126ed576126ed6123a1565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612733576127336123a1565b8160405282815287602084870101111561274c57600080fd5b61275d8360208301602088016122aa565b979650505050505050565b600063ffffffff8083168185168083038211156126775761267761260e565b600063ffffffff808416806127c5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff808316818516818304811182151516156127f4576127f461260e565b0294935050505056fea164736f6c634300080f000a04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77001d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420694b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ada11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x60806040523480156200001157600080fd5b506200004962000032600160008051602062003ce683398151915262001203565b60001b600019620000d160201b62000fc61760201c565b6040805160c080820183526001808352602080840182905260028486015260006060808601829052608080870183905260a0808801849052885160e081018a528481529485018490529784018390529083018290528201819052948101859052918201849052620000cb9361dead9390928392839290918391908290620000d5565b6200142c565b9055565b600054610100900460ff1615808015620000f65750600054600160ff909116105b806200012657506200011330620004e660201b62000fca1760201c565b15801562000126575060005460ff166001145b6200018f5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff191660011790558015620001b3576000805461ff0019166101001790555b620001bd620004f5565b620001c88a6200055d565b620001d387620005dc565b620001df89896200062e565b620001ea86620006f5565b620002217f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0886620000d160201b62000fc61760201c565b620002676200025260017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59862001203565b60001b84620000d160201b62000fc61760201c565b620002b16200029860017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063762001203565b60001b8360000151620000d160201b62000fc61760201c565b620002fb620002e260017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a862001203565b60001b8360200151620000d160201b62000fc61760201c565b620003456200032c60017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637762001203565b60001b8360400151620000d160201b62000fc61760201c565b6200038f6200037660017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90762001203565b60001b8360600151620000d160201b62000fc61760201c565b620003c8620003af600160008051602062003cc683398151915262001203565b60001b8360800151620000d160201b62000fc61760201c565b62000412620003f960017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d62001203565b60001b8360a00151620000d160201b62000fc61760201c565b6200041c620007f1565b60c08201516200042c9062000862565b620004378462000aeb565b6200044162000e2f565b6001600160401b0316866001600160401b03161015620004935760405162461bcd60e51b815260206004820152601f602482015260008051602062003c66833981519152604482015260640162000186565b8015620004da576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b6001600160a01b03163b151590565b600054610100900460ff16620005515760405162461bcd60e51b815260206004820152602b602482015260008051602062003ca683398151915260448201526a6e697469616c697a696e6760a81b606482015260840162000186565b6200055b62000e5c565b565b6200056762000ec3565b6001600160a01b038116620005ce5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000186565b620005d98162000f1f565b50565b60678190556040805160208082018490528251808303909101815290820190915260005b600060008051602062003c86833981519152836040516200062291906200124c565b60405180910390a35050565b60688054600160401b600160801b0319166801000000000000000063ffffffff85811691820263ffffffff60601b1916929092176c010000000000000000000000009285169290920291909117909155600160f81b602083811b67ffffffff0000000016909217176066819055606554604080519384019190915282015260009060600160408051601f1981840301815291905290506001600060008051602062003c8683398151915283604051620006e891906200124c565b60405180910390a3505050565b620006ff62000e2f565b6001600160401b0316816001600160401b03161015620007515760405162461bcd60e51b815260206004820152601f602482015260008051602062003c66833981519152604482015260640162000186565b630bebc2006001600160401b0382161115620007b05760405162461bcd60e51b815260206004820181905260248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f2068696768604482015260640162000186565b606880546001600160401b0319166001600160401b038316908117909155604080516020808201939093528151808203909301835281019052600262000600565b6200082562000811600160008051602062003ce683398151915262001203565b60001b62000f7160201b620007581760201c565b6000036200055b576200055b6200084d600160008051602062003ce683398151915262001203565b60001b43620000d160201b62000fc61760201c565b6001600160a01b038116158015906200089857506001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14155b8015620008ac5750620008aa62000f75565b155b15620005d957601260ff16816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620008f6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200091c919062001281565b60ff1614620009855760405162461bcd60e51b815260206004820152602e60248201527f53797374656d436f6e6669673a2062616420646563696d616c73206f6620676160448201526d39903830bcb4b733903a37b5b2b760911b606482015260840162000186565b600062000a05826001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015620009ca573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620009f49190810190620012c3565b62000fa960201b62000fe61760201c565b9050600062000a4c836001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620009ca573d6000803e3d6000fd5b905062000a6883601284846200104160201b620010891760201c565b62000a726200111d565b6040516371cfaa3f60e01b81526001600160a01b03858116600483015260126024830152604482018590526064820184905291909116906371cfaa3f90608401600060405180830381600087803b15801562000acd57600080fd5b505af115801562000ae2573d6000803e3d6000fd5b50505050505050565b8060a001516001600160801b0316816060015163ffffffff16111562000b7a5760405162461bcd60e51b815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d617820626173650000000000000000000000606482015260840162000186565b6001816040015160ff161162000beb5760405162461bcd60e51b815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201526e65206c6172676572207468616e203160881b606482015260840162000186565b606854608082015182516001600160401b039092169162000c0d91906200137b565b63ffffffff16111562000c525760405162461bcd60e51b815260206004820152601f602482015260008051602062003c66833981519152604482015260640162000186565b6000816020015160ff161162000cc35760405162461bcd60e51b815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201526e06965722063616e6e6f74206265203608c1b606482015260840162000186565b8051602082015163ffffffff82169160ff9091169062000ce5908290620013a6565b62000cf19190620013d8565b63ffffffff161462000d6c5760405162461bcd60e51b815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d6974000000000000000000606482015260840162000186565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff96871664ffffffffff199095169490941764010000000060ff948516021764ffffffffff60281b191665010000000000939092169290920263ffffffff60301b19161766010000000000009185169190910217600160501b600160f01b0319166a01000000000000000000009390941692909202600160701b600160f01b03191692909217600160701b6001600160801b0390921691909102179055565b60695460009062000e579063ffffffff6a010000000000000000000082048116911662001407565b905090565b600054610100900460ff1662000eb85760405162461bcd60e51b815260206004820152602b602482015260008051602062003ca683398151915260448201526a6e697469616c697a696e6760a81b606482015260840162000186565b6200055b3362000f1f565b6033546001600160a01b031633146200055b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000186565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b5490565b60008062000f826200113f565b506001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b6000602082511115620010255760405162461bcd60e51b815260206004820152603660248201527f476173506179696e67546f6b656e3a20737472696e672063616e6e6f7420626560448201527f2067726561746572207468616e20333220627974657300000000000000000000606482015260840162000186565b6200103b826200116060201b6200115b1760201c565b92915050565b6200108b62001061600160008051602062003c4683398151915262001203565b60001b856001600160a01b031660a08660ff16901b1760001b620000d160201b62000fc61760201c565b620010d1620010bc60017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d62001203565b60001b83620000d160201b62000fc61760201c565b620011176200110260017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd0576462001203565b60001b82620000d160201b62000fc61760201c565b50505050565b600062000e5762000811600160008051602062003cc683398151915262001203565b600080620011576200118a60201b620011841760201c565b90939092509050565b805160218110620011795763ec92f9a36000526004601cfd5b9081015160209190910360031b1b90565b60008080620011ae62000811600160008051602062003c4683398151915262001203565b6001600160a01b0381169350905082620011e1575073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee92601292509050565b60a081901c9150509091565b634e487b7160e01b600052601160045260246000fd5b600082821015620012185762001218620011ed565b500390565b60005b838110156200123a57818101518382015260200162001220565b83811115620011175750506000910152565b60208152600082518060208401526200126d8160408501602087016200121d565b601f01601f19169190910160400192915050565b6000602082840312156200129457600080fd5b815160ff81168114620012a657600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600060208284031215620012d657600080fd5b81516001600160401b0380821115620012ee57600080fd5b818401915084601f8301126200130357600080fd5b815181811115620013185762001318620012ad565b604051601f8201601f19908116603f01168101908382118183101715620013435762001343620012ad565b816040528281528760208487010111156200135d57600080fd5b620013708360208301602088016200121d565b979650505050505050565b600063ffffffff8083168185168083038211156200139d576200139d620011ed565b01949350505050565b600063ffffffff80841680620013cc57634e487b7160e01b600052601260045260246000fd5b92169190910492915050565b600063ffffffff80831681851681830481118215151615620013fe57620013fe620011ed565b02949350505050565b60006001600160401b038281168482168083038211156200139d576200139d620011ed565b61280a806200143c6000396000f3fe608060405234801561001057600080fd5b50600436106102de5760003560e01c8063a711986911610186578063e0e2016d116100e3578063f2fde38b11610097578063f8c68de011610071578063f8c68de0146106e2578063fd32aa0f146106ea578063ffa1ad74146106f257600080fd5b8063f2fde38b146106b2578063f45e65d8146106c5578063f68016b7146106ce57600080fd5b8063e81b2c6d116100c8578063e81b2c6d14610681578063ec7075171461068a578063f2b4e617146106aa57600080fd5b8063e0e2016d14610671578063e2a3285c1461067957600080fd5b8063c9b26f611161013a578063d84447151161011f578063d84447151461064e578063dac6e63a14610656578063db9040fa1461065e57600080fd5b8063c9b26f6114610507578063cc731b021461051a57600080fd5b8063bc49ce5f1161016b578063bc49ce5f146104c6578063bfb14fb7146104ce578063c4e8ddfa146104ff57600080fd5b8063a7119869146104ab578063b40a817c146104b357600080fd5b80634397dfef1161023f578063550fcdc9116101f35780638da5cb5b116101cd5780638da5cb5b14610472578063935f029e146104905780639b7d7f0a146104a357600080fd5b8063550fcdc91461045a5780635d73369c14610462578063715018a61461046a57600080fd5b80634add321d116102245780634add321d146103e95780634f16540b146103f157806354fd4d501461041857600080fd5b80634397dfef146103ab57806348cd4cb1146103e157600080fd5b806318d13918116102965780631fd19ee11161027b5780631fd19ee114610378578063213268491461038057806321d7fde51461039857600080fd5b806318d139181461035b57806319f5cea81461037057600080fd5b80630a49cb03116102c75780630a49cb031461032b5780630ae14b1b146103335780630c18c1621461035257600080fd5b806306c92657146102e3578063078f29cf146102fe575b600080fd5b6102eb6106fa565b6040519081526020015b60405180910390f35b610306610728565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102f5565b610306610761565b630bebc2005b60405167ffffffffffffffff90911681526020016102f5565b6102eb60655481565b61036e610369366004612241565b610791565b005b6102eb6107a5565b6103066107d0565b6103886107fa565b60405190151581526020016102f5565b61036e6103a6366004612277565b610839565b6103b361084f565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835260ff9091166020830152016102f5565b6102eb610863565b610339610893565b6102eb7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b60408051808201909152600c81527f322e332e302d626574612e32000000000000000000000000000000000000000060208201525b6040516102f59190612320565b61044d6108b9565b6102eb6108c3565b61036e6108ee565b60335473ffffffffffffffffffffffffffffffffffffffff16610306565b61036e61049e366004612333565b610902565b610306610914565b610306610944565b61036e6104c136600461236d565b610974565b6102eb610985565b6068546104ea9068010000000000000000900463ffffffff1681565b60405163ffffffff90911681526020016102f5565b6103066109b0565b61036e610515366004612388565b6109e0565b6105de6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b6040516102f59190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b61044d6109f1565b6103066109fb565b61036e61066c3660046124bb565b610a2b565b6102eb610e36565b6102eb610e61565b6102eb60675481565b6068546104ea906c01000000000000000000000000900463ffffffff1681565b610306610e8c565b61036e6106c0366004612241565b610ebc565b6102eb60665481565b6068546103399067ffffffffffffffff1681565b6102eb610f70565b6102eb610f9b565b6102eb600081565b61072560017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b81565b600061075c61075860017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b5490565b905090565b600061075c61075860017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b610799611201565b6107a281611282565b50565b61072560017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b600061075c7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b60008061080561084f565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b610841611201565b61084b828261133f565b5050565b60008061085a611184565b90939092509050565b600061075c61075860017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b60695460009061075c9063ffffffff6a0100000000000000000000820481169116612654565b606061075c61147d565b61072560017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b6108f6611201565b610900600061153e565b565b61090a611201565b61084b82826115b5565b600061075c61075860017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b600061075c61075860017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b61097c611201565b6107a28161168b565b61072560017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b600061075c61075860017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b6109e8611201565b6107a2816117e1565b606061075c611809565b600061075c61075860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b600054610100900460ff1615808015610a4b5750600054600160ff909116105b80610a655750303b158015610a65575060005460ff166001145b610af6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610b5457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b5c6118bf565b610b658a610ebc565b610b6e876117e1565b610b78898961133f565b610b818661168b565b610baa7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08869055565b610bdd610bd860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b849055565b610c11610c0b60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b83519055565b610c48610c3f60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b60208401519055565b610c7f610c7660017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b60408401519055565b610cb6610cad60017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b60608401519055565b610ced610ce460017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b60808401519055565b610d24610d1b60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b60a08401519055565b610d2c61195e565b610d398260c001516119c6565b610d4284611cd0565b610d4a610893565b67ffffffffffffffff168667ffffffffffffffff161015610dc7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b8015610e2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b61072560017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b61072560017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b600061075c61075860017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b610ec4611201565b73ffffffffffffffffffffffffffffffffffffffff8116610f67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610aed565b6107a28161153e565b61072560017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b61072560017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b9055565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600060208251111561107a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f476173506179696e67546f6b656e3a20737472696e672063616e6e6f7420626560448201527f2067726561746572207468616e203332206279746573000000000000000000006064820152608401610aed565b6110838261115b565b92915050565b6110ef6110b760017f04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec61263d565b74ff000000000000000000000000000000000000000060a086901b1673ffffffffffffffffffffffffffffffffffffffff8716179055565b61112261111d60017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d61263d565b839055565b61115561115060017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd0576461263d565b829055565b50505050565b8051602181106111735763ec92f9a36000526004601cfd5b9081015160209190910360031b1b90565b600080806111b661075860017f04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec61263d565b73ffffffffffffffffffffffffffffffffffffffff811693509050826111f5575073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee92601292509050565b60a081901c9150509091565b60335473ffffffffffffffffffffffffffffffffffffffff163314610900576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610aed565b6112ab7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060035b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be836040516113339190612320565b60405180910390a35050565b606880547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000063ffffffff8581169182027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16929092176c0100000000000000000000000092851692909202919091179091557f0100000000000000000000000000000000000000000000000000000000000000602083811b67ffffffff000000001690921717606681905560655460408051938401919091528201526000906060015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be836040516114709190612320565b60405180910390a3505050565b60606000611489611184565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff82160161150257505060408051808201909152600381527f4554480000000000000000000000000000000000000000000000000000000000602082015290565b61153861153361075860017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd0576461263d565b612144565b91505090565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b7fff00000000000000000000000000000000000000000000000000000000000000811615611665576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f53797374656d436f6e6669673a207363616c61722065786365656473206d617860448201527f2e000000000000000000000000000000000000000000000000000000000000006064820152608401610aed565b60658290556066819055604080516020810184905290810182905260009060600161140d565b611693610893565b67ffffffffffffffff168167ffffffffffffffff161015611710576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b630bebc20067ffffffffffffffff82161115611788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f20686967686044820152606401610aed565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002611302565b6067819055604080516020808201849052825180830390910181529082019091526000611302565b60606000611815611184565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff82160161188e57505060408051808201909152600581527f4574686572000000000000000000000000000000000000000000000000000000602082015290565b61153861153361075860017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d61263d565b600054610100900460ff16611956576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610aed565b610900612178565b61198c61075860017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b600003610900576109006119c160017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b439055565b73ffffffffffffffffffffffffffffffffffffffff811615801590611a15575073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14155b8015611a265750611a246107fa565b155b156107a257601260ff168173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a9f9190612680565b60ff1614611b2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f53797374656d436f6e6669673a2062616420646563696d616c73206f6620676160448201527f7320706179696e6720746f6b656e0000000000000000000000000000000000006064820152608401610aed565b6000611bca8273ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015611b7f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611bc5919081019061269d565b610fe6565b90506000611c1c8373ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611b7f573d6000803e3d6000fd5b9050611c2b8360128484611089565b611c33610761565b6040517f71cfaa3f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015260126024830152604482018590526064820184905291909116906371cfaa3f90608401600060405180830381600087803b158015611cb357600080fd5b505af1158015611cc7573d6000803e3d6000fd5b50505050505050565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff161115611d80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d6178206261736500000000000000000000006064820152608401610aed565b6001816040015160ff1611611e17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e203100000000000000000000000000000000006064820152608401610aed565b6068546080820151825167ffffffffffffffff90921691611e389190612768565b63ffffffff161115611ea6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b6000816020015160ff1611611f3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f74206265203000000000000000000000000000000000006064820152608401610aed565b8051602082015163ffffffff82169160ff90911690611f5d908290612787565b611f6791906127d1565b63ffffffff1614611ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d69740000000000000000006064820152608401610aed565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b60405160005b82811a1561215a5760010161214a565b80825260208201838152600082820152505060408101604052919050565b600054610100900460ff1661220f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610aed565b6109003361153e565b803573ffffffffffffffffffffffffffffffffffffffff8116811461223c57600080fd5b919050565b60006020828403121561225357600080fd5b61225c82612218565b9392505050565b803563ffffffff8116811461223c57600080fd5b6000806040838503121561228a57600080fd5b61229383612263565b91506122a160208401612263565b90509250929050565b60005b838110156122c55781810151838201526020016122ad565b838111156111555750506000910152565b600081518084526122ee8160208601602086016122aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061225c60208301846122d6565b6000806040838503121561234657600080fd5b50508035926020909101359150565b803567ffffffffffffffff8116811461223c57600080fd5b60006020828403121561237f57600080fd5b61225c82612355565b60006020828403121561239a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff811182821017156123f3576123f36123a1565b60405290565b60ff811681146107a257600080fd5b600060e0828403121561241a57600080fd5b60405160e0810181811067ffffffffffffffff8211171561243d5761243d6123a1565b60405290508061244c83612218565b815261245a60208401612218565b602082015261246b60408401612218565b604082015261247c60608401612218565b606082015261248d60808401612218565b608082015261249e60a08401612218565b60a08201526124af60c08401612218565b60c08201525092915050565b6000806000806000806000806000898b036102808112156124db57600080fd5b6124e48b612218565b99506124f260208c01612263565b985061250060408c01612263565b975060608b0135965061251560808c01612355565b955061252360a08c01612218565b945060c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff408201121561255557600080fd5b5061255e6123d0565b61256a60c08c01612263565b815260e08b013561257a816123f9565b60208201526101008b013561258e816123f9565b60408201526125a06101208c01612263565b60608201526125b26101408c01612263565b60808201526101608b01356fffffffffffffffffffffffffffffffff811681146125db57600080fd5b60a082015292506125ef6101808b01612218565b91506125ff8b6101a08c01612408565b90509295985092959850929598565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561264f5761264f61260e565b500390565b600067ffffffffffffffff8083168185168083038211156126775761267761260e565b01949350505050565b60006020828403121561269257600080fd5b815161225c816123f9565b6000602082840312156126af57600080fd5b815167ffffffffffffffff808211156126c757600080fd5b818401915084601f8301126126db57600080fd5b8151818111156126ed576126ed6123a1565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612733576127336123a1565b8160405282815287602084870101111561274c57600080fd5b61275d8360208301602088016122aa565b979650505050505050565b600063ffffffff8083168185168083038211156126775761267761260e565b600063ffffffff808416806127c5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff808316818516818304811182151516156127f4576127f461260e565b0294935050505056fea164736f6c634300080f000a04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77001d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420694b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ada11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0", - "deployedCode": "0x608060405234801561001057600080fd5b50600436106102de5760003560e01c8063a711986911610186578063e0e2016d116100e3578063f2fde38b11610097578063f8c68de011610071578063f8c68de0146106e2578063fd32aa0f146106ea578063ffa1ad74146106f257600080fd5b8063f2fde38b146106b2578063f45e65d8146106c5578063f68016b7146106ce57600080fd5b8063e81b2c6d116100c8578063e81b2c6d14610681578063ec7075171461068a578063f2b4e617146106aa57600080fd5b8063e0e2016d14610671578063e2a3285c1461067957600080fd5b8063c9b26f611161013a578063d84447151161011f578063d84447151461064e578063dac6e63a14610656578063db9040fa1461065e57600080fd5b8063c9b26f6114610507578063cc731b021461051a57600080fd5b8063bc49ce5f1161016b578063bc49ce5f146104c6578063bfb14fb7146104ce578063c4e8ddfa146104ff57600080fd5b8063a7119869146104ab578063b40a817c146104b357600080fd5b80634397dfef1161023f578063550fcdc9116101f35780638da5cb5b116101cd5780638da5cb5b14610472578063935f029e146104905780639b7d7f0a146104a357600080fd5b8063550fcdc91461045a5780635d73369c14610462578063715018a61461046a57600080fd5b80634add321d116102245780634add321d146103e95780634f16540b146103f157806354fd4d501461041857600080fd5b80634397dfef146103ab57806348cd4cb1146103e157600080fd5b806318d13918116102965780631fd19ee11161027b5780631fd19ee114610378578063213268491461038057806321d7fde51461039857600080fd5b806318d139181461035b57806319f5cea81461037057600080fd5b80630a49cb03116102c75780630a49cb031461032b5780630ae14b1b146103335780630c18c1621461035257600080fd5b806306c92657146102e3578063078f29cf146102fe575b600080fd5b6102eb6106fa565b6040519081526020015b60405180910390f35b610306610728565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102f5565b610306610761565b630bebc2005b60405167ffffffffffffffff90911681526020016102f5565b6102eb60655481565b61036e610369366004612241565b610791565b005b6102eb6107a5565b6103066107d0565b6103886107fa565b60405190151581526020016102f5565b61036e6103a6366004612277565b610839565b6103b361084f565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835260ff9091166020830152016102f5565b6102eb610863565b610339610893565b6102eb7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b60408051808201909152600c81527f322e332e302d626574612e32000000000000000000000000000000000000000060208201525b6040516102f59190612320565b61044d6108b9565b6102eb6108c3565b61036e6108ee565b60335473ffffffffffffffffffffffffffffffffffffffff16610306565b61036e61049e366004612333565b610902565b610306610914565b610306610944565b61036e6104c136600461236d565b610974565b6102eb610985565b6068546104ea9068010000000000000000900463ffffffff1681565b60405163ffffffff90911681526020016102f5565b6103066109b0565b61036e610515366004612388565b6109e0565b6105de6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b6040516102f59190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b61044d6109f1565b6103066109fb565b61036e61066c3660046124bb565b610a2b565b6102eb610e36565b6102eb610e61565b6102eb60675481565b6068546104ea906c01000000000000000000000000900463ffffffff1681565b610306610e8c565b61036e6106c0366004612241565b610ebc565b6102eb60665481565b6068546103399067ffffffffffffffff1681565b6102eb610f70565b6102eb610f9b565b6102eb600081565b61072560017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b81565b600061075c61075860017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b5490565b905090565b600061075c61075860017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b610799611201565b6107a281611282565b50565b61072560017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b600061075c7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b60008061080561084f565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b610841611201565b61084b828261133f565b5050565b60008061085a611184565b90939092509050565b600061075c61075860017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b60695460009061075c9063ffffffff6a0100000000000000000000820481169116612654565b606061075c61147d565b61072560017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b6108f6611201565b610900600061153e565b565b61090a611201565b61084b82826115b5565b600061075c61075860017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b600061075c61075860017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b61097c611201565b6107a28161168b565b61072560017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b600061075c61075860017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b6109e8611201565b6107a2816117e1565b606061075c611809565b600061075c61075860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b600054610100900460ff1615808015610a4b5750600054600160ff909116105b80610a655750303b158015610a65575060005460ff166001145b610af6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610b5457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b5c6118bf565b610b658a610ebc565b610b6e876117e1565b610b78898961133f565b610b818661168b565b610baa7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08869055565b610bdd610bd860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b849055565b610c11610c0b60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b83519055565b610c48610c3f60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b60208401519055565b610c7f610c7660017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b60408401519055565b610cb6610cad60017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b60608401519055565b610ced610ce460017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b60808401519055565b610d24610d1b60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b60a08401519055565b610d2c61195e565b610d398260c001516119c6565b610d4284611cd0565b610d4a610893565b67ffffffffffffffff168667ffffffffffffffff161015610dc7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b8015610e2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b61072560017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b61072560017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b600061075c61075860017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b610ec4611201565b73ffffffffffffffffffffffffffffffffffffffff8116610f67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610aed565b6107a28161153e565b61072560017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b61072560017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b9055565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600060208251111561107a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f476173506179696e67546f6b656e3a20737472696e672063616e6e6f7420626560448201527f2067726561746572207468616e203332206279746573000000000000000000006064820152608401610aed565b6110838261115b565b92915050565b6110ef6110b760017f04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec61263d565b74ff000000000000000000000000000000000000000060a086901b1673ffffffffffffffffffffffffffffffffffffffff8716179055565b61112261111d60017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d61263d565b839055565b61115561115060017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd0576461263d565b829055565b50505050565b8051602181106111735763ec92f9a36000526004601cfd5b9081015160209190910360031b1b90565b600080806111b661075860017f04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec61263d565b73ffffffffffffffffffffffffffffffffffffffff811693509050826111f5575073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee92601292509050565b60a081901c9150509091565b60335473ffffffffffffffffffffffffffffffffffffffff163314610900576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610aed565b6112ab7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060035b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be836040516113339190612320565b60405180910390a35050565b606880547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000063ffffffff8581169182027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16929092176c0100000000000000000000000092851692909202919091179091557f0100000000000000000000000000000000000000000000000000000000000000602083811b67ffffffff000000001690921717606681905560655460408051938401919091528201526000906060015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be836040516114709190612320565b60405180910390a3505050565b60606000611489611184565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff82160161150257505060408051808201909152600381527f4554480000000000000000000000000000000000000000000000000000000000602082015290565b61153861153361075860017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd0576461263d565b612144565b91505090565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b7fff00000000000000000000000000000000000000000000000000000000000000811615611665576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f53797374656d436f6e6669673a207363616c61722065786365656473206d617860448201527f2e000000000000000000000000000000000000000000000000000000000000006064820152608401610aed565b60658290556066819055604080516020810184905290810182905260009060600161140d565b611693610893565b67ffffffffffffffff168167ffffffffffffffff161015611710576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b630bebc20067ffffffffffffffff82161115611788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f20686967686044820152606401610aed565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002611302565b6067819055604080516020808201849052825180830390910181529082019091526000611302565b60606000611815611184565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff82160161188e57505060408051808201909152600581527f4574686572000000000000000000000000000000000000000000000000000000602082015290565b61153861153361075860017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d61263d565b600054610100900460ff16611956576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610aed565b610900612178565b61198c61075860017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b600003610900576109006119c160017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b439055565b73ffffffffffffffffffffffffffffffffffffffff811615801590611a15575073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14155b8015611a265750611a246107fa565b155b156107a257601260ff168173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a9f9190612680565b60ff1614611b2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f53797374656d436f6e6669673a2062616420646563696d616c73206f6620676160448201527f7320706179696e6720746f6b656e0000000000000000000000000000000000006064820152608401610aed565b6000611bca8273ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015611b7f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611bc5919081019061269d565b610fe6565b90506000611c1c8373ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611b7f573d6000803e3d6000fd5b9050611c2b8360128484611089565b611c33610761565b6040517f71cfaa3f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015260126024830152604482018590526064820184905291909116906371cfaa3f90608401600060405180830381600087803b158015611cb357600080fd5b505af1158015611cc7573d6000803e3d6000fd5b50505050505050565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff161115611d80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d6178206261736500000000000000000000006064820152608401610aed565b6001816040015160ff1611611e17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e203100000000000000000000000000000000006064820152608401610aed565b6068546080820151825167ffffffffffffffff90921691611e389190612768565b63ffffffff161115611ea6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b6000816020015160ff1611611f3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f74206265203000000000000000000000000000000000006064820152608401610aed565b8051602082015163ffffffff82169160ff90911690611f5d908290612787565b611f6791906127d1565b63ffffffff1614611ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d69740000000000000000006064820152608401610aed565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b60405160005b82811a1561215a5760010161214a565b80825260208201838152600082820152505060408101604052919050565b600054610100900460ff1661220f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610aed565b6109003361153e565b803573ffffffffffffffffffffffffffffffffffffffff8116811461223c57600080fd5b919050565b60006020828403121561225357600080fd5b61225c82612218565b9392505050565b803563ffffffff8116811461223c57600080fd5b6000806040838503121561228a57600080fd5b61229383612263565b91506122a160208401612263565b90509250929050565b60005b838110156122c55781810151838201526020016122ad565b838111156111555750506000910152565b600081518084526122ee8160208601602086016122aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061225c60208301846122d6565b6000806040838503121561234657600080fd5b50508035926020909101359150565b803567ffffffffffffffff8116811461223c57600080fd5b60006020828403121561237f57600080fd5b61225c82612355565b60006020828403121561239a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff811182821017156123f3576123f36123a1565b60405290565b60ff811681146107a257600080fd5b600060e0828403121561241a57600080fd5b60405160e0810181811067ffffffffffffffff8211171561243d5761243d6123a1565b60405290508061244c83612218565b815261245a60208401612218565b602082015261246b60408401612218565b604082015261247c60608401612218565b606082015261248d60808401612218565b608082015261249e60a08401612218565b60a08201526124af60c08401612218565b60c08201525092915050565b6000806000806000806000806000898b036102808112156124db57600080fd5b6124e48b612218565b99506124f260208c01612263565b985061250060408c01612263565b975060608b0135965061251560808c01612355565b955061252360a08c01612218565b945060c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff408201121561255557600080fd5b5061255e6123d0565b61256a60c08c01612263565b815260e08b013561257a816123f9565b60208201526101008b013561258e816123f9565b60408201526125a06101208c01612263565b60608201526125b26101408c01612263565b60808201526101608b01356fffffffffffffffffffffffffffffffff811681146125db57600080fd5b60a082015292506125ef6101808b01612218565b91506125ff8b6101a08c01612408565b90509295985092959850929598565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561264f5761264f61260e565b500390565b600067ffffffffffffffff8083168185168083038211156126775761267761260e565b01949350505050565b60006020828403121561269257600080fd5b815161225c816123f9565b6000602082840312156126af57600080fd5b815167ffffffffffffffff808211156126c757600080fd5b818401915084601f8301126126db57600080fd5b8151818111156126ed576126ed6123a1565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612733576127336123a1565b8160405282815287602084870101111561274c57600080fd5b61275d8360208301602088016122aa565b979650505050505050565b600063ffffffff8083168185168083038211156126775761267761260e565b600063ffffffff808416806127c5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff808316818516818304811182151516156127f4576127f461260e565b0294935050505056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": true, - "newValue": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb19f" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": true, - "newValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "previousValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "previousValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": true, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", - "previousValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000067" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": true, - "newValue": "0x0100000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000066" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000065" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000069" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc597" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580636" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a7" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6376" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa906" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ac" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320c" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "previousValue": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "reverted": false, - "slot": "0xa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb19f" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000069" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000020100000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000069" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000020100000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000020100000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000069" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xcc731b02", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000020100000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000020100000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000069" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000dead", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x0c18c162", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000065" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf45e65d8", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0100000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0100000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000066" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xbfb14fb7", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xec707517", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xe81b2c6d", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000067" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf68016b7", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x1fd19ee1", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x48cd4cb1", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "previousValue": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "reverted": false, - "slot": "0xa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb19f" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xdac6e63a", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc597" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xa7119869", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580636" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xc4e8ddfa", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a7" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x078f29cf", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6376" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf2b4e617", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa906" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x0a49cb03", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ac" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9b7d7f0a", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320c" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x638627e586f5e36fe67a77519503a7c6da22f92b150d3c6055fd40bdcfe9ffd160806040523480156200001157600080fd5b50620000206000808062000026565b6200024b565b600054610100900460ff1615808015620000475750600054600160ff909116105b806200007757506200006430620001a160201b620005891760201c565b15801562000077575060005460ff166001145b620000e05760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000104576000805461ff0019166101001790555b603280546001600160a01b038086166001600160a01b03199283161790925560338054928516929091169190911790556200015484734200000000000000000000000000000000000010620001b0565b80156200019b576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6001600160a01b03163b151590565b600054610100900460ff166200021d5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000d7565b600380546001600160a01b039384166001600160a01b03199182161790915560048054929093169116179055565b612fad806200025b6000396000f3fe6080604052600436106101845760003560e01c80637f46ddb2116100d65780639a2ac6d51161007f578063c0c53b8b11610059578063c0c53b8b14610529578063c89701a214610549578063e11013dd1461057657600080fd5b80639a2ac6d5146104e3578063a9f9e675146104f6578063b1a1a8821461051657600080fd5b80638f601f66116100b05780638f601f661461047257806391c49bf814610407578063927ede2d146104b857600080fd5b80637f46ddb214610407578063838b252014610432578063870876231461045257600080fd5b806335e80ab31161013857806354fd4d501161011257806354fd4d501461036c57806358a997f6146103c25780635c975abb146103e257600080fd5b806335e80ab3146102f25780633cb747bf1461031f578063540abf731461034c57600080fd5b80631532ec34116101695780631532ec34146102755780631635f5fd1461028857806333d7e2bd1461029b57600080fd5b80630166a07a1461024257806309fc88431461026257600080fd5b3661023d57333b1561021d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b61023b333362030d40604051806020016040528060008152506105a5565b005b600080fd5b34801561024e57600080fd5b5061023b61025d366004612991565b6105b8565b61023b610270366004612a42565b6109d2565b61023b610283366004612a95565b610aa9565b61023b610296366004612a95565b610abd565b3480156102a757600080fd5b506033546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102fe57600080fd5b506032546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b34801561032b57600080fd5b506003546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b34801561035857600080fd5b5061023b610367366004612b08565b61101b565b34801561037857600080fd5b506103b56040518060400160405280600581526020017f322e322e3000000000000000000000000000000000000000000000000000000081525081565b6040516102e99190612bf5565b3480156103ce57600080fd5b5061023b6103dd366004612c08565b611060565b3480156103ee57600080fd5b506103f7611134565b60405190151581526020016102e9565b34801561041357600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff166102c8565b34801561043e57600080fd5b5061023b61044d366004612b08565b6111cd565b34801561045e57600080fd5b5061023b61046d366004612c08565b611212565b34801561047e57600080fd5b506104aa61048d366004612c8b565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102e9565b3480156104c457600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166102c8565b61023b6104f1366004612cc4565b6112e6565b34801561050257600080fd5b5061023b610511366004612991565b611328565b61023b610524366004612a42565b611337565b34801561053557600080fd5b5061023b610544366004612d27565b611408565b34801561055557600080fd5b506004546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b61023b610584366004612cc4565b611607565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6105b2848434858561164a565b50505050565b60035473ffffffffffffffffffffffffffffffffffffffff163314801561068b575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa15801561064f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106739190612d72565b73ffffffffffffffffffffffffffffffffffffffff16145b61073d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610214565b610745611134565b156107ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610214565b6107b5876118a9565b15610903576107c4878761190b565b610876576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610214565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156108e657600080fd5b505af11580156108fa573d6000803e3d6000fd5b50505050610985565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054610941908490612dbe565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c1683529390529190912091909155610985908585611a2b565b6109c9878787878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611aff92505050565b50505050505050565b333b15610a61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b610aa43333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061164a92505050565b505050565b610ab68585858585610abd565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610b90575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa158015610b54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b789190612d72565b73ffffffffffffffffffffffffffffffffffffffff16145b610c42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610214565b610c4a611134565b15610cb1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610214565b610cb9611b8d565b15610d46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2063616e6e6f742062726964676520455460448201527f48207769746820637573746f6d2067617320746f6b656e0000000000000000006064820152608401610214565b823414610dd5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e742072657175697265640000000000006064820152608401610214565b3073ffffffffffffffffffffffffffffffffffffffff851603610e7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c6600000000000000000000000000000000000000000000000000000000006064820152608401610214565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610f25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e6765720000000000000000000000000000000000000000000000006064820152608401610214565b610f6785858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bcc92505050565b6000610f84855a8660405180602001604052806000815250611c3f565b905080611013576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c656400000000000000000000000000000000000000000000000000000000006064820152608401610214565b505050505050565b6109c987873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c5792505050565b333b156110ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b61101386863333888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061201092505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156111a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c89190612dd5565b905090565b6109c987873388888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061201092505050565b333b156112a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b61101386863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c5792505050565b6105b233858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506105a592505050565b6109c9878787878787876105b8565b333b156113c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b610aa433338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506105a592505050565b600054610100900460ff16158080156114285750600054600160ff909116105b806114425750303b158015611442575060005460ff166001145b6114ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610214565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561152c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6032805473ffffffffffffffffffffffffffffffffffffffff8086167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255603380549285169290911691909117905561159f8473420000000000000000000000000000000000001061201f565b80156105b257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b6105b23385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061164a92505050565b611652611b8d565b156116df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2063616e6e6f742062726964676520455460448201527f48207769746820637573746f6d2067617320746f6b656e0000000000000000006064820152608401610214565b82341461176e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c756500006064820152608401610214565b61177a85858584612109565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9287929116907f1635f5fd00000000000000000000000000000000000000000000000000000000906117dd908b908b9086908a90602401612df7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b909216825261187092918890600401612e40565b6000604051808303818588803b15801561188957600080fd5b505af115801561189d573d6000803e3d6000fd5b50505050505050505050565b60006118d5827f1d1d8b630000000000000000000000000000000000000000000000000000000061217c565b806119055750611905827fec4fc8e30000000000000000000000000000000000000000000000000000000061217c565b92915050565b6000611937837f1d1d8b630000000000000000000000000000000000000000000000000000000061217c565b156119e0578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611987573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ab9190612d72565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611905565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611987573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610aa49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261219f565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b3868686604051611b7793929190612e85565b60405180910390a46110138686868686866122ab565b600080611b98612333565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e6318484604051611c2b929190612ec3565b60405180910390a36105b2848484846123d0565b6000806000835160208501868989f195945050505050565b3415611ce5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f5374616e646172644272696467653a2063616e6e6f742073656e642076616c7560448201527f65000000000000000000000000000000000000000000000000000000000000006064820152608401610214565b611cee876118a9565b15611e3c57611cfd878761190b565b611daf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610214565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b158015611e1f57600080fd5b505af1158015611e33573d6000803e3d6000fd5b50505050611ed0565b611e5e73ffffffffffffffffffffffffffffffffffffffff881686308661243d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054611e9c908490612edc565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611ede87878787878661249b565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9216907f0166a07a0000000000000000000000000000000000000000000000000000000090611f42908b908d908c908c908c908b90602401612ef4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611fd592918790600401612e40565b600060405180830381600087803b158015611fef57600080fd5b505af1158015612003573d6000803e3d6000fd5b5050505050505050505050565b6109c987878787878787611c57565b600054610100900460ff166120b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610214565b6003805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560048054929093169116179055565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051612168929190612ec3565b60405180910390a36105b284848484612529565b600061218783612588565b8015612198575061219883836125ec565b9392505050565b6000612201826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166126bb9092919063ffffffff16565b805190915015610aa4578080602001905181019061221f9190612dd5565b610aa4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610214565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd86868660405161232393929190612e85565b60405180910390a4505050505050565b603354604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa1580156123a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c79190612f4f565b90939092509050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d848460405161242f929190612ec3565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526105b29085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611a7d565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039686868660405161251393929190612e85565b60405180910390a46110138686868686866126d2565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5848460405161242f929190612ec3565b60006125b4827f01ffc9a7000000000000000000000000000000000000000000000000000000006125ec565b801561190557506125e5827fffffffff000000000000000000000000000000000000000000000000000000006125ec565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156126a4575060208210155b80156126b05750600081115b979650505050505050565b60606126ca848460008561274a565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf86868660405161232393929190612e85565b6060824710156127dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610214565b73ffffffffffffffffffffffffffffffffffffffff85163b61285a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610214565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516128839190612f84565b60006040518083038185875af1925050503d80600081146128c0576040519150601f19603f3d011682016040523d82523d6000602084013e6128c5565b606091505b50915091506126b0828286606083156128df575081612198565b8251156128ef5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102149190612bf5565b73ffffffffffffffffffffffffffffffffffffffff8116811461294557600080fd5b50565b60008083601f84011261295a57600080fd5b50813567ffffffffffffffff81111561297257600080fd5b60208301915083602082850101111561298a57600080fd5b9250929050565b600080600080600080600060c0888a0312156129ac57600080fd5b87356129b781612923565b965060208801356129c781612923565b955060408801356129d781612923565b945060608801356129e781612923565b93506080880135925060a088013567ffffffffffffffff811115612a0a57600080fd5b612a168a828b01612948565b989b979a50959850939692959293505050565b803563ffffffff81168114612a3d57600080fd5b919050565b600080600060408486031215612a5757600080fd5b612a6084612a29565b9250602084013567ffffffffffffffff811115612a7c57600080fd5b612a8886828701612948565b9497909650939450505050565b600080600080600060808688031215612aad57600080fd5b8535612ab881612923565b94506020860135612ac881612923565b935060408601359250606086013567ffffffffffffffff811115612aeb57600080fd5b612af788828901612948565b969995985093965092949392505050565b600080600080600080600060c0888a031215612b2357600080fd5b8735612b2e81612923565b96506020880135612b3e81612923565b95506040880135612b4e81612923565b945060608801359350612b6360808901612a29565b925060a088013567ffffffffffffffff811115612a0a57600080fd5b60005b83811015612b9a578181015183820152602001612b82565b838111156105b25750506000910152565b60008151808452612bc3816020860160208601612b7f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006121986020830184612bab565b60008060008060008060a08789031215612c2157600080fd5b8635612c2c81612923565b95506020870135612c3c81612923565b945060408701359350612c5160608801612a29565b9250608087013567ffffffffffffffff811115612c6d57600080fd5b612c7989828a01612948565b979a9699509497509295939492505050565b60008060408385031215612c9e57600080fd5b8235612ca981612923565b91506020830135612cb981612923565b809150509250929050565b60008060008060608587031215612cda57600080fd5b8435612ce581612923565b9350612cf360208601612a29565b9250604085013567ffffffffffffffff811115612d0f57600080fd5b612d1b87828801612948565b95989497509550505050565b600080600060608486031215612d3c57600080fd5b8335612d4781612923565b92506020840135612d5781612923565b91506040840135612d6781612923565b809150509250925092565b600060208284031215612d8457600080fd5b815161219881612923565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612dd057612dd0612d8f565b500390565b600060208284031215612de757600080fd5b8151801515811461219857600080fd5b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152612e366080830184612bab565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84168152606060208201526000612e6f6060830185612bab565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000612eba6060830184612bab565b95945050505050565b8281526040602082015260006126ca6040830184612bab565b60008219821115612eef57612eef612d8f565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a0830152612f4360c0830184612bab565b98975050505050505050565b60008060408385031215612f6257600080fd5b8251612f6d81612923565b602084015190925060ff81168114612cb957600080fd5b60008251612f96818460208701612b7f565b919091019291505056fea164736f6c634300080f000a", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x60806040523480156200001157600080fd5b50620000206000808062000026565b6200024b565b600054610100900460ff1615808015620000475750600054600160ff909116105b806200007757506200006430620001a160201b620005891760201c565b15801562000077575060005460ff166001145b620000e05760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000104576000805461ff0019166101001790555b603280546001600160a01b038086166001600160a01b03199283161790925560338054928516929091169190911790556200015484734200000000000000000000000000000000000010620001b0565b80156200019b576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6001600160a01b03163b151590565b600054610100900460ff166200021d5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000d7565b600380546001600160a01b039384166001600160a01b03199182161790915560048054929093169116179055565b612fad806200025b6000396000f3fe6080604052600436106101845760003560e01c80637f46ddb2116100d65780639a2ac6d51161007f578063c0c53b8b11610059578063c0c53b8b14610529578063c89701a214610549578063e11013dd1461057657600080fd5b80639a2ac6d5146104e3578063a9f9e675146104f6578063b1a1a8821461051657600080fd5b80638f601f66116100b05780638f601f661461047257806391c49bf814610407578063927ede2d146104b857600080fd5b80637f46ddb214610407578063838b252014610432578063870876231461045257600080fd5b806335e80ab31161013857806354fd4d501161011257806354fd4d501461036c57806358a997f6146103c25780635c975abb146103e257600080fd5b806335e80ab3146102f25780633cb747bf1461031f578063540abf731461034c57600080fd5b80631532ec34116101695780631532ec34146102755780631635f5fd1461028857806333d7e2bd1461029b57600080fd5b80630166a07a1461024257806309fc88431461026257600080fd5b3661023d57333b1561021d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b61023b333362030d40604051806020016040528060008152506105a5565b005b600080fd5b34801561024e57600080fd5b5061023b61025d366004612991565b6105b8565b61023b610270366004612a42565b6109d2565b61023b610283366004612a95565b610aa9565b61023b610296366004612a95565b610abd565b3480156102a757600080fd5b506033546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102fe57600080fd5b506032546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b34801561032b57600080fd5b506003546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b34801561035857600080fd5b5061023b610367366004612b08565b61101b565b34801561037857600080fd5b506103b56040518060400160405280600581526020017f322e322e3000000000000000000000000000000000000000000000000000000081525081565b6040516102e99190612bf5565b3480156103ce57600080fd5b5061023b6103dd366004612c08565b611060565b3480156103ee57600080fd5b506103f7611134565b60405190151581526020016102e9565b34801561041357600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff166102c8565b34801561043e57600080fd5b5061023b61044d366004612b08565b6111cd565b34801561045e57600080fd5b5061023b61046d366004612c08565b611212565b34801561047e57600080fd5b506104aa61048d366004612c8b565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102e9565b3480156104c457600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166102c8565b61023b6104f1366004612cc4565b6112e6565b34801561050257600080fd5b5061023b610511366004612991565b611328565b61023b610524366004612a42565b611337565b34801561053557600080fd5b5061023b610544366004612d27565b611408565b34801561055557600080fd5b506004546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b61023b610584366004612cc4565b611607565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6105b2848434858561164a565b50505050565b60035473ffffffffffffffffffffffffffffffffffffffff163314801561068b575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa15801561064f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106739190612d72565b73ffffffffffffffffffffffffffffffffffffffff16145b61073d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610214565b610745611134565b156107ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610214565b6107b5876118a9565b15610903576107c4878761190b565b610876576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610214565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156108e657600080fd5b505af11580156108fa573d6000803e3d6000fd5b50505050610985565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054610941908490612dbe565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c1683529390529190912091909155610985908585611a2b565b6109c9878787878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611aff92505050565b50505050505050565b333b15610a61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b610aa43333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061164a92505050565b505050565b610ab68585858585610abd565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610b90575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa158015610b54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b789190612d72565b73ffffffffffffffffffffffffffffffffffffffff16145b610c42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610214565b610c4a611134565b15610cb1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610214565b610cb9611b8d565b15610d46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2063616e6e6f742062726964676520455460448201527f48207769746820637573746f6d2067617320746f6b656e0000000000000000006064820152608401610214565b823414610dd5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e742072657175697265640000000000006064820152608401610214565b3073ffffffffffffffffffffffffffffffffffffffff851603610e7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c6600000000000000000000000000000000000000000000000000000000006064820152608401610214565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610f25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e6765720000000000000000000000000000000000000000000000006064820152608401610214565b610f6785858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bcc92505050565b6000610f84855a8660405180602001604052806000815250611c3f565b905080611013576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c656400000000000000000000000000000000000000000000000000000000006064820152608401610214565b505050505050565b6109c987873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c5792505050565b333b156110ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b61101386863333888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061201092505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156111a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c89190612dd5565b905090565b6109c987873388888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061201092505050565b333b156112a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b61101386863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c5792505050565b6105b233858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506105a592505050565b6109c9878787878787876105b8565b333b156113c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b610aa433338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506105a592505050565b600054610100900460ff16158080156114285750600054600160ff909116105b806114425750303b158015611442575060005460ff166001145b6114ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610214565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561152c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6032805473ffffffffffffffffffffffffffffffffffffffff8086167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255603380549285169290911691909117905561159f8473420000000000000000000000000000000000001061201f565b80156105b257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b6105b23385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061164a92505050565b611652611b8d565b156116df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2063616e6e6f742062726964676520455460448201527f48207769746820637573746f6d2067617320746f6b656e0000000000000000006064820152608401610214565b82341461176e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c756500006064820152608401610214565b61177a85858584612109565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9287929116907f1635f5fd00000000000000000000000000000000000000000000000000000000906117dd908b908b9086908a90602401612df7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b909216825261187092918890600401612e40565b6000604051808303818588803b15801561188957600080fd5b505af115801561189d573d6000803e3d6000fd5b50505050505050505050565b60006118d5827f1d1d8b630000000000000000000000000000000000000000000000000000000061217c565b806119055750611905827fec4fc8e30000000000000000000000000000000000000000000000000000000061217c565b92915050565b6000611937837f1d1d8b630000000000000000000000000000000000000000000000000000000061217c565b156119e0578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611987573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ab9190612d72565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611905565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611987573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610aa49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261219f565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b3868686604051611b7793929190612e85565b60405180910390a46110138686868686866122ab565b600080611b98612333565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e6318484604051611c2b929190612ec3565b60405180910390a36105b2848484846123d0565b6000806000835160208501868989f195945050505050565b3415611ce5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f5374616e646172644272696467653a2063616e6e6f742073656e642076616c7560448201527f65000000000000000000000000000000000000000000000000000000000000006064820152608401610214565b611cee876118a9565b15611e3c57611cfd878761190b565b611daf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610214565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b158015611e1f57600080fd5b505af1158015611e33573d6000803e3d6000fd5b50505050611ed0565b611e5e73ffffffffffffffffffffffffffffffffffffffff881686308661243d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054611e9c908490612edc565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611ede87878787878661249b565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9216907f0166a07a0000000000000000000000000000000000000000000000000000000090611f42908b908d908c908c908c908b90602401612ef4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611fd592918790600401612e40565b600060405180830381600087803b158015611fef57600080fd5b505af1158015612003573d6000803e3d6000fd5b5050505050505050505050565b6109c987878787878787611c57565b600054610100900460ff166120b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610214565b6003805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560048054929093169116179055565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051612168929190612ec3565b60405180910390a36105b284848484612529565b600061218783612588565b8015612198575061219883836125ec565b9392505050565b6000612201826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166126bb9092919063ffffffff16565b805190915015610aa4578080602001905181019061221f9190612dd5565b610aa4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610214565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd86868660405161232393929190612e85565b60405180910390a4505050505050565b603354604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa1580156123a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c79190612f4f565b90939092509050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d848460405161242f929190612ec3565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526105b29085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611a7d565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039686868660405161251393929190612e85565b60405180910390a46110138686868686866126d2565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5848460405161242f929190612ec3565b60006125b4827f01ffc9a7000000000000000000000000000000000000000000000000000000006125ec565b801561190557506125e5827fffffffff000000000000000000000000000000000000000000000000000000006125ec565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156126a4575060208210155b80156126b05750600081115b979650505050505050565b60606126ca848460008561274a565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf86868660405161232393929190612e85565b6060824710156127dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610214565b73ffffffffffffffffffffffffffffffffffffffff85163b61285a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610214565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516128839190612f84565b60006040518083038185875af1925050503d80600081146128c0576040519150601f19603f3d011682016040523d82523d6000602084013e6128c5565b606091505b50915091506126b0828286606083156128df575081612198565b8251156128ef5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102149190612bf5565b73ffffffffffffffffffffffffffffffffffffffff8116811461294557600080fd5b50565b60008083601f84011261295a57600080fd5b50813567ffffffffffffffff81111561297257600080fd5b60208301915083602082850101111561298a57600080fd5b9250929050565b600080600080600080600060c0888a0312156129ac57600080fd5b87356129b781612923565b965060208801356129c781612923565b955060408801356129d781612923565b945060608801356129e781612923565b93506080880135925060a088013567ffffffffffffffff811115612a0a57600080fd5b612a168a828b01612948565b989b979a50959850939692959293505050565b803563ffffffff81168114612a3d57600080fd5b919050565b600080600060408486031215612a5757600080fd5b612a6084612a29565b9250602084013567ffffffffffffffff811115612a7c57600080fd5b612a8886828701612948565b9497909650939450505050565b600080600080600060808688031215612aad57600080fd5b8535612ab881612923565b94506020860135612ac881612923565b935060408601359250606086013567ffffffffffffffff811115612aeb57600080fd5b612af788828901612948565b969995985093965092949392505050565b600080600080600080600060c0888a031215612b2357600080fd5b8735612b2e81612923565b96506020880135612b3e81612923565b95506040880135612b4e81612923565b945060608801359350612b6360808901612a29565b925060a088013567ffffffffffffffff811115612a0a57600080fd5b60005b83811015612b9a578181015183820152602001612b82565b838111156105b25750506000910152565b60008151808452612bc3816020860160208601612b7f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006121986020830184612bab565b60008060008060008060a08789031215612c2157600080fd5b8635612c2c81612923565b95506020870135612c3c81612923565b945060408701359350612c5160608801612a29565b9250608087013567ffffffffffffffff811115612c6d57600080fd5b612c7989828a01612948565b979a9699509497509295939492505050565b60008060408385031215612c9e57600080fd5b8235612ca981612923565b91506020830135612cb981612923565b809150509250929050565b60008060008060608587031215612cda57600080fd5b8435612ce581612923565b9350612cf360208601612a29565b9250604085013567ffffffffffffffff811115612d0f57600080fd5b612d1b87828801612948565b95989497509550505050565b600080600060608486031215612d3c57600080fd5b8335612d4781612923565b92506020840135612d5781612923565b91506040840135612d6781612923565b809150509250925092565b600060208284031215612d8457600080fd5b815161219881612923565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612dd057612dd0612d8f565b500390565b600060208284031215612de757600080fd5b8151801515811461219857600080fd5b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152612e366080830184612bab565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84168152606060208201526000612e6f6060830185612bab565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000612eba6060830184612bab565b95945050505050565b8281526040602082015260006126ca6040830184612bab565b60008219821115612eef57612eef612d8f565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a0830152612f4360c0830184612bab565b98975050505050505050565b60008060408385031215612f6257600080fd5b8251612f6d81612923565b602084015190925060ff81168114612cb957600080fd5b60008251612f96818460208701612b7f565b919091019291505056fea164736f6c634300080f000a", - "deployedCode": "0x6080604052600436106101845760003560e01c80637f46ddb2116100d65780639a2ac6d51161007f578063c0c53b8b11610059578063c0c53b8b14610529578063c89701a214610549578063e11013dd1461057657600080fd5b80639a2ac6d5146104e3578063a9f9e675146104f6578063b1a1a8821461051657600080fd5b80638f601f66116100b05780638f601f661461047257806391c49bf814610407578063927ede2d146104b857600080fd5b80637f46ddb214610407578063838b252014610432578063870876231461045257600080fd5b806335e80ab31161013857806354fd4d501161011257806354fd4d501461036c57806358a997f6146103c25780635c975abb146103e257600080fd5b806335e80ab3146102f25780633cb747bf1461031f578063540abf731461034c57600080fd5b80631532ec34116101695780631532ec34146102755780631635f5fd1461028857806333d7e2bd1461029b57600080fd5b80630166a07a1461024257806309fc88431461026257600080fd5b3661023d57333b1561021d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b61023b333362030d40604051806020016040528060008152506105a5565b005b600080fd5b34801561024e57600080fd5b5061023b61025d366004612991565b6105b8565b61023b610270366004612a42565b6109d2565b61023b610283366004612a95565b610aa9565b61023b610296366004612a95565b610abd565b3480156102a757600080fd5b506033546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102fe57600080fd5b506032546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b34801561032b57600080fd5b506003546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b34801561035857600080fd5b5061023b610367366004612b08565b61101b565b34801561037857600080fd5b506103b56040518060400160405280600581526020017f322e322e3000000000000000000000000000000000000000000000000000000081525081565b6040516102e99190612bf5565b3480156103ce57600080fd5b5061023b6103dd366004612c08565b611060565b3480156103ee57600080fd5b506103f7611134565b60405190151581526020016102e9565b34801561041357600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff166102c8565b34801561043e57600080fd5b5061023b61044d366004612b08565b6111cd565b34801561045e57600080fd5b5061023b61046d366004612c08565b611212565b34801561047e57600080fd5b506104aa61048d366004612c8b565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102e9565b3480156104c457600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166102c8565b61023b6104f1366004612cc4565b6112e6565b34801561050257600080fd5b5061023b610511366004612991565b611328565b61023b610524366004612a42565b611337565b34801561053557600080fd5b5061023b610544366004612d27565b611408565b34801561055557600080fd5b506004546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b61023b610584366004612cc4565b611607565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6105b2848434858561164a565b50505050565b60035473ffffffffffffffffffffffffffffffffffffffff163314801561068b575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa15801561064f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106739190612d72565b73ffffffffffffffffffffffffffffffffffffffff16145b61073d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610214565b610745611134565b156107ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610214565b6107b5876118a9565b15610903576107c4878761190b565b610876576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610214565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156108e657600080fd5b505af11580156108fa573d6000803e3d6000fd5b50505050610985565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054610941908490612dbe565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c1683529390529190912091909155610985908585611a2b565b6109c9878787878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611aff92505050565b50505050505050565b333b15610a61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b610aa43333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061164a92505050565b505050565b610ab68585858585610abd565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610b90575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa158015610b54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b789190612d72565b73ffffffffffffffffffffffffffffffffffffffff16145b610c42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610214565b610c4a611134565b15610cb1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610214565b610cb9611b8d565b15610d46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2063616e6e6f742062726964676520455460448201527f48207769746820637573746f6d2067617320746f6b656e0000000000000000006064820152608401610214565b823414610dd5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e742072657175697265640000000000006064820152608401610214565b3073ffffffffffffffffffffffffffffffffffffffff851603610e7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c6600000000000000000000000000000000000000000000000000000000006064820152608401610214565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610f25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e6765720000000000000000000000000000000000000000000000006064820152608401610214565b610f6785858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bcc92505050565b6000610f84855a8660405180602001604052806000815250611c3f565b905080611013576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c656400000000000000000000000000000000000000000000000000000000006064820152608401610214565b505050505050565b6109c987873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c5792505050565b333b156110ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b61101386863333888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061201092505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156111a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c89190612dd5565b905090565b6109c987873388888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061201092505050565b333b156112a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b61101386863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c5792505050565b6105b233858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506105a592505050565b6109c9878787878787876105b8565b333b156113c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b610aa433338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506105a592505050565b600054610100900460ff16158080156114285750600054600160ff909116105b806114425750303b158015611442575060005460ff166001145b6114ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610214565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561152c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6032805473ffffffffffffffffffffffffffffffffffffffff8086167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255603380549285169290911691909117905561159f8473420000000000000000000000000000000000001061201f565b80156105b257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b6105b23385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061164a92505050565b611652611b8d565b156116df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2063616e6e6f742062726964676520455460448201527f48207769746820637573746f6d2067617320746f6b656e0000000000000000006064820152608401610214565b82341461176e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c756500006064820152608401610214565b61177a85858584612109565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9287929116907f1635f5fd00000000000000000000000000000000000000000000000000000000906117dd908b908b9086908a90602401612df7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b909216825261187092918890600401612e40565b6000604051808303818588803b15801561188957600080fd5b505af115801561189d573d6000803e3d6000fd5b50505050505050505050565b60006118d5827f1d1d8b630000000000000000000000000000000000000000000000000000000061217c565b806119055750611905827fec4fc8e30000000000000000000000000000000000000000000000000000000061217c565b92915050565b6000611937837f1d1d8b630000000000000000000000000000000000000000000000000000000061217c565b156119e0578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611987573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ab9190612d72565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611905565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611987573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610aa49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261219f565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b3868686604051611b7793929190612e85565b60405180910390a46110138686868686866122ab565b600080611b98612333565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e6318484604051611c2b929190612ec3565b60405180910390a36105b2848484846123d0565b6000806000835160208501868989f195945050505050565b3415611ce5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f5374616e646172644272696467653a2063616e6e6f742073656e642076616c7560448201527f65000000000000000000000000000000000000000000000000000000000000006064820152608401610214565b611cee876118a9565b15611e3c57611cfd878761190b565b611daf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610214565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b158015611e1f57600080fd5b505af1158015611e33573d6000803e3d6000fd5b50505050611ed0565b611e5e73ffffffffffffffffffffffffffffffffffffffff881686308661243d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054611e9c908490612edc565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611ede87878787878661249b565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9216907f0166a07a0000000000000000000000000000000000000000000000000000000090611f42908b908d908c908c908c908b90602401612ef4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611fd592918790600401612e40565b600060405180830381600087803b158015611fef57600080fd5b505af1158015612003573d6000803e3d6000fd5b5050505050505050505050565b6109c987878787878787611c57565b600054610100900460ff166120b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610214565b6003805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560048054929093169116179055565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051612168929190612ec3565b60405180910390a36105b284848484612529565b600061218783612588565b8015612198575061219883836125ec565b9392505050565b6000612201826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166126bb9092919063ffffffff16565b805190915015610aa4578080602001905181019061221f9190612dd5565b610aa4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610214565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd86868660405161232393929190612e85565b60405180910390a4505050505050565b603354604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa1580156123a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c79190612f4f565b90939092509050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d848460405161242f929190612ec3565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526105b29085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611a7d565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039686868660405161251393929190612e85565b60405180910390a46110138686868686866126d2565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5848460405161242f929190612ec3565b60006125b4827f01ffc9a7000000000000000000000000000000000000000000000000000000006125ec565b801561190557506125e5827fffffffff000000000000000000000000000000000000000000000000000000006125ec565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156126a4575060208210155b80156126b05750600081115b979650505050505050565b60606126ca848460008561274a565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf86868660405161232393929190612e85565b6060824710156127dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610214565b73ffffffffffffffffffffffffffffffffffffffff85163b61285a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610214565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516128839190612f84565b60006040518083038185875af1925050503d80600081146128c0576040519150601f19603f3d011682016040523d82523d6000602084013e6128c5565b606091505b50915091506126b0828286606083156128df575081612198565b8251156128ef5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102149190612bf5565b73ffffffffffffffffffffffffffffffffffffffff8116811461294557600080fd5b50565b60008083601f84011261295a57600080fd5b50813567ffffffffffffffff81111561297257600080fd5b60208301915083602082850101111561298a57600080fd5b9250929050565b600080600080600080600060c0888a0312156129ac57600080fd5b87356129b781612923565b965060208801356129c781612923565b955060408801356129d781612923565b945060608801356129e781612923565b93506080880135925060a088013567ffffffffffffffff811115612a0a57600080fd5b612a168a828b01612948565b989b979a50959850939692959293505050565b803563ffffffff81168114612a3d57600080fd5b919050565b600080600060408486031215612a5757600080fd5b612a6084612a29565b9250602084013567ffffffffffffffff811115612a7c57600080fd5b612a8886828701612948565b9497909650939450505050565b600080600080600060808688031215612aad57600080fd5b8535612ab881612923565b94506020860135612ac881612923565b935060408601359250606086013567ffffffffffffffff811115612aeb57600080fd5b612af788828901612948565b969995985093965092949392505050565b600080600080600080600060c0888a031215612b2357600080fd5b8735612b2e81612923565b96506020880135612b3e81612923565b95506040880135612b4e81612923565b945060608801359350612b6360808901612a29565b925060a088013567ffffffffffffffff811115612a0a57600080fd5b60005b83811015612b9a578181015183820152602001612b82565b838111156105b25750506000910152565b60008151808452612bc3816020860160208601612b7f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006121986020830184612bab565b60008060008060008060a08789031215612c2157600080fd5b8635612c2c81612923565b95506020870135612c3c81612923565b945060408701359350612c5160608801612a29565b9250608087013567ffffffffffffffff811115612c6d57600080fd5b612c7989828a01612948565b979a9699509497509295939492505050565b60008060408385031215612c9e57600080fd5b8235612ca981612923565b91506020830135612cb981612923565b809150509250929050565b60008060008060608587031215612cda57600080fd5b8435612ce581612923565b9350612cf360208601612a29565b9250604085013567ffffffffffffffff811115612d0f57600080fd5b612d1b87828801612948565b95989497509550505050565b600080600060608486031215612d3c57600080fd5b8335612d4781612923565b92506020840135612d5781612923565b91506040840135612d6781612923565b809150509250925092565b600060208284031215612d8457600080fd5b815161219881612923565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612dd057612dd0612d8f565b500390565b600060208284031215612de757600080fd5b8151801515811461219857600080fd5b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152612e366080830184612bab565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84168152606060208201526000612e6f6060830185612bab565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000612eba6060830184612bab565b95945050505050565b8281526040602082015260006126ca6040830184612bab565b60008219821115612eef57612eef612d8f565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a0830152612f4360c0830184612bab565b98975050505050505050565b60008060408385031215612f6257600080fd5b8251612f6d81612923565b602084015190925060ff81168114612cb957600080fd5b60008251612f96818460208701612b7f565b919091019291505056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - }, - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - }, - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - }, - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - }, - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": true, - "newValue": "0x0000000000000000000000004200000000000000000000000000000000000010", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x927ede2d", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x3cb747bf", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x7f46ddb2", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": false, - "newValue": "0x0000000000000000000000004200000000000000000000000000000000000010", - "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000010", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xc89701a2", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": false, - "newValue": "0x0000000000000000000000004200000000000000000000000000000000000010", - "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000010", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x35e80ab3", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x638627e586f5e36fe67a77519503a7c6da22f92b150d3c6055fd40bdcfe9ffd160806040523480156200001157600080fd5b506200001f60008062000025565b62000234565b600054610100900460ff1615808015620000465750600054600160ff909116105b8062000076575062000063306200018a60201b62000b141760201c565b15801562000076575060005460ff166001145b620000df5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000103576000805461ff0019166101001790555b603280546001600160a01b0319166001600160a01b0384161790556200013e8373420000000000000000000000000000000000001462000199565b801562000185576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03163b151590565b600054610100900460ff16620002065760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000d6565b600180546001600160a01b039384166001600160a01b03199182161790915560028054929093169116179055565b6113e980620002446000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c80635d93a3fc11610081578063927ede2d1161005b578063927ede2d14610231578063aa5574521461024f578063c89701a21461026257600080fd5b80635d93a3fc146101cc578063761f4493146102005780637f46ddb21461021357600080fd5b8063485cc955116100b2578063485cc9551461015857806354fd4d501461016b5780635c975abb146101b457600080fd5b806335e80ab3146100d95780633687011a146101235780633cb747bf14610138575b600080fd5b6032546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610136610131366004610fe1565b610282565b005b6001546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b610136610166366004611064565b61032e565b6101a76040518060400160405280600c81526020017f322e312e312b626574612e31000000000000000000000000000000000000000081525081565b60405161011a9190611108565b6101bc610518565b604051901515815260200161011a565b6101bc6101da366004611122565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b61013661020e366004611163565b6105b1565b60025473ffffffffffffffffffffffffffffffffffffffff166100f9565b60015473ffffffffffffffffffffffffffffffffffffffff166100f9565b61013661025d3660046111fb565b610a58565b6002546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b333b15610316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b6103268686333388888888610b30565b505050505050565b600054610100900460ff161580801561034e5750600054600160ff909116105b806103685750303b158015610368575060005460ff166001145b6103f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161030d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561045257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556104b083734200000000000000000000000000000000000014610e70565b801561051357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa158015610588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ac9190611272565b905090565b60015473ffffffffffffffffffffffffffffffffffffffff16331480156106865750600254600154604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691636e296e45916004808201926020929091908290030181865afa15801561064a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066e9190611294565b73ffffffffffffffffffffffffffffffffffffffff16145b610712576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f746865722062726964676500606482015260840161030d565b61071a610518565b15610781576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4c314552433732314272696467653a2070617573656400000000000000000000604482015260640161030d565b3073ffffffffffffffffffffffffffffffffffffffff881603610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c6600000000000000000000000000000000000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff1615156001146108f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c312042726964676500000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156109b557600080fd5b505af11580156109c9573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac87878787604051610a4794939291906112fa565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610afb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f74206265206164647265737328302900000000000000000000000000000000606482015260840161030d565b610b0b8787338888888888610b30565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b73ffffffffffffffffffffffffffffffffffffffff8716610bd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f742062652061646472657373283029000000000000000000000000000000606482015260840161030d565b600063761f449360e01b888a8989898888604051602401610bfa979695949392919061133a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610d3a57600080fd5b505af1158015610d4e573d6000803e3d6000fd5b50506001546002546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450633dbb202b9350610db1929091169085908990600401611397565b600060405180830381600087803b158015610dcb57600080fd5b505af1158015610ddf573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610e5d94939291906112fa565b60405180910390a4505050505050505050565b600054610100900460ff16610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161030d565b6001805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560028054929093169116179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610f7c57600080fd5b50565b803563ffffffff81168114610f9357600080fd5b919050565b60008083601f840112610faa57600080fd5b50813567ffffffffffffffff811115610fc257600080fd5b602083019150836020828501011115610fda57600080fd5b9250929050565b60008060008060008060a08789031215610ffa57600080fd5b863561100581610f5a565b9550602087013561101581610f5a565b94506040870135935061102a60608801610f7f565b9250608087013567ffffffffffffffff81111561104657600080fd5b61105289828a01610f98565b979a9699509497509295939492505050565b6000806040838503121561107757600080fd5b823561108281610f5a565b9150602083013561109281610f5a565b809150509250929050565b6000815180845260005b818110156110c3576020818501810151868301820152016110a7565b818111156110d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061111b602083018461109d565b9392505050565b60008060006060848603121561113757600080fd5b833561114281610f5a565b9250602084013561115281610f5a565b929592945050506040919091013590565b600080600080600080600060c0888a03121561117e57600080fd5b873561118981610f5a565b9650602088013561119981610f5a565b955060408801356111a981610f5a565b945060608801356111b981610f5a565b93506080880135925060a088013567ffffffffffffffff8111156111dc57600080fd5b6111e88a828b01610f98565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561121657600080fd5b873561122181610f5a565b9650602088013561123181610f5a565b9550604088013561124181610f5a565b94506060880135935061125660808901610f7f565b925060a088013567ffffffffffffffff8111156111dc57600080fd5b60006020828403121561128457600080fd5b8151801515811461111b57600080fd5b6000602082840312156112a657600080fd5b815161111b81610f5a565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006113306060830184866112b1565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261138a60c0830184866112b1565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006113c6606083018561109d565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x60806040523480156200001157600080fd5b506200001f60008062000025565b62000234565b600054610100900460ff1615808015620000465750600054600160ff909116105b8062000076575062000063306200018a60201b62000b141760201c565b15801562000076575060005460ff166001145b620000df5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000103576000805461ff0019166101001790555b603280546001600160a01b0319166001600160a01b0384161790556200013e8373420000000000000000000000000000000000001462000199565b801562000185576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03163b151590565b600054610100900460ff16620002065760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000d6565b600180546001600160a01b039384166001600160a01b03199182161790915560028054929093169116179055565b6113e980620002446000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c80635d93a3fc11610081578063927ede2d1161005b578063927ede2d14610231578063aa5574521461024f578063c89701a21461026257600080fd5b80635d93a3fc146101cc578063761f4493146102005780637f46ddb21461021357600080fd5b8063485cc955116100b2578063485cc9551461015857806354fd4d501461016b5780635c975abb146101b457600080fd5b806335e80ab3146100d95780633687011a146101235780633cb747bf14610138575b600080fd5b6032546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610136610131366004610fe1565b610282565b005b6001546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b610136610166366004611064565b61032e565b6101a76040518060400160405280600c81526020017f322e312e312b626574612e31000000000000000000000000000000000000000081525081565b60405161011a9190611108565b6101bc610518565b604051901515815260200161011a565b6101bc6101da366004611122565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b61013661020e366004611163565b6105b1565b60025473ffffffffffffffffffffffffffffffffffffffff166100f9565b60015473ffffffffffffffffffffffffffffffffffffffff166100f9565b61013661025d3660046111fb565b610a58565b6002546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b333b15610316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b6103268686333388888888610b30565b505050505050565b600054610100900460ff161580801561034e5750600054600160ff909116105b806103685750303b158015610368575060005460ff166001145b6103f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161030d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561045257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556104b083734200000000000000000000000000000000000014610e70565b801561051357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa158015610588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ac9190611272565b905090565b60015473ffffffffffffffffffffffffffffffffffffffff16331480156106865750600254600154604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691636e296e45916004808201926020929091908290030181865afa15801561064a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066e9190611294565b73ffffffffffffffffffffffffffffffffffffffff16145b610712576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f746865722062726964676500606482015260840161030d565b61071a610518565b15610781576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4c314552433732314272696467653a2070617573656400000000000000000000604482015260640161030d565b3073ffffffffffffffffffffffffffffffffffffffff881603610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c6600000000000000000000000000000000000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff1615156001146108f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c312042726964676500000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156109b557600080fd5b505af11580156109c9573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac87878787604051610a4794939291906112fa565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610afb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f74206265206164647265737328302900000000000000000000000000000000606482015260840161030d565b610b0b8787338888888888610b30565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b73ffffffffffffffffffffffffffffffffffffffff8716610bd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f742062652061646472657373283029000000000000000000000000000000606482015260840161030d565b600063761f449360e01b888a8989898888604051602401610bfa979695949392919061133a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610d3a57600080fd5b505af1158015610d4e573d6000803e3d6000fd5b50506001546002546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450633dbb202b9350610db1929091169085908990600401611397565b600060405180830381600087803b158015610dcb57600080fd5b505af1158015610ddf573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610e5d94939291906112fa565b60405180910390a4505050505050505050565b600054610100900460ff16610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161030d565b6001805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560028054929093169116179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610f7c57600080fd5b50565b803563ffffffff81168114610f9357600080fd5b919050565b60008083601f840112610faa57600080fd5b50813567ffffffffffffffff811115610fc257600080fd5b602083019150836020828501011115610fda57600080fd5b9250929050565b60008060008060008060a08789031215610ffa57600080fd5b863561100581610f5a565b9550602087013561101581610f5a565b94506040870135935061102a60608801610f7f565b9250608087013567ffffffffffffffff81111561104657600080fd5b61105289828a01610f98565b979a9699509497509295939492505050565b6000806040838503121561107757600080fd5b823561108281610f5a565b9150602083013561109281610f5a565b809150509250929050565b6000815180845260005b818110156110c3576020818501810151868301820152016110a7565b818111156110d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061111b602083018461109d565b9392505050565b60008060006060848603121561113757600080fd5b833561114281610f5a565b9250602084013561115281610f5a565b929592945050506040919091013590565b600080600080600080600060c0888a03121561117e57600080fd5b873561118981610f5a565b9650602088013561119981610f5a565b955060408801356111a981610f5a565b945060608801356111b981610f5a565b93506080880135925060a088013567ffffffffffffffff8111156111dc57600080fd5b6111e88a828b01610f98565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561121657600080fd5b873561122181610f5a565b9650602088013561123181610f5a565b9550604088013561124181610f5a565b94506060880135935061125660808901610f7f565b925060a088013567ffffffffffffffff8111156111dc57600080fd5b60006020828403121561128457600080fd5b8151801515811461111b57600080fd5b6000602082840312156112a657600080fd5b815161111b81610f5a565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006113306060830184866112b1565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261138a60c0830184866112b1565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006113c6606083018561109d565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a", - "deployedCode": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c80635d93a3fc11610081578063927ede2d1161005b578063927ede2d14610231578063aa5574521461024f578063c89701a21461026257600080fd5b80635d93a3fc146101cc578063761f4493146102005780637f46ddb21461021357600080fd5b8063485cc955116100b2578063485cc9551461015857806354fd4d501461016b5780635c975abb146101b457600080fd5b806335e80ab3146100d95780633687011a146101235780633cb747bf14610138575b600080fd5b6032546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610136610131366004610fe1565b610282565b005b6001546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b610136610166366004611064565b61032e565b6101a76040518060400160405280600c81526020017f322e312e312b626574612e31000000000000000000000000000000000000000081525081565b60405161011a9190611108565b6101bc610518565b604051901515815260200161011a565b6101bc6101da366004611122565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b61013661020e366004611163565b6105b1565b60025473ffffffffffffffffffffffffffffffffffffffff166100f9565b60015473ffffffffffffffffffffffffffffffffffffffff166100f9565b61013661025d3660046111fb565b610a58565b6002546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b333b15610316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b6103268686333388888888610b30565b505050505050565b600054610100900460ff161580801561034e5750600054600160ff909116105b806103685750303b158015610368575060005460ff166001145b6103f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161030d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561045257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556104b083734200000000000000000000000000000000000014610e70565b801561051357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa158015610588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ac9190611272565b905090565b60015473ffffffffffffffffffffffffffffffffffffffff16331480156106865750600254600154604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691636e296e45916004808201926020929091908290030181865afa15801561064a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066e9190611294565b73ffffffffffffffffffffffffffffffffffffffff16145b610712576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f746865722062726964676500606482015260840161030d565b61071a610518565b15610781576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4c314552433732314272696467653a2070617573656400000000000000000000604482015260640161030d565b3073ffffffffffffffffffffffffffffffffffffffff881603610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c6600000000000000000000000000000000000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff1615156001146108f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c312042726964676500000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156109b557600080fd5b505af11580156109c9573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac87878787604051610a4794939291906112fa565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610afb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f74206265206164647265737328302900000000000000000000000000000000606482015260840161030d565b610b0b8787338888888888610b30565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b73ffffffffffffffffffffffffffffffffffffffff8716610bd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f742062652061646472657373283029000000000000000000000000000000606482015260840161030d565b600063761f449360e01b888a8989898888604051602401610bfa979695949392919061133a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610d3a57600080fd5b505af1158015610d4e573d6000803e3d6000fd5b50506001546002546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450633dbb202b9350610db1929091169085908990600401611397565b600060405180830381600087803b158015610dcb57600080fd5b505af1158015610ddf573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610e5d94939291906112fa565b60405180910390a4505050505050505050565b600054610100900460ff16610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161030d565b6001805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560028054929093169116179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610f7c57600080fd5b50565b803563ffffffff81168114610f9357600080fd5b919050565b60008083601f840112610faa57600080fd5b50813567ffffffffffffffff811115610fc257600080fd5b602083019150836020828501011115610fda57600080fd5b9250929050565b60008060008060008060a08789031215610ffa57600080fd5b863561100581610f5a565b9550602087013561101581610f5a565b94506040870135935061102a60608801610f7f565b9250608087013567ffffffffffffffff81111561104657600080fd5b61105289828a01610f98565b979a9699509497509295939492505050565b6000806040838503121561107757600080fd5b823561108281610f5a565b9150602083013561109281610f5a565b809150509250929050565b6000815180845260005b818110156110c3576020818501810151868301820152016110a7565b818111156110d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061111b602083018461109d565b9392505050565b60008060006060848603121561113757600080fd5b833561114281610f5a565b9250602084013561115281610f5a565b929592945050506040919091013590565b600080600080600080600060c0888a03121561117e57600080fd5b873561118981610f5a565b9650602088013561119981610f5a565b955060408801356111a981610f5a565b945060608801356111b981610f5a565b93506080880135925060a088013567ffffffffffffffff8111156111dc57600080fd5b6111e88a828b01610f98565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561121657600080fd5b873561122181610f5a565b9650602088013561123181610f5a565b9550604088013561124181610f5a565b94506060880135935061125660808901610f7f565b925060a088013567ffffffffffffffff8111156111dc57600080fd5b60006020828403121561128457600080fd5b8151801515811461111b57600080fd5b6000602082840312156112a657600080fd5b815161111b81610f5a565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006113306060830184866112b1565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261138a60c0830184866112b1565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006113c6606083018561109d565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - }, - { - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - }, - { - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - { - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - { - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" - }, - { - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "isWrite": true, - "newValue": "0x0000000000000000000000004200000000000000000000000000000000000014", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" - }, - { - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x7f46ddb2", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "isWrite": false, - "newValue": "0x0000000000000000000000004200000000000000000000000000000000000014", - "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000014", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xc89701a2", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "isWrite": false, - "newValue": "0x0000000000000000000000004200000000000000000000000000000000000014", - "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000014", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x927ede2d", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x3cb747bf", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x35e80ab3", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x493f862b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000004a" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x638627e586f5e36fe67a77519503a7c6da22f92b150d3c6055fd40bdcfe9ffd160806040523480156200001157600080fd5b50620000206000808062000026565b6200028f565b600054610100900460ff1615808015620000475750600054600160ff909116105b806200007757506200006430620001c160201b62001efd1760201c565b15801562000077575060005460ff166001145b620000e05760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000104576000805461ff0019166101001790555b603680546001600160a01b03199081166001600160a01b03878116919091179092556037805490911685831617905560358054610100600160a81b03191661010085841602179055603254166200016a57603280546001600160a01b03191661dead1790555b62000174620001d0565b8015620001bb576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6001600160a01b03163b151590565b600054610100900460ff166200023d5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000d7565b600154600160c01b90046001600160401b03166000036200028d5760408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b02176001555b565b615777806200029f6000396000f3fe6080604052600436106101635760003560e01c80638c3152e9116100c0578063b69ef8a811610074578063cff0ab9611610059578063cff0ab9614610444578063e965084c146104e5578063e9e05c421461057157600080fd5b8063b69ef8a814610401578063c0c53b8b1461042457600080fd5b80639bf62d82116100a55780639bf62d821461036b578063a14238e714610398578063a35d99df146103c857600080fd5b80638c3152e91461031e5780639b5f694a1461033e57600080fd5b806354fd4d50116101175780636dbffb78116100fc5780636dbffb78146102de57806371cfaa3f146102fe5780638b4c40b01461018857600080fd5b806354fd4d501461026d5780635c975abb146102b957600080fd5b806335e80ab31161014857806335e80ab314610206578063452a9320146102385780634870496f1461024d57600080fd5b8063149f2f221461018f57806333d7e2bd146101af57600080fd5b3661018a576101883334620186a060006040518060200160405280600081525061057f565b005b600080fd5b34801561019b57600080fd5b506101886101aa366004614b97565b610624565b3480156101bb57600080fd5b506037546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561021257600080fd5b506035546101dc90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561024457600080fd5b506101dc610865565b34801561025957600080fd5b50610188610268366004614ccb565b6108fd565b34801561027957600080fd5b50604080518082018252600c81527f322e382e312d626574612e310000000000000000000000000000000000000000602082015290516101fd9190614e1d565b3480156102c557600080fd5b506102ce610eaa565b60405190151581526020016101fd565b3480156102ea57600080fd5b506102ce6102f9366004614e30565b610f3d565b34801561030a57600080fd5b50610188610319366004614e58565b610ff8565b34801561032a57600080fd5b50610188610339366004614e9e565b6111ba565b34801561034a57600080fd5b506036546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561037757600080fd5b506032546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103a457600080fd5b506102ce6103b3366004614e30565b60336020526000908152604090205460ff1681565b3480156103d457600080fd5b506103e86103e3366004614edb565b611c3c565b60405167ffffffffffffffff90911681526020016101fd565b34801561040d57600080fd5b50610416611c55565b6040519081526020016101fd565b34801561043057600080fd5b5061018861043f366004614ef6565b611caf565b34801561045057600080fd5b506001546104ac906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101fd565b3480156104f157600080fd5b50610543610500366004614e30565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101fd565b61018861057f366004614f41565b8260005a9050600061058f611f19565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906105cb57503415155b15610602576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610610883489898989611fb6565b5061061b8282612162565b50505050505050565b8260005a90506000610634611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016106a6576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546106b89190614fed565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561072a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074e9190615005565b905061077273ffffffffffffffffffffffffffffffffffffffff831633308c61242f565b61077c8982614fed565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa1580156107e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080a9190615005565b14610841576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61084f8a8a8a8a8a8a611fb6565b505061085b8282612162565b5050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f8919061501e565b905090565b610905610eaa565b1561093c576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16036109a5576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6036546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810186905260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610a15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a39919061505b565b519050610a53610a4e368690038601866150c0565b61250b565b8114610ae6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f66000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000610af187612567565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610c075750805160365460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610bdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c03919061505b565b5114155b610c93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610add565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610d5c9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610d52888a615126565b8a60400135612597565b610de8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610add565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f19573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906151aa565b6036546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101839052600091610ff29173ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd7919061505b565b602001516fffffffffffffffffffffffffffffffff166125bb565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff163314611049576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61105562030d40612661565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f000000000000000000000000000000000000000000000000000000001790529051611172969594939291016151c7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526111aa91614e1d565b60405180910390a450505050565b565b6111c2610eaa565b156111f9576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461124c576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061125782612567565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610add565b603660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d39190615005565b81602001516fffffffffffffffffffffffffffffffff16101561149e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610add565b6114bd81602001516fffffffffffffffffffffffffffffffff166125bb565b61156f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610add565b60365460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a919061505b565b82518151919250146116d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610add565b6116f381602001516fffffffffffffffffffffffffffffffff166125bb565b6117a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610add565b60008381526033602052604090205460ff1615611844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610add565b6000838152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558501516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055806118cf611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016119325761192b8660400151876080015188606001518960a001516126c3565b9150611b85565b8073ffffffffffffffffffffffffffffffffffffffff16866040015173ffffffffffffffffffffffffffffffffffffffff160361199b576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606086015115611b5c578560600151603d60008282546119bb919061522c565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015611a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a519190615005565b9050611a86876040015188606001518473ffffffffffffffffffffffffffffffffffffffff166127219092919063ffffffff16565b6060870151611a95908261522c565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015611aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b239190615005565b14611b5a576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08601515115611b805761192b8660400151876080015160008960a001516126c3565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405185907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90611be790851515815260200190565b60405180910390a281158015611bfd5750326001145b15611c34576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b6000611c49826010615243565b610ff290615208615273565b600080611c60611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601611ca7574791505090565b5050603d5490565b600054610100900460ff1615808015611ccf5750600054600160ff909116105b80611ce95750303b158015611ce9575060005460ff166001145b611d75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610add565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611dd357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603680547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8781169190911790925560378054909116858316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101008584160217905560325416611e8c57603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b611e9461277c565b8015611ef757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015611f89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fad919061529f565b90939092509050565b818015611fd8575073ffffffffffffffffffffffffffffffffffffffff861615155b1561200f576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120198151611c3c565b67ffffffffffffffff168367ffffffffffffffff161015612066576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c0815111156120a4576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333281146120c5575033731111000000000000000000000000000000001111015b600086868686866040516020016120e09594939291906151c7565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516121509190614e1d565b60405180910390a45050505050505050565b600154600090612198907801000000000000000000000000000000000000000000000000900467ffffffffffffffff164361522c565b905060006121a461288f565b90506000816020015160ff16826000015163ffffffff166121c59190615308565b905082156122fc576001546000906121fc908390700100000000000000000000000000000000900467ffffffffffffffff16615370565b90506000836040015160ff168361221391906153e4565b6001546122339084906fffffffffffffffffffffffffffffffff166153e4565b61223d9190615308565b60015490915060009061228e906122679084906fffffffffffffffffffffffffffffffff166154a0565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612950565b905060018611156122bd576122ba61226782876040015160ff1660018a6122b5919061522c565b61296f565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b6001805486919060109061232f908490700100000000000000000000000000000000900467ffffffffffffffff16615273565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1613156123bc576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906123e8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615514565b905060006123fa48633b9aca006129c4565b6124049083615551565b905060005a612413908861522c565b90508082111561085b5761085b61242a828461522c565b6129db565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052611ef79085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612a04565b6000816000015182602001518360400151846060015160405160200161254a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a0880151935160009761254a979096959101615565565b6000806125a386612b10565b90506125b181868686612b42565b9695505050505050565b603654604080517ff4daa291000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163f4daa2919160048083019260209291908290030181865afa15801561262b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264f9190615005565b6126599083614fed565b421192915050565b6001805463ffffffff8316919060109061269a908490700100000000000000000000000000000000900467ffffffffffffffff16615273565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b60008060006126d3866000612b72565b905080612709576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526127779084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612489565b505050565b600054610100900460ff16612813576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610add565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff166000036111b85760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa15801561292c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906155d0565b600061296561295f8585612b90565b83612ba0565b90505b9392505050565b6000670de0b6b3a76400006129b06129878583615308565b61299990670de0b6b3a7640000615370565b6129ab85670de0b6b3a76400006153e4565b612baf565b6129ba90866153e4565b6129659190615308565b6000818310156129d45781612968565b5090919050565b6000805a90505b825a6129ee908361522c565b1015612777576129fd82615673565b91506129e2565b6000612a66826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612be09092919063ffffffff16565b8051909150156127775780806020019051810190612a8491906151aa565b612777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610add565b60608180519060200120604051602001612b2c91815260200190565b6040516020818303038152906040529050919050565b6000612b6984612b53878686612bef565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000818312156129d45781612968565b60008183126129d45781612968565b6000612968670de0b6b3a764000083612bc78661366d565b612bd191906153e4565b612bdb9190615308565b6138b1565b60606129658484600085613af0565b60606000845111612c5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610add565b6000612c6784613c86565b90506000612c7486613d72565b9050600084604051602001612c8b91815260200190565b60405160208183030381529060405290506000805b84518110156135e4576000858281518110612cbd57612cbd6156ab565b602002602001015190508451831115612d58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610add565b82600003612e115780518051602091820120604051612da692612d8092910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610add565b612f68565b805151602011612ec75780518051602091820120604051612e3b92612d8092910190815260200190565b612e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610add565b805184516020808701919091208251919092012014612f68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610add565b612f7460106001614fed565b8160200151510361315057845183036130e857612fae8160200151601081518110612fa157612fa16156ab565b6020026020010151613dd5565b96506000875111613041576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610add565b6001865161304f919061522c565b82146130dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610add565b505050505050612968565b60008584815181106130fc576130fc6156ab565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110613127576131276156ab565b6020026020010151905061313a81613e89565b9550613147600186614fed565b945050506135d1565b60028160200151510361354957600061316882613eae565b905060008160008151811061317f5761317f6156ab565b016020015160f81c905060006131966002836156da565b6131a19060026156fc565b905060006131b2848360ff16613ed2565b905060006131c08a89613ed2565b905060006131ce8383613f08565b905080835114613260576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610add565b60ff851660021480613275575060ff85166003145b15613464578082511461330a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610add565b6133248760200151600181518110612fa157612fa16156ab565b9c5060008d51116133b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610add565b60018c516133c5919061522c565b8814613453576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610add565b505050505050505050505050612968565b60ff85161580613477575060ff85166001145b156134b6576134a38760200151600181518110613496576134966156ab565b6020026020010151613e89565b99506134af818a614fed565b985061353e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610add565b5050505050506135d1565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610add565b50806135dc81615673565b915050612ca0565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610add565b60008082136136d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b600060606136e584613fbc565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136138e257506000919050565b680755bf798b4a1bf1e58212613954576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610add565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613b82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610add565b73ffffffffffffffffffffffffffffffffffffffff85163b613c00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610add565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613c29919061571f565b60006040518083038185875af1925050503d8060008114613c66576040519150601f19603f3d011682016040523d82523d6000602084013e613c6b565b606091505b5091509150613c7b828286614092565b979650505050505050565b80516060908067ffffffffffffffff811115613ca457613ca4614a8b565b604051908082528060200260200182016040528015613ce957816020015b6040805180820190915260608082526020820152815260200190600190039081613cc25790505b50915060005b81811015613d6b576040518060400160405280858381518110613d1457613d146156ab565b60200260200101518152602001613d43868481518110613d3657613d366156ab565b60200260200101516140e5565b815250838281518110613d5857613d586156ab565b6020908102919091010152600101613cef565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015613dca578060011b82018184015160001a8060041c8253600f811660018301535050600101613d9c565b509295945050505050565b60606000806000613de5856140f8565b919450925090506000816001811115613e0057613e0061573b565b14613e37576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613e418284614fed565b855114613e7a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b6985602001518484614596565b60606020826000015110613ea557613ea082613dd5565b610ff2565b610ff28261462a565b6060610ff2613ecd8360200151600081518110612fa157612fa16156ab565b613d72565b606082518210613ef15750604080516020810190915260008152610ff2565b6129688383848651613f03919061522c565b614640565b6000808251845110613f1b578251613f1e565b83515b90505b8082108015613fa55750828281518110613f3d57613f3d6156ab565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613f7c57613f7c6156ab565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15613fb557816001019150613f21565b5092915050565b6000808211614027576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606083156140a1575081612968565b8251156140b15782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610add9190614e1d565b6060610ff26140f383614818565b614885565b6000806000836000015160000361413b576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f811161416057600060016000945094509450505061458f565b60b7811161427657600061417560808361522c565b9050808760000151116141b4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214801561422c57507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614263576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061458f915050565b60bf81116143d457600061428b60b78361522c565b9050808760000151116142ca576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361432c576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614374576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61437e8184614fed565b8951116143b7576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6143c2836001614fed565b975095506000945061458f9350505050565b60f781116144395760006143e960c08361522c565b905080876000015111614428576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061458f915050565b600061444660f78361522c565b905080876000015111614485576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036144e7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c6037811161452f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6145398184614fed565b895111614572576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61457d836001614fed565b975095506001945061458f9350505050565b9193909250565b60608167ffffffffffffffff8111156145b1576145b1614a8b565b6040519080825280601f01601f1916602001820160405280156145db576020820181803683370190505b50905081156129685760006145f08486614fed565b90506020820160005b848110156146115782810151828201526020016145f9565b84811115614620576000858301525b5050509392505050565b6060610ff2826020015160008460000151614596565b60608182601f0110156146af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b82828401101561471b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b81830184511015614788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610add565b6060821580156147a7576040519150600082526020820160405261480f565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156147e05780518352602092830192016147c8565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201528151600003614867576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000614895856140f8565b9194509250905060018160018111156148b0576148b061573b565b146148e7576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516148f38385614fed565b1461492a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816149415790505093506000835b8651811015614a2f576000806149b46040518060400160405280858c60000151614998919061522c565b8152602001858c602001516149ad9190614fed565b90526140f8565b5091509150604051806040016040528083836149d09190614fed565b8152602001848b602001516149e59190614fed565b8152508885815181106149fa576149fa6156ab565b6020908102919091010152614a10600185614fed565b9350614a1c8183614fed565b614a269084614fed565b9250505061496e565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114614a5d57600080fd5b50565b803567ffffffffffffffff81168114614a7857600080fd5b919050565b8015158114614a5d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614b0157614b01614a8b565b604052919050565b600082601f830112614b1a57600080fd5b813567ffffffffffffffff811115614b3457614b34614a8b565b614b6560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614aba565b818152846020838601011115614b7a57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614bb057600080fd5b8635614bbb81614a3b565b95506020870135945060408701359350614bd760608801614a60565b92506080870135614be781614a7d565b915060a087013567ffffffffffffffff811115614c0357600080fd5b614c0f89828a01614b09565b9150509295509295509295565b600060c08284031215614c2e57600080fd5b60405160c0810167ffffffffffffffff8282108183111715614c5257614c52614a8b565b816040528293508435835260208501359150614c6d82614a3b565b81602084015260408501359150614c8382614a3b565b816040840152606085013560608401526080850135608084015260a0850135915080821115614cb157600080fd5b50614cbe85828601614b09565b60a0830152505092915050565b600080600080600085870360e0811215614ce457600080fd5b863567ffffffffffffffff80821115614cfc57600080fd5b614d088a838b01614c1c565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614d4157600080fd5b60408901955060c0890135925080831115614d5b57600080fd5b828901925089601f840112614d6f57600080fd5b8235915080821115614d8057600080fd5b508860208260051b8401011115614d9657600080fd5b959894975092955050506020019190565b60005b83811015614dc2578181015183820152602001614daa565b83811115611ef75750506000910152565b60008151808452614deb816020860160208601614da7565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006129686020830184614dd3565b600060208284031215614e4257600080fd5b5035919050565b60ff81168114614a5d57600080fd5b60008060008060808587031215614e6e57600080fd5b8435614e7981614a3b565b93506020850135614e8981614e49565b93969395505050506040820135916060013590565b600060208284031215614eb057600080fd5b813567ffffffffffffffff811115614ec757600080fd5b614ed384828501614c1c565b949350505050565b600060208284031215614eed57600080fd5b61296882614a60565b600080600060608486031215614f0b57600080fd5b8335614f1681614a3b565b92506020840135614f2681614a3b565b91506040840135614f3681614a3b565b809150509250925092565b600080600080600060a08688031215614f5957600080fd5b8535614f6481614a3b565b945060208601359350614f7960408701614a60565b92506060860135614f8981614a7d565b9150608086013567ffffffffffffffff811115614fa557600080fd5b614fb188828901614b09565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561500057615000614fbe565b500190565b60006020828403121561501757600080fd5b5051919050565b60006020828403121561503057600080fd5b815161296881614a3b565b80516fffffffffffffffffffffffffffffffff81168114614a7857600080fd5b60006060828403121561506d57600080fd5b6040516060810181811067ffffffffffffffff8211171561509057615090614a8b565b604052825181526150a36020840161503b565b60208201526150b46040840161503b565b60408201529392505050565b6000608082840312156150d257600080fd5b6040516080810181811067ffffffffffffffff821117156150f5576150f5614a8b565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff8084111561514157615141614a8b565b8360051b6020615152818301614aba565b86815291850191818101903684111561516a57600080fd5b865b8481101561519e578035868111156151845760008081fd5b61519036828b01614b09565b84525091830191830161516c565b50979650505050505050565b6000602082840312156151bc57600080fd5b815161296881614a7d565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b60488201526000825161521b816049850160208701614da7565b919091016049019695505050505050565b60008282101561523e5761523e614fbe565b500390565b600067ffffffffffffffff8083168185168183048111821515161561526a5761526a614fbe565b02949350505050565b600067ffffffffffffffff80831681851680830382111561529657615296614fbe565b01949350505050565b600080604083850312156152b257600080fd5b82516152bd81614a3b565b60208401519092506152ce81614e49565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615317576153176152d9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561536b5761536b614fbe565b500590565b6000808312837f8000000000000000000000000000000000000000000000000000000000000000018312811516156153aa576153aa614fbe565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156153de576153de614fbe565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561542557615425614fbe565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561546057615460614fbe565b6000871292508782058712848416161561547c5761547c614fbe565b8785058712818416161561549257615492614fbe565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156154da576154da614fbe565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561550e5761550e614fbe565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561554c5761554c614fbe565b500290565b600082615560576155606152d9565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526155b060c0830184614dd3565b98975050505050505050565b805163ffffffff81168114614a7857600080fd5b600060c082840312156155e257600080fd5b60405160c0810181811067ffffffffffffffff8211171561560557615605614a8b565b604052615611836155bc565b8152602083015161562181614e49565b6020820152604083015161563481614e49565b6040820152615645606084016155bc565b6060820152615656608084016155bc565b608082015261566760a0840161503b565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036156a4576156a4614fbe565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806156ed576156ed6152d9565b8060ff84160691505092915050565b600060ff821660ff84168082101561571657615716614fbe565b90039392505050565b60008251615731818460208701614da7565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x60806040523480156200001157600080fd5b50620000206000808062000026565b6200028f565b600054610100900460ff1615808015620000475750600054600160ff909116105b806200007757506200006430620001c160201b62001efd1760201c565b15801562000077575060005460ff166001145b620000e05760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000104576000805461ff0019166101001790555b603680546001600160a01b03199081166001600160a01b03878116919091179092556037805490911685831617905560358054610100600160a81b03191661010085841602179055603254166200016a57603280546001600160a01b03191661dead1790555b62000174620001d0565b8015620001bb576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6001600160a01b03163b151590565b600054610100900460ff166200023d5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000d7565b600154600160c01b90046001600160401b03166000036200028d5760408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b02176001555b565b615777806200029f6000396000f3fe6080604052600436106101635760003560e01c80638c3152e9116100c0578063b69ef8a811610074578063cff0ab9611610059578063cff0ab9614610444578063e965084c146104e5578063e9e05c421461057157600080fd5b8063b69ef8a814610401578063c0c53b8b1461042457600080fd5b80639bf62d82116100a55780639bf62d821461036b578063a14238e714610398578063a35d99df146103c857600080fd5b80638c3152e91461031e5780639b5f694a1461033e57600080fd5b806354fd4d50116101175780636dbffb78116100fc5780636dbffb78146102de57806371cfaa3f146102fe5780638b4c40b01461018857600080fd5b806354fd4d501461026d5780635c975abb146102b957600080fd5b806335e80ab31161014857806335e80ab314610206578063452a9320146102385780634870496f1461024d57600080fd5b8063149f2f221461018f57806333d7e2bd146101af57600080fd5b3661018a576101883334620186a060006040518060200160405280600081525061057f565b005b600080fd5b34801561019b57600080fd5b506101886101aa366004614b97565b610624565b3480156101bb57600080fd5b506037546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561021257600080fd5b506035546101dc90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561024457600080fd5b506101dc610865565b34801561025957600080fd5b50610188610268366004614ccb565b6108fd565b34801561027957600080fd5b50604080518082018252600c81527f322e382e312d626574612e310000000000000000000000000000000000000000602082015290516101fd9190614e1d565b3480156102c557600080fd5b506102ce610eaa565b60405190151581526020016101fd565b3480156102ea57600080fd5b506102ce6102f9366004614e30565b610f3d565b34801561030a57600080fd5b50610188610319366004614e58565b610ff8565b34801561032a57600080fd5b50610188610339366004614e9e565b6111ba565b34801561034a57600080fd5b506036546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561037757600080fd5b506032546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103a457600080fd5b506102ce6103b3366004614e30565b60336020526000908152604090205460ff1681565b3480156103d457600080fd5b506103e86103e3366004614edb565b611c3c565b60405167ffffffffffffffff90911681526020016101fd565b34801561040d57600080fd5b50610416611c55565b6040519081526020016101fd565b34801561043057600080fd5b5061018861043f366004614ef6565b611caf565b34801561045057600080fd5b506001546104ac906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101fd565b3480156104f157600080fd5b50610543610500366004614e30565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101fd565b61018861057f366004614f41565b8260005a9050600061058f611f19565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906105cb57503415155b15610602576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610610883489898989611fb6565b5061061b8282612162565b50505050505050565b8260005a90506000610634611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016106a6576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546106b89190614fed565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561072a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074e9190615005565b905061077273ffffffffffffffffffffffffffffffffffffffff831633308c61242f565b61077c8982614fed565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa1580156107e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080a9190615005565b14610841576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61084f8a8a8a8a8a8a611fb6565b505061085b8282612162565b5050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f8919061501e565b905090565b610905610eaa565b1561093c576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16036109a5576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6036546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810186905260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610a15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a39919061505b565b519050610a53610a4e368690038601866150c0565b61250b565b8114610ae6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f66000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000610af187612567565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610c075750805160365460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610bdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c03919061505b565b5114155b610c93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610add565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610d5c9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610d52888a615126565b8a60400135612597565b610de8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610add565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f19573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906151aa565b6036546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101839052600091610ff29173ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd7919061505b565b602001516fffffffffffffffffffffffffffffffff166125bb565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff163314611049576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61105562030d40612661565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f000000000000000000000000000000000000000000000000000000001790529051611172969594939291016151c7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526111aa91614e1d565b60405180910390a450505050565b565b6111c2610eaa565b156111f9576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461124c576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061125782612567565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610add565b603660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d39190615005565b81602001516fffffffffffffffffffffffffffffffff16101561149e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610add565b6114bd81602001516fffffffffffffffffffffffffffffffff166125bb565b61156f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610add565b60365460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a919061505b565b82518151919250146116d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610add565b6116f381602001516fffffffffffffffffffffffffffffffff166125bb565b6117a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610add565b60008381526033602052604090205460ff1615611844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610add565b6000838152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558501516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055806118cf611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016119325761192b8660400151876080015188606001518960a001516126c3565b9150611b85565b8073ffffffffffffffffffffffffffffffffffffffff16866040015173ffffffffffffffffffffffffffffffffffffffff160361199b576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606086015115611b5c578560600151603d60008282546119bb919061522c565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015611a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a519190615005565b9050611a86876040015188606001518473ffffffffffffffffffffffffffffffffffffffff166127219092919063ffffffff16565b6060870151611a95908261522c565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015611aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b239190615005565b14611b5a576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08601515115611b805761192b8660400151876080015160008960a001516126c3565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405185907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90611be790851515815260200190565b60405180910390a281158015611bfd5750326001145b15611c34576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b6000611c49826010615243565b610ff290615208615273565b600080611c60611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601611ca7574791505090565b5050603d5490565b600054610100900460ff1615808015611ccf5750600054600160ff909116105b80611ce95750303b158015611ce9575060005460ff166001145b611d75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610add565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611dd357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603680547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8781169190911790925560378054909116858316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101008584160217905560325416611e8c57603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b611e9461277c565b8015611ef757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015611f89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fad919061529f565b90939092509050565b818015611fd8575073ffffffffffffffffffffffffffffffffffffffff861615155b1561200f576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120198151611c3c565b67ffffffffffffffff168367ffffffffffffffff161015612066576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c0815111156120a4576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333281146120c5575033731111000000000000000000000000000000001111015b600086868686866040516020016120e09594939291906151c7565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516121509190614e1d565b60405180910390a45050505050505050565b600154600090612198907801000000000000000000000000000000000000000000000000900467ffffffffffffffff164361522c565b905060006121a461288f565b90506000816020015160ff16826000015163ffffffff166121c59190615308565b905082156122fc576001546000906121fc908390700100000000000000000000000000000000900467ffffffffffffffff16615370565b90506000836040015160ff168361221391906153e4565b6001546122339084906fffffffffffffffffffffffffffffffff166153e4565b61223d9190615308565b60015490915060009061228e906122679084906fffffffffffffffffffffffffffffffff166154a0565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612950565b905060018611156122bd576122ba61226782876040015160ff1660018a6122b5919061522c565b61296f565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b6001805486919060109061232f908490700100000000000000000000000000000000900467ffffffffffffffff16615273565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1613156123bc576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906123e8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615514565b905060006123fa48633b9aca006129c4565b6124049083615551565b905060005a612413908861522c565b90508082111561085b5761085b61242a828461522c565b6129db565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052611ef79085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612a04565b6000816000015182602001518360400151846060015160405160200161254a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a0880151935160009761254a979096959101615565565b6000806125a386612b10565b90506125b181868686612b42565b9695505050505050565b603654604080517ff4daa291000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163f4daa2919160048083019260209291908290030181865afa15801561262b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264f9190615005565b6126599083614fed565b421192915050565b6001805463ffffffff8316919060109061269a908490700100000000000000000000000000000000900467ffffffffffffffff16615273565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b60008060006126d3866000612b72565b905080612709576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526127779084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612489565b505050565b600054610100900460ff16612813576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610add565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff166000036111b85760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa15801561292c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906155d0565b600061296561295f8585612b90565b83612ba0565b90505b9392505050565b6000670de0b6b3a76400006129b06129878583615308565b61299990670de0b6b3a7640000615370565b6129ab85670de0b6b3a76400006153e4565b612baf565b6129ba90866153e4565b6129659190615308565b6000818310156129d45781612968565b5090919050565b6000805a90505b825a6129ee908361522c565b1015612777576129fd82615673565b91506129e2565b6000612a66826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612be09092919063ffffffff16565b8051909150156127775780806020019051810190612a8491906151aa565b612777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610add565b60608180519060200120604051602001612b2c91815260200190565b6040516020818303038152906040529050919050565b6000612b6984612b53878686612bef565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000818312156129d45781612968565b60008183126129d45781612968565b6000612968670de0b6b3a764000083612bc78661366d565b612bd191906153e4565b612bdb9190615308565b6138b1565b60606129658484600085613af0565b60606000845111612c5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610add565b6000612c6784613c86565b90506000612c7486613d72565b9050600084604051602001612c8b91815260200190565b60405160208183030381529060405290506000805b84518110156135e4576000858281518110612cbd57612cbd6156ab565b602002602001015190508451831115612d58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610add565b82600003612e115780518051602091820120604051612da692612d8092910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610add565b612f68565b805151602011612ec75780518051602091820120604051612e3b92612d8092910190815260200190565b612e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610add565b805184516020808701919091208251919092012014612f68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610add565b612f7460106001614fed565b8160200151510361315057845183036130e857612fae8160200151601081518110612fa157612fa16156ab565b6020026020010151613dd5565b96506000875111613041576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610add565b6001865161304f919061522c565b82146130dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610add565b505050505050612968565b60008584815181106130fc576130fc6156ab565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110613127576131276156ab565b6020026020010151905061313a81613e89565b9550613147600186614fed565b945050506135d1565b60028160200151510361354957600061316882613eae565b905060008160008151811061317f5761317f6156ab565b016020015160f81c905060006131966002836156da565b6131a19060026156fc565b905060006131b2848360ff16613ed2565b905060006131c08a89613ed2565b905060006131ce8383613f08565b905080835114613260576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610add565b60ff851660021480613275575060ff85166003145b15613464578082511461330a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610add565b6133248760200151600181518110612fa157612fa16156ab565b9c5060008d51116133b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610add565b60018c516133c5919061522c565b8814613453576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610add565b505050505050505050505050612968565b60ff85161580613477575060ff85166001145b156134b6576134a38760200151600181518110613496576134966156ab565b6020026020010151613e89565b99506134af818a614fed565b985061353e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610add565b5050505050506135d1565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610add565b50806135dc81615673565b915050612ca0565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610add565b60008082136136d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b600060606136e584613fbc565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136138e257506000919050565b680755bf798b4a1bf1e58212613954576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610add565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613b82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610add565b73ffffffffffffffffffffffffffffffffffffffff85163b613c00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610add565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613c29919061571f565b60006040518083038185875af1925050503d8060008114613c66576040519150601f19603f3d011682016040523d82523d6000602084013e613c6b565b606091505b5091509150613c7b828286614092565b979650505050505050565b80516060908067ffffffffffffffff811115613ca457613ca4614a8b565b604051908082528060200260200182016040528015613ce957816020015b6040805180820190915260608082526020820152815260200190600190039081613cc25790505b50915060005b81811015613d6b576040518060400160405280858381518110613d1457613d146156ab565b60200260200101518152602001613d43868481518110613d3657613d366156ab565b60200260200101516140e5565b815250838281518110613d5857613d586156ab565b6020908102919091010152600101613cef565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015613dca578060011b82018184015160001a8060041c8253600f811660018301535050600101613d9c565b509295945050505050565b60606000806000613de5856140f8565b919450925090506000816001811115613e0057613e0061573b565b14613e37576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613e418284614fed565b855114613e7a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b6985602001518484614596565b60606020826000015110613ea557613ea082613dd5565b610ff2565b610ff28261462a565b6060610ff2613ecd8360200151600081518110612fa157612fa16156ab565b613d72565b606082518210613ef15750604080516020810190915260008152610ff2565b6129688383848651613f03919061522c565b614640565b6000808251845110613f1b578251613f1e565b83515b90505b8082108015613fa55750828281518110613f3d57613f3d6156ab565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613f7c57613f7c6156ab565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15613fb557816001019150613f21565b5092915050565b6000808211614027576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606083156140a1575081612968565b8251156140b15782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610add9190614e1d565b6060610ff26140f383614818565b614885565b6000806000836000015160000361413b576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f811161416057600060016000945094509450505061458f565b60b7811161427657600061417560808361522c565b9050808760000151116141b4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214801561422c57507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614263576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061458f915050565b60bf81116143d457600061428b60b78361522c565b9050808760000151116142ca576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361432c576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614374576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61437e8184614fed565b8951116143b7576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6143c2836001614fed565b975095506000945061458f9350505050565b60f781116144395760006143e960c08361522c565b905080876000015111614428576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061458f915050565b600061444660f78361522c565b905080876000015111614485576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036144e7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c6037811161452f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6145398184614fed565b895111614572576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61457d836001614fed565b975095506001945061458f9350505050565b9193909250565b60608167ffffffffffffffff8111156145b1576145b1614a8b565b6040519080825280601f01601f1916602001820160405280156145db576020820181803683370190505b50905081156129685760006145f08486614fed565b90506020820160005b848110156146115782810151828201526020016145f9565b84811115614620576000858301525b5050509392505050565b6060610ff2826020015160008460000151614596565b60608182601f0110156146af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b82828401101561471b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b81830184511015614788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610add565b6060821580156147a7576040519150600082526020820160405261480f565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156147e05780518352602092830192016147c8565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201528151600003614867576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000614895856140f8565b9194509250905060018160018111156148b0576148b061573b565b146148e7576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516148f38385614fed565b1461492a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816149415790505093506000835b8651811015614a2f576000806149b46040518060400160405280858c60000151614998919061522c565b8152602001858c602001516149ad9190614fed565b90526140f8565b5091509150604051806040016040528083836149d09190614fed565b8152602001848b602001516149e59190614fed565b8152508885815181106149fa576149fa6156ab565b6020908102919091010152614a10600185614fed565b9350614a1c8183614fed565b614a269084614fed565b9250505061496e565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114614a5d57600080fd5b50565b803567ffffffffffffffff81168114614a7857600080fd5b919050565b8015158114614a5d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614b0157614b01614a8b565b604052919050565b600082601f830112614b1a57600080fd5b813567ffffffffffffffff811115614b3457614b34614a8b565b614b6560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614aba565b818152846020838601011115614b7a57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614bb057600080fd5b8635614bbb81614a3b565b95506020870135945060408701359350614bd760608801614a60565b92506080870135614be781614a7d565b915060a087013567ffffffffffffffff811115614c0357600080fd5b614c0f89828a01614b09565b9150509295509295509295565b600060c08284031215614c2e57600080fd5b60405160c0810167ffffffffffffffff8282108183111715614c5257614c52614a8b565b816040528293508435835260208501359150614c6d82614a3b565b81602084015260408501359150614c8382614a3b565b816040840152606085013560608401526080850135608084015260a0850135915080821115614cb157600080fd5b50614cbe85828601614b09565b60a0830152505092915050565b600080600080600085870360e0811215614ce457600080fd5b863567ffffffffffffffff80821115614cfc57600080fd5b614d088a838b01614c1c565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614d4157600080fd5b60408901955060c0890135925080831115614d5b57600080fd5b828901925089601f840112614d6f57600080fd5b8235915080821115614d8057600080fd5b508860208260051b8401011115614d9657600080fd5b959894975092955050506020019190565b60005b83811015614dc2578181015183820152602001614daa565b83811115611ef75750506000910152565b60008151808452614deb816020860160208601614da7565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006129686020830184614dd3565b600060208284031215614e4257600080fd5b5035919050565b60ff81168114614a5d57600080fd5b60008060008060808587031215614e6e57600080fd5b8435614e7981614a3b565b93506020850135614e8981614e49565b93969395505050506040820135916060013590565b600060208284031215614eb057600080fd5b813567ffffffffffffffff811115614ec757600080fd5b614ed384828501614c1c565b949350505050565b600060208284031215614eed57600080fd5b61296882614a60565b600080600060608486031215614f0b57600080fd5b8335614f1681614a3b565b92506020840135614f2681614a3b565b91506040840135614f3681614a3b565b809150509250925092565b600080600080600060a08688031215614f5957600080fd5b8535614f6481614a3b565b945060208601359350614f7960408701614a60565b92506060860135614f8981614a7d565b9150608086013567ffffffffffffffff811115614fa557600080fd5b614fb188828901614b09565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561500057615000614fbe565b500190565b60006020828403121561501757600080fd5b5051919050565b60006020828403121561503057600080fd5b815161296881614a3b565b80516fffffffffffffffffffffffffffffffff81168114614a7857600080fd5b60006060828403121561506d57600080fd5b6040516060810181811067ffffffffffffffff8211171561509057615090614a8b565b604052825181526150a36020840161503b565b60208201526150b46040840161503b565b60408201529392505050565b6000608082840312156150d257600080fd5b6040516080810181811067ffffffffffffffff821117156150f5576150f5614a8b565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff8084111561514157615141614a8b565b8360051b6020615152818301614aba565b86815291850191818101903684111561516a57600080fd5b865b8481101561519e578035868111156151845760008081fd5b61519036828b01614b09565b84525091830191830161516c565b50979650505050505050565b6000602082840312156151bc57600080fd5b815161296881614a7d565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b60488201526000825161521b816049850160208701614da7565b919091016049019695505050505050565b60008282101561523e5761523e614fbe565b500390565b600067ffffffffffffffff8083168185168183048111821515161561526a5761526a614fbe565b02949350505050565b600067ffffffffffffffff80831681851680830382111561529657615296614fbe565b01949350505050565b600080604083850312156152b257600080fd5b82516152bd81614a3b565b60208401519092506152ce81614e49565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615317576153176152d9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561536b5761536b614fbe565b500590565b6000808312837f8000000000000000000000000000000000000000000000000000000000000000018312811516156153aa576153aa614fbe565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156153de576153de614fbe565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561542557615425614fbe565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561546057615460614fbe565b6000871292508782058712848416161561547c5761547c614fbe565b8785058712818416161561549257615492614fbe565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156154da576154da614fbe565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561550e5761550e614fbe565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561554c5761554c614fbe565b500290565b600082615560576155606152d9565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526155b060c0830184614dd3565b98975050505050505050565b805163ffffffff81168114614a7857600080fd5b600060c082840312156155e257600080fd5b60405160c0810181811067ffffffffffffffff8211171561560557615605614a8b565b604052615611836155bc565b8152602083015161562181614e49565b6020820152604083015161563481614e49565b6040820152615645606084016155bc565b6060820152615656608084016155bc565b608082015261566760a0840161503b565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036156a4576156a4614fbe565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806156ed576156ed6152d9565b8060ff84160691505092915050565b600060ff821660ff84168082101561571657615716614fbe565b90039392505050565b60008251615731818460208701614da7565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a", - "deployedCode": "0x6080604052600436106101635760003560e01c80638c3152e9116100c0578063b69ef8a811610074578063cff0ab9611610059578063cff0ab9614610444578063e965084c146104e5578063e9e05c421461057157600080fd5b8063b69ef8a814610401578063c0c53b8b1461042457600080fd5b80639bf62d82116100a55780639bf62d821461036b578063a14238e714610398578063a35d99df146103c857600080fd5b80638c3152e91461031e5780639b5f694a1461033e57600080fd5b806354fd4d50116101175780636dbffb78116100fc5780636dbffb78146102de57806371cfaa3f146102fe5780638b4c40b01461018857600080fd5b806354fd4d501461026d5780635c975abb146102b957600080fd5b806335e80ab31161014857806335e80ab314610206578063452a9320146102385780634870496f1461024d57600080fd5b8063149f2f221461018f57806333d7e2bd146101af57600080fd5b3661018a576101883334620186a060006040518060200160405280600081525061057f565b005b600080fd5b34801561019b57600080fd5b506101886101aa366004614b97565b610624565b3480156101bb57600080fd5b506037546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561021257600080fd5b506035546101dc90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561024457600080fd5b506101dc610865565b34801561025957600080fd5b50610188610268366004614ccb565b6108fd565b34801561027957600080fd5b50604080518082018252600c81527f322e382e312d626574612e310000000000000000000000000000000000000000602082015290516101fd9190614e1d565b3480156102c557600080fd5b506102ce610eaa565b60405190151581526020016101fd565b3480156102ea57600080fd5b506102ce6102f9366004614e30565b610f3d565b34801561030a57600080fd5b50610188610319366004614e58565b610ff8565b34801561032a57600080fd5b50610188610339366004614e9e565b6111ba565b34801561034a57600080fd5b506036546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561037757600080fd5b506032546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103a457600080fd5b506102ce6103b3366004614e30565b60336020526000908152604090205460ff1681565b3480156103d457600080fd5b506103e86103e3366004614edb565b611c3c565b60405167ffffffffffffffff90911681526020016101fd565b34801561040d57600080fd5b50610416611c55565b6040519081526020016101fd565b34801561043057600080fd5b5061018861043f366004614ef6565b611caf565b34801561045057600080fd5b506001546104ac906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101fd565b3480156104f157600080fd5b50610543610500366004614e30565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101fd565b61018861057f366004614f41565b8260005a9050600061058f611f19565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906105cb57503415155b15610602576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610610883489898989611fb6565b5061061b8282612162565b50505050505050565b8260005a90506000610634611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016106a6576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546106b89190614fed565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561072a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074e9190615005565b905061077273ffffffffffffffffffffffffffffffffffffffff831633308c61242f565b61077c8982614fed565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa1580156107e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080a9190615005565b14610841576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61084f8a8a8a8a8a8a611fb6565b505061085b8282612162565b5050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f8919061501e565b905090565b610905610eaa565b1561093c576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16036109a5576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6036546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810186905260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610a15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a39919061505b565b519050610a53610a4e368690038601866150c0565b61250b565b8114610ae6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f66000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000610af187612567565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610c075750805160365460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610bdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c03919061505b565b5114155b610c93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610add565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610d5c9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610d52888a615126565b8a60400135612597565b610de8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610add565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f19573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906151aa565b6036546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101839052600091610ff29173ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd7919061505b565b602001516fffffffffffffffffffffffffffffffff166125bb565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff163314611049576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61105562030d40612661565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f000000000000000000000000000000000000000000000000000000001790529051611172969594939291016151c7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526111aa91614e1d565b60405180910390a450505050565b565b6111c2610eaa565b156111f9576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461124c576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061125782612567565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610add565b603660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d39190615005565b81602001516fffffffffffffffffffffffffffffffff16101561149e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610add565b6114bd81602001516fffffffffffffffffffffffffffffffff166125bb565b61156f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610add565b60365460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a919061505b565b82518151919250146116d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610add565b6116f381602001516fffffffffffffffffffffffffffffffff166125bb565b6117a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610add565b60008381526033602052604090205460ff1615611844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610add565b6000838152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558501516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055806118cf611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016119325761192b8660400151876080015188606001518960a001516126c3565b9150611b85565b8073ffffffffffffffffffffffffffffffffffffffff16866040015173ffffffffffffffffffffffffffffffffffffffff160361199b576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606086015115611b5c578560600151603d60008282546119bb919061522c565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015611a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a519190615005565b9050611a86876040015188606001518473ffffffffffffffffffffffffffffffffffffffff166127219092919063ffffffff16565b6060870151611a95908261522c565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015611aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b239190615005565b14611b5a576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08601515115611b805761192b8660400151876080015160008960a001516126c3565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405185907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90611be790851515815260200190565b60405180910390a281158015611bfd5750326001145b15611c34576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b6000611c49826010615243565b610ff290615208615273565b600080611c60611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601611ca7574791505090565b5050603d5490565b600054610100900460ff1615808015611ccf5750600054600160ff909116105b80611ce95750303b158015611ce9575060005460ff166001145b611d75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610add565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611dd357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603680547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8781169190911790925560378054909116858316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101008584160217905560325416611e8c57603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b611e9461277c565b8015611ef757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015611f89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fad919061529f565b90939092509050565b818015611fd8575073ffffffffffffffffffffffffffffffffffffffff861615155b1561200f576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120198151611c3c565b67ffffffffffffffff168367ffffffffffffffff161015612066576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c0815111156120a4576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333281146120c5575033731111000000000000000000000000000000001111015b600086868686866040516020016120e09594939291906151c7565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516121509190614e1d565b60405180910390a45050505050505050565b600154600090612198907801000000000000000000000000000000000000000000000000900467ffffffffffffffff164361522c565b905060006121a461288f565b90506000816020015160ff16826000015163ffffffff166121c59190615308565b905082156122fc576001546000906121fc908390700100000000000000000000000000000000900467ffffffffffffffff16615370565b90506000836040015160ff168361221391906153e4565b6001546122339084906fffffffffffffffffffffffffffffffff166153e4565b61223d9190615308565b60015490915060009061228e906122679084906fffffffffffffffffffffffffffffffff166154a0565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612950565b905060018611156122bd576122ba61226782876040015160ff1660018a6122b5919061522c565b61296f565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b6001805486919060109061232f908490700100000000000000000000000000000000900467ffffffffffffffff16615273565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1613156123bc576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906123e8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615514565b905060006123fa48633b9aca006129c4565b6124049083615551565b905060005a612413908861522c565b90508082111561085b5761085b61242a828461522c565b6129db565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052611ef79085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612a04565b6000816000015182602001518360400151846060015160405160200161254a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a0880151935160009761254a979096959101615565565b6000806125a386612b10565b90506125b181868686612b42565b9695505050505050565b603654604080517ff4daa291000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163f4daa2919160048083019260209291908290030181865afa15801561262b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264f9190615005565b6126599083614fed565b421192915050565b6001805463ffffffff8316919060109061269a908490700100000000000000000000000000000000900467ffffffffffffffff16615273565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b60008060006126d3866000612b72565b905080612709576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526127779084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612489565b505050565b600054610100900460ff16612813576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610add565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff166000036111b85760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa15801561292c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906155d0565b600061296561295f8585612b90565b83612ba0565b90505b9392505050565b6000670de0b6b3a76400006129b06129878583615308565b61299990670de0b6b3a7640000615370565b6129ab85670de0b6b3a76400006153e4565b612baf565b6129ba90866153e4565b6129659190615308565b6000818310156129d45781612968565b5090919050565b6000805a90505b825a6129ee908361522c565b1015612777576129fd82615673565b91506129e2565b6000612a66826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612be09092919063ffffffff16565b8051909150156127775780806020019051810190612a8491906151aa565b612777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610add565b60608180519060200120604051602001612b2c91815260200190565b6040516020818303038152906040529050919050565b6000612b6984612b53878686612bef565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000818312156129d45781612968565b60008183126129d45781612968565b6000612968670de0b6b3a764000083612bc78661366d565b612bd191906153e4565b612bdb9190615308565b6138b1565b60606129658484600085613af0565b60606000845111612c5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610add565b6000612c6784613c86565b90506000612c7486613d72565b9050600084604051602001612c8b91815260200190565b60405160208183030381529060405290506000805b84518110156135e4576000858281518110612cbd57612cbd6156ab565b602002602001015190508451831115612d58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610add565b82600003612e115780518051602091820120604051612da692612d8092910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610add565b612f68565b805151602011612ec75780518051602091820120604051612e3b92612d8092910190815260200190565b612e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610add565b805184516020808701919091208251919092012014612f68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610add565b612f7460106001614fed565b8160200151510361315057845183036130e857612fae8160200151601081518110612fa157612fa16156ab565b6020026020010151613dd5565b96506000875111613041576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610add565b6001865161304f919061522c565b82146130dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610add565b505050505050612968565b60008584815181106130fc576130fc6156ab565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110613127576131276156ab565b6020026020010151905061313a81613e89565b9550613147600186614fed565b945050506135d1565b60028160200151510361354957600061316882613eae565b905060008160008151811061317f5761317f6156ab565b016020015160f81c905060006131966002836156da565b6131a19060026156fc565b905060006131b2848360ff16613ed2565b905060006131c08a89613ed2565b905060006131ce8383613f08565b905080835114613260576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610add565b60ff851660021480613275575060ff85166003145b15613464578082511461330a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610add565b6133248760200151600181518110612fa157612fa16156ab565b9c5060008d51116133b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610add565b60018c516133c5919061522c565b8814613453576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610add565b505050505050505050505050612968565b60ff85161580613477575060ff85166001145b156134b6576134a38760200151600181518110613496576134966156ab565b6020026020010151613e89565b99506134af818a614fed565b985061353e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610add565b5050505050506135d1565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610add565b50806135dc81615673565b915050612ca0565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610add565b60008082136136d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b600060606136e584613fbc565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136138e257506000919050565b680755bf798b4a1bf1e58212613954576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610add565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613b82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610add565b73ffffffffffffffffffffffffffffffffffffffff85163b613c00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610add565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613c29919061571f565b60006040518083038185875af1925050503d8060008114613c66576040519150601f19603f3d011682016040523d82523d6000602084013e613c6b565b606091505b5091509150613c7b828286614092565b979650505050505050565b80516060908067ffffffffffffffff811115613ca457613ca4614a8b565b604051908082528060200260200182016040528015613ce957816020015b6040805180820190915260608082526020820152815260200190600190039081613cc25790505b50915060005b81811015613d6b576040518060400160405280858381518110613d1457613d146156ab565b60200260200101518152602001613d43868481518110613d3657613d366156ab565b60200260200101516140e5565b815250838281518110613d5857613d586156ab565b6020908102919091010152600101613cef565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015613dca578060011b82018184015160001a8060041c8253600f811660018301535050600101613d9c565b509295945050505050565b60606000806000613de5856140f8565b919450925090506000816001811115613e0057613e0061573b565b14613e37576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613e418284614fed565b855114613e7a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b6985602001518484614596565b60606020826000015110613ea557613ea082613dd5565b610ff2565b610ff28261462a565b6060610ff2613ecd8360200151600081518110612fa157612fa16156ab565b613d72565b606082518210613ef15750604080516020810190915260008152610ff2565b6129688383848651613f03919061522c565b614640565b6000808251845110613f1b578251613f1e565b83515b90505b8082108015613fa55750828281518110613f3d57613f3d6156ab565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613f7c57613f7c6156ab565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15613fb557816001019150613f21565b5092915050565b6000808211614027576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606083156140a1575081612968565b8251156140b15782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610add9190614e1d565b6060610ff26140f383614818565b614885565b6000806000836000015160000361413b576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f811161416057600060016000945094509450505061458f565b60b7811161427657600061417560808361522c565b9050808760000151116141b4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214801561422c57507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614263576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061458f915050565b60bf81116143d457600061428b60b78361522c565b9050808760000151116142ca576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361432c576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614374576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61437e8184614fed565b8951116143b7576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6143c2836001614fed565b975095506000945061458f9350505050565b60f781116144395760006143e960c08361522c565b905080876000015111614428576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061458f915050565b600061444660f78361522c565b905080876000015111614485576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036144e7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c6037811161452f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6145398184614fed565b895111614572576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61457d836001614fed565b975095506001945061458f9350505050565b9193909250565b60608167ffffffffffffffff8111156145b1576145b1614a8b565b6040519080825280601f01601f1916602001820160405280156145db576020820181803683370190505b50905081156129685760006145f08486614fed565b90506020820160005b848110156146115782810151828201526020016145f9565b84811115614620576000858301525b5050509392505050565b6060610ff2826020015160008460000151614596565b60608182601f0110156146af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b82828401101561471b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b81830184511015614788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610add565b6060821580156147a7576040519150600082526020820160405261480f565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156147e05780518352602092830192016147c8565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201528151600003614867576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000614895856140f8565b9194509250905060018160018111156148b0576148b061573b565b146148e7576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516148f38385614fed565b1461492a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816149415790505093506000835b8651811015614a2f576000806149b46040518060400160405280858c60000151614998919061522c565b8152602001858c602001516149ad9190614fed565b90526140f8565b5091509150604051806040016040528083836149d09190614fed565b8152602001848b602001516149e59190614fed565b8152508885815181106149fa576149fa6156ab565b6020908102919091010152614a10600185614fed565b9350614a1c8183614fed565b614a269084614fed565b9250505061496e565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114614a5d57600080fd5b50565b803567ffffffffffffffff81168114614a7857600080fd5b919050565b8015158114614a5d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614b0157614b01614a8b565b604052919050565b600082601f830112614b1a57600080fd5b813567ffffffffffffffff811115614b3457614b34614a8b565b614b6560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614aba565b818152846020838601011115614b7a57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614bb057600080fd5b8635614bbb81614a3b565b95506020870135945060408701359350614bd760608801614a60565b92506080870135614be781614a7d565b915060a087013567ffffffffffffffff811115614c0357600080fd5b614c0f89828a01614b09565b9150509295509295509295565b600060c08284031215614c2e57600080fd5b60405160c0810167ffffffffffffffff8282108183111715614c5257614c52614a8b565b816040528293508435835260208501359150614c6d82614a3b565b81602084015260408501359150614c8382614a3b565b816040840152606085013560608401526080850135608084015260a0850135915080821115614cb157600080fd5b50614cbe85828601614b09565b60a0830152505092915050565b600080600080600085870360e0811215614ce457600080fd5b863567ffffffffffffffff80821115614cfc57600080fd5b614d088a838b01614c1c565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614d4157600080fd5b60408901955060c0890135925080831115614d5b57600080fd5b828901925089601f840112614d6f57600080fd5b8235915080821115614d8057600080fd5b508860208260051b8401011115614d9657600080fd5b959894975092955050506020019190565b60005b83811015614dc2578181015183820152602001614daa565b83811115611ef75750506000910152565b60008151808452614deb816020860160208601614da7565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006129686020830184614dd3565b600060208284031215614e4257600080fd5b5035919050565b60ff81168114614a5d57600080fd5b60008060008060808587031215614e6e57600080fd5b8435614e7981614a3b565b93506020850135614e8981614e49565b93969395505050506040820135916060013590565b600060208284031215614eb057600080fd5b813567ffffffffffffffff811115614ec757600080fd5b614ed384828501614c1c565b949350505050565b600060208284031215614eed57600080fd5b61296882614a60565b600080600060608486031215614f0b57600080fd5b8335614f1681614a3b565b92506020840135614f2681614a3b565b91506040840135614f3681614a3b565b809150509250925092565b600080600080600060a08688031215614f5957600080fd5b8535614f6481614a3b565b945060208601359350614f7960408701614a60565b92506060860135614f8981614a7d565b9150608086013567ffffffffffffffff811115614fa557600080fd5b614fb188828901614b09565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561500057615000614fbe565b500190565b60006020828403121561501757600080fd5b5051919050565b60006020828403121561503057600080fd5b815161296881614a3b565b80516fffffffffffffffffffffffffffffffff81168114614a7857600080fd5b60006060828403121561506d57600080fd5b6040516060810181811067ffffffffffffffff8211171561509057615090614a8b565b604052825181526150a36020840161503b565b60208201526150b46040840161503b565b60408201529392505050565b6000608082840312156150d257600080fd5b6040516080810181811067ffffffffffffffff821117156150f5576150f5614a8b565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff8084111561514157615141614a8b565b8360051b6020615152818301614aba565b86815291850191818101903684111561516a57600080fd5b865b8481101561519e578035868111156151845760008081fd5b61519036828b01614b09565b84525091830191830161516c565b50979650505050505050565b6000602082840312156151bc57600080fd5b815161296881614a7d565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b60488201526000825161521b816049850160208701614da7565b919091016049019695505050505050565b60008282101561523e5761523e614fbe565b500390565b600067ffffffffffffffff8083168185168183048111821515161561526a5761526a614fbe565b02949350505050565b600067ffffffffffffffff80831681851680830382111561529657615296614fbe565b01949350505050565b600080604083850312156152b257600080fd5b82516152bd81614a3b565b60208401519092506152ce81614e49565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615317576153176152d9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561536b5761536b614fbe565b500590565b6000808312837f8000000000000000000000000000000000000000000000000000000000000000018312811516156153aa576153aa614fbe565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156153de576153de614fbe565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561542557615425614fbe565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561546057615460614fbe565b6000871292508782058712848416161561547c5761547c614fbe565b8785058712818416161561549257615492614fbe565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156154da576154da614fbe565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561550e5761550e614fbe565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561554c5761554c614fbe565b500290565b600082615560576155606152d9565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526155b060c0830184614dd3565b98975050505050505050565b805163ffffffff81168114614a7857600080fd5b600060c082840312156155e257600080fd5b60405160c0810181811067ffffffffffffffff8211171561560557615605614a8b565b604052615611836155bc565b8152602083015161562181614e49565b6020820152604083015161563481614e49565b6040820152615645606084016155bc565b6060820152615656608084016155bc565b608082015261566760a0840161503b565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036156a4576156a4614fbe565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806156ed576156ed6152d9565b8060ff84160691505092915050565b600060ff821660ff84168082101561571657615716614fbe565b90039392505050565b60008251615731818460208701614da7565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000036" - }, - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000036" - }, - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000037" - }, - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000037" - }, - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" - }, - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" - }, - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - }, - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - }, - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": true, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - }, - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": true, - "newValue": "0x000000000000000100000000000000000000000000000000000000003b9aca00", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xfa60f9b2", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000f" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": false, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9b5f694a", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000036" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x33d7e2bd", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000037" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x35e80ab3", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9bf62d82", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000dead", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x638627e586f5e36fe67a77519503a7c6da22f92b150d3c6055fd40bdcfe9ffd160806040523480156200001157600080fd5b50620000256001806000808080806200002b565b62000328565b600054610100900460ff16158080156200004c5750600054600160ff909116105b806200007c575062000069306200031960201b6200135d1760201c565b1580156200007c575060005460ff166001145b620000e55760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000109576000805461ff0019166101001790555b60008811620001815760405162461bcd60e51b815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e20300000000000006064820152608401620000dc565b60008711620001f95760405162461bcd60e51b815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e20300000000000000000000000006064820152608401620000dc565b428511156200027f5760405162461bcd60e51b8152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201526374696d6560e01b608482015260a401620000dc565b6004889055600587905560018690556002859055600780546001600160a01b038087166001600160a01b0319928316179092556006805492861692909116919091179055600882905580156200030f576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b6001600160a01b03163b151590565b6115d580620003386000396000f3fe60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec33481461049b578063e1a41bcf146104b0578063f4daa291146104c657600080fd5b8063ce5db8d614610445578063cf8e5cf01461045b578063d1de856c1461047b57600080fd5b8063a25ae557116100b0578063a25ae55714610391578063a8e4fb90146103ed578063bffa7f0f1461041a57600080fd5b806389c44cbb1461034857806393991af3146103685780639aaab6481461037e57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa5146102fc5780637f00642014610312578063887862721461033257600080fd5b806369f16eec146102a75780636abcf563146102bc5780636b4d98dd146102d157600080fd5b8063529933df11610169578063529933df146101ea578063534db0e2146101ff57806354fd4d501461025157600080fd5b80622134cc1461018f5780631c89c97d146101b35780634599c788146101d5575b600080fd5b34801561019b57600080fd5b506005545b6040519081526020015b60405180910390f35b3480156101bf57600080fd5b506101d36101ce3660046113a2565b6104db565b005b3480156101e157600080fd5b506101a06108b6565b3480156101f657600080fd5b506004546101a0565b34801561020b57600080fd5b5060065461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101aa565b34801561025d57600080fd5b5061029a6040518060400160405280600581526020017f312e382e3000000000000000000000000000000000000000000000000000000081525081565b6040516101aa9190611405565b3480156102b357600080fd5b506101a0610929565b3480156102c857600080fd5b506003546101a0565b3480156102dd57600080fd5b5060065473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561030857600080fd5b506101a060015481565b34801561031e57600080fd5b506101a061032d366004611478565b61093b565b34801561033e57600080fd5b506101a060025481565b34801561035457600080fd5b506101d3610363366004611478565b610b4f565b34801561037457600080fd5b506101a060055481565b6101d361038c366004611491565b610de9565b34801561039d57600080fd5b506103b16103ac366004611478565b61124a565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101aa565b3480156103f957600080fd5b5060075461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561042657600080fd5b5060075473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561045157600080fd5b506101a060085481565b34801561046757600080fd5b506103b1610476366004611478565b6112de565b34801561048757600080fd5b506101a0610496366004611478565b611316565b3480156104a757600080fd5b506101a0611346565b3480156104bc57600080fd5b506101a060045481565b3480156104d257600080fd5b506008546101a0565b600054610100900460ff16158080156104fb5750600054600160ff909116105b806105155750303b158015610515575060005460ff166001145b6105a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561060457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60008811610694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e2030000000000000606482015260840161059d565b60008711610724576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e2030000000000000000000000000606482015260840161059d565b428511156107db576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60048890556005879055600186905560028590556007805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556006805492861692909116919091179055600882905580156108ac57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b6003546000901561092057600380546108d1906001906114f2565b815481106108e1576108e1611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b600354600090610924906001906114f2565b60006109456108b6565b8211156109fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161059d565b600354610aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161059d565b6003546000905b80821015610b485760006002610acc8385611538565b610ad69190611550565b90508460038281548110610aec57610aec611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610b3e57610b37816001611538565b9250610b42565b8091505b50610ab6565b5092915050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610bf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161059d565b6003548110610cad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60085460038281548110610cc357610cc3611509565b6000918252602090912060016002909202010154610cf3906fffffffffffffffffffffffffffffffff16426114f2565b10610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161059d565b6000610db160035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60075473ffffffffffffffffffffffffffffffffffffffff163314610eb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b610ebe611346565b8314610f72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161059d565b42610f7c84611316565b10611009576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161059d565b83611096576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161059d565b81156111525781814014611152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161059d565b8261115c60035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e24260405161118e91815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b60408051606081018252600080825260208201819052918101919091526003828154811061127a5761127a611509565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b604080516060810182526000808252602082018190529181019190915260036113068361093b565b8154811061127a5761127a611509565b60006005546001548361132991906114f2565b611333919061158b565b6002546113409190611538565b92915050565b60006004546113536108b6565b6109249190611538565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b803573ffffffffffffffffffffffffffffffffffffffff8116811461139d57600080fd5b919050565b600080600080600080600060e0888a0312156113bd57600080fd5b873596506020880135955060408801359450606088013593506113e260808901611379565b92506113f060a08901611379565b915060c0880135905092959891949750929550565b600060208083528351808285015260005b8181101561143257858101830151858201604001528201611416565b81811115611444576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561148a57600080fd5b5035919050565b600080600080608085870312156114a757600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611504576115046114c3565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000821982111561154b5761154b6114c3565b500190565b600082611586577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156115c3576115c36114c3565b50029056fea164736f6c634300080f000a", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x60806040523480156200001157600080fd5b50620000256001806000808080806200002b565b62000328565b600054610100900460ff16158080156200004c5750600054600160ff909116105b806200007c575062000069306200031960201b6200135d1760201c565b1580156200007c575060005460ff166001145b620000e55760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000109576000805461ff0019166101001790555b60008811620001815760405162461bcd60e51b815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e20300000000000006064820152608401620000dc565b60008711620001f95760405162461bcd60e51b815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e20300000000000000000000000006064820152608401620000dc565b428511156200027f5760405162461bcd60e51b8152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201526374696d6560e01b608482015260a401620000dc565b6004889055600587905560018690556002859055600780546001600160a01b038087166001600160a01b0319928316179092556006805492861692909116919091179055600882905580156200030f576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b6001600160a01b03163b151590565b6115d580620003386000396000f3fe60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec33481461049b578063e1a41bcf146104b0578063f4daa291146104c657600080fd5b8063ce5db8d614610445578063cf8e5cf01461045b578063d1de856c1461047b57600080fd5b8063a25ae557116100b0578063a25ae55714610391578063a8e4fb90146103ed578063bffa7f0f1461041a57600080fd5b806389c44cbb1461034857806393991af3146103685780639aaab6481461037e57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa5146102fc5780637f00642014610312578063887862721461033257600080fd5b806369f16eec146102a75780636abcf563146102bc5780636b4d98dd146102d157600080fd5b8063529933df11610169578063529933df146101ea578063534db0e2146101ff57806354fd4d501461025157600080fd5b80622134cc1461018f5780631c89c97d146101b35780634599c788146101d5575b600080fd5b34801561019b57600080fd5b506005545b6040519081526020015b60405180910390f35b3480156101bf57600080fd5b506101d36101ce3660046113a2565b6104db565b005b3480156101e157600080fd5b506101a06108b6565b3480156101f657600080fd5b506004546101a0565b34801561020b57600080fd5b5060065461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101aa565b34801561025d57600080fd5b5061029a6040518060400160405280600581526020017f312e382e3000000000000000000000000000000000000000000000000000000081525081565b6040516101aa9190611405565b3480156102b357600080fd5b506101a0610929565b3480156102c857600080fd5b506003546101a0565b3480156102dd57600080fd5b5060065473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561030857600080fd5b506101a060015481565b34801561031e57600080fd5b506101a061032d366004611478565b61093b565b34801561033e57600080fd5b506101a060025481565b34801561035457600080fd5b506101d3610363366004611478565b610b4f565b34801561037457600080fd5b506101a060055481565b6101d361038c366004611491565b610de9565b34801561039d57600080fd5b506103b16103ac366004611478565b61124a565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101aa565b3480156103f957600080fd5b5060075461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561042657600080fd5b5060075473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561045157600080fd5b506101a060085481565b34801561046757600080fd5b506103b1610476366004611478565b6112de565b34801561048757600080fd5b506101a0610496366004611478565b611316565b3480156104a757600080fd5b506101a0611346565b3480156104bc57600080fd5b506101a060045481565b3480156104d257600080fd5b506008546101a0565b600054610100900460ff16158080156104fb5750600054600160ff909116105b806105155750303b158015610515575060005460ff166001145b6105a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561060457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60008811610694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e2030000000000000606482015260840161059d565b60008711610724576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e2030000000000000000000000000606482015260840161059d565b428511156107db576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60048890556005879055600186905560028590556007805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556006805492861692909116919091179055600882905580156108ac57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b6003546000901561092057600380546108d1906001906114f2565b815481106108e1576108e1611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b600354600090610924906001906114f2565b60006109456108b6565b8211156109fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161059d565b600354610aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161059d565b6003546000905b80821015610b485760006002610acc8385611538565b610ad69190611550565b90508460038281548110610aec57610aec611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610b3e57610b37816001611538565b9250610b42565b8091505b50610ab6565b5092915050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610bf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161059d565b6003548110610cad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60085460038281548110610cc357610cc3611509565b6000918252602090912060016002909202010154610cf3906fffffffffffffffffffffffffffffffff16426114f2565b10610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161059d565b6000610db160035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60075473ffffffffffffffffffffffffffffffffffffffff163314610eb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b610ebe611346565b8314610f72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161059d565b42610f7c84611316565b10611009576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161059d565b83611096576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161059d565b81156111525781814014611152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161059d565b8261115c60035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e24260405161118e91815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b60408051606081018252600080825260208201819052918101919091526003828154811061127a5761127a611509565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b604080516060810182526000808252602082018190529181019190915260036113068361093b565b8154811061127a5761127a611509565b60006005546001548361132991906114f2565b611333919061158b565b6002546113409190611538565b92915050565b60006004546113536108b6565b6109249190611538565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b803573ffffffffffffffffffffffffffffffffffffffff8116811461139d57600080fd5b919050565b600080600080600080600060e0888a0312156113bd57600080fd5b873596506020880135955060408801359450606088013593506113e260808901611379565b92506113f060a08901611379565b915060c0880135905092959891949750929550565b600060208083528351808285015260005b8181101561143257858101830151858201604001528201611416565b81811115611444576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561148a57600080fd5b5035919050565b600080600080608085870312156114a757600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611504576115046114c3565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000821982111561154b5761154b6114c3565b500190565b600082611586577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156115c3576115c36114c3565b50029056fea164736f6c634300080f000a", - "deployedCode": "0x60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec33481461049b578063e1a41bcf146104b0578063f4daa291146104c657600080fd5b8063ce5db8d614610445578063cf8e5cf01461045b578063d1de856c1461047b57600080fd5b8063a25ae557116100b0578063a25ae55714610391578063a8e4fb90146103ed578063bffa7f0f1461041a57600080fd5b806389c44cbb1461034857806393991af3146103685780639aaab6481461037e57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa5146102fc5780637f00642014610312578063887862721461033257600080fd5b806369f16eec146102a75780636abcf563146102bc5780636b4d98dd146102d157600080fd5b8063529933df11610169578063529933df146101ea578063534db0e2146101ff57806354fd4d501461025157600080fd5b80622134cc1461018f5780631c89c97d146101b35780634599c788146101d5575b600080fd5b34801561019b57600080fd5b506005545b6040519081526020015b60405180910390f35b3480156101bf57600080fd5b506101d36101ce3660046113a2565b6104db565b005b3480156101e157600080fd5b506101a06108b6565b3480156101f657600080fd5b506004546101a0565b34801561020b57600080fd5b5060065461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101aa565b34801561025d57600080fd5b5061029a6040518060400160405280600581526020017f312e382e3000000000000000000000000000000000000000000000000000000081525081565b6040516101aa9190611405565b3480156102b357600080fd5b506101a0610929565b3480156102c857600080fd5b506003546101a0565b3480156102dd57600080fd5b5060065473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561030857600080fd5b506101a060015481565b34801561031e57600080fd5b506101a061032d366004611478565b61093b565b34801561033e57600080fd5b506101a060025481565b34801561035457600080fd5b506101d3610363366004611478565b610b4f565b34801561037457600080fd5b506101a060055481565b6101d361038c366004611491565b610de9565b34801561039d57600080fd5b506103b16103ac366004611478565b61124a565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101aa565b3480156103f957600080fd5b5060075461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561042657600080fd5b5060075473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561045157600080fd5b506101a060085481565b34801561046757600080fd5b506103b1610476366004611478565b6112de565b34801561048757600080fd5b506101a0610496366004611478565b611316565b3480156104a757600080fd5b506101a0611346565b3480156104bc57600080fd5b506101a060045481565b3480156104d257600080fd5b506008546101a0565b600054610100900460ff16158080156104fb5750600054600160ff909116105b806105155750303b158015610515575060005460ff166001145b6105a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561060457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60008811610694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e2030000000000000606482015260840161059d565b60008711610724576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e2030000000000000000000000000606482015260840161059d565b428511156107db576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60048890556005879055600186905560028590556007805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556006805492861692909116919091179055600882905580156108ac57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b6003546000901561092057600380546108d1906001906114f2565b815481106108e1576108e1611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b600354600090610924906001906114f2565b60006109456108b6565b8211156109fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161059d565b600354610aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161059d565b6003546000905b80821015610b485760006002610acc8385611538565b610ad69190611550565b90508460038281548110610aec57610aec611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610b3e57610b37816001611538565b9250610b42565b8091505b50610ab6565b5092915050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610bf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161059d565b6003548110610cad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60085460038281548110610cc357610cc3611509565b6000918252602090912060016002909202010154610cf3906fffffffffffffffffffffffffffffffff16426114f2565b10610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161059d565b6000610db160035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60075473ffffffffffffffffffffffffffffffffffffffff163314610eb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b610ebe611346565b8314610f72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161059d565b42610f7c84611316565b10611009576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161059d565b83611096576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161059d565b81156111525781814014611152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161059d565b8261115c60035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e24260405161118e91815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b60408051606081018252600080825260208201819052918101919091526003828154811061127a5761127a611509565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b604080516060810182526000808252602082018190529181019190915260036113068361093b565b8154811061127a5761127a611509565b60006005546001548361132991906114f2565b611333919061158b565b6002546113409190611538565b92915050565b60006004546113536108b6565b6109249190611538565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b803573ffffffffffffffffffffffffffffffffffffffff8116811461139d57600080fd5b919050565b600080600080600080600060e0888a0312156113bd57600080fd5b873596506020880135955060408801359450606088013593506113e260808901611379565b92506113f060a08901611379565b915060c0880135905092959891949750929550565b600060208083528351808285015260005b8181101561143257858101830151858201604001528201611416565b81811115611444576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561148a57600080fd5b5035919050565b600080600080608085870312156114a757600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611504576115046114c3565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000821982111561154b5761154b6114c3565b500190565b600082611586577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156115c3576115c36114c3565b50029056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" - }, - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000007" - }, - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000007" - }, - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000006" - }, - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000006" - }, - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000008" - }, - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x529933df", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xe1a41bcf", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x002134cc", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x93991af3", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xbffa7f0f", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000007" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xa8e4fb90", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000007" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6b4d98dd", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000006" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x534db0e2", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000006" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf4daa291", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000008" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xce5db8d6", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000008" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x70872aa5", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x88786272", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x3c9f397c", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000043" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x3c9f397c", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000043" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x493f862b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000004a" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xbf653a5c", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000000c", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000000c", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000041" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x952b2797", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000006", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000006", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000042" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x638627e586f5e36fe67a77519503a7c6da22f92b150d3c6055fd40bdcfe9ffd160c06040523480156200001157600080fd5b5060405162006010380380620060108339810160408190526200003491620002f2565b608082905260a08190526200004d600080808062000055565b505062000317565b600054610100900460ff1615808015620000765750600054600160ff909116105b80620000a6575062000093306200022460201b620023cd1760201c565b158015620000a6575060005460ff166001145b6200010f5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000133576000805461ff0019166101001790555b603880546001600160a01b03199081166001600160a01b03888116919091179092556037805490911686831617905560358054610100600160a81b0319166101008684160217905560325416620001cc576032805461dead6001600160a01b0319909116179055603b80546001600160601b031916640100000000426001600160401b03160263ffffffff19161763ffffffff84161790555b620001d662000233565b80156200021d576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b6001600160a01b03163b151590565b600054610100900460ff16620002a05760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840162000106565b600154600160c01b90046001600160401b0316600003620002f05760408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b02176001555b565b600080604083850312156200030657600080fd5b505080516020909101519092909150565b60805160a051615cc56200034b6000396000818161051a0152611b280152600081816106a601526118120152615cc56000f3fe6080604052600436106101d15760003560e01c80637fc48504116100f7578063a35d99df11610095578063bf653a5c11610064578063bf653a5c14610697578063cff0ab96146106ca578063e9e05c421461076b578063f2b4e6171461077e57600080fd5b8063a35d99df1461059b578063a3860f48146105bb578063b69ef8a8146105db578063bb2c727e146105f057600080fd5b80638e819e54116100d15780638e819e54146104eb578063952b27971461050b5780639bf62d821461053e578063a14238e71461056b57600080fd5b80637fc48504146104ab5780638b4c40b0146101f65780638c3152e9146104cb57600080fd5b80634870496f1161016f5780635c975abb1161013e5780635c975abb1461043657806371c1566e1461044b57806371cfaa3f1461046b5780637d6be8dc1461048b57600080fd5b80634870496f1461034d5780634fd0434c1461036d578063513747ab146103af57806354fd4d50146103ea57600080fd5b80633c9f397c116101ab5780633c9f397c146102a657806343ca1c50146102d8578063452a9320146102f857806345884d321461030d57600080fd5b8063149f2f22146101fd57806333d7e2bd1461021d57806335e80ab31461027457600080fd5b366101f8576101f63334620186a06000604051806020016040528060008152506107ab565b005b600080fd5b34801561020957600080fd5b506101f6610218366004614fe6565b610850565b34801561022957600080fd5b5060375461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561028057600080fd5b5060355461024a90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156102b257600080fd5b50603b546102c39063ffffffff1681565b60405163ffffffff909116815260200161026b565b3480156102e457600080fd5b506101f66102f336600461511c565b610a91565b34801561030457600080fd5b5061024a610f31565b34801561031957600080fd5b5061033d61032836600461516e565b603a6020526000908152604090205460ff1681565b604051901515815260200161026b565b34801561035957600080fd5b506101f661036836600461518b565b610fc9565b34801561037957600080fd5b50603b5461039690640100000000900467ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161026b565b3480156103bb57600080fd5b506103dc6103ca366004615267565b6000908152603c602052604090205490565b60405190815260200161026b565b3480156103f657600080fd5b50604080518082018252600d81527f332e31312e302d626574612e32000000000000000000000000000000000000006020820152905161026b91906152f6565b34801561044257600080fd5b5061033d611531565b34801561045757600080fd5b506101f6610466366004615309565b6115c4565b34801561047757600080fd5b506101f661048636600461533d565b611c7f565b34801561049757600080fd5b506101f66104a636600461516e565b611e3f565b3480156104b757600080fd5b506101f66104c6366004615395565b611f22565b3480156104d757600080fd5b506101f66104e63660046153b2565b61200e565b3480156104f757600080fd5b506101f66105063660046153ef565b61205a565b34801561051757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103dc565b34801561054a57600080fd5b5060325461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561057757600080fd5b5061033d610586366004615267565b60336020526000908152604090205460ff1681565b3480156105a757600080fd5b506103966105b636600461544b565b61230f565b3480156105c757600080fd5b5061024a6105d6366004615468565b61232e565b3480156105e757600080fd5b506103dc612373565b3480156105fc57600080fd5b5061066261060b366004615309565b603960209081526000928352604080842090915290825290205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900467ffffffffffffffff1682565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff90911660208301520161026b565b3480156106a357600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103dc565b3480156106d657600080fd5b50600154610732906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff928316602085015291169082015260600161026b565b6101f661077936600461548a565b6107ab565b34801561078a57600080fd5b5060385461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b8260005a905060006107bb6123e9565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906107f757503415155b1561082e576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61083c883489898989612486565b506108478282612632565b50505050505050565b8260005a905060006108606123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016108d2576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546108e49190615538565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610956573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097a9190615550565b905061099e73ffffffffffffffffffffffffffffffffffffffff831633308c6128ff565b6109a88982615538565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a369190615550565b14610a6d576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a7b8a8a8a8a8a8a612486565b5050610a878282612632565b5050505050505050565b610a99611531565b15610ad0576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead14610b23576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610b2e836129e1565b9050610b3a81836115c4565b6000818152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558401516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905580610bc56123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601610c2857610c218560400151866080015187606001518860a00151612a2e565b9150610e7b565b8073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610c91576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606085015115610e52578460600151603d6000828254610cb19190615569565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610d23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d479190615550565b9050610d7c866040015187606001518473ffffffffffffffffffffffffffffffffffffffff16612a8c9092919063ffffffff16565b6060860151610d8b9082615569565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e199190615550565b14610e50576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08501515115610e7657610c218560400151866080015160008860a00151612a2e565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405183907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90610edd90851515815260200190565b60405180910390a281158015610ef35750326001145b15610f2a576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fa0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615580565b905090565b610fd1611531565b15611008576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603611071576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6038546040517fbb8aa1fc00000000000000000000000000000000000000000000000000000000815260048101869052600091829173ffffffffffffffffffffffffffffffffffffffff9091169063bb8aa1fc90602401606060405180830381865afa1580156110e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611109919061559d565b925050915060008173ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561115b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117f9190615550565b603b5490915063ffffffff8481169116146111c6576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111dd6111d8368890038801886155ea565b612ae7565b8114611215576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611220896129e1565b905060018373ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611293919061567f565b60028111156112a4576112a4615650565b036112db576040517fd357347400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051602081018390526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506113a49101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f010000000000000000000000000000000000000000000000000000000000000060208301529061139a898b6156a0565b8b60400135612b26565b15156000036113df576040517fb05e92fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825273ffffffffffffffffffffffffffffffffffffffff808716825267ffffffffffffffff4281166020808501918252600088815260398252868120338252825286812095518654935190941674010000000000000000000000000000000000000000027fffffffff0000000000000000000000000000000000000000000000000000000090931693851693909317919091179093558d840151928e01519351928216939091169185917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f6291a4604051339083907f798f9f13695f8f045aa5f80ed8efebb695f3c7fe65da381969f2f28bf3c60b9790600090a3506000908152603c602090815260408220805460018101825590835291200180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115a0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615724565b600082815260396020908152604080832073ffffffffffffffffffffffffffffffffffffffff85811685529083528184208251808401845290549182168082527401000000000000000000000000000000000000000090920467ffffffffffffffff1681850152818552603a90935292205490919060ff1615611673576040517f09550c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816020015167ffffffffffffffff166000036116bb576040517f94efd49b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061173c8273ffffffffffffffffffffffffffffffffffffffff1663cf09e0d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172f9190615741565b67ffffffffffffffff1690565b90508067ffffffffffffffff16836020015167ffffffffffffffff1611611810576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e20646973707574652067616d65206372656160648201527f74696f6e2074696d657374616d70000000000000000000000000000000000000608482015260a4015b60405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000836020015167ffffffffffffffff164261184b9190615569565b116118d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c20686173206e6f74206d6174757265642079657400000000000000000000006064820152608401611807565b60028273ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611925573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611949919061567f565b600281111561195a5761195a615650565b14611991576040517fa080a3c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5463ffffffff1663ffffffff16611a1b8373ffffffffffffffffffffffffffffffffffffffff1663bbdc02db6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a12919061575e565b63ffffffff1690565b63ffffffff1614611a58576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5467ffffffffffffffff64010000000090910481169082161015611b26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a20646973707574652067616d652063726560448201527f61746564206265666f7265207265737065637465642067616d6520747970652060648201527f7761732075706461746564000000000000000000000000000000000000000000608482015260a401611807565b7f0000000000000000000000000000000000000000000000000000000000000000611b958373ffffffffffffffffffffffffffffffffffffffff166319effeb46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b611ba99067ffffffffffffffff1642615569565b11611c36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f696e206169722d676170000000000000000000000000000000000000000000006064820152608401611807565b60008581526033602052604090205460ff1615610f2a576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60375473ffffffffffffffffffffffffffffffffffffffff163314611cd0576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611cdc62030d40612b4a565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f000000000000000000000000000000000000000000000000000000001790529051611df99695949392910161577b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052611e31916152f6565b60405180910390a450505050565b611e47610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611eab576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152603a602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f192c289026d59a41a27f5aea08f3969b57931b0589202d14f4368cded95d3cda9190a250565b611f2a610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f8e576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b805463ffffffff83167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090911681176401000000004267ffffffffffffffff90811682029290921793849055604051930416917f049fe9dd413cdf037cce27011cc1790c753118272f3630e6e8bdfa5e8208176090600090a350565b565b612016611531565b1561204d576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120578133610a91565b50565b600054610100900460ff161580801561207a5750600054600160ff909116105b806120945750303b158015612094575060005460ff166001145b612120576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611807565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561217e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603880547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8881169190911790925560378054909116868316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff16610100868416021790556032541661229e576032805461dead7fffffffffffffffffffffffff0000000000000000000000000000000000000000909116179055603b80547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166401000000004267ffffffffffffffff16027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000161763ffffffff84161790555b6122a6612bac565b8015610f2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600061231c8260106157e0565b61232890615208615810565b92915050565b603c602052816000526040600020818154811061234a57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169150829050565b60008061237e6123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016123c5574791505090565b5050603d5490565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015612459573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247d919061583c565b90939092509050565b8180156124a8575073ffffffffffffffffffffffffffffffffffffffff861615155b156124df576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6124e9815161230f565b67ffffffffffffffff168367ffffffffffffffff161015612536576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c081511115612574576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33328114612595575033731111000000000000000000000000000000001111015b600086868686866040516020016125b095949392919061577b565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161262091906152f6565b60405180910390a45050505050505050565b600154600090612668907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643615569565b90506000612674612cbf565b90506000816020015160ff16826000015163ffffffff16612695919061589a565b905082156127cc576001546000906126cc908390700100000000000000000000000000000000900467ffffffffffffffff16615902565b90506000836040015160ff16836126e39190615976565b6001546127039084906fffffffffffffffffffffffffffffffff16615976565b61270d919061589a565b60015490915060009061275e906127379084906fffffffffffffffffffffffffffffffff16615a32565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612d80565b9050600186111561278d5761278a61273782876040015160ff1660018a6127859190615569565b612d9f565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b600180548691906010906127ff908490700100000000000000000000000000000000900467ffffffffffffffff16615810565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff16131561288c576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906128b8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615aa6565b905060006128ca48633b9aca00612df4565b6128d49083615ae3565b905060005a6128e39088615569565b905080821115610a8757610a876128fa8284615569565b612e0b565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526129db9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612e34565b50505050565b80516020808301516040808501516060860151608087015160a08801519351600097612a11979096959101615af7565b604051602081830303815290604052805190602001209050919050565b6000806000612a3e866000612f40565b905080612a74576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052612ae29084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612959565b505050565b60008160000151826020015183604001518460600151604051602001612a11949392919093845260208401929092526040830152606082015260800190565b600080612b3286612f5e565b9050612b4081868686612f90565b9695505050505050565b6001805463ffffffff83169190601090612b83908490700100000000000000000000000000000000900467ffffffffffffffff16615810565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b600054610100900460ff16612c43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611807565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff1660000361200c5760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa158015612d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615b4e565b6000612d95612d8f8585612fc0565b83612fd0565b90505b9392505050565b6000670de0b6b3a7640000612de0612db7858361589a565b612dc990670de0b6b3a7640000615902565b612ddb85670de0b6b3a7640000615976565b612fdf565b612dea9086615976565b612d95919061589a565b600081831015612e045781612d98565b5090919050565b6000805a90505b825a612e1e9083615569565b1015612ae257612e2d82615bf0565b9150612e12565b6000612e96826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130109092919063ffffffff16565b805190915015612ae25780806020019051810190612eb49190615724565b612ae2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611807565b600080603f83619c4001026040850201603f5a021015949350505050565b60608180519060200120604051602001612f7a91815260200190565b6040516020818303038152906040529050919050565b6000612fb784612fa187868661301f565b8051602091820120825192909101919091201490565b95945050505050565b600081831215612e045781612d98565b6000818312612e045781612d98565b6000612d98670de0b6b3a764000083612ff786613a9d565b6130019190615976565b61300b919061589a565b613ce1565b6060612d958484600085613f20565b6060600084511161308c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401611807565b6000613097846140b6565b905060006130a4866141a2565b90506000846040516020016130bb91815260200190565b60405160208183030381529060405290506000805b8451811015613a145760008582815181106130ed576130ed615c28565b602002602001015190508451831115613188576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401611807565b8260000361324157805180516020918201206040516131d6926131b092910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b61323c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401611807565b613398565b8051516020116132f7578051805160209182012060405161326b926131b092910190815260200190565b61323c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401611807565b805184516020808701919091208251919092012014613398576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401611807565b6133a460106001615538565b816020015151036135805784518303613518576133de81602001516010815181106133d1576133d1615c28565b6020026020010151614205565b96506000875111613471576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401611807565b6001865161347f9190615569565b821461350d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401611807565b505050505050612d98565b600085848151811061352c5761352c615c28565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061355757613557615c28565b6020026020010151905061356a816142b9565b9550613577600186615538565b94505050613a01565b600281602001515103613979576000613598826142de565b90506000816000815181106135af576135af615c28565b016020015160f81c905060006135c6600283615c57565b6135d1906002615c79565b905060006135e2848360ff16614302565b905060006135f08a89614302565b905060006135fe8383614338565b905080835114613690576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401611807565b60ff8516600214806136a5575060ff85166003145b15613894578082511461373a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401611807565b61375487602001516001815181106133d1576133d1615c28565b9c5060008d51116137e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401611807565b60018c516137f59190615569565b8814613883576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401611807565b505050505050505050505050612d98565b60ff851615806138a7575060ff85166001145b156138e6576138d387602001516001815181106138c6576138c6615c28565b60200260200101516142b9565b99506138df818a615538565b985061396e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401611807565b505050505050613a01565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401611807565b5080613a0c81615bf0565b9150506130d0565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401611807565b6000808213613b08576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b60006060613b15846143ec565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c18213613d1257506000919050565b680755bf798b4a1bf1e58212613d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401611807565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613fb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611807565b73ffffffffffffffffffffffffffffffffffffffff85163b614030576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611807565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516140599190615c9c565b60006040518083038185875af1925050503d8060008114614096576040519150601f19603f3d011682016040523d82523d6000602084013e61409b565b606091505b50915091506140ab8282866144c2565b979650505050505050565b80516060908067ffffffffffffffff8111156140d4576140d4614eb1565b60405190808252806020026020018201604052801561411957816020015b60408051808201909152606080825260208201528152602001906001900390816140f25790505b50915060005b8181101561419b57604051806040016040528085838151811061414457614144615c28565b6020026020010151815260200161417386848151811061416657614166615c28565b6020026020010151614515565b81525083828151811061418857614188615c28565b602090810291909101015260010161411f565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b838110156141fa578060011b82018184015160001a8060041c8253600f8116600183015350506001016141cc565b509295945050505050565b6060600080600061421585614528565b91945092509050600081600181111561423057614230615650565b14614267576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6142718284615538565b8551146142aa576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fb7856020015184846149c6565b606060208260000151106142d5576142d082614205565b612328565b61232882614a5a565b60606123286142fd83602001516000815181106133d1576133d1615c28565b6141a2565b6060825182106143215750604080516020810190915260008152612328565b612d9883838486516143339190615569565b614a70565b600080825184511061434b57825161434e565b83515b90505b80821080156143d5575082828151811061436d5761436d615c28565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168483815181106143ac576143ac615c28565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156143e557816001019150614351565b5092915050565b6000808211614457576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606083156144d1575081612d98565b8251156144e15782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180791906152f6565b606061232861452383614c48565b614cb5565b6000806000836000015160000361456b576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f81116145905760006001600094509450945050506149bf565b60b781116146a65760006145a5608083615569565b9050808760000151116145e4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214801561465c57507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614693576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600195509350600092506149bf915050565b60bf81116148045760006146bb60b783615569565b9050808760000151116146fa576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361475c576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116147a4576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147ae8184615538565b8951116147e7576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147f2836001615538565b97509550600094506149bf9350505050565b60f7811161486957600061481960c083615569565b905080876000015111614858576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001955093508492506149bf915050565b600061487660f783615569565b9050808760000151116148b5576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614917576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c6037811161495f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6149698184615538565b8951116149a2576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6149ad836001615538565b97509550600194506149bf9350505050565b9193909250565b60608167ffffffffffffffff8111156149e1576149e1614eb1565b6040519080825280601f01601f191660200182016040528015614a0b576020820181803683370190505b5090508115612d98576000614a208486615538565b90506020820160005b84811015614a41578281015182820152602001614a29565b84811115614a50576000858301525b5050509392505050565b60606123288260200151600084600001516149c6565b60608182601f011015614adf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b828284011015614b4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b81830184511015614bb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401611807565b606082158015614bd75760405191506000825260208201604052614c3f565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614c10578051835260209283019201614bf8565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201528151600003614c97576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000614cc585614528565b919450925090506001816001811115614ce057614ce0615650565b14614d17576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451614d238385615538565b14614d5a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081614d715790505093506000835b8651811015614e5f57600080614de46040518060400160405280858c60000151614dc89190615569565b8152602001858c60200151614ddd9190615538565b9052614528565b509150915060405180604001604052808383614e009190615538565b8152602001848b60200151614e159190615538565b815250888581518110614e2a57614e2a615c28565b6020908102919091010152614e40600185615538565b9350614e4c8183615538565b614e569084615538565b92505050614d9e565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461205757600080fd5b67ffffffffffffffff8116811461205757600080fd5b801515811461205757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715614f0357614f03614eb1565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614f5057614f50614eb1565b604052919050565b600082601f830112614f6957600080fd5b813567ffffffffffffffff811115614f8357614f83614eb1565b614fb460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614f09565b818152846020838601011115614fc957600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614fff57600080fd5b863561500a81614e6b565b95506020870135945060408701359350606087013561502881614e8d565b9250608087013561503881614ea3565b915060a087013567ffffffffffffffff81111561505457600080fd5b61506089828a01614f58565b9150509295509295509295565b600060c0828403121561507f57600080fd5b60405160c0810167ffffffffffffffff82821081831117156150a3576150a3614eb1565b8160405282935084358352602085013591506150be82614e6b565b816020840152604085013591506150d482614e6b565b816040840152606085013560608401526080850135608084015260a085013591508082111561510257600080fd5b5061510f85828601614f58565b60a0830152505092915050565b6000806040838503121561512f57600080fd5b823567ffffffffffffffff81111561514657600080fd5b6151528582860161506d565b925050602083013561516381614e6b565b809150509250929050565b60006020828403121561518057600080fd5b8135612d9881614e6b565b600080600080600085870360e08112156151a457600080fd5b863567ffffffffffffffff808211156151bc57600080fd5b6151c88a838b0161506d565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401121561520157600080fd5b60408901955060c089013592508083111561521b57600080fd5b828901925089601f84011261522f57600080fd5b823591508082111561524057600080fd5b508860208260051b840101111561525657600080fd5b959894975092955050506020019190565b60006020828403121561527957600080fd5b5035919050565b60005b8381101561529b578181015183820152602001615283565b838111156129db5750506000910152565b600081518084526152c4816020860160208601615280565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612d9860208301846152ac565b6000806040838503121561531c57600080fd5b82359150602083013561516381614e6b565b60ff8116811461205757600080fd5b6000806000806080858703121561535357600080fd5b843561535e81614e6b565b9350602085013561536e8161532e565b93969395505050506040820135916060013590565b63ffffffff8116811461205757600080fd5b6000602082840312156153a757600080fd5b8135612d9881615383565b6000602082840312156153c457600080fd5b813567ffffffffffffffff8111156153db57600080fd5b6153e78482850161506d565b949350505050565b6000806000806080858703121561540557600080fd5b843561541081614e6b565b9350602085013561542081614e6b565b9250604085013561543081614e6b565b9150606085013561544081615383565b939692955090935050565b60006020828403121561545d57600080fd5b8135612d9881614e8d565b6000806040838503121561547b57600080fd5b50508035926020909101359150565b600080600080600060a086880312156154a257600080fd5b85356154ad81614e6b565b94506020860135935060408601356154c481614e8d565b925060608601356154d481614ea3565b9150608086013567ffffffffffffffff8111156154f057600080fd5b6154fc88828901614f58565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561554b5761554b615509565b500190565b60006020828403121561556257600080fd5b5051919050565b60008282101561557b5761557b615509565b500390565b60006020828403121561559257600080fd5b8151612d9881614e6b565b6000806000606084860312156155b257600080fd5b83516155bd81615383565b60208501519093506155ce81614e8d565b60408501519092506155df81614e6b565b809150509250925092565b6000608082840312156155fc57600080fd5b6040516080810181811067ffffffffffffffff8211171561561f5761561f614eb1565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006020828403121561569157600080fd5b815160038110612d9857600080fd5b600067ffffffffffffffff808411156156bb576156bb614eb1565b8360051b60206156cc818301614f09565b8681529185019181810190368411156156e457600080fd5b865b84811015615718578035868111156156fe5760008081fd5b61570a36828b01614f58565b8452509183019183016156e6565b50979650505050505050565b60006020828403121561573657600080fd5b8151612d9881614ea3565b60006020828403121561575357600080fd5b8151612d9881614e8d565b60006020828403121561577057600080fd5b8151612d9881615383565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b6048820152600082516157cf816049850160208701615280565b919091016049019695505050505050565b600067ffffffffffffffff8083168185168183048111821515161561580757615807615509565b02949350505050565b600067ffffffffffffffff80831681851680830382111561583357615833615509565b01949350505050565b6000806040838503121561584f57600080fd5b825161585a81614e6b565b60208401519092506151638161532e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826158a9576158a961586b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156158fd576158fd615509565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561593c5761593c615509565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561597057615970615509565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156159b7576159b7615509565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156159f2576159f2615509565b60008712925087820587128484161615615a0e57615a0e615509565b87850587128184161615615a2457615a24615509565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03841381151615615a6c57615a6c615509565b827f8000000000000000000000000000000000000000000000000000000000000000038412811615615aa057615aa0615509565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615ade57615ade615509565b500290565b600082615af257615af261586b565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152615b4260c08301846152ac565b98975050505050505050565b600060c08284031215615b6057600080fd5b615b68614ee0565b8251615b7381615383565b81526020830151615b838161532e565b60208201526040830151615b968161532e565b60408201526060830151615ba981615383565b60608201526080830151615bbc81615383565b608082015260a08301516fffffffffffffffffffffffffffffffff81168114615be457600080fd5b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615c2157615c21615509565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff831680615c6a57615c6a61586b565b8060ff84160691505092915050565b600060ff821660ff841680821015615c9357615c93615509565b90039392505050565b60008251615cae818460208701615280565b919091019291505056fea164736f6c634300080f000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000006", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x60c06040523480156200001157600080fd5b5060405162006010380380620060108339810160408190526200003491620002f2565b608082905260a08190526200004d600080808062000055565b505062000317565b600054610100900460ff1615808015620000765750600054600160ff909116105b80620000a6575062000093306200022460201b620023cd1760201c565b158015620000a6575060005460ff166001145b6200010f5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000133576000805461ff0019166101001790555b603880546001600160a01b03199081166001600160a01b03888116919091179092556037805490911686831617905560358054610100600160a81b0319166101008684160217905560325416620001cc576032805461dead6001600160a01b0319909116179055603b80546001600160601b031916640100000000426001600160401b03160263ffffffff19161763ffffffff84161790555b620001d662000233565b80156200021d576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b6001600160a01b03163b151590565b600054610100900460ff16620002a05760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840162000106565b600154600160c01b90046001600160401b0316600003620002f05760408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b02176001555b565b600080604083850312156200030657600080fd5b505080516020909101519092909150565b60805160a051615cc56200034b6000396000818161051a0152611b280152600081816106a601526118120152615cc56000f3fe6080604052600436106101d15760003560e01c80637fc48504116100f7578063a35d99df11610095578063bf653a5c11610064578063bf653a5c14610697578063cff0ab96146106ca578063e9e05c421461076b578063f2b4e6171461077e57600080fd5b8063a35d99df1461059b578063a3860f48146105bb578063b69ef8a8146105db578063bb2c727e146105f057600080fd5b80638e819e54116100d15780638e819e54146104eb578063952b27971461050b5780639bf62d821461053e578063a14238e71461056b57600080fd5b80637fc48504146104ab5780638b4c40b0146101f65780638c3152e9146104cb57600080fd5b80634870496f1161016f5780635c975abb1161013e5780635c975abb1461043657806371c1566e1461044b57806371cfaa3f1461046b5780637d6be8dc1461048b57600080fd5b80634870496f1461034d5780634fd0434c1461036d578063513747ab146103af57806354fd4d50146103ea57600080fd5b80633c9f397c116101ab5780633c9f397c146102a657806343ca1c50146102d8578063452a9320146102f857806345884d321461030d57600080fd5b8063149f2f22146101fd57806333d7e2bd1461021d57806335e80ab31461027457600080fd5b366101f8576101f63334620186a06000604051806020016040528060008152506107ab565b005b600080fd5b34801561020957600080fd5b506101f6610218366004614fe6565b610850565b34801561022957600080fd5b5060375461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561028057600080fd5b5060355461024a90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156102b257600080fd5b50603b546102c39063ffffffff1681565b60405163ffffffff909116815260200161026b565b3480156102e457600080fd5b506101f66102f336600461511c565b610a91565b34801561030457600080fd5b5061024a610f31565b34801561031957600080fd5b5061033d61032836600461516e565b603a6020526000908152604090205460ff1681565b604051901515815260200161026b565b34801561035957600080fd5b506101f661036836600461518b565b610fc9565b34801561037957600080fd5b50603b5461039690640100000000900467ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161026b565b3480156103bb57600080fd5b506103dc6103ca366004615267565b6000908152603c602052604090205490565b60405190815260200161026b565b3480156103f657600080fd5b50604080518082018252600d81527f332e31312e302d626574612e32000000000000000000000000000000000000006020820152905161026b91906152f6565b34801561044257600080fd5b5061033d611531565b34801561045757600080fd5b506101f6610466366004615309565b6115c4565b34801561047757600080fd5b506101f661048636600461533d565b611c7f565b34801561049757600080fd5b506101f66104a636600461516e565b611e3f565b3480156104b757600080fd5b506101f66104c6366004615395565b611f22565b3480156104d757600080fd5b506101f66104e63660046153b2565b61200e565b3480156104f757600080fd5b506101f66105063660046153ef565b61205a565b34801561051757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103dc565b34801561054a57600080fd5b5060325461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561057757600080fd5b5061033d610586366004615267565b60336020526000908152604090205460ff1681565b3480156105a757600080fd5b506103966105b636600461544b565b61230f565b3480156105c757600080fd5b5061024a6105d6366004615468565b61232e565b3480156105e757600080fd5b506103dc612373565b3480156105fc57600080fd5b5061066261060b366004615309565b603960209081526000928352604080842090915290825290205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900467ffffffffffffffff1682565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff90911660208301520161026b565b3480156106a357600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103dc565b3480156106d657600080fd5b50600154610732906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff928316602085015291169082015260600161026b565b6101f661077936600461548a565b6107ab565b34801561078a57600080fd5b5060385461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b8260005a905060006107bb6123e9565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906107f757503415155b1561082e576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61083c883489898989612486565b506108478282612632565b50505050505050565b8260005a905060006108606123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016108d2576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546108e49190615538565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610956573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097a9190615550565b905061099e73ffffffffffffffffffffffffffffffffffffffff831633308c6128ff565b6109a88982615538565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a369190615550565b14610a6d576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a7b8a8a8a8a8a8a612486565b5050610a878282612632565b5050505050505050565b610a99611531565b15610ad0576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead14610b23576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610b2e836129e1565b9050610b3a81836115c4565b6000818152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558401516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905580610bc56123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601610c2857610c218560400151866080015187606001518860a00151612a2e565b9150610e7b565b8073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610c91576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606085015115610e52578460600151603d6000828254610cb19190615569565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610d23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d479190615550565b9050610d7c866040015187606001518473ffffffffffffffffffffffffffffffffffffffff16612a8c9092919063ffffffff16565b6060860151610d8b9082615569565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e199190615550565b14610e50576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08501515115610e7657610c218560400151866080015160008860a00151612a2e565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405183907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90610edd90851515815260200190565b60405180910390a281158015610ef35750326001145b15610f2a576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fa0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615580565b905090565b610fd1611531565b15611008576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603611071576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6038546040517fbb8aa1fc00000000000000000000000000000000000000000000000000000000815260048101869052600091829173ffffffffffffffffffffffffffffffffffffffff9091169063bb8aa1fc90602401606060405180830381865afa1580156110e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611109919061559d565b925050915060008173ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561115b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117f9190615550565b603b5490915063ffffffff8481169116146111c6576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111dd6111d8368890038801886155ea565b612ae7565b8114611215576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611220896129e1565b905060018373ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611293919061567f565b60028111156112a4576112a4615650565b036112db576040517fd357347400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051602081018390526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506113a49101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f010000000000000000000000000000000000000000000000000000000000000060208301529061139a898b6156a0565b8b60400135612b26565b15156000036113df576040517fb05e92fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825273ffffffffffffffffffffffffffffffffffffffff808716825267ffffffffffffffff4281166020808501918252600088815260398252868120338252825286812095518654935190941674010000000000000000000000000000000000000000027fffffffff0000000000000000000000000000000000000000000000000000000090931693851693909317919091179093558d840151928e01519351928216939091169185917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f6291a4604051339083907f798f9f13695f8f045aa5f80ed8efebb695f3c7fe65da381969f2f28bf3c60b9790600090a3506000908152603c602090815260408220805460018101825590835291200180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115a0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615724565b600082815260396020908152604080832073ffffffffffffffffffffffffffffffffffffffff85811685529083528184208251808401845290549182168082527401000000000000000000000000000000000000000090920467ffffffffffffffff1681850152818552603a90935292205490919060ff1615611673576040517f09550c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816020015167ffffffffffffffff166000036116bb576040517f94efd49b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061173c8273ffffffffffffffffffffffffffffffffffffffff1663cf09e0d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172f9190615741565b67ffffffffffffffff1690565b90508067ffffffffffffffff16836020015167ffffffffffffffff1611611810576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e20646973707574652067616d65206372656160648201527f74696f6e2074696d657374616d70000000000000000000000000000000000000608482015260a4015b60405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000836020015167ffffffffffffffff164261184b9190615569565b116118d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c20686173206e6f74206d6174757265642079657400000000000000000000006064820152608401611807565b60028273ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611925573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611949919061567f565b600281111561195a5761195a615650565b14611991576040517fa080a3c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5463ffffffff1663ffffffff16611a1b8373ffffffffffffffffffffffffffffffffffffffff1663bbdc02db6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a12919061575e565b63ffffffff1690565b63ffffffff1614611a58576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5467ffffffffffffffff64010000000090910481169082161015611b26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a20646973707574652067616d652063726560448201527f61746564206265666f7265207265737065637465642067616d6520747970652060648201527f7761732075706461746564000000000000000000000000000000000000000000608482015260a401611807565b7f0000000000000000000000000000000000000000000000000000000000000000611b958373ffffffffffffffffffffffffffffffffffffffff166319effeb46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b611ba99067ffffffffffffffff1642615569565b11611c36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f696e206169722d676170000000000000000000000000000000000000000000006064820152608401611807565b60008581526033602052604090205460ff1615610f2a576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60375473ffffffffffffffffffffffffffffffffffffffff163314611cd0576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611cdc62030d40612b4a565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f000000000000000000000000000000000000000000000000000000001790529051611df99695949392910161577b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052611e31916152f6565b60405180910390a450505050565b611e47610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611eab576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152603a602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f192c289026d59a41a27f5aea08f3969b57931b0589202d14f4368cded95d3cda9190a250565b611f2a610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f8e576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b805463ffffffff83167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090911681176401000000004267ffffffffffffffff90811682029290921793849055604051930416917f049fe9dd413cdf037cce27011cc1790c753118272f3630e6e8bdfa5e8208176090600090a350565b565b612016611531565b1561204d576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120578133610a91565b50565b600054610100900460ff161580801561207a5750600054600160ff909116105b806120945750303b158015612094575060005460ff166001145b612120576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611807565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561217e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603880547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8881169190911790925560378054909116868316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff16610100868416021790556032541661229e576032805461dead7fffffffffffffffffffffffff0000000000000000000000000000000000000000909116179055603b80547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166401000000004267ffffffffffffffff16027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000161763ffffffff84161790555b6122a6612bac565b8015610f2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600061231c8260106157e0565b61232890615208615810565b92915050565b603c602052816000526040600020818154811061234a57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169150829050565b60008061237e6123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016123c5574791505090565b5050603d5490565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015612459573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247d919061583c565b90939092509050565b8180156124a8575073ffffffffffffffffffffffffffffffffffffffff861615155b156124df576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6124e9815161230f565b67ffffffffffffffff168367ffffffffffffffff161015612536576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c081511115612574576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33328114612595575033731111000000000000000000000000000000001111015b600086868686866040516020016125b095949392919061577b565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161262091906152f6565b60405180910390a45050505050505050565b600154600090612668907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643615569565b90506000612674612cbf565b90506000816020015160ff16826000015163ffffffff16612695919061589a565b905082156127cc576001546000906126cc908390700100000000000000000000000000000000900467ffffffffffffffff16615902565b90506000836040015160ff16836126e39190615976565b6001546127039084906fffffffffffffffffffffffffffffffff16615976565b61270d919061589a565b60015490915060009061275e906127379084906fffffffffffffffffffffffffffffffff16615a32565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612d80565b9050600186111561278d5761278a61273782876040015160ff1660018a6127859190615569565b612d9f565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b600180548691906010906127ff908490700100000000000000000000000000000000900467ffffffffffffffff16615810565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff16131561288c576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906128b8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615aa6565b905060006128ca48633b9aca00612df4565b6128d49083615ae3565b905060005a6128e39088615569565b905080821115610a8757610a876128fa8284615569565b612e0b565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526129db9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612e34565b50505050565b80516020808301516040808501516060860151608087015160a08801519351600097612a11979096959101615af7565b604051602081830303815290604052805190602001209050919050565b6000806000612a3e866000612f40565b905080612a74576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052612ae29084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612959565b505050565b60008160000151826020015183604001518460600151604051602001612a11949392919093845260208401929092526040830152606082015260800190565b600080612b3286612f5e565b9050612b4081868686612f90565b9695505050505050565b6001805463ffffffff83169190601090612b83908490700100000000000000000000000000000000900467ffffffffffffffff16615810565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b600054610100900460ff16612c43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611807565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff1660000361200c5760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa158015612d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615b4e565b6000612d95612d8f8585612fc0565b83612fd0565b90505b9392505050565b6000670de0b6b3a7640000612de0612db7858361589a565b612dc990670de0b6b3a7640000615902565b612ddb85670de0b6b3a7640000615976565b612fdf565b612dea9086615976565b612d95919061589a565b600081831015612e045781612d98565b5090919050565b6000805a90505b825a612e1e9083615569565b1015612ae257612e2d82615bf0565b9150612e12565b6000612e96826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130109092919063ffffffff16565b805190915015612ae25780806020019051810190612eb49190615724565b612ae2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611807565b600080603f83619c4001026040850201603f5a021015949350505050565b60608180519060200120604051602001612f7a91815260200190565b6040516020818303038152906040529050919050565b6000612fb784612fa187868661301f565b8051602091820120825192909101919091201490565b95945050505050565b600081831215612e045781612d98565b6000818312612e045781612d98565b6000612d98670de0b6b3a764000083612ff786613a9d565b6130019190615976565b61300b919061589a565b613ce1565b6060612d958484600085613f20565b6060600084511161308c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401611807565b6000613097846140b6565b905060006130a4866141a2565b90506000846040516020016130bb91815260200190565b60405160208183030381529060405290506000805b8451811015613a145760008582815181106130ed576130ed615c28565b602002602001015190508451831115613188576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401611807565b8260000361324157805180516020918201206040516131d6926131b092910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b61323c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401611807565b613398565b8051516020116132f7578051805160209182012060405161326b926131b092910190815260200190565b61323c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401611807565b805184516020808701919091208251919092012014613398576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401611807565b6133a460106001615538565b816020015151036135805784518303613518576133de81602001516010815181106133d1576133d1615c28565b6020026020010151614205565b96506000875111613471576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401611807565b6001865161347f9190615569565b821461350d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401611807565b505050505050612d98565b600085848151811061352c5761352c615c28565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061355757613557615c28565b6020026020010151905061356a816142b9565b9550613577600186615538565b94505050613a01565b600281602001515103613979576000613598826142de565b90506000816000815181106135af576135af615c28565b016020015160f81c905060006135c6600283615c57565b6135d1906002615c79565b905060006135e2848360ff16614302565b905060006135f08a89614302565b905060006135fe8383614338565b905080835114613690576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401611807565b60ff8516600214806136a5575060ff85166003145b15613894578082511461373a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401611807565b61375487602001516001815181106133d1576133d1615c28565b9c5060008d51116137e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401611807565b60018c516137f59190615569565b8814613883576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401611807565b505050505050505050505050612d98565b60ff851615806138a7575060ff85166001145b156138e6576138d387602001516001815181106138c6576138c6615c28565b60200260200101516142b9565b99506138df818a615538565b985061396e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401611807565b505050505050613a01565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401611807565b5080613a0c81615bf0565b9150506130d0565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401611807565b6000808213613b08576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b60006060613b15846143ec565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c18213613d1257506000919050565b680755bf798b4a1bf1e58212613d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401611807565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613fb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611807565b73ffffffffffffffffffffffffffffffffffffffff85163b614030576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611807565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516140599190615c9c565b60006040518083038185875af1925050503d8060008114614096576040519150601f19603f3d011682016040523d82523d6000602084013e61409b565b606091505b50915091506140ab8282866144c2565b979650505050505050565b80516060908067ffffffffffffffff8111156140d4576140d4614eb1565b60405190808252806020026020018201604052801561411957816020015b60408051808201909152606080825260208201528152602001906001900390816140f25790505b50915060005b8181101561419b57604051806040016040528085838151811061414457614144615c28565b6020026020010151815260200161417386848151811061416657614166615c28565b6020026020010151614515565b81525083828151811061418857614188615c28565b602090810291909101015260010161411f565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b838110156141fa578060011b82018184015160001a8060041c8253600f8116600183015350506001016141cc565b509295945050505050565b6060600080600061421585614528565b91945092509050600081600181111561423057614230615650565b14614267576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6142718284615538565b8551146142aa576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fb7856020015184846149c6565b606060208260000151106142d5576142d082614205565b612328565b61232882614a5a565b60606123286142fd83602001516000815181106133d1576133d1615c28565b6141a2565b6060825182106143215750604080516020810190915260008152612328565b612d9883838486516143339190615569565b614a70565b600080825184511061434b57825161434e565b83515b90505b80821080156143d5575082828151811061436d5761436d615c28565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168483815181106143ac576143ac615c28565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156143e557816001019150614351565b5092915050565b6000808211614457576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606083156144d1575081612d98565b8251156144e15782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180791906152f6565b606061232861452383614c48565b614cb5565b6000806000836000015160000361456b576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f81116145905760006001600094509450945050506149bf565b60b781116146a65760006145a5608083615569565b9050808760000151116145e4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214801561465c57507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614693576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600195509350600092506149bf915050565b60bf81116148045760006146bb60b783615569565b9050808760000151116146fa576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361475c576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116147a4576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147ae8184615538565b8951116147e7576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147f2836001615538565b97509550600094506149bf9350505050565b60f7811161486957600061481960c083615569565b905080876000015111614858576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001955093508492506149bf915050565b600061487660f783615569565b9050808760000151116148b5576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614917576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c6037811161495f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6149698184615538565b8951116149a2576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6149ad836001615538565b97509550600194506149bf9350505050565b9193909250565b60608167ffffffffffffffff8111156149e1576149e1614eb1565b6040519080825280601f01601f191660200182016040528015614a0b576020820181803683370190505b5090508115612d98576000614a208486615538565b90506020820160005b84811015614a41578281015182820152602001614a29565b84811115614a50576000858301525b5050509392505050565b60606123288260200151600084600001516149c6565b60608182601f011015614adf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b828284011015614b4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b81830184511015614bb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401611807565b606082158015614bd75760405191506000825260208201604052614c3f565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614c10578051835260209283019201614bf8565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201528151600003614c97576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000614cc585614528565b919450925090506001816001811115614ce057614ce0615650565b14614d17576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451614d238385615538565b14614d5a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081614d715790505093506000835b8651811015614e5f57600080614de46040518060400160405280858c60000151614dc89190615569565b8152602001858c60200151614ddd9190615538565b9052614528565b509150915060405180604001604052808383614e009190615538565b8152602001848b60200151614e159190615538565b815250888581518110614e2a57614e2a615c28565b6020908102919091010152614e40600185615538565b9350614e4c8183615538565b614e569084615538565b92505050614d9e565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461205757600080fd5b67ffffffffffffffff8116811461205757600080fd5b801515811461205757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715614f0357614f03614eb1565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614f5057614f50614eb1565b604052919050565b600082601f830112614f6957600080fd5b813567ffffffffffffffff811115614f8357614f83614eb1565b614fb460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614f09565b818152846020838601011115614fc957600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614fff57600080fd5b863561500a81614e6b565b95506020870135945060408701359350606087013561502881614e8d565b9250608087013561503881614ea3565b915060a087013567ffffffffffffffff81111561505457600080fd5b61506089828a01614f58565b9150509295509295509295565b600060c0828403121561507f57600080fd5b60405160c0810167ffffffffffffffff82821081831117156150a3576150a3614eb1565b8160405282935084358352602085013591506150be82614e6b565b816020840152604085013591506150d482614e6b565b816040840152606085013560608401526080850135608084015260a085013591508082111561510257600080fd5b5061510f85828601614f58565b60a0830152505092915050565b6000806040838503121561512f57600080fd5b823567ffffffffffffffff81111561514657600080fd5b6151528582860161506d565b925050602083013561516381614e6b565b809150509250929050565b60006020828403121561518057600080fd5b8135612d9881614e6b565b600080600080600085870360e08112156151a457600080fd5b863567ffffffffffffffff808211156151bc57600080fd5b6151c88a838b0161506d565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401121561520157600080fd5b60408901955060c089013592508083111561521b57600080fd5b828901925089601f84011261522f57600080fd5b823591508082111561524057600080fd5b508860208260051b840101111561525657600080fd5b959894975092955050506020019190565b60006020828403121561527957600080fd5b5035919050565b60005b8381101561529b578181015183820152602001615283565b838111156129db5750506000910152565b600081518084526152c4816020860160208601615280565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612d9860208301846152ac565b6000806040838503121561531c57600080fd5b82359150602083013561516381614e6b565b60ff8116811461205757600080fd5b6000806000806080858703121561535357600080fd5b843561535e81614e6b565b9350602085013561536e8161532e565b93969395505050506040820135916060013590565b63ffffffff8116811461205757600080fd5b6000602082840312156153a757600080fd5b8135612d9881615383565b6000602082840312156153c457600080fd5b813567ffffffffffffffff8111156153db57600080fd5b6153e78482850161506d565b949350505050565b6000806000806080858703121561540557600080fd5b843561541081614e6b565b9350602085013561542081614e6b565b9250604085013561543081614e6b565b9150606085013561544081615383565b939692955090935050565b60006020828403121561545d57600080fd5b8135612d9881614e8d565b6000806040838503121561547b57600080fd5b50508035926020909101359150565b600080600080600060a086880312156154a257600080fd5b85356154ad81614e6b565b94506020860135935060408601356154c481614e8d565b925060608601356154d481614ea3565b9150608086013567ffffffffffffffff8111156154f057600080fd5b6154fc88828901614f58565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561554b5761554b615509565b500190565b60006020828403121561556257600080fd5b5051919050565b60008282101561557b5761557b615509565b500390565b60006020828403121561559257600080fd5b8151612d9881614e6b565b6000806000606084860312156155b257600080fd5b83516155bd81615383565b60208501519093506155ce81614e8d565b60408501519092506155df81614e6b565b809150509250925092565b6000608082840312156155fc57600080fd5b6040516080810181811067ffffffffffffffff8211171561561f5761561f614eb1565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006020828403121561569157600080fd5b815160038110612d9857600080fd5b600067ffffffffffffffff808411156156bb576156bb614eb1565b8360051b60206156cc818301614f09565b8681529185019181810190368411156156e457600080fd5b865b84811015615718578035868111156156fe5760008081fd5b61570a36828b01614f58565b8452509183019183016156e6565b50979650505050505050565b60006020828403121561573657600080fd5b8151612d9881614ea3565b60006020828403121561575357600080fd5b8151612d9881614e8d565b60006020828403121561577057600080fd5b8151612d9881615383565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b6048820152600082516157cf816049850160208701615280565b919091016049019695505050505050565b600067ffffffffffffffff8083168185168183048111821515161561580757615807615509565b02949350505050565b600067ffffffffffffffff80831681851680830382111561583357615833615509565b01949350505050565b6000806040838503121561584f57600080fd5b825161585a81614e6b565b60208401519092506151638161532e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826158a9576158a961586b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156158fd576158fd615509565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561593c5761593c615509565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561597057615970615509565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156159b7576159b7615509565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156159f2576159f2615509565b60008712925087820587128484161615615a0e57615a0e615509565b87850587128184161615615a2457615a24615509565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03841381151615615a6c57615a6c615509565b827f8000000000000000000000000000000000000000000000000000000000000000038412811615615aa057615aa0615509565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615ade57615ade615509565b500290565b600082615af257615af261586b565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152615b4260c08301846152ac565b98975050505050505050565b600060c08284031215615b6057600080fd5b615b68614ee0565b8251615b7381615383565b81526020830151615b838161532e565b60208201526040830151615b968161532e565b60408201526060830151615ba981615383565b60608201526080830151615bbc81615383565b608082015260a08301516fffffffffffffffffffffffffffffffff81168114615be457600080fd5b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615c2157615c21615509565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff831680615c6a57615c6a61586b565b8060ff84160691505092915050565b600060ff821660ff841680821015615c9357615c93615509565b90039392505050565b60008251615cae818460208701615280565b919091019291505056fea164736f6c634300080f000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000006", - "deployedCode": "0x6080604052600436106101d15760003560e01c80637fc48504116100f7578063a35d99df11610095578063bf653a5c11610064578063bf653a5c14610697578063cff0ab96146106ca578063e9e05c421461076b578063f2b4e6171461077e57600080fd5b8063a35d99df1461059b578063a3860f48146105bb578063b69ef8a8146105db578063bb2c727e146105f057600080fd5b80638e819e54116100d15780638e819e54146104eb578063952b27971461050b5780639bf62d821461053e578063a14238e71461056b57600080fd5b80637fc48504146104ab5780638b4c40b0146101f65780638c3152e9146104cb57600080fd5b80634870496f1161016f5780635c975abb1161013e5780635c975abb1461043657806371c1566e1461044b57806371cfaa3f1461046b5780637d6be8dc1461048b57600080fd5b80634870496f1461034d5780634fd0434c1461036d578063513747ab146103af57806354fd4d50146103ea57600080fd5b80633c9f397c116101ab5780633c9f397c146102a657806343ca1c50146102d8578063452a9320146102f857806345884d321461030d57600080fd5b8063149f2f22146101fd57806333d7e2bd1461021d57806335e80ab31461027457600080fd5b366101f8576101f63334620186a06000604051806020016040528060008152506107ab565b005b600080fd5b34801561020957600080fd5b506101f6610218366004614fe6565b610850565b34801561022957600080fd5b5060375461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561028057600080fd5b5060355461024a90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156102b257600080fd5b50603b546102c39063ffffffff1681565b60405163ffffffff909116815260200161026b565b3480156102e457600080fd5b506101f66102f336600461511c565b610a91565b34801561030457600080fd5b5061024a610f31565b34801561031957600080fd5b5061033d61032836600461516e565b603a6020526000908152604090205460ff1681565b604051901515815260200161026b565b34801561035957600080fd5b506101f661036836600461518b565b610fc9565b34801561037957600080fd5b50603b5461039690640100000000900467ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161026b565b3480156103bb57600080fd5b506103dc6103ca366004615267565b6000908152603c602052604090205490565b60405190815260200161026b565b3480156103f657600080fd5b50604080518082018252600d81527f332e31312e302d626574612e32000000000000000000000000000000000000006020820152905161026b91906152f6565b34801561044257600080fd5b5061033d611531565b34801561045757600080fd5b506101f6610466366004615309565b6115c4565b34801561047757600080fd5b506101f661048636600461533d565b611c7f565b34801561049757600080fd5b506101f66104a636600461516e565b611e3f565b3480156104b757600080fd5b506101f66104c6366004615395565b611f22565b3480156104d757600080fd5b506101f66104e63660046153b2565b61200e565b3480156104f757600080fd5b506101f66105063660046153ef565b61205a565b34801561051757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000066103dc565b34801561054a57600080fd5b5060325461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561057757600080fd5b5061033d610586366004615267565b60336020526000908152604090205460ff1681565b3480156105a757600080fd5b506103966105b636600461544b565b61230f565b3480156105c757600080fd5b5061024a6105d6366004615468565b61232e565b3480156105e757600080fd5b506103dc612373565b3480156105fc57600080fd5b5061066261060b366004615309565b603960209081526000928352604080842090915290825290205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900467ffffffffffffffff1682565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff90911660208301520161026b565b3480156106a357600080fd5b507f000000000000000000000000000000000000000000000000000000000000000c6103dc565b3480156106d657600080fd5b50600154610732906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff928316602085015291169082015260600161026b565b6101f661077936600461548a565b6107ab565b34801561078a57600080fd5b5060385461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b8260005a905060006107bb6123e9565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906107f757503415155b1561082e576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61083c883489898989612486565b506108478282612632565b50505050505050565b8260005a905060006108606123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016108d2576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546108e49190615538565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610956573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097a9190615550565b905061099e73ffffffffffffffffffffffffffffffffffffffff831633308c6128ff565b6109a88982615538565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a369190615550565b14610a6d576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a7b8a8a8a8a8a8a612486565b5050610a878282612632565b5050505050505050565b610a99611531565b15610ad0576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead14610b23576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610b2e836129e1565b9050610b3a81836115c4565b6000818152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558401516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905580610bc56123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601610c2857610c218560400151866080015187606001518860a00151612a2e565b9150610e7b565b8073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610c91576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606085015115610e52578460600151603d6000828254610cb19190615569565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610d23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d479190615550565b9050610d7c866040015187606001518473ffffffffffffffffffffffffffffffffffffffff16612a8c9092919063ffffffff16565b6060860151610d8b9082615569565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e199190615550565b14610e50576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08501515115610e7657610c218560400151866080015160008860a00151612a2e565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405183907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90610edd90851515815260200190565b60405180910390a281158015610ef35750326001145b15610f2a576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fa0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615580565b905090565b610fd1611531565b15611008576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603611071576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6038546040517fbb8aa1fc00000000000000000000000000000000000000000000000000000000815260048101869052600091829173ffffffffffffffffffffffffffffffffffffffff9091169063bb8aa1fc90602401606060405180830381865afa1580156110e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611109919061559d565b925050915060008173ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561115b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117f9190615550565b603b5490915063ffffffff8481169116146111c6576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111dd6111d8368890038801886155ea565b612ae7565b8114611215576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611220896129e1565b905060018373ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611293919061567f565b60028111156112a4576112a4615650565b036112db576040517fd357347400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051602081018390526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506113a49101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f010000000000000000000000000000000000000000000000000000000000000060208301529061139a898b6156a0565b8b60400135612b26565b15156000036113df576040517fb05e92fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825273ffffffffffffffffffffffffffffffffffffffff808716825267ffffffffffffffff4281166020808501918252600088815260398252868120338252825286812095518654935190941674010000000000000000000000000000000000000000027fffffffff0000000000000000000000000000000000000000000000000000000090931693851693909317919091179093558d840151928e01519351928216939091169185917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f6291a4604051339083907f798f9f13695f8f045aa5f80ed8efebb695f3c7fe65da381969f2f28bf3c60b9790600090a3506000908152603c602090815260408220805460018101825590835291200180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115a0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615724565b600082815260396020908152604080832073ffffffffffffffffffffffffffffffffffffffff85811685529083528184208251808401845290549182168082527401000000000000000000000000000000000000000090920467ffffffffffffffff1681850152818552603a90935292205490919060ff1615611673576040517f09550c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816020015167ffffffffffffffff166000036116bb576040517f94efd49b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061173c8273ffffffffffffffffffffffffffffffffffffffff1663cf09e0d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172f9190615741565b67ffffffffffffffff1690565b90508067ffffffffffffffff16836020015167ffffffffffffffff1611611810576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e20646973707574652067616d65206372656160648201527f74696f6e2074696d657374616d70000000000000000000000000000000000000608482015260a4015b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000c836020015167ffffffffffffffff164261184b9190615569565b116118d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c20686173206e6f74206d6174757265642079657400000000000000000000006064820152608401611807565b60028273ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611925573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611949919061567f565b600281111561195a5761195a615650565b14611991576040517fa080a3c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5463ffffffff1663ffffffff16611a1b8373ffffffffffffffffffffffffffffffffffffffff1663bbdc02db6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a12919061575e565b63ffffffff1690565b63ffffffff1614611a58576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5467ffffffffffffffff64010000000090910481169082161015611b26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a20646973707574652067616d652063726560448201527f61746564206265666f7265207265737065637465642067616d6520747970652060648201527f7761732075706461746564000000000000000000000000000000000000000000608482015260a401611807565b7f0000000000000000000000000000000000000000000000000000000000000006611b958373ffffffffffffffffffffffffffffffffffffffff166319effeb46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b611ba99067ffffffffffffffff1642615569565b11611c36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f696e206169722d676170000000000000000000000000000000000000000000006064820152608401611807565b60008581526033602052604090205460ff1615610f2a576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60375473ffffffffffffffffffffffffffffffffffffffff163314611cd0576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611cdc62030d40612b4a565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f000000000000000000000000000000000000000000000000000000001790529051611df99695949392910161577b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052611e31916152f6565b60405180910390a450505050565b611e47610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611eab576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152603a602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f192c289026d59a41a27f5aea08f3969b57931b0589202d14f4368cded95d3cda9190a250565b611f2a610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f8e576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b805463ffffffff83167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090911681176401000000004267ffffffffffffffff90811682029290921793849055604051930416917f049fe9dd413cdf037cce27011cc1790c753118272f3630e6e8bdfa5e8208176090600090a350565b565b612016611531565b1561204d576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120578133610a91565b50565b600054610100900460ff161580801561207a5750600054600160ff909116105b806120945750303b158015612094575060005460ff166001145b612120576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611807565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561217e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603880547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8881169190911790925560378054909116868316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff16610100868416021790556032541661229e576032805461dead7fffffffffffffffffffffffff0000000000000000000000000000000000000000909116179055603b80547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166401000000004267ffffffffffffffff16027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000161763ffffffff84161790555b6122a6612bac565b8015610f2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600061231c8260106157e0565b61232890615208615810565b92915050565b603c602052816000526040600020818154811061234a57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169150829050565b60008061237e6123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016123c5574791505090565b5050603d5490565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015612459573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247d919061583c565b90939092509050565b8180156124a8575073ffffffffffffffffffffffffffffffffffffffff861615155b156124df576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6124e9815161230f565b67ffffffffffffffff168367ffffffffffffffff161015612536576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c081511115612574576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33328114612595575033731111000000000000000000000000000000001111015b600086868686866040516020016125b095949392919061577b565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161262091906152f6565b60405180910390a45050505050505050565b600154600090612668907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643615569565b90506000612674612cbf565b90506000816020015160ff16826000015163ffffffff16612695919061589a565b905082156127cc576001546000906126cc908390700100000000000000000000000000000000900467ffffffffffffffff16615902565b90506000836040015160ff16836126e39190615976565b6001546127039084906fffffffffffffffffffffffffffffffff16615976565b61270d919061589a565b60015490915060009061275e906127379084906fffffffffffffffffffffffffffffffff16615a32565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612d80565b9050600186111561278d5761278a61273782876040015160ff1660018a6127859190615569565b612d9f565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b600180548691906010906127ff908490700100000000000000000000000000000000900467ffffffffffffffff16615810565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff16131561288c576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906128b8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615aa6565b905060006128ca48633b9aca00612df4565b6128d49083615ae3565b905060005a6128e39088615569565b905080821115610a8757610a876128fa8284615569565b612e0b565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526129db9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612e34565b50505050565b80516020808301516040808501516060860151608087015160a08801519351600097612a11979096959101615af7565b604051602081830303815290604052805190602001209050919050565b6000806000612a3e866000612f40565b905080612a74576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052612ae29084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612959565b505050565b60008160000151826020015183604001518460600151604051602001612a11949392919093845260208401929092526040830152606082015260800190565b600080612b3286612f5e565b9050612b4081868686612f90565b9695505050505050565b6001805463ffffffff83169190601090612b83908490700100000000000000000000000000000000900467ffffffffffffffff16615810565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b600054610100900460ff16612c43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611807565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff1660000361200c5760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa158015612d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615b4e565b6000612d95612d8f8585612fc0565b83612fd0565b90505b9392505050565b6000670de0b6b3a7640000612de0612db7858361589a565b612dc990670de0b6b3a7640000615902565b612ddb85670de0b6b3a7640000615976565b612fdf565b612dea9086615976565b612d95919061589a565b600081831015612e045781612d98565b5090919050565b6000805a90505b825a612e1e9083615569565b1015612ae257612e2d82615bf0565b9150612e12565b6000612e96826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130109092919063ffffffff16565b805190915015612ae25780806020019051810190612eb49190615724565b612ae2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611807565b600080603f83619c4001026040850201603f5a021015949350505050565b60608180519060200120604051602001612f7a91815260200190565b6040516020818303038152906040529050919050565b6000612fb784612fa187868661301f565b8051602091820120825192909101919091201490565b95945050505050565b600081831215612e045781612d98565b6000818312612e045781612d98565b6000612d98670de0b6b3a764000083612ff786613a9d565b6130019190615976565b61300b919061589a565b613ce1565b6060612d958484600085613f20565b6060600084511161308c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401611807565b6000613097846140b6565b905060006130a4866141a2565b90506000846040516020016130bb91815260200190565b60405160208183030381529060405290506000805b8451811015613a145760008582815181106130ed576130ed615c28565b602002602001015190508451831115613188576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401611807565b8260000361324157805180516020918201206040516131d6926131b092910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b61323c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401611807565b613398565b8051516020116132f7578051805160209182012060405161326b926131b092910190815260200190565b61323c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401611807565b805184516020808701919091208251919092012014613398576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401611807565b6133a460106001615538565b816020015151036135805784518303613518576133de81602001516010815181106133d1576133d1615c28565b6020026020010151614205565b96506000875111613471576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401611807565b6001865161347f9190615569565b821461350d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401611807565b505050505050612d98565b600085848151811061352c5761352c615c28565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061355757613557615c28565b6020026020010151905061356a816142b9565b9550613577600186615538565b94505050613a01565b600281602001515103613979576000613598826142de565b90506000816000815181106135af576135af615c28565b016020015160f81c905060006135c6600283615c57565b6135d1906002615c79565b905060006135e2848360ff16614302565b905060006135f08a89614302565b905060006135fe8383614338565b905080835114613690576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401611807565b60ff8516600214806136a5575060ff85166003145b15613894578082511461373a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401611807565b61375487602001516001815181106133d1576133d1615c28565b9c5060008d51116137e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401611807565b60018c516137f59190615569565b8814613883576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401611807565b505050505050505050505050612d98565b60ff851615806138a7575060ff85166001145b156138e6576138d387602001516001815181106138c6576138c6615c28565b60200260200101516142b9565b99506138df818a615538565b985061396e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401611807565b505050505050613a01565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401611807565b5080613a0c81615bf0565b9150506130d0565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401611807565b6000808213613b08576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b60006060613b15846143ec565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c18213613d1257506000919050565b680755bf798b4a1bf1e58212613d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401611807565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613fb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611807565b73ffffffffffffffffffffffffffffffffffffffff85163b614030576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611807565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516140599190615c9c565b60006040518083038185875af1925050503d8060008114614096576040519150601f19603f3d011682016040523d82523d6000602084013e61409b565b606091505b50915091506140ab8282866144c2565b979650505050505050565b80516060908067ffffffffffffffff8111156140d4576140d4614eb1565b60405190808252806020026020018201604052801561411957816020015b60408051808201909152606080825260208201528152602001906001900390816140f25790505b50915060005b8181101561419b57604051806040016040528085838151811061414457614144615c28565b6020026020010151815260200161417386848151811061416657614166615c28565b6020026020010151614515565b81525083828151811061418857614188615c28565b602090810291909101015260010161411f565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b838110156141fa578060011b82018184015160001a8060041c8253600f8116600183015350506001016141cc565b509295945050505050565b6060600080600061421585614528565b91945092509050600081600181111561423057614230615650565b14614267576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6142718284615538565b8551146142aa576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fb7856020015184846149c6565b606060208260000151106142d5576142d082614205565b612328565b61232882614a5a565b60606123286142fd83602001516000815181106133d1576133d1615c28565b6141a2565b6060825182106143215750604080516020810190915260008152612328565b612d9883838486516143339190615569565b614a70565b600080825184511061434b57825161434e565b83515b90505b80821080156143d5575082828151811061436d5761436d615c28565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168483815181106143ac576143ac615c28565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156143e557816001019150614351565b5092915050565b6000808211614457576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606083156144d1575081612d98565b8251156144e15782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180791906152f6565b606061232861452383614c48565b614cb5565b6000806000836000015160000361456b576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f81116145905760006001600094509450945050506149bf565b60b781116146a65760006145a5608083615569565b9050808760000151116145e4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214801561465c57507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614693576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600195509350600092506149bf915050565b60bf81116148045760006146bb60b783615569565b9050808760000151116146fa576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361475c576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116147a4576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147ae8184615538565b8951116147e7576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147f2836001615538565b97509550600094506149bf9350505050565b60f7811161486957600061481960c083615569565b905080876000015111614858576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001955093508492506149bf915050565b600061487660f783615569565b9050808760000151116148b5576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614917576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c6037811161495f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6149698184615538565b8951116149a2576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6149ad836001615538565b97509550600194506149bf9350505050565b9193909250565b60608167ffffffffffffffff8111156149e1576149e1614eb1565b6040519080825280601f01601f191660200182016040528015614a0b576020820181803683370190505b5090508115612d98576000614a208486615538565b90506020820160005b84811015614a41578281015182820152602001614a29565b84811115614a50576000858301525b5050509392505050565b60606123288260200151600084600001516149c6565b60608182601f011015614adf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b828284011015614b4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b81830184511015614bb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401611807565b606082158015614bd75760405191506000825260208201604052614c3f565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614c10578051835260209283019201614bf8565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201528151600003614c97576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000614cc585614528565b919450925090506001816001811115614ce057614ce0615650565b14614d17576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451614d238385615538565b14614d5a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081614d715790505093506000835b8651811015614e5f57600080614de46040518060400160405280858c60000151614dc89190615569565b8152602001858c60200151614ddd9190615538565b9052614528565b509150915060405180604001604052808383614e009190615538565b8152602001848b60200151614e159190615538565b815250888581518110614e2a57614e2a615c28565b6020908102919091010152614e40600185615538565b9350614e4c8183615538565b614e569084615538565b92505050614d9e565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461205757600080fd5b67ffffffffffffffff8116811461205757600080fd5b801515811461205757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715614f0357614f03614eb1565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614f5057614f50614eb1565b604052919050565b600082601f830112614f6957600080fd5b813567ffffffffffffffff811115614f8357614f83614eb1565b614fb460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614f09565b818152846020838601011115614fc957600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614fff57600080fd5b863561500a81614e6b565b95506020870135945060408701359350606087013561502881614e8d565b9250608087013561503881614ea3565b915060a087013567ffffffffffffffff81111561505457600080fd5b61506089828a01614f58565b9150509295509295509295565b600060c0828403121561507f57600080fd5b60405160c0810167ffffffffffffffff82821081831117156150a3576150a3614eb1565b8160405282935084358352602085013591506150be82614e6b565b816020840152604085013591506150d482614e6b565b816040840152606085013560608401526080850135608084015260a085013591508082111561510257600080fd5b5061510f85828601614f58565b60a0830152505092915050565b6000806040838503121561512f57600080fd5b823567ffffffffffffffff81111561514657600080fd5b6151528582860161506d565b925050602083013561516381614e6b565b809150509250929050565b60006020828403121561518057600080fd5b8135612d9881614e6b565b600080600080600085870360e08112156151a457600080fd5b863567ffffffffffffffff808211156151bc57600080fd5b6151c88a838b0161506d565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401121561520157600080fd5b60408901955060c089013592508083111561521b57600080fd5b828901925089601f84011261522f57600080fd5b823591508082111561524057600080fd5b508860208260051b840101111561525657600080fd5b959894975092955050506020019190565b60006020828403121561527957600080fd5b5035919050565b60005b8381101561529b578181015183820152602001615283565b838111156129db5750506000910152565b600081518084526152c4816020860160208601615280565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612d9860208301846152ac565b6000806040838503121561531c57600080fd5b82359150602083013561516381614e6b565b60ff8116811461205757600080fd5b6000806000806080858703121561535357600080fd5b843561535e81614e6b565b9350602085013561536e8161532e565b93969395505050506040820135916060013590565b63ffffffff8116811461205757600080fd5b6000602082840312156153a757600080fd5b8135612d9881615383565b6000602082840312156153c457600080fd5b813567ffffffffffffffff8111156153db57600080fd5b6153e78482850161506d565b949350505050565b6000806000806080858703121561540557600080fd5b843561541081614e6b565b9350602085013561542081614e6b565b9250604085013561543081614e6b565b9150606085013561544081615383565b939692955090935050565b60006020828403121561545d57600080fd5b8135612d9881614e8d565b6000806040838503121561547b57600080fd5b50508035926020909101359150565b600080600080600060a086880312156154a257600080fd5b85356154ad81614e6b565b94506020860135935060408601356154c481614e8d565b925060608601356154d481614ea3565b9150608086013567ffffffffffffffff8111156154f057600080fd5b6154fc88828901614f58565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561554b5761554b615509565b500190565b60006020828403121561556257600080fd5b5051919050565b60008282101561557b5761557b615509565b500390565b60006020828403121561559257600080fd5b8151612d9881614e6b565b6000806000606084860312156155b257600080fd5b83516155bd81615383565b60208501519093506155ce81614e8d565b60408501519092506155df81614e6b565b809150509250925092565b6000608082840312156155fc57600080fd5b6040516080810181811067ffffffffffffffff8211171561561f5761561f614eb1565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006020828403121561569157600080fd5b815160038110612d9857600080fd5b600067ffffffffffffffff808411156156bb576156bb614eb1565b8360051b60206156cc818301614f09565b8681529185019181810190368411156156e457600080fd5b865b84811015615718578035868111156156fe5760008081fd5b61570a36828b01614f58565b8452509183019183016156e6565b50979650505050505050565b60006020828403121561573657600080fd5b8151612d9881614ea3565b60006020828403121561575357600080fd5b8151612d9881614e8d565b60006020828403121561577057600080fd5b8151612d9881615383565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b6048820152600082516157cf816049850160208701615280565b919091016049019695505050505050565b600067ffffffffffffffff8083168185168183048111821515161561580757615807615509565b02949350505050565b600067ffffffffffffffff80831681851680830382111561583357615833615509565b01949350505050565b6000806040838503121561584f57600080fd5b825161585a81614e6b565b60208401519092506151638161532e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826158a9576158a961586b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156158fd576158fd615509565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561593c5761593c615509565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561597057615970615509565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156159b7576159b7615509565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156159f2576159f2615509565b60008712925087820587128484161615615a0e57615a0e615509565b87850587128184161615615a2457615a24615509565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03841381151615615a6c57615a6c615509565b827f8000000000000000000000000000000000000000000000000000000000000000038412811615615aa057615aa0615509565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615ade57615ade615509565b500290565b600082615af257615af261586b565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152615b4260c08301846152ac565b98975050505050505050565b600060c08284031215615b6057600080fd5b615b68614ee0565b8251615b7381615383565b81526020830151615b838161532e565b60208201526040830151615b968161532e565b60408201526060830151615ba981615383565b60608201526080830151615bbc81615383565b608082015260a08301516fffffffffffffffffffffffffffffffff81168114615be457600080fd5b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615c2157615c21615509565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff831680615c6a57615c6a61586b565b8060ff84160691505092915050565b600060ff821660ff841680821015615c9357615c93615509565b90039392505050565b60008251615cae818460208701615280565b919091019291505056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000038" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000038" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000037" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000037" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": true, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000003b" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000100000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000003b" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": true, - "newValue": "0x000000000000000100000000000000000000000000000000000000003b9aca00", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xfa60f9b2", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000f" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": false, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf2b4e617", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000038" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x33d7e2bd", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000037" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x35e80ab3", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9bf62d82", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000dead", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x638627e586f5e36fe67a77519503a7c6da22f92b150d3c6055fd40bdcfe9ffd160806040523480156200001157600080fd5b506200001e600062000024565b62000292565b600054610100900460ff1615808015620000455750600054600160ff909116105b8062000075575062000062306200016260201b62000ce41760201c565b15801562000075575060005460ff166001145b620000de5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000102576000805461ff0019166101001790555b6200010c62000171565b6200011782620001d9565b80156200015e576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b03163b151590565b600054610100900460ff16620001cd5760405162461bcd60e51b815260206004820152602b60248201526000805160206200185983398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000d5565b620001d76200022b565b565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16620002875760405162461bcd60e51b815260206004820152602b60248201526000805160206200185983398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000d5565b620001d733620001d9565b6115b780620002a26000396000f3fe6080604052600436106100e85760003560e01c80636593dc6e1161008a57806396cd97201161005957806396cd972014610313578063bb8aa1fc14610333578063c4d66de814610394578063f2fde38b146103b457600080fd5b80636593dc6e14610293578063715018a6146102c057806382ecf2f6146102d55780638da5cb5b146102e857600080fd5b8063254bd683116100c6578063254bd6831461019c5780634d1975b4146101c957806354fd4d50146101e85780635f0150cb1461023e57600080fd5b806314f6b1a3146100ed5780631b685b9e1461010f5780631e3342401461017c575b600080fd5b3480156100f957600080fd5b5061010d6101083660046110c6565b6103d4565b005b34801561011b57600080fd5b5061015261012a3660046110fd565b60656020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061010d610197366004611118565b61045e565b3480156101a857600080fd5b506101bc6101b7366004611142565b6104aa565b60405161017391906111ef565b3480156101d557600080fd5b506068545b604051908152602001610173565b3480156101f457600080fd5b506102316040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b60405161017391906112ac565b34801561024a57600080fd5b5061025e6102593660046112bf565b6106ee565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff909116602083015201610173565b34801561029f57600080fd5b506101da6102ae3660046110fd565b60666020526000908152604090205481565b3480156102cc57600080fd5b5061010d610741565b6101526102e33660046112bf565b610755565b3480156102f457600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff16610152565b34801561031f57600080fd5b506101da61032e3660046112bf565b6109ef565b34801561033f57600080fd5b5061035361034e366004611346565b610a28565b6040805163ffffffff909416845267ffffffffffffffff909216602084015273ffffffffffffffffffffffffffffffffffffffff1690820152606001610173565b3480156103a057600080fd5b5061010d6103af36600461135f565b610a91565b3480156103c057600080fd5b5061010d6103cf36600461135f565b610c2d565b6103dc610d00565b63ffffffff821660008181526065602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616908117909155905190917fff513d80e2c7fa487608f70a618dfbc0cf415699dc69588c747e8c71566c88de91a35050565b610466610d00565b63ffffffff8216600081815260666020526040808220849055518392917f74d6665c4b26d5596a5aa13d3014e0c06af4d322075a797f87b03cd4c5bc91ca91a35050565b606854606090831015806104bc575081155b6106e7575060408051600583901b8101602001909152825b8381116106e5576000606882815481106104f0576104f061137c565b600091825260209091200154905060e081901c60a082901c67ffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff831663ffffffff891683036106b6576001865101865260008173ffffffffffffffffffffffffffffffffffffffff1663609d33346040518163ffffffff1660e01b8152600401600060405180830381865afa15801561058a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d091908101906113da565b905060008273ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561061f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064391906114a5565b90506040518060a001604052808881526020018781526020018567ffffffffffffffff168152602001828152602001838152508860018a5161068591906114be565b815181106106955761069561137c565b6020026020010181905250888851106106b3575050505050506106e5565b50505b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191506104d49050565b505b9392505050565b60008060006106ff878787876109ef565b60009081526067602052604090205473ffffffffffffffffffffffffffffffffffffffff81169860a09190911c67ffffffffffffffff16975095505050505050565b610749610d00565b6107536000610d81565b565b63ffffffff841660009081526065602052604081205473ffffffffffffffffffffffffffffffffffffffff16806107c5576040517f031c6de400000000000000000000000000000000000000000000000000000000815263ffffffff871660048201526024015b60405180910390fd5b63ffffffff86166000908152606660205260409020543414610813576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006108206001436114be565b40905061088a338783888860405160200161083f9594939291906114fc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905273ffffffffffffffffffffffffffffffffffffffff841690610df8565b92508273ffffffffffffffffffffffffffffffffffffffff16638129fc1c346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156108d457600080fd5b505af11580156108e8573d6000803e3d6000fd5b505050505060006108fb888888886109ef565b60008181526067602052604090205490915015610947576040517f014f6fe5000000000000000000000000000000000000000000000000000000008152600481018290526024016107bc565b60004260a01b60e08a901b178517600083815260676020526040808220839055606880546001810182559083527fa2153420d844928b4421650203c77babc8b33d7f2e7b450e2966db0c220977530183905551919250899163ffffffff8c169173ffffffffffffffffffffffffffffffffffffffff8916917f5b565efe82411da98814f356d0e7bcb8f0219b8d970307c5afb4a6903a8b2e359190a450505050949350505050565b600084848484604051602001610a089493929190611549565b604051602081830303815290604052805190602001209050949350505050565b600080600080600080610a8160688881548110610a4757610a4761137c565b906000526020600020015460e081901c9160a082901c67ffffffffffffffff169173ffffffffffffffffffffffffffffffffffffffff1690565b9199909850909650945050505050565b600054610100900460ff1615808015610ab15750600054600160ff909116105b80610acb5750303b158015610acb575060005460ff166001145b610b57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107bc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610bb557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610bbd610e06565b610bc682610d81565b8015610c2957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b610c35610d00565b73ffffffffffffffffffffffffffffffffffffffff8116610cd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016107bc565b610ce181610d81565b50565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60335473ffffffffffffffffffffffffffffffffffffffff163314610753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107bc565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006106e760008484610ea5565b600054610100900460ff16610e9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b610753610feb565b600060608203516040830351602084035184518060208701018051600283016c5af43d3d93803e606057fd5bf3895289600d8a035278593da1005b363d3d373d3d3d3d610000806062363936013d738160481b1760218a03527f9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff603a8a035272fd6100003d81600a3d39f336602c57343d527f6062820160781b1761ff9e82106059018a03528060f01b8352606c8101604c8a038cf097505086610f715763301164256000526004601cfd5b905285527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08501527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa09092019190915292915050565b600054610100900460ff16611082576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b61075333610d81565b803563ffffffff8116811461109f57600080fd5b919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610ce157600080fd5b600080604083850312156110d957600080fd5b6110e28361108b565b915060208301356110f2816110a4565b809150509250929050565b60006020828403121561110f57600080fd5b6106e78261108b565b6000806040838503121561112b57600080fd5b6111348361108b565b946020939093013593505050565b60008060006060848603121561115757600080fd5b6111608461108b565b95602085013595506040909401359392505050565b60005b83811015611190578181015183820152602001611178565b8381111561119f576000848401525b50505050565b600081518084526111bd816020860160208601611175565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561129e578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001855281518051845287810151888501528681015167ffffffffffffffff16878501526060808201519085015260809081015160a09185018290529061128a818601836111a5565b968901969450505090860190600101611216565b509098975050505050505050565b6020815260006106e760208301846111a5565b600080600080606085870312156112d557600080fd5b6112de8561108b565b935060208501359250604085013567ffffffffffffffff8082111561130257600080fd5b818701915087601f83011261131657600080fd5b81358181111561132557600080fd5b88602082850101111561133757600080fd5b95989497505060200194505050565b60006020828403121561135857600080fd5b5035919050565b60006020828403121561137157600080fd5b81356106e7816110a4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156113ec57600080fd5b815167ffffffffffffffff8082111561140457600080fd5b818401915084601f83011261141857600080fd5b81518181111561142a5761142a6113ab565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611470576114706113ab565b8160405282815287602084870101111561148957600080fd5b61149a836020830160208801611175565b979650505050505050565b6000602082840312156114b757600080fd5b5051919050565b6000828210156114f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500390565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008660601b1681528460148201528360348201528183605483013760009101605401908152949350505050565b63ffffffff8516815283602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101939250505056fea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x60806040523480156200001157600080fd5b506200001e600062000024565b62000292565b600054610100900460ff1615808015620000455750600054600160ff909116105b8062000075575062000062306200016260201b62000ce41760201c565b15801562000075575060005460ff166001145b620000de5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000102576000805461ff0019166101001790555b6200010c62000171565b6200011782620001d9565b80156200015e576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b03163b151590565b600054610100900460ff16620001cd5760405162461bcd60e51b815260206004820152602b60248201526000805160206200185983398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000d5565b620001d76200022b565b565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16620002875760405162461bcd60e51b815260206004820152602b60248201526000805160206200185983398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000d5565b620001d733620001d9565b6115b780620002a26000396000f3fe6080604052600436106100e85760003560e01c80636593dc6e1161008a57806396cd97201161005957806396cd972014610313578063bb8aa1fc14610333578063c4d66de814610394578063f2fde38b146103b457600080fd5b80636593dc6e14610293578063715018a6146102c057806382ecf2f6146102d55780638da5cb5b146102e857600080fd5b8063254bd683116100c6578063254bd6831461019c5780634d1975b4146101c957806354fd4d50146101e85780635f0150cb1461023e57600080fd5b806314f6b1a3146100ed5780631b685b9e1461010f5780631e3342401461017c575b600080fd5b3480156100f957600080fd5b5061010d6101083660046110c6565b6103d4565b005b34801561011b57600080fd5b5061015261012a3660046110fd565b60656020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061010d610197366004611118565b61045e565b3480156101a857600080fd5b506101bc6101b7366004611142565b6104aa565b60405161017391906111ef565b3480156101d557600080fd5b506068545b604051908152602001610173565b3480156101f457600080fd5b506102316040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b60405161017391906112ac565b34801561024a57600080fd5b5061025e6102593660046112bf565b6106ee565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff909116602083015201610173565b34801561029f57600080fd5b506101da6102ae3660046110fd565b60666020526000908152604090205481565b3480156102cc57600080fd5b5061010d610741565b6101526102e33660046112bf565b610755565b3480156102f457600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff16610152565b34801561031f57600080fd5b506101da61032e3660046112bf565b6109ef565b34801561033f57600080fd5b5061035361034e366004611346565b610a28565b6040805163ffffffff909416845267ffffffffffffffff909216602084015273ffffffffffffffffffffffffffffffffffffffff1690820152606001610173565b3480156103a057600080fd5b5061010d6103af36600461135f565b610a91565b3480156103c057600080fd5b5061010d6103cf36600461135f565b610c2d565b6103dc610d00565b63ffffffff821660008181526065602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616908117909155905190917fff513d80e2c7fa487608f70a618dfbc0cf415699dc69588c747e8c71566c88de91a35050565b610466610d00565b63ffffffff8216600081815260666020526040808220849055518392917f74d6665c4b26d5596a5aa13d3014e0c06af4d322075a797f87b03cd4c5bc91ca91a35050565b606854606090831015806104bc575081155b6106e7575060408051600583901b8101602001909152825b8381116106e5576000606882815481106104f0576104f061137c565b600091825260209091200154905060e081901c60a082901c67ffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff831663ffffffff891683036106b6576001865101865260008173ffffffffffffffffffffffffffffffffffffffff1663609d33346040518163ffffffff1660e01b8152600401600060405180830381865afa15801561058a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d091908101906113da565b905060008273ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561061f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064391906114a5565b90506040518060a001604052808881526020018781526020018567ffffffffffffffff168152602001828152602001838152508860018a5161068591906114be565b815181106106955761069561137c565b6020026020010181905250888851106106b3575050505050506106e5565b50505b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191506104d49050565b505b9392505050565b60008060006106ff878787876109ef565b60009081526067602052604090205473ffffffffffffffffffffffffffffffffffffffff81169860a09190911c67ffffffffffffffff16975095505050505050565b610749610d00565b6107536000610d81565b565b63ffffffff841660009081526065602052604081205473ffffffffffffffffffffffffffffffffffffffff16806107c5576040517f031c6de400000000000000000000000000000000000000000000000000000000815263ffffffff871660048201526024015b60405180910390fd5b63ffffffff86166000908152606660205260409020543414610813576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006108206001436114be565b40905061088a338783888860405160200161083f9594939291906114fc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905273ffffffffffffffffffffffffffffffffffffffff841690610df8565b92508273ffffffffffffffffffffffffffffffffffffffff16638129fc1c346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156108d457600080fd5b505af11580156108e8573d6000803e3d6000fd5b505050505060006108fb888888886109ef565b60008181526067602052604090205490915015610947576040517f014f6fe5000000000000000000000000000000000000000000000000000000008152600481018290526024016107bc565b60004260a01b60e08a901b178517600083815260676020526040808220839055606880546001810182559083527fa2153420d844928b4421650203c77babc8b33d7f2e7b450e2966db0c220977530183905551919250899163ffffffff8c169173ffffffffffffffffffffffffffffffffffffffff8916917f5b565efe82411da98814f356d0e7bcb8f0219b8d970307c5afb4a6903a8b2e359190a450505050949350505050565b600084848484604051602001610a089493929190611549565b604051602081830303815290604052805190602001209050949350505050565b600080600080600080610a8160688881548110610a4757610a4761137c565b906000526020600020015460e081901c9160a082901c67ffffffffffffffff169173ffffffffffffffffffffffffffffffffffffffff1690565b9199909850909650945050505050565b600054610100900460ff1615808015610ab15750600054600160ff909116105b80610acb5750303b158015610acb575060005460ff166001145b610b57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107bc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610bb557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610bbd610e06565b610bc682610d81565b8015610c2957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b610c35610d00565b73ffffffffffffffffffffffffffffffffffffffff8116610cd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016107bc565b610ce181610d81565b50565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60335473ffffffffffffffffffffffffffffffffffffffff163314610753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107bc565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006106e760008484610ea5565b600054610100900460ff16610e9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b610753610feb565b600060608203516040830351602084035184518060208701018051600283016c5af43d3d93803e606057fd5bf3895289600d8a035278593da1005b363d3d373d3d3d3d610000806062363936013d738160481b1760218a03527f9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff603a8a035272fd6100003d81600a3d39f336602c57343d527f6062820160781b1761ff9e82106059018a03528060f01b8352606c8101604c8a038cf097505086610f715763301164256000526004601cfd5b905285527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08501527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa09092019190915292915050565b600054610100900460ff16611082576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b61075333610d81565b803563ffffffff8116811461109f57600080fd5b919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610ce157600080fd5b600080604083850312156110d957600080fd5b6110e28361108b565b915060208301356110f2816110a4565b809150509250929050565b60006020828403121561110f57600080fd5b6106e78261108b565b6000806040838503121561112b57600080fd5b6111348361108b565b946020939093013593505050565b60008060006060848603121561115757600080fd5b6111608461108b565b95602085013595506040909401359392505050565b60005b83811015611190578181015183820152602001611178565b8381111561119f576000848401525b50505050565b600081518084526111bd816020860160208601611175565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561129e578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001855281518051845287810151888501528681015167ffffffffffffffff16878501526060808201519085015260809081015160a09185018290529061128a818601836111a5565b968901969450505090860190600101611216565b509098975050505050505050565b6020815260006106e760208301846111a5565b600080600080606085870312156112d557600080fd5b6112de8561108b565b935060208501359250604085013567ffffffffffffffff8082111561130257600080fd5b818701915087601f83011261131657600080fd5b81358181111561132557600080fd5b88602082850101111561133757600080fd5b95989497505060200194505050565b60006020828403121561135857600080fd5b5035919050565b60006020828403121561137157600080fd5b81356106e7816110a4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156113ec57600080fd5b815167ffffffffffffffff8082111561140457600080fd5b818401915084601f83011261141857600080fd5b81518181111561142a5761142a6113ab565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611470576114706113ab565b8160405282815287602084870101111561148957600080fd5b61149a836020830160208801611175565b979650505050505050565b6000602082840312156114b757600080fd5b5051919050565b6000828210156114f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500390565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008660601b1681528460148201528360348201528183605483013760009101605401908152949350505050565b63ffffffff8516815283602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101939250505056fea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", - "deployedCode": "0x6080604052600436106100e85760003560e01c80636593dc6e1161008a57806396cd97201161005957806396cd972014610313578063bb8aa1fc14610333578063c4d66de814610394578063f2fde38b146103b457600080fd5b80636593dc6e14610293578063715018a6146102c057806382ecf2f6146102d55780638da5cb5b146102e857600080fd5b8063254bd683116100c6578063254bd6831461019c5780634d1975b4146101c957806354fd4d50146101e85780635f0150cb1461023e57600080fd5b806314f6b1a3146100ed5780631b685b9e1461010f5780631e3342401461017c575b600080fd5b3480156100f957600080fd5b5061010d6101083660046110c6565b6103d4565b005b34801561011b57600080fd5b5061015261012a3660046110fd565b60656020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061010d610197366004611118565b61045e565b3480156101a857600080fd5b506101bc6101b7366004611142565b6104aa565b60405161017391906111ef565b3480156101d557600080fd5b506068545b604051908152602001610173565b3480156101f457600080fd5b506102316040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b60405161017391906112ac565b34801561024a57600080fd5b5061025e6102593660046112bf565b6106ee565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff909116602083015201610173565b34801561029f57600080fd5b506101da6102ae3660046110fd565b60666020526000908152604090205481565b3480156102cc57600080fd5b5061010d610741565b6101526102e33660046112bf565b610755565b3480156102f457600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff16610152565b34801561031f57600080fd5b506101da61032e3660046112bf565b6109ef565b34801561033f57600080fd5b5061035361034e366004611346565b610a28565b6040805163ffffffff909416845267ffffffffffffffff909216602084015273ffffffffffffffffffffffffffffffffffffffff1690820152606001610173565b3480156103a057600080fd5b5061010d6103af36600461135f565b610a91565b3480156103c057600080fd5b5061010d6103cf36600461135f565b610c2d565b6103dc610d00565b63ffffffff821660008181526065602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616908117909155905190917fff513d80e2c7fa487608f70a618dfbc0cf415699dc69588c747e8c71566c88de91a35050565b610466610d00565b63ffffffff8216600081815260666020526040808220849055518392917f74d6665c4b26d5596a5aa13d3014e0c06af4d322075a797f87b03cd4c5bc91ca91a35050565b606854606090831015806104bc575081155b6106e7575060408051600583901b8101602001909152825b8381116106e5576000606882815481106104f0576104f061137c565b600091825260209091200154905060e081901c60a082901c67ffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff831663ffffffff891683036106b6576001865101865260008173ffffffffffffffffffffffffffffffffffffffff1663609d33346040518163ffffffff1660e01b8152600401600060405180830381865afa15801561058a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d091908101906113da565b905060008273ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561061f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064391906114a5565b90506040518060a001604052808881526020018781526020018567ffffffffffffffff168152602001828152602001838152508860018a5161068591906114be565b815181106106955761069561137c565b6020026020010181905250888851106106b3575050505050506106e5565b50505b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191506104d49050565b505b9392505050565b60008060006106ff878787876109ef565b60009081526067602052604090205473ffffffffffffffffffffffffffffffffffffffff81169860a09190911c67ffffffffffffffff16975095505050505050565b610749610d00565b6107536000610d81565b565b63ffffffff841660009081526065602052604081205473ffffffffffffffffffffffffffffffffffffffff16806107c5576040517f031c6de400000000000000000000000000000000000000000000000000000000815263ffffffff871660048201526024015b60405180910390fd5b63ffffffff86166000908152606660205260409020543414610813576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006108206001436114be565b40905061088a338783888860405160200161083f9594939291906114fc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905273ffffffffffffffffffffffffffffffffffffffff841690610df8565b92508273ffffffffffffffffffffffffffffffffffffffff16638129fc1c346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156108d457600080fd5b505af11580156108e8573d6000803e3d6000fd5b505050505060006108fb888888886109ef565b60008181526067602052604090205490915015610947576040517f014f6fe5000000000000000000000000000000000000000000000000000000008152600481018290526024016107bc565b60004260a01b60e08a901b178517600083815260676020526040808220839055606880546001810182559083527fa2153420d844928b4421650203c77babc8b33d7f2e7b450e2966db0c220977530183905551919250899163ffffffff8c169173ffffffffffffffffffffffffffffffffffffffff8916917f5b565efe82411da98814f356d0e7bcb8f0219b8d970307c5afb4a6903a8b2e359190a450505050949350505050565b600084848484604051602001610a089493929190611549565b604051602081830303815290604052805190602001209050949350505050565b600080600080600080610a8160688881548110610a4757610a4761137c565b906000526020600020015460e081901c9160a082901c67ffffffffffffffff169173ffffffffffffffffffffffffffffffffffffffff1690565b9199909850909650945050505050565b600054610100900460ff1615808015610ab15750600054600160ff909116105b80610acb5750303b158015610acb575060005460ff166001145b610b57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107bc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610bb557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610bbd610e06565b610bc682610d81565b8015610c2957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b610c35610d00565b73ffffffffffffffffffffffffffffffffffffffff8116610cd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016107bc565b610ce181610d81565b50565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60335473ffffffffffffffffffffffffffffffffffffffff163314610753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107bc565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006106e760008484610ea5565b600054610100900460ff16610e9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b610753610feb565b600060608203516040830351602084035184518060208701018051600283016c5af43d3d93803e606057fd5bf3895289600d8a035278593da1005b363d3d373d3d3d3d610000806062363936013d738160481b1760218a03527f9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff603a8a035272fd6100003d81600a3d39f336602c57343d527f6062820160781b1761ff9e82106059018a03528060f01b8352606c8101604c8a038cf097505086610f715763301164256000526004601cfd5b905285527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08501527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa09092019190915292915050565b600054610100900460ff16611082576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b61075333610d81565b803563ffffffff8116811461109f57600080fd5b919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610ce157600080fd5b600080604083850312156110d957600080fd5b6110e28361108b565b915060208301356110f2816110a4565b809150509250929050565b60006020828403121561110f57600080fd5b6106e78261108b565b6000806040838503121561112b57600080fd5b6111348361108b565b946020939093013593505050565b60008060006060848603121561115757600080fd5b6111608461108b565b95602085013595506040909401359392505050565b60005b83811015611190578181015183820152602001611178565b8381111561119f576000848401525b50505050565b600081518084526111bd816020860160208601611175565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561129e578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001855281518051845287810151888501528681015167ffffffffffffffff16878501526060808201519085015260809081015160a09185018290529061128a818601836111a5565b968901969450505090860190600101611216565b509098975050505050505050565b6020815260006106e760208301846111a5565b600080600080606085870312156112d557600080fd5b6112de8561108b565b935060208501359250604085013567ffffffffffffffff8082111561130257600080fd5b818701915087601f83011261131657600080fd5b81358181111561132557600080fd5b88602082850101111561133757600080fd5b95989497505060200194505050565b60006020828403121561135857600080fd5b5035919050565b60006020828403121561137157600080fd5b81356106e7816110a4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156113ec57600080fd5b815167ffffffffffffffff8082111561140457600080fd5b818401915084601f83011261141857600080fd5b81518181111561142a5761142a6113ab565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611470576114706113ab565b8160405282815287602084870101111561148957600080fd5b61149a836020830160208801611175565b979650505050505050565b6000602082840312156114b757600080fd5b5051919050565b6000828210156114f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500390565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008660601b1681528460148201528360348201528183605483013760009101605401908152949350505050565b63ffffffff8516815283602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101939250505056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "isWrite": true, - "newValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "isWrite": false, - "newValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "previousValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x7a07653f", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000093a80", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000093a80", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000003b" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x638627e586f5e36fe67a77519503a7c6da22f92b150d3c6055fd40bdcfe9ffd160a06040523480156200001157600080fd5b506040516200192f3803806200192f8339810160408190526200003491620002d7565b6080819052620000466000806200004d565b50620002f1565b600054610100900460ff16158080156200006e5750600054600160ff909116105b806200009e57506200008b30620001a760201b620011041760201c565b1580156200009e575060005460ff166001145b620001075760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff1916600117905580156200012b576000805461ff0019166101001790555b62000135620001b6565b62000140836200021e565b606880546001600160a01b0319166001600160a01b0384161790558015620001a2576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03163b151590565b600054610100900460ff16620002125760405162461bcd60e51b815260206004820152602b60248201526000805160206200190f83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000fe565b6200021c62000270565b565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16620002cc5760405162461bcd60e51b815260206004820152602b60248201526000805160206200190f83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000fe565b6200021c336200021e565b600060208284031215620002ea57600080fd5b5051919050565b6080516115fb620003146000396000818161033f015261102501526115fb6000f3fe6080604052600436106101845760003560e01c8063715018a6116100d6578063a9059cbb1161007f578063dd62ed3e11610059578063dd62ed3e1461051c578063f2fde38b14610554578063f3fef3a31461057457610193565b8063a9059cbb146104a8578063cd47bde1146104c8578063d0e30db01461019357610193565b80638da5cb5b116100b05780638da5cb5b1461041757806395d89b4114610442578063977a5ec51461048857610193565b8063715018a61461039057806379502c55146103a55780637eee288d146103f757610193565b80632e1a7d4d1161013857806354fd4d501161011257806354fd4d50146102e75780636a42b8f81461033057806370a082311461036357610193565b80632e1a7d4d14610280578063313ce567146102a0578063485cc955146102c757610193565b80630ca35682116101695780630ca356821461022357806318160ddd1461024357806323b872dd1461026057610193565b806306fdde031461019b578063095ea7b3146101f357610193565b3661019357610191610594565b005b610191610594565b3480156101a757600080fd5b5060408051808201909152600d81527f577261707065642045746865720000000000000000000000000000000000000060208201525b6040516101ea91906113fd565b60405180910390f35b3480156101ff57600080fd5b5061021361020e366004611492565b6105ef565b60405190151581526020016101ea565b34801561022f57600080fd5b5061019161023e3660046114be565b610668565b34801561024f57600080fd5b50475b6040519081526020016101ea565b34801561026c57600080fd5b5061021361027b3660046114d7565b6107b9565b34801561028c57600080fd5b5061019161029b3660046114be565b6109d0565b3480156102ac57600080fd5b506102b5601281565b60405160ff90911681526020016101ea565b3480156102d357600080fd5b506101916102e2366004611518565b6109dd565b3480156102f357600080fd5b506101dd6040518060400160405280600a81526020017f312e312e302d72632e310000000000000000000000000000000000000000000081525081565b34801561033c57600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610252565b34801561036f57600080fd5b5061025261037e366004611551565b60656020526000908152604090205481565b34801561039c57600080fd5b50610191610bb9565b3480156103b157600080fd5b506068546103d29073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ea565b34801561040357600080fd5b50610191610412366004611492565b610bcd565b34801561042357600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff166103d2565b34801561044e57600080fd5b5060408051808201909152600481527f574554480000000000000000000000000000000000000000000000000000000060208201526101dd565b34801561049457600080fd5b506101916104a3366004611492565b610c21565b3480156104b457600080fd5b506102136104c3366004611492565b610d0e565b3480156104d457600080fd5b506105076104e3366004611518565b60676020908152600092835260408084209091529082529020805460019091015482565b604080519283526020830191909152016101ea565b34801561052857600080fd5b50610252610537366004611518565b606660209081526000928352604080842090915290825290205481565b34801561056057600080fd5b5061019161056f366004611551565b610d22565b34801561058057600080fd5b5061019161058f366004611492565b610dd6565b33600090815260656020526040812080543492906105b390849061159d565b909155505060405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b33600081815260666020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106579086815260200190565b60405180910390a350600192915050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064015b60405180910390fd5b60004782106106fd57476106ff565b815b604051909150600090339083908381818185875af1925050503d8060008114610744576040519150601f19603f3d011682016040523d82523d6000602084013e610749565b606091505b50509050806107b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f44656c61796564574554483a207265636f766572206661696c6564000000000060448201526064016106e5565b505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152606560205260408120548211156107eb57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610861575073ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156108e95773ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091529020548211156108a357600080fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152606660209081526040808320338452909152812080548492906108e39084906115b5565b90915550505b73ffffffffffffffffffffffffffffffffffffffff84166000908152606560205260408120805484929061091e9084906115b5565b909155505073ffffffffffffffffffffffffffffffffffffffff83166000908152606560205260408120805484929061095890849061159d565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109be91815260200190565b60405180910390a35060019392505050565b6109da3382610dd6565b50565b600054610100900460ff16158080156109fd5750600054600160ff909116105b80610a175750303b158015610a17575060005460ff166001145b610aa3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016106e5565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610b0157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b09611120565b610b12836111bf565b606880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617905580156107b457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b610bc1611236565b610bcb60006111bf565b565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120426001820155805490918391839190610c1790849061159d565b9091555050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610ca2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064016106e5565b73ffffffffffffffffffffffffffffffffffffffff821660008181526066602090815260408083203380855290835292819020859055518481529192917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a35050565b6000610d1b3384846107b9565b9392505050565b610d2a611236565b73ffffffffffffffffffffffffffffffffffffffff8116610dcd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016106e5565b6109da816111bf565b606860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6791906115cc565b15610ece576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f44656c61796564574554483a20636f6e7472616374206973207061757365640060448201526064016106e5565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290208054821115610f8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f44656c61796564574554483a20696e73756666696369656e7420756e6c6f636b60448201527f6564207769746864726177616c0000000000000000000000000000000000000060648201526084016106e5565b6000816001015411611022576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f44656c61796564574554483a207769746864726177616c206e6f7420756e6c6f60448201527f636b65640000000000000000000000000000000000000000000000000000000060648201526084016106e5565b427f00000000000000000000000000000000000000000000000000000000000000008260010154611053919061159d565b11156110e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f44656c61796564574554483a207769746864726177616c2064656c6179206e6f60448201527f74206d657400000000000000000000000000000000000000000000000000000060648201526084016106e5565b818160000160008282546110f591906115b5565b909155506107b49050826112b7565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff166111b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106e5565b610bcb61135d565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610bcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106e5565b336000908152606560205260409020548111156112d357600080fd5b33600090815260656020526040812080548392906112f29084906115b5565b9091555050604051339082156108fc029083906000818181858888f19350505050158015611324573d6000803e3d6000fd5b5060405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a250565b600054610100900460ff166113f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106e5565b610bcb336111bf565b600060208083528351808285015260005b8181101561142a5785810183015185820160400152820161140e565b8181111561143c576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146109da57600080fd5b600080604083850312156114a557600080fd5b82356114b081611470565b946020939093013593505050565b6000602082840312156114d057600080fd5b5035919050565b6000806000606084860312156114ec57600080fd5b83356114f781611470565b9250602084013561150781611470565b929592945050506040919091013590565b6000806040838503121561152b57600080fd5b823561153681611470565b9150602083013561154681611470565b809150509250929050565b60006020828403121561156357600080fd5b8135610d1b81611470565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115b0576115b061156e565b500190565b6000828210156115c7576115c761156e565b500390565b6000602082840312156115de57600080fd5b81518015158114610d1b57600080fdfea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420690000000000000000000000000000000000000000000000000000000000093a80", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x60a06040523480156200001157600080fd5b506040516200192f3803806200192f8339810160408190526200003491620002d7565b6080819052620000466000806200004d565b50620002f1565b600054610100900460ff16158080156200006e5750600054600160ff909116105b806200009e57506200008b30620001a760201b620011041760201c565b1580156200009e575060005460ff166001145b620001075760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff1916600117905580156200012b576000805461ff0019166101001790555b62000135620001b6565b62000140836200021e565b606880546001600160a01b0319166001600160a01b0384161790558015620001a2576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03163b151590565b600054610100900460ff16620002125760405162461bcd60e51b815260206004820152602b60248201526000805160206200190f83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000fe565b6200021c62000270565b565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16620002cc5760405162461bcd60e51b815260206004820152602b60248201526000805160206200190f83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000fe565b6200021c336200021e565b600060208284031215620002ea57600080fd5b5051919050565b6080516115fb620003146000396000818161033f015261102501526115fb6000f3fe6080604052600436106101845760003560e01c8063715018a6116100d6578063a9059cbb1161007f578063dd62ed3e11610059578063dd62ed3e1461051c578063f2fde38b14610554578063f3fef3a31461057457610193565b8063a9059cbb146104a8578063cd47bde1146104c8578063d0e30db01461019357610193565b80638da5cb5b116100b05780638da5cb5b1461041757806395d89b4114610442578063977a5ec51461048857610193565b8063715018a61461039057806379502c55146103a55780637eee288d146103f757610193565b80632e1a7d4d1161013857806354fd4d501161011257806354fd4d50146102e75780636a42b8f81461033057806370a082311461036357610193565b80632e1a7d4d14610280578063313ce567146102a0578063485cc955146102c757610193565b80630ca35682116101695780630ca356821461022357806318160ddd1461024357806323b872dd1461026057610193565b806306fdde031461019b578063095ea7b3146101f357610193565b3661019357610191610594565b005b610191610594565b3480156101a757600080fd5b5060408051808201909152600d81527f577261707065642045746865720000000000000000000000000000000000000060208201525b6040516101ea91906113fd565b60405180910390f35b3480156101ff57600080fd5b5061021361020e366004611492565b6105ef565b60405190151581526020016101ea565b34801561022f57600080fd5b5061019161023e3660046114be565b610668565b34801561024f57600080fd5b50475b6040519081526020016101ea565b34801561026c57600080fd5b5061021361027b3660046114d7565b6107b9565b34801561028c57600080fd5b5061019161029b3660046114be565b6109d0565b3480156102ac57600080fd5b506102b5601281565b60405160ff90911681526020016101ea565b3480156102d357600080fd5b506101916102e2366004611518565b6109dd565b3480156102f357600080fd5b506101dd6040518060400160405280600a81526020017f312e312e302d72632e310000000000000000000000000000000000000000000081525081565b34801561033c57600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610252565b34801561036f57600080fd5b5061025261037e366004611551565b60656020526000908152604090205481565b34801561039c57600080fd5b50610191610bb9565b3480156103b157600080fd5b506068546103d29073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ea565b34801561040357600080fd5b50610191610412366004611492565b610bcd565b34801561042357600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff166103d2565b34801561044e57600080fd5b5060408051808201909152600481527f574554480000000000000000000000000000000000000000000000000000000060208201526101dd565b34801561049457600080fd5b506101916104a3366004611492565b610c21565b3480156104b457600080fd5b506102136104c3366004611492565b610d0e565b3480156104d457600080fd5b506105076104e3366004611518565b60676020908152600092835260408084209091529082529020805460019091015482565b604080519283526020830191909152016101ea565b34801561052857600080fd5b50610252610537366004611518565b606660209081526000928352604080842090915290825290205481565b34801561056057600080fd5b5061019161056f366004611551565b610d22565b34801561058057600080fd5b5061019161058f366004611492565b610dd6565b33600090815260656020526040812080543492906105b390849061159d565b909155505060405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b33600081815260666020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106579086815260200190565b60405180910390a350600192915050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064015b60405180910390fd5b60004782106106fd57476106ff565b815b604051909150600090339083908381818185875af1925050503d8060008114610744576040519150601f19603f3d011682016040523d82523d6000602084013e610749565b606091505b50509050806107b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f44656c61796564574554483a207265636f766572206661696c6564000000000060448201526064016106e5565b505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152606560205260408120548211156107eb57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610861575073ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156108e95773ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091529020548211156108a357600080fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152606660209081526040808320338452909152812080548492906108e39084906115b5565b90915550505b73ffffffffffffffffffffffffffffffffffffffff84166000908152606560205260408120805484929061091e9084906115b5565b909155505073ffffffffffffffffffffffffffffffffffffffff83166000908152606560205260408120805484929061095890849061159d565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109be91815260200190565b60405180910390a35060019392505050565b6109da3382610dd6565b50565b600054610100900460ff16158080156109fd5750600054600160ff909116105b80610a175750303b158015610a17575060005460ff166001145b610aa3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016106e5565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610b0157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b09611120565b610b12836111bf565b606880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617905580156107b457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b610bc1611236565b610bcb60006111bf565b565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120426001820155805490918391839190610c1790849061159d565b9091555050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610ca2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064016106e5565b73ffffffffffffffffffffffffffffffffffffffff821660008181526066602090815260408083203380855290835292819020859055518481529192917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a35050565b6000610d1b3384846107b9565b9392505050565b610d2a611236565b73ffffffffffffffffffffffffffffffffffffffff8116610dcd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016106e5565b6109da816111bf565b606860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6791906115cc565b15610ece576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f44656c61796564574554483a20636f6e7472616374206973207061757365640060448201526064016106e5565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290208054821115610f8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f44656c61796564574554483a20696e73756666696369656e7420756e6c6f636b60448201527f6564207769746864726177616c0000000000000000000000000000000000000060648201526084016106e5565b6000816001015411611022576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f44656c61796564574554483a207769746864726177616c206e6f7420756e6c6f60448201527f636b65640000000000000000000000000000000000000000000000000000000060648201526084016106e5565b427f00000000000000000000000000000000000000000000000000000000000000008260010154611053919061159d565b11156110e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f44656c61796564574554483a207769746864726177616c2064656c6179206e6f60448201527f74206d657400000000000000000000000000000000000000000000000000000060648201526084016106e5565b818160000160008282546110f591906115b5565b909155506107b49050826112b7565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff166111b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106e5565b610bcb61135d565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610bcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106e5565b336000908152606560205260409020548111156112d357600080fd5b33600090815260656020526040812080548392906112f29084906115b5565b9091555050604051339082156108fc029083906000818181858888f19350505050158015611324573d6000803e3d6000fd5b5060405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a250565b600054610100900460ff166113f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106e5565b610bcb336111bf565b600060208083528351808285015260005b8181101561142a5785810183015185820160400152820161140e565b8181111561143c576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146109da57600080fd5b600080604083850312156114a557600080fd5b82356114b081611470565b946020939093013593505050565b6000602082840312156114d057600080fd5b5035919050565b6000806000606084860312156114ec57600080fd5b83356114f781611470565b9250602084013561150781611470565b929592945050506040919091013590565b6000806040838503121561152b57600080fd5b823561153681611470565b9150602083013561154681611470565b809150509250929050565b60006020828403121561156357600080fd5b8135610d1b81611470565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115b0576115b061156e565b500190565b6000828210156115c7576115c761156e565b500390565b6000602082840312156115de57600080fd5b81518015158114610d1b57600080fdfea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420690000000000000000000000000000000000000000000000000000000000093a80", - "deployedCode": "0x6080604052600436106101845760003560e01c8063715018a6116100d6578063a9059cbb1161007f578063dd62ed3e11610059578063dd62ed3e1461051c578063f2fde38b14610554578063f3fef3a31461057457610193565b8063a9059cbb146104a8578063cd47bde1146104c8578063d0e30db01461019357610193565b80638da5cb5b116100b05780638da5cb5b1461041757806395d89b4114610442578063977a5ec51461048857610193565b8063715018a61461039057806379502c55146103a55780637eee288d146103f757610193565b80632e1a7d4d1161013857806354fd4d501161011257806354fd4d50146102e75780636a42b8f81461033057806370a082311461036357610193565b80632e1a7d4d14610280578063313ce567146102a0578063485cc955146102c757610193565b80630ca35682116101695780630ca356821461022357806318160ddd1461024357806323b872dd1461026057610193565b806306fdde031461019b578063095ea7b3146101f357610193565b3661019357610191610594565b005b610191610594565b3480156101a757600080fd5b5060408051808201909152600d81527f577261707065642045746865720000000000000000000000000000000000000060208201525b6040516101ea91906113fd565b60405180910390f35b3480156101ff57600080fd5b5061021361020e366004611492565b6105ef565b60405190151581526020016101ea565b34801561022f57600080fd5b5061019161023e3660046114be565b610668565b34801561024f57600080fd5b50475b6040519081526020016101ea565b34801561026c57600080fd5b5061021361027b3660046114d7565b6107b9565b34801561028c57600080fd5b5061019161029b3660046114be565b6109d0565b3480156102ac57600080fd5b506102b5601281565b60405160ff90911681526020016101ea565b3480156102d357600080fd5b506101916102e2366004611518565b6109dd565b3480156102f357600080fd5b506101dd6040518060400160405280600a81526020017f312e312e302d72632e310000000000000000000000000000000000000000000081525081565b34801561033c57600080fd5b507f0000000000000000000000000000000000000000000000000000000000093a80610252565b34801561036f57600080fd5b5061025261037e366004611551565b60656020526000908152604090205481565b34801561039c57600080fd5b50610191610bb9565b3480156103b157600080fd5b506068546103d29073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ea565b34801561040357600080fd5b50610191610412366004611492565b610bcd565b34801561042357600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff166103d2565b34801561044e57600080fd5b5060408051808201909152600481527f574554480000000000000000000000000000000000000000000000000000000060208201526101dd565b34801561049457600080fd5b506101916104a3366004611492565b610c21565b3480156104b457600080fd5b506102136104c3366004611492565b610d0e565b3480156104d457600080fd5b506105076104e3366004611518565b60676020908152600092835260408084209091529082529020805460019091015482565b604080519283526020830191909152016101ea565b34801561052857600080fd5b50610252610537366004611518565b606660209081526000928352604080842090915290825290205481565b34801561056057600080fd5b5061019161056f366004611551565b610d22565b34801561058057600080fd5b5061019161058f366004611492565b610dd6565b33600090815260656020526040812080543492906105b390849061159d565b909155505060405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b33600081815260666020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106579086815260200190565b60405180910390a350600192915050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064015b60405180910390fd5b60004782106106fd57476106ff565b815b604051909150600090339083908381818185875af1925050503d8060008114610744576040519150601f19603f3d011682016040523d82523d6000602084013e610749565b606091505b50509050806107b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f44656c61796564574554483a207265636f766572206661696c6564000000000060448201526064016106e5565b505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152606560205260408120548211156107eb57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610861575073ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156108e95773ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091529020548211156108a357600080fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152606660209081526040808320338452909152812080548492906108e39084906115b5565b90915550505b73ffffffffffffffffffffffffffffffffffffffff84166000908152606560205260408120805484929061091e9084906115b5565b909155505073ffffffffffffffffffffffffffffffffffffffff83166000908152606560205260408120805484929061095890849061159d565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109be91815260200190565b60405180910390a35060019392505050565b6109da3382610dd6565b50565b600054610100900460ff16158080156109fd5750600054600160ff909116105b80610a175750303b158015610a17575060005460ff166001145b610aa3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016106e5565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610b0157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b09611120565b610b12836111bf565b606880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617905580156107b457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b610bc1611236565b610bcb60006111bf565b565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120426001820155805490918391839190610c1790849061159d565b9091555050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610ca2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064016106e5565b73ffffffffffffffffffffffffffffffffffffffff821660008181526066602090815260408083203380855290835292819020859055518481529192917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a35050565b6000610d1b3384846107b9565b9392505050565b610d2a611236565b73ffffffffffffffffffffffffffffffffffffffff8116610dcd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016106e5565b6109da816111bf565b606860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6791906115cc565b15610ece576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f44656c61796564574554483a20636f6e7472616374206973207061757365640060448201526064016106e5565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290208054821115610f8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f44656c61796564574554483a20696e73756666696369656e7420756e6c6f636b60448201527f6564207769746864726177616c0000000000000000000000000000000000000060648201526084016106e5565b6000816001015411611022576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f44656c61796564574554483a207769746864726177616c206e6f7420756e6c6f60448201527f636b65640000000000000000000000000000000000000000000000000000000060648201526084016106e5565b427f0000000000000000000000000000000000000000000000000000000000093a808260010154611053919061159d565b11156110e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f44656c61796564574554483a207769746864726177616c2064656c6179206e6f60448201527f74206d657400000000000000000000000000000000000000000000000000000060648201526084016106e5565b818160000160008282546110f591906115b5565b909155506107b49050826112b7565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff166111b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106e5565b610bcb61135d565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610bcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106e5565b336000908152606560205260409020548111156112d357600080fd5b33600090815260656020526040812080548392906112f29084906115b5565b9091555050604051339082156108fc029083906000818181858888f19350505050158015611324573d6000803e3d6000fd5b5060405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a250565b600054610100900460ff166113f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106e5565b610bcb336111bf565b600060208083528351808285015260005b8181101561142a5785810183015185820160400152820161140e565b8181111561143c576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146109da57600080fd5b600080604083850312156114a557600080fd5b82356114b081611470565b946020939093013593505050565b6000602082840312156114d057600080fd5b5035919050565b6000806000606084860312156114ec57600080fd5b83356114f781611470565b9250602084013561150781611470565b929592945050506040919091013590565b6000806040838503121561152b57600080fd5b823561153681611470565b9150602083013561154681611470565b809150509250929050565b60006020828403121561156357600080fd5b8135610d1b81611470565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115b0576115b061156e565b500190565b6000828210156115c7576115c761156e565b500390565b6000602082840312156115de57600080fd5b81518015158114610d1b57600080fdfea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "isWrite": true, - "newValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "isWrite": false, - "newValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "previousValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - }, - { - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - }, - { - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x7a07653f", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000093a80", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000093a80", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000003b" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a42b8f8", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6d74ca1f", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000002710", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000002710", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000003c" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf0deb91f", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000078", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000078", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000003d" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x638627e586f5e36fe67a77519503a7c6da22f92b150d3c6055fd40bdcfe9ffd160c06040523480156200001157600080fd5b5060405162003b6038038062003b6083398101604081905262000034916200014f565b60a082905260808190526001600160401b038111156200009a5760405162461bcd60e51b815260206004820152601a60248201527f6368616c6c656e676520706572696f6420746f6f206c61726765000000000000604482015260640160405180910390fd5b60005b620000ab600160106200018a565b811015620001465760038160108110620000c957620000c9620001a4565b015460038260108110620000e157620000e1620001a4565b01546040805160208101939093528201526060016040516020818303038152906040528051906020012060038260016200011c9190620001ba565b601081106200012f576200012f620001a4565b0155806200013d81620001d5565b9150506200009d565b505050620001f1565b600080604083850312156200016357600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b6000828210156200019f576200019f62000174565b500390565b634e487b7160e01b600052603260045260246000fd5b60008219821115620001d057620001d062000174565b500190565b600060018201620001ea57620001ea62000174565b5060010190565b60805160a05161393b62000225600039600081816105b00152611dea0152600081816106b001526114f3015261393b6000f3fe6080604052600436106101d85760003560e01c80639d53a64811610102578063ddcd58de11610095578063ec5efcbc11610064578063ec5efcbc14610681578063f3f480d9146106a1578063faf37bc7146106d4578063fef2b4ed146106e757600080fd5b8063ddcd58de146105d4578063e03110e11461060c578063e159261114610641578063ea7139501461066157600080fd5b8063b5e7154c116100d1578063b5e7154c14610555578063d18534b51461056c578063da35c6641461058c578063dd24f9bf146105a157600080fd5b80639d53a6481461048e5780639d7e8769146104dd578063b2e67ba8146104fd578063b4801e611461053557600080fd5b806361238bde1161017a5780637ac54767116101495780637ac54767146103ca5780638542cf50146103ea578063882856ef146104355780638dc4be111461046e57600080fd5b806361238bde1461031e5780636551927b146103565780637051472e1461038e5780637917de1d146103aa57600080fd5b80633909af5c116101b65780633909af5c146102715780634d52b4c91461029357806352f0f3ad146102a857806354fd4d50146102c857600080fd5b8063013cf08b146101dd5780630359a5631461022e5780632055b36b1461025c575b600080fd5b3480156101e957600080fd5b506101fd6101f8366004612e29565b610714565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526020830191909152015b60405180910390f35b34801561023a57600080fd5b5061024e610249366004612e6b565b610759565b604051908152602001610225565b34801561026857600080fd5b5061024e601081565b34801561027d57600080fd5b5061029161028c366004613073565b610891565b005b34801561029f57600080fd5b5061024e610ae8565b3480156102b457600080fd5b5061024e6102c336600461315f565b610b03565b3480156102d457600080fd5b506103116040518060400160405280600a81526020017f312e312e322d72632e310000000000000000000000000000000000000000000081525081565b60405161022591906131c6565b34801561032a57600080fd5b5061024e610339366004613217565b600160209081526000928352604080842090915290825290205481565b34801561036257600080fd5b5061024e610371366004612e6b565b601560209081526000928352604080842090915290825290205481565b34801561039a57600080fd5b5061024e6703782dace9d9000081565b3480156103b657600080fd5b506102916103c536600461327b565b610bd9565b3480156103d657600080fd5b5061024e6103e5366004612e29565b6110dc565b3480156103f657600080fd5b50610425610405366004613217565b600260209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610225565b34801561044157600080fd5b50610455610450366004613317565b6110f3565b60405167ffffffffffffffff9091168152602001610225565b34801561047a57600080fd5b5061029161048936600461334a565b61114d565b34801561049a57600080fd5b5061024e6104a9366004612e6b565b73ffffffffffffffffffffffffffffffffffffffff9091166000908152601860209081526040808320938352929052205490565b3480156104e957600080fd5b506102916104f8366004613396565b611248565b34801561050957600080fd5b5061024e610518366004612e6b565b601760209081526000928352604080842090915290825290205481565b34801561054157600080fd5b5061024e610550366004613317565b6113ff565b34801561056157600080fd5b5061024e620186a081565b34801561057857600080fd5b50610291610587366004613073565b611431565b34801561059857600080fd5b5060135461024e565b3480156105ad57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061024e565b3480156105e057600080fd5b5061024e6105ef366004612e6b565b601660209081526000928352604080842090915290825290205481565b34801561061857600080fd5b5061062c610627366004613217565b611840565b60408051928352602083019190915201610225565b34801561064d57600080fd5b5061029161065c36600461334a565b611931565b34801561066d57600080fd5b5061029161067c366004613422565b611a39565b34801561068d57600080fd5b5061029161069c366004613491565b611b98565b3480156106ad57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061024e565b6102916106e2366004613519565b611d1e565b3480156106f357600080fd5b5061024e610702366004612e29565b60006020819052908152604090205481565b6013818154811061072457600080fd5b60009182526020909120600290910201805460019091015473ffffffffffffffffffffffffffffffffffffffff909116915082565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601560209081526040808320848452909152812054819061079c9060601c63ffffffff1690565b63ffffffff16905060005b6010811015610889578160011660010361082f5773ffffffffffffffffffffffffffffffffffffffff85166000908152601460209081526040808320878452909152902081601081106107fc576107fc613555565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250610870565b826003826010811061084357610843613555565b01546040805160208101939093528201526060016040516020818303038152906040528051906020012092505b60019190911c9080610881816135b3565b9150506107a7565b505092915050565b600061089d8a8a610759565b90506108c086868360208b01356108bb6108b68d6135eb565b611fea565b61202a565b80156108de57506108de83838360208801356108bb6108b68a6135eb565b610914576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b86604001358860405160200161092a91906136ba565b6040516020818303038152906040528051906020012014610977576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83602001358760200135600161098d91906136f8565b146109c4576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a0c886109d28680613710565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061208b92505050565b610a15886121e6565b836040013588604051602001610a2b91906136ba565b6040516020818303038152906040528051906020012003610a78576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8a1660009081526015602090815260408083208c8452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055610adc8a8a3361298e565b50505050505050505050565b6001610af660106002613897565b610b0091906138a3565b81565b6000610b0f8686612a47565b9050610b1c8360086136f8565b82101580610b2a5750602083115b15610b61576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b60608115610bf257610beb8686612af4565b9050610c2c565b85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050505b3360009081526014602090815260408083208b845290915280822081516102008101928390529160109082845b815481526020019060010190808311610c5957505050505090506000601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b81526020019081526020016000205490506000610cda8260601c63ffffffff1690565b63ffffffff169050333214610d1b576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d2b8260801c63ffffffff1690565b63ffffffff16600003610d6a576040517f87138d5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d748260c01c90565b67ffffffffffffffff1615610db5576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b898114610dee576040517f60f95d5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610dfb89898d8886612b6d565b83516020850160888204881415608883061715610e20576307b1daf16000526004601cfd5b60405160c8810160405260005b83811015610ed0578083018051835260208101516020840152604081015160408401526060810151606084015260808101516080840152508460888301526088810460051b8b013560a883015260c882206001860195508560005b610200811015610ec5576001821615610ea55782818b0152610ec5565b8981015160009081526020938452604090209260019290921c9101610e88565b505050608801610e2d565b50505050600160106002610ee49190613897565b610eee91906138a3565b811115610f27576040517f6229572300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f9c610f3a8360401c63ffffffff1690565b610f4a9063ffffffff168a6136f8565b60401b7fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff606084901b167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff8516171790565b915084156110295777ffffffffffffffffffffffffffffffffffffffffffffffff82164260c01b179150610fd68260801c63ffffffff1690565b63ffffffff16610fec8360401c63ffffffff1690565b63ffffffff1614611029576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526014602090815260408083208e8452909152902061104f90846010612d9f565b503360008181526018602090815260408083208f8452825280832080546001810182559084528284206004820401805460039092166008026101000a67ffffffffffffffff818102199093164390931602919091179055838352601582528083208f8452909152812084905560609190911b81523690601437366014016000a05050505050505050505050565b600381601081106110ec57600080fd5b0154905081565b6018602052826000526040600020602052816000526040600020818154811061111b57600080fd5b906000526020600020906004918282040191900660080292509250509054906101000a900467ffffffffffffffff1681565b60443560008060088301861061116b5763fe2549876000526004601cfd5b60c083901b60805260888386823786600882030151915060206000858360025afa90508061119857600080fd5b50600080517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0400000000000000000000000000000000000000000000000000000000000000178082526002602090815260408084208a8552825280842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558385528252808420998452988152888320939093558152908190529490942055505050565b600080603087600037602060006030600060025afa806112705763f91129696000526004601cfd5b6000517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f010000000000000000000000000000000000000000000000000000000000000017608081815260a08c905260c08b905260308a60e037603088609083013760008060c083600a5afa9250826112f2576309bde3396000526004601cfd5b602886106113085763fe2549876000526004601cfd5b6000602882015278200000000000000000000000000000000000000000000000008152600881018b905285810151935060308a8237603081019b909b52505060509098207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0500000000000000000000000000000000000000000000000000000000000000176000818152600260209081526040808320868452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209583529481528482209a909a559081528089529190912096909655505050505050565b6014602052826000526040600020602052816000526040600020816010811061142757600080fd5b0154925083915050565b73ffffffffffffffffffffffffffffffffffffffff891660009081526015602090815260408083208b845290915290205467ffffffffffffffff8116156114a4576040517fc334f06900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114ae8160c01c90565b67ffffffffffffffff166000036114f1576040517f55d4cbf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000061151c8260c01c90565b6115309067ffffffffffffffff16426138a3565b11611567576040517f55d4cbf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006115738b8b610759565b905061158c87878360208c01356108bb6108b68e6135eb565b80156115aa57506115aa84848360208901356108bb6108b68b6135eb565b6115e0576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8760400135896040516020016115f691906136ba565b6040516020818303038152906040528051906020012014611643576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84602001358860200135600161165991906136f8565b14158061168b575060016116738360601c63ffffffff1690565b61167d91906138ba565b63ffffffff16856020013514155b156116c2576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116d0896109d28780613710565b6116d9896121e6565b60006116e48a612cc0565b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0200000000000000000000000000000000000000000000000000000000000000179050600061173b8460a01c63ffffffff1690565b67ffffffffffffffff169050600160026000848152602001908152602001600020600083815260200190815260200160002060006101000a81548160ff021916908315150217905550601760008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008d8152602001908152602001600020546001600084815260200190815260200160002060008381526020019081526020016000208190555061180d8460801c63ffffffff1690565b600083815260208190526040902063ffffffff9190911690556118318d8d8161298e565b50505050505050505050505050565b6000828152600260209081526040808320848452909152812054819060ff166118c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546118e58160086136f8565b6118f08560206136f8565b1061190e57836119018260086136f8565b61190b91906138a3565b91505b506000938452600160209081526040808620948652939052919092205492909150565b60443560008060088301861061194f5763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b60008060008060808860601b81528760c01b6014820152858782601c0137601c860181207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0600000000000000000000000000000000000000000000000000000000000000179350604088026260216001603f5a021015611ac35763dd629f866000526004601cfd5b6000808783601c018c5afa94503d6001019150600882018a10611aee5763fe2549876000526004601cfd5b60c082901b81526008018481533d6000600183013e89017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8015160008481526002602090815260408083208d8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915587845282528083209c83529b81528b8220929092559384528390529790912096909655505050505050565b6000611ba48686610759565b9050611bbd83838360208801356108bb6108b68a6135eb565b611bf3576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602084013515611c2f576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c37612ddd565b611c45816109d28780613710565b611c4e816121e6565b846040013581604051602001611c6491906136ba565b6040516020818303038152906040528051906020012003611cb1576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166000908152601560209081526040808320898452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055611d1587873361298e565b50505050505050565b6703782dace9d90000341015611d60576040517fe92c469f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333214611d99576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611da48160086138df565b63ffffffff168263ffffffff1610611de8576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000008163ffffffff161015611e48576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152601560209081526040808320868452909152902054611e738160801c63ffffffff1690565b63ffffffff1615611eb0576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608082901b7fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff60a085901b167fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff83161717336000818152601560209081526040808320898452825280832094909455835180850185528381528082018981526013805460018101825590855291517f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a090600290930292830180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055517f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0919091015591815260168252828120968152959052909320349055505050565b600081600001518260200151836040015160405160200161200d93929190613907565b604051602081830303815290604052805190602001209050919050565b60008160005b601081101561207e578060051b880135600186831c16600181146120635760008481526020839052604090209350612074565b600082815260208590526040902093505b5050600101612030565b5090931495945050505050565b608881511461209957600080fd5b602081016020830161211a565b8260031b8201518060001a8160011a60081b178160021a60101b8260031a60181b17178160041a60201b8260051a60281b178260061a60301b8360071a60381b1717179050612114816120ff868560059190911b015190565b1867ffffffffffffffff16600586901b840152565b50505050565b612126600083836120a6565b612132600183836120a6565b61213e600283836120a6565b61214a600383836120a6565b612156600483836120a6565b612162600583836120a6565b61216e600683836120a6565b61217a600783836120a6565b612186600883836120a6565b612192600983836120a6565b61219e600a83836120a6565b6121aa600b83836120a6565b6121b6600c83836120a6565b6121c2600d83836120a6565b6121ce600e83836120a6565b6121da600f83836120a6565b612114601083836120a6565b6040805178010000000000008082800000000000808a8000000080008000602082015279808b00000000800000018000000080008081800000000000800991810191909152788a00000000000000880000000080008009000000008000000a60608201527b8000808b800000000000008b8000000000008089800000000000800360808201527f80000000000080028000000000000080000000000000800a800000008000000a60a08201527f800000008000808180000000000080800000000080000001800000008000800860c082015260009060e0016040516020818303038152906040529050602082016020820161286e565b6102808101516101e082015161014083015160a0840151845118189118186102a082015161020083015161016084015160c0850151602086015118189118186102c083015161022084015161018085015160e0860151604087015118189118186102e08401516102408501516101a0860151610100870151606088015118189118186103008501516102608601516101c0870151610120880151608089015118189118188084603f1c6123998660011b67ffffffffffffffff1690565b18188584603f1c6123b48660011b67ffffffffffffffff1690565b18188584603f1c6123cf8660011b67ffffffffffffffff1690565b181895508483603f1c6123ec8560011b67ffffffffffffffff1690565b181894508387603f1c6124098960011b67ffffffffffffffff1690565b60208b01518b51861867ffffffffffffffff168c5291189190911897508118600181901b603f9190911c18935060c08801518118601481901c602c9190911b1867ffffffffffffffff1660208901526101208801518718602c81901c60149190911b1867ffffffffffffffff1660c08901526102c08801518618600381901c603d9190911b1867ffffffffffffffff166101208901526101c08801518718601981901c60279190911b1867ffffffffffffffff166102c08901526102808801518218602e81901c60129190911b1867ffffffffffffffff166101c089015260408801518618600281901c603e9190911b1867ffffffffffffffff166102808901526101808801518618601581901c602b9190911b1867ffffffffffffffff1660408901526101a08801518518602781901c60199190911b1867ffffffffffffffff166101808901526102608801518718603881901c60089190911b1867ffffffffffffffff166101a08901526102e08801518518600881901c60389190911b1867ffffffffffffffff166102608901526101e08801518218601781901c60299190911b1867ffffffffffffffff166102e089015260808801518718602581901c601b9190911b1867ffffffffffffffff166101e08901526103008801518718603281901c600e9190911b1867ffffffffffffffff1660808901526102a08801518118603e81901c60029190911b1867ffffffffffffffff166103008901526101008801518518600981901c60379190911b1867ffffffffffffffff166102a08901526102008801518118601381901c602d9190911b1867ffffffffffffffff1661010089015260a08801518218601c81901c60249190911b1867ffffffffffffffff1661020089015260608801518518602481901c601c9190911b1867ffffffffffffffff1660a08901526102408801518518602b81901c60159190911b1867ffffffffffffffff1660608901526102208801518618603181901c600f9190911b1867ffffffffffffffff166102408901526101608801518118603681901c600a9190911b1867ffffffffffffffff166102208901525060e08701518518603a81901c60069190911b1867ffffffffffffffff166101608801526101408701518118603d81901c60039190911b1867ffffffffffffffff1660e0880152505067ffffffffffffffff81166101408601525b5050505050565b600582811b8201805160018501831b8401805160028701851b8601805160038901871b8801805160048b0190981b8901805167ffffffffffffffff861985168918811690995283198a16861889169096528819861683188816909352841986168818871690528419831684189095169052919391929190611d15565b612808600082612781565b612813600582612781565b61281e600a82612781565b612829600f82612781565b612834601482612781565b50565b612840816122dc565b612849816127fd565b600383901b820151815160c09190911c9061211490821867ffffffffffffffff168352565b61287a60008284612837565b61288660018284612837565b61289260028284612837565b61289e60038284612837565b6128aa60048284612837565b6128b660058284612837565b6128c260068284612837565b6128ce60078284612837565b6128da60088284612837565b6128e660098284612837565b6128f2600a8284612837565b6128fe600b8284612837565b61290a600c8284612837565b612916600d8284612837565b612922600e8284612837565b61292e600f8284612837565b61293a60108284612837565b61294660118284612837565b61295260128284612837565b61295e60138284612837565b61296a60148284612837565b61297660158284612837565b61298260168284612837565b61211460178284612837565b73ffffffffffffffffffffffffffffffffffffffff83811660009081526016602090815260408083208684529091528082208054908390559051909284169083908381818185875af1925050503d8060008114612a07576040519150601f19603f3d011682016040523d82523d6000602084013e612a0c565b606091505b505090508061277a576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831617612aed818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b6060604051905081602082018181018286833760888306808015612b3d5760888290038501848101848103803687375060806001820353506001845160001a1784538652612b54565b608836843760018353608060878401536088850186525b5050505050601f19603f82510116810160405292915050565b6000612b7f8260a01c63ffffffff1690565b67ffffffffffffffff1690506000612b9d8360801c63ffffffff1690565b63ffffffff1690506000612bb78460401c63ffffffff1690565b63ffffffff169050600883108015612bcd575080155b15612c015760c082901b6000908152883560085283513382526017602090815260408084208a855290915290912055612cb6565b60088310158015612c1f575080612c196008856138a3565b93508310155b8015612c335750612c3087826136f8565b83105b15612cb6576000612c4482856138a3565b905087612c528260206136f8565b10158015612c5e575085155b15612c95576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526017602090815260408083208a845290915290209089013590555b5050505050505050565b6000612d43565b66ff00ff00ff00ff8160081c1667ff00ff00ff00ff00612cf18360081b67ffffffffffffffff1690565b1617905065ffff0000ffff8160101c1667ffff0000ffff0000612d1e8360101b67ffffffffffffffff1690565b1617905060008160201c612d3c8360201b67ffffffffffffffff1690565b1792915050565b60808201516020830190612d5b90612cc7565b612cc7565b6040820151612d6990612cc7565b60401b17612d81612d5660018460059190911b015190565b825160809190911b90612d9390612cc7565b60c01b17179392505050565b8260108101928215612dcd579160200282015b82811115612dcd578251825591602001919060010190612db2565b50612dd9929150612df5565b5090565b6040518060200160405280612df0612e0a565b905290565b5b80821115612dd95760008155600101612df6565b6040518061032001604052806019906020820280368337509192915050565b600060208284031215612e3b57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612e6657600080fd5b919050565b60008060408385031215612e7e57600080fd5b612e8783612e42565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610320810167ffffffffffffffff81118282101715612ee857612ee8612e95565b60405290565b6040516060810167ffffffffffffffff81118282101715612ee857612ee8612e95565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612f5857612f58612e95565b604052919050565b803567ffffffffffffffff81168114612e6657600080fd5b6000610320808385031215612f8c57600080fd5b604051602080820182811067ffffffffffffffff82111715612fb057612fb0612e95565b806040525081935085601f860112612fc757600080fd5b612fcf612ec4565b928501928087851115612fe157600080fd5b865b8581101561300157612ff481612f60565b8352918301918301612fe3565b509092525091949350505050565b60006060828403121561302157600080fd5b50919050565b60008083601f84011261303957600080fd5b50813567ffffffffffffffff81111561305157600080fd5b6020830191508360208260051b850101111561306c57600080fd5b9250929050565b60008060008060008060008060006103e08a8c03121561309257600080fd5b61309b8a612e42565b985060208a013597506130b18b60408c01612f78565b96506103608a013567ffffffffffffffff808211156130cf57600080fd5b6130db8d838e0161300f565b97506103808c01359150808211156130f257600080fd5b6130fe8d838e01613027565b90975095506103a08c013591508082111561311857600080fd5b6131248d838e0161300f565b94506103c08c013591508082111561313b57600080fd5b506131488c828d01613027565b915080935050809150509295985092959850929598565b600080600080600060a0868803121561317757600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60005b838110156131b557818101518382015260200161319d565b838111156121145750506000910152565b60208152600082518060208401526131e581604085016020870161319a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000806040838503121561322a57600080fd5b50508035926020909101359150565b60008083601f84011261324b57600080fd5b50813567ffffffffffffffff81111561326357600080fd5b60208301915083602082850101111561306c57600080fd5b600080600080600080600060a0888a03121561329657600080fd5b8735965060208801359550604088013567ffffffffffffffff808211156132bc57600080fd5b6132c88b838c01613239565b909750955060608a01359150808211156132e157600080fd5b506132ee8a828b01613027565b9094509250506080880135801515811461330757600080fd5b8091505092959891949750929550565b60008060006060848603121561332c57600080fd5b61333584612e42565b95602085013595506040909401359392505050565b60008060006040848603121561335f57600080fd5b83359250602084013567ffffffffffffffff81111561337d57600080fd5b61338986828701613239565b9497909650939450505050565b600080600080600080600060a0888a0312156133b157600080fd5b8735965060208801359550604088013567ffffffffffffffff808211156133d757600080fd5b6133e38b838c01613239565b909750955060608a01359150808211156133fc57600080fd5b506134098a828b01613239565b989b979a50959894979596608090950135949350505050565b60008060008060006080868803121561343a57600080fd5b8535945061344a60208701612e42565b935061345860408701612f60565b9250606086013567ffffffffffffffff81111561347457600080fd5b61348088828901613239565b969995985093965092949392505050565b6000806000806000608086880312156134a957600080fd5b6134b286612e42565b945060208601359350604086013567ffffffffffffffff808211156134d657600080fd5b6134e289838a0161300f565b945060608801359150808211156134f857600080fd5b5061348088828901613027565b803563ffffffff81168114612e6657600080fd5b60008060006060848603121561352e57600080fd5b8335925061353e60208501613505565b915061354c60408501613505565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135e4576135e4613584565b5060010190565b6000606082360312156135fd57600080fd5b613605612eee565b823567ffffffffffffffff8082111561361d57600080fd5b9084019036601f83011261363057600080fd5b813560208282111561364457613644612e95565b613674817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011601612f11565b9250818352368183860101111561368a57600080fd5b81818501828501376000918301810191909152908352848101359083015250604092830135928101929092525090565b81516103208201908260005b60198110156136ef57825167ffffffffffffffff168252602092830192909101906001016136c6565b50505092915050565b6000821982111561370b5761370b613584565b500190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261374557600080fd5b83018035915067ffffffffffffffff82111561376057600080fd5b60200191503681900382131561306c57600080fd5b600181815b808511156137ce57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156137b4576137b4613584565b808516156137c157918102915b93841c939080029061377a565b509250929050565b6000826137e557506001613891565b816137f257506000613891565b816001811461380857600281146138125761382e565b6001915050613891565b60ff84111561382357613823613584565b50506001821b613891565b5060208310610133831016604e8410600b8410161715613851575081810a613891565b61385b8383613775565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561388d5761388d613584565b0290505b92915050565b6000612aed83836137d6565b6000828210156138b5576138b5613584565b500390565b600063ffffffff838116908316818110156138d7576138d7613584565b039392505050565b600063ffffffff8083168185168083038211156138fe576138fe613584565b01949350505050565b6000845161391981846020890161319a565b9190910192835250602082015260400191905056fea164736f6c634300080f000a00000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000000078", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x60c06040523480156200001157600080fd5b5060405162003b6038038062003b6083398101604081905262000034916200014f565b60a082905260808190526001600160401b038111156200009a5760405162461bcd60e51b815260206004820152601a60248201527f6368616c6c656e676520706572696f6420746f6f206c61726765000000000000604482015260640160405180910390fd5b60005b620000ab600160106200018a565b811015620001465760038160108110620000c957620000c9620001a4565b015460038260108110620000e157620000e1620001a4565b01546040805160208101939093528201526060016040516020818303038152906040528051906020012060038260016200011c9190620001ba565b601081106200012f576200012f620001a4565b0155806200013d81620001d5565b9150506200009d565b505050620001f1565b600080604083850312156200016357600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b6000828210156200019f576200019f62000174565b500390565b634e487b7160e01b600052603260045260246000fd5b60008219821115620001d057620001d062000174565b500190565b600060018201620001ea57620001ea62000174565b5060010190565b60805160a05161393b62000225600039600081816105b00152611dea0152600081816106b001526114f3015261393b6000f3fe6080604052600436106101d85760003560e01c80639d53a64811610102578063ddcd58de11610095578063ec5efcbc11610064578063ec5efcbc14610681578063f3f480d9146106a1578063faf37bc7146106d4578063fef2b4ed146106e757600080fd5b8063ddcd58de146105d4578063e03110e11461060c578063e159261114610641578063ea7139501461066157600080fd5b8063b5e7154c116100d1578063b5e7154c14610555578063d18534b51461056c578063da35c6641461058c578063dd24f9bf146105a157600080fd5b80639d53a6481461048e5780639d7e8769146104dd578063b2e67ba8146104fd578063b4801e611461053557600080fd5b806361238bde1161017a5780637ac54767116101495780637ac54767146103ca5780638542cf50146103ea578063882856ef146104355780638dc4be111461046e57600080fd5b806361238bde1461031e5780636551927b146103565780637051472e1461038e5780637917de1d146103aa57600080fd5b80633909af5c116101b65780633909af5c146102715780634d52b4c91461029357806352f0f3ad146102a857806354fd4d50146102c857600080fd5b8063013cf08b146101dd5780630359a5631461022e5780632055b36b1461025c575b600080fd5b3480156101e957600080fd5b506101fd6101f8366004612e29565b610714565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526020830191909152015b60405180910390f35b34801561023a57600080fd5b5061024e610249366004612e6b565b610759565b604051908152602001610225565b34801561026857600080fd5b5061024e601081565b34801561027d57600080fd5b5061029161028c366004613073565b610891565b005b34801561029f57600080fd5b5061024e610ae8565b3480156102b457600080fd5b5061024e6102c336600461315f565b610b03565b3480156102d457600080fd5b506103116040518060400160405280600a81526020017f312e312e322d72632e310000000000000000000000000000000000000000000081525081565b60405161022591906131c6565b34801561032a57600080fd5b5061024e610339366004613217565b600160209081526000928352604080842090915290825290205481565b34801561036257600080fd5b5061024e610371366004612e6b565b601560209081526000928352604080842090915290825290205481565b34801561039a57600080fd5b5061024e6703782dace9d9000081565b3480156103b657600080fd5b506102916103c536600461327b565b610bd9565b3480156103d657600080fd5b5061024e6103e5366004612e29565b6110dc565b3480156103f657600080fd5b50610425610405366004613217565b600260209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610225565b34801561044157600080fd5b50610455610450366004613317565b6110f3565b60405167ffffffffffffffff9091168152602001610225565b34801561047a57600080fd5b5061029161048936600461334a565b61114d565b34801561049a57600080fd5b5061024e6104a9366004612e6b565b73ffffffffffffffffffffffffffffffffffffffff9091166000908152601860209081526040808320938352929052205490565b3480156104e957600080fd5b506102916104f8366004613396565b611248565b34801561050957600080fd5b5061024e610518366004612e6b565b601760209081526000928352604080842090915290825290205481565b34801561054157600080fd5b5061024e610550366004613317565b6113ff565b34801561056157600080fd5b5061024e620186a081565b34801561057857600080fd5b50610291610587366004613073565b611431565b34801561059857600080fd5b5060135461024e565b3480156105ad57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061024e565b3480156105e057600080fd5b5061024e6105ef366004612e6b565b601660209081526000928352604080842090915290825290205481565b34801561061857600080fd5b5061062c610627366004613217565b611840565b60408051928352602083019190915201610225565b34801561064d57600080fd5b5061029161065c36600461334a565b611931565b34801561066d57600080fd5b5061029161067c366004613422565b611a39565b34801561068d57600080fd5b5061029161069c366004613491565b611b98565b3480156106ad57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061024e565b6102916106e2366004613519565b611d1e565b3480156106f357600080fd5b5061024e610702366004612e29565b60006020819052908152604090205481565b6013818154811061072457600080fd5b60009182526020909120600290910201805460019091015473ffffffffffffffffffffffffffffffffffffffff909116915082565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601560209081526040808320848452909152812054819061079c9060601c63ffffffff1690565b63ffffffff16905060005b6010811015610889578160011660010361082f5773ffffffffffffffffffffffffffffffffffffffff85166000908152601460209081526040808320878452909152902081601081106107fc576107fc613555565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250610870565b826003826010811061084357610843613555565b01546040805160208101939093528201526060016040516020818303038152906040528051906020012092505b60019190911c9080610881816135b3565b9150506107a7565b505092915050565b600061089d8a8a610759565b90506108c086868360208b01356108bb6108b68d6135eb565b611fea565b61202a565b80156108de57506108de83838360208801356108bb6108b68a6135eb565b610914576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b86604001358860405160200161092a91906136ba565b6040516020818303038152906040528051906020012014610977576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83602001358760200135600161098d91906136f8565b146109c4576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a0c886109d28680613710565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061208b92505050565b610a15886121e6565b836040013588604051602001610a2b91906136ba565b6040516020818303038152906040528051906020012003610a78576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8a1660009081526015602090815260408083208c8452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055610adc8a8a3361298e565b50505050505050505050565b6001610af660106002613897565b610b0091906138a3565b81565b6000610b0f8686612a47565b9050610b1c8360086136f8565b82101580610b2a5750602083115b15610b61576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b60608115610bf257610beb8686612af4565b9050610c2c565b85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050505b3360009081526014602090815260408083208b845290915280822081516102008101928390529160109082845b815481526020019060010190808311610c5957505050505090506000601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b81526020019081526020016000205490506000610cda8260601c63ffffffff1690565b63ffffffff169050333214610d1b576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d2b8260801c63ffffffff1690565b63ffffffff16600003610d6a576040517f87138d5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d748260c01c90565b67ffffffffffffffff1615610db5576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b898114610dee576040517f60f95d5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610dfb89898d8886612b6d565b83516020850160888204881415608883061715610e20576307b1daf16000526004601cfd5b60405160c8810160405260005b83811015610ed0578083018051835260208101516020840152604081015160408401526060810151606084015260808101516080840152508460888301526088810460051b8b013560a883015260c882206001860195508560005b610200811015610ec5576001821615610ea55782818b0152610ec5565b8981015160009081526020938452604090209260019290921c9101610e88565b505050608801610e2d565b50505050600160106002610ee49190613897565b610eee91906138a3565b811115610f27576040517f6229572300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f9c610f3a8360401c63ffffffff1690565b610f4a9063ffffffff168a6136f8565b60401b7fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff606084901b167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff8516171790565b915084156110295777ffffffffffffffffffffffffffffffffffffffffffffffff82164260c01b179150610fd68260801c63ffffffff1690565b63ffffffff16610fec8360401c63ffffffff1690565b63ffffffff1614611029576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526014602090815260408083208e8452909152902061104f90846010612d9f565b503360008181526018602090815260408083208f8452825280832080546001810182559084528284206004820401805460039092166008026101000a67ffffffffffffffff818102199093164390931602919091179055838352601582528083208f8452909152812084905560609190911b81523690601437366014016000a05050505050505050505050565b600381601081106110ec57600080fd5b0154905081565b6018602052826000526040600020602052816000526040600020818154811061111b57600080fd5b906000526020600020906004918282040191900660080292509250509054906101000a900467ffffffffffffffff1681565b60443560008060088301861061116b5763fe2549876000526004601cfd5b60c083901b60805260888386823786600882030151915060206000858360025afa90508061119857600080fd5b50600080517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0400000000000000000000000000000000000000000000000000000000000000178082526002602090815260408084208a8552825280842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558385528252808420998452988152888320939093558152908190529490942055505050565b600080603087600037602060006030600060025afa806112705763f91129696000526004601cfd5b6000517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f010000000000000000000000000000000000000000000000000000000000000017608081815260a08c905260c08b905260308a60e037603088609083013760008060c083600a5afa9250826112f2576309bde3396000526004601cfd5b602886106113085763fe2549876000526004601cfd5b6000602882015278200000000000000000000000000000000000000000000000008152600881018b905285810151935060308a8237603081019b909b52505060509098207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0500000000000000000000000000000000000000000000000000000000000000176000818152600260209081526040808320868452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209583529481528482209a909a559081528089529190912096909655505050505050565b6014602052826000526040600020602052816000526040600020816010811061142757600080fd5b0154925083915050565b73ffffffffffffffffffffffffffffffffffffffff891660009081526015602090815260408083208b845290915290205467ffffffffffffffff8116156114a4576040517fc334f06900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114ae8160c01c90565b67ffffffffffffffff166000036114f1576040517f55d4cbf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000061151c8260c01c90565b6115309067ffffffffffffffff16426138a3565b11611567576040517f55d4cbf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006115738b8b610759565b905061158c87878360208c01356108bb6108b68e6135eb565b80156115aa57506115aa84848360208901356108bb6108b68b6135eb565b6115e0576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8760400135896040516020016115f691906136ba565b6040516020818303038152906040528051906020012014611643576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84602001358860200135600161165991906136f8565b14158061168b575060016116738360601c63ffffffff1690565b61167d91906138ba565b63ffffffff16856020013514155b156116c2576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116d0896109d28780613710565b6116d9896121e6565b60006116e48a612cc0565b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0200000000000000000000000000000000000000000000000000000000000000179050600061173b8460a01c63ffffffff1690565b67ffffffffffffffff169050600160026000848152602001908152602001600020600083815260200190815260200160002060006101000a81548160ff021916908315150217905550601760008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008d8152602001908152602001600020546001600084815260200190815260200160002060008381526020019081526020016000208190555061180d8460801c63ffffffff1690565b600083815260208190526040902063ffffffff9190911690556118318d8d8161298e565b50505050505050505050505050565b6000828152600260209081526040808320848452909152812054819060ff166118c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546118e58160086136f8565b6118f08560206136f8565b1061190e57836119018260086136f8565b61190b91906138a3565b91505b506000938452600160209081526040808620948652939052919092205492909150565b60443560008060088301861061194f5763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b60008060008060808860601b81528760c01b6014820152858782601c0137601c860181207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0600000000000000000000000000000000000000000000000000000000000000179350604088026260216001603f5a021015611ac35763dd629f866000526004601cfd5b6000808783601c018c5afa94503d6001019150600882018a10611aee5763fe2549876000526004601cfd5b60c082901b81526008018481533d6000600183013e89017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8015160008481526002602090815260408083208d8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915587845282528083209c83529b81528b8220929092559384528390529790912096909655505050505050565b6000611ba48686610759565b9050611bbd83838360208801356108bb6108b68a6135eb565b611bf3576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602084013515611c2f576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c37612ddd565b611c45816109d28780613710565b611c4e816121e6565b846040013581604051602001611c6491906136ba565b6040516020818303038152906040528051906020012003611cb1576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166000908152601560209081526040808320898452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055611d1587873361298e565b50505050505050565b6703782dace9d90000341015611d60576040517fe92c469f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333214611d99576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611da48160086138df565b63ffffffff168263ffffffff1610611de8576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000008163ffffffff161015611e48576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152601560209081526040808320868452909152902054611e738160801c63ffffffff1690565b63ffffffff1615611eb0576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608082901b7fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff60a085901b167fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff83161717336000818152601560209081526040808320898452825280832094909455835180850185528381528082018981526013805460018101825590855291517f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a090600290930292830180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055517f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0919091015591815260168252828120968152959052909320349055505050565b600081600001518260200151836040015160405160200161200d93929190613907565b604051602081830303815290604052805190602001209050919050565b60008160005b601081101561207e578060051b880135600186831c16600181146120635760008481526020839052604090209350612074565b600082815260208590526040902093505b5050600101612030565b5090931495945050505050565b608881511461209957600080fd5b602081016020830161211a565b8260031b8201518060001a8160011a60081b178160021a60101b8260031a60181b17178160041a60201b8260051a60281b178260061a60301b8360071a60381b1717179050612114816120ff868560059190911b015190565b1867ffffffffffffffff16600586901b840152565b50505050565b612126600083836120a6565b612132600183836120a6565b61213e600283836120a6565b61214a600383836120a6565b612156600483836120a6565b612162600583836120a6565b61216e600683836120a6565b61217a600783836120a6565b612186600883836120a6565b612192600983836120a6565b61219e600a83836120a6565b6121aa600b83836120a6565b6121b6600c83836120a6565b6121c2600d83836120a6565b6121ce600e83836120a6565b6121da600f83836120a6565b612114601083836120a6565b6040805178010000000000008082800000000000808a8000000080008000602082015279808b00000000800000018000000080008081800000000000800991810191909152788a00000000000000880000000080008009000000008000000a60608201527b8000808b800000000000008b8000000000008089800000000000800360808201527f80000000000080028000000000000080000000000000800a800000008000000a60a08201527f800000008000808180000000000080800000000080000001800000008000800860c082015260009060e0016040516020818303038152906040529050602082016020820161286e565b6102808101516101e082015161014083015160a0840151845118189118186102a082015161020083015161016084015160c0850151602086015118189118186102c083015161022084015161018085015160e0860151604087015118189118186102e08401516102408501516101a0860151610100870151606088015118189118186103008501516102608601516101c0870151610120880151608089015118189118188084603f1c6123998660011b67ffffffffffffffff1690565b18188584603f1c6123b48660011b67ffffffffffffffff1690565b18188584603f1c6123cf8660011b67ffffffffffffffff1690565b181895508483603f1c6123ec8560011b67ffffffffffffffff1690565b181894508387603f1c6124098960011b67ffffffffffffffff1690565b60208b01518b51861867ffffffffffffffff168c5291189190911897508118600181901b603f9190911c18935060c08801518118601481901c602c9190911b1867ffffffffffffffff1660208901526101208801518718602c81901c60149190911b1867ffffffffffffffff1660c08901526102c08801518618600381901c603d9190911b1867ffffffffffffffff166101208901526101c08801518718601981901c60279190911b1867ffffffffffffffff166102c08901526102808801518218602e81901c60129190911b1867ffffffffffffffff166101c089015260408801518618600281901c603e9190911b1867ffffffffffffffff166102808901526101808801518618601581901c602b9190911b1867ffffffffffffffff1660408901526101a08801518518602781901c60199190911b1867ffffffffffffffff166101808901526102608801518718603881901c60089190911b1867ffffffffffffffff166101a08901526102e08801518518600881901c60389190911b1867ffffffffffffffff166102608901526101e08801518218601781901c60299190911b1867ffffffffffffffff166102e089015260808801518718602581901c601b9190911b1867ffffffffffffffff166101e08901526103008801518718603281901c600e9190911b1867ffffffffffffffff1660808901526102a08801518118603e81901c60029190911b1867ffffffffffffffff166103008901526101008801518518600981901c60379190911b1867ffffffffffffffff166102a08901526102008801518118601381901c602d9190911b1867ffffffffffffffff1661010089015260a08801518218601c81901c60249190911b1867ffffffffffffffff1661020089015260608801518518602481901c601c9190911b1867ffffffffffffffff1660a08901526102408801518518602b81901c60159190911b1867ffffffffffffffff1660608901526102208801518618603181901c600f9190911b1867ffffffffffffffff166102408901526101608801518118603681901c600a9190911b1867ffffffffffffffff166102208901525060e08701518518603a81901c60069190911b1867ffffffffffffffff166101608801526101408701518118603d81901c60039190911b1867ffffffffffffffff1660e0880152505067ffffffffffffffff81166101408601525b5050505050565b600582811b8201805160018501831b8401805160028701851b8601805160038901871b8801805160048b0190981b8901805167ffffffffffffffff861985168918811690995283198a16861889169096528819861683188816909352841986168818871690528419831684189095169052919391929190611d15565b612808600082612781565b612813600582612781565b61281e600a82612781565b612829600f82612781565b612834601482612781565b50565b612840816122dc565b612849816127fd565b600383901b820151815160c09190911c9061211490821867ffffffffffffffff168352565b61287a60008284612837565b61288660018284612837565b61289260028284612837565b61289e60038284612837565b6128aa60048284612837565b6128b660058284612837565b6128c260068284612837565b6128ce60078284612837565b6128da60088284612837565b6128e660098284612837565b6128f2600a8284612837565b6128fe600b8284612837565b61290a600c8284612837565b612916600d8284612837565b612922600e8284612837565b61292e600f8284612837565b61293a60108284612837565b61294660118284612837565b61295260128284612837565b61295e60138284612837565b61296a60148284612837565b61297660158284612837565b61298260168284612837565b61211460178284612837565b73ffffffffffffffffffffffffffffffffffffffff83811660009081526016602090815260408083208684529091528082208054908390559051909284169083908381818185875af1925050503d8060008114612a07576040519150601f19603f3d011682016040523d82523d6000602084013e612a0c565b606091505b505090508061277a576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831617612aed818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b6060604051905081602082018181018286833760888306808015612b3d5760888290038501848101848103803687375060806001820353506001845160001a1784538652612b54565b608836843760018353608060878401536088850186525b5050505050601f19603f82510116810160405292915050565b6000612b7f8260a01c63ffffffff1690565b67ffffffffffffffff1690506000612b9d8360801c63ffffffff1690565b63ffffffff1690506000612bb78460401c63ffffffff1690565b63ffffffff169050600883108015612bcd575080155b15612c015760c082901b6000908152883560085283513382526017602090815260408084208a855290915290912055612cb6565b60088310158015612c1f575080612c196008856138a3565b93508310155b8015612c335750612c3087826136f8565b83105b15612cb6576000612c4482856138a3565b905087612c528260206136f8565b10158015612c5e575085155b15612c95576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526017602090815260408083208a845290915290209089013590555b5050505050505050565b6000612d43565b66ff00ff00ff00ff8160081c1667ff00ff00ff00ff00612cf18360081b67ffffffffffffffff1690565b1617905065ffff0000ffff8160101c1667ffff0000ffff0000612d1e8360101b67ffffffffffffffff1690565b1617905060008160201c612d3c8360201b67ffffffffffffffff1690565b1792915050565b60808201516020830190612d5b90612cc7565b612cc7565b6040820151612d6990612cc7565b60401b17612d81612d5660018460059190911b015190565b825160809190911b90612d9390612cc7565b60c01b17179392505050565b8260108101928215612dcd579160200282015b82811115612dcd578251825591602001919060010190612db2565b50612dd9929150612df5565b5090565b6040518060200160405280612df0612e0a565b905290565b5b80821115612dd95760008155600101612df6565b6040518061032001604052806019906020820280368337509192915050565b600060208284031215612e3b57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612e6657600080fd5b919050565b60008060408385031215612e7e57600080fd5b612e8783612e42565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610320810167ffffffffffffffff81118282101715612ee857612ee8612e95565b60405290565b6040516060810167ffffffffffffffff81118282101715612ee857612ee8612e95565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612f5857612f58612e95565b604052919050565b803567ffffffffffffffff81168114612e6657600080fd5b6000610320808385031215612f8c57600080fd5b604051602080820182811067ffffffffffffffff82111715612fb057612fb0612e95565b806040525081935085601f860112612fc757600080fd5b612fcf612ec4565b928501928087851115612fe157600080fd5b865b8581101561300157612ff481612f60565b8352918301918301612fe3565b509092525091949350505050565b60006060828403121561302157600080fd5b50919050565b60008083601f84011261303957600080fd5b50813567ffffffffffffffff81111561305157600080fd5b6020830191508360208260051b850101111561306c57600080fd5b9250929050565b60008060008060008060008060006103e08a8c03121561309257600080fd5b61309b8a612e42565b985060208a013597506130b18b60408c01612f78565b96506103608a013567ffffffffffffffff808211156130cf57600080fd5b6130db8d838e0161300f565b97506103808c01359150808211156130f257600080fd5b6130fe8d838e01613027565b90975095506103a08c013591508082111561311857600080fd5b6131248d838e0161300f565b94506103c08c013591508082111561313b57600080fd5b506131488c828d01613027565b915080935050809150509295985092959850929598565b600080600080600060a0868803121561317757600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60005b838110156131b557818101518382015260200161319d565b838111156121145750506000910152565b60208152600082518060208401526131e581604085016020870161319a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000806040838503121561322a57600080fd5b50508035926020909101359150565b60008083601f84011261324b57600080fd5b50813567ffffffffffffffff81111561326357600080fd5b60208301915083602082850101111561306c57600080fd5b600080600080600080600060a0888a03121561329657600080fd5b8735965060208801359550604088013567ffffffffffffffff808211156132bc57600080fd5b6132c88b838c01613239565b909750955060608a01359150808211156132e157600080fd5b506132ee8a828b01613027565b9094509250506080880135801515811461330757600080fd5b8091505092959891949750929550565b60008060006060848603121561332c57600080fd5b61333584612e42565b95602085013595506040909401359392505050565b60008060006040848603121561335f57600080fd5b83359250602084013567ffffffffffffffff81111561337d57600080fd5b61338986828701613239565b9497909650939450505050565b600080600080600080600060a0888a0312156133b157600080fd5b8735965060208801359550604088013567ffffffffffffffff808211156133d757600080fd5b6133e38b838c01613239565b909750955060608a01359150808211156133fc57600080fd5b506134098a828b01613239565b989b979a50959894979596608090950135949350505050565b60008060008060006080868803121561343a57600080fd5b8535945061344a60208701612e42565b935061345860408701612f60565b9250606086013567ffffffffffffffff81111561347457600080fd5b61348088828901613239565b969995985093965092949392505050565b6000806000806000608086880312156134a957600080fd5b6134b286612e42565b945060208601359350604086013567ffffffffffffffff808211156134d657600080fd5b6134e289838a0161300f565b945060608801359150808211156134f857600080fd5b5061348088828901613027565b803563ffffffff81168114612e6657600080fd5b60008060006060848603121561352e57600080fd5b8335925061353e60208501613505565b915061354c60408501613505565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135e4576135e4613584565b5060010190565b6000606082360312156135fd57600080fd5b613605612eee565b823567ffffffffffffffff8082111561361d57600080fd5b9084019036601f83011261363057600080fd5b813560208282111561364457613644612e95565b613674817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011601612f11565b9250818352368183860101111561368a57600080fd5b81818501828501376000918301810191909152908352848101359083015250604092830135928101929092525090565b81516103208201908260005b60198110156136ef57825167ffffffffffffffff168252602092830192909101906001016136c6565b50505092915050565b6000821982111561370b5761370b613584565b500190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261374557600080fd5b83018035915067ffffffffffffffff82111561376057600080fd5b60200191503681900382131561306c57600080fd5b600181815b808511156137ce57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156137b4576137b4613584565b808516156137c157918102915b93841c939080029061377a565b509250929050565b6000826137e557506001613891565b816137f257506000613891565b816001811461380857600281146138125761382e565b6001915050613891565b60ff84111561382357613823613584565b50506001821b613891565b5060208310610133831016604e8410600b8410161715613851575081810a613891565b61385b8383613775565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561388d5761388d613584565b0290505b92915050565b6000612aed83836137d6565b6000828210156138b5576138b5613584565b500390565b600063ffffffff838116908316818110156138d7576138d7613584565b039392505050565b600063ffffffff8083168185168083038211156138fe576138fe613584565b01949350505050565b6000845161391981846020890161319a565b9190910192835250602082015260400191905056fea164736f6c634300080f000a00000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000000078", - "deployedCode": "0x6080604052600436106101d85760003560e01c80639d53a64811610102578063ddcd58de11610095578063ec5efcbc11610064578063ec5efcbc14610681578063f3f480d9146106a1578063faf37bc7146106d4578063fef2b4ed146106e757600080fd5b8063ddcd58de146105d4578063e03110e11461060c578063e159261114610641578063ea7139501461066157600080fd5b8063b5e7154c116100d1578063b5e7154c14610555578063d18534b51461056c578063da35c6641461058c578063dd24f9bf146105a157600080fd5b80639d53a6481461048e5780639d7e8769146104dd578063b2e67ba8146104fd578063b4801e611461053557600080fd5b806361238bde1161017a5780637ac54767116101495780637ac54767146103ca5780638542cf50146103ea578063882856ef146104355780638dc4be111461046e57600080fd5b806361238bde1461031e5780636551927b146103565780637051472e1461038e5780637917de1d146103aa57600080fd5b80633909af5c116101b65780633909af5c146102715780634d52b4c91461029357806352f0f3ad146102a857806354fd4d50146102c857600080fd5b8063013cf08b146101dd5780630359a5631461022e5780632055b36b1461025c575b600080fd5b3480156101e957600080fd5b506101fd6101f8366004612e29565b610714565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526020830191909152015b60405180910390f35b34801561023a57600080fd5b5061024e610249366004612e6b565b610759565b604051908152602001610225565b34801561026857600080fd5b5061024e601081565b34801561027d57600080fd5b5061029161028c366004613073565b610891565b005b34801561029f57600080fd5b5061024e610ae8565b3480156102b457600080fd5b5061024e6102c336600461315f565b610b03565b3480156102d457600080fd5b506103116040518060400160405280600a81526020017f312e312e322d72632e310000000000000000000000000000000000000000000081525081565b60405161022591906131c6565b34801561032a57600080fd5b5061024e610339366004613217565b600160209081526000928352604080842090915290825290205481565b34801561036257600080fd5b5061024e610371366004612e6b565b601560209081526000928352604080842090915290825290205481565b34801561039a57600080fd5b5061024e6703782dace9d9000081565b3480156103b657600080fd5b506102916103c536600461327b565b610bd9565b3480156103d657600080fd5b5061024e6103e5366004612e29565b6110dc565b3480156103f657600080fd5b50610425610405366004613217565b600260209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610225565b34801561044157600080fd5b50610455610450366004613317565b6110f3565b60405167ffffffffffffffff9091168152602001610225565b34801561047a57600080fd5b5061029161048936600461334a565b61114d565b34801561049a57600080fd5b5061024e6104a9366004612e6b565b73ffffffffffffffffffffffffffffffffffffffff9091166000908152601860209081526040808320938352929052205490565b3480156104e957600080fd5b506102916104f8366004613396565b611248565b34801561050957600080fd5b5061024e610518366004612e6b565b601760209081526000928352604080842090915290825290205481565b34801561054157600080fd5b5061024e610550366004613317565b6113ff565b34801561056157600080fd5b5061024e620186a081565b34801561057857600080fd5b50610291610587366004613073565b611431565b34801561059857600080fd5b5060135461024e565b3480156105ad57600080fd5b507f000000000000000000000000000000000000000000000000000000000000271061024e565b3480156105e057600080fd5b5061024e6105ef366004612e6b565b601660209081526000928352604080842090915290825290205481565b34801561061857600080fd5b5061062c610627366004613217565b611840565b60408051928352602083019190915201610225565b34801561064d57600080fd5b5061029161065c36600461334a565b611931565b34801561066d57600080fd5b5061029161067c366004613422565b611a39565b34801561068d57600080fd5b5061029161069c366004613491565b611b98565b3480156106ad57600080fd5b507f000000000000000000000000000000000000000000000000000000000000007861024e565b6102916106e2366004613519565b611d1e565b3480156106f357600080fd5b5061024e610702366004612e29565b60006020819052908152604090205481565b6013818154811061072457600080fd5b60009182526020909120600290910201805460019091015473ffffffffffffffffffffffffffffffffffffffff909116915082565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601560209081526040808320848452909152812054819061079c9060601c63ffffffff1690565b63ffffffff16905060005b6010811015610889578160011660010361082f5773ffffffffffffffffffffffffffffffffffffffff85166000908152601460209081526040808320878452909152902081601081106107fc576107fc613555565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250610870565b826003826010811061084357610843613555565b01546040805160208101939093528201526060016040516020818303038152906040528051906020012092505b60019190911c9080610881816135b3565b9150506107a7565b505092915050565b600061089d8a8a610759565b90506108c086868360208b01356108bb6108b68d6135eb565b611fea565b61202a565b80156108de57506108de83838360208801356108bb6108b68a6135eb565b610914576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b86604001358860405160200161092a91906136ba565b6040516020818303038152906040528051906020012014610977576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83602001358760200135600161098d91906136f8565b146109c4576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a0c886109d28680613710565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061208b92505050565b610a15886121e6565b836040013588604051602001610a2b91906136ba565b6040516020818303038152906040528051906020012003610a78576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8a1660009081526015602090815260408083208c8452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055610adc8a8a3361298e565b50505050505050505050565b6001610af660106002613897565b610b0091906138a3565b81565b6000610b0f8686612a47565b9050610b1c8360086136f8565b82101580610b2a5750602083115b15610b61576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b60608115610bf257610beb8686612af4565b9050610c2c565b85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050505b3360009081526014602090815260408083208b845290915280822081516102008101928390529160109082845b815481526020019060010190808311610c5957505050505090506000601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b81526020019081526020016000205490506000610cda8260601c63ffffffff1690565b63ffffffff169050333214610d1b576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d2b8260801c63ffffffff1690565b63ffffffff16600003610d6a576040517f87138d5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d748260c01c90565b67ffffffffffffffff1615610db5576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b898114610dee576040517f60f95d5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610dfb89898d8886612b6d565b83516020850160888204881415608883061715610e20576307b1daf16000526004601cfd5b60405160c8810160405260005b83811015610ed0578083018051835260208101516020840152604081015160408401526060810151606084015260808101516080840152508460888301526088810460051b8b013560a883015260c882206001860195508560005b610200811015610ec5576001821615610ea55782818b0152610ec5565b8981015160009081526020938452604090209260019290921c9101610e88565b505050608801610e2d565b50505050600160106002610ee49190613897565b610eee91906138a3565b811115610f27576040517f6229572300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f9c610f3a8360401c63ffffffff1690565b610f4a9063ffffffff168a6136f8565b60401b7fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff606084901b167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff8516171790565b915084156110295777ffffffffffffffffffffffffffffffffffffffffffffffff82164260c01b179150610fd68260801c63ffffffff1690565b63ffffffff16610fec8360401c63ffffffff1690565b63ffffffff1614611029576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526014602090815260408083208e8452909152902061104f90846010612d9f565b503360008181526018602090815260408083208f8452825280832080546001810182559084528284206004820401805460039092166008026101000a67ffffffffffffffff818102199093164390931602919091179055838352601582528083208f8452909152812084905560609190911b81523690601437366014016000a05050505050505050505050565b600381601081106110ec57600080fd5b0154905081565b6018602052826000526040600020602052816000526040600020818154811061111b57600080fd5b906000526020600020906004918282040191900660080292509250509054906101000a900467ffffffffffffffff1681565b60443560008060088301861061116b5763fe2549876000526004601cfd5b60c083901b60805260888386823786600882030151915060206000858360025afa90508061119857600080fd5b50600080517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0400000000000000000000000000000000000000000000000000000000000000178082526002602090815260408084208a8552825280842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558385528252808420998452988152888320939093558152908190529490942055505050565b600080603087600037602060006030600060025afa806112705763f91129696000526004601cfd5b6000517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f010000000000000000000000000000000000000000000000000000000000000017608081815260a08c905260c08b905260308a60e037603088609083013760008060c083600a5afa9250826112f2576309bde3396000526004601cfd5b602886106113085763fe2549876000526004601cfd5b6000602882015278200000000000000000000000000000000000000000000000008152600881018b905285810151935060308a8237603081019b909b52505060509098207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0500000000000000000000000000000000000000000000000000000000000000176000818152600260209081526040808320868452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209583529481528482209a909a559081528089529190912096909655505050505050565b6014602052826000526040600020602052816000526040600020816010811061142757600080fd5b0154925083915050565b73ffffffffffffffffffffffffffffffffffffffff891660009081526015602090815260408083208b845290915290205467ffffffffffffffff8116156114a4576040517fc334f06900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114ae8160c01c90565b67ffffffffffffffff166000036114f1576040517f55d4cbf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000007861151c8260c01c90565b6115309067ffffffffffffffff16426138a3565b11611567576040517f55d4cbf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006115738b8b610759565b905061158c87878360208c01356108bb6108b68e6135eb565b80156115aa57506115aa84848360208901356108bb6108b68b6135eb565b6115e0576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8760400135896040516020016115f691906136ba565b6040516020818303038152906040528051906020012014611643576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84602001358860200135600161165991906136f8565b14158061168b575060016116738360601c63ffffffff1690565b61167d91906138ba565b63ffffffff16856020013514155b156116c2576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116d0896109d28780613710565b6116d9896121e6565b60006116e48a612cc0565b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0200000000000000000000000000000000000000000000000000000000000000179050600061173b8460a01c63ffffffff1690565b67ffffffffffffffff169050600160026000848152602001908152602001600020600083815260200190815260200160002060006101000a81548160ff021916908315150217905550601760008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008d8152602001908152602001600020546001600084815260200190815260200160002060008381526020019081526020016000208190555061180d8460801c63ffffffff1690565b600083815260208190526040902063ffffffff9190911690556118318d8d8161298e565b50505050505050505050505050565b6000828152600260209081526040808320848452909152812054819060ff166118c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546118e58160086136f8565b6118f08560206136f8565b1061190e57836119018260086136f8565b61190b91906138a3565b91505b506000938452600160209081526040808620948652939052919092205492909150565b60443560008060088301861061194f5763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b60008060008060808860601b81528760c01b6014820152858782601c0137601c860181207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0600000000000000000000000000000000000000000000000000000000000000179350604088026260216001603f5a021015611ac35763dd629f866000526004601cfd5b6000808783601c018c5afa94503d6001019150600882018a10611aee5763fe2549876000526004601cfd5b60c082901b81526008018481533d6000600183013e89017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8015160008481526002602090815260408083208d8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915587845282528083209c83529b81528b8220929092559384528390529790912096909655505050505050565b6000611ba48686610759565b9050611bbd83838360208801356108bb6108b68a6135eb565b611bf3576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602084013515611c2f576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c37612ddd565b611c45816109d28780613710565b611c4e816121e6565b846040013581604051602001611c6491906136ba565b6040516020818303038152906040528051906020012003611cb1576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166000908152601560209081526040808320898452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055611d1587873361298e565b50505050505050565b6703782dace9d90000341015611d60576040517fe92c469f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333214611d99576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611da48160086138df565b63ffffffff168263ffffffff1610611de8576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000027108163ffffffff161015611e48576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152601560209081526040808320868452909152902054611e738160801c63ffffffff1690565b63ffffffff1615611eb0576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608082901b7fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff60a085901b167fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff83161717336000818152601560209081526040808320898452825280832094909455835180850185528381528082018981526013805460018101825590855291517f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a090600290930292830180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055517f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0919091015591815260168252828120968152959052909320349055505050565b600081600001518260200151836040015160405160200161200d93929190613907565b604051602081830303815290604052805190602001209050919050565b60008160005b601081101561207e578060051b880135600186831c16600181146120635760008481526020839052604090209350612074565b600082815260208590526040902093505b5050600101612030565b5090931495945050505050565b608881511461209957600080fd5b602081016020830161211a565b8260031b8201518060001a8160011a60081b178160021a60101b8260031a60181b17178160041a60201b8260051a60281b178260061a60301b8360071a60381b1717179050612114816120ff868560059190911b015190565b1867ffffffffffffffff16600586901b840152565b50505050565b612126600083836120a6565b612132600183836120a6565b61213e600283836120a6565b61214a600383836120a6565b612156600483836120a6565b612162600583836120a6565b61216e600683836120a6565b61217a600783836120a6565b612186600883836120a6565b612192600983836120a6565b61219e600a83836120a6565b6121aa600b83836120a6565b6121b6600c83836120a6565b6121c2600d83836120a6565b6121ce600e83836120a6565b6121da600f83836120a6565b612114601083836120a6565b6040805178010000000000008082800000000000808a8000000080008000602082015279808b00000000800000018000000080008081800000000000800991810191909152788a00000000000000880000000080008009000000008000000a60608201527b8000808b800000000000008b8000000000008089800000000000800360808201527f80000000000080028000000000000080000000000000800a800000008000000a60a08201527f800000008000808180000000000080800000000080000001800000008000800860c082015260009060e0016040516020818303038152906040529050602082016020820161286e565b6102808101516101e082015161014083015160a0840151845118189118186102a082015161020083015161016084015160c0850151602086015118189118186102c083015161022084015161018085015160e0860151604087015118189118186102e08401516102408501516101a0860151610100870151606088015118189118186103008501516102608601516101c0870151610120880151608089015118189118188084603f1c6123998660011b67ffffffffffffffff1690565b18188584603f1c6123b48660011b67ffffffffffffffff1690565b18188584603f1c6123cf8660011b67ffffffffffffffff1690565b181895508483603f1c6123ec8560011b67ffffffffffffffff1690565b181894508387603f1c6124098960011b67ffffffffffffffff1690565b60208b01518b51861867ffffffffffffffff168c5291189190911897508118600181901b603f9190911c18935060c08801518118601481901c602c9190911b1867ffffffffffffffff1660208901526101208801518718602c81901c60149190911b1867ffffffffffffffff1660c08901526102c08801518618600381901c603d9190911b1867ffffffffffffffff166101208901526101c08801518718601981901c60279190911b1867ffffffffffffffff166102c08901526102808801518218602e81901c60129190911b1867ffffffffffffffff166101c089015260408801518618600281901c603e9190911b1867ffffffffffffffff166102808901526101808801518618601581901c602b9190911b1867ffffffffffffffff1660408901526101a08801518518602781901c60199190911b1867ffffffffffffffff166101808901526102608801518718603881901c60089190911b1867ffffffffffffffff166101a08901526102e08801518518600881901c60389190911b1867ffffffffffffffff166102608901526101e08801518218601781901c60299190911b1867ffffffffffffffff166102e089015260808801518718602581901c601b9190911b1867ffffffffffffffff166101e08901526103008801518718603281901c600e9190911b1867ffffffffffffffff1660808901526102a08801518118603e81901c60029190911b1867ffffffffffffffff166103008901526101008801518518600981901c60379190911b1867ffffffffffffffff166102a08901526102008801518118601381901c602d9190911b1867ffffffffffffffff1661010089015260a08801518218601c81901c60249190911b1867ffffffffffffffff1661020089015260608801518518602481901c601c9190911b1867ffffffffffffffff1660a08901526102408801518518602b81901c60159190911b1867ffffffffffffffff1660608901526102208801518618603181901c600f9190911b1867ffffffffffffffff166102408901526101608801518118603681901c600a9190911b1867ffffffffffffffff166102208901525060e08701518518603a81901c60069190911b1867ffffffffffffffff166101608801526101408701518118603d81901c60039190911b1867ffffffffffffffff1660e0880152505067ffffffffffffffff81166101408601525b5050505050565b600582811b8201805160018501831b8401805160028701851b8601805160038901871b8801805160048b0190981b8901805167ffffffffffffffff861985168918811690995283198a16861889169096528819861683188816909352841986168818871690528419831684189095169052919391929190611d15565b612808600082612781565b612813600582612781565b61281e600a82612781565b612829600f82612781565b612834601482612781565b50565b612840816122dc565b612849816127fd565b600383901b820151815160c09190911c9061211490821867ffffffffffffffff168352565b61287a60008284612837565b61288660018284612837565b61289260028284612837565b61289e60038284612837565b6128aa60048284612837565b6128b660058284612837565b6128c260068284612837565b6128ce60078284612837565b6128da60088284612837565b6128e660098284612837565b6128f2600a8284612837565b6128fe600b8284612837565b61290a600c8284612837565b612916600d8284612837565b612922600e8284612837565b61292e600f8284612837565b61293a60108284612837565b61294660118284612837565b61295260128284612837565b61295e60138284612837565b61296a60148284612837565b61297660158284612837565b61298260168284612837565b61211460178284612837565b73ffffffffffffffffffffffffffffffffffffffff83811660009081526016602090815260408083208684529091528082208054908390559051909284169083908381818185875af1925050503d8060008114612a07576040519150601f19603f3d011682016040523d82523d6000602084013e612a0c565b606091505b505090508061277a576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831617612aed818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b6060604051905081602082018181018286833760888306808015612b3d5760888290038501848101848103803687375060806001820353506001845160001a1784538652612b54565b608836843760018353608060878401536088850186525b5050505050601f19603f82510116810160405292915050565b6000612b7f8260a01c63ffffffff1690565b67ffffffffffffffff1690506000612b9d8360801c63ffffffff1690565b63ffffffff1690506000612bb78460401c63ffffffff1690565b63ffffffff169050600883108015612bcd575080155b15612c015760c082901b6000908152883560085283513382526017602090815260408084208a855290915290912055612cb6565b60088310158015612c1f575080612c196008856138a3565b93508310155b8015612c335750612c3087826136f8565b83105b15612cb6576000612c4482856138a3565b905087612c528260206136f8565b10158015612c5e575085155b15612c95576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526017602090815260408083208a845290915290209089013590555b5050505050505050565b6000612d43565b66ff00ff00ff00ff8160081c1667ff00ff00ff00ff00612cf18360081b67ffffffffffffffff1690565b1617905065ffff0000ffff8160101c1667ffff0000ffff0000612d1e8360101b67ffffffffffffffff1690565b1617905060008160201c612d3c8360201b67ffffffffffffffff1690565b1792915050565b60808201516020830190612d5b90612cc7565b612cc7565b6040820151612d6990612cc7565b60401b17612d81612d5660018460059190911b015190565b825160809190911b90612d9390612cc7565b60c01b17179392505050565b8260108101928215612dcd579160200282015b82811115612dcd578251825591602001919060010190612db2565b50612dd9929150612df5565b5090565b6040518060200160405280612df0612e0a565b905290565b5b80821115612dd95760008155600101612df6565b6040518061032001604052806019906020820280368337509192915050565b600060208284031215612e3b57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612e6657600080fd5b919050565b60008060408385031215612e7e57600080fd5b612e8783612e42565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610320810167ffffffffffffffff81118282101715612ee857612ee8612e95565b60405290565b6040516060810167ffffffffffffffff81118282101715612ee857612ee8612e95565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612f5857612f58612e95565b604052919050565b803567ffffffffffffffff81168114612e6657600080fd5b6000610320808385031215612f8c57600080fd5b604051602080820182811067ffffffffffffffff82111715612fb057612fb0612e95565b806040525081935085601f860112612fc757600080fd5b612fcf612ec4565b928501928087851115612fe157600080fd5b865b8581101561300157612ff481612f60565b8352918301918301612fe3565b509092525091949350505050565b60006060828403121561302157600080fd5b50919050565b60008083601f84011261303957600080fd5b50813567ffffffffffffffff81111561305157600080fd5b6020830191508360208260051b850101111561306c57600080fd5b9250929050565b60008060008060008060008060006103e08a8c03121561309257600080fd5b61309b8a612e42565b985060208a013597506130b18b60408c01612f78565b96506103608a013567ffffffffffffffff808211156130cf57600080fd5b6130db8d838e0161300f565b97506103808c01359150808211156130f257600080fd5b6130fe8d838e01613027565b90975095506103a08c013591508082111561311857600080fd5b6131248d838e0161300f565b94506103c08c013591508082111561313b57600080fd5b506131488c828d01613027565b915080935050809150509295985092959850929598565b600080600080600060a0868803121561317757600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60005b838110156131b557818101518382015260200161319d565b838111156121145750506000910152565b60208152600082518060208401526131e581604085016020870161319a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000806040838503121561322a57600080fd5b50508035926020909101359150565b60008083601f84011261324b57600080fd5b50813567ffffffffffffffff81111561326357600080fd5b60208301915083602082850101111561306c57600080fd5b600080600080600080600060a0888a03121561329657600080fd5b8735965060208801359550604088013567ffffffffffffffff808211156132bc57600080fd5b6132c88b838c01613239565b909750955060608a01359150808211156132e157600080fd5b506132ee8a828b01613027565b9094509250506080880135801515811461330757600080fd5b8091505092959891949750929550565b60008060006060848603121561332c57600080fd5b61333584612e42565b95602085013595506040909401359392505050565b60008060006040848603121561335f57600080fd5b83359250602084013567ffffffffffffffff81111561337d57600080fd5b61338986828701613239565b9497909650939450505050565b600080600080600080600060a0888a0312156133b157600080fd5b8735965060208801359550604088013567ffffffffffffffff808211156133d757600080fd5b6133e38b838c01613239565b909750955060608a01359150808211156133fc57600080fd5b506134098a828b01613239565b989b979a50959894979596608090950135949350505050565b60008060008060006080868803121561343a57600080fd5b8535945061344a60208701612e42565b935061345860408701612f60565b9250606086013567ffffffffffffffff81111561347457600080fd5b61348088828901613239565b969995985093965092949392505050565b6000806000806000608086880312156134a957600080fd5b6134b286612e42565b945060208601359350604086013567ffffffffffffffff808211156134d657600080fd5b6134e289838a0161300f565b945060608801359150808211156134f857600080fd5b5061348088828901613027565b803563ffffffff81168114612e6657600080fd5b60008060006060848603121561352e57600080fd5b8335925061353e60208501613505565b915061354c60408501613505565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135e4576135e4613584565b5060010190565b6000606082360312156135fd57600080fd5b613605612eee565b823567ffffffffffffffff8082111561361d57600080fd5b9084019036601f83011261363057600080fd5b813560208282111561364457613644612e95565b613674817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011601612f11565b9250818352368183860101111561368a57600080fd5b81818501828501376000918301810191909152908352848101359083015250604092830135928101929092525090565b81516103208201908260005b60198110156136ef57825167ffffffffffffffff168252602092830192909101906001016136c6565b50505092915050565b6000821982111561370b5761370b613584565b500190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261374557600080fd5b83018035915067ffffffffffffffff82111561376057600080fd5b60200191503681900382131561306c57600080fd5b600181815b808511156137ce57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156137b4576137b4613584565b808516156137c157918102915b93841c939080029061377a565b509250929050565b6000826137e557506001613891565b816137f257506000613891565b816001811461380857600281146138125761382e565b6001915050613891565b60ff84111561382357613823613584565b50506001821b613891565b5060208310610133831016604e8410600b8410161715613851575081810a613891565b61385b8383613775565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561388d5761388d613584565b0290505b92915050565b6000612aed83836137d6565b6000828210156138b5576138b5613584565b500390565b600063ffffffff838116908316818110156138d7576138d7613584565b039392505050565b600063ffffffff8083168185168083038211156138fe576138fe613584565b01949350505050565b6000845161391981846020890161319a565b9190910192835250602082015260400191905056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": true, - "newValue": "0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5", - "previousValue": "0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5", - "previousValue": "0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": true, - "newValue": "0xb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0xb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30", - "previousValue": "0xb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0xb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30", - "previousValue": "0xb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": true, - "newValue": "0x21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000006" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0x21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85", - "previousValue": "0x21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000006" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0x21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85", - "previousValue": "0x21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000006" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": true, - "newValue": "0xe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000007" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0xe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344", - "previousValue": "0xe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000007" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0xe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344", - "previousValue": "0xe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000007" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": true, - "newValue": "0x0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000008" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0x0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d", - "previousValue": "0x0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000008" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0x0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d", - "previousValue": "0x0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000008" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": true, - "newValue": "0x887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000009" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0x887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968", - "previousValue": "0x887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000009" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0x887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968", - "previousValue": "0x887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000009" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": true, - "newValue": "0xffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000a" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0xffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83", - "previousValue": "0xffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000a" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0xffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83", - "previousValue": "0xffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000a" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": true, - "newValue": "0x9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000b" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0x9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af", - "previousValue": "0x9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000b" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0x9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af", - "previousValue": "0x9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000b" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": true, - "newValue": "0xcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000c" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0xcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0", - "previousValue": "0xcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000c" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0xcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0", - "previousValue": "0xcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000c" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": true, - "newValue": "0xf9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000d" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0xf9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5", - "previousValue": "0xf9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000d" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0xf9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5", - "previousValue": "0xf9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000d" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": true, - "newValue": "0xf8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000e" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0xf8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892", - "previousValue": "0xf8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000e" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0xf8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892", - "previousValue": "0xf8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000e" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": true, - "newValue": "0x3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000f" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0x3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c", - "previousValue": "0x3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000f" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0x3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c", - "previousValue": "0x3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000f" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": true, - "newValue": "0xc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000010" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0xc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb", - "previousValue": "0xc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000010" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0xc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb", - "previousValue": "0xc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000010" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": true, - "newValue": "0x5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000011" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0x5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc", - "previousValue": "0x5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000011" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": false, - "newValue": "0x5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc", - "previousValue": "0x5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000011" - }, - { - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "isWrite": true, - "newValue": "0xda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000012" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x638627e586f5e36fe67a77519503a7c6da22f92b150d3c6055fd40bdcfe9ffd160a060405234801561001057600080fd5b506040516200243a3803806200243a83398101604081905261003191610042565b6001600160a01b0316608052610072565b60006020828403121561005457600080fd5b81516001600160a01b038116811461006b57600080fd5b9392505050565b6080516123a6620000946000396000818160b201526106eb01526123a66000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d50146100465780637dc0d1d014610098578063e14ced32146100dc575b600080fd5b6100826040518060400160405280600a81526020017f312e312e302d72632e310000000000000000000000000000000000000000000081525081565b60405161008f91906121ee565b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260200161008f565b6100ef6100ea3660046122a3565b6100fd565b60405190815260200161008f565b6000610107612164565b6080811461011457600080fd5b6040516106001461012457600080fd5b6084871461013157600080fd5b6101a4851461013f57600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a0819052605a89013590911c6101c05260628801906101e09060018111156101f5576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b506020810181511461020657600080fd5b60200160005b602081101561023057823560e01c825260049092019160209091019060010161020c565b5050508061012001511561024e576102466103a6565b91505061039d565b6101408101805160010167ffffffffffffffff16905260006101a49050600080600061028385606001518660000151866104f7565b9250925092508163ffffffff1660001480156102a557508063ffffffff16600c145b156102bf576102b387610521565b9550505050505061039d565b6000610339866040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b6101608701518751919250610356918391906105248888886108f9565b8652805163ffffffff9081166060808901919091526020830151821660808901526040830151821660a08901528201511660c08701526103946103a6565b96505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a8401526000926102009290916062830191906001811115610453576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b60005b602081101561047a57601c8601518452602090950194600490930192600101610456565b506000835283830384a060009450806001811461049a57600395506104c2565b8280156104b257600181146104bb57600296506104c0565b600096506104c0565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b6000806000610507858786610cdf565b925050603f601a83901c8116915082165b93509350939050565b600061052b612164565b608090506000806000806105628561016001516040810151608082015160a083015160c084015160e0909401519294919390929091565b509350935093509350600080610ffa63ffffffff168663ffffffff16036105a75761059285858960e00151610d93565b63ffffffff1660e08a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03363ffffffff8716016105e05763400000009150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefe863ffffffff8716016106165760019150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef6a63ffffffff87160161066a57600161012088015260ff851661010088015261065d6103a6565b9998505050505050505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05d63ffffffff8716016107665760006040518061012001604052808763ffffffff1681526020018663ffffffff1681526020018563ffffffff16815260200189602001518152602001896040015163ffffffff1681526020018b81526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020016107386101a4600160ff16610380020190565b81528951602090910152905061074d81610e27565b8b5263ffffffff1660408b015290935091506108089050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05c63ffffffff8716016107cb57602087015160408801516107b1918791879187916105248d5161109f565b63ffffffff1660408b015260208a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff02963ffffffff871601610808576108028585611195565b90925090505b6000610882886040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b61016089015163ffffffff85811660408084019190915285821660e0909301929092526020830180518083168086526004909101831682526060808e01919091529051821660808d015291830151811660a08c0152908201511660c08a015290506108eb6103a6565b9a9950505050505050505050565b84600263ffffffff8416148061091557508263ffffffff166003145b156109675760006002856303ffffff1663ffffffff16901b896020015163f00000001617905061096189898663ffffffff1660021461095557601f610958565b60005b60ff168461124a565b50610cd4565b600080601f601087901c8116908a90601589901c166020811061098c5761098c612317565b602002015192508063ffffffff871615806109ad57508663ffffffff16601c145b156109df578a8263ffffffff16602081106109ca576109ca612317565b6020020151925050601f600b88901c16610a96565b60208763ffffffff161015610a41578663ffffffff16600c1480610a0957508663ffffffff16600d145b80610a1a57508663ffffffff16600e145b15610a2b578761ffff169250610a96565b610a3a8861ffff166010611322565b9250610a96565b60288763ffffffff16101580610a5d57508663ffffffff166022145b80610a6e57508663ffffffff166026145b15610a96578a8263ffffffff1660208110610a8b57610a8b612317565b602002015192508190505b60048763ffffffff1610158015610ab3575060088763ffffffff16105b80610ac457508663ffffffff166001145b15610ae057610ad78c8c898b8689611395565b50505050610cd4565b63ffffffff6000602089831610610b4557610b008a61ffff166010611322565b9095019463fffffffc8616610b168d828e610cdf565b915060288a63ffffffff1610158015610b3657508963ffffffff16603014155b15610b4357809250600093505b505b6000610b558b8b8b8a8a87611583565b63ffffffff1690508963ffffffff166000148015610b7a575060088963ffffffff1610155b8015610b8c5750601c8963ffffffff16105b15610c54578863ffffffff1660081480610bac57508863ffffffff166009145b15610bdf57610bd38f8f8b63ffffffff16600814610bca5786610bcd565b60005b8a61124a565b50505050505050610cd4565b8863ffffffff16600a03610c0157610bd38f8f868a63ffffffff8b1615611ca0565b8863ffffffff16600b03610c2457610bd38f8f868a63ffffffff8b161515611ca0565b60108963ffffffff1610158015610c415750601c8963ffffffff16105b15610c5457610bd38f8f8b8a8a89611d70565b8963ffffffff166038148015610c6f575063ffffffff851615155b15610c9f5760018e8663ffffffff1660208110610c8e57610c8e612317565b63ffffffff90921660209290920201525b8263ffffffff1663ffffffff14610cbe57610cbb838d83612029565b97505b610ccc8f8f86846001611ca0565b505050505050505b979650505050505050565b6000610cea826120cb565b6003831615610cf857600080fd5b6020820191358360051c8160005b601b811015610d5e5760208601953583821c6001168015610d2e5760018114610d4357610d54565b60008481526020839052604090209350610d54565b600082815260208590526040902093505b5050600101610d06565b50868114610d7457630badf00d60005260206000fd5b5050601f93909316601c0360031b9290921c63ffffffff169392505050565b6000808284610fff811615610dad57610fff811661100003015b8663ffffffff16600003610e195784935090810190636000000063ffffffff83161180610de557508463ffffffff168263ffffffff16105b80610dfb57508563ffffffff168163ffffffff16105b15610e14575063ffffffff925060169150839050610518565b610e1d565b8693505b5093509350939050565b6101008101516080820151825160009283929163ffffffff161561109857845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb01611052576000610e93866101000151876020015163fffffffc168860e00151610cdf565b606087015190915060001a600103610f1557610f0f86606001518760a0015160408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b60608701525b6000808760c0015173ffffffffffffffffffffffffffffffffffffffff1663e03110e189606001518a608001516040518363ffffffff1660e01b8152600401610f6e92919091825263ffffffff16602082015260400190565b6040805180830381865afa158015610f8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fae9190612346565b60208a015160408b01519294509092509060038216600481900384811015610fd4578094505b5083821015610fe1578193505b8460088502610100031c9450846008828660040303021b9450600180600883600403021b036001806008878560040303021b0391508119811690508581198816179650505061103f8a6020015163fffffffc168b60e0015187612029565b9298505050938601939250611098915050565b845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0161108c5784604001519350611098565b63ffffffff9350600992505b9193509193565b600080858563ffffffff8b16600114806110bf575063ffffffff8b166002145b806110d0575063ffffffff8b166004145b156110dd57889350611187565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8c160161117b57600061111d868c63fffffffc1689610cdf565b90508860038c166004038b81101561113357809b505b8b965086900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193880293841b0116911b17915060009050611187565b63ffffffff9350600992505b975097509750979350505050565b60008063ffffffff83166003036112385763ffffffff841615806111bf575063ffffffff84166005145b806111d0575063ffffffff84166003145b156111de5760009150611243565b63ffffffff8416600114806111f9575063ffffffff84166002145b8061120a575063ffffffff84166006145b8061121b575063ffffffff84166004145b156112295760019150611243565b5063ffffffff90506009611243565b5063ffffffff905060165b9250929050565b836000015160040163ffffffff16846020015163ffffffff16146112cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b835160208501805163ffffffff908116875283811690915283161561131b5780600801848463ffffffff166020811061130a5761130a612317565b63ffffffff90921660209290920201525b5050505050565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b018261137f576000611381565b815b90861663ffffffff16179250505092915050565b6000866000015160040163ffffffff16876020015163ffffffff1614611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f7400000000000000000000000060448201526064016112c6565b8463ffffffff166004148061143257508463ffffffff166005145b156114a9576000868463ffffffff166020811061145157611451612317565b602002015190508063ffffffff168363ffffffff1614801561147957508563ffffffff166004145b806114a157508063ffffffff168363ffffffff16141580156114a157508563ffffffff166005145b915050611526565b8463ffffffff166006036114c65760008260030b13159050611526565b8463ffffffff166007036114e25760008260030b139050611526565b8463ffffffff1660010361152657601f601085901c16600081900361150b5760008360030b1291505b8063ffffffff166001036115245760008360030b121591505b505b8651602088015163ffffffff168852811561156757600261154c8661ffff166010611322565b63ffffffff90811690911b8201600401166020890152611579565b60208801805160040163ffffffff1690525b5050505050505050565b600063ffffffff861615806115b0575060088663ffffffff16101580156115b05750600f8663ffffffff16105b156119b05785600881146115f357600981146115fc57600a811461160557600b811461160e57600c811461161757600d811461162057600e81146116295761162e565b6020955061162e565b6021955061162e565b602a955061162e565b602b955061162e565b6024955061162e565b6025955061162e565b602695505b508463ffffffff16600003611653575063ffffffff8216601f600688901c161b611c96565b8463ffffffff16600203611677575063ffffffff8216601f600688901c161c611c96565b8463ffffffff166003036116ab57601f600688901c166116a363ffffffff8516821c6020839003611322565b915050611c96565b8463ffffffff166004036116cb575063ffffffff8216601f84161b611c96565b8463ffffffff166006036116eb575063ffffffff8216601f84161c611c96565b8463ffffffff1660070361171357601f84166116a363ffffffff8516821c6020839003611322565b8463ffffffff16600803611728575082611c96565b8463ffffffff1660090361173d575082611c96565b8463ffffffff16600a03611752575082611c96565b8463ffffffff16600b03611767575082611c96565b8463ffffffff16600c0361177c575082611c96565b8463ffffffff16600f03611791575082611c96565b8463ffffffff166010036117a6575082611c96565b8463ffffffff166011036117bb575082611c96565b8463ffffffff166012036117d0575082611c96565b8463ffffffff166013036117e5575082611c96565b8463ffffffff166018036117fa575082611c96565b8463ffffffff1660190361180f575082611c96565b8463ffffffff16601a03611824575082611c96565b8463ffffffff16601b03611839575082611c96565b8463ffffffff166020036118505750828201611c96565b8463ffffffff166021036118675750828201611c96565b8463ffffffff1660220361187e5750818303611c96565b8463ffffffff166023036118955750818303611c96565b8463ffffffff166024036118ac5750828216611c96565b8463ffffffff166025036118c35750828217611c96565b8463ffffffff166026036118da5750828218611c96565b8463ffffffff166027036118f2575082821719611c96565b8463ffffffff16602a03611921578260030b8460030b12611914576000611917565b60015b60ff169050611c96565b8463ffffffff16602b03611949578263ffffffff168463ffffffff1610611914576000611917565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e0000000000000000000000000060448201526064016112c6565b611949565b8563ffffffff16601c03611a30578463ffffffff166002036119d55750828202611c96565b8463ffffffff16602014806119f057508463ffffffff166021145b156119ab578463ffffffff16602003611a07579219925b60005b6380000000851615611a29576401fffffffe600195861b169401611a0a565b9050611c96565b8563ffffffff16600f03611a51575065ffffffff0000601083901b16611c96565b8563ffffffff16602003611a8557611a298460031660080260180363ffffffff168363ffffffff16901c60ff166008611322565b8563ffffffff16602103611aba57611a298460021660080260100363ffffffff168363ffffffff16901c61ffff166010611322565b8563ffffffff16602203611ae8575063ffffffff60086003851602811681811b198416918316901b17611c96565b8563ffffffff16602303611afd575080611c96565b8563ffffffff16602403611b2e578360031660080260180363ffffffff168263ffffffff16901c60ff169050611c96565b8563ffffffff16602503611b60578360021660080260100363ffffffff168263ffffffff16901c61ffff169050611c96565b8563ffffffff16602603611b91575063ffffffff60086003851602601803811681811c198416918316901c17611c96565b8563ffffffff16602803611bc6575060ff63ffffffff60086003861602601803811682811b9091188316918416901b17611c96565b8563ffffffff16602903611bfc575061ffff63ffffffff60086002861602601003811682811b9091188316918416901b17611c96565b8563ffffffff16602a03611c2a575063ffffffff60086003851602811681811c198316918416901c17611c96565b8563ffffffff16602b03611c3f575081611c96565b8563ffffffff16602e03611c70575063ffffffff60086003851602601803811681811b198316918416901b17611c96565b8563ffffffff16603003611c85575080611c96565b8563ffffffff166038036119495750815b9695505050505050565b60208363ffffffff1610611d10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c696420726567697374657200000000000000000000000000000000000060448201526064016112c6565b63ffffffff831615801590611d225750805b15611d515781848463ffffffff1660208110611d4057611d40612317565b63ffffffff90921660209290920201525b5050505060208101805163ffffffff8082169093526004019091169052565b60008463ffffffff16601003611d8b57506060860151611fd1565b8463ffffffff16601103611daa5763ffffffff84166060880152611fd1565b8463ffffffff16601203611dc357506040860151611fd1565b8463ffffffff16601303611de25763ffffffff84166040880152611fd1565b8463ffffffff16601803611e165763ffffffff600385810b9085900b02602081901c821660608a0152166040880152611fd1565b8463ffffffff16601903611e475763ffffffff84811681851602602081901c821660608a0152166040880152611fd1565b8463ffffffff16601a03611f0a578260030b600003611ec2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8260030b8460030b81611ed757611ed761236a565b0763ffffffff166060880152600383810b9085900b81611ef957611ef961236a565b0563ffffffff166040880152611fd1565b8463ffffffff16601b03611fd1578263ffffffff16600003611f88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8263ffffffff168463ffffffff1681611fa357611fa361236a565b0663ffffffff908116606089015283811690851681611fc457611fc461236a565b0463ffffffff1660408801525b63ffffffff8216156120075780868363ffffffff1660208110611ff657611ff6612317565b63ffffffff90921660209290920201525b50505060208401805163ffffffff808216909652600401909416909352505050565b6000612034836120cb565b600384161561204257600080fd5b6020830192601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b8110156120c05760208601953582821c600116801561209057600181146120a5576120b6565b600085815260208390526040902094506120b6565b600082815260208690526040902094505b5050600101612068565b509095945050505050565b366103808201811015612160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f617461000000000000000000000000000000000000000000000000000000000060648201526084016112c6565b5050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915261016081016121ca6121cf565b905290565b6040518061040001604052806020906020820280368337509192915050565b600060208083528351808285015260005b8181101561221b578581018301518582016040015282016121ff565b8181111561222d576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60008083601f84011261227357600080fd5b50813567ffffffffffffffff81111561228b57600080fd5b60208301915083602082850101111561124357600080fd5b6000806000806000606086880312156122bb57600080fd5b853567ffffffffffffffff808211156122d357600080fd5b6122df89838a01612261565b909750955060208801359150808211156122f857600080fd5b5061230588828901612261565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561235957600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a000000000000000000000000373d916d11cce55b548f7051002e76bcfbd7a85d", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "account": "0x444e09fe6D839273316a87002aB0EFBeA6fe7806", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x60a060405234801561001057600080fd5b506040516200243a3803806200243a83398101604081905261003191610042565b6001600160a01b0316608052610072565b60006020828403121561005457600080fd5b81516001600160a01b038116811461006b57600080fd5b9392505050565b6080516123a6620000946000396000818160b201526106eb01526123a66000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d50146100465780637dc0d1d014610098578063e14ced32146100dc575b600080fd5b6100826040518060400160405280600a81526020017f312e312e302d72632e310000000000000000000000000000000000000000000081525081565b60405161008f91906121ee565b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260200161008f565b6100ef6100ea3660046122a3565b6100fd565b60405190815260200161008f565b6000610107612164565b6080811461011457600080fd5b6040516106001461012457600080fd5b6084871461013157600080fd5b6101a4851461013f57600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a0819052605a89013590911c6101c05260628801906101e09060018111156101f5576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b506020810181511461020657600080fd5b60200160005b602081101561023057823560e01c825260049092019160209091019060010161020c565b5050508061012001511561024e576102466103a6565b91505061039d565b6101408101805160010167ffffffffffffffff16905260006101a49050600080600061028385606001518660000151866104f7565b9250925092508163ffffffff1660001480156102a557508063ffffffff16600c145b156102bf576102b387610521565b9550505050505061039d565b6000610339866040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b6101608701518751919250610356918391906105248888886108f9565b8652805163ffffffff9081166060808901919091526020830151821660808901526040830151821660a08901528201511660c08701526103946103a6565b96505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a8401526000926102009290916062830191906001811115610453576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b60005b602081101561047a57601c8601518452602090950194600490930192600101610456565b506000835283830384a060009450806001811461049a57600395506104c2565b8280156104b257600181146104bb57600296506104c0565b600096506104c0565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b6000806000610507858786610cdf565b925050603f601a83901c8116915082165b93509350939050565b600061052b612164565b608090506000806000806105628561016001516040810151608082015160a083015160c084015160e0909401519294919390929091565b509350935093509350600080610ffa63ffffffff168663ffffffff16036105a75761059285858960e00151610d93565b63ffffffff1660e08a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03363ffffffff8716016105e05763400000009150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefe863ffffffff8716016106165760019150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef6a63ffffffff87160161066a57600161012088015260ff851661010088015261065d6103a6565b9998505050505050505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05d63ffffffff8716016107665760006040518061012001604052808763ffffffff1681526020018663ffffffff1681526020018563ffffffff16815260200189602001518152602001896040015163ffffffff1681526020018b81526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020016107386101a4600160ff16610380020190565b81528951602090910152905061074d81610e27565b8b5263ffffffff1660408b015290935091506108089050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05c63ffffffff8716016107cb57602087015160408801516107b1918791879187916105248d5161109f565b63ffffffff1660408b015260208a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff02963ffffffff871601610808576108028585611195565b90925090505b6000610882886040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b61016089015163ffffffff85811660408084019190915285821660e0909301929092526020830180518083168086526004909101831682526060808e01919091529051821660808d015291830151811660a08c0152908201511660c08a015290506108eb6103a6565b9a9950505050505050505050565b84600263ffffffff8416148061091557508263ffffffff166003145b156109675760006002856303ffffff1663ffffffff16901b896020015163f00000001617905061096189898663ffffffff1660021461095557601f610958565b60005b60ff168461124a565b50610cd4565b600080601f601087901c8116908a90601589901c166020811061098c5761098c612317565b602002015192508063ffffffff871615806109ad57508663ffffffff16601c145b156109df578a8263ffffffff16602081106109ca576109ca612317565b6020020151925050601f600b88901c16610a96565b60208763ffffffff161015610a41578663ffffffff16600c1480610a0957508663ffffffff16600d145b80610a1a57508663ffffffff16600e145b15610a2b578761ffff169250610a96565b610a3a8861ffff166010611322565b9250610a96565b60288763ffffffff16101580610a5d57508663ffffffff166022145b80610a6e57508663ffffffff166026145b15610a96578a8263ffffffff1660208110610a8b57610a8b612317565b602002015192508190505b60048763ffffffff1610158015610ab3575060088763ffffffff16105b80610ac457508663ffffffff166001145b15610ae057610ad78c8c898b8689611395565b50505050610cd4565b63ffffffff6000602089831610610b4557610b008a61ffff166010611322565b9095019463fffffffc8616610b168d828e610cdf565b915060288a63ffffffff1610158015610b3657508963ffffffff16603014155b15610b4357809250600093505b505b6000610b558b8b8b8a8a87611583565b63ffffffff1690508963ffffffff166000148015610b7a575060088963ffffffff1610155b8015610b8c5750601c8963ffffffff16105b15610c54578863ffffffff1660081480610bac57508863ffffffff166009145b15610bdf57610bd38f8f8b63ffffffff16600814610bca5786610bcd565b60005b8a61124a565b50505050505050610cd4565b8863ffffffff16600a03610c0157610bd38f8f868a63ffffffff8b1615611ca0565b8863ffffffff16600b03610c2457610bd38f8f868a63ffffffff8b161515611ca0565b60108963ffffffff1610158015610c415750601c8963ffffffff16105b15610c5457610bd38f8f8b8a8a89611d70565b8963ffffffff166038148015610c6f575063ffffffff851615155b15610c9f5760018e8663ffffffff1660208110610c8e57610c8e612317565b63ffffffff90921660209290920201525b8263ffffffff1663ffffffff14610cbe57610cbb838d83612029565b97505b610ccc8f8f86846001611ca0565b505050505050505b979650505050505050565b6000610cea826120cb565b6003831615610cf857600080fd5b6020820191358360051c8160005b601b811015610d5e5760208601953583821c6001168015610d2e5760018114610d4357610d54565b60008481526020839052604090209350610d54565b600082815260208590526040902093505b5050600101610d06565b50868114610d7457630badf00d60005260206000fd5b5050601f93909316601c0360031b9290921c63ffffffff169392505050565b6000808284610fff811615610dad57610fff811661100003015b8663ffffffff16600003610e195784935090810190636000000063ffffffff83161180610de557508463ffffffff168263ffffffff16105b80610dfb57508563ffffffff168163ffffffff16105b15610e14575063ffffffff925060169150839050610518565b610e1d565b8693505b5093509350939050565b6101008101516080820151825160009283929163ffffffff161561109857845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb01611052576000610e93866101000151876020015163fffffffc168860e00151610cdf565b606087015190915060001a600103610f1557610f0f86606001518760a0015160408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b60608701525b6000808760c0015173ffffffffffffffffffffffffffffffffffffffff1663e03110e189606001518a608001516040518363ffffffff1660e01b8152600401610f6e92919091825263ffffffff16602082015260400190565b6040805180830381865afa158015610f8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fae9190612346565b60208a015160408b01519294509092509060038216600481900384811015610fd4578094505b5083821015610fe1578193505b8460088502610100031c9450846008828660040303021b9450600180600883600403021b036001806008878560040303021b0391508119811690508581198816179650505061103f8a6020015163fffffffc168b60e0015187612029565b9298505050938601939250611098915050565b845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0161108c5784604001519350611098565b63ffffffff9350600992505b9193509193565b600080858563ffffffff8b16600114806110bf575063ffffffff8b166002145b806110d0575063ffffffff8b166004145b156110dd57889350611187565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8c160161117b57600061111d868c63fffffffc1689610cdf565b90508860038c166004038b81101561113357809b505b8b965086900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193880293841b0116911b17915060009050611187565b63ffffffff9350600992505b975097509750979350505050565b60008063ffffffff83166003036112385763ffffffff841615806111bf575063ffffffff84166005145b806111d0575063ffffffff84166003145b156111de5760009150611243565b63ffffffff8416600114806111f9575063ffffffff84166002145b8061120a575063ffffffff84166006145b8061121b575063ffffffff84166004145b156112295760019150611243565b5063ffffffff90506009611243565b5063ffffffff905060165b9250929050565b836000015160040163ffffffff16846020015163ffffffff16146112cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b835160208501805163ffffffff908116875283811690915283161561131b5780600801848463ffffffff166020811061130a5761130a612317565b63ffffffff90921660209290920201525b5050505050565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b018261137f576000611381565b815b90861663ffffffff16179250505092915050565b6000866000015160040163ffffffff16876020015163ffffffff1614611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f7400000000000000000000000060448201526064016112c6565b8463ffffffff166004148061143257508463ffffffff166005145b156114a9576000868463ffffffff166020811061145157611451612317565b602002015190508063ffffffff168363ffffffff1614801561147957508563ffffffff166004145b806114a157508063ffffffff168363ffffffff16141580156114a157508563ffffffff166005145b915050611526565b8463ffffffff166006036114c65760008260030b13159050611526565b8463ffffffff166007036114e25760008260030b139050611526565b8463ffffffff1660010361152657601f601085901c16600081900361150b5760008360030b1291505b8063ffffffff166001036115245760008360030b121591505b505b8651602088015163ffffffff168852811561156757600261154c8661ffff166010611322565b63ffffffff90811690911b8201600401166020890152611579565b60208801805160040163ffffffff1690525b5050505050505050565b600063ffffffff861615806115b0575060088663ffffffff16101580156115b05750600f8663ffffffff16105b156119b05785600881146115f357600981146115fc57600a811461160557600b811461160e57600c811461161757600d811461162057600e81146116295761162e565b6020955061162e565b6021955061162e565b602a955061162e565b602b955061162e565b6024955061162e565b6025955061162e565b602695505b508463ffffffff16600003611653575063ffffffff8216601f600688901c161b611c96565b8463ffffffff16600203611677575063ffffffff8216601f600688901c161c611c96565b8463ffffffff166003036116ab57601f600688901c166116a363ffffffff8516821c6020839003611322565b915050611c96565b8463ffffffff166004036116cb575063ffffffff8216601f84161b611c96565b8463ffffffff166006036116eb575063ffffffff8216601f84161c611c96565b8463ffffffff1660070361171357601f84166116a363ffffffff8516821c6020839003611322565b8463ffffffff16600803611728575082611c96565b8463ffffffff1660090361173d575082611c96565b8463ffffffff16600a03611752575082611c96565b8463ffffffff16600b03611767575082611c96565b8463ffffffff16600c0361177c575082611c96565b8463ffffffff16600f03611791575082611c96565b8463ffffffff166010036117a6575082611c96565b8463ffffffff166011036117bb575082611c96565b8463ffffffff166012036117d0575082611c96565b8463ffffffff166013036117e5575082611c96565b8463ffffffff166018036117fa575082611c96565b8463ffffffff1660190361180f575082611c96565b8463ffffffff16601a03611824575082611c96565b8463ffffffff16601b03611839575082611c96565b8463ffffffff166020036118505750828201611c96565b8463ffffffff166021036118675750828201611c96565b8463ffffffff1660220361187e5750818303611c96565b8463ffffffff166023036118955750818303611c96565b8463ffffffff166024036118ac5750828216611c96565b8463ffffffff166025036118c35750828217611c96565b8463ffffffff166026036118da5750828218611c96565b8463ffffffff166027036118f2575082821719611c96565b8463ffffffff16602a03611921578260030b8460030b12611914576000611917565b60015b60ff169050611c96565b8463ffffffff16602b03611949578263ffffffff168463ffffffff1610611914576000611917565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e0000000000000000000000000060448201526064016112c6565b611949565b8563ffffffff16601c03611a30578463ffffffff166002036119d55750828202611c96565b8463ffffffff16602014806119f057508463ffffffff166021145b156119ab578463ffffffff16602003611a07579219925b60005b6380000000851615611a29576401fffffffe600195861b169401611a0a565b9050611c96565b8563ffffffff16600f03611a51575065ffffffff0000601083901b16611c96565b8563ffffffff16602003611a8557611a298460031660080260180363ffffffff168363ffffffff16901c60ff166008611322565b8563ffffffff16602103611aba57611a298460021660080260100363ffffffff168363ffffffff16901c61ffff166010611322565b8563ffffffff16602203611ae8575063ffffffff60086003851602811681811b198416918316901b17611c96565b8563ffffffff16602303611afd575080611c96565b8563ffffffff16602403611b2e578360031660080260180363ffffffff168263ffffffff16901c60ff169050611c96565b8563ffffffff16602503611b60578360021660080260100363ffffffff168263ffffffff16901c61ffff169050611c96565b8563ffffffff16602603611b91575063ffffffff60086003851602601803811681811c198416918316901c17611c96565b8563ffffffff16602803611bc6575060ff63ffffffff60086003861602601803811682811b9091188316918416901b17611c96565b8563ffffffff16602903611bfc575061ffff63ffffffff60086002861602601003811682811b9091188316918416901b17611c96565b8563ffffffff16602a03611c2a575063ffffffff60086003851602811681811c198316918416901c17611c96565b8563ffffffff16602b03611c3f575081611c96565b8563ffffffff16602e03611c70575063ffffffff60086003851602601803811681811b198316918416901b17611c96565b8563ffffffff16603003611c85575080611c96565b8563ffffffff166038036119495750815b9695505050505050565b60208363ffffffff1610611d10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c696420726567697374657200000000000000000000000000000000000060448201526064016112c6565b63ffffffff831615801590611d225750805b15611d515781848463ffffffff1660208110611d4057611d40612317565b63ffffffff90921660209290920201525b5050505060208101805163ffffffff8082169093526004019091169052565b60008463ffffffff16601003611d8b57506060860151611fd1565b8463ffffffff16601103611daa5763ffffffff84166060880152611fd1565b8463ffffffff16601203611dc357506040860151611fd1565b8463ffffffff16601303611de25763ffffffff84166040880152611fd1565b8463ffffffff16601803611e165763ffffffff600385810b9085900b02602081901c821660608a0152166040880152611fd1565b8463ffffffff16601903611e475763ffffffff84811681851602602081901c821660608a0152166040880152611fd1565b8463ffffffff16601a03611f0a578260030b600003611ec2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8260030b8460030b81611ed757611ed761236a565b0763ffffffff166060880152600383810b9085900b81611ef957611ef961236a565b0563ffffffff166040880152611fd1565b8463ffffffff16601b03611fd1578263ffffffff16600003611f88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8263ffffffff168463ffffffff1681611fa357611fa361236a565b0663ffffffff908116606089015283811690851681611fc457611fc461236a565b0463ffffffff1660408801525b63ffffffff8216156120075780868363ffffffff1660208110611ff657611ff6612317565b63ffffffff90921660209290920201525b50505060208401805163ffffffff808216909652600401909416909352505050565b6000612034836120cb565b600384161561204257600080fd5b6020830192601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b8110156120c05760208601953582821c600116801561209057600181146120a5576120b6565b600085815260208390526040902094506120b6565b600082815260208690526040902094505b5050600101612068565b509095945050505050565b366103808201811015612160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f617461000000000000000000000000000000000000000000000000000000000060648201526084016112c6565b5050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915261016081016121ca6121cf565b905290565b6040518061040001604052806020906020820280368337509192915050565b600060208083528351808285015260005b8181101561221b578581018301518582016040015282016121ff565b8181111561222d576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60008083601f84011261227357600080fd5b50813567ffffffffffffffff81111561228b57600080fd5b60208301915083602082850101111561124357600080fd5b6000806000806000606086880312156122bb57600080fd5b853567ffffffffffffffff808211156122d357600080fd5b6122df89838a01612261565b909750955060208801359150808211156122f857600080fd5b5061230588828901612261565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561235957600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a000000000000000000000000373d916d11cce55b548f7051002e76bcfbd7a85d", - "deployedCode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d50146100465780637dc0d1d014610098578063e14ced32146100dc575b600080fd5b6100826040518060400160405280600a81526020017f312e312e302d72632e310000000000000000000000000000000000000000000081525081565b60405161008f91906121ee565b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000373d916d11cce55b548f7051002e76bcfbd7a85d16815260200161008f565b6100ef6100ea3660046122a3565b6100fd565b60405190815260200161008f565b6000610107612164565b6080811461011457600080fd5b6040516106001461012457600080fd5b6084871461013157600080fd5b6101a4851461013f57600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a0819052605a89013590911c6101c05260628801906101e09060018111156101f5576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b506020810181511461020657600080fd5b60200160005b602081101561023057823560e01c825260049092019160209091019060010161020c565b5050508061012001511561024e576102466103a6565b91505061039d565b6101408101805160010167ffffffffffffffff16905260006101a49050600080600061028385606001518660000151866104f7565b9250925092508163ffffffff1660001480156102a557508063ffffffff16600c145b156102bf576102b387610521565b9550505050505061039d565b6000610339866040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b6101608701518751919250610356918391906105248888886108f9565b8652805163ffffffff9081166060808901919091526020830151821660808901526040830151821660a08901528201511660c08701526103946103a6565b96505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a8401526000926102009290916062830191906001811115610453576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b60005b602081101561047a57601c8601518452602090950194600490930192600101610456565b506000835283830384a060009450806001811461049a57600395506104c2565b8280156104b257600181146104bb57600296506104c0565b600096506104c0565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b6000806000610507858786610cdf565b925050603f601a83901c8116915082165b93509350939050565b600061052b612164565b608090506000806000806105628561016001516040810151608082015160a083015160c084015160e0909401519294919390929091565b509350935093509350600080610ffa63ffffffff168663ffffffff16036105a75761059285858960e00151610d93565b63ffffffff1660e08a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03363ffffffff8716016105e05763400000009150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefe863ffffffff8716016106165760019150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef6a63ffffffff87160161066a57600161012088015260ff851661010088015261065d6103a6565b9998505050505050505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05d63ffffffff8716016107665760006040518061012001604052808763ffffffff1681526020018663ffffffff1681526020018563ffffffff16815260200189602001518152602001896040015163ffffffff1681526020018b81526020017f000000000000000000000000373d916d11cce55b548f7051002e76bcfbd7a85d73ffffffffffffffffffffffffffffffffffffffff1681526020016107386101a4600160ff16610380020190565b81528951602090910152905061074d81610e27565b8b5263ffffffff1660408b015290935091506108089050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05c63ffffffff8716016107cb57602087015160408801516107b1918791879187916105248d5161109f565b63ffffffff1660408b015260208a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff02963ffffffff871601610808576108028585611195565b90925090505b6000610882886040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b61016089015163ffffffff85811660408084019190915285821660e0909301929092526020830180518083168086526004909101831682526060808e01919091529051821660808d015291830151811660a08c0152908201511660c08a015290506108eb6103a6565b9a9950505050505050505050565b84600263ffffffff8416148061091557508263ffffffff166003145b156109675760006002856303ffffff1663ffffffff16901b896020015163f00000001617905061096189898663ffffffff1660021461095557601f610958565b60005b60ff168461124a565b50610cd4565b600080601f601087901c8116908a90601589901c166020811061098c5761098c612317565b602002015192508063ffffffff871615806109ad57508663ffffffff16601c145b156109df578a8263ffffffff16602081106109ca576109ca612317565b6020020151925050601f600b88901c16610a96565b60208763ffffffff161015610a41578663ffffffff16600c1480610a0957508663ffffffff16600d145b80610a1a57508663ffffffff16600e145b15610a2b578761ffff169250610a96565b610a3a8861ffff166010611322565b9250610a96565b60288763ffffffff16101580610a5d57508663ffffffff166022145b80610a6e57508663ffffffff166026145b15610a96578a8263ffffffff1660208110610a8b57610a8b612317565b602002015192508190505b60048763ffffffff1610158015610ab3575060088763ffffffff16105b80610ac457508663ffffffff166001145b15610ae057610ad78c8c898b8689611395565b50505050610cd4565b63ffffffff6000602089831610610b4557610b008a61ffff166010611322565b9095019463fffffffc8616610b168d828e610cdf565b915060288a63ffffffff1610158015610b3657508963ffffffff16603014155b15610b4357809250600093505b505b6000610b558b8b8b8a8a87611583565b63ffffffff1690508963ffffffff166000148015610b7a575060088963ffffffff1610155b8015610b8c5750601c8963ffffffff16105b15610c54578863ffffffff1660081480610bac57508863ffffffff166009145b15610bdf57610bd38f8f8b63ffffffff16600814610bca5786610bcd565b60005b8a61124a565b50505050505050610cd4565b8863ffffffff16600a03610c0157610bd38f8f868a63ffffffff8b1615611ca0565b8863ffffffff16600b03610c2457610bd38f8f868a63ffffffff8b161515611ca0565b60108963ffffffff1610158015610c415750601c8963ffffffff16105b15610c5457610bd38f8f8b8a8a89611d70565b8963ffffffff166038148015610c6f575063ffffffff851615155b15610c9f5760018e8663ffffffff1660208110610c8e57610c8e612317565b63ffffffff90921660209290920201525b8263ffffffff1663ffffffff14610cbe57610cbb838d83612029565b97505b610ccc8f8f86846001611ca0565b505050505050505b979650505050505050565b6000610cea826120cb565b6003831615610cf857600080fd5b6020820191358360051c8160005b601b811015610d5e5760208601953583821c6001168015610d2e5760018114610d4357610d54565b60008481526020839052604090209350610d54565b600082815260208590526040902093505b5050600101610d06565b50868114610d7457630badf00d60005260206000fd5b5050601f93909316601c0360031b9290921c63ffffffff169392505050565b6000808284610fff811615610dad57610fff811661100003015b8663ffffffff16600003610e195784935090810190636000000063ffffffff83161180610de557508463ffffffff168263ffffffff16105b80610dfb57508563ffffffff168163ffffffff16105b15610e14575063ffffffff925060169150839050610518565b610e1d565b8693505b5093509350939050565b6101008101516080820151825160009283929163ffffffff161561109857845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb01611052576000610e93866101000151876020015163fffffffc168860e00151610cdf565b606087015190915060001a600103610f1557610f0f86606001518760a0015160408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b60608701525b6000808760c0015173ffffffffffffffffffffffffffffffffffffffff1663e03110e189606001518a608001516040518363ffffffff1660e01b8152600401610f6e92919091825263ffffffff16602082015260400190565b6040805180830381865afa158015610f8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fae9190612346565b60208a015160408b01519294509092509060038216600481900384811015610fd4578094505b5083821015610fe1578193505b8460088502610100031c9450846008828660040303021b9450600180600883600403021b036001806008878560040303021b0391508119811690508581198816179650505061103f8a6020015163fffffffc168b60e0015187612029565b9298505050938601939250611098915050565b845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0161108c5784604001519350611098565b63ffffffff9350600992505b9193509193565b600080858563ffffffff8b16600114806110bf575063ffffffff8b166002145b806110d0575063ffffffff8b166004145b156110dd57889350611187565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8c160161117b57600061111d868c63fffffffc1689610cdf565b90508860038c166004038b81101561113357809b505b8b965086900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193880293841b0116911b17915060009050611187565b63ffffffff9350600992505b975097509750979350505050565b60008063ffffffff83166003036112385763ffffffff841615806111bf575063ffffffff84166005145b806111d0575063ffffffff84166003145b156111de5760009150611243565b63ffffffff8416600114806111f9575063ffffffff84166002145b8061120a575063ffffffff84166006145b8061121b575063ffffffff84166004145b156112295760019150611243565b5063ffffffff90506009611243565b5063ffffffff905060165b9250929050565b836000015160040163ffffffff16846020015163ffffffff16146112cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b835160208501805163ffffffff908116875283811690915283161561131b5780600801848463ffffffff166020811061130a5761130a612317565b63ffffffff90921660209290920201525b5050505050565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b018261137f576000611381565b815b90861663ffffffff16179250505092915050565b6000866000015160040163ffffffff16876020015163ffffffff1614611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f7400000000000000000000000060448201526064016112c6565b8463ffffffff166004148061143257508463ffffffff166005145b156114a9576000868463ffffffff166020811061145157611451612317565b602002015190508063ffffffff168363ffffffff1614801561147957508563ffffffff166004145b806114a157508063ffffffff168363ffffffff16141580156114a157508563ffffffff166005145b915050611526565b8463ffffffff166006036114c65760008260030b13159050611526565b8463ffffffff166007036114e25760008260030b139050611526565b8463ffffffff1660010361152657601f601085901c16600081900361150b5760008360030b1291505b8063ffffffff166001036115245760008360030b121591505b505b8651602088015163ffffffff168852811561156757600261154c8661ffff166010611322565b63ffffffff90811690911b8201600401166020890152611579565b60208801805160040163ffffffff1690525b5050505050505050565b600063ffffffff861615806115b0575060088663ffffffff16101580156115b05750600f8663ffffffff16105b156119b05785600881146115f357600981146115fc57600a811461160557600b811461160e57600c811461161757600d811461162057600e81146116295761162e565b6020955061162e565b6021955061162e565b602a955061162e565b602b955061162e565b6024955061162e565b6025955061162e565b602695505b508463ffffffff16600003611653575063ffffffff8216601f600688901c161b611c96565b8463ffffffff16600203611677575063ffffffff8216601f600688901c161c611c96565b8463ffffffff166003036116ab57601f600688901c166116a363ffffffff8516821c6020839003611322565b915050611c96565b8463ffffffff166004036116cb575063ffffffff8216601f84161b611c96565b8463ffffffff166006036116eb575063ffffffff8216601f84161c611c96565b8463ffffffff1660070361171357601f84166116a363ffffffff8516821c6020839003611322565b8463ffffffff16600803611728575082611c96565b8463ffffffff1660090361173d575082611c96565b8463ffffffff16600a03611752575082611c96565b8463ffffffff16600b03611767575082611c96565b8463ffffffff16600c0361177c575082611c96565b8463ffffffff16600f03611791575082611c96565b8463ffffffff166010036117a6575082611c96565b8463ffffffff166011036117bb575082611c96565b8463ffffffff166012036117d0575082611c96565b8463ffffffff166013036117e5575082611c96565b8463ffffffff166018036117fa575082611c96565b8463ffffffff1660190361180f575082611c96565b8463ffffffff16601a03611824575082611c96565b8463ffffffff16601b03611839575082611c96565b8463ffffffff166020036118505750828201611c96565b8463ffffffff166021036118675750828201611c96565b8463ffffffff1660220361187e5750818303611c96565b8463ffffffff166023036118955750818303611c96565b8463ffffffff166024036118ac5750828216611c96565b8463ffffffff166025036118c35750828217611c96565b8463ffffffff166026036118da5750828218611c96565b8463ffffffff166027036118f2575082821719611c96565b8463ffffffff16602a03611921578260030b8460030b12611914576000611917565b60015b60ff169050611c96565b8463ffffffff16602b03611949578263ffffffff168463ffffffff1610611914576000611917565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e0000000000000000000000000060448201526064016112c6565b611949565b8563ffffffff16601c03611a30578463ffffffff166002036119d55750828202611c96565b8463ffffffff16602014806119f057508463ffffffff166021145b156119ab578463ffffffff16602003611a07579219925b60005b6380000000851615611a29576401fffffffe600195861b169401611a0a565b9050611c96565b8563ffffffff16600f03611a51575065ffffffff0000601083901b16611c96565b8563ffffffff16602003611a8557611a298460031660080260180363ffffffff168363ffffffff16901c60ff166008611322565b8563ffffffff16602103611aba57611a298460021660080260100363ffffffff168363ffffffff16901c61ffff166010611322565b8563ffffffff16602203611ae8575063ffffffff60086003851602811681811b198416918316901b17611c96565b8563ffffffff16602303611afd575080611c96565b8563ffffffff16602403611b2e578360031660080260180363ffffffff168263ffffffff16901c60ff169050611c96565b8563ffffffff16602503611b60578360021660080260100363ffffffff168263ffffffff16901c61ffff169050611c96565b8563ffffffff16602603611b91575063ffffffff60086003851602601803811681811c198416918316901c17611c96565b8563ffffffff16602803611bc6575060ff63ffffffff60086003861602601803811682811b9091188316918416901b17611c96565b8563ffffffff16602903611bfc575061ffff63ffffffff60086002861602601003811682811b9091188316918416901b17611c96565b8563ffffffff16602a03611c2a575063ffffffff60086003851602811681811c198316918416901c17611c96565b8563ffffffff16602b03611c3f575081611c96565b8563ffffffff16602e03611c70575063ffffffff60086003851602601803811681811b198316918416901b17611c96565b8563ffffffff16603003611c85575080611c96565b8563ffffffff166038036119495750815b9695505050505050565b60208363ffffffff1610611d10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c696420726567697374657200000000000000000000000000000000000060448201526064016112c6565b63ffffffff831615801590611d225750805b15611d515781848463ffffffff1660208110611d4057611d40612317565b63ffffffff90921660209290920201525b5050505060208101805163ffffffff8082169093526004019091169052565b60008463ffffffff16601003611d8b57506060860151611fd1565b8463ffffffff16601103611daa5763ffffffff84166060880152611fd1565b8463ffffffff16601203611dc357506040860151611fd1565b8463ffffffff16601303611de25763ffffffff84166040880152611fd1565b8463ffffffff16601803611e165763ffffffff600385810b9085900b02602081901c821660608a0152166040880152611fd1565b8463ffffffff16601903611e475763ffffffff84811681851602602081901c821660608a0152166040880152611fd1565b8463ffffffff16601a03611f0a578260030b600003611ec2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8260030b8460030b81611ed757611ed761236a565b0763ffffffff166060880152600383810b9085900b81611ef957611ef961236a565b0563ffffffff166040880152611fd1565b8463ffffffff16601b03611fd1578263ffffffff16600003611f88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8263ffffffff168463ffffffff1681611fa357611fa361236a565b0663ffffffff908116606089015283811690851681611fc457611fc461236a565b0463ffffffff1660408801525b63ffffffff8216156120075780868363ffffffff1660208110611ff657611ff6612317565b63ffffffff90921660209290920201525b50505060208401805163ffffffff808216909652600401909416909352505050565b6000612034836120cb565b600384161561204257600080fd5b6020830192601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b8110156120c05760208601953582821c600116801561209057600181146120a5576120b6565b600085815260208390526040902094506120b6565b600082815260208690526040902094505b5050600101612068565b509095945050505050565b366103808201811015612160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f617461000000000000000000000000000000000000000000000000000000000060648201526084016112c6565b5050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915261016081016121ca6121cf565b905290565b6040518061040001604052806020906020820280368337509192915050565b600060208083528351808285015260005b8181101561221b578581018301518582016040015282016121ff565b8181111561222d576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60008083601f84011261227357600080fd5b50813567ffffffffffffffff81111561228b57600080fd5b60208301915083602082850101111561124357600080fd5b6000806000806000606086880312156122bb57600080fd5b853567ffffffffffffffff808211156122d357600080fd5b6122df89838a01612261565b909750955060208801359150808211156122f857600080fd5b5061230588828901612261565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561235957600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x638627e586f5e36fe67a77519503a7c6da22f92b150d3c6055fd40bdcfe9ffd160a060405234801561001057600080fd5b506040516111d73803806111d783398101604081905261002f9161010a565b6001600160a01b03811660805261004461004a565b5061013a565b600054610100900460ff16156100b65760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015610108576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b60006020828403121561011c57600080fd5b81516001600160a01b038116811461013357600080fd5b9392505050565b608051611074610163600039600081816101830152818161033c01526108f801526110746000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80635e05fbd01161005b5780635e05fbd01461012a5780637258a8071461013d578063838c2d1e14610179578063f2b4e6171461018157600080fd5b806317cf21a91461008257806335e80ab31461009757806354fd4d50146100e1575b600080fd5b610095610090366004610b4c565b6101a7565b005b6002546100b79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61011d6040518060400160405280600a81526020017f322e302e302d72632e310000000000000000000000000000000000000000000081525081565b6040516100d89190610bea565b610095610138366004610cc6565b61061c565b61016461014b366004610df0565b6001602081905260009182526040909120805491015482565b604080519283526020830191909152016100d8565b610095610853565b7f00000000000000000000000000000000000000000000000000000000000000006100b7565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610214573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102389190610e0d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461029c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156102ec573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526103329190810190610e2a565b92509250925060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161039793929190610efb565b6040805180830381865afa1580156103b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d79190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043f576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561048c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b09190610f9f565b60028111156104c1576104c1610f70565b146104f8576040517f8f8af25f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806105788773ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610551573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105759190610fc0565b90565b81526020018673ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ec9190610fc0565b905263ffffffff909416600090815260016020818152604090922086518155959091015194019390935550505050565b600054610100900460ff161580801561063c5750600054600160ff909116105b806106565750303b158015610656575060005460ff166001145b6106e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561074457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60005b83518110156107aa57600084828151811061076457610764610fd9565b60209081029190910181015180820151905163ffffffff1660009081526001808452604090912082518155919092015191015550806107a281611008565b915050610747565b50600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055801561084e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600033905060008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108a8573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526108ee9190810190610e2a565b92509250925060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161095393929190610efb565b6040805180830381865afa15801561096f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109939190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109fb576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160008563ffffffff1663ffffffff168152602001908152602001600020600101548573ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8d9190610fc0565b11610a99575050505050565b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ae6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0a9190610f9f565b6002811115610b1b57610b1b610f70565b146104f8575050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4957600080fd5b50565b600060208284031215610b5e57600080fd5b8135610b6981610b27565b9392505050565b60005b83811015610b8b578181015183820152602001610b73565b83811115610b9a576000848401525b50505050565b60008151808452610bb8816020860160208601610b70565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610b696020830184610ba0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610c4f57610c4f610bfd565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610c9c57610c9c610bfd565b604052919050565b63ffffffff81168114610b4957600080fd5b8035610cc181610b27565b919050565b6000806040808486031215610cda57600080fd5b833567ffffffffffffffff80821115610cf257600080fd5b818601915086601f830112610d0657600080fd5b8135602082821115610d1a57610d1a610bfd565b610d28818360051b01610c55565b8281528181019350606092830285018201928a841115610d4757600080fd5b948201945b83861015610dd457858b0381811215610d655760008081fd5b610d6d610c2c565b8735610d7881610ca4565b81527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201891315610daa5760008081fd5b610db2610c2c565b8886013581528989013586820152818601528652509485019493820193610d4c565b509650610de2888201610cb6565b955050505050509250929050565b600060208284031215610e0257600080fd5b8135610b6981610ca4565b600060208284031215610e1f57600080fd5b8151610b6981610b27565b600080600060608486031215610e3f57600080fd5b8351610e4a81610ca4565b60208501516040860151919450925067ffffffffffffffff80821115610e6f57600080fd5b818601915086601f830112610e8357600080fd5b815181811115610e9557610e95610bfd565b610ec660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610c55565b9150808252876020828501011115610edd57600080fd5b610eee816020840160208601610b70565b5080925050509250925092565b63ffffffff84168152826020820152606060408201526000610f206060830184610ba0565b95945050505050565b60008060408385031215610f3c57600080fd5b8251610f4781610b27565b602084015190925067ffffffffffffffff81168114610f6557600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060208284031215610fb157600080fd5b815160038110610b6957600080fd5b600060208284031215610fd257600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611060577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea164736f6c634300080f000a0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "account": "0x63B71B96756C693f7065345fecD9b7843b3e7C57", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x60a060405234801561001057600080fd5b506040516111d73803806111d783398101604081905261002f9161010a565b6001600160a01b03811660805261004461004a565b5061013a565b600054610100900460ff16156100b65760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015610108576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b60006020828403121561011c57600080fd5b81516001600160a01b038116811461013357600080fd5b9392505050565b608051611074610163600039600081816101830152818161033c01526108f801526110746000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80635e05fbd01161005b5780635e05fbd01461012a5780637258a8071461013d578063838c2d1e14610179578063f2b4e6171461018157600080fd5b806317cf21a91461008257806335e80ab31461009757806354fd4d50146100e1575b600080fd5b610095610090366004610b4c565b6101a7565b005b6002546100b79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61011d6040518060400160405280600a81526020017f322e302e302d72632e310000000000000000000000000000000000000000000081525081565b6040516100d89190610bea565b610095610138366004610cc6565b61061c565b61016461014b366004610df0565b6001602081905260009182526040909120805491015482565b604080519283526020830191909152016100d8565b610095610853565b7f00000000000000000000000000000000000000000000000000000000000000006100b7565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610214573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102389190610e0d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461029c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156102ec573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526103329190810190610e2a565b92509250925060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161039793929190610efb565b6040805180830381865afa1580156103b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d79190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043f576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561048c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b09190610f9f565b60028111156104c1576104c1610f70565b146104f8576040517f8f8af25f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806105788773ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610551573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105759190610fc0565b90565b81526020018673ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ec9190610fc0565b905263ffffffff909416600090815260016020818152604090922086518155959091015194019390935550505050565b600054610100900460ff161580801561063c5750600054600160ff909116105b806106565750303b158015610656575060005460ff166001145b6106e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561074457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60005b83518110156107aa57600084828151811061076457610764610fd9565b60209081029190910181015180820151905163ffffffff1660009081526001808452604090912082518155919092015191015550806107a281611008565b915050610747565b50600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055801561084e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600033905060008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108a8573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526108ee9190810190610e2a565b92509250925060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161095393929190610efb565b6040805180830381865afa15801561096f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109939190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109fb576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160008563ffffffff1663ffffffff168152602001908152602001600020600101548573ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8d9190610fc0565b11610a99575050505050565b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ae6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0a9190610f9f565b6002811115610b1b57610b1b610f70565b146104f8575050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4957600080fd5b50565b600060208284031215610b5e57600080fd5b8135610b6981610b27565b9392505050565b60005b83811015610b8b578181015183820152602001610b73565b83811115610b9a576000848401525b50505050565b60008151808452610bb8816020860160208601610b70565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610b696020830184610ba0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610c4f57610c4f610bfd565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610c9c57610c9c610bfd565b604052919050565b63ffffffff81168114610b4957600080fd5b8035610cc181610b27565b919050565b6000806040808486031215610cda57600080fd5b833567ffffffffffffffff80821115610cf257600080fd5b818601915086601f830112610d0657600080fd5b8135602082821115610d1a57610d1a610bfd565b610d28818360051b01610c55565b8281528181019350606092830285018201928a841115610d4757600080fd5b948201945b83861015610dd457858b0381811215610d655760008081fd5b610d6d610c2c565b8735610d7881610ca4565b81527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201891315610daa5760008081fd5b610db2610c2c565b8886013581528989013586820152818601528652509485019493820193610d4c565b509650610de2888201610cb6565b955050505050509250929050565b600060208284031215610e0257600080fd5b8135610b6981610ca4565b600060208284031215610e1f57600080fd5b8151610b6981610b27565b600080600060608486031215610e3f57600080fd5b8351610e4a81610ca4565b60208501516040860151919450925067ffffffffffffffff80821115610e6f57600080fd5b818601915086601f830112610e8357600080fd5b815181811115610e9557610e95610bfd565b610ec660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610c55565b9150808252876020828501011115610edd57600080fd5b610eee816020840160208601610b70565b5080925050509250925092565b63ffffffff84168152826020820152606060408201526000610f206060830184610ba0565b95945050505050565b60008060408385031215610f3c57600080fd5b8251610f4781610b27565b602084015190925067ffffffffffffffff81168114610f6557600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060208284031215610fb157600080fd5b815160038110610b6957600080fd5b600060208284031215610fd257600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611060577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea164736f6c634300080f000a0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d", - "deployedCode": "0x608060405234801561001057600080fd5b506004361061007d5760003560e01c80635e05fbd01161005b5780635e05fbd01461012a5780637258a8071461013d578063838c2d1e14610179578063f2b4e6171461018157600080fd5b806317cf21a91461008257806335e80ab31461009757806354fd4d50146100e1575b600080fd5b610095610090366004610b4c565b6101a7565b005b6002546100b79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61011d6040518060400160405280600a81526020017f322e302e302d72632e310000000000000000000000000000000000000000000081525081565b6040516100d89190610bea565b610095610138366004610cc6565b61061c565b61016461014b366004610df0565b6001602081905260009182526040909120805491015482565b604080519283526020830191909152016100d8565b610095610853565b7f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d6100b7565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610214573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102389190610e0d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461029c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156102ec573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526103329190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161039793929190610efb565b6040805180830381865afa1580156103b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d79190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043f576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561048c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b09190610f9f565b60028111156104c1576104c1610f70565b146104f8576040517f8f8af25f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806105788773ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610551573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105759190610fc0565b90565b81526020018673ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ec9190610fc0565b905263ffffffff909416600090815260016020818152604090922086518155959091015194019390935550505050565b600054610100900460ff161580801561063c5750600054600160ff909116105b806106565750303b158015610656575060005460ff166001145b6106e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561074457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60005b83518110156107aa57600084828151811061076457610764610fd9565b60209081029190910181015180820151905163ffffffff1660009081526001808452604090912082518155919092015191015550806107a281611008565b915050610747565b50600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055801561084e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600033905060008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108a8573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526108ee9190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161095393929190610efb565b6040805180830381865afa15801561096f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109939190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109fb576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160008563ffffffff1663ffffffff168152602001908152602001600020600101548573ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8d9190610fc0565b11610a99575050505050565b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ae6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0a9190610f9f565b6002811115610b1b57610b1b610f70565b146104f8575050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4957600080fd5b50565b600060208284031215610b5e57600080fd5b8135610b6981610b27565b9392505050565b60005b83811015610b8b578181015183820152602001610b73565b83811115610b9a576000848401525b50505050565b60008151808452610bb8816020860160208601610b70565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610b696020830184610ba0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610c4f57610c4f610bfd565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610c9c57610c9c610bfd565b604052919050565b63ffffffff81168114610b4957600080fd5b8035610cc181610b27565b919050565b6000806040808486031215610cda57600080fd5b833567ffffffffffffffff80821115610cf257600080fd5b818601915086601f830112610d0657600080fd5b8135602082821115610d1a57610d1a610bfd565b610d28818360051b01610c55565b8281528181019350606092830285018201928a841115610d4757600080fd5b948201945b83861015610dd457858b0381811215610d655760008081fd5b610d6d610c2c565b8735610d7881610ca4565b81527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201891315610daa5760008081fd5b610db2610c2c565b8886013581528989013586820152818601528652509485019493820193610d4c565b509650610de2888201610cb6565b955050505050509250929050565b600060208284031215610e0257600080fd5b8135610b6981610ca4565b600060208284031215610e1f57600080fd5b8151610b6981610b27565b600080600060608486031215610e3f57600080fd5b8351610e4a81610ca4565b60208501516040860151919450925067ffffffffffffffff80821115610e6f57600080fd5b818601915086601f830112610e8357600080fd5b815181811115610e9557610e95610bfd565b610ec660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610c55565b9150808252876020828501011115610edd57600080fd5b610eee816020840160208601610b70565b5080925050509250925092565b63ffffffff84168152826020820152606060408201526000610f206060830184610ba0565b95945050505050565b60008060408385031215610f3c57600080fd5b8251610f4781610b27565b602084015190925067ffffffffffffffff81168114610f6557600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060208284031215610fb157600080fd5b815160038110610b6957600080fd5b600060208284031215610fd257600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611060577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x63B71B96756C693f7065345fecD9b7843b3e7C57", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x63B71B96756C693f7065345fecD9b7843b3e7C57", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x63B71B96756C693f7065345fecD9b7843b3e7C57", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x63B71B96756C693f7065345fecD9b7843b3e7C57", - "isWrite": true, - "newValue": "0x00000000000000000000000000000000000000000000000000000000000000ff", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x434da94d", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000044" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000001049623609d0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4000000000000000000000000bdd90485fcbcac869d5b5752179815a3103d813100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b00000000000000000000000039af23e00f1e662025aa01b0ceda19542b78df990000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa60000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000001049623609d0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4000000000000000000000000bdd90485fcbcac869d5b5752179815a3103d813100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b00000000000000000000000039af23e00f1e662025aa01b0ceda19542b78df990000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa60000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000003", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" - } - ], - "value": 0 - }, - { - "accessor": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9623609d0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4000000000000000000000000bdd90485fcbcac869d5b5752179815a3103d813100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b00000000000000000000000039af23e00f1e662025aa01b0ceda19542b78df990000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa60000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab035100000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x727598a658f6983be3a9f29beef55aaee89ef8a176baeeacbe7edf5ff94a781b" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x4f1ef286000000000000000000000000bdd90485fcbcac869d5b5752179815a3103d813100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064c0c53b8b00000000000000000000000039af23e00f1e662025aa01b0ceda19542b78df990000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa60000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab035100000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": true, - "newValue": "0x000000000000000000000000bdd90485fcbcac869d5b5752179815a3103d8131", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xc0c53b8b00000000000000000000000039af23e00f1e662025aa01b0ceda19542b78df990000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa60000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000036" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": true, - "newValue": "0x00000000000000000000000039af23e00f1e662025aa01b0ceda19542b78df99", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000036" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000037" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": true, - "newValue": "0x0000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa6", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000037" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": true, - "newValue": "0x00000000000000000000004f559f30f5eb88d635fde1548c4267db8fab035100", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": true, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": true, - "newValue": "0x000000000000000100000000000000000000000000000000000000003b9aca00", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x000000000000000000000000bdd90485fcbcac869d5b5752179815a3103d8131", - "previousValue": "0x000000000000000000000000bdd90485fcbcac869d5b5752179815a3103d8131", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xfa60f9b2", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000f" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": false, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9b5f694a", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x000000000000000000000000bdd90485fcbcac869d5b5752179815a3103d8131", - "previousValue": "0x000000000000000000000000bdd90485fcbcac869d5b5752179815a3103d8131", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9b5f694a", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x00000000000000000000000039af23e00f1e662025aa01b0ceda19542b78df99", - "previousValue": "0x00000000000000000000000039af23e00f1e662025aa01b0ceda19542b78df99", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000036" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x33d7e2bd", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x000000000000000000000000bdd90485fcbcac869d5b5752179815a3103d8131", - "previousValue": "0x000000000000000000000000bdd90485fcbcac869d5b5752179815a3103d8131", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x33d7e2bd", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x0000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa6", - "previousValue": "0x0000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa6", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000037" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x452a9320", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x000000000000000000000000bdd90485fcbcac869d5b5752179815a3103d8131", - "previousValue": "0x000000000000000000000000bdd90485fcbcac869d5b5752179815a3103d8131", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x452a9320", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x00000000000000000000004f559f30f5eb88d635fde1548c4267db8fab035100", - "previousValue": "0x00000000000000000000004f559f30f5eb88d635fde1548c4267db8fab035100", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" - } - ], - "value": 0 - }, - { - "accessor": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x452a9320", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": false, - "newValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", - "previousValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "account": "0x068E44eB31e111028c41598E4535be7468674D0A", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x452a9320", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": false, - "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "reverted": false, - "slot": "0xd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe68" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x35e80ab3", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x000000000000000000000000bdd90485fcbcac869d5b5752179815a3103d8131", - "previousValue": "0x000000000000000000000000bdd90485fcbcac869d5b5752179815a3103d8131", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x35e80ab3", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x00000000000000000000004f559f30f5eb88d635fde1548c4267db8fab035100", - "previousValue": "0x00000000000000000000004f559f30f5eb88d635fde1548c4267db8fab035100", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x5c975abb", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": false, - "newValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", - "previousValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x068E44eB31e111028c41598E4535be7468674D0A", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x5c975abb", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b6" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x5c975abb", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x000000000000000000000000bdd90485fcbcac869d5b5752179815a3103d8131", - "previousValue": "0x000000000000000000000000bdd90485fcbcac869d5b5752179815a3103d8131", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x5c975abb", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x00000000000000000000004f559f30f5eb88d635fde1548c4267db8fab035100", - "previousValue": "0x00000000000000000000004f559f30f5eb88d635fde1548c4267db8fab035100", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" - } - ], - "value": 0 - }, - { - "accessor": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x5c975abb", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": false, - "newValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", - "previousValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "account": "0x068E44eB31e111028c41598E4535be7468674D0A", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x5c975abb", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b6" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9bf62d82", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x000000000000000000000000bdd90485fcbcac869d5b5752179815a3103d8131", - "previousValue": "0x000000000000000000000000bdd90485fcbcac869d5b5752179815a3103d8131", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xbdD90485FCbcac869D5b5752179815a3103d8131", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9bf62d82", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000dead", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x68ea2a43", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc", - "previousValue": "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000001c" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf77a09bd", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000004a" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xd2354f20", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000e" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xbfb14fb7", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000001000c5fc500000558", - "previousValue": "0x000000000000000000000000000000000000000000000001000c5fc500000558", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000031" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xec707517", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000001000c5fc500000558", - "previousValue": "0x000000000000000000000000000000000000000000000001000c5fc500000558", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000031" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x2dde36f5", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x00000000000000000000000000000000000000000000000000000000017d7840", - "previousValue": "0x00000000000000000000000000000000000000000000000000000000017d7840", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000030" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xe7d6cd42", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000001a" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9c16360f", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x000000000000000000000000ff00000000000000000000000000000000000000", - "previousValue": "0x000000000000000000000000ff00000000000000000000000000000000000000", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000001b" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004a000000000000000000000000000000000000000000000000000000000000003249623609d0000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa600000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000284db9040fa0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc000000000000000000000000000000000000000000000000000000000000055800000000000000000000000000000000000000000000000000000000000c5fc50000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc00000000000000000000000000000000000000000000000000000000017d78400000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc0000000000000000000000000000000000000000000000000000000001312d00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000ffffffffffffffffffffffffffffffff000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f000000000000000000000000d31598c909d9c935a9e35ba70d9a3dd47d4d586500000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4000000000000000000000000c7b87b2b892ea5c3cff47168881fe168c00377fb000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004a000000000000000000000000000000000000000000000000000000000000003249623609d0000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa600000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000284db9040fa0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc000000000000000000000000000000000000000000000000000000000000055800000000000000000000000000000000000000000000000000000000000c5fc50000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc00000000000000000000000000000000000000000000000000000000017d78400000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc0000000000000000000000000000000000000000000000000000000001312d00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000ffffffffffffffffffffffffffffffff000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f000000000000000000000000d31598c909d9c935a9e35ba70d9a3dd47d4d586500000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4000000000000000000000000c7b87b2b892ea5c3cff47168881fe168c00377fb000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000003", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000003", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000003", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000003", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000004", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000003", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" - } - ], - "value": 0 - }, - { - "accessor": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9623609d0000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa600000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000284db9040fa0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc000000000000000000000000000000000000000000000000000000000000055800000000000000000000000000000000000000000000000000000000000c5fc50000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc00000000000000000000000000000000000000000000000000000000017d78400000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc0000000000000000000000000000000000000000000000000000000001312d00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000ffffffffffffffffffffffffffffffff000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f000000000000000000000000d31598c909d9c935a9e35ba70d9a3dd47d4d586500000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4000000000000000000000000c7b87b2b892ea5c3cff47168881fe168c00377fb000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xa8f0d50211ac8ff1a40793a899dff3ced4762e0466f69b0078ab7b00d037835c" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x4f1ef28600000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000284db9040fa0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc000000000000000000000000000000000000000000000000000000000000055800000000000000000000000000000000000000000000000000000000000c5fc50000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc00000000000000000000000000000000000000000000000000000000017d78400000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc0000000000000000000000000000000000000000000000000000000001312d00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000ffffffffffffffffffffffffffffffff000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f000000000000000000000000d31598c909d9c935a9e35ba70d9a3dd47d4d586500000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4000000000000000000000000c7b87b2b892ea5c3cff47168881fe168c00377fb000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xdb9040fa0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc000000000000000000000000000000000000000000000000000000000000055800000000000000000000000000000000000000000000000000000000000c5fc50000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc00000000000000000000000000000000000000000000000000000000017d78400000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc0000000000000000000000000000000000000000000000000000000001312d00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000ffffffffffffffffffffffffffffffff000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f000000000000000000000000d31598c909d9c935a9e35ba70d9a3dd47d4d586500000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4000000000000000000000000c7b87b2b892ea5c3cff47168881fe168c00377fb000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000067" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x00000000000000000000000000000000000c5fc5000005580000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x010000000000000000000000000000000000000000000000000c5fc500000558", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000066" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000065" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000069" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000000000000000c5fc5000005580000000000000000", - "previousValue": "0x00000000000000000000000000000000000c5fc5000005580000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x00000000000000000000000000000000000c5fc50000055800000000017d7840", - "previousValue": "0x00000000000000000000000000000000000c5fc5000005580000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x000000000000000000000000ff00000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc597" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580636" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x000000000000000000000000d31598c909d9c935a9e35ba70d9a3dd47d4d5865", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a7" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6376" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa906" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ac" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x000000000000000000000000c7b87b2b892ea5c3cff47168881fe168c00377fb", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320c" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb19f" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb19f" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000000000000000c5fc50000055800000000017d7840", - "previousValue": "0x00000000000000000000000000000000000c5fc50000055800000000017d7840", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000069" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x0000ffffffffffffffffffffffffffffffff000f42403b9aca00080a01312d00", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000069" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000ffffffffffffffffffffffffffffffff000f42403b9aca00080a01312d00", - "previousValue": "0x0000ffffffffffffffffffffffffffffffff000f42403b9aca00080a01312d00", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000069" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "previousValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xcc731b02", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "previousValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xcc731b02", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000ffffffffffffffffffffffffffffffff000f42403b9aca00080a01312d00", - "previousValue": "0x0000ffffffffffffffffffffffffffffffff000f42403b9aca00080a01312d00", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000069" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xd2354f20", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000000e" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "previousValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xbfb14fb7", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000001000c5fc500000558", - "previousValue": "0x000000000000000000000000000000000000000000000001000c5fc500000558", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000031" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xbfb14fb7", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "previousValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xbfb14fb7", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000000000000000c5fc50000055800000000017d7840", - "previousValue": "0x00000000000000000000000000000000000c5fc50000055800000000017d7840", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xec707517", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000001000c5fc500000558", - "previousValue": "0x000000000000000000000000000000000000000000000001000c5fc500000558", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000031" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xec707517", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "previousValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xec707517", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000000000000000c5fc50000055800000000017d7840", - "previousValue": "0x00000000000000000000000000000000000c5fc50000055800000000017d7840", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x68ea2a43", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc", - "previousValue": "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000001c" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xe81b2c6d", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "previousValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xe81b2c6d", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc", - "previousValue": "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000067" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x2dde36f5", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x00000000000000000000000000000000000000000000000000000000017d7840", - "previousValue": "0x00000000000000000000000000000000000000000000000000000000017d7840", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000030" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf68016b7", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "previousValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf68016b7", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000000000000000c5fc50000055800000000017d7840", - "previousValue": "0x00000000000000000000000000000000000c5fc50000055800000000017d7840", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xe7d6cd42", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000001a" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x1fd19ee1", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "previousValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x1fd19ee1", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", - "reverted": false, - "slot": "0x65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf45e65d8", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "previousValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf45e65d8", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x010000000000000000000000000000000000000000000000000c5fc500000558", - "previousValue": "0x010000000000000000000000000000000000000000000000000c5fc500000558", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000066" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x102c9aa4", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000003e" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x48cd4cb1", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "previousValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x48cd4cb1", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0xa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb19f" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9c16360f", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x000000000000000000000000ff00000000000000000000000000000000000000", - "previousValue": "0x000000000000000000000000ff00000000000000000000000000000000000000", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000001b" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xdac6e63a", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "previousValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xdac6e63a", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x000000000000000000000000ff00000000000000000000000000000000000000", - "previousValue": "0x000000000000000000000000ff00000000000000000000000000000000000000", - "reverted": false, - "slot": "0x71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc597" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xa7119869", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "previousValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xa7119869", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f", - "previousValue": "0x000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f", - "reverted": false, - "slot": "0x383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580636" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xc4e8ddfa", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "previousValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xc4e8ddfa", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x000000000000000000000000d31598c909d9c935a9e35ba70d9a3dd47d4d5865", - "previousValue": "0x000000000000000000000000d31598c909d9c935a9e35ba70d9a3dd47d4d5865", - "reverted": false, - "slot": "0x46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a7" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x078f29cf", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "previousValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x078f29cf", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", - "previousValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", - "reverted": false, - "slot": "0x9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6376" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf2b4e617", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "previousValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf2b4e617", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d", - "previousValue": "0x0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d", - "reverted": false, - "slot": "0x52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa906" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x0a49cb03", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "previousValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x0a49cb03", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4", - "previousValue": "0x0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4", - "reverted": false, - "slot": "0x4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ac" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9b7d7f0a", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "previousValue": "0x00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x67866A5052E5302aaD08e9f352331fd8622eB6DC", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9b7d7f0a", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", - "isWrite": false, - "newValue": "0x000000000000000000000000c7b87b2b892ea5c3cff47168881fe168c00377fb", - "previousValue": "0x000000000000000000000000c7b87b2b892ea5c3cff47168881fe168c00377fb", - "reverted": false, - "slot": "0xa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320c" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6bd9f51600000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000448d52d4a000000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000448d52d4a000000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000004", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000004", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000004", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000004", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000005", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000004", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" - } - ], - "value": 0 - }, - { - "accessor": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8d52d4a000000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d0000000000000000000000000000000000000000000000000000000000000001", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6bd9f51600000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000001049623609d00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab03510000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000001049623609d00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab03510000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000005", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000005", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000005", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000005", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000006", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000005", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" - } - ], - "value": 0 - }, - { - "accessor": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9623609d00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab03510000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa600000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9b0b0fda360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": true, - "newValue": "0x000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xc0c53b8b000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab03510000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa6", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - } - ], - "value": 0 - }, - { - "accessor": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xb7947262", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "previousValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b", - "previousValue": "0x000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xc0c53b8b000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab03510000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa6", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - }, - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": true, - "newValue": "0x0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - }, - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": true, - "newValue": "0x0000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa6", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - }, - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": true, - "newValue": "0x000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - }, - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": true, - "newValue": "0x0000000000000000000000004200000000000000000000000000000000000010", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - } - ], - "value": 0 - }, - { - "accessor": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xb7947262", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "previousValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b", - "previousValue": "0x000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x927ede2d", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - } - ], - "value": 0 - }, - { - "accessor": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xb7947262", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "previousValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b", - "previousValue": "0x000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x927ede2d", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f", - "previousValue": "0x000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x3cb747bf", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - } - ], - "value": 0 - }, - { - "accessor": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xb7947262", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "previousValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b", - "previousValue": "0x000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x3cb747bf", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f", - "previousValue": "0x000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x7f46ddb2", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - } - ], - "value": 0 - }, - { - "accessor": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xb7947262", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "previousValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b", - "previousValue": "0x000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x7f46ddb2", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x0000000000000000000000004200000000000000000000000000000000000010", - "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000010", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xc89701a2", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - } - ], - "value": 0 - }, - { - "accessor": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xb7947262", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "previousValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b", - "previousValue": "0x000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xc89701a2", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x0000000000000000000000004200000000000000000000000000000000000010", - "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000010", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x35e80ab3", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - } - ], - "value": 0 - }, - { - "accessor": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xb7947262", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "previousValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b", - "previousValue": "0x000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x35e80ab3", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", - "isWrite": false, - "newValue": "0x0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "previousValue": "0x0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000e49623609d000000000000000000000000d31598c909d9c935a9e35ba70d9a3dd47d4d58650000000000000000000000005c4f5e749a61a9503c4aae8a9393e89609a0e80400000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc955000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000e49623609d000000000000000000000000d31598c909d9c935a9e35ba70d9a3dd47d4d58650000000000000000000000005c4f5e749a61a9503c4aae8a9393e89609a0e80400000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc955000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000006", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000006", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000006", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000006", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000007", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000006", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" - } - ], - "value": 0 - }, - { - "accessor": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9623609d000000000000000000000000d31598c909d9c935a9e35ba70d9a3dd47d4d58650000000000000000000000005c4f5e749a61a9503c4aae8a9393e89609a0e80400000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc955000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab035100000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x9ab6929e7d0104b9744ecf48c9c83f65e34bb9eb80c70a88b6b8885e3bf62b15" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x4f1ef2860000000000000000000000005c4f5e749a61a9503c4aae8a9393e89609a0e80400000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000044485cc955000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab035100000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": true, - "newValue": "0x0000000000000000000000005c4f5e749a61a9503c4aae8a9393e89609a0e804", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x485cc955000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - }, - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": true, - "newValue": "0x0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - }, - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": true, - "newValue": "0x000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" - }, - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": true, - "newValue": "0x0000000000000000000000004200000000000000000000000000000000000014", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" - }, - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x0000000000000000000000005c4f5e749a61a9503c4aae8a9393e89609a0e804", - "previousValue": "0x0000000000000000000000005c4f5e749a61a9503c4aae8a9393e89609a0e804", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x7f46ddb2", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x0000000000000000000000005c4f5e749a61a9503c4aae8a9393e89609a0e804", - "previousValue": "0x0000000000000000000000005c4f5e749a61a9503c4aae8a9393e89609a0e804", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x7f46ddb2", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x0000000000000000000000004200000000000000000000000000000000000014", - "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000014", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xc89701a2", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x0000000000000000000000005c4f5e749a61a9503c4aae8a9393e89609a0e804", - "previousValue": "0x0000000000000000000000005c4f5e749a61a9503c4aae8a9393e89609a0e804", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xc89701a2", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x0000000000000000000000004200000000000000000000000000000000000014", - "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000014", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x927ede2d", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x0000000000000000000000005c4f5e749a61a9503c4aae8a9393e89609a0e804", - "previousValue": "0x0000000000000000000000005c4f5e749a61a9503c4aae8a9393e89609a0e804", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x927ede2d", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f", - "previousValue": "0x000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x3cb747bf", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x0000000000000000000000005c4f5e749a61a9503c4aae8a9393e89609a0e804", - "previousValue": "0x0000000000000000000000005c4f5e749a61a9503c4aae8a9393e89609a0e804", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x3cb747bf", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f", - "previousValue": "0x000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x35e80ab3", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x0000000000000000000000005c4f5e749a61a9503c4aae8a9393e89609a0e804", - "previousValue": "0x0000000000000000000000005c4f5e749a61a9503c4aae8a9393e89609a0e804", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x35e80ab3", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865", - "isWrite": false, - "newValue": "0x0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "previousValue": "0x0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000c49623609d000000000000000000000000c7b87b2b892ea5c3cff47168881fe168c00377fb0000000000000000000000007c06d3a0a2f45e39e1798afbd9c3330971332a4f00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000024c4d66de800000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000c49623609d000000000000000000000000c7b87b2b892ea5c3cff47168881fe168c00377fb0000000000000000000000007c06d3a0a2f45e39e1798afbd9c3330971332a4f00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000024c4d66de800000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000007", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000007", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000007", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000007", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000008", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000007", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" - } - ], - "value": 0 - }, - { - "accessor": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9623609d000000000000000000000000c7b87b2b892ea5c3cff47168881fe168c00377fb0000000000000000000000007c06d3a0a2f45e39e1798afbd9c3330971332a4f00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000024c4d66de800000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d00000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xf6cecbacbfeb99e6ab0f02c22fd8a103f8837deb80af03d481ac5bc8d5475f58" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x4f1ef2860000000000000000000000007c06d3a0a2f45e39e1798afbd9c3330971332a4f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000024c4d66de800000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d00000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "isWrite": true, - "newValue": "0x0000000000000000000000007c06d3a0a2f45e39e1798afbd9c3330971332a4f", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xc4d66de800000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - { - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "isWrite": true, - "newValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - { - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "isWrite": false, - "newValue": "0x0000000000000000000000007c06d3a0a2f45e39e1798afbd9c3330971332a4f", - "previousValue": "0x0000000000000000000000007c06d3a0a2f45e39e1798afbd9c3330971332a4f", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xee9a31a2", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "isWrite": false, - "newValue": "0x0000000000000000000000007c06d3a0a2f45e39e1798afbd9c3330971332a4f", - "previousValue": "0x0000000000000000000000007c06d3a0a2f45e39e1798afbd9c3330971332a4f", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xee9a31a2", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "isWrite": false, - "newValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", - "previousValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xe78cea92", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "isWrite": false, - "newValue": "0x0000000000000000000000007c06d3a0a2f45e39e1798afbd9c3330971332a4f", - "previousValue": "0x0000000000000000000000007c06d3a0a2f45e39e1798afbd9c3330971332a4f", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xe78cea92", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xc7B87b2b892EA5C3CfF47168881FE168C00377FB", - "isWrite": false, - "newValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", - "previousValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6bd9f516000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x191cda7b5a8219e0cc3bb6c2b45be830e3ba520f78e119446a476c4147fcc284" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000448d52d4a0000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000448d52d4a0000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000008", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000008", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000008", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000008", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000009", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000008", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" - } - ], - "value": 0 - }, - { - "accessor": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8d52d4a0000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f0000000000000000000000000000000000000000000000000000000000000002", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x191cda7b5a8219e0cc3bb6c2b45be830e3ba520f78e119446a476c4147fcc284" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x191cda7b5a8219e0cc3bb6c2b45be830e3ba520f78e119446a476c4147fcc284" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6bd9f516000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "reverted": false, - "slot": "0x191cda7b5a8219e0cc3bb6c2b45be830e3ba520f78e119446a476c4147fcc284" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x238181ae000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xa90bdf0e44f0927a7a755fa7e7503fcc3da69ee33c69f36790fa0e0ef2db4745" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xa90bdf0e44f0927a7a755fa7e7503fcc3da69ee33c69f36790fa0e0ef2db4745" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000084860f7cda000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e6765720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000084860f7cda000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e6765720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000009", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000009", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000009", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000009", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000000a", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000009", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" - } - ], - "value": 0 - }, - { - "accessor": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x860f7cda000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x89a8cb4d9b6f179480a9e676431122d6ba6a5fb2aa9462528e7e48e497a5c045" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": true, - "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x89a8cb4d9b6f179480a9e676431122d6ba6a5fb2aa9462528e7e48e497a5c045" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x238181ae000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "reverted": false, - "slot": "0x89a8cb4d9b6f179480a9e676431122d6ba6a5fb2aa9462528e7e48e497a5c045" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "reverted": false, - "slot": "0x89a8cb4d9b6f179480a9e676431122d6ba6a5fb2aa9462528e7e48e497a5c045" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "reverted": false, - "slot": "0x89a8cb4d9b6f179480a9e676431122d6ba6a5fb2aa9462528e7e48e497a5c045" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000001049623609d000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab03510000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e40000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000001049623609d000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab03510000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e40000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000000a", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000000a", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000000a", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000000a", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000000b", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000000a", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" - } - ], - "value": 0 - }, - { - "accessor": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9623609d000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab03510000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e40000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa600000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "reverted": false, - "slot": "0x191cda7b5a8219e0cc3bb6c2b45be830e3ba520f78e119446a476c4147fcc284" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "reverted": false, - "slot": "0x191cda7b5a8219e0cc3bb6c2b45be830e3ba520f78e119446a476c4147fcc284" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "reverted": false, - "slot": "0x89a8cb4d9b6f179480a9e676431122d6ba6a5fb2aa9462528e7e48e497a5c045" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "reverted": false, - "slot": "0x89a8cb4d9b6f179480a9e676431122d6ba6a5fb2aa9462528e7e48e497a5c045" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "reverted": false, - "slot": "0x89a8cb4d9b6f179480a9e676431122d6ba6a5fb2aa9462528e7e48e497a5c045" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "previousValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9b2ea4bd0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e" - }, - { - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "isWrite": true, - "newValue": "0x000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xc0c53b8b0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab03510000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e40000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa6", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "previousValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "reverted": false, - "slot": "0x191cda7b5a8219e0cc3bb6c2b45be830e3ba520f78e119446a476c4147fcc284" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "reverted": false, - "slot": "0x6822ddba83a78589c753bb747cf4919773ec1d36eeb0bb2a09d64b6d87adda0b" - } - ], - "value": 0 - }, - { - "accessor": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xbf40fac10000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "isWrite": false, - "newValue": "0x000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b", - "previousValue": "0x000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b", - "reverted": false, - "slot": "0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xc0c53b8b0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab03510000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e40000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa6", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": true, - "newValue": "0x0000000000000000000000010000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x0000000000000000000000010000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000010000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": true, - "newValue": "0x0000000000000000000001010000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000010000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000fb" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": true, - "newValue": "0x0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000fb" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000fc" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": true, - "newValue": "0x0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000fc" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000fd" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": true, - "newValue": "0x0000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa6", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000fd" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x0000000000000000000001010000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000001010000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000cc" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000cc" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": true, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000cc" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000cf" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": true, - "newValue": "0x0000000000000000000000004200000000000000000000000000000000000007", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000cf" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x0000000000000000000001010000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000001010000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": true, - "newValue": "0x0000000000000000000000010000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000001010000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "previousValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "reverted": false, - "slot": "0x191cda7b5a8219e0cc3bb6c2b45be830e3ba520f78e119446a476c4147fcc284" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "reverted": false, - "slot": "0x6822ddba83a78589c753bb747cf4919773ec1d36eeb0bb2a09d64b6d87adda0b" - } - ], - "value": 0 - }, - { - "accessor": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xbf40fac10000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "isWrite": false, - "newValue": "0x000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b", - "previousValue": "0x000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b", - "reverted": false, - "slot": "0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9fce812c", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "previousValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "reverted": false, - "slot": "0x191cda7b5a8219e0cc3bb6c2b45be830e3ba520f78e119446a476c4147fcc284" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "reverted": false, - "slot": "0x6822ddba83a78589c753bb747cf4919773ec1d36eeb0bb2a09d64b6d87adda0b" - } - ], - "value": 0 - }, - { - "accessor": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xbf40fac10000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "isWrite": false, - "newValue": "0x000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b", - "previousValue": "0x000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b", - "reverted": false, - "slot": "0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9fce812c", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x0000000000000000000000004200000000000000000000000000000000000007", - "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000007", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000cf" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xdb505d80", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "previousValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "reverted": false, - "slot": "0x191cda7b5a8219e0cc3bb6c2b45be830e3ba520f78e119446a476c4147fcc284" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "reverted": false, - "slot": "0x6822ddba83a78589c753bb747cf4919773ec1d36eeb0bb2a09d64b6d87adda0b" - } - ], - "value": 0 - }, - { - "accessor": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xbf40fac10000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "isWrite": false, - "newValue": "0x000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b", - "previousValue": "0x000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b", - "reverted": false, - "slot": "0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xdb505d80", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x0000000000000000000000004200000000000000000000000000000000000007", - "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000007", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000cf" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x0ff754ea", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "previousValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "reverted": false, - "slot": "0x191cda7b5a8219e0cc3bb6c2b45be830e3ba520f78e119446a476c4147fcc284" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "reverted": false, - "slot": "0x6822ddba83a78589c753bb747cf4919773ec1d36eeb0bb2a09d64b6d87adda0b" - } - ], - "value": 0 - }, - { - "accessor": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xbf40fac10000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "isWrite": false, - "newValue": "0x000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b", - "previousValue": "0x000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b", - "reverted": false, - "slot": "0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x0ff754ea", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4", - "previousValue": "0x0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000fc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6425666b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "previousValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "reverted": false, - "slot": "0x191cda7b5a8219e0cc3bb6c2b45be830e3ba520f78e119446a476c4147fcc284" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "reverted": false, - "slot": "0x6822ddba83a78589c753bb747cf4919773ec1d36eeb0bb2a09d64b6d87adda0b" - } - ], - "value": 0 - }, - { - "accessor": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xbf40fac10000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "isWrite": false, - "newValue": "0x000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b", - "previousValue": "0x000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b", - "reverted": false, - "slot": "0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6425666b", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4", - "previousValue": "0x0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000fc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x35e80ab3", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "previousValue": "0x00000000000000000000000050eef481cae4250d252ae577a09bf514f224c6c4", - "reverted": false, - "slot": "0x191cda7b5a8219e0cc3bb6c2b45be830e3ba520f78e119446a476c4147fcc284" - }, - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", - "reverted": false, - "slot": "0x6822ddba83a78589c753bb747cf4919773ec1d36eeb0bb2a09d64b6d87adda0b" - } - ], - "value": 0 - }, - { - "accessor": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xbf40fac10000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x50EEf481cae4250d252Ae577A09bF514f224C6C4", - "isWrite": false, - "newValue": "0x000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b", - "previousValue": "0x000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b", - "reverted": false, - "slot": "0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x35e80ab3", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", - "isWrite": false, - "newValue": "0x0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "previousValue": "0x0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "reverted": false, - "slot": "0x00000000000000000000000000000000000000000000000000000000000000fb" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x276b657a", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000006", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000006", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000001d" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x93991af3", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000012" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x5d4546a0", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000001f" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x98f34df5", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000001e" - }, - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000001e" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x241e2d7e", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8", - "previousValue": "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000020" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x08cb822d", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63", - "previousValue": "0x0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000021" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xce5db8d6", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000024", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000024", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000022" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001849623609d00000000000000000000000039af23e00f1e662025aa01b0ceda19542b78df9900000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e41c89c97d000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c80000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b630000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001849623609d00000000000000000000000039af23e00f1e662025aa01b0ceda19542b78df9900000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e41c89c97d000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c80000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b630000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000000b", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000000b", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000000b", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000000b", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000000c", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000000b", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" - } - ], - "value": 0 - }, - { - "accessor": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9623609d00000000000000000000000039af23e00f1e662025aa01b0ceda19542b78df9900000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e41c89c97d000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c80000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x134d4d69ca1de3e4a1fde55b9ed577a7c39fd3329d50f2f437a3bff291bb9473" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x4f1ef28600000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e41c89c97d000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c80000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": true, - "newValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x1c89c97d000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c80000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b630000000000000000000000000000000000000000000000000000000000000024", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000006", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" - }, - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000007" - }, - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": true, - "newValue": "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000007" - }, - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000006" - }, - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": true, - "newValue": "0x0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000006" - }, - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000024", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000008" - }, - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "previousValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x98f34df5", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000001e" - }, - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000001e" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x276b657a", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000006", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000006", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000001d" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x529933df", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "previousValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x529933df", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000006", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000006", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x276b657a", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000006", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000006", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000001d" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xe1a41bcf", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "previousValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xe1a41bcf", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000006", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000006", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x93991af3", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000012" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x002134cc", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "previousValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x002134cc", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x93991af3", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000012" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x93991af3", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "previousValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x93991af3", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000002", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x241e2d7e", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8", - "previousValue": "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000020" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xbffa7f0f", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "previousValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xbffa7f0f", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8", - "previousValue": "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000007" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x241e2d7e", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8", - "previousValue": "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000020" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xa8e4fb90", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "previousValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xa8e4fb90", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8", - "previousValue": "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000007" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x08cb822d", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63", - "previousValue": "0x0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000021" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6b4d98dd", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "previousValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6b4d98dd", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63", - "previousValue": "0x0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000006" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x08cb822d", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63", - "previousValue": "0x0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000021" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x534db0e2", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "previousValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x534db0e2", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63", - "previousValue": "0x0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000006" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xce5db8d6", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000024", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000024", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000022" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf4daa291", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "previousValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf4daa291", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000024", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000024", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000008" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xce5db8d6", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000024", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000024", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000022" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xce5db8d6", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "previousValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xce5db8d6", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000024", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000024", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000008" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x5d4546a0", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000001f" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x70872aa5", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "previousValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x70872aa5", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x88786272", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "previousValue": "0x00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x88786272", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x39Af23E00F1e662025aA01b0cEdA19542B78DF99", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000c49623609d0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d00000000000000000000000020b168142354cee65a32f6d8cf3033e59229976500000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000024c4d66de80000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000c49623609d0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d00000000000000000000000020b168142354cee65a32f6d8cf3033e59229976500000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000024c4d66de80000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000000c", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000000c", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000000c", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000000c", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000000d", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000000c", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" - } - ], - "value": 0 - }, - { - "accessor": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9623609d0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d00000000000000000000000020b168142354cee65a32f6d8cf3033e59229976500000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000024c4d66de80000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x67ba7d8bdda390f76c7887f0749c8ddd97a5488c0685a6600f6146d45a37e9e3" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x4f1ef28600000000000000000000000020b168142354cee65a32f6d8cf3033e59229976500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000024c4d66de80000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": true, - "newValue": "0x00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xc4d66de80000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": true, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": true, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765", - "previousValue": "0x00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765", - "previousValue": "0x00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000e49623609d000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd920000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc0500000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc9550000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f380000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000e49623609d000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd920000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc0500000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc9550000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f380000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000000d", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000000d", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000000d", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000000d", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000000e", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000000d", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" - } - ], - "value": 0 - }, - { - "accessor": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9623609d000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd920000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc0500000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc9550000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f380000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab035100000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x6c22ba077ba2894f0240d58c3ef000efde161f39c3d967610259aa4c063ae31b" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x4f1ef2860000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc0500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000044485cc9550000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f380000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab035100000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": true, - "newValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x485cc9550000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f380000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": true, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": true, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - }, - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": true, - "newValue": "0x0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - }, - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "previousValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "previousValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x7a07653f", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000093a80", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000093a80", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000003b" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a42b8f8", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "previousValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a42b8f8", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x79502c55", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "previousValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x79502c55", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "previousValue": "0x0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000e49623609d000000000000000000000000d6eaf4c146261653ee059077b78ed088add543090000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc0500000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc9550000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f380000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000e49623609d000000000000000000000000d6eaf4c146261653ee059077b78ed088add543090000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc0500000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc9550000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f380000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000000e", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000000e", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000000e", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000000e", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000000f", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000000e", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" - } - ], - "value": 0 - }, - { - "accessor": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9623609d000000000000000000000000d6eaf4c146261653ee059077b78ed088add543090000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc0500000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc9550000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f380000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab035100000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xf08d105018e9af96f1d26510b09691f8b2194940cdd630ffcaf9fa37fb25c6a6" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x4f1ef2860000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc0500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000044485cc9550000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f380000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab035100000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": true, - "newValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x485cc9550000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f380000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": true, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": true, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - }, - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": true, - "newValue": "0x0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - }, - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": false, - "newValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "previousValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": false, - "newValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "previousValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x7a07653f", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000093a80", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000093a80", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000003b" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a42b8f8", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": false, - "newValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "previousValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a42b8f8", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x79502c55", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": false, - "newValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "previousValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x79502c55", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xd6EAF4c146261653EE059077B78ED088Add54309", - "isWrite": false, - "newValue": "0x0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "previousValue": "0x0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xb7033188", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", - "previousValue": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000036" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf0e5df46", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xb7033188", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", - "previousValue": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000036" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf0e5df46", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xb7033188", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", - "previousValue": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000036" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf0e5df46", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xb7033188", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", - "previousValue": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000036" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf0e5df46", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xb7033188", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", - "previousValue": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000036" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf0e5df46", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000002e49623609d000000000000000000000000970670459734a83899773a0fd45941b5afc1200e00000000000000000000000063b71b96756c693f7065345fecd9b7843b3e7c57000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002445e05fbd000000000000000000000000000000000000000000000000000000000000000400000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab035100000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fedeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a76120200000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000002e49623609d000000000000000000000000970670459734a83899773a0fd45941b5afc1200e00000000000000000000000063b71b96756c693f7065345fecd9b7843b3e7c57000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002445e05fbd000000000000000000000000000000000000000000000000000000000000000400000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab035100000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fedeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000000f", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000000f", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x000000000000000000000000000000000000000000000000000000000000000f", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000000f", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000010", - "previousValue": "0x000000000000000000000000000000000000000000000000000000000000000f", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" - }, - { - "account": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" - } - ], - "value": 0 - }, - { - "accessor": "0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD", - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9623609d000000000000000000000000970670459734a83899773a0fd45941b5afc1200e00000000000000000000000063b71b96756c693f7065345fecd9b7843b3e7c57000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002445e05fbd000000000000000000000000000000000000000000000000000000000000000400000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab035100000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fedeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x86458026e238c6fd356c082b2224f486dbd447ea5c3ff57e9610d5d6dedf4935" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x4f1ef28600000000000000000000000063b71b96756c693f7065345fecd9b7843b3e7c57000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002445e05fbd000000000000000000000000000000000000000000000000000000000000000400000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab035100000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fedeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": false, - "newValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "previousValue": "0x00000000000000000000000062c20aa1e0272312bc100b4e23b4dc1ed96dd7d1", - "reverted": false, - "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": true, - "newValue": "0x00000000000000000000000063b71b96756c693f7065345fecd9b7843b3e7c57", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1", - "account": "0x63B71B96756C693f7065345fecD9b7843b3e7C57", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x5e05fbd000000000000000000000000000000000000000000000000000000000000000400000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab035100000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fedeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef0000000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": true, - "newValue": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb4a" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": true, - "newValue": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b6887930" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": true, - "newValue": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x24a9e90595537a4321bf3a8fd43f02c179fe79a94dde54a8c1a057e2967a4d0b" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x24a9e90595537a4321bf3a8fd43f02c179fe79a94dde54a8c1a057e2967a4d0c" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": true, - "newValue": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xd9d16d34ffb15ba3a3d852f0d403e2ce1d691fb54de27ac87cd2f993f3ec330f" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xd9d16d34ffb15ba3a3d852f0d403e2ce1d691fb54de27ac87cd2f993f3ec3310" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": true, - "newValue": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x1d32deecea32fd1365d10df47fc6666a05871102e61a115a5c569bca7e5de14d" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x1d32deecea32fd1365d10df47fc6666a05871102e61a115a5c569bca7e5de14e" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": true, - "newValue": "0x0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": true, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x970670459734a83899773A0fd45941B5afC1200e", - "isWrite": false, - "newValue": "0x00000000000000000000000063b71b96756c693f7065345fecd9b7843b3e7c57", - "previousValue": "0x00000000000000000000000063b71b96756c693f7065345fecd9b7843b3e7c57", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x63B71B96756C693f7065345fecD9b7843b3e7C57", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x54fd4d50", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x935e3829", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000034" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x935e3829", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000034" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x0b7b1b30", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000008", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000008", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000037" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9110ec4a", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x00000000000000000000000000000000000000000000000000000000000004b0", - "previousValue": "0x00000000000000000000000000000000000000000000000000000000000004b0", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000003a" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x1b685b9e0000000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765", - "previousValue": "0x00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x1b685b9e0000000000000000000000000000000000000000000000000000000000000000", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xffdfc1249c027f9191656349feb0761381bb32c9f557e01f419fd08754bf5a1b" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xe1a05cc3", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000004", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000004", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000038" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xdb75b649", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000039" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xa2af0d1f", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000385", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000385", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000011" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xb6b1579AA54e2F61e621a40d5F2704D717B3544F", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6101c06040523480156200001257600080fd5b506040516200648a3803806200648a833981016040819052620000359162000436565b620000436001607e6200050d565b60ff168811156200006757604051633beff19960e11b815260040160405180910390fd5b600019871480620000845750876200008188600162000533565b10155b15620000a35760405163e62ccf3960e01b815260040160405180910390fd5b6002871015620000c65760405163e62ccf3960e01b815260040160405180910390fd5b6001600160401b038016846001600160a01b0316637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200010f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200013591906200054e565b6001600160a01b031663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000173573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200019991906200056e565b1115620001b95760405163b4e1243360e01b815260040160405180910390fd5b6000620001da876001600160401b0316620003e260201b62000c891760201c565b620001f0906001600160401b0316600262000588565b90506000856001600160a01b0316637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000233573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200025991906200054e565b6001600160a01b031663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000297573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002bd91906200056e565b620002dc896001600160401b0316620003e260201b62000c891760201c565b6001600160401b0316620002f1919062000533565b905060006200030c8383620003e560201b62003a261760201c565b90506001600160401b03811115620003375760405163235dfb2b60e21b815260040160405180910390fd5b62000356886001600160401b0316620003e260201b62000c891760201c565b6001600160401b0316816001600160401b03161115620003895760405163235dfb2b60e21b815260040160405180910390fd5b50505063ffffffff9099166101205260809790975260a09590955260c0939093526001600160401b039182166101a0521660e0526001600160a01b039081166101005290811661014052166101605261018052620005aa565b90565b600081831015620003f75781620003f9565b825b9392505050565b80516001600160401b03811681146200041857600080fd5b919050565b6001600160a01b03811681146200043357600080fd5b50565b6000806000806000806000806000806101408b8d0312156200045757600080fd5b8a5163ffffffff811681146200046c57600080fd5b809a505060208b0151985060408b0151975060608b015196506200049360808c0162000400565b9550620004a360a08c0162000400565b945060c08b0151620004b5816200041d565b60e08c0151909450620004c8816200041d565b6101008c0151909350620004dc816200041d565b809250506101208b015190509295989b9194979a5092959850565b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff8416808210156200052a576200052a620004f7565b90039392505050565b60008219821115620005495762000549620004f7565b500190565b6000602082840312156200056157600080fd5b8151620003f9816200041d565b6000602082840312156200058157600080fd5b5051919050565b6000816000190483118215151615620005a557620005a5620004f7565b500290565b60805160a05160c05160e05161010051610120516101405161016051610180516101a051615d5a62000730600039600081816106bb01528181611fbb015281816120260152612059015260008181610a1e01526139390152600081816106130152818161178a01526125e80152600081816105270152818161194c01528181612480015281816129ea0152613e1401526000818161088d015281816125a701526139c80152600081816104b401528181611eba015281816132420152613597015260008181610a7101528181610f6001528181611e2a01528181612089015281816120e801528181612bf60152612c38015260008181610aa401528181611c7301528181611d9901528181611ff7015281816130950152818161379601528181613f0b015281816146280152818161475601528181614857015261492c015260008181610b4b01528181611d3c01528181611e8e01528181612d0601528181612d8c01528181612f8b01526130b601526000818161078601526131540152615d5a6000f3fe6080604052600436106102f25760003560e01c806370872aa51161018f578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b18578063fa315aa914610b3c578063fe2bbeb214610b6f57600080fd5b8063ec5e630814610a95578063eff0f59214610ac8578063f8f43ff614610af857600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a0f578063d8cc1a3c14610a42578063dabd396d14610a6257600080fd5b8063c6f0308c14610937578063cf09e0d0146109c1578063d5d44d80146109e257600080fd5b80638d450a9511610143578063bcef3b551161011d578063bcef3b55146108b7578063bd8da956146108f7578063c395e1ca1461091757600080fd5b80638d450a9514610777578063a445ece6146107aa578063bbdc02db1461087657600080fd5b80638129fc1c116101745780638129fc1c1461071a5780638980e0cc146107225780638b85902b1461073757600080fd5b806370872aa5146106f25780637b0f0adc1461070757600080fd5b80633fc8cef3116102485780635c0cba33116101fc5780636361506d116101d65780636361506d1461066c5780636b6716c0146106ac5780636f034409146106df57600080fd5b80635c0cba3314610604578063609d33341461063757806360e274641461064c57600080fd5b806354fd4d501161022d57806354fd4d501461055e57806357da950e146105b45780635a5fa2d9146105e457600080fd5b80633fc8cef314610518578063472777c61461054b57600080fd5b80632810e1d6116102aa57806337b1b2291161028457806337b1b229146104655780633a768463146104a55780633e3ac912146104d857600080fd5b80632810e1d6146103de5780632ad69aeb146103f357806330dbe5701461041357600080fd5b806319effeb4116102db57806319effeb414610339578063200d2ed21461038457806325fc2ace146103bf57600080fd5b806301935130146102f757806303c2924d14610319575b600080fd5b34801561030357600080fd5b506103176103123660046154e2565b610b9f565b005b34801561032557600080fd5b5061031761033436600461553d565b610ec0565b34801561034557600080fd5b506000546103669068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561039057600080fd5b506000546103b290700100000000000000000000000000000000900460ff1681565b60405161037b919061558e565b3480156103cb57600080fd5b506008545b60405190815260200161037b565b3480156103ea57600080fd5b506103b2611566565b3480156103ff57600080fd5b506103d061040e36600461553d565b61180b565b34801561041f57600080fd5b506001546104409073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161037b565b34801561047157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610440565b3480156104b157600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610440565b3480156104e457600080fd5b50600054610508907201000000000000000000000000000000000000900460ff1681565b604051901515815260200161037b565b34801561052457600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610440565b6103176105593660046155cf565b611841565b34801561056a57600080fd5b506105a76040518060400160405280600a81526020017f312e332e302d72632e310000000000000000000000000000000000000000000081525081565b60405161037b9190615666565b3480156105c057600080fd5b506008546009546105cf919082565b6040805192835260208301919091520161037b565b3480156105f057600080fd5b506103d06105ff366004615679565b611853565b34801561061057600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610440565b34801561064357600080fd5b506105a761188d565b34801561065857600080fd5b506103176106673660046156b7565b61189b565b34801561067857600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103d0565b3480156106b857600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610366565b6103176106ed3660046156e9565b611a42565b3480156106fe57600080fd5b506009546103d0565b6103176107153660046155cf565b61251b565b610317612528565b34801561072e57600080fd5b506002546103d0565b34801561074357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103d0565b34801561078357600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103d0565b3480156107b657600080fd5b506108226107c5366004615679565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff16606082015260800161037b565b34801561088257600080fd5b5060405163ffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260200161037b565b3480156108c357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103d0565b34801561090357600080fd5b50610366610912366004615679565b612a81565b34801561092357600080fd5b506103d0610932366004615728565b612c60565b34801561094357600080fd5b50610957610952366004615679565b612e43565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e00161037b565b3480156109cd57600080fd5b506000546103669067ffffffffffffffff1681565b3480156109ee57600080fd5b506103d06109fd3660046156b7565b60036020526000908152604090205481565b348015610a1b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103d0565b348015610a4e57600080fd5b50610317610a5d36600461575a565b612eda565b348015610a6e57600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610366565b348015610aa157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103d0565b348015610ad457600080fd5b50610508610ae3366004615679565b60046020526000908152604090205460ff1681565b348015610b0457600080fd5b50610317610b133660046155cf565b613509565b348015610b2457600080fd5b50610b2d6139c6565b60405161037b939291906157e4565b348015610b4857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103d0565b348015610b7b57600080fd5b50610508610b8a366004615679565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610bcb57610bcb61555f565b14610c02576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610c55576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610ca3610c9e36869003860186615838565b613a41565b14610cda576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610cef9291906158c5565b604051809103902014610d2e576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d77610d7284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613a9d92505050565b613b0a565b90506000610d9e82600881518110610d9157610d916158d5565b6020026020010151613cc0565b9050602081511115610ddc576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610e51576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610eec57610eec61555f565b14610f23576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610f3857610f386158d5565b906000526020600020906005020190506000610f5384612a81565b905067ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081169082161015610fbc576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611005576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561102257508515155b156110bd578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110555781611071565b600186015473ffffffffffffffffffffffffffffffffffffffff165b905061107d8187613d74565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff166060830152611160576fffffffffffffffffffffffffffffffff6040820152600181526000869003611160578195505b600086826020015163ffffffff166111789190615933565b90506000838211611189578161118b565b835b602084015190915063ffffffff165b818110156112d75760008682815481106111b6576111b66158d5565b6000918252602080832090910154808352600690915260409091205490915060ff1661120e576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611223576112236158d5565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112805750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b156112c257600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b505080806112cf9061594b565b91505061119a565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921790915584900361155b57606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558915801561145757506000547201000000000000000000000000000000000000900460ff165b156114cc5760015473ffffffffffffffffffffffffffffffffffffffff1661147f818a613d74565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff909116178855611559565b61151373ffffffffffffffffffffffffffffffffffffffff8216156114f1578161150d565b600189015473ffffffffffffffffffffffffffffffffffffffff165b89613d74565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff1660028111156115945761159461555f565b146115cb576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff1661162f576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008154811061165b5761165b6158d5565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611696576001611699565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff9091161770010000000000000000000000000000000083600281111561174a5761174a61555f565b02179055600281111561175f5761175f61555f565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156117f057600080fd5b505af1158015611804573d6000803e3d6000fd5b5050505090565b6005602052816000526040600020818154811061182757600080fd5b90600052602060002001600091509150505481565b905090565b61184e8383836001611a42565b505050565b6000818152600760209081526040808320600590925282208054825461188490610100900463ffffffff1682615983565b95945050505050565b606061183c60546020613e75565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260036020526040812080549082905590819003611900576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063f3fef3a390604401600060405180830381600087803b15801561199057600080fd5b505af11580156119a4573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a02576040519150601f19603f3d011682016040523d82523d6000602084013e611a07565b606091505b505090508061184e576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008054700100000000000000000000000000000000900460ff166002811115611a6e57611a6e61555f565b14611aa5576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110611aba57611aba6158d5565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514611ba1576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000611c61826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580611c9c5750611c997f00000000000000000000000000000000000000000000000000000000000000006002615933565b81145b8015611ca6575084155b15611cdd576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015611d03575086155b15611d3a576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000811115611d94576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dbf7f00000000000000000000000000000000000000000000000000000000000000006001615933565b8103611dd157611dd186888588613ec7565b34611ddb83612c60565b14611e12576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611e1d88612a81565b905067ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811690821603611e85576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611eb260017f0000000000000000000000000000000000000000000000000000000000000000615983565b8303611ff0577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f47919061599a565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb591906159b7565b611fe9907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166159d0565b9050612083565b61201b60017f0000000000000000000000000000000000000000000000000000000000000000615983565b830361205657611fe97f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1660026159fc565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b6120b7817f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16615a2c565b67ffffffffffffffff166120d28367ffffffffffffffff1690565b67ffffffffffffffff16111561211957612116817f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16615a2c565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615612197576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c8152602001908152602001600020600160028054905061242d9190615983565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169263d0e30db09234926004808301939282900301818588803b1580156124c557600080fd5b505af11580156124d9573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b61184e8383836000611a42565b60005471010000000000000000000000000000000000900460ff161561257a576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690637258a807906024016040805180830381865afa15801561262e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126529190615a55565b90925090508161268e576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a146126c157639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401351161275b576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f00000000000000000000000000000000000000000000000000000000000000009092169363d0e30db093926004828101939282900301818588803b158015612a3057600080fd5b505af1158015612a44573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b600080600054700100000000000000000000000000000000900460ff166002811115612aaf57612aaf61555f565b14612ae6576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110612afb57612afb6158d5565b600091825260208220600590910201805490925063ffffffff90811614612b6a57815460028054909163ffffffff16908110612b3957612b396158d5565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090612ba290700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b612bb69067ffffffffffffffff1642615983565b612bd5612b95846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16612be99190615933565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001667ffffffffffffffff168167ffffffffffffffff1611612c365780611884565b7f000000000000000000000000000000000000000000000000000000000000000095945050505050565b600080612cff836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000000811115612d5e576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000612d798383615aa8565b9050670de0b6b3a76400006000612db0827f0000000000000000000000000000000000000000000000000000000000000000615abc565b90506000612dce612dc9670de0b6b3a764000086615abc565b614078565b90506000612ddc84846142d3565b90506000612dea8383614322565b90506000612df782614350565b90506000612e1682612e11670de0b6b3a76400008f615abc565b614538565b90506000612e248b83614322565b9050612e30818d615abc565b9f9e505050505050505050505050505050565b60028181548110612e5357600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b60008054700100000000000000000000000000000000900460ff166002811115612f0657612f0661555f565b14612f3d576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028781548110612f5257612f526158d5565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b9050612fb17f00000000000000000000000000000000000000000000000000000000000000006001615933565b61304d826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1614613087576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561317e576130da7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000615983565b6001901b6130f9846fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff166131159190615af9565b156131525761314961313a60016fffffffffffffffffffffffffffffffff8716615b0d565b865463ffffffff166000614608565b60030154613174565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506131a8565b600385015491506131a561313a6fffffffffffffffffffffffffffffffff86166001615b36565b90505b600882901b60088a8a6040516131bf9291906158c5565b6040518091039020901b14613200576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061320b8c6146ec565b9050600061321a836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e14ced3290613294908f908f908f908f908a90600401615baa565b6020604051808303816000875af11580156132b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d791906159b7565b600485015491149150600090600290613382906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b61341e896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6134289190615be4565b6134329190615c07565b60ff161590508115158103613473576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156134ca576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff1660028111156135355761353561555f565b1461356c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061357b8661471b565b9350935093509350600061359185858585614b24565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015613600573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613624919061599a565b90506001890361371c5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a84613680367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af11580156136f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061371691906159b7565b5061155b565b600289036137485773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8489613680565b600389036137745773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8487613680565b600489036138fb5760006137ba6fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000000614bde565b6009546137c79190615933565b6137d2906001615933565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061383b57367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036054013561383d565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156138d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f491906159b7565b505061155b565b60058903613994576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000000060c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016136d3565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060613a1f61188d565b9050909192565b600081831015613a365781613a38565b825b90505b92915050565b60008160000151826020015183604001518460600151604051602001613a80949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003613aec576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000613b1a85614c8c565b919450925090506001816001811115613b3557613b3561555f565b14613b6c576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451613b788385615933565b14613baf576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081613bc65790505093506000835b8651811015613cb457600080613c396040518060400160405280858c60000151613c1d9190615983565b8152602001858c60200151613c329190615933565b9052614c8c565b509150915060405180604001604052808383613c559190615933565b8152602001848b60200151613c6a9190615933565b815250888581518110613c7f57613c7f6158d5565b6020908102919091010152613c95600185615933565b9350613ca18183615933565b613cab9084615933565b92505050613bf3565b50845250919392505050565b60606000806000613cd085614c8c565b919450925090506000816001811115613ceb57613ceb61555f565b14613d22576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613d2c8284615933565b855114613d65576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118848560200151848461512a565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff90931692839290613dc3908490615933565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f00000000000000000000000000000000000000000000000000000000000000001690637eee288d90604401600060405180830381600087803b158015613e5857600080fd5b505af1158015613e6c573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b6000613ee66fffffffffffffffffffffffffffffffff84166001615b36565b90506000613ef682866001614608565b9050600086901a8380613fe25750613f2f60027f0000000000000000000000000000000000000000000000000000000000000000615af9565b6004830154600290613fd3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b613fdd9190615c07565b60ff16145b1561403a5760ff811660011480613ffc575060ff81166002145b614035576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b613e6c565b60ff811615613e6c576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b17600082136140d757631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a76400000215820261431057637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b6000816000190483118202156143405763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d7821361437e57919050565b680755bf798b4a1bf1e5821261439c5763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000613a38670de0b6b3a76400008361455086614078565b61455a9190615c29565b6145649190615ce5565b614350565b6000806145f6837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826146515761464c6fffffffffffffffffffffffffffffffff86167f00000000000000000000000000000000000000000000000000000000000000006151bf565b61466c565b61466c856fffffffffffffffffffffffffffffffff1661534b565b905060028481548110614681576146816158d5565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff8281169116146146e457815460028054909163ffffffff169081106146cf576146cf6158d5565b90600052602060002090600502019150614692565b509392505050565b60008060008060006146fd8661471b565b935093509350935061471184848484614b24565b9695505050505050565b600080600080600085905060006002828154811061473b5761473b6158d5565b600091825260209091206004600590920201908101549091507f000000000000000000000000000000000000000000000000000000000000000090614812906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff161161484c576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f000000000000000000000000000000000000000000000000000000000000000090614913906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16925082111561498857825463ffffffff166149527f00000000000000000000000000000000000000000000000000000000000000006001615933565b830361495c578391505b6002818154811061496f5761496f6158d5565b9060005260206000209060050201935080945050614850565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149f16149dc856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff161490508015614ac0576000614a29836fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff161115614a94576000614a6b614a6360016fffffffffffffffffffffffffffffffff8616615b0d565b896001614608565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a50614a9a9050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614b16565b6000614ae2614a636fffffffffffffffffffffffffffffffff85166001615b36565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614b915760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611884565b8282604051602001614bbf9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614c6b847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614ccf576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614cf4576000600160009450945094505050615123565b60b78111614e0a576000614d09608083615983565b905080876000015111614d48576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614dc057507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614df7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060019550935060009250615123915050565b60bf8111614f68576000614e1f60b783615983565b905080876000015111614e5e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614ec0576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614f08576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f128184615933565b895111614f4b576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f56836001615933565b97509550600094506151239350505050565b60f78111614fcd576000614f7d60c083615983565b905080876000015111614fbc576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600195509350849250615123915050565b6000614fda60f783615983565b905080876000015111615019576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361507b576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116150c3576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6150cd8184615933565b895111615106576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615111836001615933565b97509550600194506151239350505050565b9193909250565b60608167ffffffffffffffff81111561514557615145615809565b6040519080825280601f01601f19166020018201604052801561516f576020820181803683370190505b50905081156151b85760006151848486615933565b90506020820160005b848110156151a557828101518282015260200161518d565b848111156151b4576000858301525b5050505b9392505050565b60008161525e846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116152745763b34b5c226000526004601cfd5b61527d8361534b565b90508161531c826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611613a3b57613a38615332836001615933565b6fffffffffffffffffffffffffffffffff8316906153f0565b600081196001830116816153df827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b60008061547d847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f8401126154ab57600080fd5b50813567ffffffffffffffff8111156154c357600080fd5b6020830191508360208285010111156154db57600080fd5b9250929050565b600080600083850360a08112156154f857600080fd5b608081121561550657600080fd5b50839250608084013567ffffffffffffffff81111561552457600080fd5b61553086828701615499565b9497909650939450505050565b6000806040838503121561555057600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106155c9577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806000606084860312156155e457600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561562157602081850181015186830182015201615605565b81811115615633576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000613a3860208301846155fb565b60006020828403121561568b57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146156b457600080fd5b50565b6000602082840312156156c957600080fd5b81356151b881615692565b803580151581146156e457600080fd5b919050565b600080600080608085870312156156ff57600080fd5b84359350602085013592506040850135915061571d606086016156d4565b905092959194509250565b60006020828403121561573a57600080fd5b81356fffffffffffffffffffffffffffffffff811681146151b857600080fd5b6000806000806000806080878903121561577357600080fd5b86359550615783602088016156d4565b9450604087013567ffffffffffffffff808211156157a057600080fd5b6157ac8a838b01615499565b909650945060608901359150808211156157c557600080fd5b506157d289828a01615499565b979a9699509497509295939492505050565b63ffffffff8416815282602082015260606040820152600061188460608301846155fb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006080828403121561584a57600080fd5b6040516080810181811067ffffffffffffffff82111715615894577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561594657615946615904565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361597c5761597c615904565b5060010190565b60008282101561599557615995615904565b500390565b6000602082840312156159ac57600080fd5b81516151b881615692565b6000602082840312156159c957600080fd5b5051919050565b600067ffffffffffffffff8083168185168083038211156159f3576159f3615904565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615a2357615a23615904565b02949350505050565b600067ffffffffffffffff83811690831681811015615a4d57615a4d615904565b039392505050565b60008060408385031215615a6857600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615ab757615ab7615a79565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615af457615af4615904565b500290565b600082615b0857615b08615a79565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615a4d57615a4d615904565b60006fffffffffffffffffffffffffffffffff8083168185168083038211156159f3576159f3615904565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615bbe606083018789615b61565b8281036020840152615bd1818688615b61565b9150508260408301529695505050505050565b600060ff821660ff841680821015615bfe57615bfe615904565b90039392505050565b600060ff831680615c1a57615c1a615a79565b8060ff84160691505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615c6a57615c6a615904565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615ca557615ca5615904565b60008712925087820587128484161615615cc157615cc1615904565b87850587128184161615615cd757615cd7615904565b505050929093029392505050565b600082615cf457615cf4615a79565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615d4857615d48615904565b50059056fea164736f6c634300080f000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004b0000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe7806000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92000000000000000000000000970670459734a83899773a0fd45941b5afc1200e0000000000000000000000000000000000000000000000000000000000000385", - "deployedCode": "0x6080604052600436106102f25760003560e01c806370872aa51161018f578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b18578063fa315aa914610b3c578063fe2bbeb214610b6f57600080fd5b8063ec5e630814610a95578063eff0f59214610ac8578063f8f43ff614610af857600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a0f578063d8cc1a3c14610a42578063dabd396d14610a6257600080fd5b8063c6f0308c14610937578063cf09e0d0146109c1578063d5d44d80146109e257600080fd5b80638d450a9511610143578063bcef3b551161011d578063bcef3b55146108b7578063bd8da956146108f7578063c395e1ca1461091757600080fd5b80638d450a9514610777578063a445ece6146107aa578063bbdc02db1461087657600080fd5b80638129fc1c116101745780638129fc1c1461071a5780638980e0cc146107225780638b85902b1461073757600080fd5b806370872aa5146106f25780637b0f0adc1461070757600080fd5b80633fc8cef3116102485780635c0cba33116101fc5780636361506d116101d65780636361506d1461066c5780636b6716c0146106ac5780636f034409146106df57600080fd5b80635c0cba3314610604578063609d33341461063757806360e274641461064c57600080fd5b806354fd4d501161022d57806354fd4d501461055e57806357da950e146105b45780635a5fa2d9146105e457600080fd5b80633fc8cef314610518578063472777c61461054b57600080fd5b80632810e1d6116102aa57806337b1b2291161028457806337b1b229146104655780633a768463146104a55780633e3ac912146104d857600080fd5b80632810e1d6146103de5780632ad69aeb146103f357806330dbe5701461041357600080fd5b806319effeb4116102db57806319effeb414610339578063200d2ed21461038457806325fc2ace146103bf57600080fd5b806301935130146102f757806303c2924d14610319575b600080fd5b34801561030357600080fd5b506103176103123660046154e2565b610b9f565b005b34801561032557600080fd5b5061031761033436600461553d565b610ec0565b34801561034557600080fd5b506000546103669068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561039057600080fd5b506000546103b290700100000000000000000000000000000000900460ff1681565b60405161037b919061558e565b3480156103cb57600080fd5b506008545b60405190815260200161037b565b3480156103ea57600080fd5b506103b2611566565b3480156103ff57600080fd5b506103d061040e36600461553d565b61180b565b34801561041f57600080fd5b506001546104409073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161037b565b34801561047157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610440565b3480156104b157600080fd5b507f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe7806610440565b3480156104e457600080fd5b50600054610508907201000000000000000000000000000000000000900460ff1681565b604051901515815260200161037b565b34801561052457600080fd5b507f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92610440565b6103176105593660046155cf565b611841565b34801561056a57600080fd5b506105a76040518060400160405280600a81526020017f312e332e302d72632e310000000000000000000000000000000000000000000081525081565b60405161037b9190615666565b3480156105c057600080fd5b506008546009546105cf919082565b6040805192835260208301919091520161037b565b3480156105f057600080fd5b506103d06105ff366004615679565b611853565b34801561061057600080fd5b507f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e610440565b34801561064357600080fd5b506105a761188d565b34801561065857600080fd5b506103176106673660046156b7565b61189b565b34801561067857600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103d0565b3480156106b857600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610366565b6103176106ed3660046156e9565b611a42565b3480156106fe57600080fd5b506009546103d0565b6103176107153660046155cf565b61251b565b610317612528565b34801561072e57600080fd5b506002546103d0565b34801561074357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103d0565b34801561078357600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103d0565b3480156107b657600080fd5b506108226107c5366004615679565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff16606082015260800161037b565b34801561088257600080fd5b5060405163ffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260200161037b565b3480156108c357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103d0565b34801561090357600080fd5b50610366610912366004615679565b612a81565b34801561092357600080fd5b506103d0610932366004615728565b612c60565b34801561094357600080fd5b50610957610952366004615679565b612e43565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e00161037b565b3480156109cd57600080fd5b506000546103669067ffffffffffffffff1681565b3480156109ee57600080fd5b506103d06109fd3660046156b7565b60036020526000908152604090205481565b348015610a1b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000003856103d0565b348015610a4e57600080fd5b50610317610a5d36600461575a565b612eda565b348015610a6e57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b0610366565b348015610aa157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000046103d0565b348015610ad457600080fd5b50610508610ae3366004615679565b60046020526000908152604090205460ff1681565b348015610b0457600080fd5b50610317610b133660046155cf565b613509565b348015610b2457600080fd5b50610b2d6139c6565b60405161037b939291906157e4565b348015610b4857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000086103d0565b348015610b7b57600080fd5b50610508610b8a366004615679565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610bcb57610bcb61555f565b14610c02576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610c55576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610ca3610c9e36869003860186615838565b613a41565b14610cda576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610cef9291906158c5565b604051809103902014610d2e576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d77610d7284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613a9d92505050565b613b0a565b90506000610d9e82600881518110610d9157610d916158d5565b6020026020010151613cc0565b9050602081511115610ddc576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610e51576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610eec57610eec61555f565b14610f23576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610f3857610f386158d5565b906000526020600020906005020190506000610f5384612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b081169082161015610fbc576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611005576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561102257508515155b156110bd578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110555781611071565b600186015473ffffffffffffffffffffffffffffffffffffffff165b905061107d8187613d74565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff166060830152611160576fffffffffffffffffffffffffffffffff6040820152600181526000869003611160578195505b600086826020015163ffffffff166111789190615933565b90506000838211611189578161118b565b835b602084015190915063ffffffff165b818110156112d75760008682815481106111b6576111b66158d5565b6000918252602080832090910154808352600690915260409091205490915060ff1661120e576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611223576112236158d5565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112805750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b156112c257600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b505080806112cf9061594b565b91505061119a565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921790915584900361155b57606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558915801561145757506000547201000000000000000000000000000000000000900460ff165b156114cc5760015473ffffffffffffffffffffffffffffffffffffffff1661147f818a613d74565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff909116178855611559565b61151373ffffffffffffffffffffffffffffffffffffffff8216156114f1578161150d565b600189015473ffffffffffffffffffffffffffffffffffffffff165b89613d74565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff1660028111156115945761159461555f565b146115cb576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff1661162f576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008154811061165b5761165b6158d5565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611696576001611699565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff9091161770010000000000000000000000000000000083600281111561174a5761174a61555f565b02179055600281111561175f5761175f61555f565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e73ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156117f057600080fd5b505af1158015611804573d6000803e3d6000fd5b5050505090565b6005602052816000526040600020818154811061182757600080fd5b90600052602060002001600091509150505481565b905090565b61184e8383836001611a42565b505050565b6000818152600760209081526040808320600590925282208054825461188490610100900463ffffffff1682615983565b95945050505050565b606061183c60546020613e75565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260036020526040812080549082905590819003611900576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169063f3fef3a390604401600060405180830381600087803b15801561199057600080fd5b505af11580156119a4573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a02576040519150601f19603f3d011682016040523d82523d6000602084013e611a07565b606091505b505090508061184e576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008054700100000000000000000000000000000000900460ff166002811115611a6e57611a6e61555f565b14611aa5576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110611aba57611aba6158d5565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514611ba1576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000611c61826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580611c9c5750611c997f00000000000000000000000000000000000000000000000000000000000000046002615933565b81145b8015611ca6575084155b15611cdd576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015611d03575086155b15611d3a576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000008811115611d94576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dbf7f00000000000000000000000000000000000000000000000000000000000000046001615933565b8103611dd157611dd186888588613ec7565b34611ddb83612c60565b14611e12576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611e1d88612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b0811690821603611e85576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611eb260017f0000000000000000000000000000000000000000000000000000000000000008615983565b8303611ff0577f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f47919061599a565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb591906159b7565b611fe9907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166159d0565b9050612083565b61201b60017f0000000000000000000000000000000000000000000000000000000000000004615983565b830361205657611fe97f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1660026159fc565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b6120b7817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b67ffffffffffffffff166120d28367ffffffffffffffff1690565b67ffffffffffffffff16111561211957612116817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615612197576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c8152602001908152602001600020600160028054905061242d9190615983565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169263d0e30db09234926004808301939282900301818588803b1580156124c557600080fd5b505af11580156124d9573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b61184e8383836000611a42565b60005471010000000000000000000000000000000000900460ff161561257a576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e1690637258a807906024016040805180830381865afa15801561262e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126529190615a55565b90925090508161268e576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a146126c157639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401351161275b576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd929092169363d0e30db093926004828101939282900301818588803b158015612a3057600080fd5b505af1158015612a44573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b600080600054700100000000000000000000000000000000900460ff166002811115612aaf57612aaf61555f565b14612ae6576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110612afb57612afb6158d5565b600091825260208220600590910201805490925063ffffffff90811614612b6a57815460028054909163ffffffff16908110612b3957612b396158d5565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090612ba290700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b612bb69067ffffffffffffffff1642615983565b612bd5612b95846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16612be99190615933565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b01667ffffffffffffffff168167ffffffffffffffff1611612c365780611884565b7f00000000000000000000000000000000000000000000000000000000000004b095945050505050565b600080612cff836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000008811115612d5e576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000612d798383615aa8565b9050670de0b6b3a76400006000612db0827f0000000000000000000000000000000000000000000000000000000000000008615abc565b90506000612dce612dc9670de0b6b3a764000086615abc565b614078565b90506000612ddc84846142d3565b90506000612dea8383614322565b90506000612df782614350565b90506000612e1682612e11670de0b6b3a76400008f615abc565b614538565b90506000612e248b83614322565b9050612e30818d615abc565b9f9e505050505050505050505050505050565b60028181548110612e5357600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b60008054700100000000000000000000000000000000900460ff166002811115612f0657612f0661555f565b14612f3d576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028781548110612f5257612f526158d5565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b9050612fb17f00000000000000000000000000000000000000000000000000000000000000086001615933565b61304d826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1614613087576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561317e576130da7f00000000000000000000000000000000000000000000000000000000000000047f0000000000000000000000000000000000000000000000000000000000000008615983565b6001901b6130f9846fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff166131159190615af9565b156131525761314961313a60016fffffffffffffffffffffffffffffffff8716615b0d565b865463ffffffff166000614608565b60030154613174565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506131a8565b600385015491506131a561313a6fffffffffffffffffffffffffffffffff86166001615b36565b90505b600882901b60088a8a6040516131bf9291906158c5565b6040518091039020901b14613200576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061320b8c6146ec565b9050600061321a836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff169063e14ced3290613294908f908f908f908f908a90600401615baa565b6020604051808303816000875af11580156132b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d791906159b7565b600485015491149150600090600290613382906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b61341e896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6134289190615be4565b6134329190615c07565b60ff161590508115158103613473576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156134ca576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff1660028111156135355761353561555f565b1461356c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061357b8661471b565b9350935093509350600061359185858585614b24565b905060007f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015613600573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613624919061599a565b90506001890361371c5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a84613680367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af11580156136f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061371691906159b7565b5061155b565b600289036137485773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8489613680565b600389036137745773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8487613680565b600489036138fb5760006137ba6fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000004614bde565b6009546137c79190615933565b6137d2906001615933565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061383b57367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036054013561383d565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156138d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f491906159b7565b505061155b565b60058903613994576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000038560c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016136d3565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060613a1f61188d565b9050909192565b600081831015613a365781613a38565b825b90505b92915050565b60008160000151826020015183604001518460600151604051602001613a80949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003613aec576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000613b1a85614c8c565b919450925090506001816001811115613b3557613b3561555f565b14613b6c576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451613b788385615933565b14613baf576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081613bc65790505093506000835b8651811015613cb457600080613c396040518060400160405280858c60000151613c1d9190615983565b8152602001858c60200151613c329190615933565b9052614c8c565b509150915060405180604001604052808383613c559190615933565b8152602001848b60200151613c6a9190615933565b815250888581518110613c7f57613c7f6158d5565b6020908102919091010152613c95600185615933565b9350613ca18183615933565b613cab9084615933565b92505050613bf3565b50845250919392505050565b60606000806000613cd085614c8c565b919450925090506000816001811115613ceb57613ceb61555f565b14613d22576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613d2c8284615933565b855114613d65576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118848560200151848461512a565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff90931692839290613dc3908490615933565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd921690637eee288d90604401600060405180830381600087803b158015613e5857600080fd5b505af1158015613e6c573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b6000613ee66fffffffffffffffffffffffffffffffff84166001615b36565b90506000613ef682866001614608565b9050600086901a8380613fe25750613f2f60027f0000000000000000000000000000000000000000000000000000000000000004615af9565b6004830154600290613fd3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b613fdd9190615c07565b60ff16145b1561403a5760ff811660011480613ffc575060ff81166002145b614035576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b613e6c565b60ff811615613e6c576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b17600082136140d757631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a76400000215820261431057637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b6000816000190483118202156143405763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d7821361437e57919050565b680755bf798b4a1bf1e5821261439c5763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000613a38670de0b6b3a76400008361455086614078565b61455a9190615c29565b6145649190615ce5565b614350565b6000806145f6837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826146515761464c6fffffffffffffffffffffffffffffffff86167f00000000000000000000000000000000000000000000000000000000000000046151bf565b61466c565b61466c856fffffffffffffffffffffffffffffffff1661534b565b905060028481548110614681576146816158d5565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff8281169116146146e457815460028054909163ffffffff169081106146cf576146cf6158d5565b90600052602060002090600502019150614692565b509392505050565b60008060008060006146fd8661471b565b935093509350935061471184848484614b24565b9695505050505050565b600080600080600085905060006002828154811061473b5761473b6158d5565b600091825260209091206004600590920201908101549091507f000000000000000000000000000000000000000000000000000000000000000490614812906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff161161484c576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f000000000000000000000000000000000000000000000000000000000000000490614913906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16925082111561498857825463ffffffff166149527f00000000000000000000000000000000000000000000000000000000000000046001615933565b830361495c578391505b6002818154811061496f5761496f6158d5565b9060005260206000209060050201935080945050614850565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149f16149dc856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff161490508015614ac0576000614a29836fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff161115614a94576000614a6b614a6360016fffffffffffffffffffffffffffffffff8616615b0d565b896001614608565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a50614a9a9050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614b16565b6000614ae2614a636fffffffffffffffffffffffffffffffff85166001615b36565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614b915760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611884565b8282604051602001614bbf9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614c6b847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614ccf576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614cf4576000600160009450945094505050615123565b60b78111614e0a576000614d09608083615983565b905080876000015111614d48576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614dc057507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614df7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060019550935060009250615123915050565b60bf8111614f68576000614e1f60b783615983565b905080876000015111614e5e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614ec0576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614f08576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f128184615933565b895111614f4b576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f56836001615933565b97509550600094506151239350505050565b60f78111614fcd576000614f7d60c083615983565b905080876000015111614fbc576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600195509350849250615123915050565b6000614fda60f783615983565b905080876000015111615019576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361507b576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116150c3576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6150cd8184615933565b895111615106576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615111836001615933565b97509550600194506151239350505050565b9193909250565b60608167ffffffffffffffff81111561514557615145615809565b6040519080825280601f01601f19166020018201604052801561516f576020820181803683370190505b50905081156151b85760006151848486615933565b90506020820160005b848110156151a557828101518282015260200161518d565b848111156151b4576000858301525b5050505b9392505050565b60008161525e846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116152745763b34b5c226000526004601cfd5b61527d8361534b565b90508161531c826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611613a3b57613a38615332836001615933565b6fffffffffffffffffffffffffffffffff8316906153f0565b600081196001830116816153df827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b60008061547d847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f8401126154ab57600080fd5b50813567ffffffffffffffff8111156154c357600080fd5b6020830191508360208285010111156154db57600080fd5b9250929050565b600080600083850360a08112156154f857600080fd5b608081121561550657600080fd5b50839250608084013567ffffffffffffffff81111561552457600080fd5b61553086828701615499565b9497909650939450505050565b6000806040838503121561555057600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106155c9577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806000606084860312156155e457600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561562157602081850181015186830182015201615605565b81811115615633576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000613a3860208301846155fb565b60006020828403121561568b57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146156b457600080fd5b50565b6000602082840312156156c957600080fd5b81356151b881615692565b803580151581146156e457600080fd5b919050565b600080600080608085870312156156ff57600080fd5b84359350602085013592506040850135915061571d606086016156d4565b905092959194509250565b60006020828403121561573a57600080fd5b81356fffffffffffffffffffffffffffffffff811681146151b857600080fd5b6000806000806000806080878903121561577357600080fd5b86359550615783602088016156d4565b9450604087013567ffffffffffffffff808211156157a057600080fd5b6157ac8a838b01615499565b909650945060608901359150808211156157c557600080fd5b506157d289828a01615499565b979a9699509497509295939492505050565b63ffffffff8416815282602082015260606040820152600061188460608301846155fb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006080828403121561584a57600080fd5b6040516080810181811067ffffffffffffffff82111715615894577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561594657615946615904565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361597c5761597c615904565b5060010190565b60008282101561599557615995615904565b500390565b6000602082840312156159ac57600080fd5b81516151b881615692565b6000602082840312156159c957600080fd5b5051919050565b600067ffffffffffffffff8083168185168083038211156159f3576159f3615904565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615a2357615a23615904565b02949350505050565b600067ffffffffffffffff83811690831681811015615a4d57615a4d615904565b039392505050565b60008060408385031215615a6857600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615ab757615ab7615a79565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615af457615af4615904565b500290565b600082615b0857615b08615a79565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615a4d57615a4d615904565b60006fffffffffffffffffffffffffffffffff8083168185168083038211156159f3576159f3615904565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615bbe606083018789615b61565b8281036020840152615bd1818688615b61565b9150508260408301529695505050505050565b600060ff821660ff841680821015615bfe57615bfe615904565b90039392505050565b600060ff831680615c1a57615c1a615a79565b8060ff84160691505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615c6a57615c6a615904565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615ca557615ca5615904565b60008712925087820587128484161615615cc157615cc1615904565b87850587128184161615615cd757615cd7615904565b505050929093029392505050565b600082615cf457615cf4615a79565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615d4857615d48615904565b50059056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0xb6b1579AA54e2F61e621a40d5F2704D717B3544F", - "account": "0x444e09fe6D839273316a87002aB0EFBeA6fe7806", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x7dc0d1d0", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0xb6b1579AA54e2F61e621a40d5F2704D717B3544F", - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf3f480d9", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0xb6b1579AA54e2F61e621a40d5F2704D717B3544F", - "account": "0x444e09fe6D839273316a87002aB0EFBeA6fe7806", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x7dc0d1d0", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0xb6b1579AA54e2F61e621a40d5F2704D717B3544F", - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf3f480d9", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x14f6b1a30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b6b1579aa54e2f61e621a40d5f2704d717b3544f", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765", - "previousValue": "0x00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x14f6b1a30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b6b1579aa54e2f61e621a40d5f2704d717b3544f", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xffdfc1249c027f9191656349feb0761381bb32c9f557e01f419fd08754bf5a1b" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": true, - "newValue": "0x000000000000000000000000b6b1579aa54e2f61e621a40d5f2704d717b3544f", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0xffdfc1249c027f9191656349feb0761381bb32c9f557e01f419fd08754bf5a1b" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x935e3829", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000034" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x935e3829", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000034" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x0b7b1b30", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000008", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000008", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000037" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9110ec4a", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x00000000000000000000000000000000000000000000000000000000000004b0", - "previousValue": "0x00000000000000000000000000000000000000000000000000000000000004b0", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000003a" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x1b685b9e0000000000000000000000000000000000000000000000000000000000000001", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765", - "previousValue": "0x00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x1b685b9e0000000000000000000000000000000000000000000000000000000000000001", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4d5a9bd2e41301728d41c8e705190becb4e74abe869f75bdb405b63716a35f9e" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xe1a05cc3", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000004", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000004", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000038" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xdb75b649", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000039" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x9110ec4a", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x00000000000000000000000000000000000000000000000000000000000004b0", - "previousValue": "0x00000000000000000000000000000000000000000000000000000000000004b0", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000003a" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xa2af0d1f", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000385", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000385", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000011" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x241e2d7e", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8", - "previousValue": "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000020" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x08cb822d", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63", - "previousValue": "0x0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000021" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x59B99034FBdd5E554661a2100cB2b6b7C5d495F8", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6102006040523480156200001257600080fd5b506040516200678d3803806200678d833981016040819052620000359162000469565b8b8b8b8b8b8b8b8b8b8b6200004d6001607e6200055c565b60ff168811156200007157604051633beff19960e11b815260040160405180910390fd5b6000198714806200008e5750876200008b88600162000582565b10155b15620000ad5760405163e62ccf3960e01b815260040160405180910390fd5b6002871015620000d05760405163e62ccf3960e01b815260040160405180910390fd5b6001600160401b038016846001600160a01b0316637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000119573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200013f91906200059d565b6001600160a01b031663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200017d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001a39190620005bd565b1115620001c35760405163b4e1243360e01b815260040160405180910390fd5b6000620001e4876001600160401b03166200040860201b62000d051760201c565b620001fa906001600160401b03166002620005d7565b90506000856001600160a01b0316637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200023d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200026391906200059d565b6001600160a01b031663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002a1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002c79190620005bd565b620002e6896001600160401b03166200040860201b62000d051760201c565b6001600160401b0316620002fb919062000582565b905060006200031683836200040b60201b620026401760201c565b90506001600160401b03811115620003415760405163235dfb2b60e21b815260040160405180910390fd5b62000360886001600160401b03166200040860201b62000d051760201c565b6001600160401b0316816001600160401b03161115620003935760405163235dfb2b60e21b815260040160405180910390fd5b50505063ffffffff9099166101205260809790975260a09590955260c0939093526001600160401b039182166101a0521660e0526001600160a01b03908116610100529081166101405290811661016052610180919091529182166101c052166101e05250620005f998505050505050505050565b90565b6000818310156200041d57816200041f565b825b9392505050565b80516001600160401b03811681146200043e57600080fd5b919050565b6001600160a01b03811681146200045957600080fd5b50565b80516200043e8162000443565b6000806000806000806000806000806000806101808d8f0312156200048d57600080fd5b8c5163ffffffff81168114620004a257600080fd5b809c505060208d01519a5060408d0151995060608d01519850620004c960808e0162000426565b9750620004d960a08e0162000426565b9650620004e960c08e016200045c565b9550620004f960e08e016200045c565b94506200050a6101008e016200045c565b93506101208d01519250620005236101408e016200045c565b9150620005346101608e016200045c565b90509295989b509295989b509295989b565b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff84168082101562000579576200057962000546565b90039392505050565b6000821982111562000598576200059862000546565b500190565b600060208284031215620005b057600080fd5b81516200041f8162000443565b600060208284031215620005d057600080fd5b5051919050565b6000816000190483118215151615620005f457620005f462000546565b500290565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e051615fd5620007b86000396000818161058301528181611b1501526120b50152600081816108ce01528181611ad601528181611ba401526120760152600081816107040152818161305a015281816130c501526130f8015260008181610a9a015261255301526000818161065c01528181611806015261367a01526000818161053d015281816119c801528181612a2e0152818161351f0152613a7c015260008181610909015281816125e201526136390152600081816104ca015281816121b101528181612f59015261436c015260008181610aed01528181610fdc01528181611d7a01528181611dbc01528181612ec9015281816131280152613187015260008181610b20015281816123b001528181612d1201528181612e3801528181613096015281816141bf0152818161466e0152818161476f015281816148440152818161511b0152615347015260008181610bc701528181611e8a01528181611f1001528181612ddb01528181612f2d015281816140b501526141e00152600081816107cf015261427e0152615fd56000f3fe6080604052600436106103085760003560e01c806370872aa51161019a578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b94578063fa315aa914610bb8578063fe2bbeb214610beb57600080fd5b8063ec5e630814610b11578063eff0f59214610b44578063f8f43ff614610b7457600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a8b578063d8cc1a3c14610abe578063dabd396d14610ade57600080fd5b8063c6f0308c146109b3578063cf09e0d014610a3d578063d5d44d8014610a5e57600080fd5b8063a445ece611610143578063bcef3b551161011d578063bcef3b5514610933578063bd8da95614610973578063c395e1ca1461099357600080fd5b8063a445ece6146107f3578063a8e4fb90146108bf578063bbdc02db146108f257600080fd5b80638980e0cc116101745780638980e0cc1461076b5780638b85902b146107805780638d450a95146107c057600080fd5b806370872aa51461073b5780637b0f0adc146107505780638129fc1c1461076357600080fd5b80633fc8cef31161025e5780635c0cba33116102075780636361506d116101e15780636361506d146106b55780636b6716c0146106f55780636f0344091461072857600080fd5b80635c0cba331461064d578063609d33341461068057806360e274641461069557600080fd5b806354fd4d501161023857806354fd4d50146105a757806357da950e146105fd5780635a5fa2d91461062d57600080fd5b80633fc8cef31461052e578063472777c614610561578063534db0e21461057457600080fd5b80632810e1d6116102c057806337b1b2291161029a57806337b1b2291461047b5780633a768463146104bb5780633e3ac912146104ee57600080fd5b80632810e1d6146103f45780632ad69aeb1461040957806330dbe5701461042957600080fd5b806319effeb4116102f157806319effeb41461034f578063200d2ed21461039a57806325fc2ace146103d557600080fd5b8063019351301461030d57806303c2924d1461032f575b600080fd5b34801561031957600080fd5b5061032d61032836600461575d565b610c1b565b005b34801561033b57600080fd5b5061032d61034a3660046157b8565b610f3c565b34801561035b57600080fd5b5060005461037c9068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156103a657600080fd5b506000546103c890700100000000000000000000000000000000900460ff1681565b6040516103919190615809565b3480156103e157600080fd5b506008545b604051908152602001610391565b34801561040057600080fd5b506103c86115e2565b34801561041557600080fd5b506103e66104243660046157b8565b611887565b34801561043557600080fd5b506001546104569073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610391565b34801561048757600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610456565b3480156104c757600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610456565b3480156104fa57600080fd5b5060005461051e907201000000000000000000000000000000000000900460ff1681565b6040519015158152602001610391565b34801561053a57600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610456565b61032d61056f36600461584a565b6118bd565b34801561058057600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610456565b3480156105b357600080fd5b506105f06040518060400160405280600a81526020017f312e332e302d72632e310000000000000000000000000000000000000000000081525081565b60405161039191906158e1565b34801561060957600080fd5b50600854600954610618919082565b60408051928352602083019190915201610391565b34801561063957600080fd5b506103e66106483660046158f4565b6118cf565b34801561065957600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610456565b34801561068c57600080fd5b506105f0611909565b3480156106a157600080fd5b5061032d6106b0366004615932565b611917565b3480156106c157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103e6565b34801561070157600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061037c565b61032d610736366004615964565b611abe565b34801561074757600080fd5b506009546103e6565b61032d61075e36600461584a565b611b7f565b61032d611b8c565b34801561077757600080fd5b506002546103e6565b34801561078c57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103e6565b3480156107cc57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103e6565b3480156107ff57600080fd5b5061086b61080e3660046158f4565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff166060820152608001610391565b3480156108cb57600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610456565b3480156108fe57600080fd5b5060405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610391565b34801561093f57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103e6565b34801561097f57600080fd5b5061037c61098e3660046158f4565b611c05565b34801561099f57600080fd5b506103e66109ae3660046159a3565b611de4565b3480156109bf57600080fd5b506109d36109ce3660046158f4565b611fc7565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e001610391565b348015610a4957600080fd5b5060005461037c9067ffffffffffffffff1681565b348015610a6a57600080fd5b506103e6610a79366004615932565b60036020526000908152604090205481565b348015610a9757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103e6565b348015610aca57600080fd5b5061032d610ad93660046159d5565b61205e565b348015610aea57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061037c565b348015610b1d57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103e6565b348015610b5057600080fd5b5061051e610b5f3660046158f4565b60046020526000908152604090205460ff1681565b348015610b8057600080fd5b5061032d610b8f36600461584a565b612123565b348015610ba057600080fd5b50610ba96125e0565b60405161039193929190615a5f565b348015610bc457600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103e6565b348015610bf757600080fd5b5061051e610c063660046158f4565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610c4757610c476157da565b14610c7e576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610cd1576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d08367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610d1f610d1a36869003860186615ab3565b61265b565b14610d56576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610d6b929190615b40565b604051809103902014610daa576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610df3610dee84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506126b792505050565b612724565b90506000610e1a82600881518110610e0d57610e0d615b50565b60200260200101516128da565b9050602081511115610e58576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610ecd576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610f6857610f686157da565b14610f9f576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610fb457610fb4615b50565b906000526020600020906005020190506000610fcf84611c05565b905067ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081169082161015611038576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611081576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561109e57508515155b15611139578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110d157816110ed565b600186015473ffffffffffffffffffffffffffffffffffffffff165b90506110f9818761298e565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff1660608301526111dc576fffffffffffffffffffffffffffffffff60408201526001815260008690036111dc578195505b600086826020015163ffffffff166111f49190615bae565b905060008382116112055781611207565b835b602084015190915063ffffffff165b8181101561135357600086828154811061123257611232615b50565b6000918252602080832090910154808352600690915260409091205490915060ff1661128a576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002828154811061129f5761129f615b50565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112fc5750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b1561133e57600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b5050808061134b90615bc6565b915050611216565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909316929092179091558490036115d757606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055891580156114d357506000547201000000000000000000000000000000000000900460ff165b156115485760015473ffffffffffffffffffffffffffffffffffffffff166114fb818a61298e565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff9091161788556115d5565b61158f73ffffffffffffffffffffffffffffffffffffffff82161561156d5781611589565b600189015473ffffffffffffffffffffffffffffffffffffffff165b8961298e565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff166002811115611610576116106157da565b14611647576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff166116ab576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660026000815481106116d7576116d7615b50565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611712576001611715565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff909116177001000000000000000000000000000000008360028111156117c6576117c66157da565b0217905560028111156117db576117db6157da565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561186c57600080fd5b505af1158015611880573d6000803e3d6000fd5b5050505090565b600560205281600052604060002081815481106118a357600080fd5b90600052602060002001600091509150505481565b905090565b6118ca8383836001611abe565b505050565b6000818152600760209081526040808320600590925282208054825461190090610100900463ffffffff1682615bfe565b95945050505050565b60606118b860546020612a8f565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604081208054908290559081900361197c576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063f3fef3a390604401600060405180830381600087803b158015611a0c57600080fd5b505af1158015611a20573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a7e576040519150601f19603f3d011682016040523d82523d6000602084013e611a83565b606091505b50509050806118ca576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480611b3757503373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016145b611b6d576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b7984848484612ae1565b50505050565b6118ca8383836000611abe565b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611bfb576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c036135ba565b565b600080600054700100000000000000000000000000000000900460ff166002811115611c3357611c336157da565b14611c6a576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110611c7f57611c7f615b50565b600091825260208220600590910201805490925063ffffffff90811614611cee57815460028054909163ffffffff16908110611cbd57611cbd615b50565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090611d2690700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b611d3a9067ffffffffffffffff1642615bfe565b611d59611d19846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16611d6d9190615bae565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001667ffffffffffffffff168167ffffffffffffffff1611611dba5780611900565b7f000000000000000000000000000000000000000000000000000000000000000095945050505050565b600080611e83836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000000811115611ee2576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000611efd8383615c44565b9050670de0b6b3a76400006000611f34827f0000000000000000000000000000000000000000000000000000000000000000615c58565b90506000611f52611f4d670de0b6b3a764000086615c58565b613b13565b90506000611f608484613d6e565b90506000611f6e8383613dbd565b90506000611f7b82613deb565b90506000611f9a82611f95670de0b6b3a76400008f615c58565b613fd3565b90506000611fa88b83613dbd565b9050611fb4818d615c58565b9f9e505050505050505050505050505050565b60028181548110611fd757600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614806120d757503373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016145b61210d576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61211b868686868686614004565b505050505050565b60008054700100000000000000000000000000000000900460ff16600281111561214f5761214f6157da565b14612186576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061219586614633565b935093509350935060006121ab85858585614a3c565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561221a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223e9190615c95565b9050600189036123365773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8461229a367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af115801561230c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123309190615cb2565b506115d7565b600289036123625773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848961229a565b6003890361238e5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848761229a565b600489036125155760006123d46fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000000614af6565b6009546123e19190615bae565b6123ec906001615bae565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061245557367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135612457565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156124ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250e9190615cb2565b50506115d7565b600589036125ae576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000000060c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016122ed565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060612639611909565b9050909192565b6000818310156126505781612652565b825b90505b92915050565b6000816000015182602001518360400151846060015160405160200161269a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003612706576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b6060600080600061273485614ba4565b91945092509050600181600181111561274f5761274f6157da565b14612786576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516127928385615bae565b146127c9576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816127e05790505093506000835b86518110156128ce576000806128536040518060400160405280858c600001516128379190615bfe565b8152602001858c6020015161284c9190615bae565b9052614ba4565b50915091506040518060400160405280838361286f9190615bae565b8152602001848b602001516128849190615bae565b81525088858151811061289957612899615b50565b60209081029190910101526128af600185615bae565b93506128bb8183615bae565b6128c59084615bae565b9250505061280d565b50845250919392505050565b606060008060006128ea85614ba4565b919450925090506000816001811115612905576129056157da565b1461293c576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129468284615bae565b85511461297f576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61190085602001518484615042565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff909316928392906129dd908490615bae565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f00000000000000000000000000000000000000000000000000000000000000001690637eee288d90604401600060405180830381600087803b158015612a7257600080fd5b505af1158015612a86573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b60008054700100000000000000000000000000000000900460ff166002811115612b0d57612b0d6157da565b14612b44576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110612b5957612b59615b50565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514612c40576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000612d00826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580612d3b5750612d387f00000000000000000000000000000000000000000000000000000000000000006002615bae565b81145b8015612d45575084155b15612d7c576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015612da2575086155b15612dd9576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000811115612e33576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e5e7f00000000000000000000000000000000000000000000000000000000000000006001615bae565b8103612e7057612e70868885886150d7565b34612e7a83611de4565b14612eb1576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612ebc88611c05565b905067ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811690821603612f24576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612f5160017f0000000000000000000000000000000000000000000000000000000000000000615bfe565b830361308f577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fe69190615c95565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015613030573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130549190615cb2565b613088907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16615ccb565b9050613122565b6130ba60017f0000000000000000000000000000000000000000000000000000000000000000615bfe565b83036130f5576130887f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166002615cf7565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b613156817f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16615d27565b67ffffffffffffffff166131718367ffffffffffffffff1690565b67ffffffffffffffff1611156131b8576131b5817f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16615d27565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615613236576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c815260200190815260200160002060016002805490506134cc9190615bfe565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169263d0e30db09234926004808301939282900301818588803b15801561356457600080fd5b505af1158015613578573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b60005471010000000000000000000000000000000000900460ff161561360c576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690637258a807906024016040805180830381865afa1580156136c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136e49190615d50565b909250905081613720576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a1461375357639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135116137ed576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f00000000000000000000000000000000000000000000000000000000000000009092169363d0e30db093926004828101939282900301818588803b158015613ac257600080fd5b505af1158015613ad6573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b1760008213613b7257631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a764000002158202613dab57637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b600081600019048311820215613ddb5763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d78213613e1957919050565b680755bf798b4a1bf1e58212613e375763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000612652670de0b6b3a764000083613feb86613b13565b613ff59190615d74565b613fff9190615e30565b613deb565b60008054700100000000000000000000000000000000900460ff166002811115614030576140306157da565b14614067576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002878154811061407c5761407c615b50565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506140db7f00000000000000000000000000000000000000000000000000000000000000006001615bae565b614177826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16146141b1576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008089156142a8576142047f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000615bfe565b6001901b614223846fffffffffffffffffffffffffffffffff16615288565b6fffffffffffffffffffffffffffffffff1661423f9190615e98565b1561427c5761427361426460016fffffffffffffffffffffffffffffffff8716615eac565b865463ffffffff166000615327565b6003015461429e565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506142d2565b600385015491506142cf6142646fffffffffffffffffffffffffffffffff86166001615ed5565b90505b600882901b60088a8a6040516142e9929190615b40565b6040518091039020901b1461432a576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006143358c61540b565b90506000614344836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e14ced32906143be908f908f908f908f908a90600401615f49565b6020604051808303816000875af11580156143dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144019190615cb2565b6004850154911491506000906002906144ac906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b614548896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6145529190615f83565b61455c9190615fa6565b60ff16159050811515810361459d576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156145f4576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b600080600080600085905060006002828154811061465357614653615b50565b600091825260209091206004600590920201908101549091507f00000000000000000000000000000000000000000000000000000000000000009061472a906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611614764576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f00000000000000000000000000000000000000000000000000000000000000009061482b906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1692508211156148a057825463ffffffff1661486a7f00000000000000000000000000000000000000000000000000000000000000006001615bae565b8303614874578391505b6002818154811061488757614887615b50565b9060005260206000209060050201935080945050614768565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149096148f4856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff1614905080156149d8576000614941836fffffffffffffffffffffffffffffffff16615288565b6fffffffffffffffffffffffffffffffff1611156149ac57600061498361497b60016fffffffffffffffffffffffffffffffff8616615eac565b896001615327565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a506149b29050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614a2e565b60006149fa61497b6fffffffffffffffffffffffffffffffff85166001615ed5565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614aa95760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611900565b8282604051602001614ad79291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614b83847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614be7576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614c0c57600060016000945094509450505061503b565b60b78111614d22576000614c21608083615bfe565b905080876000015111614c60576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614cd857507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614d0f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061503b915050565b60bf8111614e80576000614d3760b783615bfe565b905080876000015111614d76576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614dd8576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614e20576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614e2a8184615bae565b895111614e63576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614e6e836001615bae565b975095506000945061503b9350505050565b60f78111614ee5576000614e9560c083615bfe565b905080876000015111614ed4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061503b915050565b6000614ef260f783615bfe565b905080876000015111614f31576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614f93576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614fdb576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614fe58184615bae565b89511161501e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615029836001615bae565b975095506001945061503b9350505050565b9193909250565b60608167ffffffffffffffff81111561505d5761505d615a84565b6040519080825280601f01601f191660200182016040528015615087576020820181803683370190505b50905081156150d057600061509c8486615bae565b90506020820160005b848110156150bd5782810151828201526020016150a5565b848111156150cc576000858301525b5050505b9392505050565b60006150f66fffffffffffffffffffffffffffffffff84166001615ed5565b9050600061510682866001615327565b9050600086901a83806151f2575061513f60027f0000000000000000000000000000000000000000000000000000000000000000615e98565b60048301546002906151e3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6151ed9190615fa6565b60ff16145b1561524a5760ff81166001148061520c575060ff81166002145b615245576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016137e4565b612a86565b60ff811615612a86576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016137e4565b600080615315837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826153705761536b6fffffffffffffffffffffffffffffffff86167f000000000000000000000000000000000000000000000000000000000000000061543a565b61538b565b61538b856fffffffffffffffffffffffffffffffff166155c6565b9050600284815481106153a0576153a0615b50565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff82811691161461540357815460028054909163ffffffff169081106153ee576153ee615b50565b906000526020600020906005020191506153b1565b509392505050565b600080600080600061541c86614633565b935093509350935061543084848484614a3c565b9695505050505050565b6000816154d9846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116154ef5763b34b5c226000526004601cfd5b6154f8836155c6565b905081615597826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611612655576126526155ad836001615bae565b6fffffffffffffffffffffffffffffffff83169061566b565b6000811960018301168161565a827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b6000806156f8847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f84011261572657600080fd5b50813567ffffffffffffffff81111561573e57600080fd5b60208301915083602082850101111561575657600080fd5b9250929050565b600080600083850360a081121561577357600080fd5b608081121561578157600080fd5b50839250608084013567ffffffffffffffff81111561579f57600080fd5b6157ab86828701615714565b9497909650939450505050565b600080604083850312156157cb57600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310615844577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060006060848603121561585f57600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561589c57602081850181015186830182015201615880565b818111156158ae576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006126526020830184615876565b60006020828403121561590657600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461592f57600080fd5b50565b60006020828403121561594457600080fd5b81356150d08161590d565b8035801515811461595f57600080fd5b919050565b6000806000806080858703121561597a57600080fd5b8435935060208501359250604085013591506159986060860161594f565b905092959194509250565b6000602082840312156159b557600080fd5b81356fffffffffffffffffffffffffffffffff811681146150d057600080fd5b600080600080600080608087890312156159ee57600080fd5b863595506159fe6020880161594f565b9450604087013567ffffffffffffffff80821115615a1b57600080fd5b615a278a838b01615714565b90965094506060890135915080821115615a4057600080fd5b50615a4d89828a01615714565b979a9699509497509295939492505050565b63ffffffff841681528260208201526060604082015260006119006060830184615876565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060808284031215615ac557600080fd5b6040516080810181811067ffffffffffffffff82111715615b0f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115615bc157615bc1615b7f565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615bf757615bf7615b7f565b5060010190565b600082821015615c1057615c10615b7f565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615c5357615c53615c15565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615c9057615c90615b7f565b500290565b600060208284031215615ca757600080fd5b81516150d08161590d565b600060208284031215615cc457600080fd5b5051919050565b600067ffffffffffffffff808316818516808303821115615cee57615cee615b7f565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615d1e57615d1e615b7f565b02949350505050565b600067ffffffffffffffff83811690831681811015615d4857615d48615b7f565b039392505050565b60008060408385031215615d6357600080fd5b505080516020909101519092909150565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615db557615db5615b7f565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615df057615df0615b7f565b60008712925087820587128484161615615e0c57615e0c615b7f565b87850587128184161615615e2257615e22615b7f565b505050929093029392505050565b600082615e3f57615e3f615c15565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615e9357615e93615b7f565b500590565b600082615ea757615ea7615c15565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615d4857615d48615b7f565b60006fffffffffffffffffffffffffffffffff808316818516808303821115615cee57615cee615b7f565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615f5d606083018789615f00565b8281036020840152615f70818688615f00565b9150508260408301529695505050505050565b600060ff821660ff841680821015615f9d57615f9d615b7f565b90039392505050565b600060ff831680615fb957615fb9615c15565b8060ff8416069150509291505056fea164736f6c634300080f000a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004b0000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe7806000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309000000000000000000000000970670459734a83899773a0fd45941b5afc1200e000000000000000000000000000000000000000000000000000000000000038500000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c80000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63", - "deployedCode": "0x6080604052600436106103085760003560e01c806370872aa51161019a578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b94578063fa315aa914610bb8578063fe2bbeb214610beb57600080fd5b8063ec5e630814610b11578063eff0f59214610b44578063f8f43ff614610b7457600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a8b578063d8cc1a3c14610abe578063dabd396d14610ade57600080fd5b8063c6f0308c146109b3578063cf09e0d014610a3d578063d5d44d8014610a5e57600080fd5b8063a445ece611610143578063bcef3b551161011d578063bcef3b5514610933578063bd8da95614610973578063c395e1ca1461099357600080fd5b8063a445ece6146107f3578063a8e4fb90146108bf578063bbdc02db146108f257600080fd5b80638980e0cc116101745780638980e0cc1461076b5780638b85902b146107805780638d450a95146107c057600080fd5b806370872aa51461073b5780637b0f0adc146107505780638129fc1c1461076357600080fd5b80633fc8cef31161025e5780635c0cba33116102075780636361506d116101e15780636361506d146106b55780636b6716c0146106f55780636f0344091461072857600080fd5b80635c0cba331461064d578063609d33341461068057806360e274641461069557600080fd5b806354fd4d501161023857806354fd4d50146105a757806357da950e146105fd5780635a5fa2d91461062d57600080fd5b80633fc8cef31461052e578063472777c614610561578063534db0e21461057457600080fd5b80632810e1d6116102c057806337b1b2291161029a57806337b1b2291461047b5780633a768463146104bb5780633e3ac912146104ee57600080fd5b80632810e1d6146103f45780632ad69aeb1461040957806330dbe5701461042957600080fd5b806319effeb4116102f157806319effeb41461034f578063200d2ed21461039a57806325fc2ace146103d557600080fd5b8063019351301461030d57806303c2924d1461032f575b600080fd5b34801561031957600080fd5b5061032d61032836600461575d565b610c1b565b005b34801561033b57600080fd5b5061032d61034a3660046157b8565b610f3c565b34801561035b57600080fd5b5060005461037c9068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156103a657600080fd5b506000546103c890700100000000000000000000000000000000900460ff1681565b6040516103919190615809565b3480156103e157600080fd5b506008545b604051908152602001610391565b34801561040057600080fd5b506103c86115e2565b34801561041557600080fd5b506103e66104243660046157b8565b611887565b34801561043557600080fd5b506001546104569073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610391565b34801561048757600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610456565b3480156104c757600080fd5b507f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe7806610456565b3480156104fa57600080fd5b5060005461051e907201000000000000000000000000000000000000900460ff1681565b6040519015158152602001610391565b34801561053a57600080fd5b507f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309610456565b61032d61056f36600461584a565b6118bd565b34801561058057600080fd5b507f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63610456565b3480156105b357600080fd5b506105f06040518060400160405280600a81526020017f312e332e302d72632e310000000000000000000000000000000000000000000081525081565b60405161039191906158e1565b34801561060957600080fd5b50600854600954610618919082565b60408051928352602083019190915201610391565b34801561063957600080fd5b506103e66106483660046158f4565b6118cf565b34801561065957600080fd5b507f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e610456565b34801561068c57600080fd5b506105f0611909565b3480156106a157600080fd5b5061032d6106b0366004615932565b611917565b3480156106c157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103e6565b34801561070157600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061037c565b61032d610736366004615964565b611abe565b34801561074757600080fd5b506009546103e6565b61032d61075e36600461584a565b611b7f565b61032d611b8c565b34801561077757600080fd5b506002546103e6565b34801561078c57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103e6565b3480156107cc57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103e6565b3480156107ff57600080fd5b5061086b61080e3660046158f4565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff166060820152608001610391565b3480156108cb57600080fd5b507f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8610456565b3480156108fe57600080fd5b5060405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000001168152602001610391565b34801561093f57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103e6565b34801561097f57600080fd5b5061037c61098e3660046158f4565b611c05565b34801561099f57600080fd5b506103e66109ae3660046159a3565b611de4565b3480156109bf57600080fd5b506109d36109ce3660046158f4565b611fc7565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e001610391565b348015610a4957600080fd5b5060005461037c9067ffffffffffffffff1681565b348015610a6a57600080fd5b506103e6610a79366004615932565b60036020526000908152604090205481565b348015610a9757600080fd5b507f00000000000000000000000000000000000000000000000000000000000003856103e6565b348015610aca57600080fd5b5061032d610ad93660046159d5565b61205e565b348015610aea57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b061037c565b348015610b1d57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000046103e6565b348015610b5057600080fd5b5061051e610b5f3660046158f4565b60046020526000908152604090205460ff1681565b348015610b8057600080fd5b5061032d610b8f36600461584a565b612123565b348015610ba057600080fd5b50610ba96125e0565b60405161039193929190615a5f565b348015610bc457600080fd5b507f00000000000000000000000000000000000000000000000000000000000000086103e6565b348015610bf757600080fd5b5061051e610c063660046158f4565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610c4757610c476157da565b14610c7e576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610cd1576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d08367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610d1f610d1a36869003860186615ab3565b61265b565b14610d56576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610d6b929190615b40565b604051809103902014610daa576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610df3610dee84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506126b792505050565b612724565b90506000610e1a82600881518110610e0d57610e0d615b50565b60200260200101516128da565b9050602081511115610e58576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610ecd576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610f6857610f686157da565b14610f9f576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610fb457610fb4615b50565b906000526020600020906005020190506000610fcf84611c05565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b081169082161015611038576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611081576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561109e57508515155b15611139578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110d157816110ed565b600186015473ffffffffffffffffffffffffffffffffffffffff165b90506110f9818761298e565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff1660608301526111dc576fffffffffffffffffffffffffffffffff60408201526001815260008690036111dc578195505b600086826020015163ffffffff166111f49190615bae565b905060008382116112055781611207565b835b602084015190915063ffffffff165b8181101561135357600086828154811061123257611232615b50565b6000918252602080832090910154808352600690915260409091205490915060ff1661128a576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002828154811061129f5761129f615b50565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112fc5750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b1561133e57600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b5050808061134b90615bc6565b915050611216565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909316929092179091558490036115d757606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055891580156114d357506000547201000000000000000000000000000000000000900460ff165b156115485760015473ffffffffffffffffffffffffffffffffffffffff166114fb818a61298e565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff9091161788556115d5565b61158f73ffffffffffffffffffffffffffffffffffffffff82161561156d5781611589565b600189015473ffffffffffffffffffffffffffffffffffffffff165b8961298e565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff166002811115611610576116106157da565b14611647576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff166116ab576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660026000815481106116d7576116d7615b50565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611712576001611715565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff909116177001000000000000000000000000000000008360028111156117c6576117c66157da565b0217905560028111156117db576117db6157da565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e73ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561186c57600080fd5b505af1158015611880573d6000803e3d6000fd5b5050505090565b600560205281600052604060002081815481106118a357600080fd5b90600052602060002001600091509150505481565b905090565b6118ca8383836001611abe565b505050565b6000818152600760209081526040808320600590925282208054825461190090610100900463ffffffff1682615bfe565b95945050505050565b60606118b860546020612a8f565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604081208054908290559081900361197c576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309169063f3fef3a390604401600060405180830381600087803b158015611a0c57600080fd5b505af1158015611a20573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a7e576040519150601f19603f3d011682016040523d82523d6000602084013e611a83565b606091505b50509050806118ca576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8161480611b3757503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b6316145b611b6d576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b7984848484612ae1565b50505050565b6118ca8383836000611abe565b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c81614611bfb576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c036135ba565b565b600080600054700100000000000000000000000000000000900460ff166002811115611c3357611c336157da565b14611c6a576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110611c7f57611c7f615b50565b600091825260208220600590910201805490925063ffffffff90811614611cee57815460028054909163ffffffff16908110611cbd57611cbd615b50565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090611d2690700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b611d3a9067ffffffffffffffff1642615bfe565b611d59611d19846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16611d6d9190615bae565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b01667ffffffffffffffff168167ffffffffffffffff1611611dba5780611900565b7f00000000000000000000000000000000000000000000000000000000000004b095945050505050565b600080611e83836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000008811115611ee2576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000611efd8383615c44565b9050670de0b6b3a76400006000611f34827f0000000000000000000000000000000000000000000000000000000000000008615c58565b90506000611f52611f4d670de0b6b3a764000086615c58565b613b13565b90506000611f608484613d6e565b90506000611f6e8383613dbd565b90506000611f7b82613deb565b90506000611f9a82611f95670de0b6b3a76400008f615c58565b613fd3565b90506000611fa88b83613dbd565b9050611fb4818d615c58565b9f9e505050505050505050505050505050565b60028181548110611fd757600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c81614806120d757503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b6316145b61210d576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61211b868686868686614004565b505050505050565b60008054700100000000000000000000000000000000900460ff16600281111561214f5761214f6157da565b14612186576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061219586614633565b935093509350935060006121ab85858585614a3c565b905060007f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561221a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223e9190615c95565b9050600189036123365773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8461229a367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af115801561230c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123309190615cb2565b506115d7565b600289036123625773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848961229a565b6003890361238e5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848761229a565b600489036125155760006123d46fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000004614af6565b6009546123e19190615bae565b6123ec906001615bae565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061245557367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135612457565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156124ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250e9190615cb2565b50506115d7565b600589036125ae576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000038560c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016122ed565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000001367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060612639611909565b9050909192565b6000818310156126505781612652565b825b90505b92915050565b6000816000015182602001518360400151846060015160405160200161269a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003612706576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b6060600080600061273485614ba4565b91945092509050600181600181111561274f5761274f6157da565b14612786576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516127928385615bae565b146127c9576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816127e05790505093506000835b86518110156128ce576000806128536040518060400160405280858c600001516128379190615bfe565b8152602001858c6020015161284c9190615bae565b9052614ba4565b50915091506040518060400160405280838361286f9190615bae565b8152602001848b602001516128849190615bae565b81525088858151811061289957612899615b50565b60209081029190910101526128af600185615bae565b93506128bb8183615bae565b6128c59084615bae565b9250505061280d565b50845250919392505050565b606060008060006128ea85614ba4565b919450925090506000816001811115612905576129056157da565b1461293c576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129468284615bae565b85511461297f576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61190085602001518484615042565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff909316928392906129dd908490615bae565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f000000000000000000000000d6eaf4c146261653ee059077b78ed088add543091690637eee288d90604401600060405180830381600087803b158015612a7257600080fd5b505af1158015612a86573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b60008054700100000000000000000000000000000000900460ff166002811115612b0d57612b0d6157da565b14612b44576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110612b5957612b59615b50565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514612c40576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000612d00826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580612d3b5750612d387f00000000000000000000000000000000000000000000000000000000000000046002615bae565b81145b8015612d45575084155b15612d7c576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015612da2575086155b15612dd9576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000008811115612e33576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e5e7f00000000000000000000000000000000000000000000000000000000000000046001615bae565b8103612e7057612e70868885886150d7565b34612e7a83611de4565b14612eb1576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612ebc88611c05565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b0811690821603612f24576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612f5160017f0000000000000000000000000000000000000000000000000000000000000008615bfe565b830361308f577f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fe69190615c95565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015613030573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130549190615cb2565b613088907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16615ccb565b9050613122565b6130ba60017f0000000000000000000000000000000000000000000000000000000000000004615bfe565b83036130f5576130887f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166002615cf7565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b613156817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615d27565b67ffffffffffffffff166131718367ffffffffffffffff1690565b67ffffffffffffffff1611156131b8576131b5817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615d27565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615613236576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c815260200190815260200160002060016002805490506134cc9190615bfe565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309169263d0e30db09234926004808301939282900301818588803b15801561356457600080fd5b505af1158015613578573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b60005471010000000000000000000000000000000000900460ff161561360c576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000001166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e1690637258a807906024016040805180830381865afa1580156136c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136e49190615d50565b909250905081613720576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a1461375357639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135116137ed576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f000000000000000000000000d6eaf4c146261653ee059077b78ed088add543099092169363d0e30db093926004828101939282900301818588803b158015613ac257600080fd5b505af1158015613ad6573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b1760008213613b7257631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a764000002158202613dab57637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b600081600019048311820215613ddb5763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d78213613e1957919050565b680755bf798b4a1bf1e58212613e375763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000612652670de0b6b3a764000083613feb86613b13565b613ff59190615d74565b613fff9190615e30565b613deb565b60008054700100000000000000000000000000000000900460ff166002811115614030576140306157da565b14614067576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002878154811061407c5761407c615b50565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506140db7f00000000000000000000000000000000000000000000000000000000000000086001615bae565b614177826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16146141b1576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008089156142a8576142047f00000000000000000000000000000000000000000000000000000000000000047f0000000000000000000000000000000000000000000000000000000000000008615bfe565b6001901b614223846fffffffffffffffffffffffffffffffff16615288565b6fffffffffffffffffffffffffffffffff1661423f9190615e98565b1561427c5761427361426460016fffffffffffffffffffffffffffffffff8716615eac565b865463ffffffff166000615327565b6003015461429e565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506142d2565b600385015491506142cf6142646fffffffffffffffffffffffffffffffff86166001615ed5565b90505b600882901b60088a8a6040516142e9929190615b40565b6040518091039020901b1461432a576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006143358c61540b565b90506000614344836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff169063e14ced32906143be908f908f908f908f908a90600401615f49565b6020604051808303816000875af11580156143dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144019190615cb2565b6004850154911491506000906002906144ac906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b614548896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6145529190615f83565b61455c9190615fa6565b60ff16159050811515810361459d576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156145f4576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b600080600080600085905060006002828154811061465357614653615b50565b600091825260209091206004600590920201908101549091507f00000000000000000000000000000000000000000000000000000000000000049061472a906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611614764576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f00000000000000000000000000000000000000000000000000000000000000049061482b906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1692508211156148a057825463ffffffff1661486a7f00000000000000000000000000000000000000000000000000000000000000046001615bae565b8303614874578391505b6002818154811061488757614887615b50565b9060005260206000209060050201935080945050614768565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149096148f4856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff1614905080156149d8576000614941836fffffffffffffffffffffffffffffffff16615288565b6fffffffffffffffffffffffffffffffff1611156149ac57600061498361497b60016fffffffffffffffffffffffffffffffff8616615eac565b896001615327565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a506149b29050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614a2e565b60006149fa61497b6fffffffffffffffffffffffffffffffff85166001615ed5565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614aa95760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611900565b8282604051602001614ad79291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614b83847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614be7576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614c0c57600060016000945094509450505061503b565b60b78111614d22576000614c21608083615bfe565b905080876000015111614c60576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614cd857507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614d0f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061503b915050565b60bf8111614e80576000614d3760b783615bfe565b905080876000015111614d76576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614dd8576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614e20576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614e2a8184615bae565b895111614e63576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614e6e836001615bae565b975095506000945061503b9350505050565b60f78111614ee5576000614e9560c083615bfe565b905080876000015111614ed4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061503b915050565b6000614ef260f783615bfe565b905080876000015111614f31576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614f93576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614fdb576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614fe58184615bae565b89511161501e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615029836001615bae565b975095506001945061503b9350505050565b9193909250565b60608167ffffffffffffffff81111561505d5761505d615a84565b6040519080825280601f01601f191660200182016040528015615087576020820181803683370190505b50905081156150d057600061509c8486615bae565b90506020820160005b848110156150bd5782810151828201526020016150a5565b848111156150cc576000858301525b5050505b9392505050565b60006150f66fffffffffffffffffffffffffffffffff84166001615ed5565b9050600061510682866001615327565b9050600086901a83806151f2575061513f60027f0000000000000000000000000000000000000000000000000000000000000004615e98565b60048301546002906151e3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6151ed9190615fa6565b60ff16145b1561524a5760ff81166001148061520c575060ff81166002145b615245576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016137e4565b612a86565b60ff811615612a86576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016137e4565b600080615315837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826153705761536b6fffffffffffffffffffffffffffffffff86167f000000000000000000000000000000000000000000000000000000000000000461543a565b61538b565b61538b856fffffffffffffffffffffffffffffffff166155c6565b9050600284815481106153a0576153a0615b50565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff82811691161461540357815460028054909163ffffffff169081106153ee576153ee615b50565b906000526020600020906005020191506153b1565b509392505050565b600080600080600061541c86614633565b935093509350935061543084848484614a3c565b9695505050505050565b6000816154d9846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116154ef5763b34b5c226000526004601cfd5b6154f8836155c6565b905081615597826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611612655576126526155ad836001615bae565b6fffffffffffffffffffffffffffffffff83169061566b565b6000811960018301168161565a827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b6000806156f8847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f84011261572657600080fd5b50813567ffffffffffffffff81111561573e57600080fd5b60208301915083602082850101111561575657600080fd5b9250929050565b600080600083850360a081121561577357600080fd5b608081121561578157600080fd5b50839250608084013567ffffffffffffffff81111561579f57600080fd5b6157ab86828701615714565b9497909650939450505050565b600080604083850312156157cb57600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310615844577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060006060848603121561585f57600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561589c57602081850181015186830182015201615880565b818111156158ae576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006126526020830184615876565b60006020828403121561590657600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461592f57600080fd5b50565b60006020828403121561594457600080fd5b81356150d08161590d565b8035801515811461595f57600080fd5b919050565b6000806000806080858703121561597a57600080fd5b8435935060208501359250604085013591506159986060860161594f565b905092959194509250565b6000602082840312156159b557600080fd5b81356fffffffffffffffffffffffffffffffff811681146150d057600080fd5b600080600080600080608087890312156159ee57600080fd5b863595506159fe6020880161594f565b9450604087013567ffffffffffffffff80821115615a1b57600080fd5b615a278a838b01615714565b90965094506060890135915080821115615a4057600080fd5b50615a4d89828a01615714565b979a9699509497509295939492505050565b63ffffffff841681528260208201526060604082015260006119006060830184615876565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060808284031215615ac557600080fd5b6040516080810181811067ffffffffffffffff82111715615b0f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115615bc157615bc1615b7f565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615bf757615bf7615b7f565b5060010190565b600082821015615c1057615c10615b7f565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615c5357615c53615c15565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615c9057615c90615b7f565b500290565b600060208284031215615ca757600080fd5b81516150d08161590d565b600060208284031215615cc457600080fd5b5051919050565b600067ffffffffffffffff808316818516808303821115615cee57615cee615b7f565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615d1e57615d1e615b7f565b02949350505050565b600067ffffffffffffffff83811690831681811015615d4857615d48615b7f565b039392505050565b60008060408385031215615d6357600080fd5b505080516020909101519092909150565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615db557615db5615b7f565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615df057615df0615b7f565b60008712925087820587128484161615615e0c57615e0c615b7f565b87850587128184161615615e2257615e22615b7f565b505050929093029392505050565b600082615e3f57615e3f615c15565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615e9357615e93615b7f565b500590565b600082615ea757615ea7615c15565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615d4857615d48615b7f565b60006fffffffffffffffffffffffffffffffff808316818516808303821115615cee57615cee615b7f565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615f5d606083018789615f00565b8281036020840152615f70818688615f00565b9150508260408301529695505050505050565b600060ff821660ff841680821015615f9d57615f9d615b7f565b90039392505050565b600060ff831680615fb957615fb9615c15565b8060ff8416069150509291505056fea164736f6c634300080f000a", - "initialized": true, - "kind": "Create", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x59B99034FBdd5E554661a2100cB2b6b7C5d495F8", - "account": "0x444e09fe6D839273316a87002aB0EFBeA6fe7806", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x7dc0d1d0", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x59B99034FBdd5E554661a2100cB2b6b7C5d495F8", - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf3f480d9", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x59B99034FBdd5E554661a2100cB2b6b7C5d495F8", - "account": "0x444e09fe6D839273316a87002aB0EFBeA6fe7806", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x7dc0d1d0", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x59B99034FBdd5E554661a2100cB2b6b7C5d495F8", - "account": "0x373d916D11cce55b548F7051002e76BCFBD7a85d", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf3f480d9", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x14f6b1a3000000000000000000000000000000000000000000000000000000000000000100000000000000000000000059b99034fbdd5e554661a2100cb2b6b7c5d495f8", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765", - "previousValue": "0x00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x14f6b1a3000000000000000000000000000000000000000000000000000000000000000100000000000000000000000059b99034fbdd5e554661a2100cb2b6b7c5d495f8", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4d5a9bd2e41301728d41c8e705190becb4e74abe869f75bdb405b63716a35f9e" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": true, - "newValue": "0x00000000000000000000000059b99034fbdd5e554661a2100cb2b6b7c5d495f8", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", - "reverted": false, - "slot": "0x4d5a9bd2e41301728d41c8e705190becb4e74abe869f75bdb405b63716a35f9e" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765", - "previousValue": "0x00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf2fde38b0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765", - "previousValue": "0x00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf2fde38b0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": true, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765", - "previousValue": "0x00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x20B168142354Cee65a32f6D8cf3033E592299765", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d", - "isWrite": false, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "previousValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf2fde38b0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "deployedCode": "0x", - "initialized": true, - "kind": "Call", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "previousValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0xf2fde38b0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - }, - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": true, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "previousValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x8da5cb5b", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "previousValue": "0x0000000000000000000000007c0c8a15773ed7b50e7c738d1af4c5e3a2b210bd", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x7a07653f", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", - "isWrite": false, - "newValue": "0x0000000000000000000000000000000000000000000000000000000000093a80", - "previousValue": "0x0000000000000000000000000000000000000000000000000000000000093a80", - "reverted": false, - "slot": "0x000000000000000000000000000000000000000000000000000000000000003b" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a42b8f8", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "previousValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x6a42b8f8", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x79502c55", - "deployedCode": "0x", - "initialized": true, - "kind": "StaticCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "previousValue": "0x0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05", - "reverted": false, - "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - } - ], - "value": 0 - }, - { - "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", - "account": "0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x79502c55", - "deployedCode": "0x", - "initialized": true, - "kind": "DelegateCall", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [ - { - "account": "0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92", - "isWrite": false, - "newValue": "0x0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "previousValue": "0x0000000000000000000000004f559f30f5eb88d635fde1548c4267db8fab0351", - "reverted": false, - "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" - } - ], - "value": 0 - }, - { - "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", - "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", - "chainInfo": { - "chainId": 31337, - "forkId": 0 - }, - "data": "0x", - "deployedCode": "0x", - "initialized": true, - "kind": "Resume", - "newBalance": 0, - "oldBalance": 0, - "reverted": false, - "storageAccesses": [], - "value": 0 - } - ] -} diff --git a/packages/contracts-bedrock/test/kontrol/deployment/DeploymentSummary.t.sol b/packages/contracts-bedrock/test/kontrol/deployment/DeploymentSummary.t.sol deleted file mode 100644 index c9c351e143e3..000000000000 --- a/packages/contracts-bedrock/test/kontrol/deployment/DeploymentSummary.t.sol +++ /dev/null @@ -1,254 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Libraries -import { Constants } from "src/libraries/Constants.sol"; -import { Predeploys } from "src/libraries/Predeploys.sol"; - -// Target contract dependencies -import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; -import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; -import { DeploymentSummary } from "../proofs/utils/DeploymentSummary.sol"; -import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; -import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import { LegacyMintableERC20 } from "src/legacy/LegacyMintableERC20.sol"; - -// Tests -import { L1CrossDomainMessenger_Test } from "test/L1/L1CrossDomainMessenger.t.sol"; -import { OptimismPortal_Test } from "test/L1/OptimismPortal.t.sol"; -import { L1ERC721Bridge_Test, TestERC721 } from "test/L1/L1ERC721Bridge.t.sol"; -import { - L1StandardBridge_Getter_Test, - L1StandardBridge_Initialize_Test, - L1StandardBridge_Pause_Test -} from "test/L1/L1StandardBridge.t.sol"; - -/// @dev Contract testing the deployment summary correctness -contract DeploymentSummary_TestOptimismPortal is DeploymentSummary, OptimismPortal_Test { - /// @notice super.setUp is not called on purpose - function setUp() public override { - // Recreate Deployment Summary state changes - DeploymentSummary deploymentSummary = new DeploymentSummary(); - deploymentSummary.recreateDeployment(); - - // Set summary addresses - optimismPortal = OptimismPortal(payable(optimismPortalProxyAddress)); - superchainConfig = SuperchainConfig(superchainConfigProxyAddress); - l2OutputOracle = L2OutputOracle(l2OutputOracleProxyAddress); - systemConfig = SystemConfig(systemConfigProxyAddress); - - // Set up utilized addresses - depositor = makeAddr("depositor"); - alice = makeAddr("alice"); - bob = makeAddr("bob"); - vm.deal(alice, 10000 ether); - vm.deal(bob, 10000 ether); - } - - /// @dev Skips the first line of `super.test_constructor_succeeds` because - /// we're not exercising the `Deploy` logic in these tests. However, - /// the remaining assertions of the test are important to check - function test_constructor_succeeds() external view override { - // OptimismPortal opImpl = OptimismPortal(payable(deploy.mustGetAddress("OptimismPortal"))); - OptimismPortal opImpl = OptimismPortal(payable(optimismPortalAddress)); - assertEq(address(opImpl.l2Oracle()), address(0)); - assertEq(address(opImpl.systemConfig()), address(0)); - assertEq(address(opImpl.superchainConfig()), address(0)); - assertEq(opImpl.l2Sender(), Constants.DEFAULT_L2_SENDER); - } - - /// @dev Skips the first line of `super.test_initialize_succeeds` because - /// we're not exercising the `Deploy` logic in these tests. However, - /// the remaining assertions of the test are important to check - function test_initialize_succeeds() external view override { - // address guardian = deploy.cfg().superchainConfigGuardian(); - address guardian = superchainConfig.guardian(); - assertEq(address(optimismPortal.l2Oracle()), address(l2OutputOracle)); - assertEq(address(optimismPortal.systemConfig()), address(systemConfig)); - assertEq(optimismPortal.guardian(), guardian); - assertEq(address(optimismPortal.superchainConfig()), address(superchainConfig)); - assertEq(optimismPortal.l2Sender(), Constants.DEFAULT_L2_SENDER); - assertEq(optimismPortal.paused(), false); - } - - /// @notice This test is overridden because `KontrolDeployment` doesn't initialize - /// the L2OutputOracle, which is needed in this test - function test_simple_isOutputFinalized_succeeds() external override { } - - /// @notice This test is overridden because `KontrolDeployment` doesn't initialize - /// the L2OutputOracle, which is needed in this test - function test_isOutputFinalized_succeeds() external override { } -} - -contract DeploymentSummary_TestL1CrossDomainMessenger is DeploymentSummary, L1CrossDomainMessenger_Test { - /// @notice super.setUp is not called on purpose - function setUp() public override { - // Recreate Deployment Summary state changes - DeploymentSummary deploymentSummary = new DeploymentSummary(); - deploymentSummary.recreateDeployment(); - - // Set summary addresses - optimismPortal = OptimismPortal(payable(optimismPortalProxyAddress)); - superchainConfig = SuperchainConfig(superchainConfigProxyAddress); - l2OutputOracle = L2OutputOracle(l2OutputOracleProxyAddress); - systemConfig = SystemConfig(systemConfigProxyAddress); - l1CrossDomainMessenger = L1CrossDomainMessenger(l1CrossDomainMessengerProxyAddress); - - // Set up utilized addresses - alice = makeAddr("alice"); - bob = makeAddr("bob"); - vm.deal(alice, 10000 ether); - vm.deal(bob, 10000 ether); - } - - /// @dev Skips the first line of `super.test_constructor_succeeds` because - /// we're not exercising the `Deploy` logic in these tests. However, - /// the remaining assertions of the test are important to check - function test_constructor_succeeds() external view override { - // L1CrossDomainMessenger impl = L1CrossDomainMessenger(deploy.mustGetAddress("L1CrossDomainMessenger")); - L1CrossDomainMessenger impl = L1CrossDomainMessenger(l1CrossDomainMessengerAddress); - assertEq(address(impl.superchainConfig()), address(0)); - assertEq(address(impl.PORTAL()), address(0)); - assertEq(address(impl.portal()), address(0)); - assertEq(address(impl.OTHER_MESSENGER()), Predeploys.L2_CROSS_DOMAIN_MESSENGER); - assertEq(address(impl.otherMessenger()), Predeploys.L2_CROSS_DOMAIN_MESSENGER); - } - - /// @notice This test is overridden because `KontrolDeployment` doesn't deploy - /// L2CrossDomainMessenger, which is needed in this test - function test_relayMessage_v2_reverts() external override { } -} - -contract DeploymentSummary_TestL1ERC721Bridge is DeploymentSummary, L1ERC721Bridge_Test { - /// @notice super.setUp is not called on purpose - function setUp() public override { - // Recreate Deployment Summary state changes - DeploymentSummary deploymentSummary = new DeploymentSummary(); - deploymentSummary.recreateDeployment(); - - // Set summary addresses - optimismPortal = OptimismPortal(payable(optimismPortalProxyAddress)); - superchainConfig = SuperchainConfig(superchainConfigProxyAddress); - l2OutputOracle = L2OutputOracle(l2OutputOracleProxyAddress); - systemConfig = SystemConfig(systemConfigProxyAddress); - l1CrossDomainMessenger = L1CrossDomainMessenger(l1CrossDomainMessengerProxyAddress); - l1ERC721Bridge = L1ERC721Bridge(l1ERC721BridgeProxyAddress); - - // Set up utilized addresses - alice = makeAddr("alice"); - bob = makeAddr("bob"); - vm.deal(alice, 10000 ether); - vm.deal(bob, 10000 ether); - - // Bridge_Initializer setUp - L1Token = new ERC20("Native L1 Token", "L1T"); - - LegacyL2Token = new LegacyMintableERC20({ - _l2Bridge: address(l2StandardBridge), - _l1Token: address(L1Token), - _name: string.concat("LegacyL2-", L1Token.name()), - _symbol: string.concat("LegacyL2-", L1Token.symbol()) - }); - vm.label(address(LegacyL2Token), "LegacyMintableERC20"); - - // Deploy the L2 ERC20 now - // L2Token = OptimismMintableERC20( - // l2OptimismMintableERC20Factory.createStandardL2Token( - // address(L1Token), - // string(abi.encodePacked("L2-", L1Token.name())), - // string(abi.encodePacked("L2-", L1Token.symbol())) - // ) - // ); - - // BadL2Token = OptimismMintableERC20( - // l2OptimismMintableERC20Factory.createStandardL2Token( - // address(1), - // string(abi.encodePacked("L2-", L1Token.name())), - // string(abi.encodePacked("L2-", L1Token.symbol())) - // ) - // ); - - NativeL2Token = new ERC20("Native L2 Token", "L2T"); - - // RemoteL1Token = OptimismMintableERC20( - // l1OptimismMintableERC20Factory.createStandardL2Token( - // address(NativeL2Token), - // string(abi.encodePacked("L1-", NativeL2Token.name())), - // string(abi.encodePacked("L1-", NativeL2Token.symbol())) - // ) - // ); - - // BadL1Token = OptimismMintableERC20( - // l1OptimismMintableERC20Factory.createStandardL2Token( - // address(1), - // string(abi.encodePacked("L1-", NativeL2Token.name())), - // string(abi.encodePacked("L1-", NativeL2Token.symbol())) - // ) - // ); - - // L1ERC721Bridge_Test setUp - localToken = new TestERC721(); - remoteToken = new TestERC721(); - - // Mint alice a token. - localToken.mint(alice, tokenId); - - // Approve the bridge to transfer the token. - vm.prank(alice); - localToken.approve(address(l1ERC721Bridge), tokenId); - } - - /// @dev Skips the first line of `super.test_constructor_succeeds` because - /// we're not exercising the `Deploy` logic in these tests. However, - /// the remaining assertions of the test are important to check - function test_constructor_succeeds() public view override { - // L1ERC721Bridge impl = L1ERC721Bridge(deploy.mustGetAddress("L1ERC721Bridge")); - L1ERC721Bridge impl = L1ERC721Bridge(l1ERC721BridgeAddress); - assertEq(address(impl.MESSENGER()), address(0)); - assertEq(address(impl.messenger()), address(0)); - assertEq(address(impl.OTHER_BRIDGE()), Predeploys.L2_ERC721_BRIDGE); - assertEq(address(impl.otherBridge()), Predeploys.L2_ERC721_BRIDGE); - assertEq(address(impl.superchainConfig()), address(0)); - } -} - -contract DeploymentSummary_TestL1StandardBridge is - DeploymentSummary, - L1StandardBridge_Getter_Test, - L1StandardBridge_Initialize_Test, - L1StandardBridge_Pause_Test -{ - /// @notice super.setUp is not called on purpose - function setUp() public override { - // Recreate Deployment Summary state changes - DeploymentSummary deploymentSummary = new DeploymentSummary(); - deploymentSummary.recreateDeployment(); - - // Set summary addresses - optimismPortal = OptimismPortal(payable(optimismPortalProxyAddress)); - superchainConfig = SuperchainConfig(superchainConfigProxyAddress); - l2OutputOracle = L2OutputOracle(l2OutputOracleProxyAddress); - systemConfig = SystemConfig(systemConfigProxyAddress); - l1CrossDomainMessenger = L1CrossDomainMessenger(l1CrossDomainMessengerProxyAddress); - l1ERC721Bridge = L1ERC721Bridge(l1ERC721BridgeProxyAddress); - l1StandardBridge = L1StandardBridge(payable(l1StandardBridgeProxyAddress)); - } - - /// @dev Skips the first line of `super.test_constructor_succeeds` because - /// we're not exercising the `Deploy` logic in these tests. However, - /// the remaining assertions of the test are important to check - function test_constructor_succeeds() external view override { - // L1StandardBridge impl = L1StandardBridge(deploy.mustGetAddress("L1StandardBridge")); - L1StandardBridge impl = L1StandardBridge(payable(l1StandardBridgeAddress)); - assertEq(address(impl.superchainConfig()), address(0)); - assertEq(address(impl.MESSENGER()), address(0)); - assertEq(address(impl.messenger()), address(0)); - assertEq(address(impl.OTHER_BRIDGE()), Predeploys.L2_STANDARD_BRIDGE); - assertEq(address(impl.otherBridge()), Predeploys.L2_STANDARD_BRIDGE); - assertEq(address(l2StandardBridge), Predeploys.L2_STANDARD_BRIDGE); - } -} diff --git a/packages/contracts-bedrock/test/kontrol/deployment/DeploymentSummaryFaultProofs.t.sol b/packages/contracts-bedrock/test/kontrol/deployment/DeploymentSummaryFaultProofs.t.sol deleted file mode 100644 index 2f96f3145119..000000000000 --- a/packages/contracts-bedrock/test/kontrol/deployment/DeploymentSummaryFaultProofs.t.sol +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Libraries -import { Constants } from "src/libraries/Constants.sol"; -import { Predeploys } from "src/libraries/Predeploys.sol"; - -// Target contract dependencies -import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; -import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; -import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; -import { DeploymentSummaryFaultProofs } from "../proofs/utils/DeploymentSummaryFaultProofs.sol"; -import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; -import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import { LegacyMintableERC20 } from "src/legacy/LegacyMintableERC20.sol"; - -// Tests -import { L1CrossDomainMessenger_Test } from "test/L1/L1CrossDomainMessenger.t.sol"; -import { OptimismPortal2_Test } from "test/L1/OptimismPortal2.t.sol"; -import { L1ERC721Bridge_Test, TestERC721 } from "test/L1/L1ERC721Bridge.t.sol"; -import { - L1StandardBridge_Getter_Test, - L1StandardBridge_Initialize_Test, - L1StandardBridge_Pause_Test -} from "test/L1/L1StandardBridge.t.sol"; - -/// @dev Contract testing the deployment summary correctness -contract DeploymentSummaryFaultProofs_TestOptimismPortal is DeploymentSummaryFaultProofs, OptimismPortal2_Test { - /// @notice super.setUp is not called on purpose - function setUp() public override { - // Recreate Deployment Summary state changes - DeploymentSummaryFaultProofs deploymentSummary = new DeploymentSummaryFaultProofs(); - deploymentSummary.recreateDeployment(); - - // Set summary addresses - optimismPortal2 = OptimismPortal2(payable(optimismPortalProxyAddress)); - superchainConfig = SuperchainConfig(superchainConfigProxyAddress); - disputeGameFactory = DisputeGameFactory(disputeGameFactoryProxyAddress); - systemConfig = SystemConfig(systemConfigProxyAddress); - - // Set up utilized addresses - depositor = makeAddr("depositor"); - alice = makeAddr("alice"); - bob = makeAddr("bob"); - vm.deal(alice, 10000 ether); - vm.deal(bob, 10000 ether); - } - - /// @dev Skips the first line of `super.test_constructor_succeeds` because - /// we're not exercising the `Deploy` logic in these tests. However, - /// the remaining assertions of the test are important to check - function test_constructor_succeeds() external view override { - // OptimismPortal opImpl = OptimismPortal(payable(deploy.mustGetAddress("OptimismPortal"))); - OptimismPortal2 opImpl = OptimismPortal2(payable(optimismPortal2Address)); - assertEq(address(opImpl.disputeGameFactory()), address(0)); - assertEq(address(opImpl.systemConfig()), address(0)); - assertEq(address(opImpl.superchainConfig()), address(0)); - assertEq(opImpl.l2Sender(), Constants.DEFAULT_L2_SENDER); - } - - /// @dev Skips the first line of `super.test_initialize_succeeds` because - /// we're not exercising the `Deploy` logic in these tests. However, - /// the remaining assertions of the test are important to check - function test_initialize_succeeds() external view override { - // address guardian = deploy.cfg().superchainConfigGuardian(); - address guardian = superchainConfig.guardian(); - assertEq(address(optimismPortal2.disputeGameFactory()), address(disputeGameFactory)); - assertEq(address(optimismPortal2.systemConfig()), address(systemConfig)); - assertEq(optimismPortal2.guardian(), guardian); - assertEq(address(optimismPortal2.superchainConfig()), address(superchainConfig)); - assertEq(optimismPortal2.l2Sender(), Constants.DEFAULT_L2_SENDER); - assertEq(optimismPortal2.paused(), false); - } -} From 337749f8d9fd929762606eebadd5693bae407071 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Tue, 3 Sep 2024 21:05:55 -0400 Subject: [PATCH 024/264] feat: check interface differences in CI (#11677) Adds a new check script to contracts-bedrock that verifies that interfaces being added to the repository accurately represent the interface of the contract that the interface was generated for. --- .circleci/config.yml | 9 + packages/contracts-bedrock/justfile | 9 + .../scripts/checks/check-interfaces.sh | 179 ++++++++++++++++++ 3 files changed, 197 insertions(+) create mode 100755 packages/contracts-bedrock/scripts/checks/check-interfaces.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 6ef7dff3d7ba..f1308ae13080 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -620,6 +620,11 @@ jobs: command: | just kontrol-deployment-check || echo "export KONTROL_DEPLOYMENT_STATUS=1" >> "$BASH_ENV" working_directory: packages/contracts-bedrock + - run: + name: interfaces + command: | + just interfaces-check-no-build || echo "export INTERFACES_STATUS=1" >> "$BASH_ENV" + working_directory: packages/contracts-bedrock - run: name: size check command: | @@ -662,6 +667,10 @@ jobs: echo "Kontrol deployment check failed, see job output for details." FAILED=1 fi + if [[ "$INTERFACES_STATUS" -ne 0 ]]; then + echo "Interface check failed, see job output for details." + FAILED=1 + fi if [[ "$SIZE_CHECK" -ne 0 ]]; then echo "Contract(s) exceed size limit, see job output for details." FAILED=1 diff --git a/packages/contracts-bedrock/justfile b/packages/contracts-bedrock/justfile index 58c5d3b0b93d..995c4b71eb71 100644 --- a/packages/contracts-bedrock/justfile +++ b/packages/contracts-bedrock/justfile @@ -82,6 +82,15 @@ snapshots: build snapshots-no-build snapshots-check: ./scripts/checks/check-snapshots.sh +# Checks interface correctness without building. +interfaces-check-no-build: + ./scripts/checks/check-interfaces.sh + +# Checks that all interfaces are appropriately named and accurately reflect the corresponding +# contract that they're meant to represent. We run "clean" before building because leftover +# artifacts can cause the script to detect issues incorrectly.2 +interfaces-check: clean build interfaces-check-no-build + semver-lock: forge script scripts/autogen/SemverLock.s.sol diff --git a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh new file mode 100755 index 000000000000..a3b15768b73c --- /dev/null +++ b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh @@ -0,0 +1,179 @@ +#!/usr/bin/env bash +set -euo pipefail + +# This script checks for ABI consistency between interfaces and their corresponding contracts. +# It compares the ABIs of interfaces (files starting with 'I') with their implementation contracts, +# excluding constructors and certain predefined files. The script reports any differences found +# and exits with an error if inconsistencies are detected. +# NOTE: Script is fast enough but could be parallelized if necessary. + +# Parse flags +no_diff=false +if [[ "${1:-}" == "--no-diff" ]]; then + no_diff=true +fi + +# Grab the directory of the contracts-bedrock package +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +CONTRACTS_BASE=$(dirname "$(dirname "$SCRIPT_DIR")") + +# Define the files to exclude (glob patterns can be used) +EXCLUDE_FILES=( + # External dependencies + "IMulticall3" + "IERC20" + "IERC721" + "IERC721Enumerable" + "IERC721Metadata" + "IERC721Upgradeable" + "IERC721Receiver" + "IERC1271" + "IERC165" + "IVotes" + "IBeacon" + "IProxyCreationCallback" + "IAutomate" + "IGelato1Balance" + "ERC721TokenReceiver" + "ERC1155TokenReceiver" + "ERC777TokensRecipient" + "Guard" + "GnosisSafeProxy" + + # Foundry + "Common" + "Vm" + "VmSafe" + + # EAS + "IEAS" + "ISchemaResolver" + "ISchemaRegistry" + + # Kontrol + "KontrolCheatsBase" + "KontrolCheats" + + # Error definition files + "CommonErrors" + "Errors" + + # TODO: Interfaces that need to be fixed + "IPreimageOracle" + "IOptimismMintableERC721" + "IFaultDisputeGame" + "IOptimismSuperchainERC20" + "IInitializable" + "IOptimismMintableERC20" + "ILegacyMintableERC20" + "MintableAndBurnable" + "IDisputeGameFactory" + "IAddressManager" + "IWETH" + "IDelayedWETH" + "IAnchorStateRegistry" + "ICrossL2Inbox" + "IL2ToL2CrossDomainMessenger" + "KontrolInterfaces" +) + +# Convert the exclude files array to a pipe-separated string +EXCLUDE_PATTERN=$( (IFS="|"; echo "${EXCLUDE_FILES[*]}") ) + +# Find all JSON files in the forge-artifacts folder +JSON_FILES=$(find "$CONTRACTS_BASE/forge-artifacts" -type f -name "*.json" | grep -Ev "$EXCLUDE_PATTERN") + +# Initialize a flag to track if any issues are detected +issues_detected=false + +# Create a temporary file to store files that have already been reported +REPORTED_INTERFACES_FILE=$(mktemp) + +# Define a cleanup function +cleanup() { + rm -f "$REPORTED_INTERFACES_FILE" +} + +# Trap exit and error signals and call cleanup function +trap cleanup EXIT ERR + +# Iterate over all JSON files +for interface_file in $JSON_FILES; do + # Extract contract kind and name in a single pass + contract_definitions=$(jq -r '.ast.nodes[] | select(.nodeType == "ContractDefinition") | "\(.contractKind),\(.name)"' "$interface_file") + + # Warn and continue if no contract definitions are found + if [ -z "$contract_definitions" ]; then + echo "Warning: Could not extract contract definitions from $interface_file." + echo "Add this file to the EXCLUDE_FILES list if it can be ignored." + continue + fi + + while IFS=',' read -r contract_kind contract_name; do + # If contract kind is not "interface", skip the file + if [ "$contract_kind" != "interface" ]; then + continue + fi + + # If contract name is in the exclude list, skip the file + # Exclude list functions double duty as a list of files to exclude (glob patterns allowed) + # and a list of interface names that shouldn't be checked. Simplifies the script a bit and + # means we can ignore specific interfaces without ignoring the entire file if desired. + exclude=false + for exclude_item in "${EXCLUDE_FILES[@]}"; do + if [[ "$exclude_item" == "$contract_name" ]]; then + exclude=true + break + fi + done + if [[ "$exclude" == true ]]; then + continue + fi + + # If contract name does not start with an "I", throw an error + if [[ "$contract_name" != I* ]]; then + if ! grep -q "^$contract_name$" "$REPORTED_INTERFACES_FILE"; then + echo "Issue found in ABI for interface $contract_name from file $interface_file." + echo "Interface $contract_name does not start with 'I'." + echo "$contract_name" >> "$REPORTED_INTERFACES_FILE" + issues_detected=true + fi + continue + fi + + # Construct the corresponding contract name by removing the leading "I" + contract_basename=${contract_name:1} + corresponding_contract_file="$CONTRACTS_BASE/forge-artifacts/$contract_basename.sol/$contract_basename.json" + + # Check if the corresponding contract file exists + if [ -f "$corresponding_contract_file" ]; then + # Extract and compare ABIs excluding constructors + interface_abi=$(jq '[.abi[] | select(.type != "constructor")]' < "$interface_file") + contract_abi=$(jq '[.abi[] | select(.type != "constructor")]' < "$corresponding_contract_file") + + # Use jq to compare the ABIs + if ! diff_result=$(diff -u <(echo "$interface_abi" | jq -S .) <(echo "$contract_abi" | jq -S .)); then + if ! grep -q "^$contract_name$" "$REPORTED_INTERFACES_FILE"; then + echo "Issue found in ABI for interface $contract_name from file $interface_file." + echo "Differences found in ABI between interface $contract_name and actual contract $contract_basename." + if [ "$no_diff" = false ]; then + echo "$diff_result" + fi + echo "$contract_name" >> "$REPORTED_INTERFACES_FILE" + issues_detected=true + fi + fi + fi + done <<< "$contract_definitions" +done + +# Fail the script if any issues were detected +if [ "$issues_detected" = true ]; then + echo "Issues were detected while validating interface files." + echo "If the interface is an external dependency or should otherwise be excluded from this" + echo "check, add the interface name to the EXCLUDE_FILES list in the script. This will prevent" + echo "the script from comparing it against a corresponding contract." + exit 1 +else + exit 0 +fi From 72eff5f9719fdd8b473998c4567540dfd1fa3fa9 Mon Sep 17 00:00:00 2001 From: zhiqiangxu <652732310@qq.com> Date: Wed, 4 Sep 2024 09:28:53 +0800 Subject: [PATCH 025/264] add comment to SingularBatch.Timestamp (#11720) --- op-node/rollup/derive/singular_batch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op-node/rollup/derive/singular_batch.go b/op-node/rollup/derive/singular_batch.go index fdb867efbe72..9993c351bf23 100644 --- a/op-node/rollup/derive/singular_batch.go +++ b/op-node/rollup/derive/singular_batch.go @@ -23,7 +23,7 @@ type SingularBatch struct { ParentHash common.Hash // parent L2 block hash EpochNum rollup.Epoch // aka l1 num EpochHash common.Hash // l1 block hash - Timestamp uint64 + Timestamp uint64 // l2 block timestamp Transactions []hexutil.Bytes } From e80d23b64ceb207e8f70c2a497f9d6d49155e7ac Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Wed, 4 Sep 2024 12:47:55 +1000 Subject: [PATCH 026/264] op-program: Use PebbleDB for DiskKV (Reapply with fixes) (#11709) * feat(op-program): Use `PebbleDB` for `DiskKV` (#11705) * feat(op-program): Use `PebbleDB` for `DiskKV` * close db * fix `testFaultProofProgramScenario` tests * switch to snappy compression https://github.com/cockroachdb/pebble/issues/3434 * fix tempdir * update compat release * defer k/v until preimage server and hinter have both exited * Only open preimage source when actually needing preimages. Avoids concurrent access to the pebbledb. * op-program: Handle interrupts in host Ensures the preimage kv store is closed cleanly even when the process is sent an interrupt signal. Enables non-blocking IO so that read calls return io.EOF when a file handle is closed rather than blocking forever. * op-program: Restore file based kv store. Add pebble as an additional option. * op-program: Add option to specify KV store format to use * op-program: Switch pebble to perform sync writes. * op-program: Rename disk kv to file kv * op-program: Rename DBFormat to DataFormat for consistency. --------- Co-authored-by: clabby --- cannon/cmd/run.go | 22 +++++- .../game/fault/trace/asterisc/provider.go | 28 ++++---- .../game/fault/trace/cannon/provider.go | 28 ++++---- .../game/fault/trace/utils/preimage.go | 23 +++++-- .../game/fault/trace/utils/preimage_test.go | 39 ++++++++--- op-preimage/filechan.go | 26 +++++-- op-program/client/program.go | 24 ++----- op-program/host/cmd/main_test.go | 16 +++++ op-program/host/config/config.go | 15 ++++ op-program/host/config/config_test.go | 18 +++++ op-program/host/flags/flags.go | 8 +++ op-program/host/host.go | 35 ++++++++-- op-program/host/kvstore/{disk.go => file.go} | 30 ++++---- .../kvstore/{disk_test.go => file_test.go} | 8 ++- op-program/host/kvstore/kv.go | 3 + op-program/host/kvstore/mem.go | 4 ++ op-program/host/kvstore/pebble.go | 68 +++++++++++++++++++ op-program/host/kvstore/pebble_test.go | 28 ++++++++ op-program/host/types/types.go | 10 +++ op-program/scripts/run-compat.sh | 4 +- 20 files changed, 347 insertions(+), 90 deletions(-) rename op-program/host/kvstore/{disk.go => file.go} (76%) rename op-program/host/kvstore/{disk_test.go => file_test.go} (72%) create mode 100644 op-program/host/kvstore/pebble.go create mode 100644 op-program/host/kvstore/pebble_test.go create mode 100644 op-program/host/types/types.go diff --git a/cannon/cmd/run.go b/cannon/cmd/run.go index 23b6e1b75719..a806778578aa 100644 --- a/cannon/cmd/run.go +++ b/cannon/cmd/run.go @@ -217,9 +217,29 @@ func (p *ProcessPreimageOracle) Close() error { if p.cmd == nil { return nil } + + tryWait := func(dur time.Duration) (bool, error) { + ctx, cancel := context.WithTimeout(context.Background(), dur) + defer cancel() + select { + case <-ctx.Done(): + return false, nil + case err := <-p.waitErr: + return true, err + } + } // Give the pre-image server time to exit cleanly before killing it. - time.Sleep(time.Second * 1) + if exited, err := tryWait(1 * time.Second); exited { + return err + } + // Politely ask the process to exit and give it some more time _ = p.cmd.Process.Signal(os.Interrupt) + if exited, err := tryWait(30 * time.Second); exited { + return err + } + + // Force the process to exit + _ = p.cmd.Process.Signal(os.Kill) return <-p.waitErr } diff --git a/op-challenger/game/fault/trace/asterisc/provider.go b/op-challenger/game/fault/trace/asterisc/provider.go index c4647234c64f..cad5e36b839e 100644 --- a/op-challenger/game/fault/trace/asterisc/provider.go +++ b/op-challenger/game/fault/trace/asterisc/provider.go @@ -37,12 +37,14 @@ type AsteriscTraceProvider struct { func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, vmCfg vm.OracleServerExecutor, prestateProvider types.PrestateProvider, asteriscPrestate string, localInputs utils.LocalGameInputs, dir string, gameDepth types.Depth) *AsteriscTraceProvider { return &AsteriscTraceProvider{ - logger: logger, - dir: dir, - prestate: asteriscPrestate, - generator: vm.NewExecutor(logger, m, cfg, vmCfg, asteriscPrestate, localInputs), - gameDepth: gameDepth, - preimageLoader: utils.NewPreimageLoader(kvstore.NewDiskKV(vm.PreimageDir(dir)).Get), + logger: logger, + dir: dir, + prestate: asteriscPrestate, + generator: vm.NewExecutor(logger, m, cfg, vmCfg, asteriscPrestate, localInputs), + gameDepth: gameDepth, + preimageLoader: utils.NewPreimageLoader(func() utils.PreimageSource { + return kvstore.NewFileKV(vm.PreimageDir(dir)) + }), PrestateProvider: prestateProvider, } } @@ -174,12 +176,14 @@ type AsteriscTraceProviderForTest struct { func NewTraceProviderForTest(logger log.Logger, m vm.Metricer, cfg *config.Config, localInputs utils.LocalGameInputs, dir string, gameDepth types.Depth) *AsteriscTraceProviderForTest { p := &AsteriscTraceProvider{ - logger: logger, - dir: dir, - prestate: cfg.AsteriscAbsolutePreState, - generator: vm.NewExecutor(logger, m, cfg.Asterisc, vm.NewOpProgramServerExecutor(), cfg.AsteriscAbsolutePreState, localInputs), - gameDepth: gameDepth, - preimageLoader: utils.NewPreimageLoader(kvstore.NewDiskKV(vm.PreimageDir(dir)).Get), + logger: logger, + dir: dir, + prestate: cfg.AsteriscAbsolutePreState, + generator: vm.NewExecutor(logger, m, cfg.Asterisc, vm.NewOpProgramServerExecutor(), cfg.AsteriscAbsolutePreState, localInputs), + gameDepth: gameDepth, + preimageLoader: utils.NewPreimageLoader(func() utils.PreimageSource { + return kvstore.NewFileKV(vm.PreimageDir(dir)) + }), } return &AsteriscTraceProviderForTest{p} } diff --git a/op-challenger/game/fault/trace/cannon/provider.go b/op-challenger/game/fault/trace/cannon/provider.go index 7262ec918040..fc7a71c1cda0 100644 --- a/op-challenger/game/fault/trace/cannon/provider.go +++ b/op-challenger/game/fault/trace/cannon/provider.go @@ -40,12 +40,14 @@ type CannonTraceProvider struct { func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, vmCfg vm.OracleServerExecutor, prestateProvider types.PrestateProvider, prestate string, localInputs utils.LocalGameInputs, dir string, gameDepth types.Depth) *CannonTraceProvider { return &CannonTraceProvider{ - logger: logger, - dir: dir, - prestate: prestate, - generator: vm.NewExecutor(logger, m, cfg, vmCfg, prestate, localInputs), - gameDepth: gameDepth, - preimageLoader: utils.NewPreimageLoader(kvstore.NewDiskKV(vm.PreimageDir(dir)).Get), + logger: logger, + dir: dir, + prestate: prestate, + generator: vm.NewExecutor(logger, m, cfg, vmCfg, prestate, localInputs), + gameDepth: gameDepth, + preimageLoader: utils.NewPreimageLoader(func() utils.PreimageSource { + return kvstore.NewFileKV(vm.PreimageDir(dir)) + }), PrestateProvider: prestateProvider, } } @@ -178,12 +180,14 @@ type CannonTraceProviderForTest struct { func NewTraceProviderForTest(logger log.Logger, m vm.Metricer, cfg *config.Config, localInputs utils.LocalGameInputs, dir string, gameDepth types.Depth) *CannonTraceProviderForTest { p := &CannonTraceProvider{ - logger: logger, - dir: dir, - prestate: cfg.CannonAbsolutePreState, - generator: vm.NewExecutor(logger, m, cfg.Cannon, vm.NewOpProgramServerExecutor(), cfg.CannonAbsolutePreState, localInputs), - gameDepth: gameDepth, - preimageLoader: utils.NewPreimageLoader(kvstore.NewDiskKV(vm.PreimageDir(dir)).Get), + logger: logger, + dir: dir, + prestate: cfg.CannonAbsolutePreState, + generator: vm.NewExecutor(logger, m, cfg.Cannon, vm.NewOpProgramServerExecutor(), cfg.CannonAbsolutePreState, localInputs), + gameDepth: gameDepth, + preimageLoader: utils.NewPreimageLoader(func() utils.PreimageSource { + return kvstore.NewFileKV(vm.PreimageDir(dir)) + }), } return &CannonTraceProviderForTest{p} } diff --git a/op-challenger/game/fault/trace/utils/preimage.go b/op-challenger/game/fault/trace/utils/preimage.go index 09a48ee912f6..0c14882fa774 100644 --- a/op-challenger/game/fault/trace/utils/preimage.go +++ b/op-challenger/game/fault/trace/utils/preimage.go @@ -27,15 +27,20 @@ var ( ErrInvalidBlobKeyPreimage = errors.New("invalid blob key preimage") ) -type preimageSource func(key common.Hash) ([]byte, error) +type PreimageSource interface { + Get(key common.Hash) ([]byte, error) + Close() error +} + +type PreimageSourceCreator func() PreimageSource type PreimageLoader struct { - getPreimage preimageSource + makeSource PreimageSourceCreator } -func NewPreimageLoader(getPreimage preimageSource) *PreimageLoader { +func NewPreimageLoader(makeSource PreimageSourceCreator) *PreimageLoader { return &PreimageLoader{ - getPreimage: getPreimage, + makeSource: makeSource, } } @@ -57,7 +62,9 @@ func (l *PreimageLoader) loadBlobPreimage(proof *ProofData) (*types.PreimageOrac // The key for a blob field element is a keccak hash of commitment++fieldElementIndex. // First retrieve the preimage of the key as a keccak hash so we have the commitment and required field element inputsKey := preimage.Keccak256Key(proof.OracleKey).PreimageKey() - inputs, err := l.getPreimage(inputsKey) + source := l.makeSource() + defer source.Close() + inputs, err := source.Get(inputsKey) if err != nil { return nil, fmt.Errorf("failed to get key preimage: %w", err) } @@ -74,7 +81,7 @@ func (l *PreimageLoader) loadBlobPreimage(proof *ProofData) (*types.PreimageOrac for i := 0; i < params.BlobTxFieldElementsPerBlob; i++ { binary.BigEndian.PutUint64(fieldElemKey[72:], uint64(i)) key := preimage.BlobKey(crypto.Keccak256(fieldElemKey)).PreimageKey() - fieldElement, err := l.getPreimage(key) + fieldElement, err := source.Get(key) if err != nil { return nil, fmt.Errorf("failed to load field element %v with key %v: %w", i, common.Hash(key), err) } @@ -105,7 +112,9 @@ func (l *PreimageLoader) loadBlobPreimage(proof *ProofData) (*types.PreimageOrac func (l *PreimageLoader) loadPrecompilePreimage(proof *ProofData) (*types.PreimageOracleData, error) { inputKey := preimage.Keccak256Key(proof.OracleKey).PreimageKey() - input, err := l.getPreimage(inputKey) + source := l.makeSource() + defer source.Close() + input, err := source.Get(inputKey) if err != nil { return nil, fmt.Errorf("failed to get key preimage: %w", err) } diff --git a/op-challenger/game/fault/trace/utils/preimage_test.go b/op-challenger/game/fault/trace/utils/preimage_test.go index 46778f080c37..cc4b8fa0d14b 100644 --- a/op-challenger/game/fault/trace/utils/preimage_test.go +++ b/op-challenger/game/fault/trace/utils/preimage_test.go @@ -20,14 +20,20 @@ import ( ) func TestPreimageLoader_NoPreimage(t *testing.T) { - loader := NewPreimageLoader(kvstore.NewMemKV().Get) + kv := kvstore.NewMemKV() + loader := NewPreimageLoader(func() PreimageSource { + return kv + }) actual, err := loader.LoadPreimage(&ProofData{}) require.NoError(t, err) require.Nil(t, actual) } func TestPreimageLoader_LocalPreimage(t *testing.T) { - loader := NewPreimageLoader(kvstore.NewMemKV().Get) + kv := kvstore.NewMemKV() + loader := NewPreimageLoader(func() PreimageSource { + return kv + }) proof := &ProofData{ OracleKey: common.Hash{byte(preimage.LocalKeyType), 0xaa, 0xbb}.Bytes(), OracleValue: nil, @@ -48,7 +54,10 @@ func TestPreimageLoader_SimpleTypes(t *testing.T) { for _, keyType := range tests { keyType := keyType t.Run(fmt.Sprintf("type-%v", keyType), func(t *testing.T) { - loader := NewPreimageLoader(kvstore.NewMemKV().Get) + kv := kvstore.NewMemKV() + loader := NewPreimageLoader(func() PreimageSource { + return kv + }) proof := &ProofData{ OracleKey: common.Hash{byte(keyType), 0xaa, 0xbb}.Bytes(), OracleValue: []byte{1, 2, 3, 4, 5, 6}, @@ -90,7 +99,9 @@ func TestPreimageLoader_BlobPreimage(t *testing.T) { t.Run("NoKeyPreimage", func(t *testing.T) { kv := kvstore.NewMemKV() - loader := NewPreimageLoader(kv.Get) + loader := NewPreimageLoader(func() PreimageSource { + return kv + }) proof := &ProofData{ OracleKey: common.Hash{byte(preimage.BlobKeyType), 0xaf}.Bytes(), OracleValue: proof.OracleValue, @@ -102,7 +113,9 @@ func TestPreimageLoader_BlobPreimage(t *testing.T) { t.Run("InvalidKeyPreimage", func(t *testing.T) { kv := kvstore.NewMemKV() - loader := NewPreimageLoader(kv.Get) + loader := NewPreimageLoader(func() PreimageSource { + return kv + }) proof := &ProofData{ OracleKey: common.Hash{byte(preimage.BlobKeyType), 0xad}.Bytes(), OracleValue: proof.OracleValue, @@ -115,7 +128,9 @@ func TestPreimageLoader_BlobPreimage(t *testing.T) { t.Run("MissingBlobs", func(t *testing.T) { kv := kvstore.NewMemKV() - loader := NewPreimageLoader(kv.Get) + loader := NewPreimageLoader(func() PreimageSource { + return kv + }) proof := &ProofData{ OracleKey: common.Hash{byte(preimage.BlobKeyType), 0xae}.Bytes(), OracleValue: proof.OracleValue, @@ -128,7 +143,9 @@ func TestPreimageLoader_BlobPreimage(t *testing.T) { t.Run("Valid", func(t *testing.T) { kv := kvstore.NewMemKV() - loader := NewPreimageLoader(kv.Get) + loader := NewPreimageLoader(func() PreimageSource { + return kv + }) storeBlob(t, kv, gokzg4844.KZGCommitment(commitment), gokzg4844.Blob(blob)) actual, err := loader.LoadPreimage(proof) require.NoError(t, err) @@ -161,13 +178,17 @@ func TestPreimageLoader_PrecompilePreimage(t *testing.T) { t.Run("NoInputPreimage", func(t *testing.T) { kv := kvstore.NewMemKV() - loader := NewPreimageLoader(kv.Get) + loader := NewPreimageLoader(func() PreimageSource { + return kv + }) _, err := loader.LoadPreimage(proof) require.ErrorIs(t, err, kvstore.ErrNotFound) }) t.Run("Valid", func(t *testing.T) { kv := kvstore.NewMemKV() - loader := NewPreimageLoader(kv.Get) + loader := NewPreimageLoader(func() PreimageSource { + return kv + }) require.NoError(t, kv.Put(preimage.Keccak256Key(proof.OracleKey).PreimageKey(), input)) actual, err := loader.LoadPreimage(proof) require.NoError(t, err) diff --git a/op-preimage/filechan.go b/op-preimage/filechan.go index 1b5f3e6286c9..3d844c58b6b5 100644 --- a/op-preimage/filechan.go +++ b/op-preimage/filechan.go @@ -1,8 +1,11 @@ package preimage import ( + "errors" + "fmt" "io" "os" + "syscall" ) // FileChannel is a unidirectional channel for file I/O @@ -41,10 +44,14 @@ func (rw *ReadWritePair) Writer() *os.File { } func (rw *ReadWritePair) Close() error { + var combinedErr error if err := rw.r.Close(); err != nil { - return err + combinedErr = errors.Join(fmt.Errorf("failed to close reader: %w", err)) } - return rw.w.Close() + if err := rw.w.Close(); err != nil { + combinedErr = errors.Join(fmt.Errorf("failed to close writer: %w", err)) + } + return combinedErr } // CreateBidirectionalChannel creates a pair of FileChannels that are connected to each other. @@ -68,14 +75,21 @@ const ( ) func ClientHinterChannel() *ReadWritePair { - r := os.NewFile(HClientRFd, "preimage-hint-read") - w := os.NewFile(HClientWFd, "preimage-hint-write") + r := newFileNonBlocking(HClientRFd, "preimage-hint-read") + w := newFileNonBlocking(HClientWFd, "preimage-hint-write") return NewReadWritePair(r, w) } // ClientPreimageChannel returns a FileChannel for the preimage oracle in a detached context func ClientPreimageChannel() *ReadWritePair { - r := os.NewFile(PClientRFd, "preimage-oracle-read") - w := os.NewFile(PClientWFd, "preimage-oracle-write") + r := newFileNonBlocking(PClientRFd, "preimage-oracle-read") + w := newFileNonBlocking(PClientWFd, "preimage-oracle-write") return NewReadWritePair(r, w) } + +func newFileNonBlocking(fd int, name string) *os.File { + // Try to enable non-blocking mode for IO so that read calls return when the file is closed + // This may not be possible on all systems so errors are ignored. + _ = syscall.SetNonblock(fd, true) + return os.NewFile(uintptr(fd), name) +} diff --git a/op-program/client/program.go b/op-program/client/program.go index a539c1aff4a9..75d5fa93aa30 100644 --- a/op-program/client/program.go +++ b/op-program/client/program.go @@ -6,10 +6,6 @@ import ( "io" "os" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/params" - "github.com/ethereum-optimism/optimism/op-node/rollup" preimage "github.com/ethereum-optimism/optimism/op-preimage" "github.com/ethereum-optimism/optimism/op-program/client/claim" @@ -17,14 +13,17 @@ import ( "github.com/ethereum-optimism/optimism/op-program/client/l1" "github.com/ethereum-optimism/optimism/op-program/client/l2" "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" ) // Main executes the client program in a detached context and exits the current process. // The client runtime environment must be preset before calling this function. func Main(logger log.Logger) { log.Info("Starting fault proof program client") - preimageOracle := CreatePreimageChannel() - preimageHinter := CreateHinterChannel() + preimageOracle := preimage.ClientPreimageChannel() + preimageHinter := preimage.ClientHinterChannel() if err := RunProgram(logger, preimageOracle, preimageHinter); errors.Is(err, claim.ErrClaimNotValid) { log.Error("Claim is invalid", "err", err) os.Exit(1) @@ -76,16 +75,3 @@ func runDerivation(logger log.Logger, cfg *rollup.Config, l2Cfg *params.ChainCon } return claim.ValidateClaim(logger, l2ClaimBlockNum, eth.Bytes32(l2Claim), l2Source) } - -func CreateHinterChannel() preimage.FileChannel { - r := os.NewFile(HClientRFd, "preimage-hint-read") - w := os.NewFile(HClientWFd, "preimage-hint-write") - return preimage.NewReadWritePair(r, w) -} - -// CreatePreimageChannel returns a FileChannel for the preimage oracle in a detached context -func CreatePreimageChannel() preimage.FileChannel { - r := os.NewFile(PClientRFd, "preimage-oracle-read") - w := os.NewFile(PClientWFd, "preimage-oracle-write") - return preimage.NewReadWritePair(r, w) -} diff --git a/op-program/host/cmd/main_test.go b/op-program/host/cmd/main_test.go index 0bff6513ffc5..6c91bf13365d 100644 --- a/op-program/host/cmd/main_test.go +++ b/op-program/host/cmd/main_test.go @@ -2,6 +2,7 @@ package main import ( "encoding/json" + "fmt" "os" "strconv" "testing" @@ -9,6 +10,7 @@ import ( "github.com/ethereum-optimism/optimism/op-node/chaincfg" "github.com/ethereum-optimism/optimism/op-program/chainconfig" "github.com/ethereum-optimism/optimism/op-program/host/config" + "github.com/ethereum-optimism/optimism/op-program/host/types" oplog "github.com/ethereum-optimism/optimism/op-service/log" "github.com/ethereum-optimism/optimism/op-service/sources" @@ -119,6 +121,20 @@ func TestDataDir(t *testing.T) { require.Equal(t, expected, cfg.DataDir) } +func TestDataFormat(t *testing.T) { + for _, format := range types.SupportedDataFormats { + format := format + t.Run(fmt.Sprintf("Valid-%v", format), func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgs("--data.format", string(format))) + require.Equal(t, format, cfg.DataFormat) + }) + } + + t.Run("Invalid", func(t *testing.T) { + verifyArgsInvalid(t, "invalid data format: foo", addRequiredArgs("--data.format", "foo")) + }) +} + func TestL2(t *testing.T) { expected := "https://example.com:8545" cfg := configForArgs(t, addRequiredArgs("--l2", expected)) diff --git a/op-program/host/config/config.go b/op-program/host/config/config.go index 25f1a75724c9..dd9a2dff15ca 100644 --- a/op-program/host/config/config.go +++ b/op-program/host/config/config.go @@ -5,8 +5,10 @@ import ( "errors" "fmt" "os" + "slices" "github.com/ethereum-optimism/optimism/op-node/chaincfg" + "github.com/ethereum-optimism/optimism/op-program/host/types" opnode "github.com/ethereum-optimism/optimism/op-node" "github.com/ethereum-optimism/optimism/op-node/rollup" @@ -30,6 +32,7 @@ var ( ErrInvalidL2ClaimBlock = errors.New("invalid l2 claim block number") ErrDataDirRequired = errors.New("datadir must be specified when in non-fetching mode") ErrNoExecInServerMode = errors.New("exec command must not be set when in server mode") + ErrInvalidDataFormat = errors.New("invalid data format") ) type Config struct { @@ -38,6 +41,9 @@ type Config struct { // If not set, an in-memory key-value store is used and fetching data must be enabled DataDir string + // DataFormat specifies the format to use for on-disk storage. Only applies when DataDir is set. + DataFormat types.DataFormat + // L1Head is the block hash of the L1 chain head block L1Head common.Hash L1URL string @@ -100,6 +106,9 @@ func (c *Config) Check() error { if c.ServerMode && c.ExecCmd != "" { return ErrNoExecInServerMode } + if c.DataDir != "" && !slices.Contains(types.SupportedDataFormats, c.DataFormat) { + return ErrInvalidDataFormat + } return nil } @@ -130,6 +139,7 @@ func NewConfig( L2ClaimBlockNumber: l2ClaimBlockNum, L1RPCKind: sources.RPCKindStandard, IsCustomChainConfig: isCustomConfig, + DataFormat: types.DataFormatFile, } } @@ -183,9 +193,14 @@ func NewConfigFromCLI(log log.Logger, ctx *cli.Context) (*Config, error) { if err != nil { return nil, fmt.Errorf("invalid genesis: %w", err) } + dbFormat := types.DataFormat(ctx.String(flags.DataFormat.Name)) + if !slices.Contains(types.SupportedDataFormats, dbFormat) { + return nil, fmt.Errorf("invalid %w: %v", ErrInvalidDataFormat, dbFormat) + } return &Config{ Rollup: rollupCfg, DataDir: ctx.String(flags.DataDir.Name), + DataFormat: dbFormat, L2URL: ctx.String(flags.L2NodeAddr.Name), L2ChainConfig: l2ChainConfig, L2Head: l2Head, diff --git a/op-program/host/config/config_test.go b/op-program/host/config/config_test.go index 7497b5db4bd9..b9aaccc65416 100644 --- a/op-program/host/config/config_test.go +++ b/op-program/host/config/config_test.go @@ -1,12 +1,14 @@ package config import ( + "fmt" "math/big" "testing" "github.com/ethereum-optimism/optimism/op-node/chaincfg" "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-program/chainconfig" + "github.com/ethereum-optimism/optimism/op-program/host/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/params" "github.com/stretchr/testify/require" @@ -173,6 +175,22 @@ func TestIsCustomChainConfig(t *testing.T) { } +func TestDBFormat(t *testing.T) { + t.Run("invalid", func(t *testing.T) { + cfg := validConfig() + cfg.DataFormat = "foo" + require.ErrorIs(t, cfg.Check(), ErrInvalidDataFormat) + }) + for _, format := range types.SupportedDataFormats { + format := format + t.Run(fmt.Sprintf("%v", format), func(t *testing.T) { + cfg := validConfig() + cfg.DataFormat = format + require.NoError(t, cfg.Check()) + }) + } +} + func validConfig() *Config { cfg := NewConfig(validRollupConfig, validL2Genesis, validL1Head, validL2Head, validL2OutputRoot, validL2Claim, validL2ClaimBlockNum) cfg.DataDir = "/tmp/configTest" diff --git a/op-program/host/flags/flags.go b/op-program/host/flags/flags.go index 3356bbfda8a9..c46422876d63 100644 --- a/op-program/host/flags/flags.go +++ b/op-program/host/flags/flags.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" + "github.com/ethereum-optimism/optimism/op-program/host/types" "github.com/urfave/cli/v2" "github.com/ethereum-optimism/optimism/op-node/chaincfg" @@ -35,6 +36,12 @@ var ( Usage: "Directory to use for preimage data storage. Default uses in-memory storage", EnvVars: prefixEnvVars("DATADIR"), } + DataFormat = &cli.StringFlag{ + Name: "data.format", + Usage: fmt.Sprintf("Format to use for preimage data storage. Available formats: %s", openum.EnumString(types.SupportedDataFormats)), + EnvVars: prefixEnvVars("DATA_FORMAT"), + Value: string(types.DataFormatFile), + } L2NodeAddr = &cli.StringFlag{ Name: "l2", Usage: "Address of L2 JSON-RPC endpoint to use (eth and debug namespace required)", @@ -122,6 +129,7 @@ var programFlags = []cli.Flag{ RollupConfig, Network, DataDir, + DataFormat, L2NodeAddr, L2GenesisPath, L1NodeAddr, diff --git a/op-program/host/host.go b/op-program/host/host.go index ddffde7ee513..a2ee245adede 100644 --- a/op-program/host/host.go +++ b/op-program/host/host.go @@ -16,8 +16,10 @@ import ( "github.com/ethereum-optimism/optimism/op-program/host/flags" "github.com/ethereum-optimism/optimism/op-program/host/kvstore" "github.com/ethereum-optimism/optimism/op-program/host/prefetcher" + "github.com/ethereum-optimism/optimism/op-program/host/types" opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" @@ -35,10 +37,12 @@ func Main(logger log.Logger, cfg *config.Config) error { opservice.ValidateEnvVars(flags.EnvVarPrefix, flags.Flags, logger) cfg.Rollup.LogDescription(logger, chaincfg.L2ChainIDToNetworkDisplayName) - ctx := context.Background() + hostCtx, stop := ctxinterrupt.WithSignalWaiter(context.Background()) + defer stop() + ctx := ctxinterrupt.WithCancelOnInterrupt(hostCtx) if cfg.ServerMode { - preimageChan := cl.CreatePreimageChannel() - hinterChan := cl.CreateHinterChannel() + preimageChan := preimage.ClientPreimageChannel() + hinterChan := preimage.ClientHinterChannel() return PreimageServer(ctx, logger, cfg, preimageChan, hinterChan) } @@ -122,6 +126,10 @@ func FaultProofProgram(ctx context.Context, logger log.Logger, cfg *config.Confi func PreimageServer(ctx context.Context, logger log.Logger, cfg *config.Config, preimageChannel preimage.FileChannel, hintChannel preimage.FileChannel) error { var serverDone chan error var hinterDone chan error + logger.Info("Starting preimage server") + var kv kvstore.KV + + // Close the preimage/hint channels, and then kv store once the server and hinter have exited. defer func() { preimageChannel.Close() hintChannel.Close() @@ -133,18 +141,28 @@ func PreimageServer(ctx context.Context, logger log.Logger, cfg *config.Config, // Wait for hinter to complete <-hinterDone } + + if kv != nil { + kv.Close() + } }() - logger.Info("Starting preimage server") - var kv kvstore.KV + if cfg.DataDir == "" { logger.Info("Using in-memory storage") kv = kvstore.NewMemKV() } else { - logger.Info("Creating disk storage", "datadir", cfg.DataDir) + logger.Info("Creating disk storage", "datadir", cfg.DataDir, "format", cfg.DataFormat) if err := os.MkdirAll(cfg.DataDir, 0755); err != nil { return fmt.Errorf("creating datadir: %w", err) } - kv = kvstore.NewDiskKV(cfg.DataDir) + switch cfg.DataFormat { + case types.DataFormatFile: + kv = kvstore.NewFileKV(cfg.DataDir) + case types.DataFormatPebble: + kv = kvstore.NewPebbleKV(cfg.DataDir) + default: + return fmt.Errorf("invalid data format: %s", cfg.DataFormat) + } } var ( @@ -178,6 +196,9 @@ func PreimageServer(ctx context.Context, logger log.Logger, cfg *config.Config, return err case err := <-hinterDone: return err + case <-ctx.Done(): + logger.Info("Shutting down") + return ctx.Err() } } diff --git a/op-program/host/kvstore/disk.go b/op-program/host/kvstore/file.go similarity index 76% rename from op-program/host/kvstore/disk.go rename to op-program/host/kvstore/file.go index 0f6bd19068ae..353bcedfe7c4 100644 --- a/op-program/host/kvstore/disk.go +++ b/op-program/host/kvstore/file.go @@ -13,28 +13,28 @@ import ( ) // read/write mode for user/group/other, not executable. -const diskPermission = 0666 +const filePermission = 0666 -// DiskKV is a disk-backed key-value store, every key-value pair is a hex-encoded .txt file, with the value as content. -// DiskKV is safe for concurrent use with a single DiskKV instance. -// DiskKV is safe for concurrent use between different DiskKV instances of the same disk directory as long as the +// FileKV is a disk-backed key-value store, every key-value pair is a hex-encoded .txt file, with the value as content. +// FileKV is safe for concurrent use with a single FileKV instance. +// FileKV is safe for concurrent use between different FileKV instances of the same disk directory as long as the // file system supports atomic renames. -type DiskKV struct { +type FileKV struct { sync.RWMutex path string } -// NewDiskKV creates a DiskKV that puts/gets pre-images as files in the given directory path. +// NewFileKV creates a FileKV that puts/gets pre-images as files in the given directory path. // The path must exist, or subsequent Put/Get calls will error when it does not. -func NewDiskKV(path string) *DiskKV { - return &DiskKV{path: path} +func NewFileKV(path string) *FileKV { + return &FileKV{path: path} } -func (d *DiskKV) pathKey(k common.Hash) string { +func (d *FileKV) pathKey(k common.Hash) string { return path.Join(d.path, k.String()+".txt") } -func (d *DiskKV) Put(k common.Hash, v []byte) error { +func (d *FileKV) Put(k common.Hash, v []byte) error { d.Lock() defer d.Unlock() f, err := openTempFile(d.path, k.String()+".txt.*") @@ -72,10 +72,10 @@ func openTempFile(dir string, nameTemplate string) (*os.File, error) { return f, nil } -func (d *DiskKV) Get(k common.Hash) ([]byte, error) { +func (d *FileKV) Get(k common.Hash) ([]byte, error) { d.RLock() defer d.RUnlock() - f, err := os.OpenFile(d.pathKey(k), os.O_RDONLY, diskPermission) + f, err := os.OpenFile(d.pathKey(k), os.O_RDONLY, filePermission) if err != nil { if errors.Is(err, os.ErrNotExist) { return nil, ErrNotFound @@ -90,4 +90,8 @@ func (d *DiskKV) Get(k common.Hash) ([]byte, error) { return hex.DecodeString(string(dat)) } -var _ KV = (*DiskKV)(nil) +func (d *FileKV) Close() error { + return nil +} + +var _ KV = (*FileKV)(nil) diff --git a/op-program/host/kvstore/disk_test.go b/op-program/host/kvstore/file_test.go similarity index 72% rename from op-program/host/kvstore/disk_test.go rename to op-program/host/kvstore/file_test.go index 1ea0eaa2dfa8..b30517db2faa 100644 --- a/op-program/host/kvstore/disk_test.go +++ b/op-program/host/kvstore/file_test.go @@ -10,14 +10,18 @@ import ( func TestDiskKV(t *testing.T) { tmp := t.TempDir() // automatically removed by testing cleanup - kv := NewDiskKV(tmp) + kv := NewFileKV(tmp) + t.Cleanup(func() { // Can't use defer because kvTest runs tests in parallel. + require.NoError(t, kv.Close()) + }) kvTest(t, kv) } func TestCreateMissingDirectory(t *testing.T) { tmp := t.TempDir() dir := filepath.Join(tmp, "data") - kv := NewDiskKV(dir) + kv := NewFileKV(dir) + defer kv.Close() val := []byte{1, 2, 3, 4} key := crypto.Keccak256Hash(val) require.NoError(t, kv.Put(key, val)) diff --git a/op-program/host/kvstore/kv.go b/op-program/host/kvstore/kv.go index e75dcd699d9f..054230950d0b 100644 --- a/op-program/host/kvstore/kv.go +++ b/op-program/host/kvstore/kv.go @@ -19,4 +19,7 @@ type KV interface { // It returns ErrNotFound when the pre-image cannot be found. // KV store implementations may return additional errors specific to the KV storage. Get(k common.Hash) ([]byte, error) + + // Closes the KV store. + Close() error } diff --git a/op-program/host/kvstore/mem.go b/op-program/host/kvstore/mem.go index 9af540e235fa..0c3b950b7e9c 100644 --- a/op-program/host/kvstore/mem.go +++ b/op-program/host/kvstore/mem.go @@ -37,3 +37,7 @@ func (m *MemKV) Get(k common.Hash) ([]byte, error) { } return slices.Clone(v), nil } + +func (m *MemKV) Close() error { + return nil +} diff --git a/op-program/host/kvstore/pebble.go b/op-program/host/kvstore/pebble.go new file mode 100644 index 000000000000..1276fa6b7ef7 --- /dev/null +++ b/op-program/host/kvstore/pebble.go @@ -0,0 +1,68 @@ +package kvstore + +import ( + "errors" + "fmt" + "runtime" + "sync" + + "github.com/cockroachdb/pebble" + "github.com/ethereum/go-ethereum/common" +) + +// PebbleKV is a disk-backed key-value store, with PebbleDB as the underlying DBMS. +// PebbleKV is safe for concurrent use with a single PebbleKV instance. +type PebbleKV struct { + sync.RWMutex + db *pebble.DB +} + +// NewPebbleKV creates a PebbleKV that puts/gets pre-images as files in the given directory path. +// The path must exist, or subsequent Put/Get calls will error when it does not. +func NewPebbleKV(path string) *PebbleKV { + opts := &pebble.Options{ + Cache: pebble.NewCache(int64(32 * 1024 * 1024)), + MaxConcurrentCompactions: runtime.NumCPU, + Levels: []pebble.LevelOptions{ + {Compression: pebble.SnappyCompression}, + }, + } + db, err := pebble.Open(path, opts) + if err != nil { + panic(fmt.Errorf("failed to open pebbledb at %s: %w", path, err)) + } + + return &PebbleKV{db: db} +} + +func (d *PebbleKV) Put(k common.Hash, v []byte) error { + d.Lock() + defer d.Unlock() + return d.db.Set(k.Bytes(), v, pebble.Sync) +} + +func (d *PebbleKV) Get(k common.Hash) ([]byte, error) { + d.RLock() + defer d.RUnlock() + + dat, closer, err := d.db.Get(k.Bytes()) + if err != nil { + if errors.Is(err, pebble.ErrNotFound) { + return nil, ErrNotFound + } + return nil, err + } + ret := make([]byte, len(dat)) + copy(ret, dat) + closer.Close() + return ret, nil +} + +func (d *PebbleKV) Close() error { + d.Lock() + defer d.Unlock() + + return d.db.Close() +} + +var _ KV = (*PebbleKV)(nil) diff --git a/op-program/host/kvstore/pebble_test.go b/op-program/host/kvstore/pebble_test.go new file mode 100644 index 000000000000..28aab0c58248 --- /dev/null +++ b/op-program/host/kvstore/pebble_test.go @@ -0,0 +1,28 @@ +package kvstore + +import ( + "path/filepath" + "testing" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/require" +) + +func TestPebbleKV(t *testing.T) { + tmp := t.TempDir() // automatically removed by testing cleanup + kv := NewPebbleKV(tmp) + t.Cleanup(func() { // Can't use defer because kvTest runs tests in parallel. + require.NoError(t, kv.Close()) + }) + kvTest(t, kv) +} + +func TestPebbleKV_CreateMissingDirectory(t *testing.T) { + tmp := t.TempDir() + dir := filepath.Join(tmp, "data") + kv := NewPebbleKV(dir) + defer kv.Close() + val := []byte{1, 2, 3, 4} + key := crypto.Keccak256Hash(val) + require.NoError(t, kv.Put(key, val)) +} diff --git a/op-program/host/types/types.go b/op-program/host/types/types.go new file mode 100644 index 000000000000..104dafe2dbc4 --- /dev/null +++ b/op-program/host/types/types.go @@ -0,0 +1,10 @@ +package types + +type DataFormat string + +const ( + DataFormatFile DataFormat = "file" + DataFormatPebble DataFormat = "pebble" +) + +var SupportedDataFormats = []DataFormat{DataFormatFile, DataFormatPebble} diff --git a/op-program/scripts/run-compat.sh b/op-program/scripts/run-compat.sh index ed853a8d980b..9849b8da8938 100755 --- a/op-program/scripts/run-compat.sh +++ b/op-program/scripts/run-compat.sh @@ -5,7 +5,7 @@ SCRIPTS_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) COMPAT_DIR="${SCRIPTS_DIR}/../temp/compat" TESTNAME="${1?Must specify compat file to run}" -BASEURL="${2:-https://github.com/ethereum-optimism/chain-test-data/releases/download/2024-08-02}" +BASEURL="${2:-https://github.com/ethereum-optimism/chain-test-data/releases/download/2024-09-01}" URL="${BASEURL}/${TESTNAME}.tar.bz" @@ -13,4 +13,4 @@ mkdir -p "${COMPAT_DIR}" curl --etag-save "${COMPAT_DIR}/${TESTNAME}-etag.txt" --etag-compare "${COMPAT_DIR}/${TESTNAME}-etag.txt" -L --fail -o "${COMPAT_DIR}/${TESTNAME}.tar.bz" "${URL}" tar jxf "${COMPAT_DIR}/${TESTNAME}.tar.bz" -C "${COMPAT_DIR}" # shellcheck disable=SC2046 -"${SCRIPTS_DIR}/../bin/op-program" $(cat "${COMPAT_DIR}/${TESTNAME}/args.txt") +"${SCRIPTS_DIR}/../bin/op-program" --data.format=pebble $(cat "${COMPAT_DIR}/${TESTNAME}/args.txt") From 5a1a18d0ceedc40aad99baf4359e06f09fc7b718 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Tue, 3 Sep 2024 23:46:12 -0400 Subject: [PATCH 027/264] fix: SuperchainWETH fuzz flake with bad sender (#11728) Fixes a number of places where SuperchainWETH fuzz tests can flake as a result of using a sender address that is the ETHLiquidity or SuperchainWETH contract. --- packages/contracts-bedrock/test/L2/SuperchainWETH.t.sol | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/contracts-bedrock/test/L2/SuperchainWETH.t.sol b/packages/contracts-bedrock/test/L2/SuperchainWETH.t.sol index 3bee1fc74b7d..d75734b2c776 100644 --- a/packages/contracts-bedrock/test/L2/SuperchainWETH.t.sol +++ b/packages/contracts-bedrock/test/L2/SuperchainWETH.t.sol @@ -134,6 +134,8 @@ contract SuperchainWETH_Test is CommonTest { { // Assume vm.assume(_chainId != block.chainid); + vm.assume(_caller != address(ethLiquidity)); + vm.assume(_caller != address(superchainWeth)); _amount = bound(_amount, 0, type(uint248).max - 1); // Arrange @@ -233,6 +235,9 @@ contract SuperchainWETH_Test is CommonTest { /// @param _amount The amount of WETH to send. function testFuzz_relayERC20_fromMessenger_succeeds(address _sender, uint256 _amount, uint256 _chainId) public { // Assume + vm.assume(_chainId != block.chainid); + vm.assume(_sender != address(ethLiquidity)); + vm.assume(_sender != address(superchainWeth)); _amount = bound(_amount, 0, type(uint248).max - 1); // Arrange @@ -272,6 +277,9 @@ contract SuperchainWETH_Test is CommonTest { public { // Assume + vm.assume(_chainId != block.chainid); + vm.assume(_sender != address(ethLiquidity)); + vm.assume(_sender != address(superchainWeth)); _amount = bound(_amount, 0, type(uint248).max - 1); // Arrange From f8b421b850f7b3eb1b485139818226aafcc3967b Mon Sep 17 00:00:00 2001 From: George Knee Date: Wed, 4 Sep 2024 16:24:34 +0100 Subject: [PATCH 028/264] Fix copy-paste typo (#11731) --- op-node/rollup/sequencing/sequencer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op-node/rollup/sequencing/sequencer.go b/op-node/rollup/sequencing/sequencer.go index 118cdf4be3fa..70a0164249b3 100644 --- a/op-node/rollup/sequencing/sequencer.go +++ b/op-node/rollup/sequencing/sequencer.go @@ -527,7 +527,7 @@ func (d *Sequencer) startBuildingBlock() { d.log.Info("Sequencing Fjord upgrade block") } - // For the Fjord activation block we shouldn't include any sequencer transactions. + // For the Granite activation block we shouldn't include any sequencer transactions. if d.rollupCfg.IsGraniteActivationBlock(uint64(attrs.Timestamp)) { d.log.Info("Sequencing Granite upgrade block") } From e0f6e1e74cbbd444394d105d4be8e65e315172b8 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Wed, 4 Sep 2024 11:52:51 -0400 Subject: [PATCH 029/264] maint: add interfaces for legacy contracts (#11625) Adds interfaces for the contracts inside of /legacy. Interface is not included for the LegacyMintableERC20 contract because that interface has already been defined elsewhere. --- .../contracts-bedrock/scripts/Artifacts.s.sol | 2 +- .../scripts/checks/check-interfaces.sh | 1 - .../scripts/interfaces/IAddressManager.sol | 22 ------------------- .../src/legacy/interfaces/IAddressManager.sol | 13 +++++++++++ .../legacy/interfaces/IDeployerWhitelist.sol | 20 +++++++++++++++++ .../src/legacy/interfaces/IL1BlockNumber.sol | 14 ++++++++++++ .../legacy/interfaces/IL1ChugSplashProxy.sol | 16 ++++++++++++++ .../interfaces/ILegacyMessagePasser.sol | 11 ++++++++++ .../interfaces/IResolvedDelegateProxy.sol | 8 +++++++ .../src/universal/interfaces/IOwnable.sol | 12 ++++++++++ 10 files changed, 95 insertions(+), 24 deletions(-) delete mode 100644 packages/contracts-bedrock/scripts/interfaces/IAddressManager.sol create mode 100644 packages/contracts-bedrock/src/legacy/interfaces/IAddressManager.sol create mode 100644 packages/contracts-bedrock/src/legacy/interfaces/IDeployerWhitelist.sol create mode 100644 packages/contracts-bedrock/src/legacy/interfaces/IL1BlockNumber.sol create mode 100644 packages/contracts-bedrock/src/legacy/interfaces/IL1ChugSplashProxy.sol create mode 100644 packages/contracts-bedrock/src/legacy/interfaces/ILegacyMessagePasser.sol create mode 100644 packages/contracts-bedrock/src/legacy/interfaces/IResolvedDelegateProxy.sol create mode 100644 packages/contracts-bedrock/src/universal/interfaces/IOwnable.sol diff --git a/packages/contracts-bedrock/scripts/Artifacts.s.sol b/packages/contracts-bedrock/scripts/Artifacts.s.sol index b054d2e27254..3325f98d3acc 100644 --- a/packages/contracts-bedrock/scripts/Artifacts.s.sol +++ b/packages/contracts-bedrock/scripts/Artifacts.s.sol @@ -11,7 +11,7 @@ import { StorageSlot } from "scripts/libraries/ForgeArtifacts.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { LibString } from "@solady/utils/LibString.sol"; import { ForgeArtifacts } from "scripts/libraries/ForgeArtifacts.sol"; -import { IAddressManager } from "scripts/interfaces/IAddressManager.sol"; +import { IAddressManager } from "src/legacy/interfaces/IAddressManager.sol"; import { Process } from "scripts/libraries/Process.sol"; /// @notice Represents a deployment. Is serialized to JSON as a key/value diff --git a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh index a3b15768b73c..d57f5c9b665b 100755 --- a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh +++ b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh @@ -68,7 +68,6 @@ EXCLUDE_FILES=( "ILegacyMintableERC20" "MintableAndBurnable" "IDisputeGameFactory" - "IAddressManager" "IWETH" "IDelayedWETH" "IAnchorStateRegistry" diff --git a/packages/contracts-bedrock/scripts/interfaces/IAddressManager.sol b/packages/contracts-bedrock/scripts/interfaces/IAddressManager.sol deleted file mode 100644 index f7e87cdc8702..000000000000 --- a/packages/contracts-bedrock/scripts/interfaces/IAddressManager.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; - -/// @title IAddressManager -/// @notice Minimal interface of the Legacy AddressManager. -interface IAddressManager { - /// @notice Emitted when an address is modified in the registry. - /// @param name String name being set in the registry. - /// @param newAddress Address set for the given name. - /// @param oldAddress Address that was previously set for the given name. - event AddressSet(string indexed name, address newAddress, address oldAddress); - - /// @notice Changes the address associated with a particular name. - /// @param _name String name to associate an address with. - /// @param _address Address to associate with the name. - function setAddress(string memory _name, address _address) external; - - /// @notice Retrieves the address associated with a given name. - /// @param _name Name to retrieve an address for. - /// @return Address associated with the given name. - function getAddress(string memory _name) external view returns (address); -} diff --git a/packages/contracts-bedrock/src/legacy/interfaces/IAddressManager.sol b/packages/contracts-bedrock/src/legacy/interfaces/IAddressManager.sol new file mode 100644 index 000000000000..3fae2cbab430 --- /dev/null +++ b/packages/contracts-bedrock/src/legacy/interfaces/IAddressManager.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { IOwnable } from "src/universal/interfaces/IOwnable.sol"; + +/// @title IAddressManager +/// @notice Interface for the AddressManager contract. +interface IAddressManager is IOwnable { + event AddressSet(string indexed name, address newAddress, address oldAddress); + + function getAddress(string memory _name) external view returns (address); + function setAddress(string memory _name, address _address) external; +} diff --git a/packages/contracts-bedrock/src/legacy/interfaces/IDeployerWhitelist.sol b/packages/contracts-bedrock/src/legacy/interfaces/IDeployerWhitelist.sol new file mode 100644 index 000000000000..6914eefabb3d --- /dev/null +++ b/packages/contracts-bedrock/src/legacy/interfaces/IDeployerWhitelist.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ISemver } from "src/universal/ISemver.sol"; + +/// @title IDeployerWhitelist +/// @notice Interface for the DeployerWhitelist contract. +interface IDeployerWhitelist { + event OwnerChanged(address oldOwner, address newOwner); + event WhitelistDisabled(address oldOwner); + event WhitelistStatusChanged(address deployer, bool whitelisted); + + function enableArbitraryContractDeployment() external; + function isDeployerAllowed(address _deployer) external view returns (bool); + function owner() external view returns (address); + function setOwner(address _owner) external; + function setWhitelistedDeployer(address _deployer, bool _isWhitelisted) external; + function version() external view returns (string memory); + function whitelist(address) external view returns (bool); +} diff --git a/packages/contracts-bedrock/src/legacy/interfaces/IL1BlockNumber.sol b/packages/contracts-bedrock/src/legacy/interfaces/IL1BlockNumber.sol new file mode 100644 index 000000000000..1b59b53e396f --- /dev/null +++ b/packages/contracts-bedrock/src/legacy/interfaces/IL1BlockNumber.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ISemver } from "src/universal/ISemver.sol"; + +/// @title IL1BlockNumber +/// @notice Interface for the L1BlockNumber contract. +interface IL1BlockNumber is ISemver { + fallback() external payable; + + receive() external payable; + + function getL1BlockNumber() external view returns (uint256); +} diff --git a/packages/contracts-bedrock/src/legacy/interfaces/IL1ChugSplashProxy.sol b/packages/contracts-bedrock/src/legacy/interfaces/IL1ChugSplashProxy.sol new file mode 100644 index 000000000000..5840dcf056c3 --- /dev/null +++ b/packages/contracts-bedrock/src/legacy/interfaces/IL1ChugSplashProxy.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @title IL1ChugSplashProxy +/// @notice Interface for the L1ChugSplashProxy contract. +interface IL1ChugSplashProxy { + fallback() external payable; + + receive() external payable; + + function getImplementation() external returns (address); + function getOwner() external returns (address); + function setCode(bytes memory _code) external; + function setOwner(address _owner) external; + function setStorage(bytes32 _key, bytes32 _value) external; +} diff --git a/packages/contracts-bedrock/src/legacy/interfaces/ILegacyMessagePasser.sol b/packages/contracts-bedrock/src/legacy/interfaces/ILegacyMessagePasser.sol new file mode 100644 index 000000000000..79e03871f236 --- /dev/null +++ b/packages/contracts-bedrock/src/legacy/interfaces/ILegacyMessagePasser.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ISemver } from "src/universal/ISemver.sol"; + +/// @title ILegacyMessagePasser +/// @notice Interface for the LegacyMessagePasser contract. +interface ILegacyMessagePasser is ISemver { + function passMessageToL1(bytes memory _message) external; + function sentMessages(bytes32) external view returns (bool); +} diff --git a/packages/contracts-bedrock/src/legacy/interfaces/IResolvedDelegateProxy.sol b/packages/contracts-bedrock/src/legacy/interfaces/IResolvedDelegateProxy.sol new file mode 100644 index 000000000000..abeb3817d9be --- /dev/null +++ b/packages/contracts-bedrock/src/legacy/interfaces/IResolvedDelegateProxy.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @title IResolvedDelegateProxy +/// @notice Interface for the ResolvedDelegateProxy contract. +interface IResolvedDelegateProxy { + fallback() external payable; +} diff --git a/packages/contracts-bedrock/src/universal/interfaces/IOwnable.sol b/packages/contracts-bedrock/src/universal/interfaces/IOwnable.sol new file mode 100644 index 000000000000..968ad63a7652 --- /dev/null +++ b/packages/contracts-bedrock/src/universal/interfaces/IOwnable.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @title IOwnable +/// @notice Interface for Ownable. +interface IOwnable { + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + function owner() external view returns (address); + function renounceOwnership() external; + function transferOwnership(address newOwner) external; // nosemgrep: sol-style-input-arg-fmt. +} From 2f10fb7a96e70051b5a2cf1e0dbdc625449fbf98 Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Wed, 4 Sep 2024 10:59:57 -0600 Subject: [PATCH 030/264] Slim down contracts-bedrock package (#11723) * Slim down contracts-bedrock package The contracts-bedrock package was over 2GB in size, mostly because it contained the Git repository. It also supported multiple platforms, which would lead to costly recompilation steps every time the image was used on a different platform (e.g., OSX). The PR updates the Dockerfile to no longer ship the Git repo. It also updates the Debian base image to a more modern, slimmed down version. The new image is <1G in size. * fix bakefile --- docker-bake.hcl | 3 +- ops/docker/Dockerfile.packages | 57 +++++++++++++------ .../scripts/libraries/Executables.sol | 8 ++- 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/docker-bake.hcl b/docker-bake.hcl index d57ab76e7e62..47509616416a 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -219,6 +219,7 @@ target "contracts-bedrock" { dockerfile = "./ops/docker/Dockerfile.packages" context = "." target = "contracts-bedrock" - platforms = split(",", PLATFORMS) + # See comment in Dockerfile.packages for why we only build for linux/amd64. + platforms = ["linux/amd64"] tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/contracts-bedrock:${tag}"] } diff --git a/ops/docker/Dockerfile.packages b/ops/docker/Dockerfile.packages index 598f40b3e3bb..f4f110244f5f 100644 --- a/ops/docker/Dockerfile.packages +++ b/ops/docker/Dockerfile.packages @@ -1,11 +1,12 @@ +# We need to specify the platforms below, otherwise platforms other than +# linux/amd64 will be forced to rebuild the contracts every time this +# image is used. + # This Dockerfile builds all the dependencies needed by the smart-contracts, excluding Go and Python. -FROM us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest as foundry +FROM --platform=linux/amd64 us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest as foundry -# Historically the contracts-bedrock was on the node image based on Debian 11 (bullseye), -# for Node / PNPM compatibility reasons. -# We no longer use Node JS, but continue to use the same Debian version for compatibility. -FROM debian:bullseye-slim as base +FROM --platform=linux/amd64 debian:bookworm-20240812-slim as base # Base: install deps RUN apt-get update && apt-get install -y \ @@ -17,13 +18,7 @@ RUN apt-get update && apt-get install -y \ bash \ --no-install-recommends -COPY /ops/docker/oplabs.crt /usr/local/share/ca-certificates/oplabs.crt -RUN chmod 644 /usr/local/share/ca-certificates/oplabs.crt \ - && update-ca-certificates - -# Note: "just" is only available on Debian 13. Instead, pull it from the foundry image. COPY --from=foundry /usr/local/bin/just /usr/local/bin/just - COPY --from=foundry /usr/local/bin/forge /usr/local/bin/forge COPY --from=foundry /usr/local/bin/cast /usr/local/bin/cast @@ -31,18 +26,48 @@ WORKDIR /opt/optimism COPY ./versions.json ./versions.json COPY ./packages ./packages - COPY .git/ ./.git COPY .gitmodules ./.gitmodules -RUN git submodule update --init --recursive + +RUN git submodule update --init --recursive \ + && cd packages/contracts-bedrock \ + && just build \ + && echo $(git rev-parse HEAD) > .gitcommit + +FROM --platform=linux/amd64 debian:bookworm-20240812-slim + +RUN apt-get update && apt-get install -y \ + curl \ + jq \ + ca-certificates \ + git \ + make \ + bash \ + --no-install-recommends + +COPY /ops/docker/oplabs.crt /usr/local/share/ca-certificates/oplabs.crt + +RUN chmod 644 /usr/local/share/ca-certificates/oplabs.crt \ + && update-ca-certificates + +COPY --from=foundry /usr/local/bin/just /usr/local/bin/just +COPY --from=foundry /usr/local/bin/forge /usr/local/bin/forge +COPY --from=foundry /usr/local/bin/cast /usr/local/bin/cast +COPY --from=foundry /usr/local/bin/svm /usr/local/bin/svm + +RUN svm install 0.8.25 && \ + svm install 0.8.15 && \ + svm install 0.8.19 && \ + svm install 0.8.26 # Not to be confused with OP, this is a OnePassword CLI tool. COPY --from=1password/op:2 /usr/local/bin/op /usr/local/bin/op -# prebuild the smart-contracts for the convenience of the user -RUN cd packages/contracts-bedrock && just build +RUN mkdir -p /opt/optimism/packages/contracts-bedrock + +COPY --from=base /opt/optimism/packages/contracts-bedrock /opt/optimism/packages/contracts-bedrock +COPY --from=base /opt/optimism/versions.json /opt/optimism/versions.json -FROM base as contracts-bedrock WORKDIR /opt/optimism/packages/contracts-bedrock # Set "just" as entrypoint, so the default args (the Dockerfile CMD) diff --git a/packages/contracts-bedrock/scripts/libraries/Executables.sol b/packages/contracts-bedrock/scripts/libraries/Executables.sol index 31f81da71ee5..0dc91e32072d 100644 --- a/packages/contracts-bedrock/scripts/libraries/Executables.sol +++ b/packages/contracts-bedrock/scripts/libraries/Executables.sol @@ -19,12 +19,16 @@ library Executables { string internal constant ls = "ls"; string internal constant git = "git"; - /// @notice Returns the commit hash of HEAD. + /// @notice Returns the commit hash of HEAD. If no git repository is + /// found, it will return the contents of the .gitcommit file. Otherwise, + /// it will return an error. The .gitcommit file is used to store the + /// git commit of the contracts when they are packaged into docker images + /// in order to avoid the need to have a git repository in the image. function gitCommitHash() internal returns (string memory) { string[] memory commands = new string[](3); commands[0] = bash; commands[1] = "-c"; - commands[2] = "cast abi-encode 'f(string)' $(git rev-parse HEAD)"; + commands[2] = "cast abi-encode 'f(string)' $(git rev-parse HEAD || cat .gitcommit)"; return abi.decode(Process.run(commands), (string)); } } From 1f0d8a8b6ca872016de9b719ae577fe37bef2472 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Wed, 4 Sep 2024 14:28:55 -0400 Subject: [PATCH 031/264] fix: properly check all interfaces (#11734) Interfaces check script had a bug that would cause it to use the wrong ABI when checking an interface. Each compiler artifact only has a single ABI in it but this same ABI was being used for all contract definitions found within that file. Since each separate contract definition gets its own file anyway, this script now properly verifies by finding the specific definition that matches the filename. --- .../scripts/checks/check-interfaces.sh | 165 ++++++++++-------- 1 file changed, 92 insertions(+), 73 deletions(-) diff --git a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh index d57f5c9b665b..e08c35f19e71 100755 --- a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh +++ b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh @@ -17,31 +17,22 @@ fi SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) CONTRACTS_BASE=$(dirname "$(dirname "$SCRIPT_DIR")") -# Define the files to exclude (glob patterns can be used) -EXCLUDE_FILES=( +# Define contracts that should be excluded from the check +EXCLUDE_CONTRACTS=( # External dependencies - "IMulticall3" "IERC20" "IERC721" "IERC721Enumerable" - "IERC721Metadata" "IERC721Upgradeable" - "IERC721Receiver" - "IERC1271" "IERC165" - "IVotes" - "IBeacon" - "IProxyCreationCallback" - "IAutomate" - "IGelato1Balance" + "IERC165Upgradeable" "ERC721TokenReceiver" "ERC1155TokenReceiver" "ERC777TokensRecipient" "Guard" - "GnosisSafeProxy" + "IProxy" # Foundry - "Common" "Vm" "VmSafe" @@ -52,11 +43,6 @@ EXCLUDE_FILES=( # Kontrol "KontrolCheatsBase" - "KontrolCheats" - - # Error definition files - "CommonErrors" - "Errors" # TODO: Interfaces that need to be fixed "IPreimageOracle" @@ -72,15 +58,16 @@ EXCLUDE_FILES=( "IDelayedWETH" "IAnchorStateRegistry" "ICrossL2Inbox" + "IL1CrossDomainMessenger" "IL2ToL2CrossDomainMessenger" - "KontrolInterfaces" + "IL1ERC721Bridge" + "IL1StandardBridge" + "ISuperchainConfig" + "IOptimismPortal" ) -# Convert the exclude files array to a pipe-separated string -EXCLUDE_PATTERN=$( (IFS="|"; echo "${EXCLUDE_FILES[*]}") ) - # Find all JSON files in the forge-artifacts folder -JSON_FILES=$(find "$CONTRACTS_BASE/forge-artifacts" -type f -name "*.json" | grep -Ev "$EXCLUDE_PATTERN") +JSON_FILES=$(find "$CONTRACTS_BASE/forge-artifacts" -type f -name "*.json") # Initialize a flag to track if any issues are detected issues_detected=false @@ -88,7 +75,7 @@ issues_detected=false # Create a temporary file to store files that have already been reported REPORTED_INTERFACES_FILE=$(mktemp) -# Define a cleanup function +# Clean up the temporary file on exit cleanup() { rm -f "$REPORTED_INTERFACES_FILE" } @@ -96,81 +83,113 @@ cleanup() { # Trap exit and error signals and call cleanup function trap cleanup EXIT ERR +# Check if a contract is excluded +is_excluded() { + for exclude in "${EXCLUDE_CONTRACTS[@]}"; do + if [[ "$exclude" == "$1" ]]; then + return 0 + fi + done + return 1 +} + # Iterate over all JSON files for interface_file in $JSON_FILES; do - # Extract contract kind and name in a single pass + # Grab the contract name from the file name + contract_name=$(basename "$interface_file" .json | cut -d '.' -f 1) + + # Extract all contract definitions in a single pass contract_definitions=$(jq -r '.ast.nodes[] | select(.nodeType == "ContractDefinition") | "\(.contractKind),\(.name)"' "$interface_file") - # Warn and continue if no contract definitions are found + # Continue if no contract definitions are found + # Can happen in Solidity files that don't declare any contracts/interfaces if [ -z "$contract_definitions" ]; then - echo "Warning: Could not extract contract definitions from $interface_file." - echo "Add this file to the EXCLUDE_FILES list if it can be ignored." continue fi - while IFS=',' read -r contract_kind contract_name; do - # If contract kind is not "interface", skip the file - if [ "$contract_kind" != "interface" ]; then - continue + # Iterate over the found contract definitions and figure out which one + # matches the file name. We do this so that we can figure out if this is an + # interface or a contract based on the contract kind. + found=false + contract_temp="" + contract_kind="" + for definition in $contract_definitions; do + IFS=',' read -r contract_kind contract_temp <<< "$definition" + if [[ "$contract_name" == "$contract_temp" ]]; then + found=true + break fi + done - # If contract name is in the exclude list, skip the file - # Exclude list functions double duty as a list of files to exclude (glob patterns allowed) - # and a list of interface names that shouldn't be checked. Simplifies the script a bit and - # means we can ignore specific interfaces without ignoring the entire file if desired. - exclude=false - for exclude_item in "${EXCLUDE_FILES[@]}"; do - if [[ "$exclude_item" == "$contract_name" ]]; then - exclude=true - break - fi - done - if [[ "$exclude" == true ]]; then - continue - fi + # Continue if no matching contract name is found. Can happen in Solidity + # files where no contracts/interfaces are defined with the same name as the + # file. Still OK because a separate artifact *will* be generated for the + # specific contract/interface. + if [ "$found" = false ]; then + continue + fi - # If contract name does not start with an "I", throw an error - if [[ "$contract_name" != I* ]]; then - if ! grep -q "^$contract_name$" "$REPORTED_INTERFACES_FILE"; then + # If contract kind is not "interface", skip the file + if [ "$contract_kind" != "interface" ]; then + continue + fi + + # If contract name does not start with an "I", throw an error + if [[ "$contract_name" != I* ]]; then + if ! grep -q "^$contract_name$" "$REPORTED_INTERFACES_FILE"; then + echo "$contract_name" >> "$REPORTED_INTERFACES_FILE" + if ! is_excluded "$contract_name"; then echo "Issue found in ABI for interface $contract_name from file $interface_file." echo "Interface $contract_name does not start with 'I'." - echo "$contract_name" >> "$REPORTED_INTERFACES_FILE" issues_detected=true fi - continue fi + continue + fi + + # Construct the corresponding contract name by removing the leading "I" + contract_basename=${contract_name:1} + corresponding_contract_file="$CONTRACTS_BASE/forge-artifacts/$contract_basename.sol/$contract_basename.json" - # Construct the corresponding contract name by removing the leading "I" - contract_basename=${contract_name:1} - corresponding_contract_file="$CONTRACTS_BASE/forge-artifacts/$contract_basename.sol/$contract_basename.json" - - # Check if the corresponding contract file exists - if [ -f "$corresponding_contract_file" ]; then - # Extract and compare ABIs excluding constructors - interface_abi=$(jq '[.abi[] | select(.type != "constructor")]' < "$interface_file") - contract_abi=$(jq '[.abi[] | select(.type != "constructor")]' < "$corresponding_contract_file") - - # Use jq to compare the ABIs - if ! diff_result=$(diff -u <(echo "$interface_abi" | jq -S .) <(echo "$contract_abi" | jq -S .)); then - if ! grep -q "^$contract_name$" "$REPORTED_INTERFACES_FILE"; then - echo "Issue found in ABI for interface $contract_name from file $interface_file." - echo "Differences found in ABI between interface $contract_name and actual contract $contract_basename." - if [ "$no_diff" = false ]; then - echo "$diff_result" - fi - echo "$contract_name" >> "$REPORTED_INTERFACES_FILE" - issues_detected=true + # Skip the file if the corresponding contract file does not exist + if [ ! -f "$corresponding_contract_file" ]; then + continue + fi + + # Extract and compare ABIs excluding constructors + interface_abi=$(jq '[.abi[] | select(.type != "constructor")]' < "$interface_file") + contract_abi=$(jq '[.abi[] | select(.type != "constructor")]' < "$corresponding_contract_file") + + # Use jq to compare the ABIs + if ! diff_result=$(diff -u <(echo "$interface_abi" | jq -S .) <(echo "$contract_abi" | jq -S .)); then + if ! grep -q "^$contract_name$" "$REPORTED_INTERFACES_FILE"; then + echo "$contract_name" >> "$REPORTED_INTERFACES_FILE" + if ! is_excluded "$contract_name"; then + echo "Issue found in ABI for interface $contract_name from file $interface_file." + echo "Differences found in ABI between interface $contract_name and actual contract $contract_basename." + if [ "$no_diff" = false ]; then + echo "$diff_result" fi + issues_detected=true fi fi - done <<< "$contract_definitions" + continue + fi +done + +# Check for unnecessary exclusions +for exclude_item in "${EXCLUDE_CONTRACTS[@]}"; do + if ! grep -q "^$exclude_item$" "$REPORTED_INTERFACES_FILE"; then + echo "Warning: $exclude_item is in the exclude list but was not reported as an issue." + echo "Consider removing it from the EXCLUDE_CONTRACTS list in the script." + fi done # Fail the script if any issues were detected if [ "$issues_detected" = true ]; then echo "Issues were detected while validating interface files." echo "If the interface is an external dependency or should otherwise be excluded from this" - echo "check, add the interface name to the EXCLUDE_FILES list in the script. This will prevent" + echo "check, add the interface name to the EXCLUDE_CONTRACTS list in the script. This will prevent" echo "the script from comparing it against a corresponding contract." exit 1 else From 31f408bf3899e08d50ed22d0345c59d59f28bf1b Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Wed, 4 Sep 2024 16:32:19 -0400 Subject: [PATCH 032/264] feat: update interface validation script to check semver (#11740) Updates the interface validation script to verify that all interface contracts are using Solidity ^0.8.0 exactly. --- .../scripts/checks/check-interfaces.sh | 23 +++++++++++++++++-- .../scripts/interfaces/IGnosisSafe.sol | 2 +- .../scripts/interfaces/ISystemConfigV0.sol | 2 +- packages/contracts-bedrock/semver-lock.json | 2 +- .../contracts-bedrock/src/L2/CrossL2Inbox.sol | 11 +-------- .../src/L2/interfaces/IDependencySet.sol | 12 ++++++++++ .../src/cannon/interfaces/IMIPS.sol | 2 +- .../src/cannon/interfaces/IMIPS2.sol | 2 +- .../src/cannon/interfaces/IPreimageOracle.sol | 2 +- .../src/legacy/L1ChugSplashProxy.sol | 6 +---- .../legacy/interfaces/IL1ChugSplashProxy.sol | 12 ++++++++++ .../drippie/dripchecks/CheckGelatoLow.sol | 6 +---- .../faucet/authmodules/IFaucetAuthModule.sol | 2 +- .../src/universal/ProxyAdmin.sol | 18 ++------------- .../src/universal/interfaces/IEIP712.sol | 7 ++++++ .../interfaces/IStaticERC1967Proxy.sol | 9 ++++++++ .../src/vendor/interfaces/IGelatoTreasury.sol | 9 ++++++++ .../contracts-bedrock/test/Preinstalls.t.sol | 5 +--- .../test/periphery/op-nft/Optimist.t.sol | 16 +------------ 19 files changed, 84 insertions(+), 64 deletions(-) create mode 100644 packages/contracts-bedrock/src/L2/interfaces/IDependencySet.sol create mode 100644 packages/contracts-bedrock/src/universal/interfaces/IEIP712.sol create mode 100644 packages/contracts-bedrock/src/universal/interfaces/IStaticERC1967Proxy.sol create mode 100644 packages/contracts-bedrock/src/vendor/interfaces/IGelatoTreasury.sol diff --git a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh index e08c35f19e71..d7dd7007cb57 100755 --- a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh +++ b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh @@ -24,6 +24,7 @@ EXCLUDE_CONTRACTS=( "IERC721" "IERC721Enumerable" "IERC721Upgradeable" + "IERC721Metadata" "IERC165" "IERC165Upgradeable" "ERC721TokenReceiver" @@ -31,10 +32,12 @@ EXCLUDE_CONTRACTS=( "ERC777TokensRecipient" "Guard" "IProxy" - - # Foundry "Vm" "VmSafe" + "IMulticall3" + "IBeacon" + "IERC721TokenReceiver" + "IProxyCreationCallback" # EAS "IEAS" @@ -147,6 +150,22 @@ for interface_file in $JSON_FILES; do continue fi + # Extract contract semver + contract_semver=$(jq -r '.ast.nodes[] | select(.nodeType == "PragmaDirective") | .literals | join("")' "$interface_file") + + # If semver is not exactly "solidity^0.8.0", throw an error + if [ "$contract_semver" != "solidity^0.8.0" ]; then + if ! grep -q "^$contract_name$" "$REPORTED_INTERFACES_FILE"; then + echo "$contract_name" >> "$REPORTED_INTERFACES_FILE" + if ! is_excluded "$contract_name"; then + echo "Issue found in ABI for interface $contract_name from file $interface_file." + echo "Interface $contract_name does not have correct compiler version (MUST be exactly solidity ^0.8.0)." + issues_detected=true + fi + fi + continue + fi + # Construct the corresponding contract name by removing the leading "I" contract_basename=${contract_name:1} corresponding_contract_file="$CONTRACTS_BASE/forge-artifacts/$contract_basename.sol/$contract_basename.json" diff --git a/packages/contracts-bedrock/scripts/interfaces/IGnosisSafe.sol b/packages/contracts-bedrock/scripts/interfaces/IGnosisSafe.sol index 60434364fd9a..068f3815134a 100644 --- a/packages/contracts-bedrock/scripts/interfaces/IGnosisSafe.sol +++ b/packages/contracts-bedrock/scripts/interfaces/IGnosisSafe.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-only -pragma solidity ^0.8.10; +pragma solidity ^0.8.0; /// @title Enum - Collection of enums used in Safe contracts. /// @author Richard Meissner - @rmeissner diff --git a/packages/contracts-bedrock/scripts/interfaces/ISystemConfigV0.sol b/packages/contracts-bedrock/scripts/interfaces/ISystemConfigV0.sol index 2871d76b8238..07f911e762a9 100644 --- a/packages/contracts-bedrock/scripts/interfaces/ISystemConfigV0.sol +++ b/packages/contracts-bedrock/scripts/interfaces/ISystemConfigV0.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.15; +pragma solidity ^0.8.0; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 59def1ae86cf..21f17a54a727 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -69,7 +69,7 @@ }, "src/L2/CrossL2Inbox.sol": { "initCodeHash": "0x071b53cd8cf0503af856c4ee0ee34643e85059d53c096453891225472e02abfa", - "sourceCodeHash": "0x3c78129b91d9f06afa4787d4b3039f45a3b22b3edf5155ed73d4f0c3ab33c6c8" + "sourceCodeHash": "0xc3478a7036b8c58ed1a90ad90556a62c99a4abb124b0fa47f2edfca31eec680f" }, "src/L2/ETHLiquidity.sol": { "initCodeHash": "0x98177562fca0de0dfea5313c9acefe2fdbd73dee5ce6c1232055601f208f0177", diff --git a/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol b/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol index cb0ccfa7714d..da1ab5e056d9 100644 --- a/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol +++ b/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol @@ -6,16 +6,7 @@ import { TransientContext, TransientReentrancyAware } from "src/libraries/Transi import { ISemver } from "src/universal/ISemver.sol"; import { ICrossL2Inbox } from "src/L2/ICrossL2Inbox.sol"; import { SafeCall } from "src/libraries/SafeCall.sol"; - -/// @title IDependencySet -/// @notice Interface for L1Block with only `isInDependencySet(uint256)` method. -interface IDependencySet { - /// @notice Returns true if the chain associated with input chain ID is in the interop dependency set. - /// Every chain is in the interop dependency set of itself. - /// @param _chainId Input chain ID. - /// @return True if the input chain ID corresponds to a chain in the interop dependency set, and false otherwise. - function isInDependencySet(uint256 _chainId) external view returns (bool); -} +import { IDependencySet } from "src/L2/interfaces/IDependencySet.sol"; /// @notice Thrown when the caller is not DEPOSITOR_ACCOUNT when calling `setInteropStart()` error NotDepositor(); diff --git a/packages/contracts-bedrock/src/L2/interfaces/IDependencySet.sol b/packages/contracts-bedrock/src/L2/interfaces/IDependencySet.sol new file mode 100644 index 000000000000..fb294bee8d19 --- /dev/null +++ b/packages/contracts-bedrock/src/L2/interfaces/IDependencySet.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @title IDependencySet +/// @notice Interface for L1Block with only `isInDependencySet(uint256)` method. +interface IDependencySet { + /// @notice Returns true if the chain associated with input chain ID is in the interop dependency set. + /// Every chain is in the interop dependency set of itself. + /// @param _chainId Input chain ID. + /// @return True if the input chain ID corresponds to a chain in the interop dependency set, and false otherwise. + function isInDependencySet(uint256 _chainId) external view returns (bool); +} diff --git a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS.sol b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS.sol index 97b3dc8ef283..9617ddb9c010 100644 --- a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS.sol +++ b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.15; +pragma solidity ^0.8.0; import { ISemver } from "src/universal/ISemver.sol"; import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol"; diff --git a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol index 540033433329..ea7033aea907 100644 --- a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol +++ b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.15; +pragma solidity ^0.8.0; import { ISemver } from "src/universal/ISemver.sol"; diff --git a/packages/contracts-bedrock/src/cannon/interfaces/IPreimageOracle.sol b/packages/contracts-bedrock/src/cannon/interfaces/IPreimageOracle.sol index 9f923fcfe8fc..79ee56f821c9 100644 --- a/packages/contracts-bedrock/src/cannon/interfaces/IPreimageOracle.sol +++ b/packages/contracts-bedrock/src/cannon/interfaces/IPreimageOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.15; +pragma solidity ^0.8.0; /// @title IPreimageOracle /// @notice Interface for a preimage oracle. diff --git a/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol b/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol index 4f3f7509c9fd..b68eb13d1018 100644 --- a/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol +++ b/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol @@ -2,11 +2,7 @@ pragma solidity 0.8.15; import { Constants } from "src/libraries/Constants.sol"; - -/// @title IL1ChugSplashDeployer -interface IL1ChugSplashDeployer { - function isUpgrading() external view returns (bool); -} +import { IL1ChugSplashDeployer } from "src/legacy/interfaces/IL1ChugSplashProxy.sol"; /// @custom:legacy /// @title L1ChugSplashProxy diff --git a/packages/contracts-bedrock/src/legacy/interfaces/IL1ChugSplashProxy.sol b/packages/contracts-bedrock/src/legacy/interfaces/IL1ChugSplashProxy.sol index 5840dcf056c3..f4ca59fb5511 100644 --- a/packages/contracts-bedrock/src/legacy/interfaces/IL1ChugSplashProxy.sol +++ b/packages/contracts-bedrock/src/legacy/interfaces/IL1ChugSplashProxy.sol @@ -14,3 +14,15 @@ interface IL1ChugSplashProxy { function setOwner(address _owner) external; function setStorage(bytes32 _key, bytes32 _value) external; } + +/// @title IStaticL1ChugSplashProxy +/// @notice IStaticL1ChugSplashProxy is a static version of the ChugSplash proxy interface. +interface IStaticL1ChugSplashProxy { + function getImplementation() external view returns (address); + function getOwner() external view returns (address); +} + +/// @title IL1ChugSplashDeployer +interface IL1ChugSplashDeployer { + function isUpgrading() external view returns (bool); +} diff --git a/packages/contracts-bedrock/src/periphery/drippie/dripchecks/CheckGelatoLow.sol b/packages/contracts-bedrock/src/periphery/drippie/dripchecks/CheckGelatoLow.sol index 0ef6a0020c6a..a5ef463f89e6 100644 --- a/packages/contracts-bedrock/src/periphery/drippie/dripchecks/CheckGelatoLow.sol +++ b/packages/contracts-bedrock/src/periphery/drippie/dripchecks/CheckGelatoLow.sol @@ -2,11 +2,7 @@ pragma solidity 0.8.15; import { IDripCheck } from "../IDripCheck.sol"; - -interface IGelatoTreasury { - function totalDepositedAmount(address _user, address _token) external view returns (uint256); - function totalWithdrawnAmount(address _user, address _token) external view returns (uint256); -} +import { IGelatoTreasury } from "src/vendor/interfaces/IGelatoTreasury.sol"; /// @title CheckGelatoLow /// @notice DripCheck for checking if an account's Gelato ETH balance is below some threshold. diff --git a/packages/contracts-bedrock/src/periphery/faucet/authmodules/IFaucetAuthModule.sol b/packages/contracts-bedrock/src/periphery/faucet/authmodules/IFaucetAuthModule.sol index 5bef4c8c705a..a94071dd2bef 100644 --- a/packages/contracts-bedrock/src/periphery/faucet/authmodules/IFaucetAuthModule.sol +++ b/packages/contracts-bedrock/src/periphery/faucet/authmodules/IFaucetAuthModule.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.15; +pragma solidity ^0.8.0; import { Faucet } from "../Faucet.sol"; diff --git a/packages/contracts-bedrock/src/universal/ProxyAdmin.sol b/packages/contracts-bedrock/src/universal/ProxyAdmin.sol index 8558d421bb46..e554345d4264 100644 --- a/packages/contracts-bedrock/src/universal/ProxyAdmin.sol +++ b/packages/contracts-bedrock/src/universal/ProxyAdmin.sol @@ -6,22 +6,8 @@ import { Proxy } from "src/universal/Proxy.sol"; import { AddressManager } from "src/legacy/AddressManager.sol"; import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol"; import { Constants } from "src/libraries/Constants.sol"; - -/// @title IStaticERC1967Proxy -/// @notice IStaticERC1967Proxy is a static version of the ERC1967 proxy interface. -interface IStaticERC1967Proxy { - function implementation() external view returns (address); - - function admin() external view returns (address); -} - -/// @title IStaticL1ChugSplashProxy -/// @notice IStaticL1ChugSplashProxy is a static version of the ChugSplash proxy interface. -interface IStaticL1ChugSplashProxy { - function getImplementation() external view returns (address); - - function getOwner() external view returns (address); -} +import { IStaticERC1967Proxy } from "src/universal/interfaces/IStaticERC1967Proxy.sol"; +import { IStaticL1ChugSplashProxy } from "src/legacy/interfaces/IL1ChugSplashProxy.sol"; /// @title ProxyAdmin /// @notice This is an auxiliary contract meant to be assigned as the admin of an ERC1967 Proxy, diff --git a/packages/contracts-bedrock/src/universal/interfaces/IEIP712.sol b/packages/contracts-bedrock/src/universal/interfaces/IEIP712.sol new file mode 100644 index 000000000000..b05a49cb01ea --- /dev/null +++ b/packages/contracts-bedrock/src/universal/interfaces/IEIP712.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @title IEIP712 +interface IEIP712 { + function DOMAIN_SEPARATOR() external view returns (bytes32); +} diff --git a/packages/contracts-bedrock/src/universal/interfaces/IStaticERC1967Proxy.sol b/packages/contracts-bedrock/src/universal/interfaces/IStaticERC1967Proxy.sol new file mode 100644 index 000000000000..511f2be7b4f2 --- /dev/null +++ b/packages/contracts-bedrock/src/universal/interfaces/IStaticERC1967Proxy.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @title IStaticERC1967Proxy +/// @notice IStaticERC1967Proxy is a static version of the ERC1967 proxy interface. +interface IStaticERC1967Proxy { + function implementation() external view returns (address); + function admin() external view returns (address); +} diff --git a/packages/contracts-bedrock/src/vendor/interfaces/IGelatoTreasury.sol b/packages/contracts-bedrock/src/vendor/interfaces/IGelatoTreasury.sol new file mode 100644 index 000000000000..8438948f850d --- /dev/null +++ b/packages/contracts-bedrock/src/vendor/interfaces/IGelatoTreasury.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @title IGelatoTreasury +/// @notice Interface for the GelatoTreasury contract. +interface IGelatoTreasury { + function totalDepositedAmount(address _user, address _token) external view returns (uint256); + function totalWithdrawnAmount(address _user, address _token) external view returns (uint256); +} diff --git a/packages/contracts-bedrock/test/Preinstalls.t.sol b/packages/contracts-bedrock/test/Preinstalls.t.sol index a0da8c5e32cc..9154dfc064c6 100644 --- a/packages/contracts-bedrock/test/Preinstalls.t.sol +++ b/packages/contracts-bedrock/test/Preinstalls.t.sol @@ -5,10 +5,7 @@ import { CommonTest } from "test/setup/CommonTest.sol"; import { Preinstalls } from "src/libraries/Preinstalls.sol"; import { Bytes } from "src/libraries/Bytes.sol"; import { console2 as console } from "forge-std/console2.sol"; - -interface IEIP712 { - function DOMAIN_SEPARATOR() external view returns (bytes32); -} +import { IEIP712 } from "src/universal/interfaces/IEIP712.sol"; /// @title PreinstallsTest contract PreinstallsTest is CommonTest { diff --git a/packages/contracts-bedrock/test/periphery/op-nft/Optimist.t.sol b/packages/contracts-bedrock/test/periphery/op-nft/Optimist.t.sol index 9aab06fde007..22b6effc7ed4 100644 --- a/packages/contracts-bedrock/test/periphery/op-nft/Optimist.t.sol +++ b/packages/contracts-bedrock/test/periphery/op-nft/Optimist.t.sol @@ -3,6 +3,7 @@ pragma solidity >=0.6.2 <0.9.0; // Testing utilities import { Test } from "forge-std/Test.sol"; +import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol"; import { AttestationStation } from "src/periphery/op-nft/AttestationStation.sol"; import { Optimist } from "src/periphery/op-nft/Optimist.sol"; import { OptimistAllowlist } from "src/periphery/op-nft/OptimistAllowlist.sol"; @@ -11,21 +12,6 @@ import { OptimistInviterHelper } from "test/mocks/OptimistInviterHelper.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; -interface IMulticall3 { - struct Call3 { - address target; - bool allowFailure; - bytes callData; - } - - struct Result { - bool success; - bytes returnData; - } - - function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData); -} - library Multicall { bytes internal constant code = hex"6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461025a578063bce38bd714610275578063c3077fa914610288578063ee82ac5e1461029b57600080fd5b80634d2301cc146101ec57806372425d9d1461022157806382ad56cb1461023457806386d516e81461024757600080fd5b80633408e470116100c65780633408e47014610191578063399542e9146101a45780633e64a696146101c657806342cbb15c146101d957600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d610128366004610a85565b6102ba565b6040516101119190610bbe565b61014d610148366004610a85565b6104ef565b604051610111929190610bd8565b34801561016757600080fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610107565b34801561019d57600080fd5b5046610107565b6101b76101b2366004610c60565b610690565b60405161011193929190610cba565b3480156101d257600080fd5b5048610107565b3480156101e557600080fd5b5043610107565b3480156101f857600080fd5b50610107610207366004610ce2565b73ffffffffffffffffffffffffffffffffffffffff163190565b34801561022d57600080fd5b5044610107565b61012d610242366004610a85565b6106ab565b34801561025357600080fd5b5045610107565b34801561026657600080fd5b50604051418152602001610111565b61012d610283366004610c60565b61085a565b6101b7610296366004610a85565b610a1a565b3480156102a757600080fd5b506101076102b6366004610d18565b4090565b60606000828067ffffffffffffffff8111156102d8576102d8610d31565b60405190808252806020026020018201604052801561031e57816020015b6040805180820190915260008152606060208201528152602001906001900390816102f65790505b5092503660005b8281101561047757600085828151811061034157610341610d60565b6020026020010151905087878381811061035d5761035d610d60565b905060200281019061036f9190610d8f565b6040810135958601959093506103886020850185610ce2565b73ffffffffffffffffffffffffffffffffffffffff16816103ac6060870187610dcd565b6040516103ba929190610e32565b60006040518083038185875af1925050503d80600081146103f7576040519150601f19603f3d011682016040523d82523d6000602084013e6103fc565b606091505b50602080850191909152901515808452908501351761046d577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fd5b5050600101610325565b508234146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561050c5761050c610d31565b60405190808252806020026020018201604052801561053f57816020015b606081526020019060019003908161052a5790505b5091503660005b8281101561068657600087878381811061056257610562610d60565b90506020028101906105749190610e42565b92506105836020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166105a66020850185610dcd565b6040516105b4929190610e32565b6000604051808303816000865af19150503d80600081146105f1576040519150601f19603f3d011682016040523d82523d6000602084013e6105f6565b606091505b5086848151811061060957610609610d60565b602090810291909101015290508061067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b50600101610546565b5050509250929050565b43804060606106a086868661085a565b905093509350939050565b6060818067ffffffffffffffff8111156106c7576106c7610d31565b60405190808252806020026020018201604052801561070d57816020015b6040805180820190915260008152606060208201528152602001906001900390816106e55790505b5091503660005b828110156104e657600084828151811061073057610730610d60565b6020026020010151905086868381811061074c5761074c610d60565b905060200281019061075e9190610e76565b925061076d6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166107906040850185610dcd565b60405161079e929190610e32565b6000604051808303816000865af19150503d80600081146107db576040519150601f19603f3d011682016040523d82523d6000602084013e6107e0565b606091505b506020808401919091529015158083529084013517610851577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b50600101610714565b6060818067ffffffffffffffff81111561087657610876610d31565b6040519080825280602002602001820160405280156108bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816108945790505b5091503660005b82811015610a105760008482815181106108df576108df610d60565b602002602001015190508686838181106108fb576108fb610d60565b905060200281019061090d9190610e42565b925061091c6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff1661093f6020850185610dcd565b60405161094d929190610e32565b6000604051808303816000865af19150503d806000811461098a576040519150601f19603f3d011682016040523d82523d6000602084013e61098f565b606091505b506020830152151581528715610a07578051610a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b506001016108c3565b5050509392505050565b6000806060610a2b60018686610690565b919790965090945092505050565b60008083601f840112610a4b57600080fd5b50813567ffffffffffffffff811115610a6357600080fd5b6020830191508360208260051b8501011115610a7e57600080fd5b9250929050565b60008060208385031215610a9857600080fd5b823567ffffffffffffffff811115610aaf57600080fd5b610abb85828601610a39565b90969095509350505050565b6000815180845260005b81811015610aed57602081850181015186830182015201610ad1565b81811115610aff576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b84811015610bb1578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b9d81860183610ac7565b9a86019a9450505090830190600101610b4f565b5090979650505050505050565b602081526000610bd16020830184610b32565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610c52577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610c40868351610ac7565b95509284019290840190600101610c06565b509398975050505050505050565b600080600060408486031215610c7557600080fd5b83358015158114610c8557600080fd5b9250602084013567ffffffffffffffff811115610ca157600080fd5b610cad86828701610a39565b9497909650939450505050565b838152826020820152606060408201526000610cd96060830184610b32565b95945050505050565b600060208284031215610cf457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610bd157600080fd5b600060208284031215610d2a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610dc357600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610e0257600080fd5b83018035915067ffffffffffffffff821115610e1d57600080fd5b602001915036819003821315610a7e57600080fd5b8183823760009101908152919050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610dc357600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610dc357600080fdfea2646970667358221220bb2b5c71a328032f97c676ae39a1ec2148d3e5d6f73d95e9b17910152d61f16264736f6c634300080c0033"; From 3410109155ae75915ff95dc0a1995ac0d3cac8b5 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Thu, 5 Sep 2024 07:20:55 +1000 Subject: [PATCH 033/264] challenger: Introduce StateConverter to abstract loading VM states (#11715) --- op-challenger/game/fault/register_task.go | 8 +- .../game/fault/trace/asterisc/prestate.go | 45 ---------- .../fault/trace/asterisc/prestate_test.go | 59 ------------ .../game/fault/trace/asterisc/provider.go | 34 +++---- .../fault/trace/asterisc/provider_test.go | 11 +-- .../asterisc/{state.go => state_converter.go} | 25 ++++++ .../game/fault/trace/cannon/prestate.go | 47 ---------- .../game/fault/trace/cannon/prestate_test.go | 89 ------------------- .../game/fault/trace/cannon/provider.go | 43 +++------ .../game/fault/trace/cannon/provider_test.go | 11 +-- .../game/fault/trace/cannon/state.go | 27 ------ .../fault/trace/cannon/state_converter.go | 53 +++++++++++ op-challenger/game/fault/trace/vm/iface.go | 9 ++ op-challenger/game/fault/trace/vm/prestate.go | 42 +++++++++ .../game/fault/trace/vm/prestate_test.go | 63 +++++++++++++ op-challenger/runner/factory.go | 6 +- 16 files changed, 233 insertions(+), 339 deletions(-) delete mode 100644 op-challenger/game/fault/trace/asterisc/prestate.go delete mode 100644 op-challenger/game/fault/trace/asterisc/prestate_test.go rename op-challenger/game/fault/trace/asterisc/{state.go => state_converter.go} (73%) delete mode 100644 op-challenger/game/fault/trace/cannon/prestate.go delete mode 100644 op-challenger/game/fault/trace/cannon/prestate_test.go delete mode 100644 op-challenger/game/fault/trace/cannon/state.go create mode 100644 op-challenger/game/fault/trace/cannon/state_converter.go create mode 100644 op-challenger/game/fault/trace/vm/iface.go create mode 100644 op-challenger/game/fault/trace/vm/prestate.go create mode 100644 op-challenger/game/fault/trace/vm/prestate_test.go diff --git a/op-challenger/game/fault/register_task.go b/op-challenger/game/fault/register_task.go index b9b2db6b4951..40acfecce22b 100644 --- a/op-challenger/game/fault/register_task.go +++ b/op-challenger/game/fault/register_task.go @@ -57,7 +57,7 @@ func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m c cfg.CannonAbsolutePreState, filepath.Join(cfg.Datadir, "cannon-prestates"), func(path string) faultTypes.PrestateProvider { - return cannon.NewPrestateProvider(path) + return vm.NewPrestateProvider(path, cannon.NewStateConverter()) }), newTraceAccessor: func( logger log.Logger, @@ -71,7 +71,7 @@ func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m c splitDepth faultTypes.Depth, prestateBlock uint64, poststateBlock uint64) (*trace.Accessor, error) { - provider := vmPrestateProvider.(*cannon.CannonPrestateProvider) + provider := vmPrestateProvider.(*vm.PrestateProvider) return outputs.NewOutputCannonTraceAccessor(logger, m, cfg.Cannon, serverExecutor, l2Client, prestateProvider, provider.PrestatePath(), rollupClient, dir, l1Head, splitDepth, prestateBlock, poststateBlock) }, } @@ -87,7 +87,7 @@ func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m cfg.AsteriscAbsolutePreState, filepath.Join(cfg.Datadir, "asterisc-prestates"), func(path string) faultTypes.PrestateProvider { - return asterisc.NewPrestateProvider(path) + return vm.NewPrestateProvider(path, asterisc.NewStateConverter()) }), newTraceAccessor: func( logger log.Logger, @@ -101,7 +101,7 @@ func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m splitDepth faultTypes.Depth, prestateBlock uint64, poststateBlock uint64) (*trace.Accessor, error) { - provider := vmPrestateProvider.(*asterisc.AsteriscPreStateProvider) + provider := vmPrestateProvider.(*vm.PrestateProvider) return outputs.NewOutputAsteriscTraceAccessor(logger, m, cfg.Asterisc, serverExecutor, l2Client, prestateProvider, provider.PrestatePath(), rollupClient, dir, l1Head, splitDepth, prestateBlock, poststateBlock) }, } diff --git a/op-challenger/game/fault/trace/asterisc/prestate.go b/op-challenger/game/fault/trace/asterisc/prestate.go deleted file mode 100644 index f65e4d9c901c..000000000000 --- a/op-challenger/game/fault/trace/asterisc/prestate.go +++ /dev/null @@ -1,45 +0,0 @@ -package asterisc - -import ( - "context" - "fmt" - - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - "github.com/ethereum/go-ethereum/common" -) - -var _ types.PrestateProvider = (*AsteriscPreStateProvider)(nil) - -type AsteriscPreStateProvider struct { - prestate string - - prestateCommitment common.Hash -} - -func NewPrestateProvider(prestate string) *AsteriscPreStateProvider { - return &AsteriscPreStateProvider{prestate: prestate} -} - -func (p *AsteriscPreStateProvider) absolutePreState() (*VMState, error) { - state, err := parseState(p.prestate) - if err != nil { - return nil, fmt.Errorf("cannot load absolute pre-state: %w", err) - } - return state, nil -} - -func (p *AsteriscPreStateProvider) AbsolutePreStateCommitment(_ context.Context) (common.Hash, error) { - if p.prestateCommitment != (common.Hash{}) { - return p.prestateCommitment, nil - } - state, err := p.absolutePreState() - if err != nil { - return common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err) - } - p.prestateCommitment = state.StateHash - return state.StateHash, nil -} - -func (p *AsteriscPreStateProvider) PrestatePath() string { - return p.prestate -} diff --git a/op-challenger/game/fault/trace/asterisc/prestate_test.go b/op-challenger/game/fault/trace/asterisc/prestate_test.go deleted file mode 100644 index 38bc6d360e7b..000000000000 --- a/op-challenger/game/fault/trace/asterisc/prestate_test.go +++ /dev/null @@ -1,59 +0,0 @@ -package asterisc - -import ( - "context" - "os" - "path/filepath" - "testing" - - "github.com/stretchr/testify/require" -) - -func newAsteriscPrestateProvider(dataDir string, prestate string) *AsteriscPreStateProvider { - return &AsteriscPreStateProvider{ - prestate: filepath.Join(dataDir, prestate), - } -} - -func TestAbsolutePreStateCommitment(t *testing.T) { - dataDir := t.TempDir() - - prestate := "state.json" - - t.Run("StateUnavailable", func(t *testing.T) { - provider := newAsteriscPrestateProvider("/dir/does/not/exist", prestate) - _, err := provider.AbsolutePreStateCommitment(context.Background()) - require.ErrorIs(t, err, os.ErrNotExist) - }) - - t.Run("InvalidStateFile", func(t *testing.T) { - setupPreState(t, dataDir, "invalid.json") - provider := newAsteriscPrestateProvider(dataDir, prestate) - _, err := provider.AbsolutePreStateCommitment(context.Background()) - require.ErrorContains(t, err, "invalid asterisc VM state") - }) - - t.Run("CacheAbsolutePreState", func(t *testing.T) { - setupPreState(t, dataDir, prestate) - provider := newAsteriscPrestateProvider(dataDir, prestate) - first, err := provider.AbsolutePreStateCommitment(context.Background()) - require.NoError(t, err) - - // Remove the prestate from disk - require.NoError(t, os.Remove(provider.prestate)) - - // Value should still be available from cache - cached, err := provider.AbsolutePreStateCommitment(context.Background()) - require.NoError(t, err) - require.Equal(t, first, cached) - }) -} - -func setupPreState(t *testing.T, dataDir string, filename string) { - srcDir := filepath.Join("test_data") - path := filepath.Join(srcDir, filename) - file, err := testData.ReadFile(path) - require.NoErrorf(t, err, "reading %v", path) - err = os.WriteFile(filepath.Join(dataDir, "state.json"), file, 0o644) - require.NoErrorf(t, err, "writing %v", path) -} diff --git a/op-challenger/game/fault/trace/asterisc/provider.go b/op-challenger/game/fault/trace/asterisc/provider.go index cad5e36b839e..4ee345f807f4 100644 --- a/op-challenger/game/fault/trace/asterisc/provider.go +++ b/op-challenger/game/fault/trace/asterisc/provider.go @@ -27,6 +27,7 @@ type AsteriscTraceProvider struct { generator utils.ProofGenerator gameDepth types.Depth preimageLoader *utils.PreimageLoader + stateConverter vm.StateConverter types.PrestateProvider @@ -46,6 +47,7 @@ func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, vmCfg vm. return kvstore.NewFileKV(vm.PreimageDir(dir)) }), PrestateProvider: prestateProvider, + stateConverter: NewStateConverter(), } } @@ -120,31 +122,23 @@ func (p *AsteriscTraceProvider) loadProof(ctx context.Context, i uint64) (*utils file, err = ioutil.OpenDecompressed(path) if errors.Is(err, os.ErrNotExist) { // Expected proof wasn't generated, check if we reached the end of execution - state, err := p.finalState() + proof, step, exited, err := p.stateConverter.ConvertStateToProof(filepath.Join(p.dir, vm.FinalState)) if err != nil { return nil, err } - if state.Exited && state.Step <= i { - p.logger.Warn("Requested proof was after the program exited", "proof", i, "last", state.Step) + if exited && step <= i { + p.logger.Warn("Requested proof was after the program exited", "proof", i, "last", step) // The final instruction has already been applied to this state, so the last step we can execute // is one before its Step value. - p.lastStep = state.Step - 1 + p.lastStep = step - 1 // Extend the trace out to the full length using a no-op instruction that doesn't change any state // No execution is done, so no proof-data or oracle values are required. - proof := &utils.ProofData{ - ClaimValue: state.StateHash, - StateData: state.Witness, - ProofData: []byte{}, - OracleKey: nil, - OracleValue: nil, - OracleOffset: 0, - } if err := utils.WriteLastStep(p.dir, proof, p.lastStep); err != nil { p.logger.Warn("Failed to write last step to disk cache", "step", p.lastStep) } return proof, nil } else { - return nil, fmt.Errorf("expected proof not generated but final state was not exited, requested step %v, final state at step %v", i, state.Step) + return nil, fmt.Errorf("expected proof not generated but final state was not exited, requested step %v, final state at step %v", i, step) } } } @@ -160,14 +154,6 @@ func (p *AsteriscTraceProvider) loadProof(ctx context.Context, i uint64) (*utils return &proof, nil } -func (c *AsteriscTraceProvider) finalState() (*VMState, error) { - state, err := parseState(filepath.Join(c.dir, vm.FinalState)) - if err != nil { - return nil, fmt.Errorf("cannot read final state: %w", err) - } - return state, nil -} - // AsteriscTraceProviderForTest is a AsteriscTraceProvider that can find the step referencing the preimage read // Only to be used for testing type AsteriscTraceProviderForTest struct { @@ -194,14 +180,14 @@ func (p *AsteriscTraceProviderForTest) FindStep(ctx context.Context, start uint6 return 0, fmt.Errorf("generate asterisc trace (until preimage read): %w", err) } // Load the step from the state asterisc finished with - state, err := p.finalState() + _, step, exited, err := p.stateConverter.ConvertStateToProof(filepath.Join(p.dir, vm.FinalState)) if err != nil { return 0, fmt.Errorf("failed to load final state: %w", err) } // Check we didn't get to the end of the trace without finding the preimage read we were looking for - if state.Exited { + if exited { return 0, fmt.Errorf("preimage read not found: %w", io.EOF) } // The state is the post-state so the step we want to execute to read the preimage is step - 1. - return state.Step - 1, nil + return step - 1, nil } diff --git a/op-challenger/game/fault/trace/asterisc/provider_test.go b/op-challenger/game/fault/trace/asterisc/provider_test.go index 939a27decc30..d467bbb668dc 100644 --- a/op-challenger/game/fault/trace/asterisc/provider_test.go +++ b/op-challenger/game/fault/trace/asterisc/provider_test.go @@ -221,11 +221,12 @@ func setupTestData(t *testing.T) (string, string) { func setupWithTestData(t *testing.T, dataDir string, prestate string) (*AsteriscTraceProvider, *stubGenerator) { generator := &stubGenerator{} return &AsteriscTraceProvider{ - logger: testlog.Logger(t, log.LevelInfo), - dir: dataDir, - generator: generator, - prestate: filepath.Join(dataDir, prestate), - gameDepth: 63, + logger: testlog.Logger(t, log.LevelInfo), + dir: dataDir, + generator: generator, + prestate: filepath.Join(dataDir, prestate), + gameDepth: 63, + stateConverter: &StateConverter{}, }, generator } diff --git a/op-challenger/game/fault/trace/asterisc/state.go b/op-challenger/game/fault/trace/asterisc/state_converter.go similarity index 73% rename from op-challenger/game/fault/trace/asterisc/state.go rename to op-challenger/game/fault/trace/asterisc/state_converter.go index e30ebf8702d8..29c9f8b2ea50 100644 --- a/op-challenger/game/fault/trace/asterisc/state.go +++ b/op-challenger/game/fault/trace/asterisc/state_converter.go @@ -8,6 +8,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum-optimism/optimism/cannon/mipsevm" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" "github.com/ethereum-optimism/optimism/op-service/ioutil" ) @@ -74,3 +75,27 @@ func parseStateFromReader(in io.ReadCloser) (*VMState, error) { } return &state, nil } + +type StateConverter struct { +} + +func NewStateConverter() *StateConverter { + return &StateConverter{} +} + +func (c *StateConverter) ConvertStateToProof(statePath string) (*utils.ProofData, uint64, bool, error) { + state, err := parseState(statePath) + if err != nil { + return nil, 0, false, fmt.Errorf("cannot read final state: %w", err) + } + // Extend the trace out to the full length using a no-op instruction that doesn't change any state + // No execution is done, so no proof-data or oracle values are required. + return &utils.ProofData{ + ClaimValue: state.StateHash, + StateData: state.Witness, + ProofData: []byte{}, + OracleKey: nil, + OracleValue: nil, + OracleOffset: 0, + }, state.Step, state.Exited, nil +} diff --git a/op-challenger/game/fault/trace/cannon/prestate.go b/op-challenger/game/fault/trace/cannon/prestate.go deleted file mode 100644 index 6fcb8f50f662..000000000000 --- a/op-challenger/game/fault/trace/cannon/prestate.go +++ /dev/null @@ -1,47 +0,0 @@ -package cannon - -import ( - "context" - "fmt" - - "github.com/ethereum/go-ethereum/common" - - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" -) - -var _ types.PrestateProvider = (*CannonPrestateProvider)(nil) - -type CannonPrestateProvider struct { - prestate string - - prestateCommitment common.Hash -} - -func NewPrestateProvider(prestate string) *CannonPrestateProvider { - return &CannonPrestateProvider{prestate: prestate} -} - -func (p *CannonPrestateProvider) absolutePreState() ([]byte, common.Hash, error) { - state, err := parseState(p.prestate) - if err != nil { - return nil, common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err) - } - witness, hash := state.EncodeWitness() - return witness, hash, nil -} - -func (p *CannonPrestateProvider) AbsolutePreStateCommitment(_ context.Context) (common.Hash, error) { - if p.prestateCommitment != (common.Hash{}) { - return p.prestateCommitment, nil - } - _, hash, err := p.absolutePreState() - if err != nil { - return common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err) - } - p.prestateCommitment = hash - return hash, nil -} - -func (p *CannonPrestateProvider) PrestatePath() string { - return p.prestate -} diff --git a/op-challenger/game/fault/trace/cannon/prestate_test.go b/op-challenger/game/fault/trace/cannon/prestate_test.go deleted file mode 100644 index 9566e9d0664c..000000000000 --- a/op-challenger/game/fault/trace/cannon/prestate_test.go +++ /dev/null @@ -1,89 +0,0 @@ -package cannon - -import ( - "context" - "os" - "path/filepath" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/require" - - "github.com/ethereum-optimism/optimism/cannon/mipsevm" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/memory" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" -) - -func newCannonPrestateProvider(dataDir string, prestate string) *CannonPrestateProvider { - return &CannonPrestateProvider{ - prestate: filepath.Join(dataDir, prestate), - } -} - -func TestAbsolutePreStateCommitment(t *testing.T) { - dataDir := t.TempDir() - - prestate := "state.json" - - t.Run("StateUnavailable", func(t *testing.T) { - provider := newCannonPrestateProvider("/dir/does/not/exist", prestate) - _, err := provider.AbsolutePreStateCommitment(context.Background()) - require.ErrorIs(t, err, os.ErrNotExist) - }) - - t.Run("InvalidStateFile", func(t *testing.T) { - setupPreState(t, dataDir, "invalid.json") - provider := newCannonPrestateProvider(dataDir, prestate) - _, err := provider.AbsolutePreStateCommitment(context.Background()) - require.ErrorContains(t, err, "invalid mipsevm state") - }) - - t.Run("ExpectedAbsolutePreState", func(t *testing.T) { - setupPreState(t, dataDir, "state.json") - provider := newCannonPrestateProvider(dataDir, prestate) - actual, err := provider.AbsolutePreStateCommitment(context.Background()) - require.NoError(t, err) - state := singlethreaded.State{ - Memory: memory.NewMemory(), - PreimageKey: common.HexToHash("cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"), - PreimageOffset: 0, - Cpu: mipsevm.CpuScalars{ - PC: 0, - NextPC: 1, - LO: 0, - HI: 0, - }, - Heap: 0, - ExitCode: 0, - Exited: false, - Step: 0, - Registers: [32]uint32{}, - } - _, expected := state.EncodeWitness() - require.Equal(t, expected, actual) - }) - - t.Run("CacheAbsolutePreState", func(t *testing.T) { - setupPreState(t, dataDir, prestate) - provider := newCannonPrestateProvider(dataDir, prestate) - first, err := provider.AbsolutePreStateCommitment(context.Background()) - require.NoError(t, err) - - // Remove the prestate from disk - require.NoError(t, os.Remove(provider.prestate)) - - // Value should still be available from cache - cached, err := provider.AbsolutePreStateCommitment(context.Background()) - require.NoError(t, err) - require.Equal(t, first, cached) - }) -} - -func setupPreState(t *testing.T, dataDir string, filename string) { - srcDir := filepath.Join("test_data") - path := filepath.Join(srcDir, filename) - file, err := testData.ReadFile(path) - require.NoErrorf(t, err, "reading %v", path) - err = os.WriteFile(filepath.Join(dataDir, "state.json"), file, 0o644) - require.NoErrorf(t, err, "writing %v", path) -} diff --git a/op-challenger/game/fault/trace/cannon/provider.go b/op-challenger/game/fault/trace/cannon/provider.go index fc7a71c1cda0..fb85222d0064 100644 --- a/op-challenger/game/fault/trace/cannon/provider.go +++ b/op-challenger/game/fault/trace/cannon/provider.go @@ -11,10 +11,8 @@ import ( "path/filepath" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" "github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" @@ -30,6 +28,7 @@ type CannonTraceProvider struct { generator utils.ProofGenerator gameDepth types.Depth preimageLoader *utils.PreimageLoader + stateConverter vm.StateConverter types.PrestateProvider @@ -49,6 +48,7 @@ func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, vmCfg vm. return kvstore.NewFileKV(vm.PreimageDir(dir)) }), PrestateProvider: prestateProvider, + stateConverter: &StateConverter{}, } } @@ -122,33 +122,22 @@ func (p *CannonTraceProvider) loadProof(ctx context.Context, i uint64) (*utils.P // Try opening the file again now and it should exist. file, err = ioutil.OpenDecompressed(path) if errors.Is(err, os.ErrNotExist) { - // Expected proof wasn't generated, check if we reached the end of execution - state, err := p.finalState() + proof, stateStep, exited, err := p.stateConverter.ConvertStateToProof(filepath.Join(p.dir, vm.FinalState)) if err != nil { - return nil, err + return nil, fmt.Errorf("cannot create proof from final state: %w", err) } - if state.Exited && state.Step <= i { - p.logger.Warn("Requested proof was after the program exited", "proof", i, "last", state.Step) + + if exited && stateStep <= i { + p.logger.Warn("Requested proof was after the program exited", "proof", i, "last", stateStep) // The final instruction has already been applied to this state, so the last step we can execute // is one before its Step value. - p.lastStep = state.Step - 1 - // Extend the trace out to the full length using a no-op instruction that doesn't change any state - // No execution is done, so no proof-data or oracle values are required. - witness, witnessHash := state.EncodeWitness() - proof := &utils.ProofData{ - ClaimValue: witnessHash, - StateData: hexutil.Bytes(witness), - ProofData: []byte{}, - OracleKey: nil, - OracleValue: nil, - OracleOffset: 0, - } + p.lastStep = stateStep - 1 if err := utils.WriteLastStep(p.dir, proof, p.lastStep); err != nil { p.logger.Warn("Failed to write last step to disk cache", "step", p.lastStep) } return proof, nil } else { - return nil, fmt.Errorf("expected proof not generated but final state was not exited, requested step %v, final state at step %v", i, state.Step) + return nil, fmt.Errorf("expected proof not generated but final state was not exited, requested step %v, final state at step %v", i, stateStep) } } } @@ -164,14 +153,6 @@ func (p *CannonTraceProvider) loadProof(ctx context.Context, i uint64) (*utils.P return &proof, nil } -func (c *CannonTraceProvider) finalState() (*singlethreaded.State, error) { - state, err := parseState(filepath.Join(c.dir, vm.FinalState)) - if err != nil { - return nil, fmt.Errorf("cannot read final state: %w", err) - } - return state, nil -} - // CannonTraceProviderForTest is a CannonTraceProvider that can find the step referencing the preimage read // Only to be used for testing type CannonTraceProviderForTest struct { @@ -198,14 +179,14 @@ func (p *CannonTraceProviderForTest) FindStep(ctx context.Context, start uint64, return 0, fmt.Errorf("generate cannon trace (until preimage read): %w", err) } // Load the step from the state cannon finished with - state, err := p.finalState() + _, step, exited, err := p.stateConverter.ConvertStateToProof(filepath.Join(p.dir, vm.FinalState)) if err != nil { return 0, fmt.Errorf("failed to load final state: %w", err) } // Check we didn't get to the end of the trace without finding the preimage read we were looking for - if state.Exited { + if exited { return 0, fmt.Errorf("preimage read not found: %w", io.EOF) } // The state is the post-state so the step we want to execute to read the preimage is step - 1. - return state.Step - 1, nil + return step - 1, nil } diff --git a/op-challenger/game/fault/trace/cannon/provider_test.go b/op-challenger/game/fault/trace/cannon/provider_test.go index 3343b581f1c1..c650bd6ef818 100644 --- a/op-challenger/game/fault/trace/cannon/provider_test.go +++ b/op-challenger/game/fault/trace/cannon/provider_test.go @@ -239,11 +239,12 @@ func setupTestData(t *testing.T) (string, string) { func setupWithTestData(t *testing.T, dataDir string, prestate string) (*CannonTraceProvider, *stubGenerator) { generator := &stubGenerator{} return &CannonTraceProvider{ - logger: testlog.Logger(t, log.LevelInfo), - dir: dataDir, - generator: generator, - prestate: filepath.Join(dataDir, prestate), - gameDepth: 63, + logger: testlog.Logger(t, log.LevelInfo), + dir: dataDir, + generator: generator, + prestate: filepath.Join(dataDir, prestate), + gameDepth: 63, + stateConverter: &StateConverter{}, }, generator } diff --git a/op-challenger/game/fault/trace/cannon/state.go b/op-challenger/game/fault/trace/cannon/state.go deleted file mode 100644 index cf781c8bd428..000000000000 --- a/op-challenger/game/fault/trace/cannon/state.go +++ /dev/null @@ -1,27 +0,0 @@ -package cannon - -import ( - "encoding/json" - "fmt" - "io" - - "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" - "github.com/ethereum-optimism/optimism/op-service/ioutil" -) - -func parseState(path string) (*singlethreaded.State, error) { - file, err := ioutil.OpenDecompressed(path) - if err != nil { - return nil, fmt.Errorf("cannot open state file (%v): %w", path, err) - } - return parseStateFromReader(file) -} - -func parseStateFromReader(in io.ReadCloser) (*singlethreaded.State, error) { - defer in.Close() - var state singlethreaded.State - if err := json.NewDecoder(in).Decode(&state); err != nil { - return nil, fmt.Errorf("invalid mipsevm state: %w", err) - } - return &state, nil -} diff --git a/op-challenger/game/fault/trace/cannon/state_converter.go b/op-challenger/game/fault/trace/cannon/state_converter.go new file mode 100644 index 000000000000..e11b0ee53caa --- /dev/null +++ b/op-challenger/game/fault/trace/cannon/state_converter.go @@ -0,0 +1,53 @@ +package cannon + +import ( + "encoding/json" + "fmt" + "io" + + "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" + "github.com/ethereum-optimism/optimism/op-service/ioutil" +) + +type StateConverter struct { +} + +func NewStateConverter() *StateConverter { + return &StateConverter{} +} + +func (c *StateConverter) ConvertStateToProof(statePath string) (*utils.ProofData, uint64, bool, error) { + state, err := parseState(statePath) + if err != nil { + return nil, 0, false, fmt.Errorf("cannot read final state: %w", err) + } + // Extend the trace out to the full length using a no-op instruction that doesn't change any state + // No execution is done, so no proof-data or oracle values are required. + witness, witnessHash := state.EncodeWitness() + return &utils.ProofData{ + ClaimValue: witnessHash, + StateData: witness, + ProofData: []byte{}, + OracleKey: nil, + OracleValue: nil, + OracleOffset: 0, + }, state.Step, state.Exited, nil +} + +func parseState(path string) (*singlethreaded.State, error) { + file, err := ioutil.OpenDecompressed(path) + if err != nil { + return nil, fmt.Errorf("cannot open state file (%v): %w", path, err) + } + return parseStateFromReader(file) +} + +func parseStateFromReader(in io.ReadCloser) (*singlethreaded.State, error) { + defer in.Close() + var state singlethreaded.State + if err := json.NewDecoder(in).Decode(&state); err != nil { + return nil, fmt.Errorf("invalid mipsevm state: %w", err) + } + return &state, nil +} diff --git a/op-challenger/game/fault/trace/vm/iface.go b/op-challenger/game/fault/trace/vm/iface.go new file mode 100644 index 000000000000..188f19e0c8e2 --- /dev/null +++ b/op-challenger/game/fault/trace/vm/iface.go @@ -0,0 +1,9 @@ +package vm + +import "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" + +type StateConverter interface { + // ConvertStateToProof reads the state snapshot at the specified path and converts it to ProofData. + // Returns the proof data, the VM step the state is from and whether or not the VM had exited. + ConvertStateToProof(statePath string) (*utils.ProofData, uint64, bool, error) +} diff --git a/op-challenger/game/fault/trace/vm/prestate.go b/op-challenger/game/fault/trace/vm/prestate.go new file mode 100644 index 000000000000..bbb4a9437d9a --- /dev/null +++ b/op-challenger/game/fault/trace/vm/prestate.go @@ -0,0 +1,42 @@ +package vm + +import ( + "context" + "fmt" + + "github.com/ethereum/go-ethereum/common" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" +) + +var _ types.PrestateProvider = (*PrestateProvider)(nil) + +type PrestateProvider struct { + prestate string + stateConverter StateConverter + + prestateCommitment common.Hash +} + +func NewPrestateProvider(prestate string, converter StateConverter) *PrestateProvider { + return &PrestateProvider{ + prestate: prestate, + stateConverter: converter, + } +} + +func (p *PrestateProvider) AbsolutePreStateCommitment(_ context.Context) (common.Hash, error) { + if p.prestateCommitment != (common.Hash{}) { + return p.prestateCommitment, nil + } + proof, _, _, err := p.stateConverter.ConvertStateToProof(p.prestate) + if err != nil { + return common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err) + } + p.prestateCommitment = proof.ClaimValue + return proof.ClaimValue, nil +} + +func (p *PrestateProvider) PrestatePath() string { + return p.prestate +} diff --git a/op-challenger/game/fault/trace/vm/prestate_test.go b/op-challenger/game/fault/trace/vm/prestate_test.go new file mode 100644 index 000000000000..69498e323c59 --- /dev/null +++ b/op-challenger/game/fault/trace/vm/prestate_test.go @@ -0,0 +1,63 @@ +package vm + +import ( + "context" + "errors" + "path/filepath" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +type stubConverter struct { + err error + hash common.Hash +} + +func (s *stubConverter) ConvertStateToProof(statePath string) (*utils.ProofData, uint64, bool, error) { + if s.err != nil { + return nil, 0, false, s.err + } + return &utils.ProofData{ + ClaimValue: s.hash, + }, 0, false, nil +} + +func newPrestateProvider(prestate common.Hash) *PrestateProvider { + return NewPrestateProvider("state.json", &stubConverter{hash: prestate}) +} + +func TestAbsolutePreStateCommitment(t *testing.T) { + prestate := common.Hash{0xaa, 0xbb} + + t.Run("StateUnavailable", func(t *testing.T) { + expectedErr := errors.New("kaboom") + provider := NewPrestateProvider("foo", &stubConverter{err: expectedErr}) + _, err := provider.AbsolutePreStateCommitment(context.Background()) + require.ErrorIs(t, err, expectedErr) + }) + + t.Run("ExpectedAbsolutePreState", func(t *testing.T) { + provider := newPrestateProvider(prestate) + actual, err := provider.AbsolutePreStateCommitment(context.Background()) + require.NoError(t, err) + require.Equal(t, prestate, actual) + }) + + t.Run("CacheAbsolutePreState", func(t *testing.T) { + converter := &stubConverter{hash: prestate} + provider := NewPrestateProvider(filepath.Join("state.json"), converter) + first, err := provider.AbsolutePreStateCommitment(context.Background()) + require.NoError(t, err) + + // Remove the prestate from disk + converter.err = errors.New("no soup for you") + + // Value should still be available from cache + cached, err := provider.AbsolutePreStateCommitment(context.Background()) + require.NoError(t, err) + require.Equal(t, first, cached) + }) +} diff --git a/op-challenger/runner/factory.go b/op-challenger/runner/factory.go index dae0a3fce146..59188210d8e5 100644 --- a/op-challenger/runner/factory.go +++ b/op-challenger/runner/factory.go @@ -33,7 +33,7 @@ func createTraceProvider( if err != nil { return nil, err } - prestateProvider := cannon.NewPrestateProvider(prestate) + prestateProvider := vm.NewPrestateProvider(prestate, cannon.NewStateConverter()) return cannon.NewTraceProvider(logger, m, cfg.Cannon, vmConfig, prestateProvider, prestate, localInputs, dir, 42), nil case types.TraceTypeAsterisc: vmConfig := vm.NewOpProgramServerExecutor() @@ -41,7 +41,7 @@ func createTraceProvider( if err != nil { return nil, err } - prestateProvider := asterisc.NewPrestateProvider(prestate) + prestateProvider := vm.NewPrestateProvider(prestate, asterisc.NewStateConverter()) return asterisc.NewTraceProvider(logger, m, cfg.Asterisc, vmConfig, prestateProvider, prestate, localInputs, dir, 42), nil case types.TraceTypeAsteriscKona: vmConfig := vm.NewKonaServerExecutor() @@ -49,7 +49,7 @@ func createTraceProvider( if err != nil { return nil, err } - prestateProvider := asterisc.NewPrestateProvider(prestate) + prestateProvider := vm.NewPrestateProvider(prestate, asterisc.NewStateConverter()) return asterisc.NewTraceProvider(logger, m, cfg.Asterisc, vmConfig, prestateProvider, prestate, localInputs, dir, 42), nil } return nil, errors.New("invalid trace type") From f63cba6fdca683677d2be4b07d82cd878170f322 Mon Sep 17 00:00:00 2001 From: Disco <131301107+0xDiscotech@users.noreply.github.com> Date: Wed, 4 Sep 2024 18:23:21 -0300 Subject: [PATCH 034/264] fix: flake tests (#11742) * fix: add optimism mintable check on assume address helper * fix: mock interfaces checks * chore: remove unused import --------- Co-authored-by: 0xng <87835144+0xng@users.noreply.github.com> --- .../test/L2/L2StandardBridgeInterop.t.sol | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol b/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol index d60ceb264a73..0fe37f2cf7c2 100644 --- a/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol +++ b/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol @@ -17,6 +17,7 @@ import { import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { IOptimismMintableERC20 } from "src/universal/IOptimismMintableERC20.sol"; +import { ILegacyMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; // TODO: Replace Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY with optimismSuperchainERC20Factory import { Predeploys } from "src/libraries/Predeploys.sol"; @@ -80,7 +81,7 @@ contract L2StandardBridgeInterop_LegacyToSuper_Test is L2StandardBridgeInterop_T // Mock `_from` to be a legacy address _mockInterface(_from, type(IERC165).interfaceId, true); - _mockInterface(_from, type(IOptimismMintableERC20).interfaceId, true); + _mockInterface(_from, type(ILegacyMintableERC20).interfaceId, true); } /// @notice Test that the `convert` function with different decimals reverts @@ -230,6 +231,11 @@ contract L2StandardBridgeInterop_SuperToLegacy_Test is L2StandardBridgeInterop_T // Mock same decimals _mockDecimals(_from, 18); _mockDecimals(_to, 18); + + // Mock `_from` so it is not a LegacyMintableERC20 address + _mockInterface(_from, type(IERC165).interfaceId, true); + _mockInterface(_from, type(ILegacyMintableERC20).interfaceId, false); + _mockInterface(_from, type(IOptimismMintableERC20).interfaceId, false); } /// @notice Test that the `convert` function with different decimals reverts From 2272a5dea9e2b4bdb7c78903a1ce00a0ea8cb003 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 4 Sep 2024 15:32:27 -0600 Subject: [PATCH 035/264] repo: bump foundry (#11746) Bumps foundry to the following commit: https://github.com/foundry-rs/foundry/commit/143abd6a768eeb52a5785240b763d72a56987b4a Release: https://github.com/foundry-rs/foundry/releases/tag/nightly This needs to be followed up with a rebuild of `ci-builder` --- versions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions.json b/versions.json index 21cb42e985c2..f1ca1a282c0a 100644 --- a/versions.json +++ b/versions.json @@ -1,7 +1,7 @@ { "go": "1.22.6", "abigen": "v1.10.25", - "foundry": "d28a3377e52e6a4114a8cea2903c115b023279e8", + "foundry": "143abd6a768eeb52a5785240b763d72a56987b4a", "geth": "v1.14.7", "geth_release": "1.14.7-aa55f5ea", "eth2_testnet_genesis": "v0.10.0", From 3f7a8ad1b8030a3d01d44bc57bf0553a249eae23 Mon Sep 17 00:00:00 2001 From: clabby Date: Wed, 4 Sep 2024 18:19:04 -0400 Subject: [PATCH 036/264] =?UTF-8?q?Revert=20"challenger:=20Introduce=20Sta?= =?UTF-8?q?teConverter=20to=20abstract=20loading=20VM=20states=20(#?= =?UTF-8?q?=E2=80=A6"=20(#11747)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 3410109155ae75915ff95dc0a1995ac0d3cac8b5. --- op-challenger/game/fault/register_task.go | 8 +- .../game/fault/trace/asterisc/prestate.go | 45 ++++++++++ .../fault/trace/asterisc/prestate_test.go | 59 ++++++++++++ .../game/fault/trace/asterisc/provider.go | 34 ++++--- .../fault/trace/asterisc/provider_test.go | 11 ++- .../asterisc/{state_converter.go => state.go} | 25 ------ .../game/fault/trace/cannon/prestate.go | 47 ++++++++++ .../game/fault/trace/cannon/prestate_test.go | 89 +++++++++++++++++++ .../game/fault/trace/cannon/provider.go | 43 ++++++--- .../game/fault/trace/cannon/provider_test.go | 11 ++- .../game/fault/trace/cannon/state.go | 27 ++++++ .../fault/trace/cannon/state_converter.go | 53 ----------- op-challenger/game/fault/trace/vm/iface.go | 9 -- op-challenger/game/fault/trace/vm/prestate.go | 42 --------- .../game/fault/trace/vm/prestate_test.go | 63 ------------- op-challenger/runner/factory.go | 6 +- 16 files changed, 339 insertions(+), 233 deletions(-) create mode 100644 op-challenger/game/fault/trace/asterisc/prestate.go create mode 100644 op-challenger/game/fault/trace/asterisc/prestate_test.go rename op-challenger/game/fault/trace/asterisc/{state_converter.go => state.go} (73%) create mode 100644 op-challenger/game/fault/trace/cannon/prestate.go create mode 100644 op-challenger/game/fault/trace/cannon/prestate_test.go create mode 100644 op-challenger/game/fault/trace/cannon/state.go delete mode 100644 op-challenger/game/fault/trace/cannon/state_converter.go delete mode 100644 op-challenger/game/fault/trace/vm/iface.go delete mode 100644 op-challenger/game/fault/trace/vm/prestate.go delete mode 100644 op-challenger/game/fault/trace/vm/prestate_test.go diff --git a/op-challenger/game/fault/register_task.go b/op-challenger/game/fault/register_task.go index 40acfecce22b..b9b2db6b4951 100644 --- a/op-challenger/game/fault/register_task.go +++ b/op-challenger/game/fault/register_task.go @@ -57,7 +57,7 @@ func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m c cfg.CannonAbsolutePreState, filepath.Join(cfg.Datadir, "cannon-prestates"), func(path string) faultTypes.PrestateProvider { - return vm.NewPrestateProvider(path, cannon.NewStateConverter()) + return cannon.NewPrestateProvider(path) }), newTraceAccessor: func( logger log.Logger, @@ -71,7 +71,7 @@ func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m c splitDepth faultTypes.Depth, prestateBlock uint64, poststateBlock uint64) (*trace.Accessor, error) { - provider := vmPrestateProvider.(*vm.PrestateProvider) + provider := vmPrestateProvider.(*cannon.CannonPrestateProvider) return outputs.NewOutputCannonTraceAccessor(logger, m, cfg.Cannon, serverExecutor, l2Client, prestateProvider, provider.PrestatePath(), rollupClient, dir, l1Head, splitDepth, prestateBlock, poststateBlock) }, } @@ -87,7 +87,7 @@ func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m cfg.AsteriscAbsolutePreState, filepath.Join(cfg.Datadir, "asterisc-prestates"), func(path string) faultTypes.PrestateProvider { - return vm.NewPrestateProvider(path, asterisc.NewStateConverter()) + return asterisc.NewPrestateProvider(path) }), newTraceAccessor: func( logger log.Logger, @@ -101,7 +101,7 @@ func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m splitDepth faultTypes.Depth, prestateBlock uint64, poststateBlock uint64) (*trace.Accessor, error) { - provider := vmPrestateProvider.(*vm.PrestateProvider) + provider := vmPrestateProvider.(*asterisc.AsteriscPreStateProvider) return outputs.NewOutputAsteriscTraceAccessor(logger, m, cfg.Asterisc, serverExecutor, l2Client, prestateProvider, provider.PrestatePath(), rollupClient, dir, l1Head, splitDepth, prestateBlock, poststateBlock) }, } diff --git a/op-challenger/game/fault/trace/asterisc/prestate.go b/op-challenger/game/fault/trace/asterisc/prestate.go new file mode 100644 index 000000000000..f65e4d9c901c --- /dev/null +++ b/op-challenger/game/fault/trace/asterisc/prestate.go @@ -0,0 +1,45 @@ +package asterisc + +import ( + "context" + "fmt" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum/go-ethereum/common" +) + +var _ types.PrestateProvider = (*AsteriscPreStateProvider)(nil) + +type AsteriscPreStateProvider struct { + prestate string + + prestateCommitment common.Hash +} + +func NewPrestateProvider(prestate string) *AsteriscPreStateProvider { + return &AsteriscPreStateProvider{prestate: prestate} +} + +func (p *AsteriscPreStateProvider) absolutePreState() (*VMState, error) { + state, err := parseState(p.prestate) + if err != nil { + return nil, fmt.Errorf("cannot load absolute pre-state: %w", err) + } + return state, nil +} + +func (p *AsteriscPreStateProvider) AbsolutePreStateCommitment(_ context.Context) (common.Hash, error) { + if p.prestateCommitment != (common.Hash{}) { + return p.prestateCommitment, nil + } + state, err := p.absolutePreState() + if err != nil { + return common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err) + } + p.prestateCommitment = state.StateHash + return state.StateHash, nil +} + +func (p *AsteriscPreStateProvider) PrestatePath() string { + return p.prestate +} diff --git a/op-challenger/game/fault/trace/asterisc/prestate_test.go b/op-challenger/game/fault/trace/asterisc/prestate_test.go new file mode 100644 index 000000000000..38bc6d360e7b --- /dev/null +++ b/op-challenger/game/fault/trace/asterisc/prestate_test.go @@ -0,0 +1,59 @@ +package asterisc + +import ( + "context" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +func newAsteriscPrestateProvider(dataDir string, prestate string) *AsteriscPreStateProvider { + return &AsteriscPreStateProvider{ + prestate: filepath.Join(dataDir, prestate), + } +} + +func TestAbsolutePreStateCommitment(t *testing.T) { + dataDir := t.TempDir() + + prestate := "state.json" + + t.Run("StateUnavailable", func(t *testing.T) { + provider := newAsteriscPrestateProvider("/dir/does/not/exist", prestate) + _, err := provider.AbsolutePreStateCommitment(context.Background()) + require.ErrorIs(t, err, os.ErrNotExist) + }) + + t.Run("InvalidStateFile", func(t *testing.T) { + setupPreState(t, dataDir, "invalid.json") + provider := newAsteriscPrestateProvider(dataDir, prestate) + _, err := provider.AbsolutePreStateCommitment(context.Background()) + require.ErrorContains(t, err, "invalid asterisc VM state") + }) + + t.Run("CacheAbsolutePreState", func(t *testing.T) { + setupPreState(t, dataDir, prestate) + provider := newAsteriscPrestateProvider(dataDir, prestate) + first, err := provider.AbsolutePreStateCommitment(context.Background()) + require.NoError(t, err) + + // Remove the prestate from disk + require.NoError(t, os.Remove(provider.prestate)) + + // Value should still be available from cache + cached, err := provider.AbsolutePreStateCommitment(context.Background()) + require.NoError(t, err) + require.Equal(t, first, cached) + }) +} + +func setupPreState(t *testing.T, dataDir string, filename string) { + srcDir := filepath.Join("test_data") + path := filepath.Join(srcDir, filename) + file, err := testData.ReadFile(path) + require.NoErrorf(t, err, "reading %v", path) + err = os.WriteFile(filepath.Join(dataDir, "state.json"), file, 0o644) + require.NoErrorf(t, err, "writing %v", path) +} diff --git a/op-challenger/game/fault/trace/asterisc/provider.go b/op-challenger/game/fault/trace/asterisc/provider.go index 4ee345f807f4..cad5e36b839e 100644 --- a/op-challenger/game/fault/trace/asterisc/provider.go +++ b/op-challenger/game/fault/trace/asterisc/provider.go @@ -27,7 +27,6 @@ type AsteriscTraceProvider struct { generator utils.ProofGenerator gameDepth types.Depth preimageLoader *utils.PreimageLoader - stateConverter vm.StateConverter types.PrestateProvider @@ -47,7 +46,6 @@ func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, vmCfg vm. return kvstore.NewFileKV(vm.PreimageDir(dir)) }), PrestateProvider: prestateProvider, - stateConverter: NewStateConverter(), } } @@ -122,23 +120,31 @@ func (p *AsteriscTraceProvider) loadProof(ctx context.Context, i uint64) (*utils file, err = ioutil.OpenDecompressed(path) if errors.Is(err, os.ErrNotExist) { // Expected proof wasn't generated, check if we reached the end of execution - proof, step, exited, err := p.stateConverter.ConvertStateToProof(filepath.Join(p.dir, vm.FinalState)) + state, err := p.finalState() if err != nil { return nil, err } - if exited && step <= i { - p.logger.Warn("Requested proof was after the program exited", "proof", i, "last", step) + if state.Exited && state.Step <= i { + p.logger.Warn("Requested proof was after the program exited", "proof", i, "last", state.Step) // The final instruction has already been applied to this state, so the last step we can execute // is one before its Step value. - p.lastStep = step - 1 + p.lastStep = state.Step - 1 // Extend the trace out to the full length using a no-op instruction that doesn't change any state // No execution is done, so no proof-data or oracle values are required. + proof := &utils.ProofData{ + ClaimValue: state.StateHash, + StateData: state.Witness, + ProofData: []byte{}, + OracleKey: nil, + OracleValue: nil, + OracleOffset: 0, + } if err := utils.WriteLastStep(p.dir, proof, p.lastStep); err != nil { p.logger.Warn("Failed to write last step to disk cache", "step", p.lastStep) } return proof, nil } else { - return nil, fmt.Errorf("expected proof not generated but final state was not exited, requested step %v, final state at step %v", i, step) + return nil, fmt.Errorf("expected proof not generated but final state was not exited, requested step %v, final state at step %v", i, state.Step) } } } @@ -154,6 +160,14 @@ func (p *AsteriscTraceProvider) loadProof(ctx context.Context, i uint64) (*utils return &proof, nil } +func (c *AsteriscTraceProvider) finalState() (*VMState, error) { + state, err := parseState(filepath.Join(c.dir, vm.FinalState)) + if err != nil { + return nil, fmt.Errorf("cannot read final state: %w", err) + } + return state, nil +} + // AsteriscTraceProviderForTest is a AsteriscTraceProvider that can find the step referencing the preimage read // Only to be used for testing type AsteriscTraceProviderForTest struct { @@ -180,14 +194,14 @@ func (p *AsteriscTraceProviderForTest) FindStep(ctx context.Context, start uint6 return 0, fmt.Errorf("generate asterisc trace (until preimage read): %w", err) } // Load the step from the state asterisc finished with - _, step, exited, err := p.stateConverter.ConvertStateToProof(filepath.Join(p.dir, vm.FinalState)) + state, err := p.finalState() if err != nil { return 0, fmt.Errorf("failed to load final state: %w", err) } // Check we didn't get to the end of the trace without finding the preimage read we were looking for - if exited { + if state.Exited { return 0, fmt.Errorf("preimage read not found: %w", io.EOF) } // The state is the post-state so the step we want to execute to read the preimage is step - 1. - return step - 1, nil + return state.Step - 1, nil } diff --git a/op-challenger/game/fault/trace/asterisc/provider_test.go b/op-challenger/game/fault/trace/asterisc/provider_test.go index d467bbb668dc..939a27decc30 100644 --- a/op-challenger/game/fault/trace/asterisc/provider_test.go +++ b/op-challenger/game/fault/trace/asterisc/provider_test.go @@ -221,12 +221,11 @@ func setupTestData(t *testing.T) (string, string) { func setupWithTestData(t *testing.T, dataDir string, prestate string) (*AsteriscTraceProvider, *stubGenerator) { generator := &stubGenerator{} return &AsteriscTraceProvider{ - logger: testlog.Logger(t, log.LevelInfo), - dir: dataDir, - generator: generator, - prestate: filepath.Join(dataDir, prestate), - gameDepth: 63, - stateConverter: &StateConverter{}, + logger: testlog.Logger(t, log.LevelInfo), + dir: dataDir, + generator: generator, + prestate: filepath.Join(dataDir, prestate), + gameDepth: 63, }, generator } diff --git a/op-challenger/game/fault/trace/asterisc/state_converter.go b/op-challenger/game/fault/trace/asterisc/state.go similarity index 73% rename from op-challenger/game/fault/trace/asterisc/state_converter.go rename to op-challenger/game/fault/trace/asterisc/state.go index 29c9f8b2ea50..e30ebf8702d8 100644 --- a/op-challenger/game/fault/trace/asterisc/state_converter.go +++ b/op-challenger/game/fault/trace/asterisc/state.go @@ -8,7 +8,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum-optimism/optimism/cannon/mipsevm" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" "github.com/ethereum-optimism/optimism/op-service/ioutil" ) @@ -75,27 +74,3 @@ func parseStateFromReader(in io.ReadCloser) (*VMState, error) { } return &state, nil } - -type StateConverter struct { -} - -func NewStateConverter() *StateConverter { - return &StateConverter{} -} - -func (c *StateConverter) ConvertStateToProof(statePath string) (*utils.ProofData, uint64, bool, error) { - state, err := parseState(statePath) - if err != nil { - return nil, 0, false, fmt.Errorf("cannot read final state: %w", err) - } - // Extend the trace out to the full length using a no-op instruction that doesn't change any state - // No execution is done, so no proof-data or oracle values are required. - return &utils.ProofData{ - ClaimValue: state.StateHash, - StateData: state.Witness, - ProofData: []byte{}, - OracleKey: nil, - OracleValue: nil, - OracleOffset: 0, - }, state.Step, state.Exited, nil -} diff --git a/op-challenger/game/fault/trace/cannon/prestate.go b/op-challenger/game/fault/trace/cannon/prestate.go new file mode 100644 index 000000000000..6fcb8f50f662 --- /dev/null +++ b/op-challenger/game/fault/trace/cannon/prestate.go @@ -0,0 +1,47 @@ +package cannon + +import ( + "context" + "fmt" + + "github.com/ethereum/go-ethereum/common" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" +) + +var _ types.PrestateProvider = (*CannonPrestateProvider)(nil) + +type CannonPrestateProvider struct { + prestate string + + prestateCommitment common.Hash +} + +func NewPrestateProvider(prestate string) *CannonPrestateProvider { + return &CannonPrestateProvider{prestate: prestate} +} + +func (p *CannonPrestateProvider) absolutePreState() ([]byte, common.Hash, error) { + state, err := parseState(p.prestate) + if err != nil { + return nil, common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err) + } + witness, hash := state.EncodeWitness() + return witness, hash, nil +} + +func (p *CannonPrestateProvider) AbsolutePreStateCommitment(_ context.Context) (common.Hash, error) { + if p.prestateCommitment != (common.Hash{}) { + return p.prestateCommitment, nil + } + _, hash, err := p.absolutePreState() + if err != nil { + return common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err) + } + p.prestateCommitment = hash + return hash, nil +} + +func (p *CannonPrestateProvider) PrestatePath() string { + return p.prestate +} diff --git a/op-challenger/game/fault/trace/cannon/prestate_test.go b/op-challenger/game/fault/trace/cannon/prestate_test.go new file mode 100644 index 000000000000..9566e9d0664c --- /dev/null +++ b/op-challenger/game/fault/trace/cannon/prestate_test.go @@ -0,0 +1,89 @@ +package cannon + +import ( + "context" + "os" + "path/filepath" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + "github.com/ethereum-optimism/optimism/cannon/mipsevm" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/memory" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" +) + +func newCannonPrestateProvider(dataDir string, prestate string) *CannonPrestateProvider { + return &CannonPrestateProvider{ + prestate: filepath.Join(dataDir, prestate), + } +} + +func TestAbsolutePreStateCommitment(t *testing.T) { + dataDir := t.TempDir() + + prestate := "state.json" + + t.Run("StateUnavailable", func(t *testing.T) { + provider := newCannonPrestateProvider("/dir/does/not/exist", prestate) + _, err := provider.AbsolutePreStateCommitment(context.Background()) + require.ErrorIs(t, err, os.ErrNotExist) + }) + + t.Run("InvalidStateFile", func(t *testing.T) { + setupPreState(t, dataDir, "invalid.json") + provider := newCannonPrestateProvider(dataDir, prestate) + _, err := provider.AbsolutePreStateCommitment(context.Background()) + require.ErrorContains(t, err, "invalid mipsevm state") + }) + + t.Run("ExpectedAbsolutePreState", func(t *testing.T) { + setupPreState(t, dataDir, "state.json") + provider := newCannonPrestateProvider(dataDir, prestate) + actual, err := provider.AbsolutePreStateCommitment(context.Background()) + require.NoError(t, err) + state := singlethreaded.State{ + Memory: memory.NewMemory(), + PreimageKey: common.HexToHash("cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"), + PreimageOffset: 0, + Cpu: mipsevm.CpuScalars{ + PC: 0, + NextPC: 1, + LO: 0, + HI: 0, + }, + Heap: 0, + ExitCode: 0, + Exited: false, + Step: 0, + Registers: [32]uint32{}, + } + _, expected := state.EncodeWitness() + require.Equal(t, expected, actual) + }) + + t.Run("CacheAbsolutePreState", func(t *testing.T) { + setupPreState(t, dataDir, prestate) + provider := newCannonPrestateProvider(dataDir, prestate) + first, err := provider.AbsolutePreStateCommitment(context.Background()) + require.NoError(t, err) + + // Remove the prestate from disk + require.NoError(t, os.Remove(provider.prestate)) + + // Value should still be available from cache + cached, err := provider.AbsolutePreStateCommitment(context.Background()) + require.NoError(t, err) + require.Equal(t, first, cached) + }) +} + +func setupPreState(t *testing.T, dataDir string, filename string) { + srcDir := filepath.Join("test_data") + path := filepath.Join(srcDir, filename) + file, err := testData.ReadFile(path) + require.NoErrorf(t, err, "reading %v", path) + err = os.WriteFile(filepath.Join(dataDir, "state.json"), file, 0o644) + require.NoErrorf(t, err, "writing %v", path) +} diff --git a/op-challenger/game/fault/trace/cannon/provider.go b/op-challenger/game/fault/trace/cannon/provider.go index fb85222d0064..fc7a71c1cda0 100644 --- a/op-challenger/game/fault/trace/cannon/provider.go +++ b/op-challenger/game/fault/trace/cannon/provider.go @@ -11,8 +11,10 @@ import ( "path/filepath" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" "github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" @@ -28,7 +30,6 @@ type CannonTraceProvider struct { generator utils.ProofGenerator gameDepth types.Depth preimageLoader *utils.PreimageLoader - stateConverter vm.StateConverter types.PrestateProvider @@ -48,7 +49,6 @@ func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, vmCfg vm. return kvstore.NewFileKV(vm.PreimageDir(dir)) }), PrestateProvider: prestateProvider, - stateConverter: &StateConverter{}, } } @@ -122,22 +122,33 @@ func (p *CannonTraceProvider) loadProof(ctx context.Context, i uint64) (*utils.P // Try opening the file again now and it should exist. file, err = ioutil.OpenDecompressed(path) if errors.Is(err, os.ErrNotExist) { - proof, stateStep, exited, err := p.stateConverter.ConvertStateToProof(filepath.Join(p.dir, vm.FinalState)) + // Expected proof wasn't generated, check if we reached the end of execution + state, err := p.finalState() if err != nil { - return nil, fmt.Errorf("cannot create proof from final state: %w", err) + return nil, err } - - if exited && stateStep <= i { - p.logger.Warn("Requested proof was after the program exited", "proof", i, "last", stateStep) + if state.Exited && state.Step <= i { + p.logger.Warn("Requested proof was after the program exited", "proof", i, "last", state.Step) // The final instruction has already been applied to this state, so the last step we can execute // is one before its Step value. - p.lastStep = stateStep - 1 + p.lastStep = state.Step - 1 + // Extend the trace out to the full length using a no-op instruction that doesn't change any state + // No execution is done, so no proof-data or oracle values are required. + witness, witnessHash := state.EncodeWitness() + proof := &utils.ProofData{ + ClaimValue: witnessHash, + StateData: hexutil.Bytes(witness), + ProofData: []byte{}, + OracleKey: nil, + OracleValue: nil, + OracleOffset: 0, + } if err := utils.WriteLastStep(p.dir, proof, p.lastStep); err != nil { p.logger.Warn("Failed to write last step to disk cache", "step", p.lastStep) } return proof, nil } else { - return nil, fmt.Errorf("expected proof not generated but final state was not exited, requested step %v, final state at step %v", i, stateStep) + return nil, fmt.Errorf("expected proof not generated but final state was not exited, requested step %v, final state at step %v", i, state.Step) } } } @@ -153,6 +164,14 @@ func (p *CannonTraceProvider) loadProof(ctx context.Context, i uint64) (*utils.P return &proof, nil } +func (c *CannonTraceProvider) finalState() (*singlethreaded.State, error) { + state, err := parseState(filepath.Join(c.dir, vm.FinalState)) + if err != nil { + return nil, fmt.Errorf("cannot read final state: %w", err) + } + return state, nil +} + // CannonTraceProviderForTest is a CannonTraceProvider that can find the step referencing the preimage read // Only to be used for testing type CannonTraceProviderForTest struct { @@ -179,14 +198,14 @@ func (p *CannonTraceProviderForTest) FindStep(ctx context.Context, start uint64, return 0, fmt.Errorf("generate cannon trace (until preimage read): %w", err) } // Load the step from the state cannon finished with - _, step, exited, err := p.stateConverter.ConvertStateToProof(filepath.Join(p.dir, vm.FinalState)) + state, err := p.finalState() if err != nil { return 0, fmt.Errorf("failed to load final state: %w", err) } // Check we didn't get to the end of the trace without finding the preimage read we were looking for - if exited { + if state.Exited { return 0, fmt.Errorf("preimage read not found: %w", io.EOF) } // The state is the post-state so the step we want to execute to read the preimage is step - 1. - return step - 1, nil + return state.Step - 1, nil } diff --git a/op-challenger/game/fault/trace/cannon/provider_test.go b/op-challenger/game/fault/trace/cannon/provider_test.go index c650bd6ef818..3343b581f1c1 100644 --- a/op-challenger/game/fault/trace/cannon/provider_test.go +++ b/op-challenger/game/fault/trace/cannon/provider_test.go @@ -239,12 +239,11 @@ func setupTestData(t *testing.T) (string, string) { func setupWithTestData(t *testing.T, dataDir string, prestate string) (*CannonTraceProvider, *stubGenerator) { generator := &stubGenerator{} return &CannonTraceProvider{ - logger: testlog.Logger(t, log.LevelInfo), - dir: dataDir, - generator: generator, - prestate: filepath.Join(dataDir, prestate), - gameDepth: 63, - stateConverter: &StateConverter{}, + logger: testlog.Logger(t, log.LevelInfo), + dir: dataDir, + generator: generator, + prestate: filepath.Join(dataDir, prestate), + gameDepth: 63, }, generator } diff --git a/op-challenger/game/fault/trace/cannon/state.go b/op-challenger/game/fault/trace/cannon/state.go new file mode 100644 index 000000000000..cf781c8bd428 --- /dev/null +++ b/op-challenger/game/fault/trace/cannon/state.go @@ -0,0 +1,27 @@ +package cannon + +import ( + "encoding/json" + "fmt" + "io" + + "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" + "github.com/ethereum-optimism/optimism/op-service/ioutil" +) + +func parseState(path string) (*singlethreaded.State, error) { + file, err := ioutil.OpenDecompressed(path) + if err != nil { + return nil, fmt.Errorf("cannot open state file (%v): %w", path, err) + } + return parseStateFromReader(file) +} + +func parseStateFromReader(in io.ReadCloser) (*singlethreaded.State, error) { + defer in.Close() + var state singlethreaded.State + if err := json.NewDecoder(in).Decode(&state); err != nil { + return nil, fmt.Errorf("invalid mipsevm state: %w", err) + } + return &state, nil +} diff --git a/op-challenger/game/fault/trace/cannon/state_converter.go b/op-challenger/game/fault/trace/cannon/state_converter.go deleted file mode 100644 index e11b0ee53caa..000000000000 --- a/op-challenger/game/fault/trace/cannon/state_converter.go +++ /dev/null @@ -1,53 +0,0 @@ -package cannon - -import ( - "encoding/json" - "fmt" - "io" - - "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" - "github.com/ethereum-optimism/optimism/op-service/ioutil" -) - -type StateConverter struct { -} - -func NewStateConverter() *StateConverter { - return &StateConverter{} -} - -func (c *StateConverter) ConvertStateToProof(statePath string) (*utils.ProofData, uint64, bool, error) { - state, err := parseState(statePath) - if err != nil { - return nil, 0, false, fmt.Errorf("cannot read final state: %w", err) - } - // Extend the trace out to the full length using a no-op instruction that doesn't change any state - // No execution is done, so no proof-data or oracle values are required. - witness, witnessHash := state.EncodeWitness() - return &utils.ProofData{ - ClaimValue: witnessHash, - StateData: witness, - ProofData: []byte{}, - OracleKey: nil, - OracleValue: nil, - OracleOffset: 0, - }, state.Step, state.Exited, nil -} - -func parseState(path string) (*singlethreaded.State, error) { - file, err := ioutil.OpenDecompressed(path) - if err != nil { - return nil, fmt.Errorf("cannot open state file (%v): %w", path, err) - } - return parseStateFromReader(file) -} - -func parseStateFromReader(in io.ReadCloser) (*singlethreaded.State, error) { - defer in.Close() - var state singlethreaded.State - if err := json.NewDecoder(in).Decode(&state); err != nil { - return nil, fmt.Errorf("invalid mipsevm state: %w", err) - } - return &state, nil -} diff --git a/op-challenger/game/fault/trace/vm/iface.go b/op-challenger/game/fault/trace/vm/iface.go deleted file mode 100644 index 188f19e0c8e2..000000000000 --- a/op-challenger/game/fault/trace/vm/iface.go +++ /dev/null @@ -1,9 +0,0 @@ -package vm - -import "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" - -type StateConverter interface { - // ConvertStateToProof reads the state snapshot at the specified path and converts it to ProofData. - // Returns the proof data, the VM step the state is from and whether or not the VM had exited. - ConvertStateToProof(statePath string) (*utils.ProofData, uint64, bool, error) -} diff --git a/op-challenger/game/fault/trace/vm/prestate.go b/op-challenger/game/fault/trace/vm/prestate.go deleted file mode 100644 index bbb4a9437d9a..000000000000 --- a/op-challenger/game/fault/trace/vm/prestate.go +++ /dev/null @@ -1,42 +0,0 @@ -package vm - -import ( - "context" - "fmt" - - "github.com/ethereum/go-ethereum/common" - - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" -) - -var _ types.PrestateProvider = (*PrestateProvider)(nil) - -type PrestateProvider struct { - prestate string - stateConverter StateConverter - - prestateCommitment common.Hash -} - -func NewPrestateProvider(prestate string, converter StateConverter) *PrestateProvider { - return &PrestateProvider{ - prestate: prestate, - stateConverter: converter, - } -} - -func (p *PrestateProvider) AbsolutePreStateCommitment(_ context.Context) (common.Hash, error) { - if p.prestateCommitment != (common.Hash{}) { - return p.prestateCommitment, nil - } - proof, _, _, err := p.stateConverter.ConvertStateToProof(p.prestate) - if err != nil { - return common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err) - } - p.prestateCommitment = proof.ClaimValue - return proof.ClaimValue, nil -} - -func (p *PrestateProvider) PrestatePath() string { - return p.prestate -} diff --git a/op-challenger/game/fault/trace/vm/prestate_test.go b/op-challenger/game/fault/trace/vm/prestate_test.go deleted file mode 100644 index 69498e323c59..000000000000 --- a/op-challenger/game/fault/trace/vm/prestate_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package vm - -import ( - "context" - "errors" - "path/filepath" - "testing" - - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/require" -) - -type stubConverter struct { - err error - hash common.Hash -} - -func (s *stubConverter) ConvertStateToProof(statePath string) (*utils.ProofData, uint64, bool, error) { - if s.err != nil { - return nil, 0, false, s.err - } - return &utils.ProofData{ - ClaimValue: s.hash, - }, 0, false, nil -} - -func newPrestateProvider(prestate common.Hash) *PrestateProvider { - return NewPrestateProvider("state.json", &stubConverter{hash: prestate}) -} - -func TestAbsolutePreStateCommitment(t *testing.T) { - prestate := common.Hash{0xaa, 0xbb} - - t.Run("StateUnavailable", func(t *testing.T) { - expectedErr := errors.New("kaboom") - provider := NewPrestateProvider("foo", &stubConverter{err: expectedErr}) - _, err := provider.AbsolutePreStateCommitment(context.Background()) - require.ErrorIs(t, err, expectedErr) - }) - - t.Run("ExpectedAbsolutePreState", func(t *testing.T) { - provider := newPrestateProvider(prestate) - actual, err := provider.AbsolutePreStateCommitment(context.Background()) - require.NoError(t, err) - require.Equal(t, prestate, actual) - }) - - t.Run("CacheAbsolutePreState", func(t *testing.T) { - converter := &stubConverter{hash: prestate} - provider := NewPrestateProvider(filepath.Join("state.json"), converter) - first, err := provider.AbsolutePreStateCommitment(context.Background()) - require.NoError(t, err) - - // Remove the prestate from disk - converter.err = errors.New("no soup for you") - - // Value should still be available from cache - cached, err := provider.AbsolutePreStateCommitment(context.Background()) - require.NoError(t, err) - require.Equal(t, first, cached) - }) -} diff --git a/op-challenger/runner/factory.go b/op-challenger/runner/factory.go index 59188210d8e5..dae0a3fce146 100644 --- a/op-challenger/runner/factory.go +++ b/op-challenger/runner/factory.go @@ -33,7 +33,7 @@ func createTraceProvider( if err != nil { return nil, err } - prestateProvider := vm.NewPrestateProvider(prestate, cannon.NewStateConverter()) + prestateProvider := cannon.NewPrestateProvider(prestate) return cannon.NewTraceProvider(logger, m, cfg.Cannon, vmConfig, prestateProvider, prestate, localInputs, dir, 42), nil case types.TraceTypeAsterisc: vmConfig := vm.NewOpProgramServerExecutor() @@ -41,7 +41,7 @@ func createTraceProvider( if err != nil { return nil, err } - prestateProvider := vm.NewPrestateProvider(prestate, asterisc.NewStateConverter()) + prestateProvider := asterisc.NewPrestateProvider(prestate) return asterisc.NewTraceProvider(logger, m, cfg.Asterisc, vmConfig, prestateProvider, prestate, localInputs, dir, 42), nil case types.TraceTypeAsteriscKona: vmConfig := vm.NewKonaServerExecutor() @@ -49,7 +49,7 @@ func createTraceProvider( if err != nil { return nil, err } - prestateProvider := vm.NewPrestateProvider(prestate, asterisc.NewStateConverter()) + prestateProvider := asterisc.NewPrestateProvider(prestate) return asterisc.NewTraceProvider(logger, m, cfg.Asterisc, vmConfig, prestateProvider, prestate, localInputs, dir, 42), nil } return nil, errors.New("invalid trace type") From c2d091113513c421bc22fc4117b1cd7680992164 Mon Sep 17 00:00:00 2001 From: Inphi Date: Wed, 4 Sep 2024 20:36:27 -0400 Subject: [PATCH 037/264] cannon: Run expensive tests in parallel (#11739) --- cannon/mipsevm/tests/evm_common_test.go | 9 +++++++++ cannon/mipsevm/tests/evm_multithreaded_test.go | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/cannon/mipsevm/tests/evm_common_test.go b/cannon/mipsevm/tests/evm_common_test.go index 063c63c83c6c..437501140f25 100644 --- a/cannon/mipsevm/tests/evm_common_test.go +++ b/cannon/mipsevm/tests/evm_common_test.go @@ -454,11 +454,14 @@ func TestEVMFault(t *testing.T) { } func TestHelloEVM(t *testing.T) { + t.Parallel() var tracer *tracing.Hooks // no-tracer by default, but see test_util.MarkdownTracer versions := GetMipsVersionTestCases(t) for _, v := range versions { + v := v t.Run(v.Name, func(t *testing.T) { + t.Parallel() evm := testutil.NewMIPSEVM(v.Contracts) evm.SetTracer(tracer) testutil.LogStepFailureAtCleanup(t, evm) @@ -502,11 +505,14 @@ func TestHelloEVM(t *testing.T) { } func TestClaimEVM(t *testing.T) { + t.Parallel() var tracer *tracing.Hooks // no-tracer by default, but see test_util.MarkdownTracer versions := GetMipsVersionTestCases(t) for _, v := range versions { + v := v t.Run(v.Name, func(t *testing.T) { + t.Parallel() evm := testutil.NewMIPSEVM(v.Contracts) evm.SetTracer(tracer) testutil.LogStepFailureAtCleanup(t, evm) @@ -549,11 +555,14 @@ func TestClaimEVM(t *testing.T) { } func TestEntryEVM(t *testing.T) { + t.Parallel() var tracer *tracing.Hooks // no-tracer by default, but see test_util.MarkdownTracer versions := GetMipsVersionTestCases(t) for _, v := range versions { + v := v t.Run(v.Name, func(t *testing.T) { + t.Parallel() evm := testutil.NewMIPSEVM(v.Contracts) evm.SetTracer(tracer) testutil.LogStepFailureAtCleanup(t, evm) diff --git a/cannon/mipsevm/tests/evm_multithreaded_test.go b/cannon/mipsevm/tests/evm_multithreaded_test.go index ebd5dc904e28..76f9b9462dc2 100644 --- a/cannon/mipsevm/tests/evm_multithreaded_test.go +++ b/cannon/mipsevm/tests/evm_multithreaded_test.go @@ -623,6 +623,7 @@ func TestEVM_NoopSyscall(t *testing.T) { } func TestEVM_UnsupportedSyscall(t *testing.T) { + t.Parallel() var tracer *tracing.Hooks var NoopSyscallNums = maps.Values(NoopSyscalls) @@ -638,7 +639,10 @@ func TestEVM_UnsupportedSyscall(t *testing.T) { for i, syscallNum := range unsupportedSyscalls { testName := fmt.Sprintf("Unsupported syscallNum %v", syscallNum) + i := i + syscallNum := syscallNum t.Run(testName, func(t *testing.T) { + t.Parallel() goVm, state, contracts := setup(t, i*3434) // Setup basic getThreadId syscall instruction state.Memory.SetMemory(state.GetPC(), syscallInsn) From 224c5fd65cb4e8204258291e74263c1e70466176 Mon Sep 17 00:00:00 2001 From: protolambda Date: Wed, 4 Sep 2024 19:07:40 -0600 Subject: [PATCH 038/264] op-node: sequencer should clear inconsistent asyncGossip buffer on sequencer-start (#11724) * op-node: sequencer should clear inconsistent asyncGossip buffer on sequencer-start * op-node: test async-gossip clearing * Update op-node/rollup/sequencing/sequencer.go Co-authored-by: Adrian Sutton --------- Co-authored-by: Adrian Sutton --- op-node/rollup/sequencing/sequencer.go | 20 ++ op-node/rollup/sequencing/sequencer_test.go | 196 ++++++++++++++++++++ 2 files changed, 216 insertions(+) diff --git a/op-node/rollup/sequencing/sequencer.go b/op-node/rollup/sequencing/sequencer.go index 70a0164249b3..16fbca759513 100644 --- a/op-node/rollup/sequencing/sequencer.go +++ b/op-node/rollup/sequencing/sequencer.go @@ -345,6 +345,8 @@ func (d *Sequencer) onSequencerAction(x SequencerActionEvent) { d.asyncGossip.Clear() // bad payload return } + d.log.Info("Resuming sequencing with previously async-gossip confirmed payload", + "payload", payload.ExecutionPayload.ID()) // Payload is known, we must have resumed sequencer-actions after a temporary error, // meaning that we have seen BuildSealedEvent already. // We can retry processing to make it canonical. @@ -616,9 +618,27 @@ func (d *Sequencer) Init(ctx context.Context, active bool) error { // forceStart skips all the checks, and just starts the sequencer func (d *Sequencer) forceStart() error { + if d.latestHead == (eth.L2BlockRef{}) { + // This happens if sequencing is activated on op-node startup. + // The op-conductor check and choice of sequencing with this pre-state already happened before op-node startup. + d.log.Info("Starting sequencing, without known pre-state") + d.asyncGossip.Clear() // if we are starting from an unknown pre-state, just clear gossip out of caution. + } else { + // This happens when we start sequencing on an already-running node. + d.log.Info("Starting sequencing on top of known pre-state", "head", d.latestHead) + if payload := d.asyncGossip.Get(); payload != nil && + payload.ExecutionPayload.BlockHash != d.latestHead.Hash { + d.log.Warn("Cleared old block from async-gossip buffer, sequencing pre-state is different", + "buffered", payload.ExecutionPayload.ID(), "prestate", d.latestHead) + d.asyncGossip.Clear() + } + } + if err := d.listener.SequencerStarted(); err != nil { return fmt.Errorf("failed to notify sequencer-state listener of start: %w", err) } + // clear the building state; interrupting any existing sequencing job (there should never be one) + d.latest = BuildingState{} d.nextActionOK = true d.nextAction = d.timeNow() d.active.Store(true) diff --git a/op-node/rollup/sequencing/sequencer_test.go b/op-node/rollup/sequencing/sequencer_test.go index 234049096a83..3341cf0bcb08 100644 --- a/op-node/rollup/sequencing/sequencer_test.go +++ b/op-node/rollup/sequencing/sequencer_test.go @@ -210,6 +210,202 @@ func TestSequencer_StartStop(t *testing.T) { require.NoError(t, err) } +// TestSequencer_StaleBuild stops the sequencer after block-building, +// but before processing the block locally, +// and then continues it again, to check if the async-gossip gets cleared, +// instead of trying to re-insert the block. +func TestSequencer_StaleBuild(t *testing.T) { + logger := testlog.Logger(t, log.LevelError) + seq, deps := createSequencer(logger) + + testClock := clock.NewSimpleClock() + seq.timeNow = testClock.Now + testClock.SetTime(30000) + + emitter := &testutils.MockEmitter{} + seq.AttachEmitter(emitter) + deps.conductor.leader = true + + emitter.ExpectOnce(engine.ForkchoiceRequestEvent{}) + require.NoError(t, seq.Init(context.Background(), false)) + emitter.AssertExpectations(t) + require.False(t, deps.conductor.closed, "conductor is ready") + require.True(t, deps.asyncGossip.started, "async gossip is always started on initialization") + require.False(t, deps.seqState.active, "sequencer not active yet") + + head := eth.L2BlockRef{ + Hash: common.Hash{0x22}, + Number: 100, + L1Origin: eth.BlockID{ + Hash: common.Hash{0x11, 0xa}, + Number: 1000, + }, + Time: uint64(testClock.Now().Unix()), + } + seq.OnEvent(engine.ForkchoiceUpdateEvent{UnsafeL2Head: head}) + + require.NoError(t, seq.Start(context.Background(), head.Hash)) + require.True(t, seq.Active()) + require.True(t, deps.seqState.active, "sequencer signaled it is active") + + // sequencer is active now, wants to build. + _, ok := seq.NextAction() + require.True(t, ok) + + // pretend we progress to the next L1 origin, catching up with the L2 time + l1Origin := eth.L1BlockRef{ + Hash: common.Hash{0x11, 0xb}, + ParentHash: head.L1Origin.Hash, + Number: head.L1Origin.Number + 1, + Time: head.Time + 2, + } + deps.l1OriginSelector.l1OriginFn = func(l2Head eth.L2BlockRef) (eth.L1BlockRef, error) { + return l1Origin, nil + } + var sentAttributes *derive.AttributesWithParent + emitter.ExpectOnceRun(func(ev event.Event) { + x, ok := ev.(engine.BuildStartEvent) + require.True(t, ok) + require.Equal(t, head, x.Attributes.Parent) + require.Equal(t, head.Time+deps.cfg.BlockTime, uint64(x.Attributes.Attributes.Timestamp)) + require.Equal(t, eth.L1BlockRef{}, x.Attributes.DerivedFrom) + sentAttributes = x.Attributes + }) + seq.OnEvent(SequencerActionEvent{}) + emitter.AssertExpectations(t) + + // Now report the block was started + startedTime := time.Unix(int64(head.Time), 0).Add(time.Millisecond * 150) + testClock.Set(startedTime) + payloadInfo := eth.PayloadInfo{ + ID: eth.PayloadID{0x42}, + Timestamp: head.Time + deps.cfg.BlockTime, + } + seq.OnEvent(engine.BuildStartedEvent{ + Info: payloadInfo, + BuildStarted: startedTime, + Parent: head, + IsLastInSpan: false, + DerivedFrom: eth.L1BlockRef{}, + }) + + _, ok = seq.NextAction() + require.True(t, ok, "must be ready to seal the block now") + + emitter.ExpectOnce(engine.BuildSealEvent{ + Info: payloadInfo, + BuildStarted: startedTime, + IsLastInSpan: false, + DerivedFrom: eth.L1BlockRef{}, + }) + seq.OnEvent(SequencerActionEvent{}) + emitter.AssertExpectations(t) + + _, ok = seq.NextAction() + require.False(t, ok, "cannot act until sealing completes/fails") + + payloadEnvelope := ð.ExecutionPayloadEnvelope{ + ParentBeaconBlockRoot: sentAttributes.Attributes.ParentBeaconBlockRoot, + ExecutionPayload: ð.ExecutionPayload{ + ParentHash: head.Hash, + FeeRecipient: sentAttributes.Attributes.SuggestedFeeRecipient, + BlockNumber: eth.Uint64Quantity(sentAttributes.Parent.Number + 1), + BlockHash: common.Hash{0x12, 0x34}, + Timestamp: sentAttributes.Attributes.Timestamp, + Transactions: sentAttributes.Attributes.Transactions, + // Not all attributes matter to sequencer. We can leave these nil. + }, + } + payloadRef := eth.L2BlockRef{ + Hash: payloadEnvelope.ExecutionPayload.BlockHash, + Number: uint64(payloadEnvelope.ExecutionPayload.BlockNumber), + ParentHash: payloadEnvelope.ExecutionPayload.ParentHash, + Time: uint64(payloadEnvelope.ExecutionPayload.Timestamp), + L1Origin: l1Origin.ID(), + SequenceNumber: 0, + } + emitter.ExpectOnce(engine.PayloadProcessEvent{ + IsLastInSpan: false, + DerivedFrom: eth.L1BlockRef{}, + Envelope: payloadEnvelope, + Ref: payloadRef, + }) + // And report back the sealing result to the engine + seq.OnEvent(engine.BuildSealedEvent{ + IsLastInSpan: false, + DerivedFrom: eth.L1BlockRef{}, + Info: payloadInfo, + Envelope: payloadEnvelope, + Ref: payloadRef, + }) + // The sequencer should start processing the payload + emitter.AssertExpectations(t) + // But also optimistically give it to the conductor and the async gossip + require.Equal(t, payloadEnvelope, deps.conductor.committed, "must commit to conductor") + require.Equal(t, payloadEnvelope, deps.asyncGossip.payload, "must send to async gossip") + _, ok = seq.NextAction() + require.False(t, ok, "optimistically published, but not ready to sequence next, until local processing completes") + + // Now we stop the block building, + // before successful local processing of the committed block! + stopHead, err := seq.Stop(context.Background()) + require.NoError(t, err) + require.Equal(t, head.Hash, stopHead, "sequencer should not have accepted any new block yet") + require.False(t, deps.seqState.active, "sequencer signaled it is no longer active") + + // Async-gossip will try to publish this committed block + require.NotNil(t, deps.asyncGossip.payload, "still holding on to async-gossip block") + + // Now let's say another sequencer built a bunch of blocks, + // can we continue from there? We'll have to wipe the old in-flight block, + // if we continue on top of a chain that had it already included a while ago. + + // Signal the new chain we are building on + testClock.Set(testClock.Now().Add(time.Second * 100 * 2)) + + newL1Origin := eth.L1BlockRef{ + Hash: common.Hash{0x11, 0x11, 0x44}, + ParentHash: head.L1Origin.Hash, + Number: head.L1Origin.Number + 50, + Time: uint64(testClock.Now().Unix()), + } + newHead := eth.L2BlockRef{ + Hash: common.Hash{0x44}, + Number: head.Number + 100, + L1Origin: newL1Origin.ID(), + Time: uint64(testClock.Now().Unix()), + } + seq.OnEvent(engine.ForkchoiceUpdateEvent{UnsafeL2Head: newHead}) + + // Regression check: async-gossip is cleared upon sequencer un-pause. + // We could clear it earlier. But absolutely have to clear it upon Start(), + // to not continue from this older point. + require.NotNil(t, deps.asyncGossip.payload, "async-gossip still not cleared") + + // start sequencing on top of the new chain + require.NoError(t, seq.Start(context.Background(), newHead.Hash), "must continue from new block") + + // regression check: no stale async gossip is continued + require.Nil(t, deps.asyncGossip.payload, "async gossip should be cleared on Start") + + // Start building the block with the new L1 origin + deps.l1OriginSelector.l1OriginFn = func(l2Head eth.L2BlockRef) (eth.L1BlockRef, error) { + return newL1Origin, nil + } + // Sequencer action, assert we build on top of something new, + // and don't try to seal what was previously. + _, ok = seq.NextAction() + require.True(t, ok, "ready to sequence again") + // start, not seal, when continuing to sequence. + emitter.ExpectOnceRun(func(ev event.Event) { + buildEv, ok := ev.(engine.BuildStartEvent) + require.True(t, ok) + require.Equal(t, newHead, buildEv.Attributes.Parent, "build on the new L2 head") + }) + seq.OnEvent(SequencerActionEvent{}) + emitter.AssertExpectations(t) +} + func TestSequencerBuild(t *testing.T) { logger := testlog.Logger(t, log.LevelError) seq, deps := createSequencer(logger) From df4d723fa5eba7d2dbb287c0151fff6c17a23fca Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Thu, 5 Sep 2024 11:18:10 +1000 Subject: [PATCH 039/264] Reapply "challenger: Introduce StateConverter to abstract loading VM states" (#11752) With fix to set a state converter when creating trace providers for test. --- op-challenger/game/fault/register_task.go | 8 +- .../game/fault/trace/asterisc/prestate.go | 45 ---------- .../fault/trace/asterisc/prestate_test.go | 59 ------------ .../game/fault/trace/asterisc/provider.go | 35 +++----- .../fault/trace/asterisc/provider_test.go | 11 +-- .../asterisc/{state.go => state_converter.go} | 25 ++++++ .../game/fault/trace/cannon/prestate.go | 47 ---------- .../game/fault/trace/cannon/prestate_test.go | 89 ------------------- .../game/fault/trace/cannon/provider.go | 44 +++------ .../game/fault/trace/cannon/provider_test.go | 11 +-- .../game/fault/trace/cannon/state.go | 27 ------ .../fault/trace/cannon/state_converter.go | 53 +++++++++++ op-challenger/game/fault/trace/vm/iface.go | 9 ++ op-challenger/game/fault/trace/vm/prestate.go | 42 +++++++++ .../game/fault/trace/vm/prestate_test.go | 63 +++++++++++++ op-challenger/runner/factory.go | 6 +- 16 files changed, 235 insertions(+), 339 deletions(-) delete mode 100644 op-challenger/game/fault/trace/asterisc/prestate.go delete mode 100644 op-challenger/game/fault/trace/asterisc/prestate_test.go rename op-challenger/game/fault/trace/asterisc/{state.go => state_converter.go} (73%) delete mode 100644 op-challenger/game/fault/trace/cannon/prestate.go delete mode 100644 op-challenger/game/fault/trace/cannon/prestate_test.go delete mode 100644 op-challenger/game/fault/trace/cannon/state.go create mode 100644 op-challenger/game/fault/trace/cannon/state_converter.go create mode 100644 op-challenger/game/fault/trace/vm/iface.go create mode 100644 op-challenger/game/fault/trace/vm/prestate.go create mode 100644 op-challenger/game/fault/trace/vm/prestate_test.go diff --git a/op-challenger/game/fault/register_task.go b/op-challenger/game/fault/register_task.go index b9b2db6b4951..40acfecce22b 100644 --- a/op-challenger/game/fault/register_task.go +++ b/op-challenger/game/fault/register_task.go @@ -57,7 +57,7 @@ func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m c cfg.CannonAbsolutePreState, filepath.Join(cfg.Datadir, "cannon-prestates"), func(path string) faultTypes.PrestateProvider { - return cannon.NewPrestateProvider(path) + return vm.NewPrestateProvider(path, cannon.NewStateConverter()) }), newTraceAccessor: func( logger log.Logger, @@ -71,7 +71,7 @@ func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m c splitDepth faultTypes.Depth, prestateBlock uint64, poststateBlock uint64) (*trace.Accessor, error) { - provider := vmPrestateProvider.(*cannon.CannonPrestateProvider) + provider := vmPrestateProvider.(*vm.PrestateProvider) return outputs.NewOutputCannonTraceAccessor(logger, m, cfg.Cannon, serverExecutor, l2Client, prestateProvider, provider.PrestatePath(), rollupClient, dir, l1Head, splitDepth, prestateBlock, poststateBlock) }, } @@ -87,7 +87,7 @@ func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m cfg.AsteriscAbsolutePreState, filepath.Join(cfg.Datadir, "asterisc-prestates"), func(path string) faultTypes.PrestateProvider { - return asterisc.NewPrestateProvider(path) + return vm.NewPrestateProvider(path, asterisc.NewStateConverter()) }), newTraceAccessor: func( logger log.Logger, @@ -101,7 +101,7 @@ func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m splitDepth faultTypes.Depth, prestateBlock uint64, poststateBlock uint64) (*trace.Accessor, error) { - provider := vmPrestateProvider.(*asterisc.AsteriscPreStateProvider) + provider := vmPrestateProvider.(*vm.PrestateProvider) return outputs.NewOutputAsteriscTraceAccessor(logger, m, cfg.Asterisc, serverExecutor, l2Client, prestateProvider, provider.PrestatePath(), rollupClient, dir, l1Head, splitDepth, prestateBlock, poststateBlock) }, } diff --git a/op-challenger/game/fault/trace/asterisc/prestate.go b/op-challenger/game/fault/trace/asterisc/prestate.go deleted file mode 100644 index f65e4d9c901c..000000000000 --- a/op-challenger/game/fault/trace/asterisc/prestate.go +++ /dev/null @@ -1,45 +0,0 @@ -package asterisc - -import ( - "context" - "fmt" - - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - "github.com/ethereum/go-ethereum/common" -) - -var _ types.PrestateProvider = (*AsteriscPreStateProvider)(nil) - -type AsteriscPreStateProvider struct { - prestate string - - prestateCommitment common.Hash -} - -func NewPrestateProvider(prestate string) *AsteriscPreStateProvider { - return &AsteriscPreStateProvider{prestate: prestate} -} - -func (p *AsteriscPreStateProvider) absolutePreState() (*VMState, error) { - state, err := parseState(p.prestate) - if err != nil { - return nil, fmt.Errorf("cannot load absolute pre-state: %w", err) - } - return state, nil -} - -func (p *AsteriscPreStateProvider) AbsolutePreStateCommitment(_ context.Context) (common.Hash, error) { - if p.prestateCommitment != (common.Hash{}) { - return p.prestateCommitment, nil - } - state, err := p.absolutePreState() - if err != nil { - return common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err) - } - p.prestateCommitment = state.StateHash - return state.StateHash, nil -} - -func (p *AsteriscPreStateProvider) PrestatePath() string { - return p.prestate -} diff --git a/op-challenger/game/fault/trace/asterisc/prestate_test.go b/op-challenger/game/fault/trace/asterisc/prestate_test.go deleted file mode 100644 index 38bc6d360e7b..000000000000 --- a/op-challenger/game/fault/trace/asterisc/prestate_test.go +++ /dev/null @@ -1,59 +0,0 @@ -package asterisc - -import ( - "context" - "os" - "path/filepath" - "testing" - - "github.com/stretchr/testify/require" -) - -func newAsteriscPrestateProvider(dataDir string, prestate string) *AsteriscPreStateProvider { - return &AsteriscPreStateProvider{ - prestate: filepath.Join(dataDir, prestate), - } -} - -func TestAbsolutePreStateCommitment(t *testing.T) { - dataDir := t.TempDir() - - prestate := "state.json" - - t.Run("StateUnavailable", func(t *testing.T) { - provider := newAsteriscPrestateProvider("/dir/does/not/exist", prestate) - _, err := provider.AbsolutePreStateCommitment(context.Background()) - require.ErrorIs(t, err, os.ErrNotExist) - }) - - t.Run("InvalidStateFile", func(t *testing.T) { - setupPreState(t, dataDir, "invalid.json") - provider := newAsteriscPrestateProvider(dataDir, prestate) - _, err := provider.AbsolutePreStateCommitment(context.Background()) - require.ErrorContains(t, err, "invalid asterisc VM state") - }) - - t.Run("CacheAbsolutePreState", func(t *testing.T) { - setupPreState(t, dataDir, prestate) - provider := newAsteriscPrestateProvider(dataDir, prestate) - first, err := provider.AbsolutePreStateCommitment(context.Background()) - require.NoError(t, err) - - // Remove the prestate from disk - require.NoError(t, os.Remove(provider.prestate)) - - // Value should still be available from cache - cached, err := provider.AbsolutePreStateCommitment(context.Background()) - require.NoError(t, err) - require.Equal(t, first, cached) - }) -} - -func setupPreState(t *testing.T, dataDir string, filename string) { - srcDir := filepath.Join("test_data") - path := filepath.Join(srcDir, filename) - file, err := testData.ReadFile(path) - require.NoErrorf(t, err, "reading %v", path) - err = os.WriteFile(filepath.Join(dataDir, "state.json"), file, 0o644) - require.NoErrorf(t, err, "writing %v", path) -} diff --git a/op-challenger/game/fault/trace/asterisc/provider.go b/op-challenger/game/fault/trace/asterisc/provider.go index cad5e36b839e..78ae250290b6 100644 --- a/op-challenger/game/fault/trace/asterisc/provider.go +++ b/op-challenger/game/fault/trace/asterisc/provider.go @@ -27,6 +27,7 @@ type AsteriscTraceProvider struct { generator utils.ProofGenerator gameDepth types.Depth preimageLoader *utils.PreimageLoader + stateConverter vm.StateConverter types.PrestateProvider @@ -46,6 +47,7 @@ func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, vmCfg vm. return kvstore.NewFileKV(vm.PreimageDir(dir)) }), PrestateProvider: prestateProvider, + stateConverter: NewStateConverter(), } } @@ -120,31 +122,23 @@ func (p *AsteriscTraceProvider) loadProof(ctx context.Context, i uint64) (*utils file, err = ioutil.OpenDecompressed(path) if errors.Is(err, os.ErrNotExist) { // Expected proof wasn't generated, check if we reached the end of execution - state, err := p.finalState() + proof, step, exited, err := p.stateConverter.ConvertStateToProof(filepath.Join(p.dir, vm.FinalState)) if err != nil { return nil, err } - if state.Exited && state.Step <= i { - p.logger.Warn("Requested proof was after the program exited", "proof", i, "last", state.Step) + if exited && step <= i { + p.logger.Warn("Requested proof was after the program exited", "proof", i, "last", step) // The final instruction has already been applied to this state, so the last step we can execute // is one before its Step value. - p.lastStep = state.Step - 1 + p.lastStep = step - 1 // Extend the trace out to the full length using a no-op instruction that doesn't change any state // No execution is done, so no proof-data or oracle values are required. - proof := &utils.ProofData{ - ClaimValue: state.StateHash, - StateData: state.Witness, - ProofData: []byte{}, - OracleKey: nil, - OracleValue: nil, - OracleOffset: 0, - } if err := utils.WriteLastStep(p.dir, proof, p.lastStep); err != nil { p.logger.Warn("Failed to write last step to disk cache", "step", p.lastStep) } return proof, nil } else { - return nil, fmt.Errorf("expected proof not generated but final state was not exited, requested step %v, final state at step %v", i, state.Step) + return nil, fmt.Errorf("expected proof not generated but final state was not exited, requested step %v, final state at step %v", i, step) } } } @@ -160,14 +154,6 @@ func (p *AsteriscTraceProvider) loadProof(ctx context.Context, i uint64) (*utils return &proof, nil } -func (c *AsteriscTraceProvider) finalState() (*VMState, error) { - state, err := parseState(filepath.Join(c.dir, vm.FinalState)) - if err != nil { - return nil, fmt.Errorf("cannot read final state: %w", err) - } - return state, nil -} - // AsteriscTraceProviderForTest is a AsteriscTraceProvider that can find the step referencing the preimage read // Only to be used for testing type AsteriscTraceProviderForTest struct { @@ -184,6 +170,7 @@ func NewTraceProviderForTest(logger log.Logger, m vm.Metricer, cfg *config.Confi preimageLoader: utils.NewPreimageLoader(func() utils.PreimageSource { return kvstore.NewFileKV(vm.PreimageDir(dir)) }), + stateConverter: NewStateConverter(), } return &AsteriscTraceProviderForTest{p} } @@ -194,14 +181,14 @@ func (p *AsteriscTraceProviderForTest) FindStep(ctx context.Context, start uint6 return 0, fmt.Errorf("generate asterisc trace (until preimage read): %w", err) } // Load the step from the state asterisc finished with - state, err := p.finalState() + _, step, exited, err := p.stateConverter.ConvertStateToProof(filepath.Join(p.dir, vm.FinalState)) if err != nil { return 0, fmt.Errorf("failed to load final state: %w", err) } // Check we didn't get to the end of the trace without finding the preimage read we were looking for - if state.Exited { + if exited { return 0, fmt.Errorf("preimage read not found: %w", io.EOF) } // The state is the post-state so the step we want to execute to read the preimage is step - 1. - return state.Step - 1, nil + return step - 1, nil } diff --git a/op-challenger/game/fault/trace/asterisc/provider_test.go b/op-challenger/game/fault/trace/asterisc/provider_test.go index 939a27decc30..d467bbb668dc 100644 --- a/op-challenger/game/fault/trace/asterisc/provider_test.go +++ b/op-challenger/game/fault/trace/asterisc/provider_test.go @@ -221,11 +221,12 @@ func setupTestData(t *testing.T) (string, string) { func setupWithTestData(t *testing.T, dataDir string, prestate string) (*AsteriscTraceProvider, *stubGenerator) { generator := &stubGenerator{} return &AsteriscTraceProvider{ - logger: testlog.Logger(t, log.LevelInfo), - dir: dataDir, - generator: generator, - prestate: filepath.Join(dataDir, prestate), - gameDepth: 63, + logger: testlog.Logger(t, log.LevelInfo), + dir: dataDir, + generator: generator, + prestate: filepath.Join(dataDir, prestate), + gameDepth: 63, + stateConverter: &StateConverter{}, }, generator } diff --git a/op-challenger/game/fault/trace/asterisc/state.go b/op-challenger/game/fault/trace/asterisc/state_converter.go similarity index 73% rename from op-challenger/game/fault/trace/asterisc/state.go rename to op-challenger/game/fault/trace/asterisc/state_converter.go index e30ebf8702d8..29c9f8b2ea50 100644 --- a/op-challenger/game/fault/trace/asterisc/state.go +++ b/op-challenger/game/fault/trace/asterisc/state_converter.go @@ -8,6 +8,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum-optimism/optimism/cannon/mipsevm" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" "github.com/ethereum-optimism/optimism/op-service/ioutil" ) @@ -74,3 +75,27 @@ func parseStateFromReader(in io.ReadCloser) (*VMState, error) { } return &state, nil } + +type StateConverter struct { +} + +func NewStateConverter() *StateConverter { + return &StateConverter{} +} + +func (c *StateConverter) ConvertStateToProof(statePath string) (*utils.ProofData, uint64, bool, error) { + state, err := parseState(statePath) + if err != nil { + return nil, 0, false, fmt.Errorf("cannot read final state: %w", err) + } + // Extend the trace out to the full length using a no-op instruction that doesn't change any state + // No execution is done, so no proof-data or oracle values are required. + return &utils.ProofData{ + ClaimValue: state.StateHash, + StateData: state.Witness, + ProofData: []byte{}, + OracleKey: nil, + OracleValue: nil, + OracleOffset: 0, + }, state.Step, state.Exited, nil +} diff --git a/op-challenger/game/fault/trace/cannon/prestate.go b/op-challenger/game/fault/trace/cannon/prestate.go deleted file mode 100644 index 6fcb8f50f662..000000000000 --- a/op-challenger/game/fault/trace/cannon/prestate.go +++ /dev/null @@ -1,47 +0,0 @@ -package cannon - -import ( - "context" - "fmt" - - "github.com/ethereum/go-ethereum/common" - - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" -) - -var _ types.PrestateProvider = (*CannonPrestateProvider)(nil) - -type CannonPrestateProvider struct { - prestate string - - prestateCommitment common.Hash -} - -func NewPrestateProvider(prestate string) *CannonPrestateProvider { - return &CannonPrestateProvider{prestate: prestate} -} - -func (p *CannonPrestateProvider) absolutePreState() ([]byte, common.Hash, error) { - state, err := parseState(p.prestate) - if err != nil { - return nil, common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err) - } - witness, hash := state.EncodeWitness() - return witness, hash, nil -} - -func (p *CannonPrestateProvider) AbsolutePreStateCommitment(_ context.Context) (common.Hash, error) { - if p.prestateCommitment != (common.Hash{}) { - return p.prestateCommitment, nil - } - _, hash, err := p.absolutePreState() - if err != nil { - return common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err) - } - p.prestateCommitment = hash - return hash, nil -} - -func (p *CannonPrestateProvider) PrestatePath() string { - return p.prestate -} diff --git a/op-challenger/game/fault/trace/cannon/prestate_test.go b/op-challenger/game/fault/trace/cannon/prestate_test.go deleted file mode 100644 index 9566e9d0664c..000000000000 --- a/op-challenger/game/fault/trace/cannon/prestate_test.go +++ /dev/null @@ -1,89 +0,0 @@ -package cannon - -import ( - "context" - "os" - "path/filepath" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/require" - - "github.com/ethereum-optimism/optimism/cannon/mipsevm" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/memory" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" -) - -func newCannonPrestateProvider(dataDir string, prestate string) *CannonPrestateProvider { - return &CannonPrestateProvider{ - prestate: filepath.Join(dataDir, prestate), - } -} - -func TestAbsolutePreStateCommitment(t *testing.T) { - dataDir := t.TempDir() - - prestate := "state.json" - - t.Run("StateUnavailable", func(t *testing.T) { - provider := newCannonPrestateProvider("/dir/does/not/exist", prestate) - _, err := provider.AbsolutePreStateCommitment(context.Background()) - require.ErrorIs(t, err, os.ErrNotExist) - }) - - t.Run("InvalidStateFile", func(t *testing.T) { - setupPreState(t, dataDir, "invalid.json") - provider := newCannonPrestateProvider(dataDir, prestate) - _, err := provider.AbsolutePreStateCommitment(context.Background()) - require.ErrorContains(t, err, "invalid mipsevm state") - }) - - t.Run("ExpectedAbsolutePreState", func(t *testing.T) { - setupPreState(t, dataDir, "state.json") - provider := newCannonPrestateProvider(dataDir, prestate) - actual, err := provider.AbsolutePreStateCommitment(context.Background()) - require.NoError(t, err) - state := singlethreaded.State{ - Memory: memory.NewMemory(), - PreimageKey: common.HexToHash("cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"), - PreimageOffset: 0, - Cpu: mipsevm.CpuScalars{ - PC: 0, - NextPC: 1, - LO: 0, - HI: 0, - }, - Heap: 0, - ExitCode: 0, - Exited: false, - Step: 0, - Registers: [32]uint32{}, - } - _, expected := state.EncodeWitness() - require.Equal(t, expected, actual) - }) - - t.Run("CacheAbsolutePreState", func(t *testing.T) { - setupPreState(t, dataDir, prestate) - provider := newCannonPrestateProvider(dataDir, prestate) - first, err := provider.AbsolutePreStateCommitment(context.Background()) - require.NoError(t, err) - - // Remove the prestate from disk - require.NoError(t, os.Remove(provider.prestate)) - - // Value should still be available from cache - cached, err := provider.AbsolutePreStateCommitment(context.Background()) - require.NoError(t, err) - require.Equal(t, first, cached) - }) -} - -func setupPreState(t *testing.T, dataDir string, filename string) { - srcDir := filepath.Join("test_data") - path := filepath.Join(srcDir, filename) - file, err := testData.ReadFile(path) - require.NoErrorf(t, err, "reading %v", path) - err = os.WriteFile(filepath.Join(dataDir, "state.json"), file, 0o644) - require.NoErrorf(t, err, "writing %v", path) -} diff --git a/op-challenger/game/fault/trace/cannon/provider.go b/op-challenger/game/fault/trace/cannon/provider.go index fc7a71c1cda0..ce3cd8cceb96 100644 --- a/op-challenger/game/fault/trace/cannon/provider.go +++ b/op-challenger/game/fault/trace/cannon/provider.go @@ -11,10 +11,8 @@ import ( "path/filepath" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" "github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" @@ -30,6 +28,7 @@ type CannonTraceProvider struct { generator utils.ProofGenerator gameDepth types.Depth preimageLoader *utils.PreimageLoader + stateConverter vm.StateConverter types.PrestateProvider @@ -49,6 +48,7 @@ func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, vmCfg vm. return kvstore.NewFileKV(vm.PreimageDir(dir)) }), PrestateProvider: prestateProvider, + stateConverter: &StateConverter{}, } } @@ -122,33 +122,22 @@ func (p *CannonTraceProvider) loadProof(ctx context.Context, i uint64) (*utils.P // Try opening the file again now and it should exist. file, err = ioutil.OpenDecompressed(path) if errors.Is(err, os.ErrNotExist) { - // Expected proof wasn't generated, check if we reached the end of execution - state, err := p.finalState() + proof, stateStep, exited, err := p.stateConverter.ConvertStateToProof(filepath.Join(p.dir, vm.FinalState)) if err != nil { - return nil, err + return nil, fmt.Errorf("cannot create proof from final state: %w", err) } - if state.Exited && state.Step <= i { - p.logger.Warn("Requested proof was after the program exited", "proof", i, "last", state.Step) + + if exited && stateStep <= i { + p.logger.Warn("Requested proof was after the program exited", "proof", i, "last", stateStep) // The final instruction has already been applied to this state, so the last step we can execute // is one before its Step value. - p.lastStep = state.Step - 1 - // Extend the trace out to the full length using a no-op instruction that doesn't change any state - // No execution is done, so no proof-data or oracle values are required. - witness, witnessHash := state.EncodeWitness() - proof := &utils.ProofData{ - ClaimValue: witnessHash, - StateData: hexutil.Bytes(witness), - ProofData: []byte{}, - OracleKey: nil, - OracleValue: nil, - OracleOffset: 0, - } + p.lastStep = stateStep - 1 if err := utils.WriteLastStep(p.dir, proof, p.lastStep); err != nil { p.logger.Warn("Failed to write last step to disk cache", "step", p.lastStep) } return proof, nil } else { - return nil, fmt.Errorf("expected proof not generated but final state was not exited, requested step %v, final state at step %v", i, state.Step) + return nil, fmt.Errorf("expected proof not generated but final state was not exited, requested step %v, final state at step %v", i, stateStep) } } } @@ -164,14 +153,6 @@ func (p *CannonTraceProvider) loadProof(ctx context.Context, i uint64) (*utils.P return &proof, nil } -func (c *CannonTraceProvider) finalState() (*singlethreaded.State, error) { - state, err := parseState(filepath.Join(c.dir, vm.FinalState)) - if err != nil { - return nil, fmt.Errorf("cannot read final state: %w", err) - } - return state, nil -} - // CannonTraceProviderForTest is a CannonTraceProvider that can find the step referencing the preimage read // Only to be used for testing type CannonTraceProviderForTest struct { @@ -188,6 +169,7 @@ func NewTraceProviderForTest(logger log.Logger, m vm.Metricer, cfg *config.Confi preimageLoader: utils.NewPreimageLoader(func() utils.PreimageSource { return kvstore.NewFileKV(vm.PreimageDir(dir)) }), + stateConverter: NewStateConverter(), } return &CannonTraceProviderForTest{p} } @@ -198,14 +180,14 @@ func (p *CannonTraceProviderForTest) FindStep(ctx context.Context, start uint64, return 0, fmt.Errorf("generate cannon trace (until preimage read): %w", err) } // Load the step from the state cannon finished with - state, err := p.finalState() + _, step, exited, err := p.stateConverter.ConvertStateToProof(filepath.Join(p.dir, vm.FinalState)) if err != nil { return 0, fmt.Errorf("failed to load final state: %w", err) } // Check we didn't get to the end of the trace without finding the preimage read we were looking for - if state.Exited { + if exited { return 0, fmt.Errorf("preimage read not found: %w", io.EOF) } // The state is the post-state so the step we want to execute to read the preimage is step - 1. - return state.Step - 1, nil + return step - 1, nil } diff --git a/op-challenger/game/fault/trace/cannon/provider_test.go b/op-challenger/game/fault/trace/cannon/provider_test.go index 3343b581f1c1..c650bd6ef818 100644 --- a/op-challenger/game/fault/trace/cannon/provider_test.go +++ b/op-challenger/game/fault/trace/cannon/provider_test.go @@ -239,11 +239,12 @@ func setupTestData(t *testing.T) (string, string) { func setupWithTestData(t *testing.T, dataDir string, prestate string) (*CannonTraceProvider, *stubGenerator) { generator := &stubGenerator{} return &CannonTraceProvider{ - logger: testlog.Logger(t, log.LevelInfo), - dir: dataDir, - generator: generator, - prestate: filepath.Join(dataDir, prestate), - gameDepth: 63, + logger: testlog.Logger(t, log.LevelInfo), + dir: dataDir, + generator: generator, + prestate: filepath.Join(dataDir, prestate), + gameDepth: 63, + stateConverter: &StateConverter{}, }, generator } diff --git a/op-challenger/game/fault/trace/cannon/state.go b/op-challenger/game/fault/trace/cannon/state.go deleted file mode 100644 index cf781c8bd428..000000000000 --- a/op-challenger/game/fault/trace/cannon/state.go +++ /dev/null @@ -1,27 +0,0 @@ -package cannon - -import ( - "encoding/json" - "fmt" - "io" - - "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" - "github.com/ethereum-optimism/optimism/op-service/ioutil" -) - -func parseState(path string) (*singlethreaded.State, error) { - file, err := ioutil.OpenDecompressed(path) - if err != nil { - return nil, fmt.Errorf("cannot open state file (%v): %w", path, err) - } - return parseStateFromReader(file) -} - -func parseStateFromReader(in io.ReadCloser) (*singlethreaded.State, error) { - defer in.Close() - var state singlethreaded.State - if err := json.NewDecoder(in).Decode(&state); err != nil { - return nil, fmt.Errorf("invalid mipsevm state: %w", err) - } - return &state, nil -} diff --git a/op-challenger/game/fault/trace/cannon/state_converter.go b/op-challenger/game/fault/trace/cannon/state_converter.go new file mode 100644 index 000000000000..e11b0ee53caa --- /dev/null +++ b/op-challenger/game/fault/trace/cannon/state_converter.go @@ -0,0 +1,53 @@ +package cannon + +import ( + "encoding/json" + "fmt" + "io" + + "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" + "github.com/ethereum-optimism/optimism/op-service/ioutil" +) + +type StateConverter struct { +} + +func NewStateConverter() *StateConverter { + return &StateConverter{} +} + +func (c *StateConverter) ConvertStateToProof(statePath string) (*utils.ProofData, uint64, bool, error) { + state, err := parseState(statePath) + if err != nil { + return nil, 0, false, fmt.Errorf("cannot read final state: %w", err) + } + // Extend the trace out to the full length using a no-op instruction that doesn't change any state + // No execution is done, so no proof-data or oracle values are required. + witness, witnessHash := state.EncodeWitness() + return &utils.ProofData{ + ClaimValue: witnessHash, + StateData: witness, + ProofData: []byte{}, + OracleKey: nil, + OracleValue: nil, + OracleOffset: 0, + }, state.Step, state.Exited, nil +} + +func parseState(path string) (*singlethreaded.State, error) { + file, err := ioutil.OpenDecompressed(path) + if err != nil { + return nil, fmt.Errorf("cannot open state file (%v): %w", path, err) + } + return parseStateFromReader(file) +} + +func parseStateFromReader(in io.ReadCloser) (*singlethreaded.State, error) { + defer in.Close() + var state singlethreaded.State + if err := json.NewDecoder(in).Decode(&state); err != nil { + return nil, fmt.Errorf("invalid mipsevm state: %w", err) + } + return &state, nil +} diff --git a/op-challenger/game/fault/trace/vm/iface.go b/op-challenger/game/fault/trace/vm/iface.go new file mode 100644 index 000000000000..188f19e0c8e2 --- /dev/null +++ b/op-challenger/game/fault/trace/vm/iface.go @@ -0,0 +1,9 @@ +package vm + +import "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" + +type StateConverter interface { + // ConvertStateToProof reads the state snapshot at the specified path and converts it to ProofData. + // Returns the proof data, the VM step the state is from and whether or not the VM had exited. + ConvertStateToProof(statePath string) (*utils.ProofData, uint64, bool, error) +} diff --git a/op-challenger/game/fault/trace/vm/prestate.go b/op-challenger/game/fault/trace/vm/prestate.go new file mode 100644 index 000000000000..bbb4a9437d9a --- /dev/null +++ b/op-challenger/game/fault/trace/vm/prestate.go @@ -0,0 +1,42 @@ +package vm + +import ( + "context" + "fmt" + + "github.com/ethereum/go-ethereum/common" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" +) + +var _ types.PrestateProvider = (*PrestateProvider)(nil) + +type PrestateProvider struct { + prestate string + stateConverter StateConverter + + prestateCommitment common.Hash +} + +func NewPrestateProvider(prestate string, converter StateConverter) *PrestateProvider { + return &PrestateProvider{ + prestate: prestate, + stateConverter: converter, + } +} + +func (p *PrestateProvider) AbsolutePreStateCommitment(_ context.Context) (common.Hash, error) { + if p.prestateCommitment != (common.Hash{}) { + return p.prestateCommitment, nil + } + proof, _, _, err := p.stateConverter.ConvertStateToProof(p.prestate) + if err != nil { + return common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err) + } + p.prestateCommitment = proof.ClaimValue + return proof.ClaimValue, nil +} + +func (p *PrestateProvider) PrestatePath() string { + return p.prestate +} diff --git a/op-challenger/game/fault/trace/vm/prestate_test.go b/op-challenger/game/fault/trace/vm/prestate_test.go new file mode 100644 index 000000000000..69498e323c59 --- /dev/null +++ b/op-challenger/game/fault/trace/vm/prestate_test.go @@ -0,0 +1,63 @@ +package vm + +import ( + "context" + "errors" + "path/filepath" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +type stubConverter struct { + err error + hash common.Hash +} + +func (s *stubConverter) ConvertStateToProof(statePath string) (*utils.ProofData, uint64, bool, error) { + if s.err != nil { + return nil, 0, false, s.err + } + return &utils.ProofData{ + ClaimValue: s.hash, + }, 0, false, nil +} + +func newPrestateProvider(prestate common.Hash) *PrestateProvider { + return NewPrestateProvider("state.json", &stubConverter{hash: prestate}) +} + +func TestAbsolutePreStateCommitment(t *testing.T) { + prestate := common.Hash{0xaa, 0xbb} + + t.Run("StateUnavailable", func(t *testing.T) { + expectedErr := errors.New("kaboom") + provider := NewPrestateProvider("foo", &stubConverter{err: expectedErr}) + _, err := provider.AbsolutePreStateCommitment(context.Background()) + require.ErrorIs(t, err, expectedErr) + }) + + t.Run("ExpectedAbsolutePreState", func(t *testing.T) { + provider := newPrestateProvider(prestate) + actual, err := provider.AbsolutePreStateCommitment(context.Background()) + require.NoError(t, err) + require.Equal(t, prestate, actual) + }) + + t.Run("CacheAbsolutePreState", func(t *testing.T) { + converter := &stubConverter{hash: prestate} + provider := NewPrestateProvider(filepath.Join("state.json"), converter) + first, err := provider.AbsolutePreStateCommitment(context.Background()) + require.NoError(t, err) + + // Remove the prestate from disk + converter.err = errors.New("no soup for you") + + // Value should still be available from cache + cached, err := provider.AbsolutePreStateCommitment(context.Background()) + require.NoError(t, err) + require.Equal(t, first, cached) + }) +} diff --git a/op-challenger/runner/factory.go b/op-challenger/runner/factory.go index dae0a3fce146..59188210d8e5 100644 --- a/op-challenger/runner/factory.go +++ b/op-challenger/runner/factory.go @@ -33,7 +33,7 @@ func createTraceProvider( if err != nil { return nil, err } - prestateProvider := cannon.NewPrestateProvider(prestate) + prestateProvider := vm.NewPrestateProvider(prestate, cannon.NewStateConverter()) return cannon.NewTraceProvider(logger, m, cfg.Cannon, vmConfig, prestateProvider, prestate, localInputs, dir, 42), nil case types.TraceTypeAsterisc: vmConfig := vm.NewOpProgramServerExecutor() @@ -41,7 +41,7 @@ func createTraceProvider( if err != nil { return nil, err } - prestateProvider := asterisc.NewPrestateProvider(prestate) + prestateProvider := vm.NewPrestateProvider(prestate, asterisc.NewStateConverter()) return asterisc.NewTraceProvider(logger, m, cfg.Asterisc, vmConfig, prestateProvider, prestate, localInputs, dir, 42), nil case types.TraceTypeAsteriscKona: vmConfig := vm.NewKonaServerExecutor() @@ -49,7 +49,7 @@ func createTraceProvider( if err != nil { return nil, err } - prestateProvider := asterisc.NewPrestateProvider(prestate) + prestateProvider := vm.NewPrestateProvider(prestate, asterisc.NewStateConverter()) return asterisc.NewTraceProvider(logger, m, cfg.Asterisc, vmConfig, prestateProvider, prestate, localInputs, dir, 42), nil } return nil, errors.New("invalid trace type") From ec06858a21f76795cd2bfb345d8257b558c9cd1a Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Wed, 4 Sep 2024 22:05:50 -0600 Subject: [PATCH 040/264] contracts-bedrock: Add OPSM file I/O for superchain deployments (#11750) * contracts-bedrock: Add OPSM file I/O for superchain deployments * Update packages/contracts-bedrock/scripts/DeploySuperchain.s.sol Co-authored-by: Matt Solomon * Update packages/contracts-bedrock/test/DeploySuperchain.t.sol Co-authored-by: Matt Solomon * Address feedback from code review * Linter --------- Co-authored-by: Matt Solomon --- packages/contracts-bedrock/.testdata/.gitkeep | 0 packages/contracts-bedrock/foundry.toml | 3 +- .../scripts/DeploySuperchain.s.sol | 46 +++++----- .../test/DeploySuperchain.t.sol | 90 ++++++++++++++----- .../fixtures/test-deploy-superchain-in.toml | 8 ++ .../fixtures/test-deploy-superchain-out.toml | 5 ++ 6 files changed, 111 insertions(+), 41 deletions(-) create mode 100644 packages/contracts-bedrock/.testdata/.gitkeep create mode 100644 packages/contracts-bedrock/test/fixtures/test-deploy-superchain-in.toml create mode 100644 packages/contracts-bedrock/test/fixtures/test-deploy-superchain-out.toml diff --git a/packages/contracts-bedrock/.testdata/.gitkeep b/packages/contracts-bedrock/.testdata/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/contracts-bedrock/foundry.toml b/packages/contracts-bedrock/foundry.toml index 9edf752f983d..cef9f85bbaeb 100644 --- a/packages/contracts-bedrock/foundry.toml +++ b/packages/contracts-bedrock/foundry.toml @@ -49,7 +49,8 @@ fs_permissions = [ { access='read', path = './forge-artifacts/' }, { access='write', path='./semver-lock.json' }, { access='read-write', path='./.testdata/' }, - { access='read', path='./kout-deployment' } + { access='read', path='./kout-deployment' }, + { access='read', path='./test/fixtures' }, ] libs = ["node_modules", "lib"] diff --git a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol index 8a3e004b2c10..f90208ce81bd 100644 --- a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol +++ b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.15; import { Script } from "forge-std/Script.sol"; +import { CommonBase } from "forge-std/Base.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { ProtocolVersions, ProtocolVersion } from "src/L1/ProtocolVersions.sol"; @@ -57,19 +58,20 @@ import { Solarray } from "scripts/libraries/Solarray.sol"; * scripts from the existing ones that "Config" and "Artifacts" terminology. */ -contract DeploySuperchainInput { +contract DeploySuperchainInput is CommonBase { // The input struct contains all the input data required for the deployment. + // The fields must be in alphabetical order for vm.parseToml to work. struct Input { - Roles roles; bool paused; - ProtocolVersion requiredProtocolVersion; ProtocolVersion recommendedProtocolVersion; + ProtocolVersion requiredProtocolVersion; + Roles roles; } struct Roles { - address proxyAdminOwner; - address protocolVersionsOwner; address guardian; + address protocolVersionsOwner; + address proxyAdminOwner; } // This flag tells us if all inputs have been set. An `input()` getter method that returns all @@ -84,10 +86,10 @@ contract DeploySuperchainInput { // Load the input from a TOML file. function loadInputFile(string memory _infile) public { - _infile; - Input memory parsedInput; + string memory toml = vm.readFile(_infile); + bytes memory data = vm.parseToml(toml); + Input memory parsedInput = abi.decode(data, (Input)); loadInput(parsedInput); - require(false, "DeploySuperchainInput: not implemented"); } // Load the input from a struct. @@ -153,14 +155,15 @@ contract DeploySuperchainInput { } } -contract DeploySuperchainOutput { +contract DeploySuperchainOutput is CommonBase { // The output struct contains all the output data from the deployment. + // The fields must be in alphabetical order for vm.parseToml to work. struct Output { - ProxyAdmin superchainProxyAdmin; - SuperchainConfig superchainConfigImpl; - SuperchainConfig superchainConfigProxy; ProtocolVersions protocolVersionsImpl; ProtocolVersions protocolVersionsProxy; + SuperchainConfig superchainConfigImpl; + SuperchainConfig superchainConfigProxy; + ProxyAdmin superchainProxyAdmin; } // We use a similar pattern as the input contract to expose outputs. Because outputs are set @@ -182,9 +185,14 @@ contract DeploySuperchainOutput { } // Save the output to a TOML file. - function writeOutputFile(string memory _outfile) public pure { - _outfile; - require(false, "DeploySuperchainOutput: not implemented"); + function writeOutputFile(string memory _outfile) public { + string memory key = "dso-outfile"; + vm.serializeAddress(key, "superchainProxyAdmin", address(outputs.superchainProxyAdmin)); + vm.serializeAddress(key, "superchainConfigImpl", address(outputs.superchainConfigImpl)); + vm.serializeAddress(key, "superchainConfigProxy", address(outputs.superchainConfigProxy)); + vm.serializeAddress(key, "protocolVersionsImpl", address(outputs.protocolVersionsImpl)); + string memory out = vm.serializeAddress(key, "protocolVersionsProxy", address(outputs.protocolVersionsProxy)); + vm.writeToml(out, _outfile); } function output() public view returns (Output memory) { @@ -238,7 +246,7 @@ contract DeploySuperchain is Script { // This entrypoint is for end-users to deploy from an input file and write to an output file. // In this usage, we don't need the input and output contract functionality, so we deploy them // here and abstract that architectural detail away from the end user. - function run(string memory _infile) public { + function run(string memory _infile, string memory _outfile) public { // End-user without file IO, so etch the IO helper contracts. (DeploySuperchainInput dsi, DeploySuperchainOutput dso) = etchIOContracts(); @@ -248,10 +256,8 @@ contract DeploySuperchain is Script { // Run the deployment script and write outputs to the DeploySuperchainOutput contract. run(dsi, dso); - // Write the output data to a file. The file - string memory outfile = ""; // This will be derived from input file name, e.g. `foo.in.toml` -> `foo.out.toml` - dso.writeOutputFile(outfile); - require(false, "DeploySuperchain: run is not implemented"); + // Write the output data to a file. + dso.writeOutputFile(_outfile); } // This entrypoint is for use with Solidity tests, where the input and outputs are structs. diff --git a/packages/contracts-bedrock/test/DeploySuperchain.t.sol b/packages/contracts-bedrock/test/DeploySuperchain.t.sol index 2eeffb68e48a..8babb4877a25 100644 --- a/packages/contracts-bedrock/test/DeploySuperchain.t.sol +++ b/packages/contracts-bedrock/test/DeploySuperchain.t.sol @@ -32,27 +32,15 @@ contract DeploySuperchainInput_Test is Test { // parameters to e.g. avoid the zero address. Therefore we hardcode a concrete test case // which is simpler and still sufficient. dsi.loadInput(input); + assertLoadInput(); + } - assertTrue(dsi.inputSet(), "100"); + function test_loadInputFile_succeeds() public { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/test-deploy-superchain-in.toml"); - // Compare the test input struct to the getter methods. - assertEq(input.roles.proxyAdminOwner, dsi.proxyAdminOwner(), "200"); - assertEq(input.roles.protocolVersionsOwner, dsi.protocolVersionsOwner(), "300"); - assertEq(input.roles.guardian, dsi.guardian(), "400"); - assertEq(input.paused, dsi.paused(), "500"); - assertEq( - ProtocolVersion.unwrap(input.requiredProtocolVersion), - ProtocolVersion.unwrap(dsi.requiredProtocolVersion()), - "600" - ); - assertEq( - ProtocolVersion.unwrap(input.recommendedProtocolVersion), - ProtocolVersion.unwrap(dsi.recommendedProtocolVersion()), - "700" - ); - - // Compare the test input struct to the `input` getter method. - assertEq(keccak256(abi.encode(input)), keccak256(abi.encode(dsi.input())), "800"); + dsi.loadInputFile(path); + assertLoadInput(); } function test_getters_whenNotSet_revert() public { @@ -76,6 +64,29 @@ contract DeploySuperchainInput_Test is Test { vm.expectRevert(expectedErr); dsi.recommendedProtocolVersion(); } + + function assertLoadInput() internal view { + assertTrue(dsi.inputSet(), "100"); + + // Compare the test input struct to the getter methods. + assertEq(input.roles.proxyAdminOwner, dsi.proxyAdminOwner(), "200"); + assertEq(input.roles.protocolVersionsOwner, dsi.protocolVersionsOwner(), "300"); + assertEq(input.roles.guardian, dsi.guardian(), "400"); + assertEq(input.paused, dsi.paused(), "500"); + assertEq( + ProtocolVersion.unwrap(input.requiredProtocolVersion), + ProtocolVersion.unwrap(dsi.requiredProtocolVersion()), + "600" + ); + assertEq( + ProtocolVersion.unwrap(input.recommendedProtocolVersion), + ProtocolVersion.unwrap(dsi.recommendedProtocolVersion()), + "700" + ); + + // Compare the test input struct to the `input` getter method. + assertEq(keccak256(abi.encode(input)), keccak256(abi.encode(dsi.input())), "800"); + } } contract DeploySuperchainOutput_Test is Test { @@ -165,6 +176,31 @@ contract DeploySuperchainOutput_Test is Test { vm.expectRevert(expectedErr); dso.protocolVersionsProxy(); } + + function test_writeOutputFile_succeeds() public { + string memory root = vm.projectRoot(); + + // Use the expected data from the test fixture. + string memory expOutPath = string.concat(root, "/test/fixtures/test-deploy-superchain-out.toml"); + string memory expOutToml = vm.readFile(expOutPath); + bytes memory expOutData = vm.parseToml(expOutToml); + DeploySuperchainOutput.Output memory expOutput = abi.decode(expOutData, (DeploySuperchainOutput.Output)); + + dso.set(dso.superchainProxyAdmin.selector, address(expOutput.superchainProxyAdmin)); + dso.set(dso.superchainConfigImpl.selector, address(expOutput.superchainConfigImpl)); + dso.set(dso.superchainConfigProxy.selector, address(expOutput.superchainConfigProxy)); + dso.set(dso.protocolVersionsImpl.selector, address(expOutput.protocolVersionsImpl)); + dso.set(dso.protocolVersionsProxy.selector, address(expOutput.protocolVersionsProxy)); + + string memory actOutPath = string.concat(root, "/.testdata/test-deploy-superchain-output.toml"); + dso.writeOutputFile(actOutPath); + string memory actOutToml = vm.readFile(actOutPath); + + // Clean up before asserting so that we don't leave any files behind. + vm.removeFile(actOutPath); + + assertEq(expOutToml, actOutToml); + } } contract DeploySuperchain_Test is Test { @@ -193,7 +229,7 @@ contract DeploySuperchain_Test is Test { return ProtocolVersion.unwrap(_pv); } - function test_run_succeeds(DeploySuperchainInput.Input memory _input) public { + function test_run_memory_succeeds(DeploySuperchainInput.Input memory _input) public { vm.assume(_input.roles.proxyAdminOwner != address(0)); vm.assume(_input.roles.protocolVersionsOwner != address(0)); vm.assume(_input.roles.guardian != address(0)); @@ -244,6 +280,20 @@ contract DeploySuperchain_Test is Test { dso.checkOutput(); } + function test_run_io_succeeds() public { + string memory root = vm.projectRoot(); + string memory inpath = string.concat(root, "/test/fixtures/test-deploy-superchain-in.toml"); + string memory outpath = string.concat(root, "/.testdata/test-deploy-superchain-out.toml"); + + deploySuperchain.run(inpath, outpath); + + string memory actOutToml = vm.readFile(outpath); + string memory expOutToml = vm.readFile(string.concat(root, "/test/fixtures/test-deploy-superchain-out.toml")); + // Clean up before asserting so that we don't leave any files behind. + vm.removeFile(outpath); + assertEq(expOutToml, actOutToml); + } + function test_run_ZeroAddressRoleInput_reverts() public { // Snapshot the state so we can revert to the default `input` struct between assertions. uint256 snapshotId = vm.snapshot(); diff --git a/packages/contracts-bedrock/test/fixtures/test-deploy-superchain-in.toml b/packages/contracts-bedrock/test/fixtures/test-deploy-superchain-in.toml new file mode 100644 index 000000000000..4cbcce25d004 --- /dev/null +++ b/packages/contracts-bedrock/test/fixtures/test-deploy-superchain-in.toml @@ -0,0 +1,8 @@ +paused = false +requiredProtocolVersion = 1 +recommendedProtocolVersion = 2 + +[roles] +proxyAdminOwner = "0x51f0348a9fA2aAbaB45E82825Fbd13d406e04497" +protocolVersionsOwner = "0xeEB4cc05dC0dE43c465f97cfc703D165418CA93A" +guardian = "0xE5DbA98c65F4B9EB0aeEBb3674fE64f88509a1eC" \ No newline at end of file diff --git a/packages/contracts-bedrock/test/fixtures/test-deploy-superchain-out.toml b/packages/contracts-bedrock/test/fixtures/test-deploy-superchain-out.toml new file mode 100644 index 000000000000..ceb558a79d5a --- /dev/null +++ b/packages/contracts-bedrock/test/fixtures/test-deploy-superchain-out.toml @@ -0,0 +1,5 @@ +protocolVersionsImpl = "0x5991A2dF15A8F6A256D3Ec51E99254Cd3fb576A9" +protocolVersionsProxy = "0x1d1499e622D69689cdf9004d05Ec547d650Ff211" +superchainConfigImpl = "0xF62849F9A0B5Bf2913b396098F7c7019b51A820a" +superchainConfigProxy = "0xc7183455a4C133Ae270771860664b6B7ec320bB1" +superchainProxyAdmin = "0x2e234DAe75C793f67A35089C9d99245E1C58470b" From 51150d8bc66a66ecc55d30975157c63a309d1252 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Thu, 5 Sep 2024 00:29:07 -0400 Subject: [PATCH 041/264] maint: update solidity vscode extension (#11751) --- .vscode/extensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 79135484302d..0e0528fd33e2 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,7 +1,7 @@ { "recommendations": [ "editorconfig.editorconfig", - "juanblanco.solidity", + "nomicfoundation.hardhat-solidity", "golang.go" ] } From 91c7ed0d6562ae3613de7983037a6479bfd45816 Mon Sep 17 00:00:00 2001 From: Zach Howard Date: Thu, 5 Sep 2024 11:03:27 -0400 Subject: [PATCH 042/264] op-conductor: adds raft log snapshot configs (#11745) * Refactors NewRaftConsensus param list into a config struct * Adds configuration support for SnapshotInterval, SnapshotThreshold, TrailingLogs --- op-conductor/conductor/config.go | 29 +++++++++++++++++------- op-conductor/conductor/service.go | 12 +++++++++- op-conductor/consensus/raft.go | 34 ++++++++++++++++++++--------- op-conductor/consensus/raft_test.go | 15 +++++++++---- op-conductor/flags/flags.go | 22 +++++++++++++++++++ op-e2e/sequencer_failover_setup.go | 19 +++++++++------- 6 files changed, 100 insertions(+), 31 deletions(-) diff --git a/op-conductor/conductor/config.go b/op-conductor/conductor/config.go index 2d356a6553e1..ca18de7d1a18 100644 --- a/op-conductor/conductor/config.go +++ b/op-conductor/conductor/config.go @@ -3,6 +3,7 @@ package conductor import ( "fmt" "math" + "time" "github.com/ethereum/go-ethereum/log" "github.com/pkg/errors" @@ -33,6 +34,15 @@ type Config struct { // RaftBootstrap is true if this node should bootstrap a new raft cluster. RaftBootstrap bool + // RaftSnapshotInterval is the interval to check if a snapshot should be taken. + RaftSnapshotInterval time.Duration + + // RaftSnapshotThreshold is the number of logs to trigger a snapshot. + RaftSnapshotThreshold uint64 + + // RaftTrailingLogs is the number of logs to keep after a snapshot. + RaftTrailingLogs uint64 + // NodeRPC is the HTTP provider URL for op-node. NodeRPC string @@ -107,14 +117,17 @@ func NewConfig(ctx *cli.Context, log log.Logger) (*Config, error) { } return &Config{ - ConsensusAddr: ctx.String(flags.ConsensusAddr.Name), - ConsensusPort: ctx.Int(flags.ConsensusPort.Name), - RaftBootstrap: ctx.Bool(flags.RaftBootstrap.Name), - RaftServerID: ctx.String(flags.RaftServerID.Name), - RaftStorageDir: ctx.String(flags.RaftStorageDir.Name), - NodeRPC: ctx.String(flags.NodeRPC.Name), - ExecutionRPC: ctx.String(flags.ExecutionRPC.Name), - Paused: ctx.Bool(flags.Paused.Name), + ConsensusAddr: ctx.String(flags.ConsensusAddr.Name), + ConsensusPort: ctx.Int(flags.ConsensusPort.Name), + RaftBootstrap: ctx.Bool(flags.RaftBootstrap.Name), + RaftServerID: ctx.String(flags.RaftServerID.Name), + RaftStorageDir: ctx.String(flags.RaftStorageDir.Name), + RaftSnapshotInterval: ctx.Duration(flags.RaftSnapshotInterval.Name), + RaftSnapshotThreshold: ctx.Uint64(flags.RaftSnapshotThreshold.Name), + RaftTrailingLogs: ctx.Uint64(flags.RaftTrailingLogs.Name), + NodeRPC: ctx.String(flags.NodeRPC.Name), + ExecutionRPC: ctx.String(flags.ExecutionRPC.Name), + Paused: ctx.Bool(flags.Paused.Name), HealthCheck: HealthCheckConfig{ Interval: ctx.Uint64(flags.HealthCheckInterval.Name), UnsafeInterval: ctx.Uint64(flags.HealthCheckUnsafeInterval.Name), diff --git a/op-conductor/conductor/service.go b/op-conductor/conductor/service.go index 2a39193c6bcc..d2eb4fe89d9d 100644 --- a/op-conductor/conductor/service.go +++ b/op-conductor/conductor/service.go @@ -149,7 +149,17 @@ func (c *OpConductor) initConsensus(ctx context.Context) error { } serverAddr := fmt.Sprintf("%s:%d", c.cfg.ConsensusAddr, c.cfg.ConsensusPort) - cons, err := consensus.NewRaftConsensus(c.log, c.cfg.RaftServerID, serverAddr, c.cfg.RaftStorageDir, c.cfg.RaftBootstrap, &c.cfg.RollupCfg) + raftConsensusConfig := &consensus.RaftConsensusConfig{ + ServerID: c.cfg.RaftServerID, + ServerAddr: serverAddr, + StorageDir: c.cfg.RaftStorageDir, + Bootstrap: c.cfg.RaftBootstrap, + RollupCfg: &c.cfg.RollupCfg, + SnapshotInterval: c.cfg.RaftSnapshotInterval, + SnapshotThreshold: c.cfg.RaftSnapshotThreshold, + TrailingLogs: c.cfg.RaftTrailingLogs, + } + cons, err := consensus.NewRaftConsensus(c.log, raftConsensusConfig) if err != nil { return errors.Wrap(err, "failed to create raft consensus") } diff --git a/op-conductor/consensus/raft.go b/op-conductor/consensus/raft.go index c534d0305847..f6acc0fb76f1 100644 --- a/op-conductor/consensus/raft.go +++ b/op-conductor/consensus/raft.go @@ -32,6 +32,17 @@ type RaftConsensus struct { unsafeTracker *unsafeHeadTracker } +type RaftConsensusConfig struct { + ServerID string + ServerAddr string + StorageDir string + Bootstrap bool + RollupCfg *rollup.Config + SnapshotInterval time.Duration + SnapshotThreshold uint64 + TrailingLogs uint64 +} + // checkTCPPortOpen attempts to connect to the specified address and returns an error if the connection fails. func checkTCPPortOpen(address string) error { conn, err := net.DialTimeout("tcp", address, 5*time.Second) @@ -43,11 +54,14 @@ func checkTCPPortOpen(address string) error { } // NewRaftConsensus creates a new RaftConsensus instance. -func NewRaftConsensus(log log.Logger, serverID, serverAddr, storageDir string, bootstrap bool, rollupCfg *rollup.Config) (*RaftConsensus, error) { +func NewRaftConsensus(log log.Logger, cfg *RaftConsensusConfig) (*RaftConsensus, error) { rc := raft.DefaultConfig() - rc.LocalID = raft.ServerID(serverID) + rc.SnapshotInterval = cfg.SnapshotInterval + rc.TrailingLogs = cfg.TrailingLogs + rc.SnapshotThreshold = cfg.SnapshotThreshold + rc.LocalID = raft.ServerID(cfg.ServerID) - baseDir := filepath.Join(storageDir, serverID) + baseDir := filepath.Join(cfg.StorageDir, cfg.ServerID) if _, err := os.Stat(baseDir); os.IsNotExist(err) { if err := os.MkdirAll(baseDir, 0o755); err != nil { return nil, fmt.Errorf("error creating storage dir: %w", err) @@ -72,7 +86,7 @@ func NewRaftConsensus(log log.Logger, serverID, serverAddr, storageDir string, b return nil, fmt.Errorf(`raft.NewFileSnapshotStore(%q): %w`, baseDir, err) } - addr, err := net.ResolveTCPAddr("tcp", serverAddr) + addr, err := net.ResolveTCPAddr("tcp", cfg.ServerAddr) if err != nil { return nil, errors.Wrap(err, "failed to resolve tcp address") } @@ -95,18 +109,18 @@ func NewRaftConsensus(log log.Logger, serverID, serverAddr, storageDir string, b // If bootstrap = true, start raft in bootstrap mode, this will allow the current node to elect itself as leader when there's no other participants // and allow other nodes to join the cluster. - if bootstrap { - cfg := raft.Configuration{ + if cfg.Bootstrap { + raftCfg := raft.Configuration{ Servers: []raft.Server{ { ID: rc.LocalID, - Address: raft.ServerAddress(serverAddr), + Address: raft.ServerAddress(cfg.ServerAddr), Suffrage: raft.Voter, }, }, } - f := r.BootstrapCluster(cfg) + f := r.BootstrapCluster(raftCfg) if err := f.Error(); err != nil { return nil, errors.Wrap(err, "failed to bootstrap raft cluster") } @@ -115,9 +129,9 @@ func NewRaftConsensus(log log.Logger, serverID, serverAddr, storageDir string, b return &RaftConsensus{ log: log, r: r, - serverID: raft.ServerID(serverID), + serverID: raft.ServerID(cfg.ServerID), unsafeTracker: fsm, - rollupCfg: rollupCfg, + rollupCfg: cfg.RollupCfg, }, nil } diff --git a/op-conductor/consensus/raft_test.go b/op-conductor/consensus/raft_test.go index 332bbd203e7e..fbd9c7cb3bc8 100644 --- a/op-conductor/consensus/raft_test.go +++ b/op-conductor/consensus/raft_test.go @@ -18,9 +18,6 @@ import ( func TestCommitAndRead(t *testing.T) { log := testlog.Logger(t, log.LevelInfo) - serverID := "SequencerA" - serverAddr := "127.0.0.1:0" - bootstrap := true now := uint64(time.Now().Unix()) rollupCfg := &rollup.Config{ CanyonTime: &now, @@ -29,8 +26,18 @@ func TestCommitAndRead(t *testing.T) { if err := os.RemoveAll(storageDir); err != nil { t.Fatal(err) } + raftConsensusConfig := &RaftConsensusConfig{ + ServerID: "SequencerA", + ServerAddr: "127.0.0.1:0", + StorageDir: storageDir, + Bootstrap: true, + RollupCfg: rollupCfg, + SnapshotInterval: 120 * time.Second, + SnapshotThreshold: 10240, + TrailingLogs: 8192, + } - cons, err := NewRaftConsensus(log, serverID, serverAddr, storageDir, bootstrap, rollupCfg) + cons, err := NewRaftConsensus(log, raftConsensusConfig) require.NoError(t, err) // wait till it became leader diff --git a/op-conductor/flags/flags.go b/op-conductor/flags/flags.go index 4870ba4a3ab0..249e8a676e07 100644 --- a/op-conductor/flags/flags.go +++ b/op-conductor/flags/flags.go @@ -2,6 +2,7 @@ package flags import ( "fmt" + "time" "github.com/urfave/cli/v2" @@ -44,6 +45,24 @@ var ( Usage: "Directory to store raft data", EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "RAFT_STORAGE_DIR"), } + RaftSnapshotInterval = &cli.DurationFlag{ + Name: "raft.snapshot-interval", + Usage: "The interval to check if a snapshot should be taken.", + EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "RAFT_SNAPSHOT_INTERVAL"), + Value: 120 * time.Second, + } + RaftSnapshotThreshold = &cli.Uint64Flag{ + Name: "raft.snapshot-threshold", + Usage: "Number of logs to trigger a snapshot", + EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "RAFT_SNAPSHOT_THRESHOLD"), + Value: 8192, + } + RaftTrailingLogs = &cli.Uint64Flag{ + Name: "raft.trailing-logs", + Usage: "Number of logs to keep after a snapshot", + EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "RAFT_TRAILING_LOGS"), + Value: 10240, + } NodeRPC = &cli.StringFlag{ Name: "node.rpc", Usage: "HTTP provider URL for op-node", @@ -113,6 +132,9 @@ var optionalFlags = []cli.Flag{ RaftBootstrap, HealthCheckSafeEnabled, HealthCheckSafeInterval, + RaftSnapshotInterval, + RaftSnapshotThreshold, + RaftTrailingLogs, } func init() { diff --git a/op-e2e/sequencer_failover_setup.go b/op-e2e/sequencer_failover_setup.go index db4e05bff433..890c6269bdf1 100644 --- a/op-e2e/sequencer_failover_setup.go +++ b/op-e2e/sequencer_failover_setup.go @@ -208,14 +208,17 @@ func setupConductor( ) (*conductor, error) { consensusPort := findAvailablePort(t) cfg := con.Config{ - ConsensusAddr: localhost, - ConsensusPort: consensusPort, - RaftServerID: serverID, - RaftStorageDir: dir, - RaftBootstrap: bootstrap, - NodeRPC: nodeRPC, - ExecutionRPC: engineRPC, - Paused: true, + ConsensusAddr: localhost, + ConsensusPort: consensusPort, + RaftServerID: serverID, + RaftStorageDir: dir, + RaftBootstrap: bootstrap, + RaftSnapshotInterval: 120 * time.Second, + RaftSnapshotThreshold: 8192, + RaftTrailingLogs: 10240, + NodeRPC: nodeRPC, + ExecutionRPC: engineRPC, + Paused: true, HealthCheck: con.HealthCheckConfig{ Interval: 1, // per test setup, l2 block time is 1s. MinPeerCount: 2, // per test setup, each sequencer has 2 peers From ffd9ed477d93c47cd586323f250535df0309e6fb Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Thu, 5 Sep 2024 16:11:13 -0400 Subject: [PATCH 043/264] fix: initialization tests (#11674) Fixes the initialization tests, existing tests were not properly verifying that all of the initializable contracts were being accounted for. --- .../contracts-bedrock/scripts/Artifacts.s.sol | 13 +- .../scripts/libraries/ForgeArtifacts.sol | 110 +++++- packages/contracts-bedrock/semver-lock.json | 144 +++---- packages/contracts-bedrock/src/EAS/EAS.sol | 6 +- .../src/EAS/SchemaRegistry.sol | 6 +- .../src/L1/DataAvailabilityChallenge.sol | 5 +- .../src/L1/L1CrossDomainMessenger.sol | 6 +- .../src/L1/L1ERC721Bridge.sol | 5 +- .../src/L1/L1StandardBridge.sol | 6 +- .../src/L1/L2OutputOracle.sol | 6 +- .../src/L1/OPStackManager.sol | 6 +- .../src/L1/OptimismPortal.sol | 6 +- .../src/L1/OptimismPortal2.sol | 6 +- .../src/L1/OptimismPortalInterop.sol | 2 +- .../src/L1/ProtocolVersions.sol | 5 +- .../src/L1/SuperchainConfig.sol | 5 +- .../contracts-bedrock/src/L1/SystemConfig.sol | 5 +- .../src/L1/SystemConfigInterop.sol | 1 + .../contracts-bedrock/src/L2/BaseFeeVault.sol | 6 +- .../contracts-bedrock/src/L2/CrossL2Inbox.sol | 6 +- .../src/L2/GasPriceOracle.sol | 6 +- packages/contracts-bedrock/src/L2/L1Block.sol | 6 +- .../src/L2/L1BlockInterop.sol | 2 +- .../contracts-bedrock/src/L2/L1FeeVault.sol | 6 +- .../src/L2/L2CrossDomainMessenger.sol | 6 +- .../src/L2/L2ERC721Bridge.sol | 6 +- .../src/L2/L2StandardBridge.sol | 6 +- .../src/L2/L2StandardBridgeInterop.sol | 2 +- .../src/L2/L2ToL1MessagePasser.sol | 6 +- .../src/L2/L2ToL2CrossDomainMessenger.sol | 6 +- .../src/L2/OptimismSuperchainERC20.sol | 6 +- .../src/L2/SequencerFeeVault.sol | 6 +- .../src/dispute/AnchorStateRegistry.sol | 5 +- .../src/dispute/DisputeGameFactory.sol | 5 +- .../src/dispute/weth/DelayedWETH.sol | 5 +- .../src/legacy/AddressManager.sol | 2 +- .../src/legacy/DeployerWhitelist.sol | 8 +- .../src/legacy/L1BlockNumber.sol | 8 +- .../src/legacy/L1ChugSplashProxy.sol | 2 +- .../src/legacy/LegacyMessagePasser.sol | 8 +- .../src/legacy/ResolvedDelegateProxy.sol | 2 +- .../OptimismMintableERC20Factory.sol | 6 +- .../proofs/utils/DeploymentSummary.sol | 46 +-- .../proofs/utils/DeploymentSummaryCode.sol | 24 +- .../utils/DeploymentSummaryFaultProofs.sol | 46 +-- .../DeploymentSummaryFaultProofsCode.sol | 24 +- .../test/vendor/Initializable.t.sol | 357 ++++++++++-------- 47 files changed, 564 insertions(+), 403 deletions(-) diff --git a/packages/contracts-bedrock/scripts/Artifacts.s.sol b/packages/contracts-bedrock/scripts/Artifacts.s.sol index 3325f98d3acc..350d3d99ae68 100644 --- a/packages/contracts-bedrock/scripts/Artifacts.s.sol +++ b/packages/contracts-bedrock/scripts/Artifacts.s.sol @@ -28,13 +28,15 @@ struct Deployment { abstract contract Artifacts { /// @notice Foundry cheatcode VM. Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - /// @notice Error for when attempting to fetch a deployment and it does not exist + /// @notice Error for when attempting to fetch a deployment and it does not exist error DeploymentDoesNotExist(string); /// @notice Error for when trying to save an invalid deployment error InvalidDeployment(string); - /// @notice The set of deployments that have been done during execution. + /// @notice Error for when attempting to load the initialized slot of an unsupported contract. + error UnsupportedInitializableContract(string); + /// @notice The set of deployments that have been done during execution. mapping(string => Deployment) internal _namedDeployments; /// @notice The same as `_namedDeployments` but as an array. Deployment[] internal _newDeployments; @@ -211,6 +213,13 @@ abstract contract Artifacts { /// @notice Returns the value of the internal `_initialized` storage slot for a given contract. function loadInitializedSlot(string memory _contractName) public returns (uint8 initialized_) { + // FaultDisputeGame and PermissionedDisputeGame are initializable but cannot be loaded with + // this function yet because they are not properly labeled in the deploy script. + // TODO: Remove this restriction once the deploy script is fixed. + if (LibString.eq(_contractName, "FaultDisputeGame") || LibString.eq(_contractName, "PermissionedDisputeGame")) { + revert UnsupportedInitializableContract(_contractName); + } + address contractAddress; // Check if the contract name ends with `Proxy` and, if so, get the implementation address if (LibString.endsWith(_contractName, "Proxy")) { diff --git a/packages/contracts-bedrock/scripts/libraries/ForgeArtifacts.sol b/packages/contracts-bedrock/scripts/libraries/ForgeArtifacts.sol index 315ed6d0c530..4aa4309fad83 100644 --- a/packages/contracts-bedrock/scripts/libraries/ForgeArtifacts.sol +++ b/packages/contracts-bedrock/scripts/libraries/ForgeArtifacts.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.0; import { Vm } from "forge-std/Vm.sol"; import { stdJson } from "forge-std/StdJson.sol"; +import { LibString } from "@solady/utils/LibString.sol"; import { Executables } from "scripts/libraries/Executables.sol"; import { Process } from "scripts/libraries/Process.sol"; @@ -83,6 +84,67 @@ library ForgeArtifacts { ids_ = stdJson.readStringArray(string(res), ""); } + /// @notice Returns the kind of contract (i.e. library, contract, or interface). + /// @param _name The name of the contract to get the kind of. + /// @return kind_ The kind of contract ("library", "contract", or "interface"). + function getContractKind(string memory _name) internal returns (string memory kind_) { + string[] memory cmd = new string[](3); + cmd[0] = Executables.bash; + cmd[1] = "-c"; + cmd[2] = string.concat( + Executables.jq, + " -r '.ast.nodes[] | select(.nodeType == \"ContractDefinition\") | .contractKind' < ", + _getForgeArtifactPath(_name) + ); + bytes memory res = Process.run(cmd); + kind_ = string(res); + } + + /// @notice Returns whether or not a contract is proxied. + /// @param _name The name of the contract to check. + /// @return out_ Whether or not the contract is proxied. + function isProxiedContract(string memory _name) internal returns (bool out_) { + // TODO: Using the `@custom:proxied` tag is to determine if a contract is meant to be + // proxied is functional but developers can easily forget to add the tag when writing a new + // contract. We should consider determining whether a contract is proxied based on the + // deployment script since it's the source of truth for that. Current deployment script + // does not make this easy but an updated script should likely make this possible. + string[] memory cmd = new string[](3); + cmd[0] = Executables.bash; + cmd[1] = "-c"; + cmd[2] = string.concat( + Executables.jq, + " -r '.rawMetadata' ", + _getForgeArtifactPath(_name), + " | ", + Executables.jq, + " -r '.output.devdoc' | jq -r 'has(\"custom:proxied\")'" + ); + bytes memory res = Process.run(cmd); + out_ = stdJson.readBool(string(res), ""); + } + + /// @notice Returns whether or not a contract is predeployed. + /// @param _name The name of the contract to check. + /// @return out_ Whether or not the contract is predeployed. + function isPredeployedContract(string memory _name) internal returns (bool out_) { + // TODO: Similar to the above, using the `@custom:predeployed` tag is not reliable but + // functional for now. Deployment script should make this easier to determine. + string[] memory cmd = new string[](3); + cmd[0] = Executables.bash; + cmd[1] = "-c"; + cmd[2] = string.concat( + Executables.jq, + " -r '.rawMetadata' ", + _getForgeArtifactPath(_name), + " | ", + Executables.jq, + " -r '.output.devdoc' | jq -r 'has(\"custom:predeploy\")'" + ); + bytes memory res = Process.run(cmd); + out_ = stdJson.readBool(string(res), ""); + } + function _getForgeArtifactDirectory(string memory _name) internal returns (string memory dir_) { string[] memory cmd = new string[](3); cmd[0] = Executables.bash; @@ -128,6 +190,14 @@ library ForgeArtifacts { function getInitializedSlot(string memory _contractName) internal returns (StorageSlot memory slot_) { string memory storageLayout = getStorageLayout(_contractName); + // FaultDisputeGame and PermissionedDisputeGame use a different name for the initialized storage slot. + string memory slotName = "_initialized"; + string memory slotType = "t_uint8"; + if (LibString.eq(_contractName, "FaultDisputeGame") || LibString.eq(_contractName, "PermissionedDisputeGame")) { + slotName = "initialized"; + slotType = "t_bool"; + } + string[] memory command = new string[](3); command[0] = Executables.bash; command[1] = "-c"; @@ -138,7 +208,11 @@ library ForgeArtifacts { "'", " | ", Executables.jq, - " '.storage[] | select(.label == \"_initialized\" and .type == \"t_uint8\")'" + " '.storage[] | select(.label == \"", + slotName, + "\" and .type == \"", + slotType, + "\")'" ); bytes memory rawSlot = vm.parseJson(string(Process.run(command))); slot_ = abi.decode(rawSlot, (StorageSlot)); @@ -152,18 +226,21 @@ library ForgeArtifacts { initialized_ = uint8((uint256(slotVal) >> (slot.offset * 8)) & 0xFF) != 0; } - /// @notice Returns the function ABIs of all L1 contracts. - function getContractFunctionAbis( - string memory path, - string[] memory pathExcludes + /// @notice Returns the names of all contracts in a given directory. + /// @param _path The path to search for contracts. + /// @param _pathExcludes An array of paths to exclude from the search. + /// @return contractNames_ An array of contract names. + function getContractNames( + string memory _path, + string[] memory _pathExcludes ) internal - returns (Abi[] memory abis_) + returns (string[] memory contractNames_) { string memory pathExcludesPat; - for (uint256 i = 0; i < pathExcludes.length; i++) { - pathExcludesPat = string.concat(pathExcludesPat, " -path \"", pathExcludes[i], "\""); - if (i != pathExcludes.length - 1) { + for (uint256 i = 0; i < _pathExcludes.length; i++) { + pathExcludesPat = string.concat(pathExcludesPat, " -path \"", _pathExcludes[i], "\""); + if (i != _pathExcludes.length - 1) { pathExcludesPat = string.concat(pathExcludesPat, " -o "); } } @@ -174,7 +251,7 @@ library ForgeArtifacts { command[2] = string.concat( Executables.find, " ", - path, + _path, bytes(pathExcludesPat).length > 0 ? string.concat(" ! \\( ", pathExcludesPat, " \\)") : "", " -type f ", "-exec basename {} \\;", @@ -185,8 +262,19 @@ library ForgeArtifacts { Executables.jq, " -R -s 'split(\"\n\")[:-1]'" ); - string[] memory contractNames = abi.decode(vm.parseJson(string(Process.run(command))), (string[])); + contractNames_ = abi.decode(vm.parseJson(string(Process.run(command))), (string[])); + } + + /// @notice Returns the function ABIs of all L1 contracts. + function getContractFunctionAbis( + string memory path, + string[] memory pathExcludes + ) + internal + returns (Abi[] memory abis_) + { + string[] memory contractNames = getContractNames(path, pathExcludes); abis_ = new Abi[](contractNames.length); for (uint256 i; i < contractNames.length; i++) { diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 21f17a54a727..c6cd7a701729 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -1,127 +1,127 @@ { "src/EAS/EAS.sol": { - "initCodeHash": "0x1a097f352425b503a28c795dbfd390f2bc330e9c1f8a27bd26cf243b6c703499", - "sourceCodeHash": "0x23287e96b00c31ab57b05090525afdebf8e45ca09253a21b95052cf7d94e071b" + "initCodeHash": "0xf96d1ebc530ed95e2dffebcfa2b4a1f18103235e6352d97838b77b7a2c14567b", + "sourceCodeHash": "0xfaeb13f74d79a5fa8539ab3c9b8b8053b05cec78317aaf132bdeedb4018541cd" }, "src/EAS/SchemaRegistry.sol": { - "initCodeHash": "0xf4c3155413be4a4ebaaba66b9f9daaf12db7b090afdea739dfb8a543df357289", - "sourceCodeHash": "0x2ed7a2d6d66839fb3d207952f44b001bce349334adc40ce66d0503ce64e48548" + "initCodeHash": "0x06ae2c0b39c215b7fa450d382916ce6f5c6f9f2d630e572db6b72d688255b3fd", + "sourceCodeHash": "0x7e716bd2827a8f696c9345ec01ed037559447540771ffbcf3eba38f57b085a20" }, "src/L1/DataAvailabilityChallenge.sol": { - "initCodeHash": "0x9e9ac7238791b2eaade946e58b98f6f1f43f60b8b393664d85a553857a0ab5c7", - "sourceCodeHash": "0xf6c72a2cca24cfa7c9274d720e93b05d665a2751cca3d747105e6c511ccffc73" + "initCodeHash": "0xcc96cf2e4d841adb7ecb9dd84abeb0893dd62d913c0d47ab5b66a893c6e47e88", + "sourceCodeHash": "0x9d791696967f50c7a7b35b1fef3b00adaa61846623cc284e3a2b8599b77909ae" }, "src/L1/DelayedVetoable.sol": { "initCodeHash": "0x84f78e56211500a768b2c5bbafde8e7b411bd64c237297370d7d22326b68357c", "sourceCodeHash": "0xc59b8574531162e016d7342aeb6e79d05574e90dbea6c0e5ede35b65010ad894" }, "src/L1/L1CrossDomainMessenger.sol": { - "initCodeHash": "0x1f97347da46930d5b3cd40bd2699a6b78812e5f597793c8d59a90b0ef6800da8", - "sourceCodeHash": "0x56a2d3abed97eb7b292db758aac1e36fc08a12bfa44f7969824e26866a1417fa" + "initCodeHash": "0x48db42620b9f16e0dec2355f4076314f82fd0f60ef04c10cdbc266eac9472515", + "sourceCodeHash": "0xdfdbc9849a5147bb1f9ffd1d886fc0399016c3dccaabaa61fc6735c1b4af774b" }, "src/L1/L1ERC721Bridge.sol": { - "initCodeHash": "0xd56de5c193758c0c2ef3456ef9331fbcb56f7f6f4185d4a2ceeebf4f31512013", - "sourceCodeHash": "0xa8b7c9682717efbc27212ead24ba345253d18f2068126b905cc7515603288553" + "initCodeHash": "0xda80d225e332f9ab38d5f3ae655df3eea1dd56dbb523036a25c78859d2931ada", + "sourceCodeHash": "0xa4e78a2440fb560366e84e5f0ba59932ee564ff47ac3aa9a2c489fff4d6fd061" }, "src/L1/L1StandardBridge.sol": { - "initCodeHash": "0x508977d2517b49649bef57899e2c2519c271953708b2c84325377dae64a92baf", - "sourceCodeHash": "0x0d07e526c1891abb81c7e94f73642caa8ee386ab036b3b2a67f1b21ca85089c5" + "initCodeHash": "0x2868b09ecbe9f2bbc885605c2886b4c79f1c8e4171626c63776603b1b84698a8", + "sourceCodeHash": "0xfde1de7fa0f0d4840768abab775901c07e16ab59835a20e7a8ef512fa85acfcb" }, "src/L1/L2OutputOracle.sol": { - "initCodeHash": "0x14c3a582ca46ef2a6abad5590323f4de26ff4de54415c927c62e131ccbf8d9ba", - "sourceCodeHash": "0xf5fcf570721e25459fadbb37e02f9efe349e1c8afcbf1e3b5fdb09c9f612cdc0" + "initCodeHash": "0x433fac9de52d8ce8fc3471b78ef6cc9cff1019f480c9ad91b6e09ab8738a8edb", + "sourceCodeHash": "0xf0c0655221c36cfe918818ca300cca74a3713be3da090b2072eb81ba29c59e38" }, "src/L1/OPStackManager.sol": { - "initCodeHash": "0x1630942414d9711137028c48f37b6fcd7fbbedc147102e31ebcdcc03a9645c6a", - "sourceCodeHash": "0x8e9a47583c4c3d711c2b7cc5e0f86495e29d4e79c38415dd3d342e1d1aae4fb7" + "initCodeHash": "0x67bf02405bf1ca7d78c4215c350ad9c5c7b4cece35d9fab837f279d65f995c5d", + "sourceCodeHash": "0xf5db686a001aeb47cab09bb377ae226e872c806b4f5eff869d4dd6367f47c471" }, "src/L1/OptimismPortal.sol": { - "initCodeHash": "0xfdc8cf0b0b26961f6ac493ee564761716447d263291bea4d366a7b94afe33392", - "sourceCodeHash": "0x9fe0a9001edecd2a04daada4ca9e17d66141b1c982f73653493b4703d2c675c4" + "initCodeHash": "0x6bf59539298b20221de6c51db21016be8d3278bdbe0be1cdd49638dc828e003e", + "sourceCodeHash": "0x9ca40fb207eae615087f07041d4ce5349c74d7beebae1c74181c91a8631162bb" }, "src/L1/OptimismPortal2.sol": { - "initCodeHash": "0x12071439501e60420ab217cea4477306864014b66722d09b8cb8e01369f343ec", - "sourceCodeHash": "0xf597b9dcb97e733948a7179b8951dd46e4bb1ebc0715dd9440ffdabe0ecb0843" + "initCodeHash": "0x414ad1fdb6296ac32fc67ce01288b6e67bedd2ed239d7eb8ed40c7f55f9021f2", + "sourceCodeHash": "0x1af32dcddecb37ccc875edbc10203cac04319953de04bd3cba02a1740a6a0827" }, "src/L1/OptimismPortalInterop.sol": { - "initCodeHash": "0xa8ce00980799cb918b44fbbfdf4370a069d3bd15a92b2ed6850e98ebc0388b86", - "sourceCodeHash": "0xe3805faeb962594d5c2c18cdeb35c2db1248393650bec2ad5cadf41759f151f2" + "initCodeHash": "0x9222fba222d1ab66898eef09ecea3ea757e64c8ae98def4da7808cd7cc8f39a8", + "sourceCodeHash": "0x3fc9d9fc1143bec92801f8a18ad3527533923dc26c4820d03d6905f519d735b4" }, "src/L1/ProtocolVersions.sol": { - "initCodeHash": "0x72cd467e8bcf019c02675d72ab762e088bcc9cc0f1a4e9f587fa4589f7fdd1b8", - "sourceCodeHash": "0xbd56a23cd3221cb9d25029e80cd9f2afe2c615ae9c0b3956bf6ed373b8b805b6" + "initCodeHash": "0x8f033874dd8b36615b2209d553660dcff1ff91ca2bad3ca1de7b441dbfba4842", + "sourceCodeHash": "0xc823fcc6ddb4be71b5177b46748415fe5d54c2970696a00db896bec615b482d6" }, "src/L1/SuperchainConfig.sol": { - "initCodeHash": "0xa71c67640d6a25c750fef910a5fe85776ebb7bb18c677bb1b9b95c2f3f561b0c", - "sourceCodeHash": "0xd6a894e371c2c7182b5960c507491f81c3775dda0efedd29475f7c30ca07b004" + "initCodeHash": "0xfca12d9016c746e5c275b186e0ca40cfd65cf45a5665aab7589a669fea3abb47", + "sourceCodeHash": "0x4dc2a082013a7d7b76c74d15b4e9c755b0c99511ee3dd3cb4e42e9a269575135" }, "src/L1/SystemConfig.sol": { - "initCodeHash": "0x3324c93485f594bccb2af1a0c5a3551948ae9b347baea371764ce8fe239c39be", - "sourceCodeHash": "0xaed39fb8a0ce4b8d7a97ead42074e0c672fa18a58a57227b9d32abe2c3600223" + "initCodeHash": "0x2fc36af5b3c493a423a19e0b597f6ff230b756b861b68099f3192d69b6088dc0", + "sourceCodeHash": "0xd7b18e0acf8363edcffcf38cdfdc21b9a4b8eba4656b6c6524a4629bb09c9aef" }, "src/L1/SystemConfigInterop.sol": { - "initCodeHash": "0x42e1000d8542f9cbb197314d423760543d4d716d9640b2134c0d881557b22f4f", - "sourceCodeHash": "0xccb5b1ea5f1d5c4a583a2a6941db072fc3ad60ac3d08d085f17a672f6a7e2851" + "initCodeHash": "0xc5a3ffc59dd7bf1ef238087414cfa04b37f0d83fc9a4f5e6d62a1059a23359f3", + "sourceCodeHash": "0x71606c81ff4e69bac78d04731287c34dfb20a648ad384646926a62c16344e0d7" }, "src/L2/BaseFeeVault.sol": { - "initCodeHash": "0x623bf6892f0bdb536f2916bc9eb45e52012ad2c80893ff87d750757966b9be68", - "sourceCodeHash": "0x3a725791a0f5ed84dc46dcdae26f6170a759b2fe3dc360d704356d088b76cfd6" + "initCodeHash": "0x3bfcd57e25ad54b66c374f63e24e33a6cf107044aa8f5f69ef21202c380b5c5b", + "sourceCodeHash": "0x0861b8415b4657a3aee4ab5e019c42204730597ca2d6355f34e8cf7a76d3ce27" }, "src/L2/CrossL2Inbox.sol": { - "initCodeHash": "0x071b53cd8cf0503af856c4ee0ee34643e85059d53c096453891225472e02abfa", - "sourceCodeHash": "0xc3478a7036b8c58ed1a90ad90556a62c99a4abb124b0fa47f2edfca31eec680f" + "initCodeHash": "0x926ec5b92a5ff032c00ae13f1156332cb43b98b89573467e9ddfab6fce9f3e95", + "sourceCodeHash": "0xdb08fd714670d13c9c9a191f7ba07e9a208d94db379103c1f0f3812ed805f2cd" }, "src/L2/ETHLiquidity.sol": { "initCodeHash": "0x98177562fca0de0dfea5313c9acefe2fdbd73dee5ce6c1232055601f208f0177", "sourceCodeHash": "0x6dc23ceeed5a63fdc98ba8e5099df1822f3eeaa8c82afb1fa3235ff68a37b274" }, "src/L2/GasPriceOracle.sol": { - "initCodeHash": "0xb16f1e370e58c7693fd113a21a1b1e7ccebc03d4f1e5a76786fc27847ef51ead", - "sourceCodeHash": "0x5529ee28aae94904a1c08a8b188f51a39a0f51fbd3b43f1abd4fee7bba57998c" + "initCodeHash": "0xa1aae095643272e2dd08f8121dd4425cc8d4fd798cd39db63e4b957863efa8c1", + "sourceCodeHash": "0xa170fff280d94991082efffa40b6daa3dd9eff7fe6c5b1bc31e40bc128bff94e" }, "src/L2/L1Block.sol": { - "initCodeHash": "0xfd099da051edf13b147f4382ab4bed9db546d0c48157736ba298fb7e178b20d9", - "sourceCodeHash": "0x24db623574743432626ed0d7dd938bbd2149b570a00328c772debd7eb179ff1d" + "initCodeHash": "0xb12c0560e4e0aed12df5f65a1bc2b302afd183601c149285a26eafe5e4c20c0e", + "sourceCodeHash": "0x69c652c2920e6a6226f3f8f3e6ea3a977c7b15f9efb11916858613e8c8d6903b" }, "src/L2/L1BlockInterop.sol": { - "initCodeHash": "0x6833a323934b3be1e5a5c7491c652b6e90bc5102416ddbb255b5f65aa6d5d4a1", - "sourceCodeHash": "0xd8ec2f814690d1ffd55e5b8496bca5a179d6d1772d61f71cdf8296c9058dc2c6" + "initCodeHash": "0xd2afdf64b0232264e4996e0557523c108c2f12a9b6d2de45dfd961f7a1c927e3", + "sourceCodeHash": "0xfd2283b341239be76b0b8fa067e8ccdf71ef5b29eb75df6783d9f004a9203530" }, "src/L2/L1FeeVault.sol": { - "initCodeHash": "0x623bf6892f0bdb536f2916bc9eb45e52012ad2c80893ff87d750757966b9be68", - "sourceCodeHash": "0x29c64c43e3deedfa63572d36ce511febb99e500352a003242aed339716d3e3ce" + "initCodeHash": "0x3bfcd57e25ad54b66c374f63e24e33a6cf107044aa8f5f69ef21202c380b5c5b", + "sourceCodeHash": "0x35dc3bb4ab3d02cf9c1e12b0f6796d7eda9d314598bfdecab2812fe9159f443c" }, "src/L2/L2CrossDomainMessenger.sol": { - "initCodeHash": "0xad95e4e98adf35ea2baeb15348d751fc76e1bb0d001474d4eaefba47f7aeaf5f", - "sourceCodeHash": "0x440d299b7429c44f6faa4005b33428f9edc1283027d9c78a63eb3d76452bfa47" + "initCodeHash": "0xe7090ce8119fe373d930baa68c1df585953b7f6e8beea2a0084589d394bcab64", + "sourceCodeHash": "0x22033cd1923c9d52d9520de773b332ae179528065e4b8f5e37a9aaf59d140735" }, "src/L2/L2ERC721Bridge.sol": { - "initCodeHash": "0x72443939e0218f1faca4cabe957a77bb232db726d74d422bda15d1cb26857735", - "sourceCodeHash": "0xb0806d362ba5cc39acfb09e0606059a2b10a7c1d5bc1f86cd4561fd24f7dcada" + "initCodeHash": "0x827077e1a0ce6c8f9ee1196c409ea77d831efd440992b3969b05259083cdf0bd", + "sourceCodeHash": "0xd3c25187a46c7f42dfbbcb54e45b11101acc99c014e013ef8e5b9e868220f525" }, "src/L2/L2StandardBridge.sol": { - "initCodeHash": "0xfbfc7bd101022024b94114c26128c6028c25dec07e8d40fdcfdb180c0ba6ddee", - "sourceCodeHash": "0xb1a5fb22b124e8fa8eb5bae4b8e0770abbdbebe32be00480317cf4aaada28ed3" + "initCodeHash": "0x01692b613e3d4e649d877a0fd8f0798a26401ba8ccc4cda0e61f1f9079729320", + "sourceCodeHash": "0x09cf9e0d84c8d29fbf9c3288a38807edcd7c456427e222e1fd1f7aa4dbf73352" }, "src/L2/L2StandardBridgeInterop.sol": { - "initCodeHash": "0xd7f85eef12b60211104cddbd86d9f458cd31a0ba74f382404799bcf86ef003ba", - "sourceCodeHash": "0x00f415380689a5ee1762e93b032d5c3de2fcddb36b0a068cb5616f7e8001ddc0" + "initCodeHash": "0x5c9ef6b0817f715d1b8b097f3fc19e33bc54453426ca12bb48e4cea143076339", + "sourceCodeHash": "0xd28d1a4bf6c66fa26f180988b26ea564afa024f8181eca6c23e5dc5dfd5757cd" }, "src/L2/L2ToL1MessagePasser.sol": { - "initCodeHash": "0x08bbede75cd6dfd076903b8f04d24f82fa7881576c135825098778632e37eebc", - "sourceCodeHash": "0x8388b9b8075f31d580fed815b66b45394e40fb1a63cd8cda2272d2c390fc908c" + "initCodeHash": "0x13fe3729beb9ed966c97bef09acb9fe5043fe651d453145073d05f2567fa988d", + "sourceCodeHash": "0xe4e768c5f60111188979a334b684a4d9c9267375cfa991897432b5a415bea516" }, "src/L2/L2ToL2CrossDomainMessenger.sol": { - "initCodeHash": "0x3a18ecd5415ddcb7c26023f29f3acb3bc4e8a261091c3bc529b8b4d497b92469", - "sourceCodeHash": "0x972564d2e2fab111cd431f3c78d00c7b0f0ae422fa5e9a8bf5b202cdaef89bf9" + "initCodeHash": "0x3e4337542234c732a55e60fc20dcb1ad639ff2fb378e3f29e94b4059df9a637b", + "sourceCodeHash": "0x5d266f4f380cee7a267f000af16ed2fb9399fda773a7e4543d3dc1c9df982a65" }, "src/L2/OptimismSuperchainERC20.sol": { - "initCodeHash": "0xd49214518ea1a30a43fac09f28b2cee9be570894a500cef342762c9820a070b0", - "sourceCodeHash": "0x6943d40010dcbd1d51dc3668d0a154fbb1568ea49ebcf3aa039d65ef6eab321b" + "initCodeHash": "0xdd16dbc0ccbbac53ec2d4273f06334960a907a9f20b7c40300833227ee31d0de", + "sourceCodeHash": "0x8566ff63d42f48ddae977c436dae4773e43f2223800c6a0eb9e4c6cf95b19d77" }, "src/L2/SequencerFeeVault.sol": { - "initCodeHash": "0xb94145f571e92ee615c6fe903b6568e8aac5fe760b6b65148ffc45d2fb0f5433", - "sourceCodeHash": "0x8f2a54104e5e7105ba03ba37e3ef9b6684a447245f0e0b787ba4cca12957b97c" + "initCodeHash": "0x2e6551705e493bacba8cffe22e564d5c401ae5bb02577a5424e0d32784e13e74", + "sourceCodeHash": "0x846ff8fcc1091aa262cda06f93a6e1a57ae885206fe124bcf23550436a16597e" }, "src/L2/SuperchainWETH.sol": { "initCodeHash": "0x599e948350c70d699f8a8be945abffd126097de97fade056d29767128320fe75", @@ -156,32 +156,32 @@ "sourceCodeHash": "0x0a3cd959b361f1da998365da8b3c14362007d73b36196cced0606a9f082e63a8" }, "src/dispute/AnchorStateRegistry.sol": { - "initCodeHash": "0x544f0398155e958b0de59f9448801e75c66042c95a7892e2264c015973be8bec", - "sourceCodeHash": "0x65944da862332e493bffd712648511041d4adff00e24cc0e539b9dd0ef013ba0" + "initCodeHash": "0x6198f305686e6fdfd94db7aeb840a12e263036dcdc234550db49d3f0b87039a8", + "sourceCodeHash": "0x178e5c971252a9eb4b5c3fb28be1e15911c0b5aa6d27c852b73777877475f046" }, "src/dispute/DisputeGameFactory.sol": { - "initCodeHash": "0x7a7cb8f2c95df2f9afb3ce9eaefe4a6f997ccce7ed8ffda5d425a65a2474a792", - "sourceCodeHash": "0x918c395ac5d77357f2551616aad0613e68893862edd14e554623eb16ee6ba148" + "initCodeHash": "0xc1a10f65287c414076b68a7de6c238b91bc6252213187bdef35657d0f00f9382", + "sourceCodeHash": "0x5a31133388bbb0d3621993b72a5a292108f99299f9cad8bc8e709b13e1ae0bc2" }, "src/dispute/FaultDisputeGame.sol": { "initCodeHash": "0x8705f00408ff4405723bf59e2dce61a90aa49d8094da1c96a3652a2ebb169519", "sourceCodeHash": "0x3df123ab9a19f7c097510afb191099e7c3098ab892111a13c8f061ab0f0e57a0" }, "src/dispute/weth/DelayedWETH.sol": { - "initCodeHash": "0xdad40c84fe75a0f112c219bcc9553e325bacc8e11860f692353ea3ff110fd7cc", - "sourceCodeHash": "0xb1e22abf844715243a065ead50cab02e53303c5464b2857a8ee667f8d49d4d12" + "initCodeHash": "0x3e687c928b6c890b91c82584ccb1fec47b025b8e58cd9cbfa65229b38b304bae", + "sourceCodeHash": "0x7bec41daedccca173b93974f90ff2b345ac87305b29e242a386f7605b1208df9" }, "src/legacy/DeployerWhitelist.sol": { - "initCodeHash": "0x8de80fb23b26dd9d849f6328e56ea7c173cd9e9ce1f05c9beea559d1720deb3d", - "sourceCodeHash": "0xb518a9f56136a910f2450098b4823c9982f93883fe4a9ef6f6b0a89355965d38" + "initCodeHash": "0x0b8177ed75b69eddbb9ce6537683f69a9935efed86a1d6faa8feaafbd151c1bd", + "sourceCodeHash": "0xaf70fdfbe98a5794cc83c2baa0ef4346592c67ffade186852030010827c2d2d2" }, "src/legacy/L1BlockNumber.sol": { - "initCodeHash": "0xd586c4f93caf1753e53fcdc05eb547c1f3a69afda2904ae9f9d851b73e1c9c1d", - "sourceCodeHash": "0xed7d0d1695f28bf967626ee58debcf235204ecc5e814f53da369c94a9ed7cf0d" + "initCodeHash": "0xfc43380228388659578368ec31b4581404ad3f3d30f3fcedccd461b1feaeebb4", + "sourceCodeHash": "0x20c8f204aa7bcdf88c48d3f067c4c4c8e8c827e0ba7b7c4a21e6f8d8225561f5" }, "src/legacy/LegacyMessagePasser.sol": { - "initCodeHash": "0x024ff54be1762f8946c6dc1796517bd5e622349a26a908f78a31872969f10369", - "sourceCodeHash": "0x31f66f771d912ed4fe06c166f4b1c44d9f2bce8537ab42271c3900360966999f" + "initCodeHash": "0xefc6ed9e325c2d614ea0d28c3eabfff1b345f7c6054e90253c6a091c29508267", + "sourceCodeHash": "0x6ccc02c966d1548c38754f665e650763fe8e17326e76b5438398680937e37f8f" }, "src/periphery/op-nft/AttestationStation.sol": { "initCodeHash": "0xf9b8ff2ecdcaca2b1521a96f0ebaea2d77aeb986ff1b9b7d82fb0cbc63f9169a", @@ -204,8 +204,8 @@ "sourceCodeHash": "0x52737b23e99bf79dd2c23196b3298e80aa41f740efc6adc7916e696833eb546a" }, "src/universal/OptimismMintableERC20Factory.sol": { - "initCodeHash": "0x29a49fc387ad84f82199947e49a0d1960902f63492d974c26afd72372e748648", - "sourceCodeHash": "0xbc6cf74368c244bdea8ed64c501129d0b6d41db421dc91d1de051f7b505a4977" + "initCodeHash": "0x66df8ec6699dbedc70da57358ec6031d1d90b3d6672990380f4eb3dbd9cf5385", + "sourceCodeHash": "0x1fc420719e4a6bc1f53dfc4a0ddaa14f129c16c0e99f98f253a2e3c85b72a540" }, "src/universal/OptimismMintableERC721.sol": { "initCodeHash": "0xb400f430acf4d65bee9635e4935a6e1e3a0284fc50aea40ad8b7818dc826f31c", diff --git a/packages/contracts-bedrock/src/EAS/EAS.sol b/packages/contracts-bedrock/src/EAS/EAS.sol index f4872eeed26e..5307199be3b4 100644 --- a/packages/contracts-bedrock/src/EAS/EAS.sol +++ b/packages/contracts-bedrock/src/EAS/EAS.sol @@ -40,7 +40,7 @@ struct AttestationsResult { bytes32[] uids; // UIDs of the new attestations. } -/// @custom:proxied +/// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000021 /// @title EAS /// @notice The Ethereum Attestation Service protocol. @@ -80,8 +80,8 @@ contract EAS is IEAS, ISemver, EIP1271Verifier { uint256[MAX_GAP - 3] private __gap; /// @notice Semantic version. - /// @custom:semver 1.4.0 - string public constant version = "1.4.0"; + /// @custom:semver 1.4.1-beta.1 + string public constant version = "1.4.1-beta.1"; /// @dev Creates a new EAS instance. constructor() EIP1271Verifier("EAS", "1.3.0") { } diff --git a/packages/contracts-bedrock/src/EAS/SchemaRegistry.sol b/packages/contracts-bedrock/src/EAS/SchemaRegistry.sol index e6f5ee3c4d90..1a1d7c44553e 100644 --- a/packages/contracts-bedrock/src/EAS/SchemaRegistry.sol +++ b/packages/contracts-bedrock/src/EAS/SchemaRegistry.sol @@ -6,7 +6,7 @@ import { ISchemaResolver } from "src/EAS/resolver/ISchemaResolver.sol"; import { EMPTY_UID, MAX_GAP } from "src/EAS/Common.sol"; import { ISchemaRegistry, SchemaRecord } from "src/EAS/ISchemaRegistry.sol"; -/// @custom:proxied +/// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000020 /// @title SchemaRegistry /// @notice The global attestation schemas for the Ethereum Attestation Service protocol. @@ -20,8 +20,8 @@ contract SchemaRegistry is ISchemaRegistry, ISemver { uint256[MAX_GAP - 1] private __gap; /// @notice Semantic version. - /// @custom:semver 1.3.0 - string public constant version = "1.3.0"; + /// @custom:semver 1.3.1-beta.1 + string public constant version = "1.3.1-beta.1"; /// @inheritdoc ISchemaRegistry function register(string calldata schema, ISchemaResolver resolver, bool revocable) external returns (bytes32) { diff --git a/packages/contracts-bedrock/src/L1/DataAvailabilityChallenge.sol b/packages/contracts-bedrock/src/L1/DataAvailabilityChallenge.sol index 84ba91b8fa98..ef4f473bc6a3 100644 --- a/packages/contracts-bedrock/src/L1/DataAvailabilityChallenge.sol +++ b/packages/contracts-bedrock/src/L1/DataAvailabilityChallenge.sol @@ -29,6 +29,7 @@ struct Challenge { uint256 resolvedBlock; } +/// @custom:proxied true /// @title DataAvailabilityChallenge /// @notice This contract enables data availability of a data commitment at a given block number to be challenged. /// To challenge a commitment, the challenger must first post a bond (bondSize). @@ -88,8 +89,8 @@ contract DataAvailabilityChallenge is OwnableUpgradeable, ISemver { event BalanceChanged(address account, uint256 balance); /// @notice Semantic version. - /// @custom:semver 1.0.0 - string public constant version = "1.0.0"; + /// @custom:semver 1.0.1-beta.1 + string public constant version = "1.0.1-beta.1"; /// @notice The fixed cost of resolving a challenge. /// @dev The value is estimated by measuring the cost of resolving with `bytes(0)` diff --git a/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol index 4aaf2bd31156..8ed2cde08f36 100644 --- a/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol +++ b/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol @@ -8,7 +8,7 @@ import { ISemver } from "src/universal/ISemver.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; -/// @custom:proxied +/// @custom:proxied true /// @title L1CrossDomainMessenger /// @notice The L1CrossDomainMessenger is a message passing interface between L1 and L2 responsible /// for sending and receiving data on the L1 side. Users are encouraged to use this @@ -25,8 +25,8 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver { SystemConfig public systemConfig; /// @notice Semantic version. - /// @custom:semver 2.4.0 - string public constant version = "2.4.0"; + /// @custom:semver 2.4.1-beta.1 + string public constant version = "2.4.1-beta.1"; /// @notice Constructs the L1CrossDomainMessenger contract. constructor() CrossDomainMessenger() { diff --git a/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol b/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol index 75547cb5edc5..c080a67205dd 100644 --- a/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol +++ b/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol @@ -11,6 +11,7 @@ import { StandardBridge } from "src/universal/StandardBridge.sol"; import { Constants } from "src/libraries/Constants.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +/// @custom:proxied true /// @title L1ERC721Bridge /// @notice The L1 ERC721 bridge is a contract which works together with the L2 ERC721 bridge to /// make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract @@ -24,8 +25,8 @@ contract L1ERC721Bridge is ERC721Bridge, ISemver { SuperchainConfig public superchainConfig; /// @notice Semantic version. - /// @custom:semver 2.1.1+beta.1 - string public constant version = "2.1.1+beta.1"; + /// @custom:semver 2.1.1-beta.2 + string public constant version = "2.1.1-beta.2"; /// @notice Constructs the L1ERC721Bridge contract. constructor() ERC721Bridge() { diff --git a/packages/contracts-bedrock/src/L1/L1StandardBridge.sol b/packages/contracts-bedrock/src/L1/L1StandardBridge.sol index 757c140c56e4..9b5610cf3a1d 100644 --- a/packages/contracts-bedrock/src/L1/L1StandardBridge.sol +++ b/packages/contracts-bedrock/src/L1/L1StandardBridge.sol @@ -9,7 +9,7 @@ import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; -/// @custom:proxied +/// @custom:proxied true /// @title L1StandardBridge /// @notice The L1StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and /// L2. In the case that an ERC20 token is native to L1, it will be escrowed within this @@ -71,8 +71,8 @@ contract L1StandardBridge is StandardBridge, ISemver { ); /// @notice Semantic version. - /// @custom:semver 2.2.0 - string public constant version = "2.2.0"; + /// @custom:semver 2.2.1-beta.1 + string public constant version = "2.2.1-beta.1"; /// @notice Address of the SuperchainConfig contract. SuperchainConfig public superchainConfig; diff --git a/packages/contracts-bedrock/src/L1/L2OutputOracle.sol b/packages/contracts-bedrock/src/L1/L2OutputOracle.sol index fe2c7dd7c8ef..d329ff3eb1c9 100644 --- a/packages/contracts-bedrock/src/L1/L2OutputOracle.sol +++ b/packages/contracts-bedrock/src/L1/L2OutputOracle.sol @@ -6,7 +6,7 @@ import { ISemver } from "src/universal/ISemver.sol"; import { Types } from "src/libraries/Types.sol"; import { Constants } from "src/libraries/Constants.sol"; -/// @custom:proxied +/// @custom:proxied true /// @title L2OutputOracle /// @notice The L2OutputOracle contains an array of L2 state outputs, where each output is a /// commitment to the state of the L2 chain. Other contracts like the OptimismPortal use @@ -56,8 +56,8 @@ contract L2OutputOracle is Initializable, ISemver { event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex); /// @notice Semantic version. - /// @custom:semver 1.8.0 - string public constant version = "1.8.0"; + /// @custom:semver 1.8.1-beta.1 + string public constant version = "1.8.1-beta.1"; /// @notice Constructs the L2OutputOracle contract. Initializes variables to the same values as /// in the getting-started config. diff --git a/packages/contracts-bedrock/src/L1/OPStackManager.sol b/packages/contracts-bedrock/src/L1/OPStackManager.sol index ce0cb109777b..b7da7bb358fb 100644 --- a/packages/contracts-bedrock/src/L1/OPStackManager.sol +++ b/packages/contracts-bedrock/src/L1/OPStackManager.sol @@ -4,10 +4,10 @@ pragma solidity 0.8.15; import { ISemver } from "src/universal/ISemver.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; -/// @custom:proxied +/// @custom:proxied true contract OPStackManager is ISemver { - /// @custom:semver 1.0.0-beta.1 - string public constant version = "1.0.0-beta.1"; + /// @custom:semver 1.0.0-beta.2 + string public constant version = "1.0.0-beta.2"; /// @notice Represents the roles that can be set when deploying a standard OP Stack chain. struct Roles { diff --git a/packages/contracts-bedrock/src/L1/OptimismPortal.sol b/packages/contracts-bedrock/src/L1/OptimismPortal.sol index 38c638aa8e48..b7515eed00cf 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortal.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortal.sol @@ -19,7 +19,7 @@ import { L1Block } from "src/L2/L1Block.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import "src/libraries/PortalErrors.sol"; -/// @custom:proxied +/// @custom:proxied true /// @title OptimismPortal /// @notice The OptimismPortal is a low-level contract responsible for passing messages between L1 /// and L2. Messages sent directly to the OptimismPortal have no form of replayability. @@ -128,9 +128,9 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver { } /// @notice Semantic version. - /// @custom:semver 2.8.1-beta.1 + /// @custom:semver 2.8.1-beta.2 function version() public pure virtual returns (string memory) { - return "2.8.1-beta.1"; + return "2.8.1-beta.2"; } /// @notice Constructs the OptimismPortal contract. diff --git a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol index 3643ecbaa24e..dda3df0d7400 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol @@ -22,7 +22,7 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; import "src/libraries/PortalErrors.sol"; import "src/dispute/lib/Types.sol"; -/// @custom:proxied +/// @custom:proxied true /// @title OptimismPortal2 /// @notice The OptimismPortal is a low-level contract responsible for passing messages between L1 /// and L2. Messages sent directly to the OptimismPortal have no form of replayability. @@ -153,9 +153,9 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { } /// @notice Semantic version. - /// @custom:semver 3.11.0-beta.2 + /// @custom:semver 3.11.0-beta.3 function version() public pure virtual returns (string memory) { - return "3.11.0-beta.2"; + return "3.11.0-beta.3"; } /// @notice Constructs the OptimismPortal contract. diff --git a/packages/contracts-bedrock/src/L1/OptimismPortalInterop.sol b/packages/contracts-bedrock/src/L1/OptimismPortalInterop.sol index 9fad94a0916f..b22b7092a73f 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortalInterop.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortalInterop.sol @@ -6,7 +6,7 @@ import { L1BlockInterop, ConfigType } from "src/L2/L1BlockInterop.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { Constants } from "src/libraries/Constants.sol"; -/// @custom:proxied +/// @custom:proxied true /// @title OptimismPortalInterop /// @notice The OptimismPortal is a low-level contract responsible for passing messages between L1 /// and L2. Messages sent directly to the OptimismPortal have no form of replayability. diff --git a/packages/contracts-bedrock/src/L1/ProtocolVersions.sol b/packages/contracts-bedrock/src/L1/ProtocolVersions.sol index d3f06b27730b..d6976b911d24 100644 --- a/packages/contracts-bedrock/src/L1/ProtocolVersions.sol +++ b/packages/contracts-bedrock/src/L1/ProtocolVersions.sol @@ -9,6 +9,7 @@ import { Constants } from "src/libraries/Constants.sol"; /// @notice ProtocolVersion is a numeric identifier of the protocol version. type ProtocolVersion is uint256; +/// @custom:proxied true /// @title ProtocolVersions /// @notice The ProtocolVersions contract is used to manage superchain protocol version information. contract ProtocolVersions is OwnableUpgradeable, ISemver { @@ -36,8 +37,8 @@ contract ProtocolVersions is OwnableUpgradeable, ISemver { event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data); /// @notice Semantic version. - /// @custom:semver 1.0.0 - string public constant version = "1.0.0"; + /// @custom:semver 1.0.1-beta.1 + string public constant version = "1.0.1-beta.1"; /// @notice Constructs the ProtocolVersion contract. Cannot set /// the owner to `address(0)` due to the Ownable contract's diff --git a/packages/contracts-bedrock/src/L1/SuperchainConfig.sol b/packages/contracts-bedrock/src/L1/SuperchainConfig.sol index 954e1b5df3c7..cae10b331f6c 100644 --- a/packages/contracts-bedrock/src/L1/SuperchainConfig.sol +++ b/packages/contracts-bedrock/src/L1/SuperchainConfig.sol @@ -5,6 +5,7 @@ import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable import { ISemver } from "src/universal/ISemver.sol"; import { Storage } from "src/libraries/Storage.sol"; +/// @custom:proxied true /// @custom:audit none This contracts is not yet audited. /// @title SuperchainConfig /// @notice The SuperchainConfig contract is used to manage configuration of global superchain values. @@ -35,8 +36,8 @@ contract SuperchainConfig is Initializable, ISemver { event ConfigUpdate(UpdateType indexed updateType, bytes data); /// @notice Semantic version. - /// @custom:semver 1.1.0 - string public constant version = "1.1.0"; + /// @custom:semver 1.1.1-beta.1 + string public constant version = "1.1.1-beta.1"; /// @notice Constructs the SuperchainConfig contract. constructor() { diff --git a/packages/contracts-bedrock/src/L1/SystemConfig.sol b/packages/contracts-bedrock/src/L1/SystemConfig.sol index 3d00077527a8..892d5dd2c2ab 100644 --- a/packages/contracts-bedrock/src/L1/SystemConfig.sol +++ b/packages/contracts-bedrock/src/L1/SystemConfig.sol @@ -10,6 +10,7 @@ import { OptimismPortal } from "src/L1/OptimismPortal.sol"; import { GasPayingToken, IGasToken } from "src/libraries/GasPayingToken.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +/// @custom:proxied true /// @title SystemConfig /// @notice The SystemConfig contract is used to manage configuration of an Optimism network. /// All configuration is stored on L1 and picked up by L2 as part of the derviation of @@ -124,9 +125,9 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data); /// @notice Semantic version. - /// @custom:semver 2.3.0-beta.2 + /// @custom:semver 2.3.0-beta.3 function version() public pure virtual returns (string memory) { - return "2.3.0-beta.2"; + return "2.3.0-beta.3"; } /// @notice Constructs the SystemConfig contract. Cannot set diff --git a/packages/contracts-bedrock/src/L1/SystemConfigInterop.sol b/packages/contracts-bedrock/src/L1/SystemConfigInterop.sol index 098b59e1f9f7..39f1f35ca6e8 100644 --- a/packages/contracts-bedrock/src/L1/SystemConfigInterop.sol +++ b/packages/contracts-bedrock/src/L1/SystemConfigInterop.sol @@ -11,6 +11,7 @@ import { StaticConfig } from "src/libraries/StaticConfig.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { Storage } from "src/libraries/Storage.sol"; +/// @custom:proxied true /// @title SystemConfigInterop /// @notice The SystemConfig contract is used to manage configuration of an Optimism network. /// All configuration is stored on L1 and picked up by L2 as part of the derviation of diff --git a/packages/contracts-bedrock/src/L2/BaseFeeVault.sol b/packages/contracts-bedrock/src/L2/BaseFeeVault.sol index ea07fd4ef3be..f423cbe58dfe 100644 --- a/packages/contracts-bedrock/src/L2/BaseFeeVault.sol +++ b/packages/contracts-bedrock/src/L2/BaseFeeVault.sol @@ -4,14 +4,14 @@ pragma solidity 0.8.15; import { ISemver } from "src/universal/ISemver.sol"; import { FeeVault } from "src/universal/FeeVault.sol"; -/// @custom:proxied +/// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000019 /// @title BaseFeeVault /// @notice The BaseFeeVault accumulates the base fee that is paid by transactions. contract BaseFeeVault is FeeVault, ISemver { /// @notice Semantic version. - /// @custom:semver 1.5.0-beta.1 - string public constant version = "1.5.0-beta.1"; + /// @custom:semver 1.5.0-beta.2 + string public constant version = "1.5.0-beta.2"; /// @notice Constructs the BaseFeeVault contract. /// @param _recipient Wallet that will receive the fees. diff --git a/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol b/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol index da1ab5e056d9..3c5a9a814e67 100644 --- a/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol +++ b/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol @@ -26,7 +26,7 @@ error InvalidChainId(); /// @notice Thrown when trying to execute a cross chain message and the target call fails. error TargetCallFailed(); -/// @custom:proxied +/// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000022 /// @title CrossL2Inbox /// @notice The CrossL2Inbox is responsible for executing a cross chain message on the destination @@ -61,8 +61,8 @@ contract CrossL2Inbox is ICrossL2Inbox, ISemver, TransientReentrancyAware { address internal constant DEPOSITOR_ACCOUNT = 0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001; /// @notice Semantic version. - /// @custom:semver 1.0.0-beta.5 - string public constant version = "1.0.0-beta.5"; + /// @custom:semver 1.0.0-beta.6 + string public constant version = "1.0.0-beta.6"; /// @notice Emitted when a cross chain message is being executed. /// @param msgHash Hash of message payload being executed. diff --git a/packages/contracts-bedrock/src/L2/GasPriceOracle.sol b/packages/contracts-bedrock/src/L2/GasPriceOracle.sol index 79c3eb431503..8a2c20a5c325 100644 --- a/packages/contracts-bedrock/src/L2/GasPriceOracle.sol +++ b/packages/contracts-bedrock/src/L2/GasPriceOracle.sol @@ -7,7 +7,7 @@ import { L1Block } from "src/L2/L1Block.sol"; import { Constants } from "src/libraries/Constants.sol"; import { LibZip } from "@solady/utils/LibZip.sol"; -/// @custom:proxied +/// @custom:proxied true /// @custom:predeploy 0x420000000000000000000000000000000000000F /// @title GasPriceOracle /// @notice This contract maintains the variables responsible for computing the L1 portion of the @@ -26,8 +26,8 @@ contract GasPriceOracle is ISemver { uint256 public constant DECIMALS = 6; /// @notice Semantic version. - /// @custom:semver 1.3.0 - string public constant version = "1.3.0"; + /// @custom:semver 1.3.1-beta.1 + string public constant version = "1.3.1-beta.1"; /// @notice This is the intercept value for the linear regression used to estimate the final size of the /// compressed transaction. diff --git a/packages/contracts-bedrock/src/L2/L1Block.sol b/packages/contracts-bedrock/src/L2/L1Block.sol index 8cfbb391f0f5..16e2f6b26746 100644 --- a/packages/contracts-bedrock/src/L2/L1Block.sol +++ b/packages/contracts-bedrock/src/L2/L1Block.sol @@ -6,7 +6,7 @@ import { Constants } from "src/libraries/Constants.sol"; import { GasPayingToken, IGasToken } from "src/libraries/GasPayingToken.sol"; import "src/libraries/L1BlockErrors.sol"; -/// @custom:proxied +/// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000015 /// @title L1Block /// @notice The L1Block predeploy gives users access to information about the last known L1 block. @@ -57,9 +57,9 @@ contract L1Block is ISemver, IGasToken { /// @notice The latest L1 blob base fee. uint256 public blobBaseFee; - /// @custom:semver 1.4.1-beta.1 + /// @custom:semver 1.4.1-beta.2 function version() public pure virtual returns (string memory) { - return "1.4.1-beta.1"; + return "1.4.1-beta.2"; } /// @notice Returns the gas paying token, its decimals, name and symbol. diff --git a/packages/contracts-bedrock/src/L2/L1BlockInterop.sol b/packages/contracts-bedrock/src/L2/L1BlockInterop.sol index 8dbf986fb7e6..4b445e6d566c 100644 --- a/packages/contracts-bedrock/src/L2/L1BlockInterop.sol +++ b/packages/contracts-bedrock/src/L2/L1BlockInterop.sol @@ -17,7 +17,7 @@ enum ConfigType { REMOVE_DEPENDENCY } -/// @custom:proxied +/// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000015 /// @title L1BlockInterop /// @notice Interop extenstions of L1Block. diff --git a/packages/contracts-bedrock/src/L2/L1FeeVault.sol b/packages/contracts-bedrock/src/L2/L1FeeVault.sol index b8445dac5f4c..c8beba84afa1 100644 --- a/packages/contracts-bedrock/src/L2/L1FeeVault.sol +++ b/packages/contracts-bedrock/src/L2/L1FeeVault.sol @@ -4,14 +4,14 @@ pragma solidity 0.8.15; import { ISemver } from "src/universal/ISemver.sol"; import { FeeVault } from "src/universal/FeeVault.sol"; -/// @custom:proxied +/// @custom:proxied true /// @custom:predeploy 0x420000000000000000000000000000000000001A /// @title L1FeeVault /// @notice The L1FeeVault accumulates the L1 portion of the transaction fees. contract L1FeeVault is FeeVault, ISemver { /// @notice Semantic version. - /// @custom:semver 1.5.0-beta.1 - string public constant version = "1.5.0-beta.1"; + /// @custom:semver 1.5.0-beta.2 + string public constant version = "1.5.0-beta.2"; /// @notice Constructs the L1FeeVault contract. /// @param _recipient Wallet that will receive the fees. diff --git a/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol index d504b2d40d32..b3e25c763343 100644 --- a/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol +++ b/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol @@ -10,15 +10,15 @@ import { Constants } from "src/libraries/Constants.sol"; import { L1Block } from "src/L2/L1Block.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; -/// @custom:proxied +/// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000007 /// @title L2CrossDomainMessenger /// @notice The L2CrossDomainMessenger is a high-level interface for message passing between L1 and /// L2 on the L2 side. Users are generally encouraged to use this contract instead of lower /// level message passing contracts. contract L2CrossDomainMessenger is CrossDomainMessenger, ISemver { - /// @custom:semver 2.1.0 - string public constant version = "2.1.0"; + /// @custom:semver 2.1.1-beta.1 + string public constant version = "2.1.1-beta.1"; /// @notice Constructs the L2CrossDomainMessenger contract. constructor() CrossDomainMessenger() { diff --git a/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol b/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol index b0d5522fcc71..1a1c9fd0f4e8 100644 --- a/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol +++ b/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol @@ -10,6 +10,8 @@ import { ISemver } from "src/universal/ISemver.sol"; import { Constants } from "src/libraries/Constants.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; +/// @custom:proxied true +/// @custom:predeploy 0x4200000000000000000000000000000000000014 /// @title L2ERC721Bridge /// @notice The L2 ERC721 bridge is a contract which works together with the L1 ERC721 bridge to /// make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract @@ -20,8 +22,8 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; /// wait for the one-week challenge period to elapse before their Optimism-native NFT /// can be refunded on L2. contract L2ERC721Bridge is ERC721Bridge, ISemver { - /// @custom:semver 1.7.1+beta.1 - string public constant version = "1.7.1+beta.1"; + /// @custom:semver 1.7.1-beta.2 + string public constant version = "1.7.1-beta.2"; /// @notice Constructs the L2ERC721Bridge contract. constructor() ERC721Bridge() { diff --git a/packages/contracts-bedrock/src/L2/L2StandardBridge.sol b/packages/contracts-bedrock/src/L2/L2StandardBridge.sol index b11314bcc626..55ffc3d541fe 100644 --- a/packages/contracts-bedrock/src/L2/L2StandardBridge.sol +++ b/packages/contracts-bedrock/src/L2/L2StandardBridge.sol @@ -8,7 +8,7 @@ import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { L1Block } from "src/L2/L1Block.sol"; -/// @custom:proxied +/// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000010 /// @title L2StandardBridge /// @notice The L2StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and @@ -53,9 +53,9 @@ contract L2StandardBridge is StandardBridge, ISemver { ); /// @notice Semantic version. - /// @custom:semver 1.11.0 + /// @custom:semver 1.11.1-beta.1 function version() public pure virtual returns (string memory) { - return "1.11.0"; + return "1.11.1-beta.1"; } /// @notice Constructs the L2StandardBridge contract. diff --git a/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol b/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol index 818ee0f9a741..2aad93a67e6c 100644 --- a/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol +++ b/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol @@ -27,7 +27,7 @@ interface MintableAndBurnable is IERC20 { function burn(address, uint256) external; } -/// @custom:proxied +/// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000010 /// @title L2StandardBridgeInterop /// @notice The L2StandardBridgeInterop is an extension of the L2StandardBridge that allows for diff --git a/packages/contracts-bedrock/src/L2/L2ToL1MessagePasser.sol b/packages/contracts-bedrock/src/L2/L2ToL1MessagePasser.sol index 8c764e999271..460b66ebc051 100644 --- a/packages/contracts-bedrock/src/L2/L2ToL1MessagePasser.sol +++ b/packages/contracts-bedrock/src/L2/L2ToL1MessagePasser.sol @@ -7,7 +7,7 @@ import { Encoding } from "src/libraries/Encoding.sol"; import { Burn } from "src/libraries/Burn.sol"; import { ISemver } from "src/universal/ISemver.sol"; -/// @custom:proxied +/// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000016 /// @title L2ToL1MessagePasser /// @notice The L2ToL1MessagePasser is a dedicated contract where messages that are being sent from @@ -48,8 +48,8 @@ contract L2ToL1MessagePasser is ISemver { /// @param amount Amount of ETh that was burned. event WithdrawerBalanceBurnt(uint256 indexed amount); - /// @custom:semver 1.1.0 - string public constant version = "1.1.0"; + /// @custom:semver 1.1.1-beta.1 + string public constant version = "1.1.1-beta.1"; /// @notice Allows users to withdraw ETH by sending directly to this contract. receive() external payable { diff --git a/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol index 46eb76b21824..d827e4feb86e 100644 --- a/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol +++ b/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol @@ -36,7 +36,7 @@ error MessageAlreadyRelayed(); /// @notice Thrown when a reentrant call is detected. error ReentrantCall(); -/// @custom:proxied +/// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000023 /// @title L2ToL2CrossDomainMessenger /// @notice The L2ToL2CrossDomainMessenger is a higher level abstraction on top of the CrossL2Inbox that provides @@ -57,8 +57,8 @@ contract L2ToL2CrossDomainMessenger is IL2ToL2CrossDomainMessenger, ISemver, Tra uint16 public constant messageVersion = uint16(0); /// @notice Semantic version. - /// @custom:semver 1.0.0-beta.3 - string public constant version = "1.0.0-beta.3"; + /// @custom:semver 1.0.0-beta.4 + string public constant version = "1.0.0-beta.4"; /// @notice Mapping of message hashes to boolean receipt values. Note that a message will only be present in this /// mapping if it has successfully been relayed on this chain, and can therefore not be relayed again. diff --git a/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol b/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol index 9b0ba5cad8b0..75c6e22b3771 100644 --- a/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol +++ b/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol @@ -23,7 +23,7 @@ error OnlyBridge(); /// @notice Thrown when attempting to mint or burn tokens and the account is the zero address. error ZeroAddress(); -/// @custom:proxied +/// @custom:proxied true /// @title OptimismSuperchainERC20 /// @notice OptimismSuperchainERC20 is a standard extension of the base ERC20 token contract that unifies ERC20 token /// bridging to make it fungible across the Superchain. This construction allows the L2StandardBridge to burn @@ -70,8 +70,8 @@ contract OptimismSuperchainERC20 is IOptimismSuperchainERC20Extension, ERC20, IS } /// @notice Semantic version. - /// @custom:semver 1.0.0-beta.1 - string public constant version = "1.0.0-beta.1"; + /// @custom:semver 1.0.0-beta.2 + string public constant version = "1.0.0-beta.2"; /// @notice Constructs the OptimismSuperchainERC20 contract. constructor() { diff --git a/packages/contracts-bedrock/src/L2/SequencerFeeVault.sol b/packages/contracts-bedrock/src/L2/SequencerFeeVault.sol index 7216d9e3430e..208c8f367677 100644 --- a/packages/contracts-bedrock/src/L2/SequencerFeeVault.sol +++ b/packages/contracts-bedrock/src/L2/SequencerFeeVault.sol @@ -4,14 +4,14 @@ pragma solidity 0.8.15; import { ISemver } from "src/universal/ISemver.sol"; import { FeeVault } from "src/universal/FeeVault.sol"; -/// @custom:proxied +/// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000011 /// @title SequencerFeeVault /// @notice The SequencerFeeVault is the contract that holds any fees paid to the Sequencer during /// transaction processing and block production. contract SequencerFeeVault is FeeVault, ISemver { - /// @custom:semver 1.5.0-beta.1 - string public constant version = "1.5.0-beta.1"; + /// @custom:semver 1.5.0-beta.2 + string public constant version = "1.5.0-beta.2"; /// @notice Constructs the SequencerFeeVault contract. /// @param _recipient Wallet that will receive the fees. diff --git a/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol b/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol index 244dc5f60473..3d456eb0fd38 100644 --- a/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol +++ b/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol @@ -14,6 +14,7 @@ import "src/dispute/lib/Types.sol"; import { Unauthorized } from "src/libraries/errors/CommonErrors.sol"; import { UnregisteredGame, InvalidGameStatus } from "src/dispute/lib/Errors.sol"; +/// @custom:proxied true /// @title AnchorStateRegistry /// @notice The AnchorStateRegistry is a contract that stores the latest "anchor" state for each available /// FaultDisputeGame type. The anchor state is the latest state that has been proposed on L1 and was not @@ -27,8 +28,8 @@ contract AnchorStateRegistry is Initializable, IAnchorStateRegistry, ISemver { } /// @notice Semantic version. - /// @custom:semver 2.0.0-rc.1 - string public constant version = "2.0.0-rc.1"; + /// @custom:semver 2.0.1-beta.1 + string public constant version = "2.0.1-beta.1"; /// @notice DisputeGameFactory address. IDisputeGameFactory internal immutable DISPUTE_GAME_FACTORY; diff --git a/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol b/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol index 55d25abb9224..90b5754486f9 100644 --- a/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol +++ b/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol @@ -11,6 +11,7 @@ import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory. import "src/dispute/lib/Types.sol"; import "src/dispute/lib/Errors.sol"; +/// @custom:proxied true /// @title DisputeGameFactory /// @notice A factory contract for creating `IDisputeGame` contracts. All created dispute games are stored in both a /// mapping and an append only array. The timestamp of the creation time of the dispute game is packed tightly @@ -21,8 +22,8 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, ISemver using LibClone for address; /// @notice Semantic version. - /// @custom:semver 1.0.0 - string public constant version = "1.0.0"; + /// @custom:semver 1.0.1-beta.1 + string public constant version = "1.0.1-beta.1"; /// @inheritdoc IDisputeGameFactory mapping(GameType => IDisputeGame) public gameImpls; diff --git a/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol b/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol index 96cc0cf55e3b..2f875ced7865 100644 --- a/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol +++ b/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol @@ -10,6 +10,7 @@ import { WETH98 } from "src/dispute/weth/WETH98.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +/// @custom:proxied true /// @title DelayedWETH /// @notice DelayedWETH is an extension to WETH9 that allows for delayed withdrawals. Accounts must trigger an unlock /// function before they can withdraw WETH. Accounts must trigger unlock by specifying a sub-account and an @@ -21,8 +22,8 @@ import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; /// Not the prettiest contract in the world, but it gets the job done. contract DelayedWETH is OwnableUpgradeable, WETH98, IDelayedWETH, ISemver { /// @notice Semantic version. - /// @custom:semver 1.1.0-rc.1 - string public constant version = "1.1.0-rc.1"; + /// @custom:semver 1.1.1-beta.1 + string public constant version = "1.1.1-beta.1"; /// @inheritdoc IDelayedWETH mapping(address => mapping(address => WithdrawalRequest)) public withdrawals; diff --git a/packages/contracts-bedrock/src/legacy/AddressManager.sol b/packages/contracts-bedrock/src/legacy/AddressManager.sol index 6029a1142c12..daaac412e0a0 100644 --- a/packages/contracts-bedrock/src/legacy/AddressManager.sol +++ b/packages/contracts-bedrock/src/legacy/AddressManager.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; -/// @custom:legacy +/// @custom:legacy true /// @title AddressManager /// @notice AddressManager is a legacy contract that was used in the old version of the Optimism /// system to manage a registry of string names to addresses. We now use a more standard diff --git a/packages/contracts-bedrock/src/legacy/DeployerWhitelist.sol b/packages/contracts-bedrock/src/legacy/DeployerWhitelist.sol index 11585791655f..38a506c2b251 100644 --- a/packages/contracts-bedrock/src/legacy/DeployerWhitelist.sol +++ b/packages/contracts-bedrock/src/legacy/DeployerWhitelist.sol @@ -3,8 +3,8 @@ pragma solidity 0.8.15; import { ISemver } from "src/universal/ISemver.sol"; -/// @custom:legacy -/// @custom:proxied +/// @custom:legacy true +/// @custom:proxied true /// @custom:predeployed 0x4200000000000000000000000000000000000002 /// @title DeployerWhitelist /// @notice DeployerWhitelist is a legacy contract that was originally used to act as a whitelist of @@ -41,8 +41,8 @@ contract DeployerWhitelist is ISemver { } /// @notice Semantic version. - /// @custom:semver 1.1.0 - string public constant version = "1.1.0"; + /// @custom:semver 1.1.1-beta.1 + string public constant version = "1.1.1-beta.1"; /// @notice Adds or removes an address from the deployment whitelist. /// @param _deployer Address to update permissions for. diff --git a/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol b/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol index 8bd2e2a8f315..634361c51524 100644 --- a/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol +++ b/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol @@ -5,8 +5,8 @@ import { L1Block } from "src/L2/L1Block.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { ISemver } from "src/universal/ISemver.sol"; -/// @custom:legacy -/// @custom:proxied +/// @custom:legacy true +/// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000013 /// @title L1BlockNumber /// @notice L1BlockNumber is a legacy contract that fills the roll of the OVM_L1BlockNumber contract @@ -15,8 +15,8 @@ import { ISemver } from "src/universal/ISemver.sol"; /// contract instead. contract L1BlockNumber is ISemver { /// @notice Semantic version. - /// @custom:semver 1.1.0 - string public constant version = "1.1.0"; + /// @custom:semver 1.1.1-beta.1 + string public constant version = "1.1.1-beta.1"; /// @notice Returns the L1 block number. receive() external payable { diff --git a/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol b/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol index b68eb13d1018..28125a23f90f 100644 --- a/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol +++ b/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.15; import { Constants } from "src/libraries/Constants.sol"; import { IL1ChugSplashDeployer } from "src/legacy/interfaces/IL1ChugSplashProxy.sol"; -/// @custom:legacy +/// @custom:legacy true /// @title L1ChugSplashProxy /// @notice Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added /// functions `setCode` and `setStorage` for changing the code or storage of the contract. diff --git a/packages/contracts-bedrock/src/legacy/LegacyMessagePasser.sol b/packages/contracts-bedrock/src/legacy/LegacyMessagePasser.sol index caf5e6a23322..59a3f9fa3cd7 100644 --- a/packages/contracts-bedrock/src/legacy/LegacyMessagePasser.sol +++ b/packages/contracts-bedrock/src/legacy/LegacyMessagePasser.sol @@ -3,8 +3,8 @@ pragma solidity 0.8.15; import { ISemver } from "src/universal/ISemver.sol"; -/// @custom:legacy -/// @custom:proxied +/// @custom:legacy true +/// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000000 /// @title LegacyMessagePasser /// @notice The LegacyMessagePasser was the low-level mechanism used to send messages from L2 to L1 @@ -14,8 +14,8 @@ contract LegacyMessagePasser is ISemver { mapping(bytes32 => bool) public sentMessages; /// @notice Semantic version. - /// @custom:semver 1.1.0 - string public constant version = "1.1.0"; + /// @custom:semver 1.1.1-beta.1 + string public constant version = "1.1.1-beta.1"; /// @notice Passes a message to L1. /// @param _message Message to pass to L1. diff --git a/packages/contracts-bedrock/src/legacy/ResolvedDelegateProxy.sol b/packages/contracts-bedrock/src/legacy/ResolvedDelegateProxy.sol index c735339a6bb8..3005456570ff 100644 --- a/packages/contracts-bedrock/src/legacy/ResolvedDelegateProxy.sol +++ b/packages/contracts-bedrock/src/legacy/ResolvedDelegateProxy.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; import { AddressManager } from "src/legacy/AddressManager.sol"; -/// @custom:legacy +/// @custom:legacy true /// @title ResolvedDelegateProxy /// @notice ResolvedDelegateProxy is a legacy proxy contract that makes use of the AddressManager to /// resolve the implementation address. We're maintaining this contract for backwards diff --git a/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol b/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol index 799389542abe..7f1a2717a449 100644 --- a/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol +++ b/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol @@ -6,7 +6,7 @@ import { ISemver } from "src/universal/ISemver.sol"; import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import { IOptimismERC20Factory } from "src/L2/IOptimismERC20Factory.sol"; -/// @custom:proxied +/// @custom:proxied true /// @custom:predeployed 0x4200000000000000000000000000000000000012 /// @title OptimismMintableERC20Factory /// @notice OptimismMintableERC20Factory is a factory contract that generates OptimismMintableERC20 @@ -48,8 +48,8 @@ contract OptimismMintableERC20Factory is ISemver, Initializable, IOptimismERC20F /// the OptimismMintableERC20 token contract since this contract /// is responsible for deploying OptimismMintableERC20 contracts. /// @notice Semantic version. - /// @custom:semver 1.10.0 - string public constant version = "1.10.0"; + /// @custom:semver 1.10.1-beta.1 + string public constant version = "1.10.1-beta.1"; /// @notice Constructs the OptimismMintableERC20Factory contract. constructor() { diff --git a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummary.sol b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummary.sol index 12227a7daedd..5c924230ed57 100644 --- a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummary.sol +++ b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummary.sol @@ -13,36 +13,36 @@ contract DeploymentSummary is DeploymentSummaryCode { Vm private constant vm = Vm(VM_ADDRESS); address internal constant addressManagerAddress = 0x50EEf481cae4250d252Ae577A09bF514f224C6C4; - address internal constant anchorStateRegistryAddress = 0x63B71B96756C693f7065345fecD9b7843b3e7C57; + address internal constant anchorStateRegistryAddress = 0x0C21b289b76ae49983890aed23F78337333F0A5F; address internal constant anchorStateRegistryProxyAddress = 0x970670459734a83899773A0fd45941B5afC1200e; address internal constant delayedWETHAddress = 0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05; address internal constant delayedWETHProxyAddress = 0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92; - address internal constant disputeGameFactoryAddress = 0x20B168142354Cee65a32f6D8cf3033E592299765; + address internal constant disputeGameFactoryAddress = 0x8efDa795511CBBdfFC9eeca1a5bF30f5B1E1ef9E; address internal constant disputeGameFactoryProxyAddress = 0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d; - address internal constant l1CrossDomainMessengerAddress = 0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b; + address internal constant l1CrossDomainMessengerAddress = 0x357B6CdA94109749a0dA475ac1BFd395a61eb908; address internal constant l1CrossDomainMessengerProxyAddress = 0xDeF3bca8c80064589E6787477FFa7Dd616B5574F; - address internal constant l1ERC721BridgeAddress = 0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804; + address internal constant l1ERC721BridgeAddress = 0xA4BD7E58A30ED0477fe7372883d09bF86619Bb66; address internal constant l1ERC721BridgeProxyAddress = 0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865; - address internal constant l1StandardBridgeAddress = 0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b; + address internal constant l1StandardBridgeAddress = 0x6cb2c88ABCd6391F9496f44BE27d5D3b247E0159; address internal constant l1StandardBridgeProxyAddress = 0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D; - address internal constant l2OutputOracleAddress = 0x19652082F846171168Daf378C4fD3ee85a0D4A60; + address internal constant l2OutputOracleAddress = 0x60d37db59d0D14f7EA5c7425A2C03244E08B162D; address internal constant l2OutputOracleProxyAddress = 0x39Af23E00F1e662025aA01b0cEdA19542B78DF99; address internal constant mipsAddress = 0x444e09fe6D839273316a87002aB0EFBeA6fe7806; - address internal constant optimismMintableERC20FactoryAddress = 0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F; + address internal constant optimismMintableERC20FactoryAddress = 0x47a13af3fB62B24E4914C36aBD9882da23D0e29C; address internal constant optimismMintableERC20FactoryProxyAddress = 0xc7B87b2b892EA5C3CfF47168881FE168C00377FB; - address internal constant optimismPortalAddress = 0xbdD90485FCbcac869D5b5752179815a3103d8131; - address internal constant optimismPortal2Address = 0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b; + address internal constant optimismPortalAddress = 0xBE8eE5CEA97De55Ae8b020E778A5C93C2Af81Ed4; + address internal constant optimismPortal2Address = 0x5506077419b90A12C048500e2eBcafb4fC6Bab61; address internal constant optimismPortalProxyAddress = 0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4; address internal constant permissionedDelayedWETHProxyAddress = 0xd6EAF4c146261653EE059077B78ED088Add54309; address internal constant preimageOracleAddress = 0x373d916D11cce55b548F7051002e76BCFBD7a85d; - address internal constant protocolVersionsAddress = 0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F; + address internal constant protocolVersionsAddress = 0xa99F1ab91821747b76Ec0cDFA38368DF4Ba06E84; address internal constant protocolVersionsProxyAddress = 0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1; address internal constant proxyAdminAddress = 0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1; address internal constant safeProxyFactoryAddress = 0xA8452Ec99ce0C64f20701dB7dD3abDb607c00496; address internal constant safeSingletonAddress = 0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3; - address internal constant superchainConfigAddress = 0x068E44eB31e111028c41598E4535be7468674D0A; + address internal constant superchainConfigAddress = 0xDAf629c26abd7a84B6330c369887053B75dB2AF2; address internal constant superchainConfigProxyAddress = 0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351; - address internal constant systemConfigAddress = 0x67866A5052E5302aaD08e9f352331fd8622eB6DC; + address internal constant systemConfigAddress = 0xd9CEcA938f039e427Edf626FA1f377d23A6b60c9; address internal constant systemConfigProxyAddress = 0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6; address internal constant systemOwnerSafeAddress = 0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD; address internal constant acc33Address = 0xb6b1579AA54e2F61e621a40d5F2704D717B3544F; @@ -107,7 +107,7 @@ contract DeploymentSummary is DeploymentSummaryCode { value = hex"0000000000000000000000000000000000000000000000000000000000000001"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a"; + value = hex"000000000000000000000000daf629c26abd7a84b6330c369887053b75db2af2"; vm.store(superchainConfigProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -145,7 +145,7 @@ contract DeploymentSummary is DeploymentSummaryCode { value = hex"0000000000000000000000000000000000000000000000000000000000000002"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f"; + value = hex"000000000000000000000000a99f1ab91821747b76ec0cdfa38368df4ba06e84"; vm.store(protocolVersionsProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -430,7 +430,7 @@ contract DeploymentSummary is DeploymentSummaryCode { value = hex"0000000000000000000000000000000000000000000000000000000000000003"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"000000000000000000000000bdd90485fcbcac869d5b5752179815a3103d8131"; + value = hex"000000000000000000000000be8ee5cea97de55ae8b020e778a5c93c2af81ed4"; vm.store(optimismPortalProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -460,7 +460,7 @@ contract DeploymentSummary is DeploymentSummaryCode { value = hex"0000000000000000000000000000000000000000000000000000000000000004"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc"; + value = hex"000000000000000000000000d9ceca938f039e427edf626fa1f377d23a6b60c9"; vm.store(systemConfigProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -529,7 +529,7 @@ contract DeploymentSummary is DeploymentSummaryCode { value = hex"0000000000000000000000000000000000000000000000000000000000000006"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b"; + value = hex"0000000000000000000000006cb2c88abcd6391f9496f44be27d5d3b247e0159"; vm.store(l1StandardBridgeProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -556,7 +556,7 @@ contract DeploymentSummary is DeploymentSummaryCode { value = hex"0000000000000000000000000000000000000000000000000000000000000007"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"0000000000000000000000005c4f5e749a61a9503c4aae8a9393e89609a0e804"; + value = hex"000000000000000000000000a4bd7e58a30ed0477fe7372883d09bf86619bb66"; vm.store(l1ERC721BridgeProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -580,7 +580,7 @@ contract DeploymentSummary is DeploymentSummaryCode { value = hex"0000000000000000000000000000000000000000000000000000000000000008"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"0000000000000000000000007c06d3a0a2f45e39e1798afbd9c3330971332a4f"; + value = hex"00000000000000000000000047a13af3fb62b24e4914c36abd9882da23d0e29c"; vm.store(optimismMintableERC20FactoryProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -610,7 +610,7 @@ contract DeploymentSummary is DeploymentSummaryCode { value = hex"000000000000000000000000000000000000000000000000000000000000000b"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e"; - value = hex"000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b"; + value = hex"000000000000000000000000357b6cda94109749a0da475ac1bfd395a61eb908"; vm.store(addressManagerAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000010000000000000000000000000000000000000000"; @@ -640,7 +640,7 @@ contract DeploymentSummary is DeploymentSummaryCode { value = hex"000000000000000000000000000000000000000000000000000000000000000c"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60"; + value = hex"00000000000000000000000060d37db59d0d14f7ea5c7425a2c03244e08b162d"; vm.store(l2OutputOracleProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -676,7 +676,7 @@ contract DeploymentSummary is DeploymentSummaryCode { value = hex"000000000000000000000000000000000000000000000000000000000000000d"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765"; + value = hex"0000000000000000000000008efda795511cbbdffc9eeca1a5bf30f5b1e1ef9e"; vm.store(disputeGameFactoryProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -745,7 +745,7 @@ contract DeploymentSummary is DeploymentSummaryCode { value = hex"0000000000000000000000000000000000000000000000000000000000000010"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"00000000000000000000000063b71b96756c693f7065345fecd9b7843b3e7c57"; + value = hex"0000000000000000000000000c21b289b76ae49983890aed23f78337333f0a5f"; vm.store(anchorStateRegistryProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; diff --git a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryCode.sol b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryCode.sol index 025c7485cd93..e0f719886b0f 100644 --- a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryCode.sol +++ b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryCode.sol @@ -17,11 +17,11 @@ contract DeploymentSummaryCode { bytes internal constant superchainConfigProxyCode = hex"60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a"; bytes internal constant superchainConfigCode = - hex"608060405234801561001057600080fd5b50600436106100885760003560e01c80635c975abb1161005b5780635c975abb146101255780636da663551461013d5780637fbf7b6a14610150578063c23a451a1461016657600080fd5b80633f4ba83a1461008d578063400ada7514610097578063452a9320146100aa57806354fd4d50146100dc575b600080fd5b61009561016e565b005b6100956100a5366004610746565b610294565b6100b261046d565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101186040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100d39190610808565b61012d6104a6565b60405190151581526020016100d3565b61009561014b366004610851565b6104d6565b6101586105a4565b6040519081526020016100d3565b6101586105d2565b61017661046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e20756e706175736500000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61026961026360017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60009055565b6040517fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d1693390600090a1565b600054610100900460ff16158080156102b45750600054600160ff909116105b806102ce5750303b1580156102ce575060005460ff166001145b61035a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161022c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156103b857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6103c18361061d565b8115610405576104056040518060400160405280601281526020017f496e697469616c697a65722070617573656400000000000000000000000000008152506106d8565b801561046857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006104a161049d60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b5490565b905090565b60006104a161049d60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b6104de61046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610598576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e2070617573650000000000000000000000000000000000000000000000606482015260840161022c565b6105a1816106d8565b50565b6105cf60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b81565b6105cf60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b61065061064b60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b829055565b60006040805173ffffffffffffffffffffffffffffffffffffffff841660208201527f7b743789cff01dafdeae47739925425aab5dfd02d0c8229e4a508bcd2b9f42bb9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526106cd91610808565b60405180910390a250565b61070c61070660017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60019055565b7fc32e6d5d6d1de257f64eac19ddb1f700ba13527983849c9486b1ab007ea283818160405161073b9190610808565b60405180910390a150565b6000806040838503121561075957600080fd5b823573ffffffffffffffffffffffffffffffffffffffff8116811461077d57600080fd5b91506020830135801515811461079257600080fd5b809150509250929050565b6000815180845260005b818110156107c3576020818501810151868301820152016107a7565b818111156107d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061081b602083018461079d565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561086357600080fd5b813567ffffffffffffffff8082111561087b57600080fd5b818401915084601f83011261088f57600080fd5b8135818111156108a1576108a1610822565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108e7576108e7610822565b8160405282815287602084870101111561090057600080fd5b826020860160208301376000928101602001929092525095945050505050565b600082821015610959577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a"; + hex"608060405234801561001057600080fd5b50600436106100885760003560e01c80635c975abb1161005b5780635c975abb146101255780636da663551461013d5780637fbf7b6a14610150578063c23a451a1461016657600080fd5b80633f4ba83a1461008d578063400ada7514610097578063452a9320146100aa57806354fd4d50146100dc575b600080fd5b61009561016e565b005b6100956100a5366004610746565b610294565b6100b261046d565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101186040518060400160405280600c81526020017f312e312e312d626574612e31000000000000000000000000000000000000000081525081565b6040516100d39190610808565b61012d6104a6565b60405190151581526020016100d3565b61009561014b366004610851565b6104d6565b6101586105a4565b6040519081526020016100d3565b6101586105d2565b61017661046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e20756e706175736500000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61026961026360017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60009055565b6040517fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d1693390600090a1565b600054610100900460ff16158080156102b45750600054600160ff909116105b806102ce5750303b1580156102ce575060005460ff166001145b61035a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161022c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156103b857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6103c18361061d565b8115610405576104056040518060400160405280601281526020017f496e697469616c697a65722070617573656400000000000000000000000000008152506106d8565b801561046857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006104a161049d60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b5490565b905090565b60006104a161049d60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b6104de61046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610598576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e2070617573650000000000000000000000000000000000000000000000606482015260840161022c565b6105a1816106d8565b50565b6105cf60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b81565b6105cf60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b61065061064b60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b829055565b60006040805173ffffffffffffffffffffffffffffffffffffffff841660208201527f7b743789cff01dafdeae47739925425aab5dfd02d0c8229e4a508bcd2b9f42bb9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526106cd91610808565b60405180910390a250565b61070c61070660017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60019055565b7fc32e6d5d6d1de257f64eac19ddb1f700ba13527983849c9486b1ab007ea283818160405161073b9190610808565b60405180910390a150565b6000806040838503121561075957600080fd5b823573ffffffffffffffffffffffffffffffffffffffff8116811461077d57600080fd5b91506020830135801515811461079257600080fd5b809150509250929050565b6000815180845260005b818110156107c3576020818501810151868301820152016107a7565b818111156107d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061081b602083018461079d565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561086357600080fd5b813567ffffffffffffffff8082111561087b57600080fd5b818401915084601f83011261088f57600080fd5b8135818111156108a1576108a1610822565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108e7576108e7610822565b8160405282815287602084870101111561090057600080fd5b826020860160208301376000928101602001929092525095945050505050565b600082821015610959577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a"; bytes internal constant protocolVersionsProxyCode = hex"60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a"; bytes internal constant protocolVersionsCode = - hex"608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b8578063f7d12760146101cb578063ffa1ad74146101d357600080fd5b80638da5cb5b14610180578063d798b1ac146101a8578063dc8452cd146101b057600080fd5b80635fd579af116100b25780635fd579af14610152578063715018a6146101655780637a1ac61e1461016d57600080fd5b80630457d6f2146100d9578063206a8300146100ee57806354fd4d5014610109575b600080fd5b6100ec6100e73660046108c3565b6101db565b005b6100f66101ef565b6040519081526020015b60405180910390f35b6101456040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516101009190610947565b6100ec6101603660046108c3565b61021d565b6100ec61022e565b6100ec61017b36600461098a565b610242565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b6100f66103f7565b6100f6610430565b6100ec6101c63660046109bd565b610460565b6100f6610514565b6100f6600081565b6101e361055f565b6101ec816105e0565b50565b61021a60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b81565b61022561055f565b6101ec81610698565b61023661055f565b6102406000610712565b565b600054610100900460ff16158080156102625750600054600160ff909116105b8061027c5750303b15801561027c575060005460ff166001145b61030d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561036b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610373610789565b61037c84610460565b610385836105e0565b61038e82610698565b80156103f157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b600061042b61042760017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b5490565b905090565b600061042b61042760017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b61046861055f565b73ffffffffffffffffffffffffffffffffffffffff811661050b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610304565b6101ec81610712565b61021a60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610304565b61061361060e60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b829055565b60008160405160200161062891815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be8360405161068c9190610947565b60405180910390a35050565b6106c661060e60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b6000816040516020016106db91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600161065b565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16610820576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b610240600054610100900460ff166108ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b61024033610712565b6000602082840312156108d557600080fd5b5035919050565b6000815180845260005b81811015610902576020818501810151868301820152016108e6565b81811115610914576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061095a60208301846108dc565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461098557600080fd5b919050565b60008060006060848603121561099f57600080fd5b6109a884610961565b95602085013595506040909401359392505050565b6000602082840312156109cf57600080fd5b61095a82610961565b600082821015610a11577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a"; + hex"608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b8578063f7d12760146101cb578063ffa1ad74146101d357600080fd5b80638da5cb5b14610180578063d798b1ac146101a8578063dc8452cd146101b057600080fd5b80635fd579af116100b25780635fd579af14610152578063715018a6146101655780637a1ac61e1461016d57600080fd5b80630457d6f2146100d9578063206a8300146100ee57806354fd4d5014610109575b600080fd5b6100ec6100e73660046108c3565b6101db565b005b6100f66101ef565b6040519081526020015b60405180910390f35b6101456040518060400160405280600c81526020017f312e302e312d626574612e31000000000000000000000000000000000000000081525081565b6040516101009190610947565b6100ec6101603660046108c3565b61021d565b6100ec61022e565b6100ec61017b36600461098a565b610242565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b6100f66103f7565b6100f6610430565b6100ec6101c63660046109bd565b610460565b6100f6610514565b6100f6600081565b6101e361055f565b6101ec816105e0565b50565b61021a60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b81565b61022561055f565b6101ec81610698565b61023661055f565b6102406000610712565b565b600054610100900460ff16158080156102625750600054600160ff909116105b8061027c5750303b15801561027c575060005460ff166001145b61030d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561036b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610373610789565b61037c84610460565b610385836105e0565b61038e82610698565b80156103f157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b600061042b61042760017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b5490565b905090565b600061042b61042760017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b61046861055f565b73ffffffffffffffffffffffffffffffffffffffff811661050b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610304565b6101ec81610712565b61021a60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610304565b61061361060e60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b829055565b60008160405160200161062891815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be8360405161068c9190610947565b60405180910390a35050565b6106c661060e60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b6000816040516020016106db91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600161065b565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16610820576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b610240600054610100900460ff166108ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b61024033610712565b6000602082840312156108d557600080fd5b5035919050565b6000815180845260005b81811015610902576020818501810151868301820152016108e6565b81811115610914576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061095a60208301846108dc565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461098557600080fd5b919050565b60008060006060848603121561099f57600080fd5b6109a884610961565b95602085013595506040909401359392505050565b6000602082840312156109cf57600080fd5b61095a82610961565b600082821015610a11577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a"; bytes internal constant optimismPortalProxyCode = hex"60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a"; bytes internal constant systemConfigProxyCode = @@ -45,23 +45,23 @@ contract DeploymentSummaryCode { bytes internal constant anchorStateRegistryProxyCode = hex"60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a"; bytes internal constant l1CrossDomainMessengerCode = - hex"60806040526004361061018b5760003560e01c80636425666b116100d6578063b1b1b2091161007f578063d764ad0b11610059578063d764ad0b1461049b578063db505d80146104ae578063ecc70428146104db57600080fd5b8063b1b1b2091461042b578063b28ade251461045b578063c0c53b8b1461047b57600080fd5b80638cbeeef2116100b05780638cbeeef2146102d05780639fce812c146103d0578063a4e7f8bd146103fb57600080fd5b80636425666b146103775780636e296e45146103a457806383a74074146103b957600080fd5b80633dbb202b1161013857806354fd4d501161011257806354fd4d50146102e65780635644cfdf1461033c5780635c975abb1461035257600080fd5b80633dbb202b146102935780633f827a5a146102a85780634c1d6a69146102d057600080fd5b80632828d7e8116101695780632828d7e81461022457806333d7e2bd1461023957806335e80ab31461026657600080fd5b8063028f85f7146101905780630c568498146101c35780630ff754ea146101d8575b600080fd5b34801561019c57600080fd5b506101a5601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101cf57600080fd5b506101a5603f81565b3480156101e457600080fd5b5060fc5473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ba565b34801561023057600080fd5b506101a5604081565b34801561024557600080fd5b5060fd546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561027257600080fd5b5060fb546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b6102a66102a1366004611bdd565b610540565b005b3480156102b457600080fd5b506102bd600181565b60405161ffff90911681526020016101ba565b3480156102dc57600080fd5b506101a5619c4081565b3480156102f257600080fd5b5061032f6040518060400160405280600581526020017f322e342e3000000000000000000000000000000000000000000000000000000081525081565b6040516101ba9190611caf565b34801561034857600080fd5b506101a561138881565b34801561035e57600080fd5b5061036761083d565b60405190151581526020016101ba565b34801561038357600080fd5b5060fc546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103b057600080fd5b506101ff6108d6565b3480156103c557600080fd5b506101a562030d4081565b3480156103dc57600080fd5b5060cf5473ffffffffffffffffffffffffffffffffffffffff166101ff565b34801561040757600080fd5b50610367610416366004611cc9565b60ce6020526000908152604090205460ff1681565b34801561043757600080fd5b50610367610446366004611cc9565b60cb6020526000908152604090205460ff1681565b34801561046757600080fd5b506101a5610476366004611ce2565b6109bd565b34801561048757600080fd5b506102a6610496366004611d36565b610a2b565b6102a66104a9366004611d81565b610ca2565b3480156104ba57600080fd5b5060cf546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104e757600080fd5b5061053260cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b6040519081526020016101ba565b6105486115d3565b156105e05734156105e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f642076616c7565207769746820637573746f6d2067617320746f6b656e00000060648201526084015b60405180910390fd5b60cf546107129073ffffffffffffffffffffffffffffffffffffffff166106088585856109bd565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061067460cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016106909796959493929190611e50565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611612565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561079760cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b866040516107a9959493929190611eaf565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60fb54604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156108ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d19190611efd565b905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016109a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084016105d7565b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f6109d9604063ffffffff8816611f4e565b6109e39190611f7e565b6109ee601088611f4e565b6109fb9062030d40611fcc565b610a059190611fcc565b610a0f9190611fcc565b610a199190611fcc565b610a239190611fcc565b949350505050565b6000547501000000000000000000000000000000000000000000900460ff1615808015610a76575060005460017401000000000000000000000000000000000000000090910460ff16105b80610aa85750303b158015610aa8575060005474010000000000000000000000000000000000000000900460ff166001145b610b34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016105d7565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790558015610bba57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b60fb805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560fc805486841690831617905560fd805492851692909116919091179055610c397342000000000000000000000000000000000000076116ab565b8015610c9c57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b610caa61083d565b15610d11576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f43726f7373446f6d61696e4d657373656e6765723a207061757365640000000060448201526064016105d7565b60f087901c60028110610dcc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016105d7565b8061ffff16600003610ec1576000610e1d878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506117e7915050565b600081815260cb602052604090205490915060ff1615610ebf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016105d7565b505b6000610f07898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061180692505050565b9050610f11611829565b15610f4957853414610f2557610f25611ff8565b600081815260ce602052604090205460ff1615610f4457610f44611ff8565b61109b565b3415610ffd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016105d7565b600081815260ce602052604090205460ff1661109b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016105d7565b6110a487611905565b15611157576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016105d7565b600081815260cb602052604090205460ff16156111f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016105d7565b61121785611208611388619c40611fcc565b67ffffffffffffffff1661194b565b158061123d575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561135657600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161134f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016105d7565b50506115ae565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a1617905560006113e788619c405a6113aa9190612027565b8988888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061196992505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801561149d57600082815260cb602052604090205460ff161561143a5761143a611ff8565b600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26115aa565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016115aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016105d7565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6000806115de611981565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b60fc546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c4290849061167390889083908990600090899060040161203e565b6000604051808303818588803b15801561168c57600080fd5b505af11580156116a0573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611756576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105d7565b60cc5473ffffffffffffffffffffffffffffffffffffffff166117a05760cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b60cf80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006117f585858585611a1e565b805190602001209050949350505050565b6000611816878787878787611ab7565b8051906020012090509695505050505050565b60fc5460009073ffffffffffffffffffffffffffffffffffffffff16331480156108d1575060cf5460fc54604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691639bf62d82916004808201926020929091908290030181865afa1580156118c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e99190612096565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff8216301480611945575060fc5473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000806000835160208501868989f195945050505050565b60fd54604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa1580156119f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1591906120b3565b90939092509050565b606084848484604051602401611a3794939291906120f3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b6060868686868686604051602401611ad49695949392919061213d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611b7857600080fd5b50565b60008083601f840112611b8d57600080fd5b50813567ffffffffffffffff811115611ba557600080fd5b602083019150836020828501011115611bbd57600080fd5b9250929050565b803563ffffffff81168114611bd857600080fd5b919050565b60008060008060608587031215611bf357600080fd5b8435611bfe81611b56565b9350602085013567ffffffffffffffff811115611c1a57600080fd5b611c2687828801611b7b565b9094509250611c39905060408601611bc4565b905092959194509250565b6000815180845260005b81811015611c6a57602081850181015186830182015201611c4e565b81811115611c7c576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611cc26020830184611c44565b9392505050565b600060208284031215611cdb57600080fd5b5035919050565b600080600060408486031215611cf757600080fd5b833567ffffffffffffffff811115611d0e57600080fd5b611d1a86828701611b7b565b9094509250611d2d905060208501611bc4565b90509250925092565b600080600060608486031215611d4b57600080fd5b8335611d5681611b56565b92506020840135611d6681611b56565b91506040840135611d7681611b56565b809150509250925092565b600080600080600080600060c0888a031215611d9c57600080fd5b873596506020880135611dae81611b56565b95506040880135611dbe81611b56565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611de857600080fd5b611df48a828b01611b7b565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611ea260c083018486611e07565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611edf608083018688611e07565b905083604083015263ffffffff831660608301529695505050505050565b600060208284031215611f0f57600080fd5b81518015158114611cc257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611f7557611f75611f1f565b02949350505050565b600067ffffffffffffffff80841680611fc0577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611fef57611fef611f1f565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b60008282101561203957612039611f1f565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a06080820152600061208b60a0830184611c44565b979650505050505050565b6000602082840312156120a857600080fd5b8151611cc281611b56565b600080604083850312156120c657600080fd5b82516120d181611b56565b602084015190925060ff811681146120e857600080fd5b809150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152506080604083015261212c6080830185611c44565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261218860c0830184611c44565b9897505050505050505056fea164736f6c634300080f000a"; + hex"60806040526004361061018b5760003560e01c80636425666b116100d6578063b1b1b2091161007f578063d764ad0b11610059578063d764ad0b1461049b578063db505d80146104ae578063ecc70428146104db57600080fd5b8063b1b1b2091461042b578063b28ade251461045b578063c0c53b8b1461047b57600080fd5b80638cbeeef2116100b05780638cbeeef2146102d05780639fce812c146103d0578063a4e7f8bd146103fb57600080fd5b80636425666b146103775780636e296e45146103a457806383a74074146103b957600080fd5b80633dbb202b1161013857806354fd4d501161011257806354fd4d50146102e65780635644cfdf1461033c5780635c975abb1461035257600080fd5b80633dbb202b146102935780633f827a5a146102a85780634c1d6a69146102d057600080fd5b80632828d7e8116101695780632828d7e81461022457806333d7e2bd1461023957806335e80ab31461026657600080fd5b8063028f85f7146101905780630c568498146101c35780630ff754ea146101d8575b600080fd5b34801561019c57600080fd5b506101a5601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101cf57600080fd5b506101a5603f81565b3480156101e457600080fd5b5060fc5473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ba565b34801561023057600080fd5b506101a5604081565b34801561024557600080fd5b5060fd546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561027257600080fd5b5060fb546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b6102a66102a1366004611bdd565b610540565b005b3480156102b457600080fd5b506102bd600181565b60405161ffff90911681526020016101ba565b3480156102dc57600080fd5b506101a5619c4081565b3480156102f257600080fd5b5061032f6040518060400160405280600c81526020017f322e342e312d626574612e31000000000000000000000000000000000000000081525081565b6040516101ba9190611caf565b34801561034857600080fd5b506101a561138881565b34801561035e57600080fd5b5061036761083d565b60405190151581526020016101ba565b34801561038357600080fd5b5060fc546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103b057600080fd5b506101ff6108d6565b3480156103c557600080fd5b506101a562030d4081565b3480156103dc57600080fd5b5060cf5473ffffffffffffffffffffffffffffffffffffffff166101ff565b34801561040757600080fd5b50610367610416366004611cc9565b60ce6020526000908152604090205460ff1681565b34801561043757600080fd5b50610367610446366004611cc9565b60cb6020526000908152604090205460ff1681565b34801561046757600080fd5b506101a5610476366004611ce2565b6109bd565b34801561048757600080fd5b506102a6610496366004611d36565b610a2b565b6102a66104a9366004611d81565b610ca2565b3480156104ba57600080fd5b5060cf546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104e757600080fd5b5061053260cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b6040519081526020016101ba565b6105486115d3565b156105e05734156105e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f642076616c7565207769746820637573746f6d2067617320746f6b656e00000060648201526084015b60405180910390fd5b60cf546107129073ffffffffffffffffffffffffffffffffffffffff166106088585856109bd565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061067460cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016106909796959493929190611e50565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611612565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561079760cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b866040516107a9959493929190611eaf565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60fb54604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156108ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d19190611efd565b905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016109a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084016105d7565b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f6109d9604063ffffffff8816611f4e565b6109e39190611f7e565b6109ee601088611f4e565b6109fb9062030d40611fcc565b610a059190611fcc565b610a0f9190611fcc565b610a199190611fcc565b610a239190611fcc565b949350505050565b6000547501000000000000000000000000000000000000000000900460ff1615808015610a76575060005460017401000000000000000000000000000000000000000090910460ff16105b80610aa85750303b158015610aa8575060005474010000000000000000000000000000000000000000900460ff166001145b610b34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016105d7565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790558015610bba57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b60fb805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560fc805486841690831617905560fd805492851692909116919091179055610c397342000000000000000000000000000000000000076116ab565b8015610c9c57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b610caa61083d565b15610d11576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f43726f7373446f6d61696e4d657373656e6765723a207061757365640000000060448201526064016105d7565b60f087901c60028110610dcc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016105d7565b8061ffff16600003610ec1576000610e1d878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506117e7915050565b600081815260cb602052604090205490915060ff1615610ebf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016105d7565b505b6000610f07898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061180692505050565b9050610f11611829565b15610f4957853414610f2557610f25611ff8565b600081815260ce602052604090205460ff1615610f4457610f44611ff8565b61109b565b3415610ffd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016105d7565b600081815260ce602052604090205460ff1661109b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016105d7565b6110a487611905565b15611157576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016105d7565b600081815260cb602052604090205460ff16156111f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016105d7565b61121785611208611388619c40611fcc565b67ffffffffffffffff1661194b565b158061123d575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561135657600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161134f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016105d7565b50506115ae565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a1617905560006113e788619c405a6113aa9190612027565b8988888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061196992505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801561149d57600082815260cb602052604090205460ff161561143a5761143a611ff8565b600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26115aa565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016115aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016105d7565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6000806115de611981565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b60fc546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c4290849061167390889083908990600090899060040161203e565b6000604051808303818588803b15801561168c57600080fd5b505af11580156116a0573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611756576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105d7565b60cc5473ffffffffffffffffffffffffffffffffffffffff166117a05760cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b60cf80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006117f585858585611a1e565b805190602001209050949350505050565b6000611816878787878787611ab7565b8051906020012090509695505050505050565b60fc5460009073ffffffffffffffffffffffffffffffffffffffff16331480156108d1575060cf5460fc54604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691639bf62d82916004808201926020929091908290030181865afa1580156118c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e99190612096565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff8216301480611945575060fc5473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000806000835160208501868989f195945050505050565b60fd54604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa1580156119f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1591906120b3565b90939092509050565b606084848484604051602401611a3794939291906120f3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b6060868686868686604051602401611ad49695949392919061213d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611b7857600080fd5b50565b60008083601f840112611b8d57600080fd5b50813567ffffffffffffffff811115611ba557600080fd5b602083019150836020828501011115611bbd57600080fd5b9250929050565b803563ffffffff81168114611bd857600080fd5b919050565b60008060008060608587031215611bf357600080fd5b8435611bfe81611b56565b9350602085013567ffffffffffffffff811115611c1a57600080fd5b611c2687828801611b7b565b9094509250611c39905060408601611bc4565b905092959194509250565b6000815180845260005b81811015611c6a57602081850181015186830182015201611c4e565b81811115611c7c576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611cc26020830184611c44565b9392505050565b600060208284031215611cdb57600080fd5b5035919050565b600080600060408486031215611cf757600080fd5b833567ffffffffffffffff811115611d0e57600080fd5b611d1a86828701611b7b565b9094509250611d2d905060208501611bc4565b90509250925092565b600080600060608486031215611d4b57600080fd5b8335611d5681611b56565b92506020840135611d6681611b56565b91506040840135611d7681611b56565b809150509250925092565b600080600080600080600060c0888a031215611d9c57600080fd5b873596506020880135611dae81611b56565b95506040880135611dbe81611b56565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611de857600080fd5b611df48a828b01611b7b565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611ea260c083018486611e07565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611edf608083018688611e07565b905083604083015263ffffffff831660608301529695505050505050565b600060208284031215611f0f57600080fd5b81518015158114611cc257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611f7557611f75611f1f565b02949350505050565b600067ffffffffffffffff80841680611fc0577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611fef57611fef611f1f565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b60008282101561203957612039611f1f565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a06080820152600061208b60a0830184611c44565b979650505050505050565b6000602082840312156120a857600080fd5b8151611cc281611b56565b600080604083850312156120c657600080fd5b82516120d181611b56565b602084015190925060ff811681146120e857600080fd5b809150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152506080604083015261212c6080830185611c44565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261218860c0830184611c44565b9897505050505050505056fea164736f6c634300080f000a"; bytes internal constant optimismMintableERC20FactoryCode = - hex"60806040523480156200001157600080fd5b5060043610620000935760003560e01c8063c4d66de81162000062578063c4d66de81462000175578063ce5ac90f146200018e578063e78cea9214620001a5578063ee9a31a214620001c657600080fd5b8063316b3739146200009857806354fd4d5014620000fb578063896f93d114620001475780638cf0629c146200015e575b600080fd5b620000d1620000a936600462000652565b60026020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b620001386040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b604051620000f29190620006e5565b620000d162000158366004620007dc565b620001e5565b620000d16200016f36600462000859565b620001fc565b6200018c6200018636600462000652565b6200041b565b005b620000d16200019f366004620007dc565b620005ed565b600154620000d19073ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff16620000d1565b6000620001f4848484620005ed565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff8516620002a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b600085858585604051602001620002c29493929190620008f0565b604051602081830303815290604052805190602001209050600081600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168888888860405162000312906200061a565b620003229594939291906200094a565b8190604051809103906000f590508015801562000343573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff81811660008181526002602052604080822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016948d1694851790555193945090927fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf9190a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054610100900460ff16158080156200043c5750600054600160ff909116105b80620004585750303b15801562000458575060005460ff166001145b620004e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200029e565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156200054557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790558015620005e957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6000620001f48484846012620001fc565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61178a80620009b083390190565b803573ffffffffffffffffffffffffffffffffffffffff811681146200064d57600080fd5b919050565b6000602082840312156200066557600080fd5b620006708262000628565b9392505050565b6000815180845260005b818110156200069f5760208185018101518683018201520162000681565b81811115620006b2576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600062000670602083018462000677565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200073b57600080fd5b813567ffffffffffffffff80821115620007595762000759620006fa565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620007a257620007a2620006fa565b81604052838152866020858801011115620007bc57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215620007f257600080fd5b620007fd8462000628565b9250602084013567ffffffffffffffff808211156200081b57600080fd5b620008298783880162000729565b935060408601359150808211156200084057600080fd5b506200084f8682870162000729565b9150509250925092565b600080600080608085870312156200087057600080fd5b6200087b8562000628565b9350602085013567ffffffffffffffff808211156200089957600080fd5b620008a78883890162000729565b94506040870135915080821115620008be57600080fd5b50620008cd8782880162000729565b925050606085013560ff81168114620008e557600080fd5b939692955090935050565b73ffffffffffffffffffffffffffffffffffffffff8516815260806020820152600062000921608083018662000677565b828103604084015262000935818662000677565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a060408301526200098560a083018662000677565b828103606084015262000999818662000677565b91505060ff83166080830152969550505050505056fe60e06040523480156200001157600080fd5b506040516200178a3803806200178a833981016040819052620000349162000163565b828260036200004483826200029e565b5060046200005382826200029e565b5050506001600160a01b039384166080529390921660a052505060ff1660c0526200036a565b80516001600160a01b03811681146200009157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000be57600080fd5b81516001600160401b0380821115620000db57620000db62000096565b604051601f8301601f19908116603f0116810190828211818310171562000106576200010662000096565b816040528381526020925086838588010111156200012357600080fd5b600091505b8382101562000147578582018301518183018401529082019062000128565b83821115620001595760008385830101525b9695505050505050565b600080600080600060a086880312156200017c57600080fd5b620001878662000079565b9450620001976020870162000079565b60408701519094506001600160401b0380821115620001b557600080fd5b620001c389838a01620000ac565b94506060880151915080821115620001da57600080fd5b50620001e988828901620000ac565b925050608086015160ff811681146200020157600080fd5b809150509295509295909350565b600181811c908216806200022457607f821691505b6020821081036200024557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029957600081815260208120601f850160051c81016020861015620002745750805b601f850160051c820191505b81811015620002955782815560010162000280565b5050505b505050565b81516001600160401b03811115620002ba57620002ba62000096565b620002d281620002cb84546200020f565b846200024b565b602080601f8311600181146200030a5760008415620002f15750858301515b600019600386901b1c1916600185901b17855562000295565b600085815260208120601f198616915b828110156200033b578886015182559484019460019091019084016200031a565b50858210156200035a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c0516113d4620003b6600039600061024401526000818161034b015281816103e001528181610625015261075c0152600081816101a9015261037101526113d46000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610395578063e78cea9214610349578063ee9a31a2146103db57600080fd5b8063ae1f6aaf14610349578063c01e1bd61461036f578063d6c0b2c41461036f57600080fd5b80639dc29fac116100bd5780639dc29fac14610310578063a457c2d714610323578063a9059cbb1461033657600080fd5b806370a08231146102d257806395d89b411461030857600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a36600461117d565b610402565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104f3565b60405161019b91906111c6565b61018f610213366004611262565b610585565b6002545b60405190815260200161019b565b61018f61023836600461128c565b61059d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611262565b6105c1565b61029461028f366004611262565b61060d565b005b6101f86040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61021c6102e03660046112c8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610735565b61029461031e366004611262565b610744565b61018f610331366004611262565b61085b565b61018f610344366004611262565b61092c565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c6103a33660046112e3565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104bb57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104ea57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461050290611316565b80601f016020809104026020016040519081016040528092919081815260200182805461052e90611316565b801561057b5780601f106105505761010080835404028352916020019161057b565b820191906000526020600020905b81548152906001019060200180831161055e57829003601f168201915b5050505050905090565b60003361059381858561093a565b5060019392505050565b6000336105ab858285610aee565b6105b6858585610bc5565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906105939082908690610608908790611398565b61093a565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106e18282610e78565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161072991815260200190565b60405180910390a25050565b60606004805461050290611316565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016106ce565b6108138282610f98565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161072991815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561091f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016106ce565b6105b6828686840361093a565b600033610593818585610bc5565b73ffffffffffffffffffffffffffffffffffffffff83166109dc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bbf5781811015610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106ce565b610bbf848484840361093a565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610d0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e05908490611398565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e6b91815260200190565b60405180910390a3610bbf565b73ffffffffffffffffffffffffffffffffffffffff8216610ef5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106ce565b8060026000828254610f079190611398565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f41908490611398565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff821661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156110f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812083830390556002805484929061112d9084906113b0565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610ae1565b60006020828403121561118f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146111bf57600080fd5b9392505050565b600060208083528351808285015260005b818110156111f3578581018301518582016040015282016111d7565b81811115611205576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461125d57600080fd5b919050565b6000806040838503121561127557600080fd5b61127e83611239565b946020939093013593505050565b6000806000606084860312156112a157600080fd5b6112aa84611239565b92506112b860208501611239565b9150604084013590509250925092565b6000602082840312156112da57600080fd5b6111bf82611239565b600080604083850312156112f657600080fd5b6112ff83611239565b915061130d60208401611239565b90509250929050565b600181811c9082168061132a57607f821691505b602082108103611363577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156113ab576113ab611369565b500190565b6000828210156113c2576113c2611369565b50039056fea164736f6c634300080f000aa164736f6c634300080f000a"; + hex"60806040523480156200001157600080fd5b5060043610620000935760003560e01c8063c4d66de81162000062578063c4d66de81462000175578063ce5ac90f146200018e578063e78cea9214620001a5578063ee9a31a214620001c657600080fd5b8063316b3739146200009857806354fd4d5014620000fb578063896f93d114620001475780638cf0629c146200015e575b600080fd5b620000d1620000a936600462000652565b60026020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b620001386040518060400160405280600d81526020017f312e31302e312d626574612e310000000000000000000000000000000000000081525081565b604051620000f29190620006e5565b620000d162000158366004620007dc565b620001e5565b620000d16200016f36600462000859565b620001fc565b6200018c6200018636600462000652565b6200041b565b005b620000d16200019f366004620007dc565b620005ed565b600154620000d19073ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff16620000d1565b6000620001f4848484620005ed565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff8516620002a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b600085858585604051602001620002c29493929190620008f0565b604051602081830303815290604052805190602001209050600081600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168888888860405162000312906200061a565b620003229594939291906200094a565b8190604051809103906000f590508015801562000343573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff81811660008181526002602052604080822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016948d1694851790555193945090927fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf9190a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054610100900460ff16158080156200043c5750600054600160ff909116105b80620004585750303b15801562000458575060005460ff166001145b620004e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200029e565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156200054557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790558015620005e957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6000620001f48484846012620001fc565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61178a80620009b083390190565b803573ffffffffffffffffffffffffffffffffffffffff811681146200064d57600080fd5b919050565b6000602082840312156200066557600080fd5b620006708262000628565b9392505050565b6000815180845260005b818110156200069f5760208185018101518683018201520162000681565b81811115620006b2576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600062000670602083018462000677565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200073b57600080fd5b813567ffffffffffffffff80821115620007595762000759620006fa565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620007a257620007a2620006fa565b81604052838152866020858801011115620007bc57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215620007f257600080fd5b620007fd8462000628565b9250602084013567ffffffffffffffff808211156200081b57600080fd5b620008298783880162000729565b935060408601359150808211156200084057600080fd5b506200084f8682870162000729565b9150509250925092565b600080600080608085870312156200087057600080fd5b6200087b8562000628565b9350602085013567ffffffffffffffff808211156200089957600080fd5b620008a78883890162000729565b94506040870135915080821115620008be57600080fd5b50620008cd8782880162000729565b925050606085013560ff81168114620008e557600080fd5b939692955090935050565b73ffffffffffffffffffffffffffffffffffffffff8516815260806020820152600062000921608083018662000677565b828103604084015262000935818662000677565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a060408301526200098560a083018662000677565b828103606084015262000999818662000677565b91505060ff83166080830152969550505050505056fe60e06040523480156200001157600080fd5b506040516200178a3803806200178a833981016040819052620000349162000163565b828260036200004483826200029e565b5060046200005382826200029e565b5050506001600160a01b039384166080529390921660a052505060ff1660c0526200036a565b80516001600160a01b03811681146200009157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000be57600080fd5b81516001600160401b0380821115620000db57620000db62000096565b604051601f8301601f19908116603f0116810190828211818310171562000106576200010662000096565b816040528381526020925086838588010111156200012357600080fd5b600091505b8382101562000147578582018301518183018401529082019062000128565b83821115620001595760008385830101525b9695505050505050565b600080600080600060a086880312156200017c57600080fd5b620001878662000079565b9450620001976020870162000079565b60408701519094506001600160401b0380821115620001b557600080fd5b620001c389838a01620000ac565b94506060880151915080821115620001da57600080fd5b50620001e988828901620000ac565b925050608086015160ff811681146200020157600080fd5b809150509295509295909350565b600181811c908216806200022457607f821691505b6020821081036200024557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029957600081815260208120601f850160051c81016020861015620002745750805b601f850160051c820191505b81811015620002955782815560010162000280565b5050505b505050565b81516001600160401b03811115620002ba57620002ba62000096565b620002d281620002cb84546200020f565b846200024b565b602080601f8311600181146200030a5760008415620002f15750858301515b600019600386901b1c1916600185901b17855562000295565b600085815260208120601f198616915b828110156200033b578886015182559484019460019091019084016200031a565b50858210156200035a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c0516113d4620003b6600039600061024401526000818161034b015281816103e001528181610625015261075c0152600081816101a9015261037101526113d46000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610395578063e78cea9214610349578063ee9a31a2146103db57600080fd5b8063ae1f6aaf14610349578063c01e1bd61461036f578063d6c0b2c41461036f57600080fd5b80639dc29fac116100bd5780639dc29fac14610310578063a457c2d714610323578063a9059cbb1461033657600080fd5b806370a08231146102d257806395d89b411461030857600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a36600461117d565b610402565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104f3565b60405161019b91906111c6565b61018f610213366004611262565b610585565b6002545b60405190815260200161019b565b61018f61023836600461128c565b61059d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611262565b6105c1565b61029461028f366004611262565b61060d565b005b6101f86040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61021c6102e03660046112c8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610735565b61029461031e366004611262565b610744565b61018f610331366004611262565b61085b565b61018f610344366004611262565b61092c565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c6103a33660046112e3565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104bb57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104ea57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461050290611316565b80601f016020809104026020016040519081016040528092919081815260200182805461052e90611316565b801561057b5780601f106105505761010080835404028352916020019161057b565b820191906000526020600020905b81548152906001019060200180831161055e57829003601f168201915b5050505050905090565b60003361059381858561093a565b5060019392505050565b6000336105ab858285610aee565b6105b6858585610bc5565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906105939082908690610608908790611398565b61093a565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106e18282610e78565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161072991815260200190565b60405180910390a25050565b60606004805461050290611316565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016106ce565b6108138282610f98565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161072991815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561091f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016106ce565b6105b6828686840361093a565b600033610593818585610bc5565b73ffffffffffffffffffffffffffffffffffffffff83166109dc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bbf5781811015610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106ce565b610bbf848484840361093a565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610d0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e05908490611398565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e6b91815260200190565b60405180910390a3610bbf565b73ffffffffffffffffffffffffffffffffffffffff8216610ef5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106ce565b8060026000828254610f079190611398565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f41908490611398565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff821661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156110f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812083830390556002805484929061112d9084906113b0565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610ae1565b60006020828403121561118f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146111bf57600080fd5b9392505050565b600060208083528351808285015260005b818110156111f3578581018301518582016040015282016111d7565b81811115611205576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461125d57600080fd5b919050565b6000806040838503121561127557600080fd5b61127e83611239565b946020939093013593505050565b6000806000606084860312156112a157600080fd5b6112aa84611239565b92506112b860208501611239565b9150604084013590509250925092565b6000602082840312156112da57600080fd5b6111bf82611239565b600080604083850312156112f657600080fd5b6112ff83611239565b915061130d60208401611239565b90509250929050565b600181811c9082168061132a57607f821691505b602082108103611363577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156113ab576113ab611369565b500190565b6000828210156113c2576113c2611369565b50039056fea164736f6c634300080f000aa164736f6c634300080f000a"; bytes internal constant systemConfigCode = - hex"608060405234801561001057600080fd5b50600436106102de5760003560e01c8063a711986911610186578063e0e2016d116100e3578063f2fde38b11610097578063f8c68de011610071578063f8c68de0146106e2578063fd32aa0f146106ea578063ffa1ad74146106f257600080fd5b8063f2fde38b146106b2578063f45e65d8146106c5578063f68016b7146106ce57600080fd5b8063e81b2c6d116100c8578063e81b2c6d14610681578063ec7075171461068a578063f2b4e617146106aa57600080fd5b8063e0e2016d14610671578063e2a3285c1461067957600080fd5b8063c9b26f611161013a578063d84447151161011f578063d84447151461064e578063dac6e63a14610656578063db9040fa1461065e57600080fd5b8063c9b26f6114610507578063cc731b021461051a57600080fd5b8063bc49ce5f1161016b578063bc49ce5f146104c6578063bfb14fb7146104ce578063c4e8ddfa146104ff57600080fd5b8063a7119869146104ab578063b40a817c146104b357600080fd5b80634397dfef1161023f578063550fcdc9116101f35780638da5cb5b116101cd5780638da5cb5b14610472578063935f029e146104905780639b7d7f0a146104a357600080fd5b8063550fcdc91461045a5780635d73369c14610462578063715018a61461046a57600080fd5b80634add321d116102245780634add321d146103e95780634f16540b146103f157806354fd4d501461041857600080fd5b80634397dfef146103ab57806348cd4cb1146103e157600080fd5b806318d13918116102965780631fd19ee11161027b5780631fd19ee114610378578063213268491461038057806321d7fde51461039857600080fd5b806318d139181461035b57806319f5cea81461037057600080fd5b80630a49cb03116102c75780630a49cb031461032b5780630ae14b1b146103335780630c18c1621461035257600080fd5b806306c92657146102e3578063078f29cf146102fe575b600080fd5b6102eb6106fa565b6040519081526020015b60405180910390f35b610306610728565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102f5565b610306610761565b630bebc2005b60405167ffffffffffffffff90911681526020016102f5565b6102eb60655481565b61036e610369366004612241565b610791565b005b6102eb6107a5565b6103066107d0565b6103886107fa565b60405190151581526020016102f5565b61036e6103a6366004612277565b610839565b6103b361084f565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835260ff9091166020830152016102f5565b6102eb610863565b610339610893565b6102eb7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b60408051808201909152600c81527f322e332e302d626574612e32000000000000000000000000000000000000000060208201525b6040516102f59190612320565b61044d6108b9565b6102eb6108c3565b61036e6108ee565b60335473ffffffffffffffffffffffffffffffffffffffff16610306565b61036e61049e366004612333565b610902565b610306610914565b610306610944565b61036e6104c136600461236d565b610974565b6102eb610985565b6068546104ea9068010000000000000000900463ffffffff1681565b60405163ffffffff90911681526020016102f5565b6103066109b0565b61036e610515366004612388565b6109e0565b6105de6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b6040516102f59190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b61044d6109f1565b6103066109fb565b61036e61066c3660046124bb565b610a2b565b6102eb610e36565b6102eb610e61565b6102eb60675481565b6068546104ea906c01000000000000000000000000900463ffffffff1681565b610306610e8c565b61036e6106c0366004612241565b610ebc565b6102eb60665481565b6068546103399067ffffffffffffffff1681565b6102eb610f70565b6102eb610f9b565b6102eb600081565b61072560017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b81565b600061075c61075860017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b5490565b905090565b600061075c61075860017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b610799611201565b6107a281611282565b50565b61072560017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b600061075c7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b60008061080561084f565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b610841611201565b61084b828261133f565b5050565b60008061085a611184565b90939092509050565b600061075c61075860017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b60695460009061075c9063ffffffff6a0100000000000000000000820481169116612654565b606061075c61147d565b61072560017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b6108f6611201565b610900600061153e565b565b61090a611201565b61084b82826115b5565b600061075c61075860017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b600061075c61075860017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b61097c611201565b6107a28161168b565b61072560017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b600061075c61075860017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b6109e8611201565b6107a2816117e1565b606061075c611809565b600061075c61075860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b600054610100900460ff1615808015610a4b5750600054600160ff909116105b80610a655750303b158015610a65575060005460ff166001145b610af6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610b5457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b5c6118bf565b610b658a610ebc565b610b6e876117e1565b610b78898961133f565b610b818661168b565b610baa7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08869055565b610bdd610bd860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b849055565b610c11610c0b60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b83519055565b610c48610c3f60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b60208401519055565b610c7f610c7660017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b60408401519055565b610cb6610cad60017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b60608401519055565b610ced610ce460017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b60808401519055565b610d24610d1b60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b60a08401519055565b610d2c61195e565b610d398260c001516119c6565b610d4284611cd0565b610d4a610893565b67ffffffffffffffff168667ffffffffffffffff161015610dc7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b8015610e2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b61072560017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b61072560017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b600061075c61075860017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b610ec4611201565b73ffffffffffffffffffffffffffffffffffffffff8116610f67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610aed565b6107a28161153e565b61072560017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b61072560017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b9055565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600060208251111561107a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f476173506179696e67546f6b656e3a20737472696e672063616e6e6f7420626560448201527f2067726561746572207468616e203332206279746573000000000000000000006064820152608401610aed565b6110838261115b565b92915050565b6110ef6110b760017f04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec61263d565b74ff000000000000000000000000000000000000000060a086901b1673ffffffffffffffffffffffffffffffffffffffff8716179055565b61112261111d60017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d61263d565b839055565b61115561115060017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd0576461263d565b829055565b50505050565b8051602181106111735763ec92f9a36000526004601cfd5b9081015160209190910360031b1b90565b600080806111b661075860017f04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec61263d565b73ffffffffffffffffffffffffffffffffffffffff811693509050826111f5575073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee92601292509050565b60a081901c9150509091565b60335473ffffffffffffffffffffffffffffffffffffffff163314610900576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610aed565b6112ab7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060035b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be836040516113339190612320565b60405180910390a35050565b606880547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000063ffffffff8581169182027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16929092176c0100000000000000000000000092851692909202919091179091557f0100000000000000000000000000000000000000000000000000000000000000602083811b67ffffffff000000001690921717606681905560655460408051938401919091528201526000906060015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be836040516114709190612320565b60405180910390a3505050565b60606000611489611184565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff82160161150257505060408051808201909152600381527f4554480000000000000000000000000000000000000000000000000000000000602082015290565b61153861153361075860017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd0576461263d565b612144565b91505090565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b7fff00000000000000000000000000000000000000000000000000000000000000811615611665576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f53797374656d436f6e6669673a207363616c61722065786365656473206d617860448201527f2e000000000000000000000000000000000000000000000000000000000000006064820152608401610aed565b60658290556066819055604080516020810184905290810182905260009060600161140d565b611693610893565b67ffffffffffffffff168167ffffffffffffffff161015611710576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b630bebc20067ffffffffffffffff82161115611788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f20686967686044820152606401610aed565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002611302565b6067819055604080516020808201849052825180830390910181529082019091526000611302565b60606000611815611184565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff82160161188e57505060408051808201909152600581527f4574686572000000000000000000000000000000000000000000000000000000602082015290565b61153861153361075860017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d61263d565b600054610100900460ff16611956576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610aed565b610900612178565b61198c61075860017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b600003610900576109006119c160017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b439055565b73ffffffffffffffffffffffffffffffffffffffff811615801590611a15575073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14155b8015611a265750611a246107fa565b155b156107a257601260ff168173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a9f9190612680565b60ff1614611b2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f53797374656d436f6e6669673a2062616420646563696d616c73206f6620676160448201527f7320706179696e6720746f6b656e0000000000000000000000000000000000006064820152608401610aed565b6000611bca8273ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015611b7f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611bc5919081019061269d565b610fe6565b90506000611c1c8373ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611b7f573d6000803e3d6000fd5b9050611c2b8360128484611089565b611c33610761565b6040517f71cfaa3f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015260126024830152604482018590526064820184905291909116906371cfaa3f90608401600060405180830381600087803b158015611cb357600080fd5b505af1158015611cc7573d6000803e3d6000fd5b50505050505050565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff161115611d80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d6178206261736500000000000000000000006064820152608401610aed565b6001816040015160ff1611611e17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e203100000000000000000000000000000000006064820152608401610aed565b6068546080820151825167ffffffffffffffff90921691611e389190612768565b63ffffffff161115611ea6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b6000816020015160ff1611611f3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f74206265203000000000000000000000000000000000006064820152608401610aed565b8051602082015163ffffffff82169160ff90911690611f5d908290612787565b611f6791906127d1565b63ffffffff1614611ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d69740000000000000000006064820152608401610aed565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b60405160005b82811a1561215a5760010161214a565b80825260208201838152600082820152505060408101604052919050565b600054610100900460ff1661220f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610aed565b6109003361153e565b803573ffffffffffffffffffffffffffffffffffffffff8116811461223c57600080fd5b919050565b60006020828403121561225357600080fd5b61225c82612218565b9392505050565b803563ffffffff8116811461223c57600080fd5b6000806040838503121561228a57600080fd5b61229383612263565b91506122a160208401612263565b90509250929050565b60005b838110156122c55781810151838201526020016122ad565b838111156111555750506000910152565b600081518084526122ee8160208601602086016122aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061225c60208301846122d6565b6000806040838503121561234657600080fd5b50508035926020909101359150565b803567ffffffffffffffff8116811461223c57600080fd5b60006020828403121561237f57600080fd5b61225c82612355565b60006020828403121561239a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff811182821017156123f3576123f36123a1565b60405290565b60ff811681146107a257600080fd5b600060e0828403121561241a57600080fd5b60405160e0810181811067ffffffffffffffff8211171561243d5761243d6123a1565b60405290508061244c83612218565b815261245a60208401612218565b602082015261246b60408401612218565b604082015261247c60608401612218565b606082015261248d60808401612218565b608082015261249e60a08401612218565b60a08201526124af60c08401612218565b60c08201525092915050565b6000806000806000806000806000898b036102808112156124db57600080fd5b6124e48b612218565b99506124f260208c01612263565b985061250060408c01612263565b975060608b0135965061251560808c01612355565b955061252360a08c01612218565b945060c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff408201121561255557600080fd5b5061255e6123d0565b61256a60c08c01612263565b815260e08b013561257a816123f9565b60208201526101008b013561258e816123f9565b60408201526125a06101208c01612263565b60608201526125b26101408c01612263565b60808201526101608b01356fffffffffffffffffffffffffffffffff811681146125db57600080fd5b60a082015292506125ef6101808b01612218565b91506125ff8b6101a08c01612408565b90509295985092959850929598565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561264f5761264f61260e565b500390565b600067ffffffffffffffff8083168185168083038211156126775761267761260e565b01949350505050565b60006020828403121561269257600080fd5b815161225c816123f9565b6000602082840312156126af57600080fd5b815167ffffffffffffffff808211156126c757600080fd5b818401915084601f8301126126db57600080fd5b8151818111156126ed576126ed6123a1565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612733576127336123a1565b8160405282815287602084870101111561274c57600080fd5b61275d8360208301602088016122aa565b979650505050505050565b600063ffffffff8083168185168083038211156126775761267761260e565b600063ffffffff808416806127c5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff808316818516818304811182151516156127f4576127f461260e565b0294935050505056fea164736f6c634300080f000a"; + hex"608060405234801561001057600080fd5b50600436106102de5760003560e01c8063a711986911610186578063e0e2016d116100e3578063f2fde38b11610097578063f8c68de011610071578063f8c68de0146106e2578063fd32aa0f146106ea578063ffa1ad74146106f257600080fd5b8063f2fde38b146106b2578063f45e65d8146106c5578063f68016b7146106ce57600080fd5b8063e81b2c6d116100c8578063e81b2c6d14610681578063ec7075171461068a578063f2b4e617146106aa57600080fd5b8063e0e2016d14610671578063e2a3285c1461067957600080fd5b8063c9b26f611161013a578063d84447151161011f578063d84447151461064e578063dac6e63a14610656578063db9040fa1461065e57600080fd5b8063c9b26f6114610507578063cc731b021461051a57600080fd5b8063bc49ce5f1161016b578063bc49ce5f146104c6578063bfb14fb7146104ce578063c4e8ddfa146104ff57600080fd5b8063a7119869146104ab578063b40a817c146104b357600080fd5b80634397dfef1161023f578063550fcdc9116101f35780638da5cb5b116101cd5780638da5cb5b14610472578063935f029e146104905780639b7d7f0a146104a357600080fd5b8063550fcdc91461045a5780635d73369c14610462578063715018a61461046a57600080fd5b80634add321d116102245780634add321d146103e95780634f16540b146103f157806354fd4d501461041857600080fd5b80634397dfef146103ab57806348cd4cb1146103e157600080fd5b806318d13918116102965780631fd19ee11161027b5780631fd19ee114610378578063213268491461038057806321d7fde51461039857600080fd5b806318d139181461035b57806319f5cea81461037057600080fd5b80630a49cb03116102c75780630a49cb031461032b5780630ae14b1b146103335780630c18c1621461035257600080fd5b806306c92657146102e3578063078f29cf146102fe575b600080fd5b6102eb6106fa565b6040519081526020015b60405180910390f35b610306610728565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102f5565b610306610761565b630bebc2005b60405167ffffffffffffffff90911681526020016102f5565b6102eb60655481565b61036e610369366004612241565b610791565b005b6102eb6107a5565b6103066107d0565b6103886107fa565b60405190151581526020016102f5565b61036e6103a6366004612277565b610839565b6103b361084f565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835260ff9091166020830152016102f5565b6102eb610863565b610339610893565b6102eb7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b60408051808201909152600c81527f322e332e302d626574612e33000000000000000000000000000000000000000060208201525b6040516102f59190612320565b61044d6108b9565b6102eb6108c3565b61036e6108ee565b60335473ffffffffffffffffffffffffffffffffffffffff16610306565b61036e61049e366004612333565b610902565b610306610914565b610306610944565b61036e6104c136600461236d565b610974565b6102eb610985565b6068546104ea9068010000000000000000900463ffffffff1681565b60405163ffffffff90911681526020016102f5565b6103066109b0565b61036e610515366004612388565b6109e0565b6105de6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b6040516102f59190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b61044d6109f1565b6103066109fb565b61036e61066c3660046124bb565b610a2b565b6102eb610e36565b6102eb610e61565b6102eb60675481565b6068546104ea906c01000000000000000000000000900463ffffffff1681565b610306610e8c565b61036e6106c0366004612241565b610ebc565b6102eb60665481565b6068546103399067ffffffffffffffff1681565b6102eb610f70565b6102eb610f9b565b6102eb600081565b61072560017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b81565b600061075c61075860017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b5490565b905090565b600061075c61075860017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b610799611201565b6107a281611282565b50565b61072560017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b600061075c7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b60008061080561084f565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b610841611201565b61084b828261133f565b5050565b60008061085a611184565b90939092509050565b600061075c61075860017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b60695460009061075c9063ffffffff6a0100000000000000000000820481169116612654565b606061075c61147d565b61072560017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b6108f6611201565b610900600061153e565b565b61090a611201565b61084b82826115b5565b600061075c61075860017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b600061075c61075860017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b61097c611201565b6107a28161168b565b61072560017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b600061075c61075860017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b6109e8611201565b6107a2816117e1565b606061075c611809565b600061075c61075860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b600054610100900460ff1615808015610a4b5750600054600160ff909116105b80610a655750303b158015610a65575060005460ff166001145b610af6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610b5457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b5c6118bf565b610b658a610ebc565b610b6e876117e1565b610b78898961133f565b610b818661168b565b610baa7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08869055565b610bdd610bd860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b849055565b610c11610c0b60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b83519055565b610c48610c3f60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b60208401519055565b610c7f610c7660017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b60408401519055565b610cb6610cad60017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b60608401519055565b610ced610ce460017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b60808401519055565b610d24610d1b60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b60a08401519055565b610d2c61195e565b610d398260c001516119c6565b610d4284611cd0565b610d4a610893565b67ffffffffffffffff168667ffffffffffffffff161015610dc7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b8015610e2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b61072560017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b61072560017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b600061075c61075860017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b610ec4611201565b73ffffffffffffffffffffffffffffffffffffffff8116610f67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610aed565b6107a28161153e565b61072560017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b61072560017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b9055565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600060208251111561107a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f476173506179696e67546f6b656e3a20737472696e672063616e6e6f7420626560448201527f2067726561746572207468616e203332206279746573000000000000000000006064820152608401610aed565b6110838261115b565b92915050565b6110ef6110b760017f04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec61263d565b74ff000000000000000000000000000000000000000060a086901b1673ffffffffffffffffffffffffffffffffffffffff8716179055565b61112261111d60017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d61263d565b839055565b61115561115060017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd0576461263d565b829055565b50505050565b8051602181106111735763ec92f9a36000526004601cfd5b9081015160209190910360031b1b90565b600080806111b661075860017f04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec61263d565b73ffffffffffffffffffffffffffffffffffffffff811693509050826111f5575073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee92601292509050565b60a081901c9150509091565b60335473ffffffffffffffffffffffffffffffffffffffff163314610900576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610aed565b6112ab7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060035b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be836040516113339190612320565b60405180910390a35050565b606880547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000063ffffffff8581169182027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16929092176c0100000000000000000000000092851692909202919091179091557f0100000000000000000000000000000000000000000000000000000000000000602083811b67ffffffff000000001690921717606681905560655460408051938401919091528201526000906060015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be836040516114709190612320565b60405180910390a3505050565b60606000611489611184565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff82160161150257505060408051808201909152600381527f4554480000000000000000000000000000000000000000000000000000000000602082015290565b61153861153361075860017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd0576461263d565b612144565b91505090565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b7fff00000000000000000000000000000000000000000000000000000000000000811615611665576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f53797374656d436f6e6669673a207363616c61722065786365656473206d617860448201527f2e000000000000000000000000000000000000000000000000000000000000006064820152608401610aed565b60658290556066819055604080516020810184905290810182905260009060600161140d565b611693610893565b67ffffffffffffffff168167ffffffffffffffff161015611710576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b630bebc20067ffffffffffffffff82161115611788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f20686967686044820152606401610aed565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002611302565b6067819055604080516020808201849052825180830390910181529082019091526000611302565b60606000611815611184565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff82160161188e57505060408051808201909152600581527f4574686572000000000000000000000000000000000000000000000000000000602082015290565b61153861153361075860017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d61263d565b600054610100900460ff16611956576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610aed565b610900612178565b61198c61075860017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b600003610900576109006119c160017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b439055565b73ffffffffffffffffffffffffffffffffffffffff811615801590611a15575073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14155b8015611a265750611a246107fa565b155b156107a257601260ff168173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a9f9190612680565b60ff1614611b2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f53797374656d436f6e6669673a2062616420646563696d616c73206f6620676160448201527f7320706179696e6720746f6b656e0000000000000000000000000000000000006064820152608401610aed565b6000611bca8273ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015611b7f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611bc5919081019061269d565b610fe6565b90506000611c1c8373ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611b7f573d6000803e3d6000fd5b9050611c2b8360128484611089565b611c33610761565b6040517f71cfaa3f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015260126024830152604482018590526064820184905291909116906371cfaa3f90608401600060405180830381600087803b158015611cb357600080fd5b505af1158015611cc7573d6000803e3d6000fd5b50505050505050565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff161115611d80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d6178206261736500000000000000000000006064820152608401610aed565b6001816040015160ff1611611e17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e203100000000000000000000000000000000006064820152608401610aed565b6068546080820151825167ffffffffffffffff90921691611e389190612768565b63ffffffff161115611ea6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b6000816020015160ff1611611f3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f74206265203000000000000000000000000000000000006064820152608401610aed565b8051602082015163ffffffff82169160ff90911690611f5d908290612787565b611f6791906127d1565b63ffffffff1614611ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d69740000000000000000006064820152608401610aed565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b60405160005b82811a1561215a5760010161214a565b80825260208201838152600082820152505060408101604052919050565b600054610100900460ff1661220f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610aed565b6109003361153e565b803573ffffffffffffffffffffffffffffffffffffffff8116811461223c57600080fd5b919050565b60006020828403121561225357600080fd5b61225c82612218565b9392505050565b803563ffffffff8116811461223c57600080fd5b6000806040838503121561228a57600080fd5b61229383612263565b91506122a160208401612263565b90509250929050565b60005b838110156122c55781810151838201526020016122ad565b838111156111555750506000910152565b600081518084526122ee8160208601602086016122aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061225c60208301846122d6565b6000806040838503121561234657600080fd5b50508035926020909101359150565b803567ffffffffffffffff8116811461223c57600080fd5b60006020828403121561237f57600080fd5b61225c82612355565b60006020828403121561239a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff811182821017156123f3576123f36123a1565b60405290565b60ff811681146107a257600080fd5b600060e0828403121561241a57600080fd5b60405160e0810181811067ffffffffffffffff8211171561243d5761243d6123a1565b60405290508061244c83612218565b815261245a60208401612218565b602082015261246b60408401612218565b604082015261247c60608401612218565b606082015261248d60808401612218565b608082015261249e60a08401612218565b60a08201526124af60c08401612218565b60c08201525092915050565b6000806000806000806000806000898b036102808112156124db57600080fd5b6124e48b612218565b99506124f260208c01612263565b985061250060408c01612263565b975060608b0135965061251560808c01612355565b955061252360a08c01612218565b945060c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff408201121561255557600080fd5b5061255e6123d0565b61256a60c08c01612263565b815260e08b013561257a816123f9565b60208201526101008b013561258e816123f9565b60408201526125a06101208c01612263565b60608201526125b26101408c01612263565b60808201526101608b01356fffffffffffffffffffffffffffffffff811681146125db57600080fd5b60a082015292506125ef6101808b01612218565b91506125ff8b6101a08c01612408565b90509295985092959850929598565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561264f5761264f61260e565b500390565b600067ffffffffffffffff8083168185168083038211156126775761267761260e565b01949350505050565b60006020828403121561269257600080fd5b815161225c816123f9565b6000602082840312156126af57600080fd5b815167ffffffffffffffff808211156126c757600080fd5b818401915084601f8301126126db57600080fd5b8151818111156126ed576126ed6123a1565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612733576127336123a1565b8160405282815287602084870101111561274c57600080fd5b61275d8360208301602088016122aa565b979650505050505050565b600063ffffffff8083168185168083038211156126775761267761260e565b600063ffffffff808416806127c5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff808316818516818304811182151516156127f4576127f461260e565b0294935050505056fea164736f6c634300080f000a"; bytes internal constant l1StandardBridgeCode = - hex"6080604052600436106101845760003560e01c80637f46ddb2116100d65780639a2ac6d51161007f578063c0c53b8b11610059578063c0c53b8b14610529578063c89701a214610549578063e11013dd1461057657600080fd5b80639a2ac6d5146104e3578063a9f9e675146104f6578063b1a1a8821461051657600080fd5b80638f601f66116100b05780638f601f661461047257806391c49bf814610407578063927ede2d146104b857600080fd5b80637f46ddb214610407578063838b252014610432578063870876231461045257600080fd5b806335e80ab31161013857806354fd4d501161011257806354fd4d501461036c57806358a997f6146103c25780635c975abb146103e257600080fd5b806335e80ab3146102f25780633cb747bf1461031f578063540abf731461034c57600080fd5b80631532ec34116101695780631532ec34146102755780631635f5fd1461028857806333d7e2bd1461029b57600080fd5b80630166a07a1461024257806309fc88431461026257600080fd5b3661023d57333b1561021d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b61023b333362030d40604051806020016040528060008152506105a5565b005b600080fd5b34801561024e57600080fd5b5061023b61025d366004612991565b6105b8565b61023b610270366004612a42565b6109d2565b61023b610283366004612a95565b610aa9565b61023b610296366004612a95565b610abd565b3480156102a757600080fd5b506033546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102fe57600080fd5b506032546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b34801561032b57600080fd5b506003546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b34801561035857600080fd5b5061023b610367366004612b08565b61101b565b34801561037857600080fd5b506103b56040518060400160405280600581526020017f322e322e3000000000000000000000000000000000000000000000000000000081525081565b6040516102e99190612bf5565b3480156103ce57600080fd5b5061023b6103dd366004612c08565b611060565b3480156103ee57600080fd5b506103f7611134565b60405190151581526020016102e9565b34801561041357600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff166102c8565b34801561043e57600080fd5b5061023b61044d366004612b08565b6111cd565b34801561045e57600080fd5b5061023b61046d366004612c08565b611212565b34801561047e57600080fd5b506104aa61048d366004612c8b565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102e9565b3480156104c457600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166102c8565b61023b6104f1366004612cc4565b6112e6565b34801561050257600080fd5b5061023b610511366004612991565b611328565b61023b610524366004612a42565b611337565b34801561053557600080fd5b5061023b610544366004612d27565b611408565b34801561055557600080fd5b506004546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b61023b610584366004612cc4565b611607565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6105b2848434858561164a565b50505050565b60035473ffffffffffffffffffffffffffffffffffffffff163314801561068b575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa15801561064f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106739190612d72565b73ffffffffffffffffffffffffffffffffffffffff16145b61073d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610214565b610745611134565b156107ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610214565b6107b5876118a9565b15610903576107c4878761190b565b610876576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610214565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156108e657600080fd5b505af11580156108fa573d6000803e3d6000fd5b50505050610985565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054610941908490612dbe565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c1683529390529190912091909155610985908585611a2b565b6109c9878787878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611aff92505050565b50505050505050565b333b15610a61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b610aa43333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061164a92505050565b505050565b610ab68585858585610abd565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610b90575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa158015610b54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b789190612d72565b73ffffffffffffffffffffffffffffffffffffffff16145b610c42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610214565b610c4a611134565b15610cb1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610214565b610cb9611b8d565b15610d46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2063616e6e6f742062726964676520455460448201527f48207769746820637573746f6d2067617320746f6b656e0000000000000000006064820152608401610214565b823414610dd5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e742072657175697265640000000000006064820152608401610214565b3073ffffffffffffffffffffffffffffffffffffffff851603610e7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c6600000000000000000000000000000000000000000000000000000000006064820152608401610214565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610f25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e6765720000000000000000000000000000000000000000000000006064820152608401610214565b610f6785858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bcc92505050565b6000610f84855a8660405180602001604052806000815250611c3f565b905080611013576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c656400000000000000000000000000000000000000000000000000000000006064820152608401610214565b505050505050565b6109c987873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c5792505050565b333b156110ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b61101386863333888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061201092505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156111a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c89190612dd5565b905090565b6109c987873388888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061201092505050565b333b156112a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b61101386863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c5792505050565b6105b233858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506105a592505050565b6109c9878787878787876105b8565b333b156113c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b610aa433338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506105a592505050565b600054610100900460ff16158080156114285750600054600160ff909116105b806114425750303b158015611442575060005460ff166001145b6114ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610214565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561152c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6032805473ffffffffffffffffffffffffffffffffffffffff8086167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255603380549285169290911691909117905561159f8473420000000000000000000000000000000000001061201f565b80156105b257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b6105b23385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061164a92505050565b611652611b8d565b156116df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2063616e6e6f742062726964676520455460448201527f48207769746820637573746f6d2067617320746f6b656e0000000000000000006064820152608401610214565b82341461176e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c756500006064820152608401610214565b61177a85858584612109565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9287929116907f1635f5fd00000000000000000000000000000000000000000000000000000000906117dd908b908b9086908a90602401612df7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b909216825261187092918890600401612e40565b6000604051808303818588803b15801561188957600080fd5b505af115801561189d573d6000803e3d6000fd5b50505050505050505050565b60006118d5827f1d1d8b630000000000000000000000000000000000000000000000000000000061217c565b806119055750611905827fec4fc8e30000000000000000000000000000000000000000000000000000000061217c565b92915050565b6000611937837f1d1d8b630000000000000000000000000000000000000000000000000000000061217c565b156119e0578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611987573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ab9190612d72565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611905565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611987573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610aa49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261219f565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b3868686604051611b7793929190612e85565b60405180910390a46110138686868686866122ab565b600080611b98612333565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e6318484604051611c2b929190612ec3565b60405180910390a36105b2848484846123d0565b6000806000835160208501868989f195945050505050565b3415611ce5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f5374616e646172644272696467653a2063616e6e6f742073656e642076616c7560448201527f65000000000000000000000000000000000000000000000000000000000000006064820152608401610214565b611cee876118a9565b15611e3c57611cfd878761190b565b611daf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610214565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b158015611e1f57600080fd5b505af1158015611e33573d6000803e3d6000fd5b50505050611ed0565b611e5e73ffffffffffffffffffffffffffffffffffffffff881686308661243d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054611e9c908490612edc565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611ede87878787878661249b565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9216907f0166a07a0000000000000000000000000000000000000000000000000000000090611f42908b908d908c908c908c908b90602401612ef4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611fd592918790600401612e40565b600060405180830381600087803b158015611fef57600080fd5b505af1158015612003573d6000803e3d6000fd5b5050505050505050505050565b6109c987878787878787611c57565b600054610100900460ff166120b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610214565b6003805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560048054929093169116179055565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051612168929190612ec3565b60405180910390a36105b284848484612529565b600061218783612588565b8015612198575061219883836125ec565b9392505050565b6000612201826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166126bb9092919063ffffffff16565b805190915015610aa4578080602001905181019061221f9190612dd5565b610aa4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610214565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd86868660405161232393929190612e85565b60405180910390a4505050505050565b603354604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa1580156123a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c79190612f4f565b90939092509050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d848460405161242f929190612ec3565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526105b29085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611a7d565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039686868660405161251393929190612e85565b60405180910390a46110138686868686866126d2565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5848460405161242f929190612ec3565b60006125b4827f01ffc9a7000000000000000000000000000000000000000000000000000000006125ec565b801561190557506125e5827fffffffff000000000000000000000000000000000000000000000000000000006125ec565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156126a4575060208210155b80156126b05750600081115b979650505050505050565b60606126ca848460008561274a565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf86868660405161232393929190612e85565b6060824710156127dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610214565b73ffffffffffffffffffffffffffffffffffffffff85163b61285a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610214565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516128839190612f84565b60006040518083038185875af1925050503d80600081146128c0576040519150601f19603f3d011682016040523d82523d6000602084013e6128c5565b606091505b50915091506126b0828286606083156128df575081612198565b8251156128ef5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102149190612bf5565b73ffffffffffffffffffffffffffffffffffffffff8116811461294557600080fd5b50565b60008083601f84011261295a57600080fd5b50813567ffffffffffffffff81111561297257600080fd5b60208301915083602082850101111561298a57600080fd5b9250929050565b600080600080600080600060c0888a0312156129ac57600080fd5b87356129b781612923565b965060208801356129c781612923565b955060408801356129d781612923565b945060608801356129e781612923565b93506080880135925060a088013567ffffffffffffffff811115612a0a57600080fd5b612a168a828b01612948565b989b979a50959850939692959293505050565b803563ffffffff81168114612a3d57600080fd5b919050565b600080600060408486031215612a5757600080fd5b612a6084612a29565b9250602084013567ffffffffffffffff811115612a7c57600080fd5b612a8886828701612948565b9497909650939450505050565b600080600080600060808688031215612aad57600080fd5b8535612ab881612923565b94506020860135612ac881612923565b935060408601359250606086013567ffffffffffffffff811115612aeb57600080fd5b612af788828901612948565b969995985093965092949392505050565b600080600080600080600060c0888a031215612b2357600080fd5b8735612b2e81612923565b96506020880135612b3e81612923565b95506040880135612b4e81612923565b945060608801359350612b6360808901612a29565b925060a088013567ffffffffffffffff811115612a0a57600080fd5b60005b83811015612b9a578181015183820152602001612b82565b838111156105b25750506000910152565b60008151808452612bc3816020860160208601612b7f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006121986020830184612bab565b60008060008060008060a08789031215612c2157600080fd5b8635612c2c81612923565b95506020870135612c3c81612923565b945060408701359350612c5160608801612a29565b9250608087013567ffffffffffffffff811115612c6d57600080fd5b612c7989828a01612948565b979a9699509497509295939492505050565b60008060408385031215612c9e57600080fd5b8235612ca981612923565b91506020830135612cb981612923565b809150509250929050565b60008060008060608587031215612cda57600080fd5b8435612ce581612923565b9350612cf360208601612a29565b9250604085013567ffffffffffffffff811115612d0f57600080fd5b612d1b87828801612948565b95989497509550505050565b600080600060608486031215612d3c57600080fd5b8335612d4781612923565b92506020840135612d5781612923565b91506040840135612d6781612923565b809150509250925092565b600060208284031215612d8457600080fd5b815161219881612923565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612dd057612dd0612d8f565b500390565b600060208284031215612de757600080fd5b8151801515811461219857600080fd5b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152612e366080830184612bab565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84168152606060208201526000612e6f6060830185612bab565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000612eba6060830184612bab565b95945050505050565b8281526040602082015260006126ca6040830184612bab565b60008219821115612eef57612eef612d8f565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a0830152612f4360c0830184612bab565b98975050505050505050565b60008060408385031215612f6257600080fd5b8251612f6d81612923565b602084015190925060ff81168114612cb957600080fd5b60008251612f96818460208701612b7f565b919091019291505056fea164736f6c634300080f000a"; + hex"6080604052600436106101845760003560e01c80637f46ddb2116100d65780639a2ac6d51161007f578063c0c53b8b11610059578063c0c53b8b14610529578063c89701a214610549578063e11013dd1461057657600080fd5b80639a2ac6d5146104e3578063a9f9e675146104f6578063b1a1a8821461051657600080fd5b80638f601f66116100b05780638f601f661461047257806391c49bf814610407578063927ede2d146104b857600080fd5b80637f46ddb214610407578063838b252014610432578063870876231461045257600080fd5b806335e80ab31161013857806354fd4d501161011257806354fd4d501461036c57806358a997f6146103c25780635c975abb146103e257600080fd5b806335e80ab3146102f25780633cb747bf1461031f578063540abf731461034c57600080fd5b80631532ec34116101695780631532ec34146102755780631635f5fd1461028857806333d7e2bd1461029b57600080fd5b80630166a07a1461024257806309fc88431461026257600080fd5b3661023d57333b1561021d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b61023b333362030d40604051806020016040528060008152506105a5565b005b600080fd5b34801561024e57600080fd5b5061023b61025d366004612991565b6105b8565b61023b610270366004612a42565b6109d2565b61023b610283366004612a95565b610aa9565b61023b610296366004612a95565b610abd565b3480156102a757600080fd5b506033546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102fe57600080fd5b506032546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b34801561032b57600080fd5b506003546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b34801561035857600080fd5b5061023b610367366004612b08565b61101b565b34801561037857600080fd5b506103b56040518060400160405280600c81526020017f322e322e312d626574612e31000000000000000000000000000000000000000081525081565b6040516102e99190612bf5565b3480156103ce57600080fd5b5061023b6103dd366004612c08565b611060565b3480156103ee57600080fd5b506103f7611134565b60405190151581526020016102e9565b34801561041357600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff166102c8565b34801561043e57600080fd5b5061023b61044d366004612b08565b6111cd565b34801561045e57600080fd5b5061023b61046d366004612c08565b611212565b34801561047e57600080fd5b506104aa61048d366004612c8b565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102e9565b3480156104c457600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166102c8565b61023b6104f1366004612cc4565b6112e6565b34801561050257600080fd5b5061023b610511366004612991565b611328565b61023b610524366004612a42565b611337565b34801561053557600080fd5b5061023b610544366004612d27565b611408565b34801561055557600080fd5b506004546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b61023b610584366004612cc4565b611607565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6105b2848434858561164a565b50505050565b60035473ffffffffffffffffffffffffffffffffffffffff163314801561068b575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa15801561064f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106739190612d72565b73ffffffffffffffffffffffffffffffffffffffff16145b61073d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610214565b610745611134565b156107ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610214565b6107b5876118a9565b15610903576107c4878761190b565b610876576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610214565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156108e657600080fd5b505af11580156108fa573d6000803e3d6000fd5b50505050610985565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054610941908490612dbe565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c1683529390529190912091909155610985908585611a2b565b6109c9878787878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611aff92505050565b50505050505050565b333b15610a61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b610aa43333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061164a92505050565b505050565b610ab68585858585610abd565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610b90575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa158015610b54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b789190612d72565b73ffffffffffffffffffffffffffffffffffffffff16145b610c42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610214565b610c4a611134565b15610cb1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610214565b610cb9611b8d565b15610d46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2063616e6e6f742062726964676520455460448201527f48207769746820637573746f6d2067617320746f6b656e0000000000000000006064820152608401610214565b823414610dd5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e742072657175697265640000000000006064820152608401610214565b3073ffffffffffffffffffffffffffffffffffffffff851603610e7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c6600000000000000000000000000000000000000000000000000000000006064820152608401610214565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610f25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e6765720000000000000000000000000000000000000000000000006064820152608401610214565b610f6785858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bcc92505050565b6000610f84855a8660405180602001604052806000815250611c3f565b905080611013576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c656400000000000000000000000000000000000000000000000000000000006064820152608401610214565b505050505050565b6109c987873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c5792505050565b333b156110ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b61101386863333888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061201092505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156111a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c89190612dd5565b905090565b6109c987873388888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061201092505050565b333b156112a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b61101386863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c5792505050565b6105b233858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506105a592505050565b6109c9878787878787876105b8565b333b156113c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b610aa433338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506105a592505050565b600054610100900460ff16158080156114285750600054600160ff909116105b806114425750303b158015611442575060005460ff166001145b6114ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610214565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561152c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6032805473ffffffffffffffffffffffffffffffffffffffff8086167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255603380549285169290911691909117905561159f8473420000000000000000000000000000000000001061201f565b80156105b257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b6105b23385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061164a92505050565b611652611b8d565b156116df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2063616e6e6f742062726964676520455460448201527f48207769746820637573746f6d2067617320746f6b656e0000000000000000006064820152608401610214565b82341461176e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c756500006064820152608401610214565b61177a85858584612109565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9287929116907f1635f5fd00000000000000000000000000000000000000000000000000000000906117dd908b908b9086908a90602401612df7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b909216825261187092918890600401612e40565b6000604051808303818588803b15801561188957600080fd5b505af115801561189d573d6000803e3d6000fd5b50505050505050505050565b60006118d5827f1d1d8b630000000000000000000000000000000000000000000000000000000061217c565b806119055750611905827fec4fc8e30000000000000000000000000000000000000000000000000000000061217c565b92915050565b6000611937837f1d1d8b630000000000000000000000000000000000000000000000000000000061217c565b156119e0578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611987573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ab9190612d72565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611905565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611987573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610aa49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261219f565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b3868686604051611b7793929190612e85565b60405180910390a46110138686868686866122ab565b600080611b98612333565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e6318484604051611c2b929190612ec3565b60405180910390a36105b2848484846123d0565b6000806000835160208501868989f195945050505050565b3415611ce5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f5374616e646172644272696467653a2063616e6e6f742073656e642076616c7560448201527f65000000000000000000000000000000000000000000000000000000000000006064820152608401610214565b611cee876118a9565b15611e3c57611cfd878761190b565b611daf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610214565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b158015611e1f57600080fd5b505af1158015611e33573d6000803e3d6000fd5b50505050611ed0565b611e5e73ffffffffffffffffffffffffffffffffffffffff881686308661243d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054611e9c908490612edc565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611ede87878787878661249b565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9216907f0166a07a0000000000000000000000000000000000000000000000000000000090611f42908b908d908c908c908c908b90602401612ef4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611fd592918790600401612e40565b600060405180830381600087803b158015611fef57600080fd5b505af1158015612003573d6000803e3d6000fd5b5050505050505050505050565b6109c987878787878787611c57565b600054610100900460ff166120b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610214565b6003805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560048054929093169116179055565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051612168929190612ec3565b60405180910390a36105b284848484612529565b600061218783612588565b8015612198575061219883836125ec565b9392505050565b6000612201826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166126bb9092919063ffffffff16565b805190915015610aa4578080602001905181019061221f9190612dd5565b610aa4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610214565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd86868660405161232393929190612e85565b60405180910390a4505050505050565b603354604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa1580156123a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c79190612f4f565b90939092509050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d848460405161242f929190612ec3565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526105b29085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611a7d565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039686868660405161251393929190612e85565b60405180910390a46110138686868686866126d2565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5848460405161242f929190612ec3565b60006125b4827f01ffc9a7000000000000000000000000000000000000000000000000000000006125ec565b801561190557506125e5827fffffffff000000000000000000000000000000000000000000000000000000006125ec565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156126a4575060208210155b80156126b05750600081115b979650505050505050565b60606126ca848460008561274a565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf86868660405161232393929190612e85565b6060824710156127dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610214565b73ffffffffffffffffffffffffffffffffffffffff85163b61285a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610214565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516128839190612f84565b60006040518083038185875af1925050503d80600081146128c0576040519150601f19603f3d011682016040523d82523d6000602084013e6128c5565b606091505b50915091506126b0828286606083156128df575081612198565b8251156128ef5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102149190612bf5565b73ffffffffffffffffffffffffffffffffffffffff8116811461294557600080fd5b50565b60008083601f84011261295a57600080fd5b50813567ffffffffffffffff81111561297257600080fd5b60208301915083602082850101111561298a57600080fd5b9250929050565b600080600080600080600060c0888a0312156129ac57600080fd5b87356129b781612923565b965060208801356129c781612923565b955060408801356129d781612923565b945060608801356129e781612923565b93506080880135925060a088013567ffffffffffffffff811115612a0a57600080fd5b612a168a828b01612948565b989b979a50959850939692959293505050565b803563ffffffff81168114612a3d57600080fd5b919050565b600080600060408486031215612a5757600080fd5b612a6084612a29565b9250602084013567ffffffffffffffff811115612a7c57600080fd5b612a8886828701612948565b9497909650939450505050565b600080600080600060808688031215612aad57600080fd5b8535612ab881612923565b94506020860135612ac881612923565b935060408601359250606086013567ffffffffffffffff811115612aeb57600080fd5b612af788828901612948565b969995985093965092949392505050565b600080600080600080600060c0888a031215612b2357600080fd5b8735612b2e81612923565b96506020880135612b3e81612923565b95506040880135612b4e81612923565b945060608801359350612b6360808901612a29565b925060a088013567ffffffffffffffff811115612a0a57600080fd5b60005b83811015612b9a578181015183820152602001612b82565b838111156105b25750506000910152565b60008151808452612bc3816020860160208601612b7f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006121986020830184612bab565b60008060008060008060a08789031215612c2157600080fd5b8635612c2c81612923565b95506020870135612c3c81612923565b945060408701359350612c5160608801612a29565b9250608087013567ffffffffffffffff811115612c6d57600080fd5b612c7989828a01612948565b979a9699509497509295939492505050565b60008060408385031215612c9e57600080fd5b8235612ca981612923565b91506020830135612cb981612923565b809150509250929050565b60008060008060608587031215612cda57600080fd5b8435612ce581612923565b9350612cf360208601612a29565b9250604085013567ffffffffffffffff811115612d0f57600080fd5b612d1b87828801612948565b95989497509550505050565b600080600060608486031215612d3c57600080fd5b8335612d4781612923565b92506020840135612d5781612923565b91506040840135612d6781612923565b809150509250925092565b600060208284031215612d8457600080fd5b815161219881612923565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612dd057612dd0612d8f565b500390565b600060208284031215612de757600080fd5b8151801515811461219857600080fd5b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152612e366080830184612bab565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84168152606060208201526000612e6f6060830185612bab565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000612eba6060830184612bab565b95945050505050565b8281526040602082015260006126ca6040830184612bab565b60008219821115612eef57612eef612d8f565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a0830152612f4360c0830184612bab565b98975050505050505050565b60008060408385031215612f6257600080fd5b8251612f6d81612923565b602084015190925060ff81168114612cb957600080fd5b60008251612f96818460208701612b7f565b919091019291505056fea164736f6c634300080f000a"; bytes internal constant l1ERC721BridgeCode = - hex"608060405234801561001057600080fd5b50600436106100d45760003560e01c80635d93a3fc11610081578063927ede2d1161005b578063927ede2d14610231578063aa5574521461024f578063c89701a21461026257600080fd5b80635d93a3fc146101cc578063761f4493146102005780637f46ddb21461021357600080fd5b8063485cc955116100b2578063485cc9551461015857806354fd4d501461016b5780635c975abb146101b457600080fd5b806335e80ab3146100d95780633687011a146101235780633cb747bf14610138575b600080fd5b6032546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610136610131366004610fe1565b610282565b005b6001546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b610136610166366004611064565b61032e565b6101a76040518060400160405280600c81526020017f322e312e312b626574612e31000000000000000000000000000000000000000081525081565b60405161011a9190611108565b6101bc610518565b604051901515815260200161011a565b6101bc6101da366004611122565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b61013661020e366004611163565b6105b1565b60025473ffffffffffffffffffffffffffffffffffffffff166100f9565b60015473ffffffffffffffffffffffffffffffffffffffff166100f9565b61013661025d3660046111fb565b610a58565b6002546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b333b15610316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b6103268686333388888888610b30565b505050505050565b600054610100900460ff161580801561034e5750600054600160ff909116105b806103685750303b158015610368575060005460ff166001145b6103f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161030d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561045257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556104b083734200000000000000000000000000000000000014610e70565b801561051357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa158015610588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ac9190611272565b905090565b60015473ffffffffffffffffffffffffffffffffffffffff16331480156106865750600254600154604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691636e296e45916004808201926020929091908290030181865afa15801561064a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066e9190611294565b73ffffffffffffffffffffffffffffffffffffffff16145b610712576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f746865722062726964676500606482015260840161030d565b61071a610518565b15610781576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4c314552433732314272696467653a2070617573656400000000000000000000604482015260640161030d565b3073ffffffffffffffffffffffffffffffffffffffff881603610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c6600000000000000000000000000000000000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff1615156001146108f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c312042726964676500000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156109b557600080fd5b505af11580156109c9573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac87878787604051610a4794939291906112fa565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610afb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f74206265206164647265737328302900000000000000000000000000000000606482015260840161030d565b610b0b8787338888888888610b30565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b73ffffffffffffffffffffffffffffffffffffffff8716610bd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f742062652061646472657373283029000000000000000000000000000000606482015260840161030d565b600063761f449360e01b888a8989898888604051602401610bfa979695949392919061133a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610d3a57600080fd5b505af1158015610d4e573d6000803e3d6000fd5b50506001546002546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450633dbb202b9350610db1929091169085908990600401611397565b600060405180830381600087803b158015610dcb57600080fd5b505af1158015610ddf573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610e5d94939291906112fa565b60405180910390a4505050505050505050565b600054610100900460ff16610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161030d565b6001805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560028054929093169116179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610f7c57600080fd5b50565b803563ffffffff81168114610f9357600080fd5b919050565b60008083601f840112610faa57600080fd5b50813567ffffffffffffffff811115610fc257600080fd5b602083019150836020828501011115610fda57600080fd5b9250929050565b60008060008060008060a08789031215610ffa57600080fd5b863561100581610f5a565b9550602087013561101581610f5a565b94506040870135935061102a60608801610f7f565b9250608087013567ffffffffffffffff81111561104657600080fd5b61105289828a01610f98565b979a9699509497509295939492505050565b6000806040838503121561107757600080fd5b823561108281610f5a565b9150602083013561109281610f5a565b809150509250929050565b6000815180845260005b818110156110c3576020818501810151868301820152016110a7565b818111156110d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061111b602083018461109d565b9392505050565b60008060006060848603121561113757600080fd5b833561114281610f5a565b9250602084013561115281610f5a565b929592945050506040919091013590565b600080600080600080600060c0888a03121561117e57600080fd5b873561118981610f5a565b9650602088013561119981610f5a565b955060408801356111a981610f5a565b945060608801356111b981610f5a565b93506080880135925060a088013567ffffffffffffffff8111156111dc57600080fd5b6111e88a828b01610f98565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561121657600080fd5b873561122181610f5a565b9650602088013561123181610f5a565b9550604088013561124181610f5a565b94506060880135935061125660808901610f7f565b925060a088013567ffffffffffffffff8111156111dc57600080fd5b60006020828403121561128457600080fd5b8151801515811461111b57600080fd5b6000602082840312156112a657600080fd5b815161111b81610f5a565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006113306060830184866112b1565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261138a60c0830184866112b1565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006113c6606083018561109d565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a"; + hex"608060405234801561001057600080fd5b50600436106100d45760003560e01c80635d93a3fc11610081578063927ede2d1161005b578063927ede2d14610231578063aa5574521461024f578063c89701a21461026257600080fd5b80635d93a3fc146101cc578063761f4493146102005780637f46ddb21461021357600080fd5b8063485cc955116100b2578063485cc9551461015857806354fd4d501461016b5780635c975abb146101b457600080fd5b806335e80ab3146100d95780633687011a146101235780633cb747bf14610138575b600080fd5b6032546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610136610131366004610fe1565b610282565b005b6001546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b610136610166366004611064565b61032e565b6101a76040518060400160405280600c81526020017f322e312e312d626574612e32000000000000000000000000000000000000000081525081565b60405161011a9190611108565b6101bc610518565b604051901515815260200161011a565b6101bc6101da366004611122565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b61013661020e366004611163565b6105b1565b60025473ffffffffffffffffffffffffffffffffffffffff166100f9565b60015473ffffffffffffffffffffffffffffffffffffffff166100f9565b61013661025d3660046111fb565b610a58565b6002546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b333b15610316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b6103268686333388888888610b30565b505050505050565b600054610100900460ff161580801561034e5750600054600160ff909116105b806103685750303b158015610368575060005460ff166001145b6103f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161030d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561045257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556104b083734200000000000000000000000000000000000014610e70565b801561051357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa158015610588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ac9190611272565b905090565b60015473ffffffffffffffffffffffffffffffffffffffff16331480156106865750600254600154604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691636e296e45916004808201926020929091908290030181865afa15801561064a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066e9190611294565b73ffffffffffffffffffffffffffffffffffffffff16145b610712576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f746865722062726964676500606482015260840161030d565b61071a610518565b15610781576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4c314552433732314272696467653a2070617573656400000000000000000000604482015260640161030d565b3073ffffffffffffffffffffffffffffffffffffffff881603610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c6600000000000000000000000000000000000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff1615156001146108f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c312042726964676500000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156109b557600080fd5b505af11580156109c9573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac87878787604051610a4794939291906112fa565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610afb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f74206265206164647265737328302900000000000000000000000000000000606482015260840161030d565b610b0b8787338888888888610b30565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b73ffffffffffffffffffffffffffffffffffffffff8716610bd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f742062652061646472657373283029000000000000000000000000000000606482015260840161030d565b600063761f449360e01b888a8989898888604051602401610bfa979695949392919061133a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610d3a57600080fd5b505af1158015610d4e573d6000803e3d6000fd5b50506001546002546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450633dbb202b9350610db1929091169085908990600401611397565b600060405180830381600087803b158015610dcb57600080fd5b505af1158015610ddf573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610e5d94939291906112fa565b60405180910390a4505050505050505050565b600054610100900460ff16610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161030d565b6001805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560028054929093169116179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610f7c57600080fd5b50565b803563ffffffff81168114610f9357600080fd5b919050565b60008083601f840112610faa57600080fd5b50813567ffffffffffffffff811115610fc257600080fd5b602083019150836020828501011115610fda57600080fd5b9250929050565b60008060008060008060a08789031215610ffa57600080fd5b863561100581610f5a565b9550602087013561101581610f5a565b94506040870135935061102a60608801610f7f565b9250608087013567ffffffffffffffff81111561104657600080fd5b61105289828a01610f98565b979a9699509497509295939492505050565b6000806040838503121561107757600080fd5b823561108281610f5a565b9150602083013561109281610f5a565b809150509250929050565b6000815180845260005b818110156110c3576020818501810151868301820152016110a7565b818111156110d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061111b602083018461109d565b9392505050565b60008060006060848603121561113757600080fd5b833561114281610f5a565b9250602084013561115281610f5a565b929592945050506040919091013590565b600080600080600080600060c0888a03121561117e57600080fd5b873561118981610f5a565b9650602088013561119981610f5a565b955060408801356111a981610f5a565b945060608801356111b981610f5a565b93506080880135925060a088013567ffffffffffffffff8111156111dc57600080fd5b6111e88a828b01610f98565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561121657600080fd5b873561122181610f5a565b9650602088013561123181610f5a565b9550604088013561124181610f5a565b94506060880135935061125660808901610f7f565b925060a088013567ffffffffffffffff8111156111dc57600080fd5b60006020828403121561128457600080fd5b8151801515811461111b57600080fd5b6000602082840312156112a657600080fd5b815161111b81610f5a565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006113306060830184866112b1565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261138a60c0830184866112b1565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006113c6606083018561109d565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a"; bytes internal constant optimismPortalCode = - hex"6080604052600436106101635760003560e01c80638c3152e9116100c0578063b69ef8a811610074578063cff0ab9611610059578063cff0ab9614610444578063e965084c146104e5578063e9e05c421461057157600080fd5b8063b69ef8a814610401578063c0c53b8b1461042457600080fd5b80639bf62d82116100a55780639bf62d821461036b578063a14238e714610398578063a35d99df146103c857600080fd5b80638c3152e91461031e5780639b5f694a1461033e57600080fd5b806354fd4d50116101175780636dbffb78116100fc5780636dbffb78146102de57806371cfaa3f146102fe5780638b4c40b01461018857600080fd5b806354fd4d501461026d5780635c975abb146102b957600080fd5b806335e80ab31161014857806335e80ab314610206578063452a9320146102385780634870496f1461024d57600080fd5b8063149f2f221461018f57806333d7e2bd146101af57600080fd5b3661018a576101883334620186a060006040518060200160405280600081525061057f565b005b600080fd5b34801561019b57600080fd5b506101886101aa366004614b97565b610624565b3480156101bb57600080fd5b506037546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561021257600080fd5b506035546101dc90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561024457600080fd5b506101dc610865565b34801561025957600080fd5b50610188610268366004614ccb565b6108fd565b34801561027957600080fd5b50604080518082018252600c81527f322e382e312d626574612e310000000000000000000000000000000000000000602082015290516101fd9190614e1d565b3480156102c557600080fd5b506102ce610eaa565b60405190151581526020016101fd565b3480156102ea57600080fd5b506102ce6102f9366004614e30565b610f3d565b34801561030a57600080fd5b50610188610319366004614e58565b610ff8565b34801561032a57600080fd5b50610188610339366004614e9e565b6111ba565b34801561034a57600080fd5b506036546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561037757600080fd5b506032546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103a457600080fd5b506102ce6103b3366004614e30565b60336020526000908152604090205460ff1681565b3480156103d457600080fd5b506103e86103e3366004614edb565b611c3c565b60405167ffffffffffffffff90911681526020016101fd565b34801561040d57600080fd5b50610416611c55565b6040519081526020016101fd565b34801561043057600080fd5b5061018861043f366004614ef6565b611caf565b34801561045057600080fd5b506001546104ac906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101fd565b3480156104f157600080fd5b50610543610500366004614e30565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101fd565b61018861057f366004614f41565b8260005a9050600061058f611f19565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906105cb57503415155b15610602576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610610883489898989611fb6565b5061061b8282612162565b50505050505050565b8260005a90506000610634611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016106a6576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546106b89190614fed565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561072a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074e9190615005565b905061077273ffffffffffffffffffffffffffffffffffffffff831633308c61242f565b61077c8982614fed565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa1580156107e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080a9190615005565b14610841576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61084f8a8a8a8a8a8a611fb6565b505061085b8282612162565b5050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f8919061501e565b905090565b610905610eaa565b1561093c576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16036109a5576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6036546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810186905260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610a15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a39919061505b565b519050610a53610a4e368690038601866150c0565b61250b565b8114610ae6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f66000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000610af187612567565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610c075750805160365460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610bdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c03919061505b565b5114155b610c93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610add565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610d5c9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610d52888a615126565b8a60400135612597565b610de8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610add565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f19573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906151aa565b6036546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101839052600091610ff29173ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd7919061505b565b602001516fffffffffffffffffffffffffffffffff166125bb565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff163314611049576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61105562030d40612661565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f000000000000000000000000000000000000000000000000000000001790529051611172969594939291016151c7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526111aa91614e1d565b60405180910390a450505050565b565b6111c2610eaa565b156111f9576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461124c576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061125782612567565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610add565b603660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d39190615005565b81602001516fffffffffffffffffffffffffffffffff16101561149e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610add565b6114bd81602001516fffffffffffffffffffffffffffffffff166125bb565b61156f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610add565b60365460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a919061505b565b82518151919250146116d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610add565b6116f381602001516fffffffffffffffffffffffffffffffff166125bb565b6117a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610add565b60008381526033602052604090205460ff1615611844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610add565b6000838152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558501516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055806118cf611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016119325761192b8660400151876080015188606001518960a001516126c3565b9150611b85565b8073ffffffffffffffffffffffffffffffffffffffff16866040015173ffffffffffffffffffffffffffffffffffffffff160361199b576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606086015115611b5c578560600151603d60008282546119bb919061522c565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015611a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a519190615005565b9050611a86876040015188606001518473ffffffffffffffffffffffffffffffffffffffff166127219092919063ffffffff16565b6060870151611a95908261522c565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015611aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b239190615005565b14611b5a576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08601515115611b805761192b8660400151876080015160008960a001516126c3565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405185907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90611be790851515815260200190565b60405180910390a281158015611bfd5750326001145b15611c34576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b6000611c49826010615243565b610ff290615208615273565b600080611c60611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601611ca7574791505090565b5050603d5490565b600054610100900460ff1615808015611ccf5750600054600160ff909116105b80611ce95750303b158015611ce9575060005460ff166001145b611d75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610add565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611dd357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603680547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8781169190911790925560378054909116858316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101008584160217905560325416611e8c57603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b611e9461277c565b8015611ef757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015611f89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fad919061529f565b90939092509050565b818015611fd8575073ffffffffffffffffffffffffffffffffffffffff861615155b1561200f576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120198151611c3c565b67ffffffffffffffff168367ffffffffffffffff161015612066576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c0815111156120a4576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333281146120c5575033731111000000000000000000000000000000001111015b600086868686866040516020016120e09594939291906151c7565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516121509190614e1d565b60405180910390a45050505050505050565b600154600090612198907801000000000000000000000000000000000000000000000000900467ffffffffffffffff164361522c565b905060006121a461288f565b90506000816020015160ff16826000015163ffffffff166121c59190615308565b905082156122fc576001546000906121fc908390700100000000000000000000000000000000900467ffffffffffffffff16615370565b90506000836040015160ff168361221391906153e4565b6001546122339084906fffffffffffffffffffffffffffffffff166153e4565b61223d9190615308565b60015490915060009061228e906122679084906fffffffffffffffffffffffffffffffff166154a0565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612950565b905060018611156122bd576122ba61226782876040015160ff1660018a6122b5919061522c565b61296f565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b6001805486919060109061232f908490700100000000000000000000000000000000900467ffffffffffffffff16615273565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1613156123bc576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906123e8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615514565b905060006123fa48633b9aca006129c4565b6124049083615551565b905060005a612413908861522c565b90508082111561085b5761085b61242a828461522c565b6129db565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052611ef79085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612a04565b6000816000015182602001518360400151846060015160405160200161254a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a0880151935160009761254a979096959101615565565b6000806125a386612b10565b90506125b181868686612b42565b9695505050505050565b603654604080517ff4daa291000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163f4daa2919160048083019260209291908290030181865afa15801561262b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264f9190615005565b6126599083614fed565b421192915050565b6001805463ffffffff8316919060109061269a908490700100000000000000000000000000000000900467ffffffffffffffff16615273565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b60008060006126d3866000612b72565b905080612709576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526127779084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612489565b505050565b600054610100900460ff16612813576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610add565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff166000036111b85760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa15801561292c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906155d0565b600061296561295f8585612b90565b83612ba0565b90505b9392505050565b6000670de0b6b3a76400006129b06129878583615308565b61299990670de0b6b3a7640000615370565b6129ab85670de0b6b3a76400006153e4565b612baf565b6129ba90866153e4565b6129659190615308565b6000818310156129d45781612968565b5090919050565b6000805a90505b825a6129ee908361522c565b1015612777576129fd82615673565b91506129e2565b6000612a66826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612be09092919063ffffffff16565b8051909150156127775780806020019051810190612a8491906151aa565b612777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610add565b60608180519060200120604051602001612b2c91815260200190565b6040516020818303038152906040529050919050565b6000612b6984612b53878686612bef565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000818312156129d45781612968565b60008183126129d45781612968565b6000612968670de0b6b3a764000083612bc78661366d565b612bd191906153e4565b612bdb9190615308565b6138b1565b60606129658484600085613af0565b60606000845111612c5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610add565b6000612c6784613c86565b90506000612c7486613d72565b9050600084604051602001612c8b91815260200190565b60405160208183030381529060405290506000805b84518110156135e4576000858281518110612cbd57612cbd6156ab565b602002602001015190508451831115612d58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610add565b82600003612e115780518051602091820120604051612da692612d8092910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610add565b612f68565b805151602011612ec75780518051602091820120604051612e3b92612d8092910190815260200190565b612e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610add565b805184516020808701919091208251919092012014612f68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610add565b612f7460106001614fed565b8160200151510361315057845183036130e857612fae8160200151601081518110612fa157612fa16156ab565b6020026020010151613dd5565b96506000875111613041576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610add565b6001865161304f919061522c565b82146130dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610add565b505050505050612968565b60008584815181106130fc576130fc6156ab565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110613127576131276156ab565b6020026020010151905061313a81613e89565b9550613147600186614fed565b945050506135d1565b60028160200151510361354957600061316882613eae565b905060008160008151811061317f5761317f6156ab565b016020015160f81c905060006131966002836156da565b6131a19060026156fc565b905060006131b2848360ff16613ed2565b905060006131c08a89613ed2565b905060006131ce8383613f08565b905080835114613260576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610add565b60ff851660021480613275575060ff85166003145b15613464578082511461330a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610add565b6133248760200151600181518110612fa157612fa16156ab565b9c5060008d51116133b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610add565b60018c516133c5919061522c565b8814613453576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610add565b505050505050505050505050612968565b60ff85161580613477575060ff85166001145b156134b6576134a38760200151600181518110613496576134966156ab565b6020026020010151613e89565b99506134af818a614fed565b985061353e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610add565b5050505050506135d1565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610add565b50806135dc81615673565b915050612ca0565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610add565b60008082136136d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b600060606136e584613fbc565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136138e257506000919050565b680755bf798b4a1bf1e58212613954576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610add565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613b82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610add565b73ffffffffffffffffffffffffffffffffffffffff85163b613c00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610add565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613c29919061571f565b60006040518083038185875af1925050503d8060008114613c66576040519150601f19603f3d011682016040523d82523d6000602084013e613c6b565b606091505b5091509150613c7b828286614092565b979650505050505050565b80516060908067ffffffffffffffff811115613ca457613ca4614a8b565b604051908082528060200260200182016040528015613ce957816020015b6040805180820190915260608082526020820152815260200190600190039081613cc25790505b50915060005b81811015613d6b576040518060400160405280858381518110613d1457613d146156ab565b60200260200101518152602001613d43868481518110613d3657613d366156ab565b60200260200101516140e5565b815250838281518110613d5857613d586156ab565b6020908102919091010152600101613cef565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015613dca578060011b82018184015160001a8060041c8253600f811660018301535050600101613d9c565b509295945050505050565b60606000806000613de5856140f8565b919450925090506000816001811115613e0057613e0061573b565b14613e37576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613e418284614fed565b855114613e7a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b6985602001518484614596565b60606020826000015110613ea557613ea082613dd5565b610ff2565b610ff28261462a565b6060610ff2613ecd8360200151600081518110612fa157612fa16156ab565b613d72565b606082518210613ef15750604080516020810190915260008152610ff2565b6129688383848651613f03919061522c565b614640565b6000808251845110613f1b578251613f1e565b83515b90505b8082108015613fa55750828281518110613f3d57613f3d6156ab565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613f7c57613f7c6156ab565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15613fb557816001019150613f21565b5092915050565b6000808211614027576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606083156140a1575081612968565b8251156140b15782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610add9190614e1d565b6060610ff26140f383614818565b614885565b6000806000836000015160000361413b576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f811161416057600060016000945094509450505061458f565b60b7811161427657600061417560808361522c565b9050808760000151116141b4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214801561422c57507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614263576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061458f915050565b60bf81116143d457600061428b60b78361522c565b9050808760000151116142ca576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361432c576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614374576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61437e8184614fed565b8951116143b7576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6143c2836001614fed565b975095506000945061458f9350505050565b60f781116144395760006143e960c08361522c565b905080876000015111614428576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061458f915050565b600061444660f78361522c565b905080876000015111614485576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036144e7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c6037811161452f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6145398184614fed565b895111614572576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61457d836001614fed565b975095506001945061458f9350505050565b9193909250565b60608167ffffffffffffffff8111156145b1576145b1614a8b565b6040519080825280601f01601f1916602001820160405280156145db576020820181803683370190505b50905081156129685760006145f08486614fed565b90506020820160005b848110156146115782810151828201526020016145f9565b84811115614620576000858301525b5050509392505050565b6060610ff2826020015160008460000151614596565b60608182601f0110156146af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b82828401101561471b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b81830184511015614788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610add565b6060821580156147a7576040519150600082526020820160405261480f565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156147e05780518352602092830192016147c8565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201528151600003614867576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000614895856140f8565b9194509250905060018160018111156148b0576148b061573b565b146148e7576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516148f38385614fed565b1461492a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816149415790505093506000835b8651811015614a2f576000806149b46040518060400160405280858c60000151614998919061522c565b8152602001858c602001516149ad9190614fed565b90526140f8565b5091509150604051806040016040528083836149d09190614fed565b8152602001848b602001516149e59190614fed565b8152508885815181106149fa576149fa6156ab565b6020908102919091010152614a10600185614fed565b9350614a1c8183614fed565b614a269084614fed565b9250505061496e565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114614a5d57600080fd5b50565b803567ffffffffffffffff81168114614a7857600080fd5b919050565b8015158114614a5d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614b0157614b01614a8b565b604052919050565b600082601f830112614b1a57600080fd5b813567ffffffffffffffff811115614b3457614b34614a8b565b614b6560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614aba565b818152846020838601011115614b7a57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614bb057600080fd5b8635614bbb81614a3b565b95506020870135945060408701359350614bd760608801614a60565b92506080870135614be781614a7d565b915060a087013567ffffffffffffffff811115614c0357600080fd5b614c0f89828a01614b09565b9150509295509295509295565b600060c08284031215614c2e57600080fd5b60405160c0810167ffffffffffffffff8282108183111715614c5257614c52614a8b565b816040528293508435835260208501359150614c6d82614a3b565b81602084015260408501359150614c8382614a3b565b816040840152606085013560608401526080850135608084015260a0850135915080821115614cb157600080fd5b50614cbe85828601614b09565b60a0830152505092915050565b600080600080600085870360e0811215614ce457600080fd5b863567ffffffffffffffff80821115614cfc57600080fd5b614d088a838b01614c1c565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614d4157600080fd5b60408901955060c0890135925080831115614d5b57600080fd5b828901925089601f840112614d6f57600080fd5b8235915080821115614d8057600080fd5b508860208260051b8401011115614d9657600080fd5b959894975092955050506020019190565b60005b83811015614dc2578181015183820152602001614daa565b83811115611ef75750506000910152565b60008151808452614deb816020860160208601614da7565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006129686020830184614dd3565b600060208284031215614e4257600080fd5b5035919050565b60ff81168114614a5d57600080fd5b60008060008060808587031215614e6e57600080fd5b8435614e7981614a3b565b93506020850135614e8981614e49565b93969395505050506040820135916060013590565b600060208284031215614eb057600080fd5b813567ffffffffffffffff811115614ec757600080fd5b614ed384828501614c1c565b949350505050565b600060208284031215614eed57600080fd5b61296882614a60565b600080600060608486031215614f0b57600080fd5b8335614f1681614a3b565b92506020840135614f2681614a3b565b91506040840135614f3681614a3b565b809150509250925092565b600080600080600060a08688031215614f5957600080fd5b8535614f6481614a3b565b945060208601359350614f7960408701614a60565b92506060860135614f8981614a7d565b9150608086013567ffffffffffffffff811115614fa557600080fd5b614fb188828901614b09565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561500057615000614fbe565b500190565b60006020828403121561501757600080fd5b5051919050565b60006020828403121561503057600080fd5b815161296881614a3b565b80516fffffffffffffffffffffffffffffffff81168114614a7857600080fd5b60006060828403121561506d57600080fd5b6040516060810181811067ffffffffffffffff8211171561509057615090614a8b565b604052825181526150a36020840161503b565b60208201526150b46040840161503b565b60408201529392505050565b6000608082840312156150d257600080fd5b6040516080810181811067ffffffffffffffff821117156150f5576150f5614a8b565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff8084111561514157615141614a8b565b8360051b6020615152818301614aba565b86815291850191818101903684111561516a57600080fd5b865b8481101561519e578035868111156151845760008081fd5b61519036828b01614b09565b84525091830191830161516c565b50979650505050505050565b6000602082840312156151bc57600080fd5b815161296881614a7d565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b60488201526000825161521b816049850160208701614da7565b919091016049019695505050505050565b60008282101561523e5761523e614fbe565b500390565b600067ffffffffffffffff8083168185168183048111821515161561526a5761526a614fbe565b02949350505050565b600067ffffffffffffffff80831681851680830382111561529657615296614fbe565b01949350505050565b600080604083850312156152b257600080fd5b82516152bd81614a3b565b60208401519092506152ce81614e49565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615317576153176152d9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561536b5761536b614fbe565b500590565b6000808312837f8000000000000000000000000000000000000000000000000000000000000000018312811516156153aa576153aa614fbe565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156153de576153de614fbe565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561542557615425614fbe565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561546057615460614fbe565b6000871292508782058712848416161561547c5761547c614fbe565b8785058712818416161561549257615492614fbe565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156154da576154da614fbe565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561550e5761550e614fbe565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561554c5761554c614fbe565b500290565b600082615560576155606152d9565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526155b060c0830184614dd3565b98975050505050505050565b805163ffffffff81168114614a7857600080fd5b600060c082840312156155e257600080fd5b60405160c0810181811067ffffffffffffffff8211171561560557615605614a8b565b604052615611836155bc565b8152602083015161562181614e49565b6020820152604083015161563481614e49565b6040820152615645606084016155bc565b6060820152615656608084016155bc565b608082015261566760a0840161503b565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036156a4576156a4614fbe565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806156ed576156ed6152d9565b8060ff84160691505092915050565b600060ff821660ff84168082101561571657615716614fbe565b90039392505050565b60008251615731818460208701614da7565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a"; + hex"6080604052600436106101635760003560e01c80638c3152e9116100c0578063b69ef8a811610074578063cff0ab9611610059578063cff0ab9614610444578063e965084c146104e5578063e9e05c421461057157600080fd5b8063b69ef8a814610401578063c0c53b8b1461042457600080fd5b80639bf62d82116100a55780639bf62d821461036b578063a14238e714610398578063a35d99df146103c857600080fd5b80638c3152e91461031e5780639b5f694a1461033e57600080fd5b806354fd4d50116101175780636dbffb78116100fc5780636dbffb78146102de57806371cfaa3f146102fe5780638b4c40b01461018857600080fd5b806354fd4d501461026d5780635c975abb146102b957600080fd5b806335e80ab31161014857806335e80ab314610206578063452a9320146102385780634870496f1461024d57600080fd5b8063149f2f221461018f57806333d7e2bd146101af57600080fd5b3661018a576101883334620186a060006040518060200160405280600081525061057f565b005b600080fd5b34801561019b57600080fd5b506101886101aa366004614b97565b610624565b3480156101bb57600080fd5b506037546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561021257600080fd5b506035546101dc90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561024457600080fd5b506101dc610865565b34801561025957600080fd5b50610188610268366004614ccb565b6108fd565b34801561027957600080fd5b50604080518082018252600c81527f322e382e312d626574612e320000000000000000000000000000000000000000602082015290516101fd9190614e1d565b3480156102c557600080fd5b506102ce610eaa565b60405190151581526020016101fd565b3480156102ea57600080fd5b506102ce6102f9366004614e30565b610f3d565b34801561030a57600080fd5b50610188610319366004614e58565b610ff8565b34801561032a57600080fd5b50610188610339366004614e9e565b6111ba565b34801561034a57600080fd5b506036546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561037757600080fd5b506032546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103a457600080fd5b506102ce6103b3366004614e30565b60336020526000908152604090205460ff1681565b3480156103d457600080fd5b506103e86103e3366004614edb565b611c3c565b60405167ffffffffffffffff90911681526020016101fd565b34801561040d57600080fd5b50610416611c55565b6040519081526020016101fd565b34801561043057600080fd5b5061018861043f366004614ef6565b611caf565b34801561045057600080fd5b506001546104ac906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101fd565b3480156104f157600080fd5b50610543610500366004614e30565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101fd565b61018861057f366004614f41565b8260005a9050600061058f611f19565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906105cb57503415155b15610602576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610610883489898989611fb6565b5061061b8282612162565b50505050505050565b8260005a90506000610634611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016106a6576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546106b89190614fed565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561072a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074e9190615005565b905061077273ffffffffffffffffffffffffffffffffffffffff831633308c61242f565b61077c8982614fed565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa1580156107e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080a9190615005565b14610841576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61084f8a8a8a8a8a8a611fb6565b505061085b8282612162565b5050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f8919061501e565b905090565b610905610eaa565b1561093c576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16036109a5576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6036546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810186905260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610a15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a39919061505b565b519050610a53610a4e368690038601866150c0565b61250b565b8114610ae6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f66000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000610af187612567565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610c075750805160365460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610bdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c03919061505b565b5114155b610c93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610add565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610d5c9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610d52888a615126565b8a60400135612597565b610de8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610add565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f19573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906151aa565b6036546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101839052600091610ff29173ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd7919061505b565b602001516fffffffffffffffffffffffffffffffff166125bb565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff163314611049576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61105562030d40612661565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f000000000000000000000000000000000000000000000000000000001790529051611172969594939291016151c7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526111aa91614e1d565b60405180910390a450505050565b565b6111c2610eaa565b156111f9576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461124c576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061125782612567565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610add565b603660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d39190615005565b81602001516fffffffffffffffffffffffffffffffff16101561149e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610add565b6114bd81602001516fffffffffffffffffffffffffffffffff166125bb565b61156f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610add565b60365460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a919061505b565b82518151919250146116d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610add565b6116f381602001516fffffffffffffffffffffffffffffffff166125bb565b6117a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610add565b60008381526033602052604090205460ff1615611844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610add565b6000838152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558501516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055806118cf611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016119325761192b8660400151876080015188606001518960a001516126c3565b9150611b85565b8073ffffffffffffffffffffffffffffffffffffffff16866040015173ffffffffffffffffffffffffffffffffffffffff160361199b576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606086015115611b5c578560600151603d60008282546119bb919061522c565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015611a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a519190615005565b9050611a86876040015188606001518473ffffffffffffffffffffffffffffffffffffffff166127219092919063ffffffff16565b6060870151611a95908261522c565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015611aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b239190615005565b14611b5a576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08601515115611b805761192b8660400151876080015160008960a001516126c3565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405185907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90611be790851515815260200190565b60405180910390a281158015611bfd5750326001145b15611c34576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b6000611c49826010615243565b610ff290615208615273565b600080611c60611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601611ca7574791505090565b5050603d5490565b600054610100900460ff1615808015611ccf5750600054600160ff909116105b80611ce95750303b158015611ce9575060005460ff166001145b611d75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610add565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611dd357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603680547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8781169190911790925560378054909116858316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101008584160217905560325416611e8c57603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b611e9461277c565b8015611ef757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015611f89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fad919061529f565b90939092509050565b818015611fd8575073ffffffffffffffffffffffffffffffffffffffff861615155b1561200f576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120198151611c3c565b67ffffffffffffffff168367ffffffffffffffff161015612066576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c0815111156120a4576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333281146120c5575033731111000000000000000000000000000000001111015b600086868686866040516020016120e09594939291906151c7565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516121509190614e1d565b60405180910390a45050505050505050565b600154600090612198907801000000000000000000000000000000000000000000000000900467ffffffffffffffff164361522c565b905060006121a461288f565b90506000816020015160ff16826000015163ffffffff166121c59190615308565b905082156122fc576001546000906121fc908390700100000000000000000000000000000000900467ffffffffffffffff16615370565b90506000836040015160ff168361221391906153e4565b6001546122339084906fffffffffffffffffffffffffffffffff166153e4565b61223d9190615308565b60015490915060009061228e906122679084906fffffffffffffffffffffffffffffffff166154a0565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612950565b905060018611156122bd576122ba61226782876040015160ff1660018a6122b5919061522c565b61296f565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b6001805486919060109061232f908490700100000000000000000000000000000000900467ffffffffffffffff16615273565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1613156123bc576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906123e8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615514565b905060006123fa48633b9aca006129c4565b6124049083615551565b905060005a612413908861522c565b90508082111561085b5761085b61242a828461522c565b6129db565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052611ef79085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612a04565b6000816000015182602001518360400151846060015160405160200161254a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a0880151935160009761254a979096959101615565565b6000806125a386612b10565b90506125b181868686612b42565b9695505050505050565b603654604080517ff4daa291000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163f4daa2919160048083019260209291908290030181865afa15801561262b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264f9190615005565b6126599083614fed565b421192915050565b6001805463ffffffff8316919060109061269a908490700100000000000000000000000000000000900467ffffffffffffffff16615273565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b60008060006126d3866000612b72565b905080612709576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526127779084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612489565b505050565b600054610100900460ff16612813576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610add565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff166000036111b85760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa15801561292c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906155d0565b600061296561295f8585612b90565b83612ba0565b90505b9392505050565b6000670de0b6b3a76400006129b06129878583615308565b61299990670de0b6b3a7640000615370565b6129ab85670de0b6b3a76400006153e4565b612baf565b6129ba90866153e4565b6129659190615308565b6000818310156129d45781612968565b5090919050565b6000805a90505b825a6129ee908361522c565b1015612777576129fd82615673565b91506129e2565b6000612a66826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612be09092919063ffffffff16565b8051909150156127775780806020019051810190612a8491906151aa565b612777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610add565b60608180519060200120604051602001612b2c91815260200190565b6040516020818303038152906040529050919050565b6000612b6984612b53878686612bef565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000818312156129d45781612968565b60008183126129d45781612968565b6000612968670de0b6b3a764000083612bc78661366d565b612bd191906153e4565b612bdb9190615308565b6138b1565b60606129658484600085613af0565b60606000845111612c5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610add565b6000612c6784613c86565b90506000612c7486613d72565b9050600084604051602001612c8b91815260200190565b60405160208183030381529060405290506000805b84518110156135e4576000858281518110612cbd57612cbd6156ab565b602002602001015190508451831115612d58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610add565b82600003612e115780518051602091820120604051612da692612d8092910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610add565b612f68565b805151602011612ec75780518051602091820120604051612e3b92612d8092910190815260200190565b612e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610add565b805184516020808701919091208251919092012014612f68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610add565b612f7460106001614fed565b8160200151510361315057845183036130e857612fae8160200151601081518110612fa157612fa16156ab565b6020026020010151613dd5565b96506000875111613041576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610add565b6001865161304f919061522c565b82146130dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610add565b505050505050612968565b60008584815181106130fc576130fc6156ab565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110613127576131276156ab565b6020026020010151905061313a81613e89565b9550613147600186614fed565b945050506135d1565b60028160200151510361354957600061316882613eae565b905060008160008151811061317f5761317f6156ab565b016020015160f81c905060006131966002836156da565b6131a19060026156fc565b905060006131b2848360ff16613ed2565b905060006131c08a89613ed2565b905060006131ce8383613f08565b905080835114613260576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610add565b60ff851660021480613275575060ff85166003145b15613464578082511461330a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610add565b6133248760200151600181518110612fa157612fa16156ab565b9c5060008d51116133b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610add565b60018c516133c5919061522c565b8814613453576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610add565b505050505050505050505050612968565b60ff85161580613477575060ff85166001145b156134b6576134a38760200151600181518110613496576134966156ab565b6020026020010151613e89565b99506134af818a614fed565b985061353e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610add565b5050505050506135d1565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610add565b50806135dc81615673565b915050612ca0565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610add565b60008082136136d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b600060606136e584613fbc565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136138e257506000919050565b680755bf798b4a1bf1e58212613954576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610add565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613b82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610add565b73ffffffffffffffffffffffffffffffffffffffff85163b613c00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610add565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613c29919061571f565b60006040518083038185875af1925050503d8060008114613c66576040519150601f19603f3d011682016040523d82523d6000602084013e613c6b565b606091505b5091509150613c7b828286614092565b979650505050505050565b80516060908067ffffffffffffffff811115613ca457613ca4614a8b565b604051908082528060200260200182016040528015613ce957816020015b6040805180820190915260608082526020820152815260200190600190039081613cc25790505b50915060005b81811015613d6b576040518060400160405280858381518110613d1457613d146156ab565b60200260200101518152602001613d43868481518110613d3657613d366156ab565b60200260200101516140e5565b815250838281518110613d5857613d586156ab565b6020908102919091010152600101613cef565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015613dca578060011b82018184015160001a8060041c8253600f811660018301535050600101613d9c565b509295945050505050565b60606000806000613de5856140f8565b919450925090506000816001811115613e0057613e0061573b565b14613e37576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613e418284614fed565b855114613e7a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b6985602001518484614596565b60606020826000015110613ea557613ea082613dd5565b610ff2565b610ff28261462a565b6060610ff2613ecd8360200151600081518110612fa157612fa16156ab565b613d72565b606082518210613ef15750604080516020810190915260008152610ff2565b6129688383848651613f03919061522c565b614640565b6000808251845110613f1b578251613f1e565b83515b90505b8082108015613fa55750828281518110613f3d57613f3d6156ab565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613f7c57613f7c6156ab565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15613fb557816001019150613f21565b5092915050565b6000808211614027576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606083156140a1575081612968565b8251156140b15782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610add9190614e1d565b6060610ff26140f383614818565b614885565b6000806000836000015160000361413b576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f811161416057600060016000945094509450505061458f565b60b7811161427657600061417560808361522c565b9050808760000151116141b4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214801561422c57507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614263576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061458f915050565b60bf81116143d457600061428b60b78361522c565b9050808760000151116142ca576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361432c576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614374576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61437e8184614fed565b8951116143b7576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6143c2836001614fed565b975095506000945061458f9350505050565b60f781116144395760006143e960c08361522c565b905080876000015111614428576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061458f915050565b600061444660f78361522c565b905080876000015111614485576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036144e7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c6037811161452f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6145398184614fed565b895111614572576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61457d836001614fed565b975095506001945061458f9350505050565b9193909250565b60608167ffffffffffffffff8111156145b1576145b1614a8b565b6040519080825280601f01601f1916602001820160405280156145db576020820181803683370190505b50905081156129685760006145f08486614fed565b90506020820160005b848110156146115782810151828201526020016145f9565b84811115614620576000858301525b5050509392505050565b6060610ff2826020015160008460000151614596565b60608182601f0110156146af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b82828401101561471b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b81830184511015614788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610add565b6060821580156147a7576040519150600082526020820160405261480f565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156147e05780518352602092830192016147c8565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201528151600003614867576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000614895856140f8565b9194509250905060018160018111156148b0576148b061573b565b146148e7576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516148f38385614fed565b1461492a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816149415790505093506000835b8651811015614a2f576000806149b46040518060400160405280858c60000151614998919061522c565b8152602001858c602001516149ad9190614fed565b90526140f8565b5091509150604051806040016040528083836149d09190614fed565b8152602001848b602001516149e59190614fed565b8152508885815181106149fa576149fa6156ab565b6020908102919091010152614a10600185614fed565b9350614a1c8183614fed565b614a269084614fed565b9250505061496e565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114614a5d57600080fd5b50565b803567ffffffffffffffff81168114614a7857600080fd5b919050565b8015158114614a5d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614b0157614b01614a8b565b604052919050565b600082601f830112614b1a57600080fd5b813567ffffffffffffffff811115614b3457614b34614a8b565b614b6560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614aba565b818152846020838601011115614b7a57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614bb057600080fd5b8635614bbb81614a3b565b95506020870135945060408701359350614bd760608801614a60565b92506080870135614be781614a7d565b915060a087013567ffffffffffffffff811115614c0357600080fd5b614c0f89828a01614b09565b9150509295509295509295565b600060c08284031215614c2e57600080fd5b60405160c0810167ffffffffffffffff8282108183111715614c5257614c52614a8b565b816040528293508435835260208501359150614c6d82614a3b565b81602084015260408501359150614c8382614a3b565b816040840152606085013560608401526080850135608084015260a0850135915080821115614cb157600080fd5b50614cbe85828601614b09565b60a0830152505092915050565b600080600080600085870360e0811215614ce457600080fd5b863567ffffffffffffffff80821115614cfc57600080fd5b614d088a838b01614c1c565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614d4157600080fd5b60408901955060c0890135925080831115614d5b57600080fd5b828901925089601f840112614d6f57600080fd5b8235915080821115614d8057600080fd5b508860208260051b8401011115614d9657600080fd5b959894975092955050506020019190565b60005b83811015614dc2578181015183820152602001614daa565b83811115611ef75750506000910152565b60008151808452614deb816020860160208601614da7565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006129686020830184614dd3565b600060208284031215614e4257600080fd5b5035919050565b60ff81168114614a5d57600080fd5b60008060008060808587031215614e6e57600080fd5b8435614e7981614a3b565b93506020850135614e8981614e49565b93969395505050506040820135916060013590565b600060208284031215614eb057600080fd5b813567ffffffffffffffff811115614ec757600080fd5b614ed384828501614c1c565b949350505050565b600060208284031215614eed57600080fd5b61296882614a60565b600080600060608486031215614f0b57600080fd5b8335614f1681614a3b565b92506020840135614f2681614a3b565b91506040840135614f3681614a3b565b809150509250925092565b600080600080600060a08688031215614f5957600080fd5b8535614f6481614a3b565b945060208601359350614f7960408701614a60565b92506060860135614f8981614a7d565b9150608086013567ffffffffffffffff811115614fa557600080fd5b614fb188828901614b09565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561500057615000614fbe565b500190565b60006020828403121561501757600080fd5b5051919050565b60006020828403121561503057600080fd5b815161296881614a3b565b80516fffffffffffffffffffffffffffffffff81168114614a7857600080fd5b60006060828403121561506d57600080fd5b6040516060810181811067ffffffffffffffff8211171561509057615090614a8b565b604052825181526150a36020840161503b565b60208201526150b46040840161503b565b60408201529392505050565b6000608082840312156150d257600080fd5b6040516080810181811067ffffffffffffffff821117156150f5576150f5614a8b565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff8084111561514157615141614a8b565b8360051b6020615152818301614aba565b86815291850191818101903684111561516a57600080fd5b865b8481101561519e578035868111156151845760008081fd5b61519036828b01614b09565b84525091830191830161516c565b50979650505050505050565b6000602082840312156151bc57600080fd5b815161296881614a7d565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b60488201526000825161521b816049850160208701614da7565b919091016049019695505050505050565b60008282101561523e5761523e614fbe565b500390565b600067ffffffffffffffff8083168185168183048111821515161561526a5761526a614fbe565b02949350505050565b600067ffffffffffffffff80831681851680830382111561529657615296614fbe565b01949350505050565b600080604083850312156152b257600080fd5b82516152bd81614a3b565b60208401519092506152ce81614e49565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615317576153176152d9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561536b5761536b614fbe565b500590565b6000808312837f8000000000000000000000000000000000000000000000000000000000000000018312811516156153aa576153aa614fbe565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156153de576153de614fbe565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561542557615425614fbe565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561546057615460614fbe565b6000871292508782058712848416161561547c5761547c614fbe565b8785058712818416161561549257615492614fbe565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156154da576154da614fbe565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561550e5761550e614fbe565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561554c5761554c614fbe565b500290565b600082615560576155606152d9565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526155b060c0830184614dd3565b98975050505050505050565b805163ffffffff81168114614a7857600080fd5b600060c082840312156155e257600080fd5b60405160c0810181811067ffffffffffffffff8211171561560557615605614a8b565b604052615611836155bc565b8152602083015161562181614e49565b6020820152604083015161563481614e49565b6040820152615645606084016155bc565b6060820152615656608084016155bc565b608082015261566760a0840161503b565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036156a4576156a4614fbe565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806156ed576156ed6152d9565b8060ff84160691505092915050565b600060ff821660ff84168082101561571657615716614fbe565b90039392505050565b60008251615731818460208701614da7565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a"; bytes internal constant l2OutputOracleCode = - hex"60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec33481461049b578063e1a41bcf146104b0578063f4daa291146104c657600080fd5b8063ce5db8d614610445578063cf8e5cf01461045b578063d1de856c1461047b57600080fd5b8063a25ae557116100b0578063a25ae55714610391578063a8e4fb90146103ed578063bffa7f0f1461041a57600080fd5b806389c44cbb1461034857806393991af3146103685780639aaab6481461037e57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa5146102fc5780637f00642014610312578063887862721461033257600080fd5b806369f16eec146102a75780636abcf563146102bc5780636b4d98dd146102d157600080fd5b8063529933df11610169578063529933df146101ea578063534db0e2146101ff57806354fd4d501461025157600080fd5b80622134cc1461018f5780631c89c97d146101b35780634599c788146101d5575b600080fd5b34801561019b57600080fd5b506005545b6040519081526020015b60405180910390f35b3480156101bf57600080fd5b506101d36101ce3660046113a2565b6104db565b005b3480156101e157600080fd5b506101a06108b6565b3480156101f657600080fd5b506004546101a0565b34801561020b57600080fd5b5060065461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101aa565b34801561025d57600080fd5b5061029a6040518060400160405280600581526020017f312e382e3000000000000000000000000000000000000000000000000000000081525081565b6040516101aa9190611405565b3480156102b357600080fd5b506101a0610929565b3480156102c857600080fd5b506003546101a0565b3480156102dd57600080fd5b5060065473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561030857600080fd5b506101a060015481565b34801561031e57600080fd5b506101a061032d366004611478565b61093b565b34801561033e57600080fd5b506101a060025481565b34801561035457600080fd5b506101d3610363366004611478565b610b4f565b34801561037457600080fd5b506101a060055481565b6101d361038c366004611491565b610de9565b34801561039d57600080fd5b506103b16103ac366004611478565b61124a565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101aa565b3480156103f957600080fd5b5060075461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561042657600080fd5b5060075473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561045157600080fd5b506101a060085481565b34801561046757600080fd5b506103b1610476366004611478565b6112de565b34801561048757600080fd5b506101a0610496366004611478565b611316565b3480156104a757600080fd5b506101a0611346565b3480156104bc57600080fd5b506101a060045481565b3480156104d257600080fd5b506008546101a0565b600054610100900460ff16158080156104fb5750600054600160ff909116105b806105155750303b158015610515575060005460ff166001145b6105a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561060457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60008811610694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e2030000000000000606482015260840161059d565b60008711610724576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e2030000000000000000000000000606482015260840161059d565b428511156107db576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60048890556005879055600186905560028590556007805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556006805492861692909116919091179055600882905580156108ac57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b6003546000901561092057600380546108d1906001906114f2565b815481106108e1576108e1611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b600354600090610924906001906114f2565b60006109456108b6565b8211156109fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161059d565b600354610aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161059d565b6003546000905b80821015610b485760006002610acc8385611538565b610ad69190611550565b90508460038281548110610aec57610aec611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610b3e57610b37816001611538565b9250610b42565b8091505b50610ab6565b5092915050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610bf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161059d565b6003548110610cad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60085460038281548110610cc357610cc3611509565b6000918252602090912060016002909202010154610cf3906fffffffffffffffffffffffffffffffff16426114f2565b10610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161059d565b6000610db160035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60075473ffffffffffffffffffffffffffffffffffffffff163314610eb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b610ebe611346565b8314610f72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161059d565b42610f7c84611316565b10611009576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161059d565b83611096576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161059d565b81156111525781814014611152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161059d565b8261115c60035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e24260405161118e91815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b60408051606081018252600080825260208201819052918101919091526003828154811061127a5761127a611509565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b604080516060810182526000808252602082018190529181019190915260036113068361093b565b8154811061127a5761127a611509565b60006005546001548361132991906114f2565b611333919061158b565b6002546113409190611538565b92915050565b60006004546113536108b6565b6109249190611538565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b803573ffffffffffffffffffffffffffffffffffffffff8116811461139d57600080fd5b919050565b600080600080600080600060e0888a0312156113bd57600080fd5b873596506020880135955060408801359450606088013593506113e260808901611379565b92506113f060a08901611379565b915060c0880135905092959891949750929550565b600060208083528351808285015260005b8181101561143257858101830151858201604001528201611416565b81811115611444576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561148a57600080fd5b5035919050565b600080600080608085870312156114a757600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611504576115046114c3565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000821982111561154b5761154b6114c3565b500190565b600082611586577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156115c3576115c36114c3565b50029056fea164736f6c634300080f000a"; + hex"60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec33481461049b578063e1a41bcf146104b0578063f4daa291146104c657600080fd5b8063ce5db8d614610445578063cf8e5cf01461045b578063d1de856c1461047b57600080fd5b8063a25ae557116100b0578063a25ae55714610391578063a8e4fb90146103ed578063bffa7f0f1461041a57600080fd5b806389c44cbb1461034857806393991af3146103685780639aaab6481461037e57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa5146102fc5780637f00642014610312578063887862721461033257600080fd5b806369f16eec146102a75780636abcf563146102bc5780636b4d98dd146102d157600080fd5b8063529933df11610169578063529933df146101ea578063534db0e2146101ff57806354fd4d501461025157600080fd5b80622134cc1461018f5780631c89c97d146101b35780634599c788146101d5575b600080fd5b34801561019b57600080fd5b506005545b6040519081526020015b60405180910390f35b3480156101bf57600080fd5b506101d36101ce3660046113a2565b6104db565b005b3480156101e157600080fd5b506101a06108b6565b3480156101f657600080fd5b506004546101a0565b34801561020b57600080fd5b5060065461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101aa565b34801561025d57600080fd5b5061029a6040518060400160405280600c81526020017f312e382e312d626574612e31000000000000000000000000000000000000000081525081565b6040516101aa9190611405565b3480156102b357600080fd5b506101a0610929565b3480156102c857600080fd5b506003546101a0565b3480156102dd57600080fd5b5060065473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561030857600080fd5b506101a060015481565b34801561031e57600080fd5b506101a061032d366004611478565b61093b565b34801561033e57600080fd5b506101a060025481565b34801561035457600080fd5b506101d3610363366004611478565b610b4f565b34801561037457600080fd5b506101a060055481565b6101d361038c366004611491565b610de9565b34801561039d57600080fd5b506103b16103ac366004611478565b61124a565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101aa565b3480156103f957600080fd5b5060075461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561042657600080fd5b5060075473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561045157600080fd5b506101a060085481565b34801561046757600080fd5b506103b1610476366004611478565b6112de565b34801561048757600080fd5b506101a0610496366004611478565b611316565b3480156104a757600080fd5b506101a0611346565b3480156104bc57600080fd5b506101a060045481565b3480156104d257600080fd5b506008546101a0565b600054610100900460ff16158080156104fb5750600054600160ff909116105b806105155750303b158015610515575060005460ff166001145b6105a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561060457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60008811610694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e2030000000000000606482015260840161059d565b60008711610724576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e2030000000000000000000000000606482015260840161059d565b428511156107db576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60048890556005879055600186905560028590556007805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556006805492861692909116919091179055600882905580156108ac57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b6003546000901561092057600380546108d1906001906114f2565b815481106108e1576108e1611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b600354600090610924906001906114f2565b60006109456108b6565b8211156109fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161059d565b600354610aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161059d565b6003546000905b80821015610b485760006002610acc8385611538565b610ad69190611550565b90508460038281548110610aec57610aec611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610b3e57610b37816001611538565b9250610b42565b8091505b50610ab6565b5092915050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610bf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161059d565b6003548110610cad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60085460038281548110610cc357610cc3611509565b6000918252602090912060016002909202010154610cf3906fffffffffffffffffffffffffffffffff16426114f2565b10610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161059d565b6000610db160035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60075473ffffffffffffffffffffffffffffffffffffffff163314610eb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b610ebe611346565b8314610f72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161059d565b42610f7c84611316565b10611009576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161059d565b83611096576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161059d565b81156111525781814014611152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161059d565b8261115c60035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e24260405161118e91815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b60408051606081018252600080825260208201819052918101919091526003828154811061127a5761127a611509565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b604080516060810182526000808252602082018190529181019190915260036113068361093b565b8154811061127a5761127a611509565b60006005546001548361132991906114f2565b611333919061158b565b6002546113409190611538565b92915050565b60006004546113536108b6565b6109249190611538565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b803573ffffffffffffffffffffffffffffffffffffffff8116811461139d57600080fd5b919050565b600080600080600080600060e0888a0312156113bd57600080fd5b873596506020880135955060408801359450606088013593506113e260808901611379565b92506113f060a08901611379565b915060c0880135905092959891949750929550565b600060208083528351808285015260005b8181101561143257858101830151858201604001528201611416565b81811115611444576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561148a57600080fd5b5035919050565b600080600080608085870312156114a757600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611504576115046114c3565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000821982111561154b5761154b6114c3565b500190565b600082611586577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156115c3576115c36114c3565b50029056fea164736f6c634300080f000a"; bytes internal constant optimismPortal2Code = - hex"6080604052600436106101d15760003560e01c80637fc48504116100f7578063a35d99df11610095578063bf653a5c11610064578063bf653a5c14610697578063cff0ab96146106ca578063e9e05c421461076b578063f2b4e6171461077e57600080fd5b8063a35d99df1461059b578063a3860f48146105bb578063b69ef8a8146105db578063bb2c727e146105f057600080fd5b80638e819e54116100d15780638e819e54146104eb578063952b27971461050b5780639bf62d821461053e578063a14238e71461056b57600080fd5b80637fc48504146104ab5780638b4c40b0146101f65780638c3152e9146104cb57600080fd5b80634870496f1161016f5780635c975abb1161013e5780635c975abb1461043657806371c1566e1461044b57806371cfaa3f1461046b5780637d6be8dc1461048b57600080fd5b80634870496f1461034d5780634fd0434c1461036d578063513747ab146103af57806354fd4d50146103ea57600080fd5b80633c9f397c116101ab5780633c9f397c146102a657806343ca1c50146102d8578063452a9320146102f857806345884d321461030d57600080fd5b8063149f2f22146101fd57806333d7e2bd1461021d57806335e80ab31461027457600080fd5b366101f8576101f63334620186a06000604051806020016040528060008152506107ab565b005b600080fd5b34801561020957600080fd5b506101f6610218366004614fe6565b610850565b34801561022957600080fd5b5060375461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561028057600080fd5b5060355461024a90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156102b257600080fd5b50603b546102c39063ffffffff1681565b60405163ffffffff909116815260200161026b565b3480156102e457600080fd5b506101f66102f336600461511c565b610a91565b34801561030457600080fd5b5061024a610f31565b34801561031957600080fd5b5061033d61032836600461516e565b603a6020526000908152604090205460ff1681565b604051901515815260200161026b565b34801561035957600080fd5b506101f661036836600461518b565b610fc9565b34801561037957600080fd5b50603b5461039690640100000000900467ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161026b565b3480156103bb57600080fd5b506103dc6103ca366004615267565b6000908152603c602052604090205490565b60405190815260200161026b565b3480156103f657600080fd5b50604080518082018252600d81527f332e31312e302d626574612e32000000000000000000000000000000000000006020820152905161026b91906152f6565b34801561044257600080fd5b5061033d611531565b34801561045757600080fd5b506101f6610466366004615309565b6115c4565b34801561047757600080fd5b506101f661048636600461533d565b611c7f565b34801561049757600080fd5b506101f66104a636600461516e565b611e3f565b3480156104b757600080fd5b506101f66104c6366004615395565b611f22565b3480156104d757600080fd5b506101f66104e63660046153b2565b61200e565b3480156104f757600080fd5b506101f66105063660046153ef565b61205a565b34801561051757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000066103dc565b34801561054a57600080fd5b5060325461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561057757600080fd5b5061033d610586366004615267565b60336020526000908152604090205460ff1681565b3480156105a757600080fd5b506103966105b636600461544b565b61230f565b3480156105c757600080fd5b5061024a6105d6366004615468565b61232e565b3480156105e757600080fd5b506103dc612373565b3480156105fc57600080fd5b5061066261060b366004615309565b603960209081526000928352604080842090915290825290205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900467ffffffffffffffff1682565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff90911660208301520161026b565b3480156106a357600080fd5b507f000000000000000000000000000000000000000000000000000000000000000c6103dc565b3480156106d657600080fd5b50600154610732906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff928316602085015291169082015260600161026b565b6101f661077936600461548a565b6107ab565b34801561078a57600080fd5b5060385461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b8260005a905060006107bb6123e9565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906107f757503415155b1561082e576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61083c883489898989612486565b506108478282612632565b50505050505050565b8260005a905060006108606123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016108d2576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546108e49190615538565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610956573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097a9190615550565b905061099e73ffffffffffffffffffffffffffffffffffffffff831633308c6128ff565b6109a88982615538565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a369190615550565b14610a6d576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a7b8a8a8a8a8a8a612486565b5050610a878282612632565b5050505050505050565b610a99611531565b15610ad0576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead14610b23576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610b2e836129e1565b9050610b3a81836115c4565b6000818152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558401516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905580610bc56123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601610c2857610c218560400151866080015187606001518860a00151612a2e565b9150610e7b565b8073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610c91576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606085015115610e52578460600151603d6000828254610cb19190615569565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610d23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d479190615550565b9050610d7c866040015187606001518473ffffffffffffffffffffffffffffffffffffffff16612a8c9092919063ffffffff16565b6060860151610d8b9082615569565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e199190615550565b14610e50576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08501515115610e7657610c218560400151866080015160008860a00151612a2e565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405183907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90610edd90851515815260200190565b60405180910390a281158015610ef35750326001145b15610f2a576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fa0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615580565b905090565b610fd1611531565b15611008576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603611071576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6038546040517fbb8aa1fc00000000000000000000000000000000000000000000000000000000815260048101869052600091829173ffffffffffffffffffffffffffffffffffffffff9091169063bb8aa1fc90602401606060405180830381865afa1580156110e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611109919061559d565b925050915060008173ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561115b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117f9190615550565b603b5490915063ffffffff8481169116146111c6576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111dd6111d8368890038801886155ea565b612ae7565b8114611215576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611220896129e1565b905060018373ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611293919061567f565b60028111156112a4576112a4615650565b036112db576040517fd357347400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051602081018390526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506113a49101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f010000000000000000000000000000000000000000000000000000000000000060208301529061139a898b6156a0565b8b60400135612b26565b15156000036113df576040517fb05e92fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825273ffffffffffffffffffffffffffffffffffffffff808716825267ffffffffffffffff4281166020808501918252600088815260398252868120338252825286812095518654935190941674010000000000000000000000000000000000000000027fffffffff0000000000000000000000000000000000000000000000000000000090931693851693909317919091179093558d840151928e01519351928216939091169185917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f6291a4604051339083907f798f9f13695f8f045aa5f80ed8efebb695f3c7fe65da381969f2f28bf3c60b9790600090a3506000908152603c602090815260408220805460018101825590835291200180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115a0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615724565b600082815260396020908152604080832073ffffffffffffffffffffffffffffffffffffffff85811685529083528184208251808401845290549182168082527401000000000000000000000000000000000000000090920467ffffffffffffffff1681850152818552603a90935292205490919060ff1615611673576040517f09550c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816020015167ffffffffffffffff166000036116bb576040517f94efd49b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061173c8273ffffffffffffffffffffffffffffffffffffffff1663cf09e0d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172f9190615741565b67ffffffffffffffff1690565b90508067ffffffffffffffff16836020015167ffffffffffffffff1611611810576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e20646973707574652067616d65206372656160648201527f74696f6e2074696d657374616d70000000000000000000000000000000000000608482015260a4015b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000c836020015167ffffffffffffffff164261184b9190615569565b116118d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c20686173206e6f74206d6174757265642079657400000000000000000000006064820152608401611807565b60028273ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611925573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611949919061567f565b600281111561195a5761195a615650565b14611991576040517fa080a3c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5463ffffffff1663ffffffff16611a1b8373ffffffffffffffffffffffffffffffffffffffff1663bbdc02db6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a12919061575e565b63ffffffff1690565b63ffffffff1614611a58576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5467ffffffffffffffff64010000000090910481169082161015611b26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a20646973707574652067616d652063726560448201527f61746564206265666f7265207265737065637465642067616d6520747970652060648201527f7761732075706461746564000000000000000000000000000000000000000000608482015260a401611807565b7f0000000000000000000000000000000000000000000000000000000000000006611b958373ffffffffffffffffffffffffffffffffffffffff166319effeb46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b611ba99067ffffffffffffffff1642615569565b11611c36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f696e206169722d676170000000000000000000000000000000000000000000006064820152608401611807565b60008581526033602052604090205460ff1615610f2a576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60375473ffffffffffffffffffffffffffffffffffffffff163314611cd0576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611cdc62030d40612b4a565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f000000000000000000000000000000000000000000000000000000001790529051611df99695949392910161577b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052611e31916152f6565b60405180910390a450505050565b611e47610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611eab576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152603a602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f192c289026d59a41a27f5aea08f3969b57931b0589202d14f4368cded95d3cda9190a250565b611f2a610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f8e576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b805463ffffffff83167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090911681176401000000004267ffffffffffffffff90811682029290921793849055604051930416917f049fe9dd413cdf037cce27011cc1790c753118272f3630e6e8bdfa5e8208176090600090a350565b565b612016611531565b1561204d576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120578133610a91565b50565b600054610100900460ff161580801561207a5750600054600160ff909116105b806120945750303b158015612094575060005460ff166001145b612120576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611807565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561217e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603880547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8881169190911790925560378054909116868316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff16610100868416021790556032541661229e576032805461dead7fffffffffffffffffffffffff0000000000000000000000000000000000000000909116179055603b80547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166401000000004267ffffffffffffffff16027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000161763ffffffff84161790555b6122a6612bac565b8015610f2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600061231c8260106157e0565b61232890615208615810565b92915050565b603c602052816000526040600020818154811061234a57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169150829050565b60008061237e6123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016123c5574791505090565b5050603d5490565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015612459573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247d919061583c565b90939092509050565b8180156124a8575073ffffffffffffffffffffffffffffffffffffffff861615155b156124df576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6124e9815161230f565b67ffffffffffffffff168367ffffffffffffffff161015612536576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c081511115612574576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33328114612595575033731111000000000000000000000000000000001111015b600086868686866040516020016125b095949392919061577b565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161262091906152f6565b60405180910390a45050505050505050565b600154600090612668907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643615569565b90506000612674612cbf565b90506000816020015160ff16826000015163ffffffff16612695919061589a565b905082156127cc576001546000906126cc908390700100000000000000000000000000000000900467ffffffffffffffff16615902565b90506000836040015160ff16836126e39190615976565b6001546127039084906fffffffffffffffffffffffffffffffff16615976565b61270d919061589a565b60015490915060009061275e906127379084906fffffffffffffffffffffffffffffffff16615a32565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612d80565b9050600186111561278d5761278a61273782876040015160ff1660018a6127859190615569565b612d9f565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b600180548691906010906127ff908490700100000000000000000000000000000000900467ffffffffffffffff16615810565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff16131561288c576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906128b8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615aa6565b905060006128ca48633b9aca00612df4565b6128d49083615ae3565b905060005a6128e39088615569565b905080821115610a8757610a876128fa8284615569565b612e0b565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526129db9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612e34565b50505050565b80516020808301516040808501516060860151608087015160a08801519351600097612a11979096959101615af7565b604051602081830303815290604052805190602001209050919050565b6000806000612a3e866000612f40565b905080612a74576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052612ae29084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612959565b505050565b60008160000151826020015183604001518460600151604051602001612a11949392919093845260208401929092526040830152606082015260800190565b600080612b3286612f5e565b9050612b4081868686612f90565b9695505050505050565b6001805463ffffffff83169190601090612b83908490700100000000000000000000000000000000900467ffffffffffffffff16615810565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b600054610100900460ff16612c43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611807565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff1660000361200c5760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa158015612d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615b4e565b6000612d95612d8f8585612fc0565b83612fd0565b90505b9392505050565b6000670de0b6b3a7640000612de0612db7858361589a565b612dc990670de0b6b3a7640000615902565b612ddb85670de0b6b3a7640000615976565b612fdf565b612dea9086615976565b612d95919061589a565b600081831015612e045781612d98565b5090919050565b6000805a90505b825a612e1e9083615569565b1015612ae257612e2d82615bf0565b9150612e12565b6000612e96826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130109092919063ffffffff16565b805190915015612ae25780806020019051810190612eb49190615724565b612ae2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611807565b600080603f83619c4001026040850201603f5a021015949350505050565b60608180519060200120604051602001612f7a91815260200190565b6040516020818303038152906040529050919050565b6000612fb784612fa187868661301f565b8051602091820120825192909101919091201490565b95945050505050565b600081831215612e045781612d98565b6000818312612e045781612d98565b6000612d98670de0b6b3a764000083612ff786613a9d565b6130019190615976565b61300b919061589a565b613ce1565b6060612d958484600085613f20565b6060600084511161308c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401611807565b6000613097846140b6565b905060006130a4866141a2565b90506000846040516020016130bb91815260200190565b60405160208183030381529060405290506000805b8451811015613a145760008582815181106130ed576130ed615c28565b602002602001015190508451831115613188576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401611807565b8260000361324157805180516020918201206040516131d6926131b092910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b61323c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401611807565b613398565b8051516020116132f7578051805160209182012060405161326b926131b092910190815260200190565b61323c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401611807565b805184516020808701919091208251919092012014613398576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401611807565b6133a460106001615538565b816020015151036135805784518303613518576133de81602001516010815181106133d1576133d1615c28565b6020026020010151614205565b96506000875111613471576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401611807565b6001865161347f9190615569565b821461350d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401611807565b505050505050612d98565b600085848151811061352c5761352c615c28565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061355757613557615c28565b6020026020010151905061356a816142b9565b9550613577600186615538565b94505050613a01565b600281602001515103613979576000613598826142de565b90506000816000815181106135af576135af615c28565b016020015160f81c905060006135c6600283615c57565b6135d1906002615c79565b905060006135e2848360ff16614302565b905060006135f08a89614302565b905060006135fe8383614338565b905080835114613690576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401611807565b60ff8516600214806136a5575060ff85166003145b15613894578082511461373a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401611807565b61375487602001516001815181106133d1576133d1615c28565b9c5060008d51116137e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401611807565b60018c516137f59190615569565b8814613883576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401611807565b505050505050505050505050612d98565b60ff851615806138a7575060ff85166001145b156138e6576138d387602001516001815181106138c6576138c6615c28565b60200260200101516142b9565b99506138df818a615538565b985061396e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401611807565b505050505050613a01565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401611807565b5080613a0c81615bf0565b9150506130d0565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401611807565b6000808213613b08576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b60006060613b15846143ec565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c18213613d1257506000919050565b680755bf798b4a1bf1e58212613d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401611807565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613fb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611807565b73ffffffffffffffffffffffffffffffffffffffff85163b614030576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611807565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516140599190615c9c565b60006040518083038185875af1925050503d8060008114614096576040519150601f19603f3d011682016040523d82523d6000602084013e61409b565b606091505b50915091506140ab8282866144c2565b979650505050505050565b80516060908067ffffffffffffffff8111156140d4576140d4614eb1565b60405190808252806020026020018201604052801561411957816020015b60408051808201909152606080825260208201528152602001906001900390816140f25790505b50915060005b8181101561419b57604051806040016040528085838151811061414457614144615c28565b6020026020010151815260200161417386848151811061416657614166615c28565b6020026020010151614515565b81525083828151811061418857614188615c28565b602090810291909101015260010161411f565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b838110156141fa578060011b82018184015160001a8060041c8253600f8116600183015350506001016141cc565b509295945050505050565b6060600080600061421585614528565b91945092509050600081600181111561423057614230615650565b14614267576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6142718284615538565b8551146142aa576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fb7856020015184846149c6565b606060208260000151106142d5576142d082614205565b612328565b61232882614a5a565b60606123286142fd83602001516000815181106133d1576133d1615c28565b6141a2565b6060825182106143215750604080516020810190915260008152612328565b612d9883838486516143339190615569565b614a70565b600080825184511061434b57825161434e565b83515b90505b80821080156143d5575082828151811061436d5761436d615c28565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168483815181106143ac576143ac615c28565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156143e557816001019150614351565b5092915050565b6000808211614457576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606083156144d1575081612d98565b8251156144e15782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180791906152f6565b606061232861452383614c48565b614cb5565b6000806000836000015160000361456b576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f81116145905760006001600094509450945050506149bf565b60b781116146a65760006145a5608083615569565b9050808760000151116145e4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214801561465c57507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614693576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600195509350600092506149bf915050565b60bf81116148045760006146bb60b783615569565b9050808760000151116146fa576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361475c576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116147a4576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147ae8184615538565b8951116147e7576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147f2836001615538565b97509550600094506149bf9350505050565b60f7811161486957600061481960c083615569565b905080876000015111614858576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001955093508492506149bf915050565b600061487660f783615569565b9050808760000151116148b5576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614917576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c6037811161495f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6149698184615538565b8951116149a2576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6149ad836001615538565b97509550600194506149bf9350505050565b9193909250565b60608167ffffffffffffffff8111156149e1576149e1614eb1565b6040519080825280601f01601f191660200182016040528015614a0b576020820181803683370190505b5090508115612d98576000614a208486615538565b90506020820160005b84811015614a41578281015182820152602001614a29565b84811115614a50576000858301525b5050509392505050565b60606123288260200151600084600001516149c6565b60608182601f011015614adf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b828284011015614b4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b81830184511015614bb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401611807565b606082158015614bd75760405191506000825260208201604052614c3f565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614c10578051835260209283019201614bf8565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201528151600003614c97576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000614cc585614528565b919450925090506001816001811115614ce057614ce0615650565b14614d17576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451614d238385615538565b14614d5a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081614d715790505093506000835b8651811015614e5f57600080614de46040518060400160405280858c60000151614dc89190615569565b8152602001858c60200151614ddd9190615538565b9052614528565b509150915060405180604001604052808383614e009190615538565b8152602001848b60200151614e159190615538565b815250888581518110614e2a57614e2a615c28565b6020908102919091010152614e40600185615538565b9350614e4c8183615538565b614e569084615538565b92505050614d9e565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461205757600080fd5b67ffffffffffffffff8116811461205757600080fd5b801515811461205757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715614f0357614f03614eb1565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614f5057614f50614eb1565b604052919050565b600082601f830112614f6957600080fd5b813567ffffffffffffffff811115614f8357614f83614eb1565b614fb460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614f09565b818152846020838601011115614fc957600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614fff57600080fd5b863561500a81614e6b565b95506020870135945060408701359350606087013561502881614e8d565b9250608087013561503881614ea3565b915060a087013567ffffffffffffffff81111561505457600080fd5b61506089828a01614f58565b9150509295509295509295565b600060c0828403121561507f57600080fd5b60405160c0810167ffffffffffffffff82821081831117156150a3576150a3614eb1565b8160405282935084358352602085013591506150be82614e6b565b816020840152604085013591506150d482614e6b565b816040840152606085013560608401526080850135608084015260a085013591508082111561510257600080fd5b5061510f85828601614f58565b60a0830152505092915050565b6000806040838503121561512f57600080fd5b823567ffffffffffffffff81111561514657600080fd5b6151528582860161506d565b925050602083013561516381614e6b565b809150509250929050565b60006020828403121561518057600080fd5b8135612d9881614e6b565b600080600080600085870360e08112156151a457600080fd5b863567ffffffffffffffff808211156151bc57600080fd5b6151c88a838b0161506d565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401121561520157600080fd5b60408901955060c089013592508083111561521b57600080fd5b828901925089601f84011261522f57600080fd5b823591508082111561524057600080fd5b508860208260051b840101111561525657600080fd5b959894975092955050506020019190565b60006020828403121561527957600080fd5b5035919050565b60005b8381101561529b578181015183820152602001615283565b838111156129db5750506000910152565b600081518084526152c4816020860160208601615280565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612d9860208301846152ac565b6000806040838503121561531c57600080fd5b82359150602083013561516381614e6b565b60ff8116811461205757600080fd5b6000806000806080858703121561535357600080fd5b843561535e81614e6b565b9350602085013561536e8161532e565b93969395505050506040820135916060013590565b63ffffffff8116811461205757600080fd5b6000602082840312156153a757600080fd5b8135612d9881615383565b6000602082840312156153c457600080fd5b813567ffffffffffffffff8111156153db57600080fd5b6153e78482850161506d565b949350505050565b6000806000806080858703121561540557600080fd5b843561541081614e6b565b9350602085013561542081614e6b565b9250604085013561543081614e6b565b9150606085013561544081615383565b939692955090935050565b60006020828403121561545d57600080fd5b8135612d9881614e8d565b6000806040838503121561547b57600080fd5b50508035926020909101359150565b600080600080600060a086880312156154a257600080fd5b85356154ad81614e6b565b94506020860135935060408601356154c481614e8d565b925060608601356154d481614ea3565b9150608086013567ffffffffffffffff8111156154f057600080fd5b6154fc88828901614f58565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561554b5761554b615509565b500190565b60006020828403121561556257600080fd5b5051919050565b60008282101561557b5761557b615509565b500390565b60006020828403121561559257600080fd5b8151612d9881614e6b565b6000806000606084860312156155b257600080fd5b83516155bd81615383565b60208501519093506155ce81614e8d565b60408501519092506155df81614e6b565b809150509250925092565b6000608082840312156155fc57600080fd5b6040516080810181811067ffffffffffffffff8211171561561f5761561f614eb1565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006020828403121561569157600080fd5b815160038110612d9857600080fd5b600067ffffffffffffffff808411156156bb576156bb614eb1565b8360051b60206156cc818301614f09565b8681529185019181810190368411156156e457600080fd5b865b84811015615718578035868111156156fe5760008081fd5b61570a36828b01614f58565b8452509183019183016156e6565b50979650505050505050565b60006020828403121561573657600080fd5b8151612d9881614ea3565b60006020828403121561575357600080fd5b8151612d9881614e8d565b60006020828403121561577057600080fd5b8151612d9881615383565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b6048820152600082516157cf816049850160208701615280565b919091016049019695505050505050565b600067ffffffffffffffff8083168185168183048111821515161561580757615807615509565b02949350505050565b600067ffffffffffffffff80831681851680830382111561583357615833615509565b01949350505050565b6000806040838503121561584f57600080fd5b825161585a81614e6b565b60208401519092506151638161532e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826158a9576158a961586b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156158fd576158fd615509565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561593c5761593c615509565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561597057615970615509565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156159b7576159b7615509565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156159f2576159f2615509565b60008712925087820587128484161615615a0e57615a0e615509565b87850587128184161615615a2457615a24615509565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03841381151615615a6c57615a6c615509565b827f8000000000000000000000000000000000000000000000000000000000000000038412811615615aa057615aa0615509565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615ade57615ade615509565b500290565b600082615af257615af261586b565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152615b4260c08301846152ac565b98975050505050505050565b600060c08284031215615b6057600080fd5b615b68614ee0565b8251615b7381615383565b81526020830151615b838161532e565b60208201526040830151615b968161532e565b60408201526060830151615ba981615383565b60608201526080830151615bbc81615383565b608082015260a08301516fffffffffffffffffffffffffffffffff81168114615be457600080fd5b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615c2157615c21615509565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff831680615c6a57615c6a61586b565b8060ff84160691505092915050565b600060ff821660ff841680821015615c9357615c93615509565b90039392505050565b60008251615cae818460208701615280565b919091019291505056fea164736f6c634300080f000a"; + hex"6080604052600436106101d15760003560e01c80637fc48504116100f7578063a35d99df11610095578063bf653a5c11610064578063bf653a5c14610697578063cff0ab96146106ca578063e9e05c421461076b578063f2b4e6171461077e57600080fd5b8063a35d99df1461059b578063a3860f48146105bb578063b69ef8a8146105db578063bb2c727e146105f057600080fd5b80638e819e54116100d15780638e819e54146104eb578063952b27971461050b5780639bf62d821461053e578063a14238e71461056b57600080fd5b80637fc48504146104ab5780638b4c40b0146101f65780638c3152e9146104cb57600080fd5b80634870496f1161016f5780635c975abb1161013e5780635c975abb1461043657806371c1566e1461044b57806371cfaa3f1461046b5780637d6be8dc1461048b57600080fd5b80634870496f1461034d5780634fd0434c1461036d578063513747ab146103af57806354fd4d50146103ea57600080fd5b80633c9f397c116101ab5780633c9f397c146102a657806343ca1c50146102d8578063452a9320146102f857806345884d321461030d57600080fd5b8063149f2f22146101fd57806333d7e2bd1461021d57806335e80ab31461027457600080fd5b366101f8576101f63334620186a06000604051806020016040528060008152506107ab565b005b600080fd5b34801561020957600080fd5b506101f6610218366004614fe6565b610850565b34801561022957600080fd5b5060375461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561028057600080fd5b5060355461024a90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156102b257600080fd5b50603b546102c39063ffffffff1681565b60405163ffffffff909116815260200161026b565b3480156102e457600080fd5b506101f66102f336600461511c565b610a91565b34801561030457600080fd5b5061024a610f31565b34801561031957600080fd5b5061033d61032836600461516e565b603a6020526000908152604090205460ff1681565b604051901515815260200161026b565b34801561035957600080fd5b506101f661036836600461518b565b610fc9565b34801561037957600080fd5b50603b5461039690640100000000900467ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161026b565b3480156103bb57600080fd5b506103dc6103ca366004615267565b6000908152603c602052604090205490565b60405190815260200161026b565b3480156103f657600080fd5b50604080518082018252600d81527f332e31312e302d626574612e33000000000000000000000000000000000000006020820152905161026b91906152f6565b34801561044257600080fd5b5061033d611531565b34801561045757600080fd5b506101f6610466366004615309565b6115c4565b34801561047757600080fd5b506101f661048636600461533d565b611c7f565b34801561049757600080fd5b506101f66104a636600461516e565b611e3f565b3480156104b757600080fd5b506101f66104c6366004615395565b611f22565b3480156104d757600080fd5b506101f66104e63660046153b2565b61200e565b3480156104f757600080fd5b506101f66105063660046153ef565b61205a565b34801561051757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000066103dc565b34801561054a57600080fd5b5060325461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561057757600080fd5b5061033d610586366004615267565b60336020526000908152604090205460ff1681565b3480156105a757600080fd5b506103966105b636600461544b565b61230f565b3480156105c757600080fd5b5061024a6105d6366004615468565b61232e565b3480156105e757600080fd5b506103dc612373565b3480156105fc57600080fd5b5061066261060b366004615309565b603960209081526000928352604080842090915290825290205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900467ffffffffffffffff1682565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff90911660208301520161026b565b3480156106a357600080fd5b507f000000000000000000000000000000000000000000000000000000000000000c6103dc565b3480156106d657600080fd5b50600154610732906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff928316602085015291169082015260600161026b565b6101f661077936600461548a565b6107ab565b34801561078a57600080fd5b5060385461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b8260005a905060006107bb6123e9565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906107f757503415155b1561082e576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61083c883489898989612486565b506108478282612632565b50505050505050565b8260005a905060006108606123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016108d2576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546108e49190615538565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610956573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097a9190615550565b905061099e73ffffffffffffffffffffffffffffffffffffffff831633308c6128ff565b6109a88982615538565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a369190615550565b14610a6d576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a7b8a8a8a8a8a8a612486565b5050610a878282612632565b5050505050505050565b610a99611531565b15610ad0576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead14610b23576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610b2e836129e1565b9050610b3a81836115c4565b6000818152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558401516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905580610bc56123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601610c2857610c218560400151866080015187606001518860a00151612a2e565b9150610e7b565b8073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610c91576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606085015115610e52578460600151603d6000828254610cb19190615569565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610d23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d479190615550565b9050610d7c866040015187606001518473ffffffffffffffffffffffffffffffffffffffff16612a8c9092919063ffffffff16565b6060860151610d8b9082615569565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e199190615550565b14610e50576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08501515115610e7657610c218560400151866080015160008860a00151612a2e565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405183907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90610edd90851515815260200190565b60405180910390a281158015610ef35750326001145b15610f2a576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fa0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615580565b905090565b610fd1611531565b15611008576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603611071576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6038546040517fbb8aa1fc00000000000000000000000000000000000000000000000000000000815260048101869052600091829173ffffffffffffffffffffffffffffffffffffffff9091169063bb8aa1fc90602401606060405180830381865afa1580156110e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611109919061559d565b925050915060008173ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561115b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117f9190615550565b603b5490915063ffffffff8481169116146111c6576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111dd6111d8368890038801886155ea565b612ae7565b8114611215576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611220896129e1565b905060018373ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611293919061567f565b60028111156112a4576112a4615650565b036112db576040517fd357347400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051602081018390526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506113a49101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f010000000000000000000000000000000000000000000000000000000000000060208301529061139a898b6156a0565b8b60400135612b26565b15156000036113df576040517fb05e92fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825273ffffffffffffffffffffffffffffffffffffffff808716825267ffffffffffffffff4281166020808501918252600088815260398252868120338252825286812095518654935190941674010000000000000000000000000000000000000000027fffffffff0000000000000000000000000000000000000000000000000000000090931693851693909317919091179093558d840151928e01519351928216939091169185917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f6291a4604051339083907f798f9f13695f8f045aa5f80ed8efebb695f3c7fe65da381969f2f28bf3c60b9790600090a3506000908152603c602090815260408220805460018101825590835291200180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115a0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615724565b600082815260396020908152604080832073ffffffffffffffffffffffffffffffffffffffff85811685529083528184208251808401845290549182168082527401000000000000000000000000000000000000000090920467ffffffffffffffff1681850152818552603a90935292205490919060ff1615611673576040517f09550c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816020015167ffffffffffffffff166000036116bb576040517f94efd49b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061173c8273ffffffffffffffffffffffffffffffffffffffff1663cf09e0d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172f9190615741565b67ffffffffffffffff1690565b90508067ffffffffffffffff16836020015167ffffffffffffffff1611611810576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e20646973707574652067616d65206372656160648201527f74696f6e2074696d657374616d70000000000000000000000000000000000000608482015260a4015b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000c836020015167ffffffffffffffff164261184b9190615569565b116118d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c20686173206e6f74206d6174757265642079657400000000000000000000006064820152608401611807565b60028273ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611925573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611949919061567f565b600281111561195a5761195a615650565b14611991576040517fa080a3c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5463ffffffff1663ffffffff16611a1b8373ffffffffffffffffffffffffffffffffffffffff1663bbdc02db6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a12919061575e565b63ffffffff1690565b63ffffffff1614611a58576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5467ffffffffffffffff64010000000090910481169082161015611b26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a20646973707574652067616d652063726560448201527f61746564206265666f7265207265737065637465642067616d6520747970652060648201527f7761732075706461746564000000000000000000000000000000000000000000608482015260a401611807565b7f0000000000000000000000000000000000000000000000000000000000000006611b958373ffffffffffffffffffffffffffffffffffffffff166319effeb46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b611ba99067ffffffffffffffff1642615569565b11611c36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f696e206169722d676170000000000000000000000000000000000000000000006064820152608401611807565b60008581526033602052604090205460ff1615610f2a576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60375473ffffffffffffffffffffffffffffffffffffffff163314611cd0576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611cdc62030d40612b4a565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f000000000000000000000000000000000000000000000000000000001790529051611df99695949392910161577b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052611e31916152f6565b60405180910390a450505050565b611e47610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611eab576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152603a602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f192c289026d59a41a27f5aea08f3969b57931b0589202d14f4368cded95d3cda9190a250565b611f2a610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f8e576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b805463ffffffff83167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090911681176401000000004267ffffffffffffffff90811682029290921793849055604051930416917f049fe9dd413cdf037cce27011cc1790c753118272f3630e6e8bdfa5e8208176090600090a350565b565b612016611531565b1561204d576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120578133610a91565b50565b600054610100900460ff161580801561207a5750600054600160ff909116105b806120945750303b158015612094575060005460ff166001145b612120576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611807565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561217e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603880547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8881169190911790925560378054909116868316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff16610100868416021790556032541661229e576032805461dead7fffffffffffffffffffffffff0000000000000000000000000000000000000000909116179055603b80547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166401000000004267ffffffffffffffff16027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000161763ffffffff84161790555b6122a6612bac565b8015610f2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600061231c8260106157e0565b61232890615208615810565b92915050565b603c602052816000526040600020818154811061234a57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169150829050565b60008061237e6123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016123c5574791505090565b5050603d5490565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015612459573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247d919061583c565b90939092509050565b8180156124a8575073ffffffffffffffffffffffffffffffffffffffff861615155b156124df576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6124e9815161230f565b67ffffffffffffffff168367ffffffffffffffff161015612536576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c081511115612574576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33328114612595575033731111000000000000000000000000000000001111015b600086868686866040516020016125b095949392919061577b565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161262091906152f6565b60405180910390a45050505050505050565b600154600090612668907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643615569565b90506000612674612cbf565b90506000816020015160ff16826000015163ffffffff16612695919061589a565b905082156127cc576001546000906126cc908390700100000000000000000000000000000000900467ffffffffffffffff16615902565b90506000836040015160ff16836126e39190615976565b6001546127039084906fffffffffffffffffffffffffffffffff16615976565b61270d919061589a565b60015490915060009061275e906127379084906fffffffffffffffffffffffffffffffff16615a32565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612d80565b9050600186111561278d5761278a61273782876040015160ff1660018a6127859190615569565b612d9f565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b600180548691906010906127ff908490700100000000000000000000000000000000900467ffffffffffffffff16615810565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff16131561288c576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906128b8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615aa6565b905060006128ca48633b9aca00612df4565b6128d49083615ae3565b905060005a6128e39088615569565b905080821115610a8757610a876128fa8284615569565b612e0b565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526129db9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612e34565b50505050565b80516020808301516040808501516060860151608087015160a08801519351600097612a11979096959101615af7565b604051602081830303815290604052805190602001209050919050565b6000806000612a3e866000612f40565b905080612a74576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052612ae29084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612959565b505050565b60008160000151826020015183604001518460600151604051602001612a11949392919093845260208401929092526040830152606082015260800190565b600080612b3286612f5e565b9050612b4081868686612f90565b9695505050505050565b6001805463ffffffff83169190601090612b83908490700100000000000000000000000000000000900467ffffffffffffffff16615810565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b600054610100900460ff16612c43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611807565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff1660000361200c5760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa158015612d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615b4e565b6000612d95612d8f8585612fc0565b83612fd0565b90505b9392505050565b6000670de0b6b3a7640000612de0612db7858361589a565b612dc990670de0b6b3a7640000615902565b612ddb85670de0b6b3a7640000615976565b612fdf565b612dea9086615976565b612d95919061589a565b600081831015612e045781612d98565b5090919050565b6000805a90505b825a612e1e9083615569565b1015612ae257612e2d82615bf0565b9150612e12565b6000612e96826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130109092919063ffffffff16565b805190915015612ae25780806020019051810190612eb49190615724565b612ae2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611807565b600080603f83619c4001026040850201603f5a021015949350505050565b60608180519060200120604051602001612f7a91815260200190565b6040516020818303038152906040529050919050565b6000612fb784612fa187868661301f565b8051602091820120825192909101919091201490565b95945050505050565b600081831215612e045781612d98565b6000818312612e045781612d98565b6000612d98670de0b6b3a764000083612ff786613a9d565b6130019190615976565b61300b919061589a565b613ce1565b6060612d958484600085613f20565b6060600084511161308c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401611807565b6000613097846140b6565b905060006130a4866141a2565b90506000846040516020016130bb91815260200190565b60405160208183030381529060405290506000805b8451811015613a145760008582815181106130ed576130ed615c28565b602002602001015190508451831115613188576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401611807565b8260000361324157805180516020918201206040516131d6926131b092910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b61323c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401611807565b613398565b8051516020116132f7578051805160209182012060405161326b926131b092910190815260200190565b61323c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401611807565b805184516020808701919091208251919092012014613398576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401611807565b6133a460106001615538565b816020015151036135805784518303613518576133de81602001516010815181106133d1576133d1615c28565b6020026020010151614205565b96506000875111613471576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401611807565b6001865161347f9190615569565b821461350d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401611807565b505050505050612d98565b600085848151811061352c5761352c615c28565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061355757613557615c28565b6020026020010151905061356a816142b9565b9550613577600186615538565b94505050613a01565b600281602001515103613979576000613598826142de565b90506000816000815181106135af576135af615c28565b016020015160f81c905060006135c6600283615c57565b6135d1906002615c79565b905060006135e2848360ff16614302565b905060006135f08a89614302565b905060006135fe8383614338565b905080835114613690576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401611807565b60ff8516600214806136a5575060ff85166003145b15613894578082511461373a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401611807565b61375487602001516001815181106133d1576133d1615c28565b9c5060008d51116137e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401611807565b60018c516137f59190615569565b8814613883576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401611807565b505050505050505050505050612d98565b60ff851615806138a7575060ff85166001145b156138e6576138d387602001516001815181106138c6576138c6615c28565b60200260200101516142b9565b99506138df818a615538565b985061396e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401611807565b505050505050613a01565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401611807565b5080613a0c81615bf0565b9150506130d0565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401611807565b6000808213613b08576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b60006060613b15846143ec565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c18213613d1257506000919050565b680755bf798b4a1bf1e58212613d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401611807565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613fb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611807565b73ffffffffffffffffffffffffffffffffffffffff85163b614030576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611807565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516140599190615c9c565b60006040518083038185875af1925050503d8060008114614096576040519150601f19603f3d011682016040523d82523d6000602084013e61409b565b606091505b50915091506140ab8282866144c2565b979650505050505050565b80516060908067ffffffffffffffff8111156140d4576140d4614eb1565b60405190808252806020026020018201604052801561411957816020015b60408051808201909152606080825260208201528152602001906001900390816140f25790505b50915060005b8181101561419b57604051806040016040528085838151811061414457614144615c28565b6020026020010151815260200161417386848151811061416657614166615c28565b6020026020010151614515565b81525083828151811061418857614188615c28565b602090810291909101015260010161411f565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b838110156141fa578060011b82018184015160001a8060041c8253600f8116600183015350506001016141cc565b509295945050505050565b6060600080600061421585614528565b91945092509050600081600181111561423057614230615650565b14614267576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6142718284615538565b8551146142aa576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fb7856020015184846149c6565b606060208260000151106142d5576142d082614205565b612328565b61232882614a5a565b60606123286142fd83602001516000815181106133d1576133d1615c28565b6141a2565b6060825182106143215750604080516020810190915260008152612328565b612d9883838486516143339190615569565b614a70565b600080825184511061434b57825161434e565b83515b90505b80821080156143d5575082828151811061436d5761436d615c28565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168483815181106143ac576143ac615c28565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156143e557816001019150614351565b5092915050565b6000808211614457576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606083156144d1575081612d98565b8251156144e15782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180791906152f6565b606061232861452383614c48565b614cb5565b6000806000836000015160000361456b576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f81116145905760006001600094509450945050506149bf565b60b781116146a65760006145a5608083615569565b9050808760000151116145e4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214801561465c57507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614693576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600195509350600092506149bf915050565b60bf81116148045760006146bb60b783615569565b9050808760000151116146fa576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361475c576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116147a4576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147ae8184615538565b8951116147e7576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147f2836001615538565b97509550600094506149bf9350505050565b60f7811161486957600061481960c083615569565b905080876000015111614858576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001955093508492506149bf915050565b600061487660f783615569565b9050808760000151116148b5576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614917576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c6037811161495f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6149698184615538565b8951116149a2576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6149ad836001615538565b97509550600194506149bf9350505050565b9193909250565b60608167ffffffffffffffff8111156149e1576149e1614eb1565b6040519080825280601f01601f191660200182016040528015614a0b576020820181803683370190505b5090508115612d98576000614a208486615538565b90506020820160005b84811015614a41578281015182820152602001614a29565b84811115614a50576000858301525b5050509392505050565b60606123288260200151600084600001516149c6565b60608182601f011015614adf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b828284011015614b4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b81830184511015614bb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401611807565b606082158015614bd75760405191506000825260208201604052614c3f565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614c10578051835260209283019201614bf8565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201528151600003614c97576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000614cc585614528565b919450925090506001816001811115614ce057614ce0615650565b14614d17576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451614d238385615538565b14614d5a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081614d715790505093506000835b8651811015614e5f57600080614de46040518060400160405280858c60000151614dc89190615569565b8152602001858c60200151614ddd9190615538565b9052614528565b509150915060405180604001604052808383614e009190615538565b8152602001848b60200151614e159190615538565b815250888581518110614e2a57614e2a615c28565b6020908102919091010152614e40600185615538565b9350614e4c8183615538565b614e569084615538565b92505050614d9e565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461205757600080fd5b67ffffffffffffffff8116811461205757600080fd5b801515811461205757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715614f0357614f03614eb1565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614f5057614f50614eb1565b604052919050565b600082601f830112614f6957600080fd5b813567ffffffffffffffff811115614f8357614f83614eb1565b614fb460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614f09565b818152846020838601011115614fc957600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614fff57600080fd5b863561500a81614e6b565b95506020870135945060408701359350606087013561502881614e8d565b9250608087013561503881614ea3565b915060a087013567ffffffffffffffff81111561505457600080fd5b61506089828a01614f58565b9150509295509295509295565b600060c0828403121561507f57600080fd5b60405160c0810167ffffffffffffffff82821081831117156150a3576150a3614eb1565b8160405282935084358352602085013591506150be82614e6b565b816020840152604085013591506150d482614e6b565b816040840152606085013560608401526080850135608084015260a085013591508082111561510257600080fd5b5061510f85828601614f58565b60a0830152505092915050565b6000806040838503121561512f57600080fd5b823567ffffffffffffffff81111561514657600080fd5b6151528582860161506d565b925050602083013561516381614e6b565b809150509250929050565b60006020828403121561518057600080fd5b8135612d9881614e6b565b600080600080600085870360e08112156151a457600080fd5b863567ffffffffffffffff808211156151bc57600080fd5b6151c88a838b0161506d565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401121561520157600080fd5b60408901955060c089013592508083111561521b57600080fd5b828901925089601f84011261522f57600080fd5b823591508082111561524057600080fd5b508860208260051b840101111561525657600080fd5b959894975092955050506020019190565b60006020828403121561527957600080fd5b5035919050565b60005b8381101561529b578181015183820152602001615283565b838111156129db5750506000910152565b600081518084526152c4816020860160208601615280565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612d9860208301846152ac565b6000806040838503121561531c57600080fd5b82359150602083013561516381614e6b565b60ff8116811461205757600080fd5b6000806000806080858703121561535357600080fd5b843561535e81614e6b565b9350602085013561536e8161532e565b93969395505050506040820135916060013590565b63ffffffff8116811461205757600080fd5b6000602082840312156153a757600080fd5b8135612d9881615383565b6000602082840312156153c457600080fd5b813567ffffffffffffffff8111156153db57600080fd5b6153e78482850161506d565b949350505050565b6000806000806080858703121561540557600080fd5b843561541081614e6b565b9350602085013561542081614e6b565b9250604085013561543081614e6b565b9150606085013561544081615383565b939692955090935050565b60006020828403121561545d57600080fd5b8135612d9881614e8d565b6000806040838503121561547b57600080fd5b50508035926020909101359150565b600080600080600060a086880312156154a257600080fd5b85356154ad81614e6b565b94506020860135935060408601356154c481614e8d565b925060608601356154d481614ea3565b9150608086013567ffffffffffffffff8111156154f057600080fd5b6154fc88828901614f58565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561554b5761554b615509565b500190565b60006020828403121561556257600080fd5b5051919050565b60008282101561557b5761557b615509565b500390565b60006020828403121561559257600080fd5b8151612d9881614e6b565b6000806000606084860312156155b257600080fd5b83516155bd81615383565b60208501519093506155ce81614e8d565b60408501519092506155df81614e6b565b809150509250925092565b6000608082840312156155fc57600080fd5b6040516080810181811067ffffffffffffffff8211171561561f5761561f614eb1565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006020828403121561569157600080fd5b815160038110612d9857600080fd5b600067ffffffffffffffff808411156156bb576156bb614eb1565b8360051b60206156cc818301614f09565b8681529185019181810190368411156156e457600080fd5b865b84811015615718578035868111156156fe5760008081fd5b61570a36828b01614f58565b8452509183019183016156e6565b50979650505050505050565b60006020828403121561573657600080fd5b8151612d9881614ea3565b60006020828403121561575357600080fd5b8151612d9881614e8d565b60006020828403121561577057600080fd5b8151612d9881615383565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b6048820152600082516157cf816049850160208701615280565b919091016049019695505050505050565b600067ffffffffffffffff8083168185168183048111821515161561580757615807615509565b02949350505050565b600067ffffffffffffffff80831681851680830382111561583357615833615509565b01949350505050565b6000806040838503121561584f57600080fd5b825161585a81614e6b565b60208401519092506151638161532e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826158a9576158a961586b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156158fd576158fd615509565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561593c5761593c615509565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561597057615970615509565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156159b7576159b7615509565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156159f2576159f2615509565b60008712925087820587128484161615615a0e57615a0e615509565b87850587128184161615615a2457615a24615509565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03841381151615615a6c57615a6c615509565b827f8000000000000000000000000000000000000000000000000000000000000000038412811615615aa057615aa0615509565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615ade57615ade615509565b500290565b600082615af257615af261586b565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152615b4260c08301846152ac565b98975050505050505050565b600060c08284031215615b6057600080fd5b615b68614ee0565b8251615b7381615383565b81526020830151615b838161532e565b60208201526040830151615b968161532e565b60408201526060830151615ba981615383565b60608201526080830151615bbc81615383565b608082015260a08301516fffffffffffffffffffffffffffffffff81168114615be457600080fd5b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615c2157615c21615509565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff831680615c6a57615c6a61586b565b8060ff84160691505092915050565b600060ff821660ff841680821015615c9357615c93615509565b90039392505050565b60008251615cae818460208701615280565b919091019291505056fea164736f6c634300080f000a"; bytes internal constant disputeGameFactoryCode = - hex"6080604052600436106100e85760003560e01c80636593dc6e1161008a57806396cd97201161005957806396cd972014610313578063bb8aa1fc14610333578063c4d66de814610394578063f2fde38b146103b457600080fd5b80636593dc6e14610293578063715018a6146102c057806382ecf2f6146102d55780638da5cb5b146102e857600080fd5b8063254bd683116100c6578063254bd6831461019c5780634d1975b4146101c957806354fd4d50146101e85780635f0150cb1461023e57600080fd5b806314f6b1a3146100ed5780631b685b9e1461010f5780631e3342401461017c575b600080fd5b3480156100f957600080fd5b5061010d6101083660046110c6565b6103d4565b005b34801561011b57600080fd5b5061015261012a3660046110fd565b60656020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061010d610197366004611118565b61045e565b3480156101a857600080fd5b506101bc6101b7366004611142565b6104aa565b60405161017391906111ef565b3480156101d557600080fd5b506068545b604051908152602001610173565b3480156101f457600080fd5b506102316040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b60405161017391906112ac565b34801561024a57600080fd5b5061025e6102593660046112bf565b6106ee565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff909116602083015201610173565b34801561029f57600080fd5b506101da6102ae3660046110fd565b60666020526000908152604090205481565b3480156102cc57600080fd5b5061010d610741565b6101526102e33660046112bf565b610755565b3480156102f457600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff16610152565b34801561031f57600080fd5b506101da61032e3660046112bf565b6109ef565b34801561033f57600080fd5b5061035361034e366004611346565b610a28565b6040805163ffffffff909416845267ffffffffffffffff909216602084015273ffffffffffffffffffffffffffffffffffffffff1690820152606001610173565b3480156103a057600080fd5b5061010d6103af36600461135f565b610a91565b3480156103c057600080fd5b5061010d6103cf36600461135f565b610c2d565b6103dc610d00565b63ffffffff821660008181526065602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616908117909155905190917fff513d80e2c7fa487608f70a618dfbc0cf415699dc69588c747e8c71566c88de91a35050565b610466610d00565b63ffffffff8216600081815260666020526040808220849055518392917f74d6665c4b26d5596a5aa13d3014e0c06af4d322075a797f87b03cd4c5bc91ca91a35050565b606854606090831015806104bc575081155b6106e7575060408051600583901b8101602001909152825b8381116106e5576000606882815481106104f0576104f061137c565b600091825260209091200154905060e081901c60a082901c67ffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff831663ffffffff891683036106b6576001865101865260008173ffffffffffffffffffffffffffffffffffffffff1663609d33346040518163ffffffff1660e01b8152600401600060405180830381865afa15801561058a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d091908101906113da565b905060008273ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561061f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064391906114a5565b90506040518060a001604052808881526020018781526020018567ffffffffffffffff168152602001828152602001838152508860018a5161068591906114be565b815181106106955761069561137c565b6020026020010181905250888851106106b3575050505050506106e5565b50505b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191506104d49050565b505b9392505050565b60008060006106ff878787876109ef565b60009081526067602052604090205473ffffffffffffffffffffffffffffffffffffffff81169860a09190911c67ffffffffffffffff16975095505050505050565b610749610d00565b6107536000610d81565b565b63ffffffff841660009081526065602052604081205473ffffffffffffffffffffffffffffffffffffffff16806107c5576040517f031c6de400000000000000000000000000000000000000000000000000000000815263ffffffff871660048201526024015b60405180910390fd5b63ffffffff86166000908152606660205260409020543414610813576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006108206001436114be565b40905061088a338783888860405160200161083f9594939291906114fc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905273ffffffffffffffffffffffffffffffffffffffff841690610df8565b92508273ffffffffffffffffffffffffffffffffffffffff16638129fc1c346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156108d457600080fd5b505af11580156108e8573d6000803e3d6000fd5b505050505060006108fb888888886109ef565b60008181526067602052604090205490915015610947576040517f014f6fe5000000000000000000000000000000000000000000000000000000008152600481018290526024016107bc565b60004260a01b60e08a901b178517600083815260676020526040808220839055606880546001810182559083527fa2153420d844928b4421650203c77babc8b33d7f2e7b450e2966db0c220977530183905551919250899163ffffffff8c169173ffffffffffffffffffffffffffffffffffffffff8916917f5b565efe82411da98814f356d0e7bcb8f0219b8d970307c5afb4a6903a8b2e359190a450505050949350505050565b600084848484604051602001610a089493929190611549565b604051602081830303815290604052805190602001209050949350505050565b600080600080600080610a8160688881548110610a4757610a4761137c565b906000526020600020015460e081901c9160a082901c67ffffffffffffffff169173ffffffffffffffffffffffffffffffffffffffff1690565b9199909850909650945050505050565b600054610100900460ff1615808015610ab15750600054600160ff909116105b80610acb5750303b158015610acb575060005460ff166001145b610b57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107bc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610bb557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610bbd610e06565b610bc682610d81565b8015610c2957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b610c35610d00565b73ffffffffffffffffffffffffffffffffffffffff8116610cd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016107bc565b610ce181610d81565b50565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60335473ffffffffffffffffffffffffffffffffffffffff163314610753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107bc565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006106e760008484610ea5565b600054610100900460ff16610e9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b610753610feb565b600060608203516040830351602084035184518060208701018051600283016c5af43d3d93803e606057fd5bf3895289600d8a035278593da1005b363d3d373d3d3d3d610000806062363936013d738160481b1760218a03527f9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff603a8a035272fd6100003d81600a3d39f336602c57343d527f6062820160781b1761ff9e82106059018a03528060f01b8352606c8101604c8a038cf097505086610f715763301164256000526004601cfd5b905285527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08501527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa09092019190915292915050565b600054610100900460ff16611082576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b61075333610d81565b803563ffffffff8116811461109f57600080fd5b919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610ce157600080fd5b600080604083850312156110d957600080fd5b6110e28361108b565b915060208301356110f2816110a4565b809150509250929050565b60006020828403121561110f57600080fd5b6106e78261108b565b6000806040838503121561112b57600080fd5b6111348361108b565b946020939093013593505050565b60008060006060848603121561115757600080fd5b6111608461108b565b95602085013595506040909401359392505050565b60005b83811015611190578181015183820152602001611178565b8381111561119f576000848401525b50505050565b600081518084526111bd816020860160208601611175565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561129e578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001855281518051845287810151888501528681015167ffffffffffffffff16878501526060808201519085015260809081015160a09185018290529061128a818601836111a5565b968901969450505090860190600101611216565b509098975050505050505050565b6020815260006106e760208301846111a5565b600080600080606085870312156112d557600080fd5b6112de8561108b565b935060208501359250604085013567ffffffffffffffff8082111561130257600080fd5b818701915087601f83011261131657600080fd5b81358181111561132557600080fd5b88602082850101111561133757600080fd5b95989497505060200194505050565b60006020828403121561135857600080fd5b5035919050565b60006020828403121561137157600080fd5b81356106e7816110a4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156113ec57600080fd5b815167ffffffffffffffff8082111561140457600080fd5b818401915084601f83011261141857600080fd5b81518181111561142a5761142a6113ab565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611470576114706113ab565b8160405282815287602084870101111561148957600080fd5b61149a836020830160208801611175565b979650505050505050565b6000602082840312156114b757600080fd5b5051919050565b6000828210156114f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500390565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008660601b1681528460148201528360348201528183605483013760009101605401908152949350505050565b63ffffffff8516815283602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101939250505056fea164736f6c634300080f000a"; + hex"6080604052600436106100e85760003560e01c80636593dc6e1161008a57806396cd97201161005957806396cd972014610313578063bb8aa1fc14610333578063c4d66de814610394578063f2fde38b146103b457600080fd5b80636593dc6e14610293578063715018a6146102c057806382ecf2f6146102d55780638da5cb5b146102e857600080fd5b8063254bd683116100c6578063254bd6831461019c5780634d1975b4146101c957806354fd4d50146101e85780635f0150cb1461023e57600080fd5b806314f6b1a3146100ed5780631b685b9e1461010f5780631e3342401461017c575b600080fd5b3480156100f957600080fd5b5061010d6101083660046110c6565b6103d4565b005b34801561011b57600080fd5b5061015261012a3660046110fd565b60656020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061010d610197366004611118565b61045e565b3480156101a857600080fd5b506101bc6101b7366004611142565b6104aa565b60405161017391906111ef565b3480156101d557600080fd5b506068545b604051908152602001610173565b3480156101f457600080fd5b506102316040518060400160405280600c81526020017f312e302e312d626574612e31000000000000000000000000000000000000000081525081565b60405161017391906112ac565b34801561024a57600080fd5b5061025e6102593660046112bf565b6106ee565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff909116602083015201610173565b34801561029f57600080fd5b506101da6102ae3660046110fd565b60666020526000908152604090205481565b3480156102cc57600080fd5b5061010d610741565b6101526102e33660046112bf565b610755565b3480156102f457600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff16610152565b34801561031f57600080fd5b506101da61032e3660046112bf565b6109ef565b34801561033f57600080fd5b5061035361034e366004611346565b610a28565b6040805163ffffffff909416845267ffffffffffffffff909216602084015273ffffffffffffffffffffffffffffffffffffffff1690820152606001610173565b3480156103a057600080fd5b5061010d6103af36600461135f565b610a91565b3480156103c057600080fd5b5061010d6103cf36600461135f565b610c2d565b6103dc610d00565b63ffffffff821660008181526065602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616908117909155905190917fff513d80e2c7fa487608f70a618dfbc0cf415699dc69588c747e8c71566c88de91a35050565b610466610d00565b63ffffffff8216600081815260666020526040808220849055518392917f74d6665c4b26d5596a5aa13d3014e0c06af4d322075a797f87b03cd4c5bc91ca91a35050565b606854606090831015806104bc575081155b6106e7575060408051600583901b8101602001909152825b8381116106e5576000606882815481106104f0576104f061137c565b600091825260209091200154905060e081901c60a082901c67ffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff831663ffffffff891683036106b6576001865101865260008173ffffffffffffffffffffffffffffffffffffffff1663609d33346040518163ffffffff1660e01b8152600401600060405180830381865afa15801561058a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d091908101906113da565b905060008273ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561061f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064391906114a5565b90506040518060a001604052808881526020018781526020018567ffffffffffffffff168152602001828152602001838152508860018a5161068591906114be565b815181106106955761069561137c565b6020026020010181905250888851106106b3575050505050506106e5565b50505b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191506104d49050565b505b9392505050565b60008060006106ff878787876109ef565b60009081526067602052604090205473ffffffffffffffffffffffffffffffffffffffff81169860a09190911c67ffffffffffffffff16975095505050505050565b610749610d00565b6107536000610d81565b565b63ffffffff841660009081526065602052604081205473ffffffffffffffffffffffffffffffffffffffff16806107c5576040517f031c6de400000000000000000000000000000000000000000000000000000000815263ffffffff871660048201526024015b60405180910390fd5b63ffffffff86166000908152606660205260409020543414610813576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006108206001436114be565b40905061088a338783888860405160200161083f9594939291906114fc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905273ffffffffffffffffffffffffffffffffffffffff841690610df8565b92508273ffffffffffffffffffffffffffffffffffffffff16638129fc1c346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156108d457600080fd5b505af11580156108e8573d6000803e3d6000fd5b505050505060006108fb888888886109ef565b60008181526067602052604090205490915015610947576040517f014f6fe5000000000000000000000000000000000000000000000000000000008152600481018290526024016107bc565b60004260a01b60e08a901b178517600083815260676020526040808220839055606880546001810182559083527fa2153420d844928b4421650203c77babc8b33d7f2e7b450e2966db0c220977530183905551919250899163ffffffff8c169173ffffffffffffffffffffffffffffffffffffffff8916917f5b565efe82411da98814f356d0e7bcb8f0219b8d970307c5afb4a6903a8b2e359190a450505050949350505050565b600084848484604051602001610a089493929190611549565b604051602081830303815290604052805190602001209050949350505050565b600080600080600080610a8160688881548110610a4757610a4761137c565b906000526020600020015460e081901c9160a082901c67ffffffffffffffff169173ffffffffffffffffffffffffffffffffffffffff1690565b9199909850909650945050505050565b600054610100900460ff1615808015610ab15750600054600160ff909116105b80610acb5750303b158015610acb575060005460ff166001145b610b57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107bc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610bb557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610bbd610e06565b610bc682610d81565b8015610c2957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b610c35610d00565b73ffffffffffffffffffffffffffffffffffffffff8116610cd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016107bc565b610ce181610d81565b50565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60335473ffffffffffffffffffffffffffffffffffffffff163314610753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107bc565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006106e760008484610ea5565b600054610100900460ff16610e9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b610753610feb565b600060608203516040830351602084035184518060208701018051600283016c5af43d3d93803e606057fd5bf3895289600d8a035278593da1005b363d3d373d3d3d3d610000806062363936013d738160481b1760218a03527f9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff603a8a035272fd6100003d81600a3d39f336602c57343d527f6062820160781b1761ff9e82106059018a03528060f01b8352606c8101604c8a038cf097505086610f715763301164256000526004601cfd5b905285527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08501527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa09092019190915292915050565b600054610100900460ff16611082576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b61075333610d81565b803563ffffffff8116811461109f57600080fd5b919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610ce157600080fd5b600080604083850312156110d957600080fd5b6110e28361108b565b915060208301356110f2816110a4565b809150509250929050565b60006020828403121561110f57600080fd5b6106e78261108b565b6000806040838503121561112b57600080fd5b6111348361108b565b946020939093013593505050565b60008060006060848603121561115757600080fd5b6111608461108b565b95602085013595506040909401359392505050565b60005b83811015611190578181015183820152602001611178565b8381111561119f576000848401525b50505050565b600081518084526111bd816020860160208601611175565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561129e578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001855281518051845287810151888501528681015167ffffffffffffffff16878501526060808201519085015260809081015160a09185018290529061128a818601836111a5565b968901969450505090860190600101611216565b509098975050505050505050565b6020815260006106e760208301846111a5565b600080600080606085870312156112d557600080fd5b6112de8561108b565b935060208501359250604085013567ffffffffffffffff8082111561130257600080fd5b818701915087601f83011261131657600080fd5b81358181111561132557600080fd5b88602082850101111561133757600080fd5b95989497505060200194505050565b60006020828403121561135857600080fd5b5035919050565b60006020828403121561137157600080fd5b81356106e7816110a4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156113ec57600080fd5b815167ffffffffffffffff8082111561140457600080fd5b818401915084601f83011261141857600080fd5b81518181111561142a5761142a6113ab565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611470576114706113ab565b8160405282815287602084870101111561148957600080fd5b61149a836020830160208801611175565b979650505050505050565b6000602082840312156114b757600080fd5b5051919050565b6000828210156114f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500390565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008660601b1681528460148201528360348201528183605483013760009101605401908152949350505050565b63ffffffff8516815283602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101939250505056fea164736f6c634300080f000a"; bytes internal constant delayedWETHCode = hex"6080604052600436106101845760003560e01c8063715018a6116100d6578063a9059cbb1161007f578063dd62ed3e11610059578063dd62ed3e1461051c578063f2fde38b14610554578063f3fef3a31461057457610193565b8063a9059cbb146104a8578063cd47bde1146104c8578063d0e30db01461019357610193565b80638da5cb5b116100b05780638da5cb5b1461041757806395d89b4114610442578063977a5ec51461048857610193565b8063715018a61461039057806379502c55146103a55780637eee288d146103f757610193565b80632e1a7d4d1161013857806354fd4d501161011257806354fd4d50146102e75780636a42b8f81461033057806370a082311461036357610193565b80632e1a7d4d14610280578063313ce567146102a0578063485cc955146102c757610193565b80630ca35682116101695780630ca356821461022357806318160ddd1461024357806323b872dd1461026057610193565b806306fdde031461019b578063095ea7b3146101f357610193565b3661019357610191610594565b005b610191610594565b3480156101a757600080fd5b5060408051808201909152600d81527f577261707065642045746865720000000000000000000000000000000000000060208201525b6040516101ea91906113fd565b60405180910390f35b3480156101ff57600080fd5b5061021361020e366004611492565b6105ef565b60405190151581526020016101ea565b34801561022f57600080fd5b5061019161023e3660046114be565b610668565b34801561024f57600080fd5b50475b6040519081526020016101ea565b34801561026c57600080fd5b5061021361027b3660046114d7565b6107b9565b34801561028c57600080fd5b5061019161029b3660046114be565b6109d0565b3480156102ac57600080fd5b506102b5601281565b60405160ff90911681526020016101ea565b3480156102d357600080fd5b506101916102e2366004611518565b6109dd565b3480156102f357600080fd5b506101dd6040518060400160405280600a81526020017f312e312e302d72632e310000000000000000000000000000000000000000000081525081565b34801561033c57600080fd5b507f0000000000000000000000000000000000000000000000000000000000093a80610252565b34801561036f57600080fd5b5061025261037e366004611551565b60656020526000908152604090205481565b34801561039c57600080fd5b50610191610bb9565b3480156103b157600080fd5b506068546103d29073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ea565b34801561040357600080fd5b50610191610412366004611492565b610bcd565b34801561042357600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff166103d2565b34801561044e57600080fd5b5060408051808201909152600481527f574554480000000000000000000000000000000000000000000000000000000060208201526101dd565b34801561049457600080fd5b506101916104a3366004611492565b610c21565b3480156104b457600080fd5b506102136104c3366004611492565b610d0e565b3480156104d457600080fd5b506105076104e3366004611518565b60676020908152600092835260408084209091529082529020805460019091015482565b604080519283526020830191909152016101ea565b34801561052857600080fd5b50610252610537366004611518565b606660209081526000928352604080842090915290825290205481565b34801561056057600080fd5b5061019161056f366004611551565b610d22565b34801561058057600080fd5b5061019161058f366004611492565b610dd6565b33600090815260656020526040812080543492906105b390849061159d565b909155505060405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b33600081815260666020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106579086815260200190565b60405180910390a350600192915050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064015b60405180910390fd5b60004782106106fd57476106ff565b815b604051909150600090339083908381818185875af1925050503d8060008114610744576040519150601f19603f3d011682016040523d82523d6000602084013e610749565b606091505b50509050806107b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f44656c61796564574554483a207265636f766572206661696c6564000000000060448201526064016106e5565b505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152606560205260408120548211156107eb57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610861575073ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156108e95773ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091529020548211156108a357600080fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152606660209081526040808320338452909152812080548492906108e39084906115b5565b90915550505b73ffffffffffffffffffffffffffffffffffffffff84166000908152606560205260408120805484929061091e9084906115b5565b909155505073ffffffffffffffffffffffffffffffffffffffff83166000908152606560205260408120805484929061095890849061159d565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109be91815260200190565b60405180910390a35060019392505050565b6109da3382610dd6565b50565b600054610100900460ff16158080156109fd5750600054600160ff909116105b80610a175750303b158015610a17575060005460ff166001145b610aa3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016106e5565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610b0157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b09611120565b610b12836111bf565b606880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617905580156107b457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b610bc1611236565b610bcb60006111bf565b565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120426001820155805490918391839190610c1790849061159d565b9091555050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610ca2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064016106e5565b73ffffffffffffffffffffffffffffffffffffffff821660008181526066602090815260408083203380855290835292819020859055518481529192917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a35050565b6000610d1b3384846107b9565b9392505050565b610d2a611236565b73ffffffffffffffffffffffffffffffffffffffff8116610dcd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016106e5565b6109da816111bf565b606860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6791906115cc565b15610ece576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f44656c61796564574554483a20636f6e7472616374206973207061757365640060448201526064016106e5565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290208054821115610f8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f44656c61796564574554483a20696e73756666696369656e7420756e6c6f636b60448201527f6564207769746864726177616c0000000000000000000000000000000000000060648201526084016106e5565b6000816001015411611022576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f44656c61796564574554483a207769746864726177616c206e6f7420756e6c6f60448201527f636b65640000000000000000000000000000000000000000000000000000000060648201526084016106e5565b427f0000000000000000000000000000000000000000000000000000000000093a808260010154611053919061159d565b11156110e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f44656c61796564574554483a207769746864726177616c2064656c6179206e6f60448201527f74206d657400000000000000000000000000000000000000000000000000000060648201526084016106e5565b818160000160008282546110f591906115b5565b909155506107b49050826112b7565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff166111b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106e5565b610bcb61135d565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610bcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106e5565b336000908152606560205260409020548111156112d357600080fd5b33600090815260656020526040812080548392906112f29084906115b5565b9091555050604051339082156108fc029083906000818181858888f19350505050158015611324573d6000803e3d6000fd5b5060405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a250565b600054610100900460ff166113f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106e5565b610bcb336111bf565b600060208083528351808285015260005b8181101561142a5785810183015185820160400152820161140e565b8181111561143c576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146109da57600080fd5b600080604083850312156114a557600080fd5b82356114b081611470565b946020939093013593505050565b6000602082840312156114d057600080fd5b5035919050565b6000806000606084860312156114ec57600080fd5b83356114f781611470565b9250602084013561150781611470565b929592945050506040919091013590565b6000806040838503121561152b57600080fd5b823561153681611470565b9150602083013561154681611470565b809150509250929050565b60006020828403121561156357600080fd5b8135610d1b81611470565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115b0576115b061156e565b500190565b6000828210156115c7576115c761156e565b500390565b6000602082840312156115de57600080fd5b81518015158114610d1b57600080fdfea164736f6c634300080f000a"; bytes internal constant preimageOracleCode = @@ -69,7 +69,7 @@ contract DeploymentSummaryCode { bytes internal constant mipsCode = hex"608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d50146100465780637dc0d1d014610098578063e14ced32146100dc575b600080fd5b6100826040518060400160405280600a81526020017f312e312e302d72632e310000000000000000000000000000000000000000000081525081565b60405161008f91906121ee565b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000373d916d11cce55b548f7051002e76bcfbd7a85d16815260200161008f565b6100ef6100ea3660046122a3565b6100fd565b60405190815260200161008f565b6000610107612164565b6080811461011457600080fd5b6040516106001461012457600080fd5b6084871461013157600080fd5b6101a4851461013f57600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a0819052605a89013590911c6101c05260628801906101e09060018111156101f5576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b506020810181511461020657600080fd5b60200160005b602081101561023057823560e01c825260049092019160209091019060010161020c565b5050508061012001511561024e576102466103a6565b91505061039d565b6101408101805160010167ffffffffffffffff16905260006101a49050600080600061028385606001518660000151866104f7565b9250925092508163ffffffff1660001480156102a557508063ffffffff16600c145b156102bf576102b387610521565b9550505050505061039d565b6000610339866040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b6101608701518751919250610356918391906105248888886108f9565b8652805163ffffffff9081166060808901919091526020830151821660808901526040830151821660a08901528201511660c08701526103946103a6565b96505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a8401526000926102009290916062830191906001811115610453576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b60005b602081101561047a57601c8601518452602090950194600490930192600101610456565b506000835283830384a060009450806001811461049a57600395506104c2565b8280156104b257600181146104bb57600296506104c0565b600096506104c0565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b6000806000610507858786610cdf565b925050603f601a83901c8116915082165b93509350939050565b600061052b612164565b608090506000806000806105628561016001516040810151608082015160a083015160c084015160e0909401519294919390929091565b509350935093509350600080610ffa63ffffffff168663ffffffff16036105a75761059285858960e00151610d93565b63ffffffff1660e08a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03363ffffffff8716016105e05763400000009150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefe863ffffffff8716016106165760019150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef6a63ffffffff87160161066a57600161012088015260ff851661010088015261065d6103a6565b9998505050505050505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05d63ffffffff8716016107665760006040518061012001604052808763ffffffff1681526020018663ffffffff1681526020018563ffffffff16815260200189602001518152602001896040015163ffffffff1681526020018b81526020017f000000000000000000000000373d916d11cce55b548f7051002e76bcfbd7a85d73ffffffffffffffffffffffffffffffffffffffff1681526020016107386101a4600160ff16610380020190565b81528951602090910152905061074d81610e27565b8b5263ffffffff1660408b015290935091506108089050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05c63ffffffff8716016107cb57602087015160408801516107b1918791879187916105248d5161109f565b63ffffffff1660408b015260208a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff02963ffffffff871601610808576108028585611195565b90925090505b6000610882886040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b61016089015163ffffffff85811660408084019190915285821660e0909301929092526020830180518083168086526004909101831682526060808e01919091529051821660808d015291830151811660a08c0152908201511660c08a015290506108eb6103a6565b9a9950505050505050505050565b84600263ffffffff8416148061091557508263ffffffff166003145b156109675760006002856303ffffff1663ffffffff16901b896020015163f00000001617905061096189898663ffffffff1660021461095557601f610958565b60005b60ff168461124a565b50610cd4565b600080601f601087901c8116908a90601589901c166020811061098c5761098c612317565b602002015192508063ffffffff871615806109ad57508663ffffffff16601c145b156109df578a8263ffffffff16602081106109ca576109ca612317565b6020020151925050601f600b88901c16610a96565b60208763ffffffff161015610a41578663ffffffff16600c1480610a0957508663ffffffff16600d145b80610a1a57508663ffffffff16600e145b15610a2b578761ffff169250610a96565b610a3a8861ffff166010611322565b9250610a96565b60288763ffffffff16101580610a5d57508663ffffffff166022145b80610a6e57508663ffffffff166026145b15610a96578a8263ffffffff1660208110610a8b57610a8b612317565b602002015192508190505b60048763ffffffff1610158015610ab3575060088763ffffffff16105b80610ac457508663ffffffff166001145b15610ae057610ad78c8c898b8689611395565b50505050610cd4565b63ffffffff6000602089831610610b4557610b008a61ffff166010611322565b9095019463fffffffc8616610b168d828e610cdf565b915060288a63ffffffff1610158015610b3657508963ffffffff16603014155b15610b4357809250600093505b505b6000610b558b8b8b8a8a87611583565b63ffffffff1690508963ffffffff166000148015610b7a575060088963ffffffff1610155b8015610b8c5750601c8963ffffffff16105b15610c54578863ffffffff1660081480610bac57508863ffffffff166009145b15610bdf57610bd38f8f8b63ffffffff16600814610bca5786610bcd565b60005b8a61124a565b50505050505050610cd4565b8863ffffffff16600a03610c0157610bd38f8f868a63ffffffff8b1615611ca0565b8863ffffffff16600b03610c2457610bd38f8f868a63ffffffff8b161515611ca0565b60108963ffffffff1610158015610c415750601c8963ffffffff16105b15610c5457610bd38f8f8b8a8a89611d70565b8963ffffffff166038148015610c6f575063ffffffff851615155b15610c9f5760018e8663ffffffff1660208110610c8e57610c8e612317565b63ffffffff90921660209290920201525b8263ffffffff1663ffffffff14610cbe57610cbb838d83612029565b97505b610ccc8f8f86846001611ca0565b505050505050505b979650505050505050565b6000610cea826120cb565b6003831615610cf857600080fd5b6020820191358360051c8160005b601b811015610d5e5760208601953583821c6001168015610d2e5760018114610d4357610d54565b60008481526020839052604090209350610d54565b600082815260208590526040902093505b5050600101610d06565b50868114610d7457630badf00d60005260206000fd5b5050601f93909316601c0360031b9290921c63ffffffff169392505050565b6000808284610fff811615610dad57610fff811661100003015b8663ffffffff16600003610e195784935090810190636000000063ffffffff83161180610de557508463ffffffff168263ffffffff16105b80610dfb57508563ffffffff168163ffffffff16105b15610e14575063ffffffff925060169150839050610518565b610e1d565b8693505b5093509350939050565b6101008101516080820151825160009283929163ffffffff161561109857845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb01611052576000610e93866101000151876020015163fffffffc168860e00151610cdf565b606087015190915060001a600103610f1557610f0f86606001518760a0015160408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b60608701525b6000808760c0015173ffffffffffffffffffffffffffffffffffffffff1663e03110e189606001518a608001516040518363ffffffff1660e01b8152600401610f6e92919091825263ffffffff16602082015260400190565b6040805180830381865afa158015610f8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fae9190612346565b60208a015160408b01519294509092509060038216600481900384811015610fd4578094505b5083821015610fe1578193505b8460088502610100031c9450846008828660040303021b9450600180600883600403021b036001806008878560040303021b0391508119811690508581198816179650505061103f8a6020015163fffffffc168b60e0015187612029565b9298505050938601939250611098915050565b845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0161108c5784604001519350611098565b63ffffffff9350600992505b9193509193565b600080858563ffffffff8b16600114806110bf575063ffffffff8b166002145b806110d0575063ffffffff8b166004145b156110dd57889350611187565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8c160161117b57600061111d868c63fffffffc1689610cdf565b90508860038c166004038b81101561113357809b505b8b965086900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193880293841b0116911b17915060009050611187565b63ffffffff9350600992505b975097509750979350505050565b60008063ffffffff83166003036112385763ffffffff841615806111bf575063ffffffff84166005145b806111d0575063ffffffff84166003145b156111de5760009150611243565b63ffffffff8416600114806111f9575063ffffffff84166002145b8061120a575063ffffffff84166006145b8061121b575063ffffffff84166004145b156112295760019150611243565b5063ffffffff90506009611243565b5063ffffffff905060165b9250929050565b836000015160040163ffffffff16846020015163ffffffff16146112cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b835160208501805163ffffffff908116875283811690915283161561131b5780600801848463ffffffff166020811061130a5761130a612317565b63ffffffff90921660209290920201525b5050505050565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b018261137f576000611381565b815b90861663ffffffff16179250505092915050565b6000866000015160040163ffffffff16876020015163ffffffff1614611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f7400000000000000000000000060448201526064016112c6565b8463ffffffff166004148061143257508463ffffffff166005145b156114a9576000868463ffffffff166020811061145157611451612317565b602002015190508063ffffffff168363ffffffff1614801561147957508563ffffffff166004145b806114a157508063ffffffff168363ffffffff16141580156114a157508563ffffffff166005145b915050611526565b8463ffffffff166006036114c65760008260030b13159050611526565b8463ffffffff166007036114e25760008260030b139050611526565b8463ffffffff1660010361152657601f601085901c16600081900361150b5760008360030b1291505b8063ffffffff166001036115245760008360030b121591505b505b8651602088015163ffffffff168852811561156757600261154c8661ffff166010611322565b63ffffffff90811690911b8201600401166020890152611579565b60208801805160040163ffffffff1690525b5050505050505050565b600063ffffffff861615806115b0575060088663ffffffff16101580156115b05750600f8663ffffffff16105b156119b05785600881146115f357600981146115fc57600a811461160557600b811461160e57600c811461161757600d811461162057600e81146116295761162e565b6020955061162e565b6021955061162e565b602a955061162e565b602b955061162e565b6024955061162e565b6025955061162e565b602695505b508463ffffffff16600003611653575063ffffffff8216601f600688901c161b611c96565b8463ffffffff16600203611677575063ffffffff8216601f600688901c161c611c96565b8463ffffffff166003036116ab57601f600688901c166116a363ffffffff8516821c6020839003611322565b915050611c96565b8463ffffffff166004036116cb575063ffffffff8216601f84161b611c96565b8463ffffffff166006036116eb575063ffffffff8216601f84161c611c96565b8463ffffffff1660070361171357601f84166116a363ffffffff8516821c6020839003611322565b8463ffffffff16600803611728575082611c96565b8463ffffffff1660090361173d575082611c96565b8463ffffffff16600a03611752575082611c96565b8463ffffffff16600b03611767575082611c96565b8463ffffffff16600c0361177c575082611c96565b8463ffffffff16600f03611791575082611c96565b8463ffffffff166010036117a6575082611c96565b8463ffffffff166011036117bb575082611c96565b8463ffffffff166012036117d0575082611c96565b8463ffffffff166013036117e5575082611c96565b8463ffffffff166018036117fa575082611c96565b8463ffffffff1660190361180f575082611c96565b8463ffffffff16601a03611824575082611c96565b8463ffffffff16601b03611839575082611c96565b8463ffffffff166020036118505750828201611c96565b8463ffffffff166021036118675750828201611c96565b8463ffffffff1660220361187e5750818303611c96565b8463ffffffff166023036118955750818303611c96565b8463ffffffff166024036118ac5750828216611c96565b8463ffffffff166025036118c35750828217611c96565b8463ffffffff166026036118da5750828218611c96565b8463ffffffff166027036118f2575082821719611c96565b8463ffffffff16602a03611921578260030b8460030b12611914576000611917565b60015b60ff169050611c96565b8463ffffffff16602b03611949578263ffffffff168463ffffffff1610611914576000611917565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e0000000000000000000000000060448201526064016112c6565b611949565b8563ffffffff16601c03611a30578463ffffffff166002036119d55750828202611c96565b8463ffffffff16602014806119f057508463ffffffff166021145b156119ab578463ffffffff16602003611a07579219925b60005b6380000000851615611a29576401fffffffe600195861b169401611a0a565b9050611c96565b8563ffffffff16600f03611a51575065ffffffff0000601083901b16611c96565b8563ffffffff16602003611a8557611a298460031660080260180363ffffffff168363ffffffff16901c60ff166008611322565b8563ffffffff16602103611aba57611a298460021660080260100363ffffffff168363ffffffff16901c61ffff166010611322565b8563ffffffff16602203611ae8575063ffffffff60086003851602811681811b198416918316901b17611c96565b8563ffffffff16602303611afd575080611c96565b8563ffffffff16602403611b2e578360031660080260180363ffffffff168263ffffffff16901c60ff169050611c96565b8563ffffffff16602503611b60578360021660080260100363ffffffff168263ffffffff16901c61ffff169050611c96565b8563ffffffff16602603611b91575063ffffffff60086003851602601803811681811c198416918316901c17611c96565b8563ffffffff16602803611bc6575060ff63ffffffff60086003861602601803811682811b9091188316918416901b17611c96565b8563ffffffff16602903611bfc575061ffff63ffffffff60086002861602601003811682811b9091188316918416901b17611c96565b8563ffffffff16602a03611c2a575063ffffffff60086003851602811681811c198316918416901c17611c96565b8563ffffffff16602b03611c3f575081611c96565b8563ffffffff16602e03611c70575063ffffffff60086003851602601803811681811b198316918416901b17611c96565b8563ffffffff16603003611c85575080611c96565b8563ffffffff166038036119495750815b9695505050505050565b60208363ffffffff1610611d10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c696420726567697374657200000000000000000000000000000000000060448201526064016112c6565b63ffffffff831615801590611d225750805b15611d515781848463ffffffff1660208110611d4057611d40612317565b63ffffffff90921660209290920201525b5050505060208101805163ffffffff8082169093526004019091169052565b60008463ffffffff16601003611d8b57506060860151611fd1565b8463ffffffff16601103611daa5763ffffffff84166060880152611fd1565b8463ffffffff16601203611dc357506040860151611fd1565b8463ffffffff16601303611de25763ffffffff84166040880152611fd1565b8463ffffffff16601803611e165763ffffffff600385810b9085900b02602081901c821660608a0152166040880152611fd1565b8463ffffffff16601903611e475763ffffffff84811681851602602081901c821660608a0152166040880152611fd1565b8463ffffffff16601a03611f0a578260030b600003611ec2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8260030b8460030b81611ed757611ed761236a565b0763ffffffff166060880152600383810b9085900b81611ef957611ef961236a565b0563ffffffff166040880152611fd1565b8463ffffffff16601b03611fd1578263ffffffff16600003611f88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8263ffffffff168463ffffffff1681611fa357611fa361236a565b0663ffffffff908116606089015283811690851681611fc457611fc461236a565b0463ffffffff1660408801525b63ffffffff8216156120075780868363ffffffff1660208110611ff657611ff6612317565b63ffffffff90921660209290920201525b50505060208401805163ffffffff808216909652600401909416909352505050565b6000612034836120cb565b600384161561204257600080fd5b6020830192601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b8110156120c05760208601953582821c600116801561209057600181146120a5576120b6565b600085815260208390526040902094506120b6565b600082815260208690526040902094505b5050600101612068565b509095945050505050565b366103808201811015612160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f617461000000000000000000000000000000000000000000000000000000000060648201526084016112c6565b5050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915261016081016121ca6121cf565b905290565b6040518061040001604052806020906020820280368337509192915050565b600060208083528351808285015260005b8181101561221b578581018301518582016040015282016121ff565b8181111561222d576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60008083601f84011261227357600080fd5b50813567ffffffffffffffff81111561228b57600080fd5b60208301915083602082850101111561124357600080fd5b6000806000806000606086880312156122bb57600080fd5b853567ffffffffffffffff808211156122d357600080fd5b6122df89838a01612261565b909750955060208801359150808211156122f857600080fd5b5061230588828901612261565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561235957600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a"; bytes internal constant anchorStateRegistryCode = - hex"608060405234801561001057600080fd5b506004361061007d5760003560e01c80635e05fbd01161005b5780635e05fbd01461012a5780637258a8071461013d578063838c2d1e14610179578063f2b4e6171461018157600080fd5b806317cf21a91461008257806335e80ab31461009757806354fd4d50146100e1575b600080fd5b610095610090366004610b4c565b6101a7565b005b6002546100b79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61011d6040518060400160405280600a81526020017f322e302e302d72632e310000000000000000000000000000000000000000000081525081565b6040516100d89190610bea565b610095610138366004610cc6565b61061c565b61016461014b366004610df0565b6001602081905260009182526040909120805491015482565b604080519283526020830191909152016100d8565b610095610853565b7f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d6100b7565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610214573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102389190610e0d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461029c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156102ec573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526103329190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161039793929190610efb565b6040805180830381865afa1580156103b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d79190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043f576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561048c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b09190610f9f565b60028111156104c1576104c1610f70565b146104f8576040517f8f8af25f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806105788773ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610551573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105759190610fc0565b90565b81526020018673ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ec9190610fc0565b905263ffffffff909416600090815260016020818152604090922086518155959091015194019390935550505050565b600054610100900460ff161580801561063c5750600054600160ff909116105b806106565750303b158015610656575060005460ff166001145b6106e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561074457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60005b83518110156107aa57600084828151811061076457610764610fd9565b60209081029190910181015180820151905163ffffffff1660009081526001808452604090912082518155919092015191015550806107a281611008565b915050610747565b50600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055801561084e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600033905060008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108a8573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526108ee9190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161095393929190610efb565b6040805180830381865afa15801561096f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109939190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109fb576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160008563ffffffff1663ffffffff168152602001908152602001600020600101548573ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8d9190610fc0565b11610a99575050505050565b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ae6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0a9190610f9f565b6002811115610b1b57610b1b610f70565b146104f8575050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4957600080fd5b50565b600060208284031215610b5e57600080fd5b8135610b6981610b27565b9392505050565b60005b83811015610b8b578181015183820152602001610b73565b83811115610b9a576000848401525b50505050565b60008151808452610bb8816020860160208601610b70565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610b696020830184610ba0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610c4f57610c4f610bfd565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610c9c57610c9c610bfd565b604052919050565b63ffffffff81168114610b4957600080fd5b8035610cc181610b27565b919050565b6000806040808486031215610cda57600080fd5b833567ffffffffffffffff80821115610cf257600080fd5b818601915086601f830112610d0657600080fd5b8135602082821115610d1a57610d1a610bfd565b610d28818360051b01610c55565b8281528181019350606092830285018201928a841115610d4757600080fd5b948201945b83861015610dd457858b0381811215610d655760008081fd5b610d6d610c2c565b8735610d7881610ca4565b81527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201891315610daa5760008081fd5b610db2610c2c565b8886013581528989013586820152818601528652509485019493820193610d4c565b509650610de2888201610cb6565b955050505050509250929050565b600060208284031215610e0257600080fd5b8135610b6981610ca4565b600060208284031215610e1f57600080fd5b8151610b6981610b27565b600080600060608486031215610e3f57600080fd5b8351610e4a81610ca4565b60208501516040860151919450925067ffffffffffffffff80821115610e6f57600080fd5b818601915086601f830112610e8357600080fd5b815181811115610e9557610e95610bfd565b610ec660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610c55565b9150808252876020828501011115610edd57600080fd5b610eee816020840160208601610b70565b5080925050509250925092565b63ffffffff84168152826020820152606060408201526000610f206060830184610ba0565b95945050505050565b60008060408385031215610f3c57600080fd5b8251610f4781610b27565b602084015190925067ffffffffffffffff81168114610f6557600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060208284031215610fb157600080fd5b815160038110610b6957600080fd5b600060208284031215610fd257600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611060577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea164736f6c634300080f000a"; + hex"608060405234801561001057600080fd5b506004361061007d5760003560e01c80635e05fbd01161005b5780635e05fbd01461012a5780637258a8071461013d578063838c2d1e14610179578063f2b4e6171461018157600080fd5b806317cf21a91461008257806335e80ab31461009757806354fd4d50146100e1575b600080fd5b610095610090366004610b4c565b6101a7565b005b6002546100b79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61011d6040518060400160405280600c81526020017f322e302e312d626574612e31000000000000000000000000000000000000000081525081565b6040516100d89190610bea565b610095610138366004610cc6565b61061c565b61016461014b366004610df0565b6001602081905260009182526040909120805491015482565b604080519283526020830191909152016100d8565b610095610853565b7f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d6100b7565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610214573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102389190610e0d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461029c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156102ec573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526103329190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161039793929190610efb565b6040805180830381865afa1580156103b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d79190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043f576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561048c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b09190610f9f565b60028111156104c1576104c1610f70565b146104f8576040517f8f8af25f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806105788773ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610551573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105759190610fc0565b90565b81526020018673ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ec9190610fc0565b905263ffffffff909416600090815260016020818152604090922086518155959091015194019390935550505050565b600054610100900460ff161580801561063c5750600054600160ff909116105b806106565750303b158015610656575060005460ff166001145b6106e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561074457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60005b83518110156107aa57600084828151811061076457610764610fd9565b60209081029190910181015180820151905163ffffffff1660009081526001808452604090912082518155919092015191015550806107a281611008565b915050610747565b50600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055801561084e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600033905060008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108a8573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526108ee9190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161095393929190610efb565b6040805180830381865afa15801561096f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109939190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109fb576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160008563ffffffff1663ffffffff168152602001908152602001600020600101548573ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8d9190610fc0565b11610a99575050505050565b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ae6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0a9190610f9f565b6002811115610b1b57610b1b610f70565b146104f8575050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4957600080fd5b50565b600060208284031215610b5e57600080fd5b8135610b6981610b27565b9392505050565b60005b83811015610b8b578181015183820152602001610b73565b83811115610b9a576000848401525b50505050565b60008151808452610bb8816020860160208601610b70565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610b696020830184610ba0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610c4f57610c4f610bfd565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610c9c57610c9c610bfd565b604052919050565b63ffffffff81168114610b4957600080fd5b8035610cc181610b27565b919050565b6000806040808486031215610cda57600080fd5b833567ffffffffffffffff80821115610cf257600080fd5b818601915086601f830112610d0657600080fd5b8135602082821115610d1a57610d1a610bfd565b610d28818360051b01610c55565b8281528181019350606092830285018201928a841115610d4757600080fd5b948201945b83861015610dd457858b0381811215610d655760008081fd5b610d6d610c2c565b8735610d7881610ca4565b81527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201891315610daa5760008081fd5b610db2610c2c565b8886013581528989013586820152818601528652509485019493820193610d4c565b509650610de2888201610cb6565b955050505050509250929050565b600060208284031215610e0257600080fd5b8135610b6981610ca4565b600060208284031215610e1f57600080fd5b8151610b6981610b27565b600080600060608486031215610e3f57600080fd5b8351610e4a81610ca4565b60208501516040860151919450925067ffffffffffffffff80821115610e6f57600080fd5b818601915086601f830112610e8357600080fd5b815181811115610e9557610e95610bfd565b610ec660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610c55565b9150808252876020828501011115610edd57600080fd5b610eee816020840160208601610b70565b5080925050509250925092565b63ffffffff84168152826020820152606060408201526000610f206060830184610ba0565b95945050505050565b60008060408385031215610f3c57600080fd5b8251610f4781610b27565b602084015190925067ffffffffffffffff81168114610f6557600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060208284031215610fb157600080fd5b815160038110610b6957600080fd5b600060208284031215610fd257600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611060577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea164736f6c634300080f000a"; bytes internal constant acc33Code = hex"6080604052600436106102f25760003560e01c806370872aa51161018f578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b18578063fa315aa914610b3c578063fe2bbeb214610b6f57600080fd5b8063ec5e630814610a95578063eff0f59214610ac8578063f8f43ff614610af857600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a0f578063d8cc1a3c14610a42578063dabd396d14610a6257600080fd5b8063c6f0308c14610937578063cf09e0d0146109c1578063d5d44d80146109e257600080fd5b80638d450a9511610143578063bcef3b551161011d578063bcef3b55146108b7578063bd8da956146108f7578063c395e1ca1461091757600080fd5b80638d450a9514610777578063a445ece6146107aa578063bbdc02db1461087657600080fd5b80638129fc1c116101745780638129fc1c1461071a5780638980e0cc146107225780638b85902b1461073757600080fd5b806370872aa5146106f25780637b0f0adc1461070757600080fd5b80633fc8cef3116102485780635c0cba33116101fc5780636361506d116101d65780636361506d1461066c5780636b6716c0146106ac5780636f034409146106df57600080fd5b80635c0cba3314610604578063609d33341461063757806360e274641461064c57600080fd5b806354fd4d501161022d57806354fd4d501461055e57806357da950e146105b45780635a5fa2d9146105e457600080fd5b80633fc8cef314610518578063472777c61461054b57600080fd5b80632810e1d6116102aa57806337b1b2291161028457806337b1b229146104655780633a768463146104a55780633e3ac912146104d857600080fd5b80632810e1d6146103de5780632ad69aeb146103f357806330dbe5701461041357600080fd5b806319effeb4116102db57806319effeb414610339578063200d2ed21461038457806325fc2ace146103bf57600080fd5b806301935130146102f757806303c2924d14610319575b600080fd5b34801561030357600080fd5b506103176103123660046154e2565b610b9f565b005b34801561032557600080fd5b5061031761033436600461553d565b610ec0565b34801561034557600080fd5b506000546103669068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561039057600080fd5b506000546103b290700100000000000000000000000000000000900460ff1681565b60405161037b919061558e565b3480156103cb57600080fd5b506008545b60405190815260200161037b565b3480156103ea57600080fd5b506103b2611566565b3480156103ff57600080fd5b506103d061040e36600461553d565b61180b565b34801561041f57600080fd5b506001546104409073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161037b565b34801561047157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610440565b3480156104b157600080fd5b507f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe7806610440565b3480156104e457600080fd5b50600054610508907201000000000000000000000000000000000000900460ff1681565b604051901515815260200161037b565b34801561052457600080fd5b507f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92610440565b6103176105593660046155cf565b611841565b34801561056a57600080fd5b506105a76040518060400160405280600a81526020017f312e332e302d72632e310000000000000000000000000000000000000000000081525081565b60405161037b9190615666565b3480156105c057600080fd5b506008546009546105cf919082565b6040805192835260208301919091520161037b565b3480156105f057600080fd5b506103d06105ff366004615679565b611853565b34801561061057600080fd5b507f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e610440565b34801561064357600080fd5b506105a761188d565b34801561065857600080fd5b506103176106673660046156b7565b61189b565b34801561067857600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103d0565b3480156106b857600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610366565b6103176106ed3660046156e9565b611a42565b3480156106fe57600080fd5b506009546103d0565b6103176107153660046155cf565b61251b565b610317612528565b34801561072e57600080fd5b506002546103d0565b34801561074357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103d0565b34801561078357600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103d0565b3480156107b657600080fd5b506108226107c5366004615679565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff16606082015260800161037b565b34801561088257600080fd5b5060405163ffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260200161037b565b3480156108c357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103d0565b34801561090357600080fd5b50610366610912366004615679565b612a81565b34801561092357600080fd5b506103d0610932366004615728565b612c60565b34801561094357600080fd5b50610957610952366004615679565b612e43565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e00161037b565b3480156109cd57600080fd5b506000546103669067ffffffffffffffff1681565b3480156109ee57600080fd5b506103d06109fd3660046156b7565b60036020526000908152604090205481565b348015610a1b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000003856103d0565b348015610a4e57600080fd5b50610317610a5d36600461575a565b612eda565b348015610a6e57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b0610366565b348015610aa157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000046103d0565b348015610ad457600080fd5b50610508610ae3366004615679565b60046020526000908152604090205460ff1681565b348015610b0457600080fd5b50610317610b133660046155cf565b613509565b348015610b2457600080fd5b50610b2d6139c6565b60405161037b939291906157e4565b348015610b4857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000086103d0565b348015610b7b57600080fd5b50610508610b8a366004615679565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610bcb57610bcb61555f565b14610c02576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610c55576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610ca3610c9e36869003860186615838565b613a41565b14610cda576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610cef9291906158c5565b604051809103902014610d2e576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d77610d7284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613a9d92505050565b613b0a565b90506000610d9e82600881518110610d9157610d916158d5565b6020026020010151613cc0565b9050602081511115610ddc576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610e51576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610eec57610eec61555f565b14610f23576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610f3857610f386158d5565b906000526020600020906005020190506000610f5384612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b081169082161015610fbc576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611005576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561102257508515155b156110bd578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110555781611071565b600186015473ffffffffffffffffffffffffffffffffffffffff165b905061107d8187613d74565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff166060830152611160576fffffffffffffffffffffffffffffffff6040820152600181526000869003611160578195505b600086826020015163ffffffff166111789190615933565b90506000838211611189578161118b565b835b602084015190915063ffffffff165b818110156112d75760008682815481106111b6576111b66158d5565b6000918252602080832090910154808352600690915260409091205490915060ff1661120e576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611223576112236158d5565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112805750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b156112c257600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b505080806112cf9061594b565b91505061119a565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921790915584900361155b57606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558915801561145757506000547201000000000000000000000000000000000000900460ff165b156114cc5760015473ffffffffffffffffffffffffffffffffffffffff1661147f818a613d74565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff909116178855611559565b61151373ffffffffffffffffffffffffffffffffffffffff8216156114f1578161150d565b600189015473ffffffffffffffffffffffffffffffffffffffff165b89613d74565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff1660028111156115945761159461555f565b146115cb576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff1661162f576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008154811061165b5761165b6158d5565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611696576001611699565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff9091161770010000000000000000000000000000000083600281111561174a5761174a61555f565b02179055600281111561175f5761175f61555f565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e73ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156117f057600080fd5b505af1158015611804573d6000803e3d6000fd5b5050505090565b6005602052816000526040600020818154811061182757600080fd5b90600052602060002001600091509150505481565b905090565b61184e8383836001611a42565b505050565b6000818152600760209081526040808320600590925282208054825461188490610100900463ffffffff1682615983565b95945050505050565b606061183c60546020613e75565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260036020526040812080549082905590819003611900576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169063f3fef3a390604401600060405180830381600087803b15801561199057600080fd5b505af11580156119a4573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a02576040519150601f19603f3d011682016040523d82523d6000602084013e611a07565b606091505b505090508061184e576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008054700100000000000000000000000000000000900460ff166002811115611a6e57611a6e61555f565b14611aa5576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110611aba57611aba6158d5565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514611ba1576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000611c61826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580611c9c5750611c997f00000000000000000000000000000000000000000000000000000000000000046002615933565b81145b8015611ca6575084155b15611cdd576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015611d03575086155b15611d3a576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000008811115611d94576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dbf7f00000000000000000000000000000000000000000000000000000000000000046001615933565b8103611dd157611dd186888588613ec7565b34611ddb83612c60565b14611e12576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611e1d88612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b0811690821603611e85576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611eb260017f0000000000000000000000000000000000000000000000000000000000000008615983565b8303611ff0577f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f47919061599a565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb591906159b7565b611fe9907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166159d0565b9050612083565b61201b60017f0000000000000000000000000000000000000000000000000000000000000004615983565b830361205657611fe97f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1660026159fc565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b6120b7817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b67ffffffffffffffff166120d28367ffffffffffffffff1690565b67ffffffffffffffff16111561211957612116817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615612197576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c8152602001908152602001600020600160028054905061242d9190615983565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169263d0e30db09234926004808301939282900301818588803b1580156124c557600080fd5b505af11580156124d9573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b61184e8383836000611a42565b60005471010000000000000000000000000000000000900460ff161561257a576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e1690637258a807906024016040805180830381865afa15801561262e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126529190615a55565b90925090508161268e576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a146126c157639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401351161275b576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd929092169363d0e30db093926004828101939282900301818588803b158015612a3057600080fd5b505af1158015612a44573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b600080600054700100000000000000000000000000000000900460ff166002811115612aaf57612aaf61555f565b14612ae6576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110612afb57612afb6158d5565b600091825260208220600590910201805490925063ffffffff90811614612b6a57815460028054909163ffffffff16908110612b3957612b396158d5565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090612ba290700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b612bb69067ffffffffffffffff1642615983565b612bd5612b95846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16612be99190615933565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b01667ffffffffffffffff168167ffffffffffffffff1611612c365780611884565b7f00000000000000000000000000000000000000000000000000000000000004b095945050505050565b600080612cff836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000008811115612d5e576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000612d798383615aa8565b9050670de0b6b3a76400006000612db0827f0000000000000000000000000000000000000000000000000000000000000008615abc565b90506000612dce612dc9670de0b6b3a764000086615abc565b614078565b90506000612ddc84846142d3565b90506000612dea8383614322565b90506000612df782614350565b90506000612e1682612e11670de0b6b3a76400008f615abc565b614538565b90506000612e248b83614322565b9050612e30818d615abc565b9f9e505050505050505050505050505050565b60028181548110612e5357600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b60008054700100000000000000000000000000000000900460ff166002811115612f0657612f0661555f565b14612f3d576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028781548110612f5257612f526158d5565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b9050612fb17f00000000000000000000000000000000000000000000000000000000000000086001615933565b61304d826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1614613087576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561317e576130da7f00000000000000000000000000000000000000000000000000000000000000047f0000000000000000000000000000000000000000000000000000000000000008615983565b6001901b6130f9846fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff166131159190615af9565b156131525761314961313a60016fffffffffffffffffffffffffffffffff8716615b0d565b865463ffffffff166000614608565b60030154613174565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506131a8565b600385015491506131a561313a6fffffffffffffffffffffffffffffffff86166001615b36565b90505b600882901b60088a8a6040516131bf9291906158c5565b6040518091039020901b14613200576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061320b8c6146ec565b9050600061321a836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff169063e14ced3290613294908f908f908f908f908a90600401615baa565b6020604051808303816000875af11580156132b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d791906159b7565b600485015491149150600090600290613382906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b61341e896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6134289190615be4565b6134329190615c07565b60ff161590508115158103613473576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156134ca576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff1660028111156135355761353561555f565b1461356c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061357b8661471b565b9350935093509350600061359185858585614b24565b905060007f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015613600573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613624919061599a565b90506001890361371c5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a84613680367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af11580156136f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061371691906159b7565b5061155b565b600289036137485773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8489613680565b600389036137745773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8487613680565b600489036138fb5760006137ba6fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000004614bde565b6009546137c79190615933565b6137d2906001615933565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061383b57367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036054013561383d565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156138d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f491906159b7565b505061155b565b60058903613994576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000038560c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016136d3565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060613a1f61188d565b9050909192565b600081831015613a365781613a38565b825b90505b92915050565b60008160000151826020015183604001518460600151604051602001613a80949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003613aec576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000613b1a85614c8c565b919450925090506001816001811115613b3557613b3561555f565b14613b6c576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451613b788385615933565b14613baf576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081613bc65790505093506000835b8651811015613cb457600080613c396040518060400160405280858c60000151613c1d9190615983565b8152602001858c60200151613c329190615933565b9052614c8c565b509150915060405180604001604052808383613c559190615933565b8152602001848b60200151613c6a9190615933565b815250888581518110613c7f57613c7f6158d5565b6020908102919091010152613c95600185615933565b9350613ca18183615933565b613cab9084615933565b92505050613bf3565b50845250919392505050565b60606000806000613cd085614c8c565b919450925090506000816001811115613ceb57613ceb61555f565b14613d22576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613d2c8284615933565b855114613d65576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118848560200151848461512a565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff90931692839290613dc3908490615933565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd921690637eee288d90604401600060405180830381600087803b158015613e5857600080fd5b505af1158015613e6c573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b6000613ee66fffffffffffffffffffffffffffffffff84166001615b36565b90506000613ef682866001614608565b9050600086901a8380613fe25750613f2f60027f0000000000000000000000000000000000000000000000000000000000000004615af9565b6004830154600290613fd3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b613fdd9190615c07565b60ff16145b1561403a5760ff811660011480613ffc575060ff81166002145b614035576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b613e6c565b60ff811615613e6c576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b17600082136140d757631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a76400000215820261431057637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b6000816000190483118202156143405763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d7821361437e57919050565b680755bf798b4a1bf1e5821261439c5763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000613a38670de0b6b3a76400008361455086614078565b61455a9190615c29565b6145649190615ce5565b614350565b6000806145f6837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826146515761464c6fffffffffffffffffffffffffffffffff86167f00000000000000000000000000000000000000000000000000000000000000046151bf565b61466c565b61466c856fffffffffffffffffffffffffffffffff1661534b565b905060028481548110614681576146816158d5565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff8281169116146146e457815460028054909163ffffffff169081106146cf576146cf6158d5565b90600052602060002090600502019150614692565b509392505050565b60008060008060006146fd8661471b565b935093509350935061471184848484614b24565b9695505050505050565b600080600080600085905060006002828154811061473b5761473b6158d5565b600091825260209091206004600590920201908101549091507f000000000000000000000000000000000000000000000000000000000000000490614812906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff161161484c576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f000000000000000000000000000000000000000000000000000000000000000490614913906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16925082111561498857825463ffffffff166149527f00000000000000000000000000000000000000000000000000000000000000046001615933565b830361495c578391505b6002818154811061496f5761496f6158d5565b9060005260206000209060050201935080945050614850565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149f16149dc856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff161490508015614ac0576000614a29836fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff161115614a94576000614a6b614a6360016fffffffffffffffffffffffffffffffff8616615b0d565b896001614608565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a50614a9a9050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614b16565b6000614ae2614a636fffffffffffffffffffffffffffffffff85166001615b36565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614b915760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611884565b8282604051602001614bbf9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614c6b847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614ccf576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614cf4576000600160009450945094505050615123565b60b78111614e0a576000614d09608083615983565b905080876000015111614d48576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614dc057507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614df7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060019550935060009250615123915050565b60bf8111614f68576000614e1f60b783615983565b905080876000015111614e5e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614ec0576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614f08576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f128184615933565b895111614f4b576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f56836001615933565b97509550600094506151239350505050565b60f78111614fcd576000614f7d60c083615983565b905080876000015111614fbc576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600195509350849250615123915050565b6000614fda60f783615983565b905080876000015111615019576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361507b576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116150c3576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6150cd8184615933565b895111615106576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615111836001615933565b97509550600194506151239350505050565b9193909250565b60608167ffffffffffffffff81111561514557615145615809565b6040519080825280601f01601f19166020018201604052801561516f576020820181803683370190505b50905081156151b85760006151848486615933565b90506020820160005b848110156151a557828101518282015260200161518d565b848111156151b4576000858301525b5050505b9392505050565b60008161525e846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116152745763b34b5c226000526004601cfd5b61527d8361534b565b90508161531c826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611613a3b57613a38615332836001615933565b6fffffffffffffffffffffffffffffffff8316906153f0565b600081196001830116816153df827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b60008061547d847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f8401126154ab57600080fd5b50813567ffffffffffffffff8111156154c357600080fd5b6020830191508360208285010111156154db57600080fd5b9250929050565b600080600083850360a08112156154f857600080fd5b608081121561550657600080fd5b50839250608084013567ffffffffffffffff81111561552457600080fd5b61553086828701615499565b9497909650939450505050565b6000806040838503121561555057600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106155c9577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806000606084860312156155e457600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561562157602081850181015186830182015201615605565b81811115615633576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000613a3860208301846155fb565b60006020828403121561568b57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146156b457600080fd5b50565b6000602082840312156156c957600080fd5b81356151b881615692565b803580151581146156e457600080fd5b919050565b600080600080608085870312156156ff57600080fd5b84359350602085013592506040850135915061571d606086016156d4565b905092959194509250565b60006020828403121561573a57600080fd5b81356fffffffffffffffffffffffffffffffff811681146151b857600080fd5b6000806000806000806080878903121561577357600080fd5b86359550615783602088016156d4565b9450604087013567ffffffffffffffff808211156157a057600080fd5b6157ac8a838b01615499565b909650945060608901359150808211156157c557600080fd5b506157d289828a01615499565b979a9699509497509295939492505050565b63ffffffff8416815282602082015260606040820152600061188460608301846155fb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006080828403121561584a57600080fd5b6040516080810181811067ffffffffffffffff82111715615894577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561594657615946615904565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361597c5761597c615904565b5060010190565b60008282101561599557615995615904565b500390565b6000602082840312156159ac57600080fd5b81516151b881615692565b6000602082840312156159c957600080fd5b5051919050565b600067ffffffffffffffff8083168185168083038211156159f3576159f3615904565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615a2357615a23615904565b02949350505050565b600067ffffffffffffffff83811690831681811015615a4d57615a4d615904565b039392505050565b60008060408385031215615a6857600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615ab757615ab7615a79565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615af457615af4615904565b500290565b600082615b0857615b08615a79565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615a4d57615a4d615904565b60006fffffffffffffffffffffffffffffffff8083168185168083038211156159f3576159f3615904565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615bbe606083018789615b61565b8281036020840152615bd1818688615b61565b9150508260408301529695505050505050565b600060ff821660ff841680821015615bfe57615bfe615904565b90039392505050565b600060ff831680615c1a57615c1a615a79565b8060ff84160691505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615c6a57615c6a615904565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615ca557615ca5615904565b60008712925087820587128484161615615cc157615cc1615904565b87850587128184161615615cd757615cd7615904565b505050929093029392505050565b600082615cf457615cf4615a79565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615d4857615d48615904565b50059056fea164736f6c634300080f000a"; bytes internal constant acc34Code = diff --git a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofs.sol b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofs.sol index 41a56ef77bad..7f3e459b481e 100644 --- a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofs.sol +++ b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofs.sol @@ -13,36 +13,36 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { Vm private constant vm = Vm(VM_ADDRESS); address internal constant addressManagerAddress = 0x50EEf481cae4250d252Ae577A09bF514f224C6C4; - address internal constant anchorStateRegistryAddress = 0x63B71B96756C693f7065345fecD9b7843b3e7C57; + address internal constant anchorStateRegistryAddress = 0x0C21b289b76ae49983890aed23F78337333F0A5F; address internal constant anchorStateRegistryProxyAddress = 0x970670459734a83899773A0fd45941B5afC1200e; address internal constant delayedWETHAddress = 0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05; address internal constant delayedWETHProxyAddress = 0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92; - address internal constant disputeGameFactoryAddress = 0x20B168142354Cee65a32f6D8cf3033E592299765; + address internal constant disputeGameFactoryAddress = 0x8efDa795511CBBdfFC9eeca1a5bF30f5B1E1ef9E; address internal constant disputeGameFactoryProxyAddress = 0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d; - address internal constant l1CrossDomainMessengerAddress = 0x094e6508ba9d9bf1ce421fff3dE06aE56e67901b; + address internal constant l1CrossDomainMessengerAddress = 0x357B6CdA94109749a0dA475ac1BFd395a61eb908; address internal constant l1CrossDomainMessengerProxyAddress = 0xDeF3bca8c80064589E6787477FFa7Dd616B5574F; - address internal constant l1ERC721BridgeAddress = 0x5C4F5e749A61a9503c4AAE8a9393e89609a0e804; + address internal constant l1ERC721BridgeAddress = 0xA4BD7E58A30ED0477fe7372883d09bF86619Bb66; address internal constant l1ERC721BridgeProxyAddress = 0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865; - address internal constant l1StandardBridgeAddress = 0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b; + address internal constant l1StandardBridgeAddress = 0x6cb2c88ABCd6391F9496f44BE27d5D3b247E0159; address internal constant l1StandardBridgeProxyAddress = 0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D; - address internal constant l2OutputOracleAddress = 0x19652082F846171168Daf378C4fD3ee85a0D4A60; + address internal constant l2OutputOracleAddress = 0x60d37db59d0D14f7EA5c7425A2C03244E08B162D; address internal constant l2OutputOracleProxyAddress = 0x39Af23E00F1e662025aA01b0cEdA19542B78DF99; address internal constant mipsAddress = 0x444e09fe6D839273316a87002aB0EFBeA6fe7806; - address internal constant optimismMintableERC20FactoryAddress = 0x7c06d3a0a2f45e39E1798afbd9C3330971332a4F; + address internal constant optimismMintableERC20FactoryAddress = 0x47a13af3fB62B24E4914C36aBD9882da23D0e29C; address internal constant optimismMintableERC20FactoryProxyAddress = 0xc7B87b2b892EA5C3CfF47168881FE168C00377FB; - address internal constant optimismPortalAddress = 0xbdD90485FCbcac869D5b5752179815a3103d8131; - address internal constant optimismPortal2Address = 0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b; + address internal constant optimismPortalAddress = 0xBE8eE5CEA97De55Ae8b020E778A5C93C2Af81Ed4; + address internal constant optimismPortal2Address = 0x5506077419b90A12C048500e2eBcafb4fC6Bab61; address internal constant optimismPortalProxyAddress = 0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4; address internal constant permissionedDelayedWETHProxyAddress = 0xd6EAF4c146261653EE059077B78ED088Add54309; address internal constant preimageOracleAddress = 0x373d916D11cce55b548F7051002e76BCFBD7a85d; - address internal constant protocolVersionsAddress = 0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F; + address internal constant protocolVersionsAddress = 0xa99F1ab91821747b76Ec0cDFA38368DF4Ba06E84; address internal constant protocolVersionsProxyAddress = 0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1; address internal constant proxyAdminAddress = 0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1; address internal constant safeProxyFactoryAddress = 0xA8452Ec99ce0C64f20701dB7dD3abDb607c00496; address internal constant safeSingletonAddress = 0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3; - address internal constant superchainConfigAddress = 0x068E44eB31e111028c41598E4535be7468674D0A; + address internal constant superchainConfigAddress = 0xDAf629c26abd7a84B6330c369887053B75dB2AF2; address internal constant superchainConfigProxyAddress = 0x4f559F30f5eB88D635FDe1548C4267DB8FaB0351; - address internal constant systemConfigAddress = 0x67866A5052E5302aaD08e9f352331fd8622eB6DC; + address internal constant systemConfigAddress = 0xd9CEcA938f039e427Edf626FA1f377d23A6b60c9; address internal constant systemConfigProxyAddress = 0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6; address internal constant systemOwnerSafeAddress = 0x7C0c8a15773ED7B50E7c738D1aF4c5e3a2b210BD; address internal constant acc33Address = 0xb6b1579AA54e2F61e621a40d5F2704D717B3544F; @@ -107,7 +107,7 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { value = hex"0000000000000000000000000000000000000000000000000000000000000001"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a"; + value = hex"000000000000000000000000daf629c26abd7a84b6330c369887053b75db2af2"; vm.store(superchainConfigProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -145,7 +145,7 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { value = hex"0000000000000000000000000000000000000000000000000000000000000002"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f"; + value = hex"000000000000000000000000a99f1ab91821747b76ec0cdfa38368df4ba06e84"; vm.store(protocolVersionsProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -430,7 +430,7 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { value = hex"0000000000000000000000000000000000000000000000000000000000000003"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"000000000000000000000000ae5dadfc48928543f706a9e6ce25c682aad2b63b"; + value = hex"0000000000000000000000005506077419b90a12c048500e2ebcafb4fc6bab61"; vm.store(optimismPortalProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -463,7 +463,7 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { value = hex"0000000000000000000000000000000000000000000000000000000000000004"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"00000000000000000000000067866a5052e5302aad08e9f352331fd8622eb6dc"; + value = hex"000000000000000000000000d9ceca938f039e427edf626fa1f377d23a6b60c9"; vm.store(systemConfigProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -532,7 +532,7 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { value = hex"0000000000000000000000000000000000000000000000000000000000000006"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"000000000000000000000000b7900b27be8f0e0ff65d1c3a4671e1220437dd2b"; + value = hex"0000000000000000000000006cb2c88abcd6391f9496f44be27d5d3b247e0159"; vm.store(l1StandardBridgeProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -559,7 +559,7 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { value = hex"0000000000000000000000000000000000000000000000000000000000000007"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"0000000000000000000000005c4f5e749a61a9503c4aae8a9393e89609a0e804"; + value = hex"000000000000000000000000a4bd7e58a30ed0477fe7372883d09bf86619bb66"; vm.store(l1ERC721BridgeProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -583,7 +583,7 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { value = hex"0000000000000000000000000000000000000000000000000000000000000008"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"0000000000000000000000007c06d3a0a2f45e39e1798afbd9c3330971332a4f"; + value = hex"00000000000000000000000047a13af3fb62b24e4914c36abd9882da23d0e29c"; vm.store(optimismMintableERC20FactoryProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -613,7 +613,7 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { value = hex"000000000000000000000000000000000000000000000000000000000000000b"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e"; - value = hex"000000000000000000000000094e6508ba9d9bf1ce421fff3de06ae56e67901b"; + value = hex"000000000000000000000000357b6cda94109749a0da475ac1bfd395a61eb908"; vm.store(addressManagerAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000010000000000000000000000000000000000000000"; @@ -643,7 +643,7 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { value = hex"000000000000000000000000000000000000000000000000000000000000000c"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"00000000000000000000000019652082f846171168daf378c4fd3ee85a0d4a60"; + value = hex"00000000000000000000000060d37db59d0d14f7ea5c7425a2c03244e08b162d"; vm.store(l2OutputOracleProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -679,7 +679,7 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { value = hex"000000000000000000000000000000000000000000000000000000000000000d"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"00000000000000000000000020b168142354cee65a32f6d8cf3033e592299765"; + value = hex"0000000000000000000000008efda795511cbbdffc9eeca1a5bf30f5b1e1ef9e"; vm.store(disputeGameFactoryProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -748,7 +748,7 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { value = hex"0000000000000000000000000000000000000000000000000000000000000010"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"00000000000000000000000063b71b96756c693f7065345fecd9b7843b3e7c57"; + value = hex"0000000000000000000000000c21b289b76ae49983890aed23f78337333f0a5f"; vm.store(anchorStateRegistryProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; diff --git a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofsCode.sol b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofsCode.sol index d05414671296..a980e26c22f2 100644 --- a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofsCode.sol +++ b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofsCode.sol @@ -17,11 +17,11 @@ contract DeploymentSummaryFaultProofsCode { bytes internal constant superchainConfigProxyCode = hex"60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a"; bytes internal constant superchainConfigCode = - hex"608060405234801561001057600080fd5b50600436106100885760003560e01c80635c975abb1161005b5780635c975abb146101255780636da663551461013d5780637fbf7b6a14610150578063c23a451a1461016657600080fd5b80633f4ba83a1461008d578063400ada7514610097578063452a9320146100aa57806354fd4d50146100dc575b600080fd5b61009561016e565b005b6100956100a5366004610746565b610294565b6100b261046d565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101186040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100d39190610808565b61012d6104a6565b60405190151581526020016100d3565b61009561014b366004610851565b6104d6565b6101586105a4565b6040519081526020016100d3565b6101586105d2565b61017661046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e20756e706175736500000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61026961026360017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60009055565b6040517fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d1693390600090a1565b600054610100900460ff16158080156102b45750600054600160ff909116105b806102ce5750303b1580156102ce575060005460ff166001145b61035a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161022c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156103b857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6103c18361061d565b8115610405576104056040518060400160405280601281526020017f496e697469616c697a65722070617573656400000000000000000000000000008152506106d8565b801561046857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006104a161049d60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b5490565b905090565b60006104a161049d60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b6104de61046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610598576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e2070617573650000000000000000000000000000000000000000000000606482015260840161022c565b6105a1816106d8565b50565b6105cf60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b81565b6105cf60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b61065061064b60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b829055565b60006040805173ffffffffffffffffffffffffffffffffffffffff841660208201527f7b743789cff01dafdeae47739925425aab5dfd02d0c8229e4a508bcd2b9f42bb9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526106cd91610808565b60405180910390a250565b61070c61070660017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60019055565b7fc32e6d5d6d1de257f64eac19ddb1f700ba13527983849c9486b1ab007ea283818160405161073b9190610808565b60405180910390a150565b6000806040838503121561075957600080fd5b823573ffffffffffffffffffffffffffffffffffffffff8116811461077d57600080fd5b91506020830135801515811461079257600080fd5b809150509250929050565b6000815180845260005b818110156107c3576020818501810151868301820152016107a7565b818111156107d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061081b602083018461079d565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561086357600080fd5b813567ffffffffffffffff8082111561087b57600080fd5b818401915084601f83011261088f57600080fd5b8135818111156108a1576108a1610822565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108e7576108e7610822565b8160405282815287602084870101111561090057600080fd5b826020860160208301376000928101602001929092525095945050505050565b600082821015610959577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a"; + hex"608060405234801561001057600080fd5b50600436106100885760003560e01c80635c975abb1161005b5780635c975abb146101255780636da663551461013d5780637fbf7b6a14610150578063c23a451a1461016657600080fd5b80633f4ba83a1461008d578063400ada7514610097578063452a9320146100aa57806354fd4d50146100dc575b600080fd5b61009561016e565b005b6100956100a5366004610746565b610294565b6100b261046d565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101186040518060400160405280600c81526020017f312e312e312d626574612e31000000000000000000000000000000000000000081525081565b6040516100d39190610808565b61012d6104a6565b60405190151581526020016100d3565b61009561014b366004610851565b6104d6565b6101586105a4565b6040519081526020016100d3565b6101586105d2565b61017661046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e20756e706175736500000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61026961026360017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60009055565b6040517fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d1693390600090a1565b600054610100900460ff16158080156102b45750600054600160ff909116105b806102ce5750303b1580156102ce575060005460ff166001145b61035a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161022c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156103b857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6103c18361061d565b8115610405576104056040518060400160405280601281526020017f496e697469616c697a65722070617573656400000000000000000000000000008152506106d8565b801561046857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006104a161049d60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b5490565b905090565b60006104a161049d60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b6104de61046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610598576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e2070617573650000000000000000000000000000000000000000000000606482015260840161022c565b6105a1816106d8565b50565b6105cf60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b81565b6105cf60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b61065061064b60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b829055565b60006040805173ffffffffffffffffffffffffffffffffffffffff841660208201527f7b743789cff01dafdeae47739925425aab5dfd02d0c8229e4a508bcd2b9f42bb9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526106cd91610808565b60405180910390a250565b61070c61070660017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60019055565b7fc32e6d5d6d1de257f64eac19ddb1f700ba13527983849c9486b1ab007ea283818160405161073b9190610808565b60405180910390a150565b6000806040838503121561075957600080fd5b823573ffffffffffffffffffffffffffffffffffffffff8116811461077d57600080fd5b91506020830135801515811461079257600080fd5b809150509250929050565b6000815180845260005b818110156107c3576020818501810151868301820152016107a7565b818111156107d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061081b602083018461079d565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561086357600080fd5b813567ffffffffffffffff8082111561087b57600080fd5b818401915084601f83011261088f57600080fd5b8135818111156108a1576108a1610822565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108e7576108e7610822565b8160405282815287602084870101111561090057600080fd5b826020860160208301376000928101602001929092525095945050505050565b600082821015610959577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a"; bytes internal constant protocolVersionsProxyCode = hex"60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a"; bytes internal constant protocolVersionsCode = - hex"608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b8578063f7d12760146101cb578063ffa1ad74146101d357600080fd5b80638da5cb5b14610180578063d798b1ac146101a8578063dc8452cd146101b057600080fd5b80635fd579af116100b25780635fd579af14610152578063715018a6146101655780637a1ac61e1461016d57600080fd5b80630457d6f2146100d9578063206a8300146100ee57806354fd4d5014610109575b600080fd5b6100ec6100e73660046108c3565b6101db565b005b6100f66101ef565b6040519081526020015b60405180910390f35b6101456040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516101009190610947565b6100ec6101603660046108c3565b61021d565b6100ec61022e565b6100ec61017b36600461098a565b610242565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b6100f66103f7565b6100f6610430565b6100ec6101c63660046109bd565b610460565b6100f6610514565b6100f6600081565b6101e361055f565b6101ec816105e0565b50565b61021a60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b81565b61022561055f565b6101ec81610698565b61023661055f565b6102406000610712565b565b600054610100900460ff16158080156102625750600054600160ff909116105b8061027c5750303b15801561027c575060005460ff166001145b61030d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561036b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610373610789565b61037c84610460565b610385836105e0565b61038e82610698565b80156103f157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b600061042b61042760017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b5490565b905090565b600061042b61042760017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b61046861055f565b73ffffffffffffffffffffffffffffffffffffffff811661050b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610304565b6101ec81610712565b61021a60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610304565b61061361060e60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b829055565b60008160405160200161062891815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be8360405161068c9190610947565b60405180910390a35050565b6106c661060e60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b6000816040516020016106db91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600161065b565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16610820576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b610240600054610100900460ff166108ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b61024033610712565b6000602082840312156108d557600080fd5b5035919050565b6000815180845260005b81811015610902576020818501810151868301820152016108e6565b81811115610914576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061095a60208301846108dc565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461098557600080fd5b919050565b60008060006060848603121561099f57600080fd5b6109a884610961565b95602085013595506040909401359392505050565b6000602082840312156109cf57600080fd5b61095a82610961565b600082821015610a11577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a"; + hex"608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b8578063f7d12760146101cb578063ffa1ad74146101d357600080fd5b80638da5cb5b14610180578063d798b1ac146101a8578063dc8452cd146101b057600080fd5b80635fd579af116100b25780635fd579af14610152578063715018a6146101655780637a1ac61e1461016d57600080fd5b80630457d6f2146100d9578063206a8300146100ee57806354fd4d5014610109575b600080fd5b6100ec6100e73660046108c3565b6101db565b005b6100f66101ef565b6040519081526020015b60405180910390f35b6101456040518060400160405280600c81526020017f312e302e312d626574612e31000000000000000000000000000000000000000081525081565b6040516101009190610947565b6100ec6101603660046108c3565b61021d565b6100ec61022e565b6100ec61017b36600461098a565b610242565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b6100f66103f7565b6100f6610430565b6100ec6101c63660046109bd565b610460565b6100f6610514565b6100f6600081565b6101e361055f565b6101ec816105e0565b50565b61021a60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b81565b61022561055f565b6101ec81610698565b61023661055f565b6102406000610712565b565b600054610100900460ff16158080156102625750600054600160ff909116105b8061027c5750303b15801561027c575060005460ff166001145b61030d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561036b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610373610789565b61037c84610460565b610385836105e0565b61038e82610698565b80156103f157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b600061042b61042760017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b5490565b905090565b600061042b61042760017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b61046861055f565b73ffffffffffffffffffffffffffffffffffffffff811661050b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610304565b6101ec81610712565b61021a60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610304565b61061361060e60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b829055565b60008160405160200161062891815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be8360405161068c9190610947565b60405180910390a35050565b6106c661060e60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b6000816040516020016106db91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600161065b565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16610820576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b610240600054610100900460ff166108ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b61024033610712565b6000602082840312156108d557600080fd5b5035919050565b6000815180845260005b81811015610902576020818501810151868301820152016108e6565b81811115610914576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061095a60208301846108dc565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461098557600080fd5b919050565b60008060006060848603121561099f57600080fd5b6109a884610961565b95602085013595506040909401359392505050565b6000602082840312156109cf57600080fd5b61095a82610961565b600082821015610a11577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a"; bytes internal constant optimismPortalProxyCode = hex"60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a"; bytes internal constant systemConfigProxyCode = @@ -45,23 +45,23 @@ contract DeploymentSummaryFaultProofsCode { bytes internal constant anchorStateRegistryProxyCode = hex"60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a"; bytes internal constant l1CrossDomainMessengerCode = - hex"60806040526004361061018b5760003560e01c80636425666b116100d6578063b1b1b2091161007f578063d764ad0b11610059578063d764ad0b1461049b578063db505d80146104ae578063ecc70428146104db57600080fd5b8063b1b1b2091461042b578063b28ade251461045b578063c0c53b8b1461047b57600080fd5b80638cbeeef2116100b05780638cbeeef2146102d05780639fce812c146103d0578063a4e7f8bd146103fb57600080fd5b80636425666b146103775780636e296e45146103a457806383a74074146103b957600080fd5b80633dbb202b1161013857806354fd4d501161011257806354fd4d50146102e65780635644cfdf1461033c5780635c975abb1461035257600080fd5b80633dbb202b146102935780633f827a5a146102a85780634c1d6a69146102d057600080fd5b80632828d7e8116101695780632828d7e81461022457806333d7e2bd1461023957806335e80ab31461026657600080fd5b8063028f85f7146101905780630c568498146101c35780630ff754ea146101d8575b600080fd5b34801561019c57600080fd5b506101a5601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101cf57600080fd5b506101a5603f81565b3480156101e457600080fd5b5060fc5473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ba565b34801561023057600080fd5b506101a5604081565b34801561024557600080fd5b5060fd546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561027257600080fd5b5060fb546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b6102a66102a1366004611bdd565b610540565b005b3480156102b457600080fd5b506102bd600181565b60405161ffff90911681526020016101ba565b3480156102dc57600080fd5b506101a5619c4081565b3480156102f257600080fd5b5061032f6040518060400160405280600581526020017f322e342e3000000000000000000000000000000000000000000000000000000081525081565b6040516101ba9190611caf565b34801561034857600080fd5b506101a561138881565b34801561035e57600080fd5b5061036761083d565b60405190151581526020016101ba565b34801561038357600080fd5b5060fc546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103b057600080fd5b506101ff6108d6565b3480156103c557600080fd5b506101a562030d4081565b3480156103dc57600080fd5b5060cf5473ffffffffffffffffffffffffffffffffffffffff166101ff565b34801561040757600080fd5b50610367610416366004611cc9565b60ce6020526000908152604090205460ff1681565b34801561043757600080fd5b50610367610446366004611cc9565b60cb6020526000908152604090205460ff1681565b34801561046757600080fd5b506101a5610476366004611ce2565b6109bd565b34801561048757600080fd5b506102a6610496366004611d36565b610a2b565b6102a66104a9366004611d81565b610ca2565b3480156104ba57600080fd5b5060cf546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104e757600080fd5b5061053260cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b6040519081526020016101ba565b6105486115d3565b156105e05734156105e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f642076616c7565207769746820637573746f6d2067617320746f6b656e00000060648201526084015b60405180910390fd5b60cf546107129073ffffffffffffffffffffffffffffffffffffffff166106088585856109bd565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061067460cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016106909796959493929190611e50565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611612565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561079760cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b866040516107a9959493929190611eaf565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60fb54604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156108ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d19190611efd565b905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016109a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084016105d7565b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f6109d9604063ffffffff8816611f4e565b6109e39190611f7e565b6109ee601088611f4e565b6109fb9062030d40611fcc565b610a059190611fcc565b610a0f9190611fcc565b610a199190611fcc565b610a239190611fcc565b949350505050565b6000547501000000000000000000000000000000000000000000900460ff1615808015610a76575060005460017401000000000000000000000000000000000000000090910460ff16105b80610aa85750303b158015610aa8575060005474010000000000000000000000000000000000000000900460ff166001145b610b34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016105d7565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790558015610bba57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b60fb805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560fc805486841690831617905560fd805492851692909116919091179055610c397342000000000000000000000000000000000000076116ab565b8015610c9c57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b610caa61083d565b15610d11576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f43726f7373446f6d61696e4d657373656e6765723a207061757365640000000060448201526064016105d7565b60f087901c60028110610dcc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016105d7565b8061ffff16600003610ec1576000610e1d878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506117e7915050565b600081815260cb602052604090205490915060ff1615610ebf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016105d7565b505b6000610f07898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061180692505050565b9050610f11611829565b15610f4957853414610f2557610f25611ff8565b600081815260ce602052604090205460ff1615610f4457610f44611ff8565b61109b565b3415610ffd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016105d7565b600081815260ce602052604090205460ff1661109b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016105d7565b6110a487611905565b15611157576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016105d7565b600081815260cb602052604090205460ff16156111f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016105d7565b61121785611208611388619c40611fcc565b67ffffffffffffffff1661194b565b158061123d575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561135657600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161134f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016105d7565b50506115ae565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a1617905560006113e788619c405a6113aa9190612027565b8988888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061196992505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801561149d57600082815260cb602052604090205460ff161561143a5761143a611ff8565b600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26115aa565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016115aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016105d7565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6000806115de611981565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b60fc546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c4290849061167390889083908990600090899060040161203e565b6000604051808303818588803b15801561168c57600080fd5b505af11580156116a0573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611756576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105d7565b60cc5473ffffffffffffffffffffffffffffffffffffffff166117a05760cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b60cf80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006117f585858585611a1e565b805190602001209050949350505050565b6000611816878787878787611ab7565b8051906020012090509695505050505050565b60fc5460009073ffffffffffffffffffffffffffffffffffffffff16331480156108d1575060cf5460fc54604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691639bf62d82916004808201926020929091908290030181865afa1580156118c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e99190612096565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff8216301480611945575060fc5473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000806000835160208501868989f195945050505050565b60fd54604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa1580156119f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1591906120b3565b90939092509050565b606084848484604051602401611a3794939291906120f3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b6060868686868686604051602401611ad49695949392919061213d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611b7857600080fd5b50565b60008083601f840112611b8d57600080fd5b50813567ffffffffffffffff811115611ba557600080fd5b602083019150836020828501011115611bbd57600080fd5b9250929050565b803563ffffffff81168114611bd857600080fd5b919050565b60008060008060608587031215611bf357600080fd5b8435611bfe81611b56565b9350602085013567ffffffffffffffff811115611c1a57600080fd5b611c2687828801611b7b565b9094509250611c39905060408601611bc4565b905092959194509250565b6000815180845260005b81811015611c6a57602081850181015186830182015201611c4e565b81811115611c7c576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611cc26020830184611c44565b9392505050565b600060208284031215611cdb57600080fd5b5035919050565b600080600060408486031215611cf757600080fd5b833567ffffffffffffffff811115611d0e57600080fd5b611d1a86828701611b7b565b9094509250611d2d905060208501611bc4565b90509250925092565b600080600060608486031215611d4b57600080fd5b8335611d5681611b56565b92506020840135611d6681611b56565b91506040840135611d7681611b56565b809150509250925092565b600080600080600080600060c0888a031215611d9c57600080fd5b873596506020880135611dae81611b56565b95506040880135611dbe81611b56565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611de857600080fd5b611df48a828b01611b7b565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611ea260c083018486611e07565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611edf608083018688611e07565b905083604083015263ffffffff831660608301529695505050505050565b600060208284031215611f0f57600080fd5b81518015158114611cc257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611f7557611f75611f1f565b02949350505050565b600067ffffffffffffffff80841680611fc0577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611fef57611fef611f1f565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b60008282101561203957612039611f1f565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a06080820152600061208b60a0830184611c44565b979650505050505050565b6000602082840312156120a857600080fd5b8151611cc281611b56565b600080604083850312156120c657600080fd5b82516120d181611b56565b602084015190925060ff811681146120e857600080fd5b809150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152506080604083015261212c6080830185611c44565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261218860c0830184611c44565b9897505050505050505056fea164736f6c634300080f000a"; + hex"60806040526004361061018b5760003560e01c80636425666b116100d6578063b1b1b2091161007f578063d764ad0b11610059578063d764ad0b1461049b578063db505d80146104ae578063ecc70428146104db57600080fd5b8063b1b1b2091461042b578063b28ade251461045b578063c0c53b8b1461047b57600080fd5b80638cbeeef2116100b05780638cbeeef2146102d05780639fce812c146103d0578063a4e7f8bd146103fb57600080fd5b80636425666b146103775780636e296e45146103a457806383a74074146103b957600080fd5b80633dbb202b1161013857806354fd4d501161011257806354fd4d50146102e65780635644cfdf1461033c5780635c975abb1461035257600080fd5b80633dbb202b146102935780633f827a5a146102a85780634c1d6a69146102d057600080fd5b80632828d7e8116101695780632828d7e81461022457806333d7e2bd1461023957806335e80ab31461026657600080fd5b8063028f85f7146101905780630c568498146101c35780630ff754ea146101d8575b600080fd5b34801561019c57600080fd5b506101a5601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101cf57600080fd5b506101a5603f81565b3480156101e457600080fd5b5060fc5473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ba565b34801561023057600080fd5b506101a5604081565b34801561024557600080fd5b5060fd546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561027257600080fd5b5060fb546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b6102a66102a1366004611bdd565b610540565b005b3480156102b457600080fd5b506102bd600181565b60405161ffff90911681526020016101ba565b3480156102dc57600080fd5b506101a5619c4081565b3480156102f257600080fd5b5061032f6040518060400160405280600c81526020017f322e342e312d626574612e31000000000000000000000000000000000000000081525081565b6040516101ba9190611caf565b34801561034857600080fd5b506101a561138881565b34801561035e57600080fd5b5061036761083d565b60405190151581526020016101ba565b34801561038357600080fd5b5060fc546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103b057600080fd5b506101ff6108d6565b3480156103c557600080fd5b506101a562030d4081565b3480156103dc57600080fd5b5060cf5473ffffffffffffffffffffffffffffffffffffffff166101ff565b34801561040757600080fd5b50610367610416366004611cc9565b60ce6020526000908152604090205460ff1681565b34801561043757600080fd5b50610367610446366004611cc9565b60cb6020526000908152604090205460ff1681565b34801561046757600080fd5b506101a5610476366004611ce2565b6109bd565b34801561048757600080fd5b506102a6610496366004611d36565b610a2b565b6102a66104a9366004611d81565b610ca2565b3480156104ba57600080fd5b5060cf546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104e757600080fd5b5061053260cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b6040519081526020016101ba565b6105486115d3565b156105e05734156105e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f642076616c7565207769746820637573746f6d2067617320746f6b656e00000060648201526084015b60405180910390fd5b60cf546107129073ffffffffffffffffffffffffffffffffffffffff166106088585856109bd565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061067460cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016106909796959493929190611e50565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611612565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561079760cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b866040516107a9959493929190611eaf565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60fb54604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156108ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d19190611efd565b905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016109a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084016105d7565b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f6109d9604063ffffffff8816611f4e565b6109e39190611f7e565b6109ee601088611f4e565b6109fb9062030d40611fcc565b610a059190611fcc565b610a0f9190611fcc565b610a199190611fcc565b610a239190611fcc565b949350505050565b6000547501000000000000000000000000000000000000000000900460ff1615808015610a76575060005460017401000000000000000000000000000000000000000090910460ff16105b80610aa85750303b158015610aa8575060005474010000000000000000000000000000000000000000900460ff166001145b610b34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016105d7565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790558015610bba57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b60fb805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560fc805486841690831617905560fd805492851692909116919091179055610c397342000000000000000000000000000000000000076116ab565b8015610c9c57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b610caa61083d565b15610d11576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f43726f7373446f6d61696e4d657373656e6765723a207061757365640000000060448201526064016105d7565b60f087901c60028110610dcc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016105d7565b8061ffff16600003610ec1576000610e1d878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506117e7915050565b600081815260cb602052604090205490915060ff1615610ebf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016105d7565b505b6000610f07898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061180692505050565b9050610f11611829565b15610f4957853414610f2557610f25611ff8565b600081815260ce602052604090205460ff1615610f4457610f44611ff8565b61109b565b3415610ffd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016105d7565b600081815260ce602052604090205460ff1661109b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016105d7565b6110a487611905565b15611157576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016105d7565b600081815260cb602052604090205460ff16156111f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016105d7565b61121785611208611388619c40611fcc565b67ffffffffffffffff1661194b565b158061123d575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561135657600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161134f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016105d7565b50506115ae565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a1617905560006113e788619c405a6113aa9190612027565b8988888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061196992505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801561149d57600082815260cb602052604090205460ff161561143a5761143a611ff8565b600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26115aa565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016115aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016105d7565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6000806115de611981565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b60fc546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c4290849061167390889083908990600090899060040161203e565b6000604051808303818588803b15801561168c57600080fd5b505af11580156116a0573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611756576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105d7565b60cc5473ffffffffffffffffffffffffffffffffffffffff166117a05760cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b60cf80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006117f585858585611a1e565b805190602001209050949350505050565b6000611816878787878787611ab7565b8051906020012090509695505050505050565b60fc5460009073ffffffffffffffffffffffffffffffffffffffff16331480156108d1575060cf5460fc54604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691639bf62d82916004808201926020929091908290030181865afa1580156118c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e99190612096565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff8216301480611945575060fc5473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000806000835160208501868989f195945050505050565b60fd54604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa1580156119f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1591906120b3565b90939092509050565b606084848484604051602401611a3794939291906120f3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b6060868686868686604051602401611ad49695949392919061213d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611b7857600080fd5b50565b60008083601f840112611b8d57600080fd5b50813567ffffffffffffffff811115611ba557600080fd5b602083019150836020828501011115611bbd57600080fd5b9250929050565b803563ffffffff81168114611bd857600080fd5b919050565b60008060008060608587031215611bf357600080fd5b8435611bfe81611b56565b9350602085013567ffffffffffffffff811115611c1a57600080fd5b611c2687828801611b7b565b9094509250611c39905060408601611bc4565b905092959194509250565b6000815180845260005b81811015611c6a57602081850181015186830182015201611c4e565b81811115611c7c576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611cc26020830184611c44565b9392505050565b600060208284031215611cdb57600080fd5b5035919050565b600080600060408486031215611cf757600080fd5b833567ffffffffffffffff811115611d0e57600080fd5b611d1a86828701611b7b565b9094509250611d2d905060208501611bc4565b90509250925092565b600080600060608486031215611d4b57600080fd5b8335611d5681611b56565b92506020840135611d6681611b56565b91506040840135611d7681611b56565b809150509250925092565b600080600080600080600060c0888a031215611d9c57600080fd5b873596506020880135611dae81611b56565b95506040880135611dbe81611b56565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611de857600080fd5b611df48a828b01611b7b565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611ea260c083018486611e07565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611edf608083018688611e07565b905083604083015263ffffffff831660608301529695505050505050565b600060208284031215611f0f57600080fd5b81518015158114611cc257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611f7557611f75611f1f565b02949350505050565b600067ffffffffffffffff80841680611fc0577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611fef57611fef611f1f565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b60008282101561203957612039611f1f565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a06080820152600061208b60a0830184611c44565b979650505050505050565b6000602082840312156120a857600080fd5b8151611cc281611b56565b600080604083850312156120c657600080fd5b82516120d181611b56565b602084015190925060ff811681146120e857600080fd5b809150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152506080604083015261212c6080830185611c44565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261218860c0830184611c44565b9897505050505050505056fea164736f6c634300080f000a"; bytes internal constant optimismMintableERC20FactoryCode = - hex"60806040523480156200001157600080fd5b5060043610620000935760003560e01c8063c4d66de81162000062578063c4d66de81462000175578063ce5ac90f146200018e578063e78cea9214620001a5578063ee9a31a214620001c657600080fd5b8063316b3739146200009857806354fd4d5014620000fb578063896f93d114620001475780638cf0629c146200015e575b600080fd5b620000d1620000a936600462000652565b60026020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b620001386040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b604051620000f29190620006e5565b620000d162000158366004620007dc565b620001e5565b620000d16200016f36600462000859565b620001fc565b6200018c6200018636600462000652565b6200041b565b005b620000d16200019f366004620007dc565b620005ed565b600154620000d19073ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff16620000d1565b6000620001f4848484620005ed565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff8516620002a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b600085858585604051602001620002c29493929190620008f0565b604051602081830303815290604052805190602001209050600081600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168888888860405162000312906200061a565b620003229594939291906200094a565b8190604051809103906000f590508015801562000343573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff81811660008181526002602052604080822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016948d1694851790555193945090927fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf9190a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054610100900460ff16158080156200043c5750600054600160ff909116105b80620004585750303b15801562000458575060005460ff166001145b620004e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200029e565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156200054557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790558015620005e957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6000620001f48484846012620001fc565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61178a80620009b083390190565b803573ffffffffffffffffffffffffffffffffffffffff811681146200064d57600080fd5b919050565b6000602082840312156200066557600080fd5b620006708262000628565b9392505050565b6000815180845260005b818110156200069f5760208185018101518683018201520162000681565b81811115620006b2576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600062000670602083018462000677565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200073b57600080fd5b813567ffffffffffffffff80821115620007595762000759620006fa565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620007a257620007a2620006fa565b81604052838152866020858801011115620007bc57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215620007f257600080fd5b620007fd8462000628565b9250602084013567ffffffffffffffff808211156200081b57600080fd5b620008298783880162000729565b935060408601359150808211156200084057600080fd5b506200084f8682870162000729565b9150509250925092565b600080600080608085870312156200087057600080fd5b6200087b8562000628565b9350602085013567ffffffffffffffff808211156200089957600080fd5b620008a78883890162000729565b94506040870135915080821115620008be57600080fd5b50620008cd8782880162000729565b925050606085013560ff81168114620008e557600080fd5b939692955090935050565b73ffffffffffffffffffffffffffffffffffffffff8516815260806020820152600062000921608083018662000677565b828103604084015262000935818662000677565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a060408301526200098560a083018662000677565b828103606084015262000999818662000677565b91505060ff83166080830152969550505050505056fe60e06040523480156200001157600080fd5b506040516200178a3803806200178a833981016040819052620000349162000163565b828260036200004483826200029e565b5060046200005382826200029e565b5050506001600160a01b039384166080529390921660a052505060ff1660c0526200036a565b80516001600160a01b03811681146200009157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000be57600080fd5b81516001600160401b0380821115620000db57620000db62000096565b604051601f8301601f19908116603f0116810190828211818310171562000106576200010662000096565b816040528381526020925086838588010111156200012357600080fd5b600091505b8382101562000147578582018301518183018401529082019062000128565b83821115620001595760008385830101525b9695505050505050565b600080600080600060a086880312156200017c57600080fd5b620001878662000079565b9450620001976020870162000079565b60408701519094506001600160401b0380821115620001b557600080fd5b620001c389838a01620000ac565b94506060880151915080821115620001da57600080fd5b50620001e988828901620000ac565b925050608086015160ff811681146200020157600080fd5b809150509295509295909350565b600181811c908216806200022457607f821691505b6020821081036200024557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029957600081815260208120601f850160051c81016020861015620002745750805b601f850160051c820191505b81811015620002955782815560010162000280565b5050505b505050565b81516001600160401b03811115620002ba57620002ba62000096565b620002d281620002cb84546200020f565b846200024b565b602080601f8311600181146200030a5760008415620002f15750858301515b600019600386901b1c1916600185901b17855562000295565b600085815260208120601f198616915b828110156200033b578886015182559484019460019091019084016200031a565b50858210156200035a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c0516113d4620003b6600039600061024401526000818161034b015281816103e001528181610625015261075c0152600081816101a9015261037101526113d46000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610395578063e78cea9214610349578063ee9a31a2146103db57600080fd5b8063ae1f6aaf14610349578063c01e1bd61461036f578063d6c0b2c41461036f57600080fd5b80639dc29fac116100bd5780639dc29fac14610310578063a457c2d714610323578063a9059cbb1461033657600080fd5b806370a08231146102d257806395d89b411461030857600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a36600461117d565b610402565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104f3565b60405161019b91906111c6565b61018f610213366004611262565b610585565b6002545b60405190815260200161019b565b61018f61023836600461128c565b61059d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611262565b6105c1565b61029461028f366004611262565b61060d565b005b6101f86040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61021c6102e03660046112c8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610735565b61029461031e366004611262565b610744565b61018f610331366004611262565b61085b565b61018f610344366004611262565b61092c565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c6103a33660046112e3565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104bb57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104ea57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461050290611316565b80601f016020809104026020016040519081016040528092919081815260200182805461052e90611316565b801561057b5780601f106105505761010080835404028352916020019161057b565b820191906000526020600020905b81548152906001019060200180831161055e57829003601f168201915b5050505050905090565b60003361059381858561093a565b5060019392505050565b6000336105ab858285610aee565b6105b6858585610bc5565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906105939082908690610608908790611398565b61093a565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106e18282610e78565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161072991815260200190565b60405180910390a25050565b60606004805461050290611316565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016106ce565b6108138282610f98565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161072991815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561091f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016106ce565b6105b6828686840361093a565b600033610593818585610bc5565b73ffffffffffffffffffffffffffffffffffffffff83166109dc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bbf5781811015610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106ce565b610bbf848484840361093a565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610d0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e05908490611398565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e6b91815260200190565b60405180910390a3610bbf565b73ffffffffffffffffffffffffffffffffffffffff8216610ef5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106ce565b8060026000828254610f079190611398565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f41908490611398565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff821661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156110f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812083830390556002805484929061112d9084906113b0565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610ae1565b60006020828403121561118f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146111bf57600080fd5b9392505050565b600060208083528351808285015260005b818110156111f3578581018301518582016040015282016111d7565b81811115611205576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461125d57600080fd5b919050565b6000806040838503121561127557600080fd5b61127e83611239565b946020939093013593505050565b6000806000606084860312156112a157600080fd5b6112aa84611239565b92506112b860208501611239565b9150604084013590509250925092565b6000602082840312156112da57600080fd5b6111bf82611239565b600080604083850312156112f657600080fd5b6112ff83611239565b915061130d60208401611239565b90509250929050565b600181811c9082168061132a57607f821691505b602082108103611363577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156113ab576113ab611369565b500190565b6000828210156113c2576113c2611369565b50039056fea164736f6c634300080f000aa164736f6c634300080f000a"; + hex"60806040523480156200001157600080fd5b5060043610620000935760003560e01c8063c4d66de81162000062578063c4d66de81462000175578063ce5ac90f146200018e578063e78cea9214620001a5578063ee9a31a214620001c657600080fd5b8063316b3739146200009857806354fd4d5014620000fb578063896f93d114620001475780638cf0629c146200015e575b600080fd5b620000d1620000a936600462000652565b60026020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b620001386040518060400160405280600d81526020017f312e31302e312d626574612e310000000000000000000000000000000000000081525081565b604051620000f29190620006e5565b620000d162000158366004620007dc565b620001e5565b620000d16200016f36600462000859565b620001fc565b6200018c6200018636600462000652565b6200041b565b005b620000d16200019f366004620007dc565b620005ed565b600154620000d19073ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff16620000d1565b6000620001f4848484620005ed565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff8516620002a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b600085858585604051602001620002c29493929190620008f0565b604051602081830303815290604052805190602001209050600081600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168888888860405162000312906200061a565b620003229594939291906200094a565b8190604051809103906000f590508015801562000343573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff81811660008181526002602052604080822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016948d1694851790555193945090927fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf9190a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054610100900460ff16158080156200043c5750600054600160ff909116105b80620004585750303b15801562000458575060005460ff166001145b620004e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200029e565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156200054557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790558015620005e957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6000620001f48484846012620001fc565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61178a80620009b083390190565b803573ffffffffffffffffffffffffffffffffffffffff811681146200064d57600080fd5b919050565b6000602082840312156200066557600080fd5b620006708262000628565b9392505050565b6000815180845260005b818110156200069f5760208185018101518683018201520162000681565b81811115620006b2576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600062000670602083018462000677565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200073b57600080fd5b813567ffffffffffffffff80821115620007595762000759620006fa565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620007a257620007a2620006fa565b81604052838152866020858801011115620007bc57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215620007f257600080fd5b620007fd8462000628565b9250602084013567ffffffffffffffff808211156200081b57600080fd5b620008298783880162000729565b935060408601359150808211156200084057600080fd5b506200084f8682870162000729565b9150509250925092565b600080600080608085870312156200087057600080fd5b6200087b8562000628565b9350602085013567ffffffffffffffff808211156200089957600080fd5b620008a78883890162000729565b94506040870135915080821115620008be57600080fd5b50620008cd8782880162000729565b925050606085013560ff81168114620008e557600080fd5b939692955090935050565b73ffffffffffffffffffffffffffffffffffffffff8516815260806020820152600062000921608083018662000677565b828103604084015262000935818662000677565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a060408301526200098560a083018662000677565b828103606084015262000999818662000677565b91505060ff83166080830152969550505050505056fe60e06040523480156200001157600080fd5b506040516200178a3803806200178a833981016040819052620000349162000163565b828260036200004483826200029e565b5060046200005382826200029e565b5050506001600160a01b039384166080529390921660a052505060ff1660c0526200036a565b80516001600160a01b03811681146200009157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000be57600080fd5b81516001600160401b0380821115620000db57620000db62000096565b604051601f8301601f19908116603f0116810190828211818310171562000106576200010662000096565b816040528381526020925086838588010111156200012357600080fd5b600091505b8382101562000147578582018301518183018401529082019062000128565b83821115620001595760008385830101525b9695505050505050565b600080600080600060a086880312156200017c57600080fd5b620001878662000079565b9450620001976020870162000079565b60408701519094506001600160401b0380821115620001b557600080fd5b620001c389838a01620000ac565b94506060880151915080821115620001da57600080fd5b50620001e988828901620000ac565b925050608086015160ff811681146200020157600080fd5b809150509295509295909350565b600181811c908216806200022457607f821691505b6020821081036200024557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029957600081815260208120601f850160051c81016020861015620002745750805b601f850160051c820191505b81811015620002955782815560010162000280565b5050505b505050565b81516001600160401b03811115620002ba57620002ba62000096565b620002d281620002cb84546200020f565b846200024b565b602080601f8311600181146200030a5760008415620002f15750858301515b600019600386901b1c1916600185901b17855562000295565b600085815260208120601f198616915b828110156200033b578886015182559484019460019091019084016200031a565b50858210156200035a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c0516113d4620003b6600039600061024401526000818161034b015281816103e001528181610625015261075c0152600081816101a9015261037101526113d46000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610395578063e78cea9214610349578063ee9a31a2146103db57600080fd5b8063ae1f6aaf14610349578063c01e1bd61461036f578063d6c0b2c41461036f57600080fd5b80639dc29fac116100bd5780639dc29fac14610310578063a457c2d714610323578063a9059cbb1461033657600080fd5b806370a08231146102d257806395d89b411461030857600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a36600461117d565b610402565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104f3565b60405161019b91906111c6565b61018f610213366004611262565b610585565b6002545b60405190815260200161019b565b61018f61023836600461128c565b61059d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611262565b6105c1565b61029461028f366004611262565b61060d565b005b6101f86040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61021c6102e03660046112c8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610735565b61029461031e366004611262565b610744565b61018f610331366004611262565b61085b565b61018f610344366004611262565b61092c565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c6103a33660046112e3565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104bb57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104ea57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461050290611316565b80601f016020809104026020016040519081016040528092919081815260200182805461052e90611316565b801561057b5780601f106105505761010080835404028352916020019161057b565b820191906000526020600020905b81548152906001019060200180831161055e57829003601f168201915b5050505050905090565b60003361059381858561093a565b5060019392505050565b6000336105ab858285610aee565b6105b6858585610bc5565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906105939082908690610608908790611398565b61093a565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106e18282610e78565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161072991815260200190565b60405180910390a25050565b60606004805461050290611316565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016106ce565b6108138282610f98565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161072991815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561091f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016106ce565b6105b6828686840361093a565b600033610593818585610bc5565b73ffffffffffffffffffffffffffffffffffffffff83166109dc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bbf5781811015610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106ce565b610bbf848484840361093a565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610d0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e05908490611398565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e6b91815260200190565b60405180910390a3610bbf565b73ffffffffffffffffffffffffffffffffffffffff8216610ef5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106ce565b8060026000828254610f079190611398565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f41908490611398565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff821661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156110f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812083830390556002805484929061112d9084906113b0565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610ae1565b60006020828403121561118f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146111bf57600080fd5b9392505050565b600060208083528351808285015260005b818110156111f3578581018301518582016040015282016111d7565b81811115611205576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461125d57600080fd5b919050565b6000806040838503121561127557600080fd5b61127e83611239565b946020939093013593505050565b6000806000606084860312156112a157600080fd5b6112aa84611239565b92506112b860208501611239565b9150604084013590509250925092565b6000602082840312156112da57600080fd5b6111bf82611239565b600080604083850312156112f657600080fd5b6112ff83611239565b915061130d60208401611239565b90509250929050565b600181811c9082168061132a57607f821691505b602082108103611363577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156113ab576113ab611369565b500190565b6000828210156113c2576113c2611369565b50039056fea164736f6c634300080f000aa164736f6c634300080f000a"; bytes internal constant systemConfigCode = - hex"608060405234801561001057600080fd5b50600436106102de5760003560e01c8063a711986911610186578063e0e2016d116100e3578063f2fde38b11610097578063f8c68de011610071578063f8c68de0146106e2578063fd32aa0f146106ea578063ffa1ad74146106f257600080fd5b8063f2fde38b146106b2578063f45e65d8146106c5578063f68016b7146106ce57600080fd5b8063e81b2c6d116100c8578063e81b2c6d14610681578063ec7075171461068a578063f2b4e617146106aa57600080fd5b8063e0e2016d14610671578063e2a3285c1461067957600080fd5b8063c9b26f611161013a578063d84447151161011f578063d84447151461064e578063dac6e63a14610656578063db9040fa1461065e57600080fd5b8063c9b26f6114610507578063cc731b021461051a57600080fd5b8063bc49ce5f1161016b578063bc49ce5f146104c6578063bfb14fb7146104ce578063c4e8ddfa146104ff57600080fd5b8063a7119869146104ab578063b40a817c146104b357600080fd5b80634397dfef1161023f578063550fcdc9116101f35780638da5cb5b116101cd5780638da5cb5b14610472578063935f029e146104905780639b7d7f0a146104a357600080fd5b8063550fcdc91461045a5780635d73369c14610462578063715018a61461046a57600080fd5b80634add321d116102245780634add321d146103e95780634f16540b146103f157806354fd4d501461041857600080fd5b80634397dfef146103ab57806348cd4cb1146103e157600080fd5b806318d13918116102965780631fd19ee11161027b5780631fd19ee114610378578063213268491461038057806321d7fde51461039857600080fd5b806318d139181461035b57806319f5cea81461037057600080fd5b80630a49cb03116102c75780630a49cb031461032b5780630ae14b1b146103335780630c18c1621461035257600080fd5b806306c92657146102e3578063078f29cf146102fe575b600080fd5b6102eb6106fa565b6040519081526020015b60405180910390f35b610306610728565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102f5565b610306610761565b630bebc2005b60405167ffffffffffffffff90911681526020016102f5565b6102eb60655481565b61036e610369366004612241565b610791565b005b6102eb6107a5565b6103066107d0565b6103886107fa565b60405190151581526020016102f5565b61036e6103a6366004612277565b610839565b6103b361084f565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835260ff9091166020830152016102f5565b6102eb610863565b610339610893565b6102eb7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b60408051808201909152600c81527f322e332e302d626574612e32000000000000000000000000000000000000000060208201525b6040516102f59190612320565b61044d6108b9565b6102eb6108c3565b61036e6108ee565b60335473ffffffffffffffffffffffffffffffffffffffff16610306565b61036e61049e366004612333565b610902565b610306610914565b610306610944565b61036e6104c136600461236d565b610974565b6102eb610985565b6068546104ea9068010000000000000000900463ffffffff1681565b60405163ffffffff90911681526020016102f5565b6103066109b0565b61036e610515366004612388565b6109e0565b6105de6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b6040516102f59190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b61044d6109f1565b6103066109fb565b61036e61066c3660046124bb565b610a2b565b6102eb610e36565b6102eb610e61565b6102eb60675481565b6068546104ea906c01000000000000000000000000900463ffffffff1681565b610306610e8c565b61036e6106c0366004612241565b610ebc565b6102eb60665481565b6068546103399067ffffffffffffffff1681565b6102eb610f70565b6102eb610f9b565b6102eb600081565b61072560017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b81565b600061075c61075860017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b5490565b905090565b600061075c61075860017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b610799611201565b6107a281611282565b50565b61072560017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b600061075c7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b60008061080561084f565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b610841611201565b61084b828261133f565b5050565b60008061085a611184565b90939092509050565b600061075c61075860017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b60695460009061075c9063ffffffff6a0100000000000000000000820481169116612654565b606061075c61147d565b61072560017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b6108f6611201565b610900600061153e565b565b61090a611201565b61084b82826115b5565b600061075c61075860017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b600061075c61075860017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b61097c611201565b6107a28161168b565b61072560017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b600061075c61075860017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b6109e8611201565b6107a2816117e1565b606061075c611809565b600061075c61075860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b600054610100900460ff1615808015610a4b5750600054600160ff909116105b80610a655750303b158015610a65575060005460ff166001145b610af6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610b5457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b5c6118bf565b610b658a610ebc565b610b6e876117e1565b610b78898961133f565b610b818661168b565b610baa7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08869055565b610bdd610bd860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b849055565b610c11610c0b60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b83519055565b610c48610c3f60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b60208401519055565b610c7f610c7660017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b60408401519055565b610cb6610cad60017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b60608401519055565b610ced610ce460017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b60808401519055565b610d24610d1b60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b60a08401519055565b610d2c61195e565b610d398260c001516119c6565b610d4284611cd0565b610d4a610893565b67ffffffffffffffff168667ffffffffffffffff161015610dc7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b8015610e2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b61072560017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b61072560017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b600061075c61075860017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b610ec4611201565b73ffffffffffffffffffffffffffffffffffffffff8116610f67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610aed565b6107a28161153e565b61072560017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b61072560017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b9055565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600060208251111561107a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f476173506179696e67546f6b656e3a20737472696e672063616e6e6f7420626560448201527f2067726561746572207468616e203332206279746573000000000000000000006064820152608401610aed565b6110838261115b565b92915050565b6110ef6110b760017f04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec61263d565b74ff000000000000000000000000000000000000000060a086901b1673ffffffffffffffffffffffffffffffffffffffff8716179055565b61112261111d60017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d61263d565b839055565b61115561115060017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd0576461263d565b829055565b50505050565b8051602181106111735763ec92f9a36000526004601cfd5b9081015160209190910360031b1b90565b600080806111b661075860017f04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec61263d565b73ffffffffffffffffffffffffffffffffffffffff811693509050826111f5575073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee92601292509050565b60a081901c9150509091565b60335473ffffffffffffffffffffffffffffffffffffffff163314610900576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610aed565b6112ab7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060035b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be836040516113339190612320565b60405180910390a35050565b606880547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000063ffffffff8581169182027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16929092176c0100000000000000000000000092851692909202919091179091557f0100000000000000000000000000000000000000000000000000000000000000602083811b67ffffffff000000001690921717606681905560655460408051938401919091528201526000906060015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be836040516114709190612320565b60405180910390a3505050565b60606000611489611184565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff82160161150257505060408051808201909152600381527f4554480000000000000000000000000000000000000000000000000000000000602082015290565b61153861153361075860017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd0576461263d565b612144565b91505090565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b7fff00000000000000000000000000000000000000000000000000000000000000811615611665576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f53797374656d436f6e6669673a207363616c61722065786365656473206d617860448201527f2e000000000000000000000000000000000000000000000000000000000000006064820152608401610aed565b60658290556066819055604080516020810184905290810182905260009060600161140d565b611693610893565b67ffffffffffffffff168167ffffffffffffffff161015611710576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b630bebc20067ffffffffffffffff82161115611788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f20686967686044820152606401610aed565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002611302565b6067819055604080516020808201849052825180830390910181529082019091526000611302565b60606000611815611184565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff82160161188e57505060408051808201909152600581527f4574686572000000000000000000000000000000000000000000000000000000602082015290565b61153861153361075860017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d61263d565b600054610100900460ff16611956576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610aed565b610900612178565b61198c61075860017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b600003610900576109006119c160017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b439055565b73ffffffffffffffffffffffffffffffffffffffff811615801590611a15575073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14155b8015611a265750611a246107fa565b155b156107a257601260ff168173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a9f9190612680565b60ff1614611b2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f53797374656d436f6e6669673a2062616420646563696d616c73206f6620676160448201527f7320706179696e6720746f6b656e0000000000000000000000000000000000006064820152608401610aed565b6000611bca8273ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015611b7f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611bc5919081019061269d565b610fe6565b90506000611c1c8373ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611b7f573d6000803e3d6000fd5b9050611c2b8360128484611089565b611c33610761565b6040517f71cfaa3f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015260126024830152604482018590526064820184905291909116906371cfaa3f90608401600060405180830381600087803b158015611cb357600080fd5b505af1158015611cc7573d6000803e3d6000fd5b50505050505050565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff161115611d80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d6178206261736500000000000000000000006064820152608401610aed565b6001816040015160ff1611611e17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e203100000000000000000000000000000000006064820152608401610aed565b6068546080820151825167ffffffffffffffff90921691611e389190612768565b63ffffffff161115611ea6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b6000816020015160ff1611611f3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f74206265203000000000000000000000000000000000006064820152608401610aed565b8051602082015163ffffffff82169160ff90911690611f5d908290612787565b611f6791906127d1565b63ffffffff1614611ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d69740000000000000000006064820152608401610aed565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b60405160005b82811a1561215a5760010161214a565b80825260208201838152600082820152505060408101604052919050565b600054610100900460ff1661220f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610aed565b6109003361153e565b803573ffffffffffffffffffffffffffffffffffffffff8116811461223c57600080fd5b919050565b60006020828403121561225357600080fd5b61225c82612218565b9392505050565b803563ffffffff8116811461223c57600080fd5b6000806040838503121561228a57600080fd5b61229383612263565b91506122a160208401612263565b90509250929050565b60005b838110156122c55781810151838201526020016122ad565b838111156111555750506000910152565b600081518084526122ee8160208601602086016122aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061225c60208301846122d6565b6000806040838503121561234657600080fd5b50508035926020909101359150565b803567ffffffffffffffff8116811461223c57600080fd5b60006020828403121561237f57600080fd5b61225c82612355565b60006020828403121561239a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff811182821017156123f3576123f36123a1565b60405290565b60ff811681146107a257600080fd5b600060e0828403121561241a57600080fd5b60405160e0810181811067ffffffffffffffff8211171561243d5761243d6123a1565b60405290508061244c83612218565b815261245a60208401612218565b602082015261246b60408401612218565b604082015261247c60608401612218565b606082015261248d60808401612218565b608082015261249e60a08401612218565b60a08201526124af60c08401612218565b60c08201525092915050565b6000806000806000806000806000898b036102808112156124db57600080fd5b6124e48b612218565b99506124f260208c01612263565b985061250060408c01612263565b975060608b0135965061251560808c01612355565b955061252360a08c01612218565b945060c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff408201121561255557600080fd5b5061255e6123d0565b61256a60c08c01612263565b815260e08b013561257a816123f9565b60208201526101008b013561258e816123f9565b60408201526125a06101208c01612263565b60608201526125b26101408c01612263565b60808201526101608b01356fffffffffffffffffffffffffffffffff811681146125db57600080fd5b60a082015292506125ef6101808b01612218565b91506125ff8b6101a08c01612408565b90509295985092959850929598565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561264f5761264f61260e565b500390565b600067ffffffffffffffff8083168185168083038211156126775761267761260e565b01949350505050565b60006020828403121561269257600080fd5b815161225c816123f9565b6000602082840312156126af57600080fd5b815167ffffffffffffffff808211156126c757600080fd5b818401915084601f8301126126db57600080fd5b8151818111156126ed576126ed6123a1565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612733576127336123a1565b8160405282815287602084870101111561274c57600080fd5b61275d8360208301602088016122aa565b979650505050505050565b600063ffffffff8083168185168083038211156126775761267761260e565b600063ffffffff808416806127c5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff808316818516818304811182151516156127f4576127f461260e565b0294935050505056fea164736f6c634300080f000a"; + hex"608060405234801561001057600080fd5b50600436106102de5760003560e01c8063a711986911610186578063e0e2016d116100e3578063f2fde38b11610097578063f8c68de011610071578063f8c68de0146106e2578063fd32aa0f146106ea578063ffa1ad74146106f257600080fd5b8063f2fde38b146106b2578063f45e65d8146106c5578063f68016b7146106ce57600080fd5b8063e81b2c6d116100c8578063e81b2c6d14610681578063ec7075171461068a578063f2b4e617146106aa57600080fd5b8063e0e2016d14610671578063e2a3285c1461067957600080fd5b8063c9b26f611161013a578063d84447151161011f578063d84447151461064e578063dac6e63a14610656578063db9040fa1461065e57600080fd5b8063c9b26f6114610507578063cc731b021461051a57600080fd5b8063bc49ce5f1161016b578063bc49ce5f146104c6578063bfb14fb7146104ce578063c4e8ddfa146104ff57600080fd5b8063a7119869146104ab578063b40a817c146104b357600080fd5b80634397dfef1161023f578063550fcdc9116101f35780638da5cb5b116101cd5780638da5cb5b14610472578063935f029e146104905780639b7d7f0a146104a357600080fd5b8063550fcdc91461045a5780635d73369c14610462578063715018a61461046a57600080fd5b80634add321d116102245780634add321d146103e95780634f16540b146103f157806354fd4d501461041857600080fd5b80634397dfef146103ab57806348cd4cb1146103e157600080fd5b806318d13918116102965780631fd19ee11161027b5780631fd19ee114610378578063213268491461038057806321d7fde51461039857600080fd5b806318d139181461035b57806319f5cea81461037057600080fd5b80630a49cb03116102c75780630a49cb031461032b5780630ae14b1b146103335780630c18c1621461035257600080fd5b806306c92657146102e3578063078f29cf146102fe575b600080fd5b6102eb6106fa565b6040519081526020015b60405180910390f35b610306610728565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102f5565b610306610761565b630bebc2005b60405167ffffffffffffffff90911681526020016102f5565b6102eb60655481565b61036e610369366004612241565b610791565b005b6102eb6107a5565b6103066107d0565b6103886107fa565b60405190151581526020016102f5565b61036e6103a6366004612277565b610839565b6103b361084f565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835260ff9091166020830152016102f5565b6102eb610863565b610339610893565b6102eb7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b60408051808201909152600c81527f322e332e302d626574612e33000000000000000000000000000000000000000060208201525b6040516102f59190612320565b61044d6108b9565b6102eb6108c3565b61036e6108ee565b60335473ffffffffffffffffffffffffffffffffffffffff16610306565b61036e61049e366004612333565b610902565b610306610914565b610306610944565b61036e6104c136600461236d565b610974565b6102eb610985565b6068546104ea9068010000000000000000900463ffffffff1681565b60405163ffffffff90911681526020016102f5565b6103066109b0565b61036e610515366004612388565b6109e0565b6105de6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b6040516102f59190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b61044d6109f1565b6103066109fb565b61036e61066c3660046124bb565b610a2b565b6102eb610e36565b6102eb610e61565b6102eb60675481565b6068546104ea906c01000000000000000000000000900463ffffffff1681565b610306610e8c565b61036e6106c0366004612241565b610ebc565b6102eb60665481565b6068546103399067ffffffffffffffff1681565b6102eb610f70565b6102eb610f9b565b6102eb600081565b61072560017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b81565b600061075c61075860017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b5490565b905090565b600061075c61075860017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b610799611201565b6107a281611282565b50565b61072560017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b600061075c7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b60008061080561084f565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b610841611201565b61084b828261133f565b5050565b60008061085a611184565b90939092509050565b600061075c61075860017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b60695460009061075c9063ffffffff6a0100000000000000000000820481169116612654565b606061075c61147d565b61072560017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b6108f6611201565b610900600061153e565b565b61090a611201565b61084b82826115b5565b600061075c61075860017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b600061075c61075860017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b61097c611201565b6107a28161168b565b61072560017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b600061075c61075860017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b6109e8611201565b6107a2816117e1565b606061075c611809565b600061075c61075860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b600054610100900460ff1615808015610a4b5750600054600160ff909116105b80610a655750303b158015610a65575060005460ff166001145b610af6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610b5457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b5c6118bf565b610b658a610ebc565b610b6e876117e1565b610b78898961133f565b610b818661168b565b610baa7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08869055565b610bdd610bd860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b849055565b610c11610c0b60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b83519055565b610c48610c3f60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b60208401519055565b610c7f610c7660017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b60408401519055565b610cb6610cad60017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b60608401519055565b610ced610ce460017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b60808401519055565b610d24610d1b60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b60a08401519055565b610d2c61195e565b610d398260c001516119c6565b610d4284611cd0565b610d4a610893565b67ffffffffffffffff168667ffffffffffffffff161015610dc7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b8015610e2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b61072560017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b61072560017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b600061075c61075860017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b610ec4611201565b73ffffffffffffffffffffffffffffffffffffffff8116610f67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610aed565b6107a28161153e565b61072560017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b61072560017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b9055565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600060208251111561107a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f476173506179696e67546f6b656e3a20737472696e672063616e6e6f7420626560448201527f2067726561746572207468616e203332206279746573000000000000000000006064820152608401610aed565b6110838261115b565b92915050565b6110ef6110b760017f04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec61263d565b74ff000000000000000000000000000000000000000060a086901b1673ffffffffffffffffffffffffffffffffffffffff8716179055565b61112261111d60017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d61263d565b839055565b61115561115060017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd0576461263d565b829055565b50505050565b8051602181106111735763ec92f9a36000526004601cfd5b9081015160209190910360031b1b90565b600080806111b661075860017f04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec61263d565b73ffffffffffffffffffffffffffffffffffffffff811693509050826111f5575073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee92601292509050565b60a081901c9150509091565b60335473ffffffffffffffffffffffffffffffffffffffff163314610900576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610aed565b6112ab7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060035b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be836040516113339190612320565b60405180910390a35050565b606880547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000063ffffffff8581169182027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16929092176c0100000000000000000000000092851692909202919091179091557f0100000000000000000000000000000000000000000000000000000000000000602083811b67ffffffff000000001690921717606681905560655460408051938401919091528201526000906060015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be836040516114709190612320565b60405180910390a3505050565b60606000611489611184565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff82160161150257505060408051808201909152600381527f4554480000000000000000000000000000000000000000000000000000000000602082015290565b61153861153361075860017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd0576461263d565b612144565b91505090565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b7fff00000000000000000000000000000000000000000000000000000000000000811615611665576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f53797374656d436f6e6669673a207363616c61722065786365656473206d617860448201527f2e000000000000000000000000000000000000000000000000000000000000006064820152608401610aed565b60658290556066819055604080516020810184905290810182905260009060600161140d565b611693610893565b67ffffffffffffffff168167ffffffffffffffff161015611710576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b630bebc20067ffffffffffffffff82161115611788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f20686967686044820152606401610aed565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002611302565b6067819055604080516020808201849052825180830390910181529082019091526000611302565b60606000611815611184565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff82160161188e57505060408051808201909152600581527f4574686572000000000000000000000000000000000000000000000000000000602082015290565b61153861153361075860017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d61263d565b600054610100900460ff16611956576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610aed565b610900612178565b61198c61075860017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b600003610900576109006119c160017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b439055565b73ffffffffffffffffffffffffffffffffffffffff811615801590611a15575073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14155b8015611a265750611a246107fa565b155b156107a257601260ff168173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a9f9190612680565b60ff1614611b2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f53797374656d436f6e6669673a2062616420646563696d616c73206f6620676160448201527f7320706179696e6720746f6b656e0000000000000000000000000000000000006064820152608401610aed565b6000611bca8273ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015611b7f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611bc5919081019061269d565b610fe6565b90506000611c1c8373ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611b7f573d6000803e3d6000fd5b9050611c2b8360128484611089565b611c33610761565b6040517f71cfaa3f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015260126024830152604482018590526064820184905291909116906371cfaa3f90608401600060405180830381600087803b158015611cb357600080fd5b505af1158015611cc7573d6000803e3d6000fd5b50505050505050565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff161115611d80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d6178206261736500000000000000000000006064820152608401610aed565b6001816040015160ff1611611e17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e203100000000000000000000000000000000006064820152608401610aed565b6068546080820151825167ffffffffffffffff90921691611e389190612768565b63ffffffff161115611ea6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b6000816020015160ff1611611f3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f74206265203000000000000000000000000000000000006064820152608401610aed565b8051602082015163ffffffff82169160ff90911690611f5d908290612787565b611f6791906127d1565b63ffffffff1614611ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d69740000000000000000006064820152608401610aed565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b60405160005b82811a1561215a5760010161214a565b80825260208201838152600082820152505060408101604052919050565b600054610100900460ff1661220f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610aed565b6109003361153e565b803573ffffffffffffffffffffffffffffffffffffffff8116811461223c57600080fd5b919050565b60006020828403121561225357600080fd5b61225c82612218565b9392505050565b803563ffffffff8116811461223c57600080fd5b6000806040838503121561228a57600080fd5b61229383612263565b91506122a160208401612263565b90509250929050565b60005b838110156122c55781810151838201526020016122ad565b838111156111555750506000910152565b600081518084526122ee8160208601602086016122aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061225c60208301846122d6565b6000806040838503121561234657600080fd5b50508035926020909101359150565b803567ffffffffffffffff8116811461223c57600080fd5b60006020828403121561237f57600080fd5b61225c82612355565b60006020828403121561239a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff811182821017156123f3576123f36123a1565b60405290565b60ff811681146107a257600080fd5b600060e0828403121561241a57600080fd5b60405160e0810181811067ffffffffffffffff8211171561243d5761243d6123a1565b60405290508061244c83612218565b815261245a60208401612218565b602082015261246b60408401612218565b604082015261247c60608401612218565b606082015261248d60808401612218565b608082015261249e60a08401612218565b60a08201526124af60c08401612218565b60c08201525092915050565b6000806000806000806000806000898b036102808112156124db57600080fd5b6124e48b612218565b99506124f260208c01612263565b985061250060408c01612263565b975060608b0135965061251560808c01612355565b955061252360a08c01612218565b945060c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff408201121561255557600080fd5b5061255e6123d0565b61256a60c08c01612263565b815260e08b013561257a816123f9565b60208201526101008b013561258e816123f9565b60408201526125a06101208c01612263565b60608201526125b26101408c01612263565b60808201526101608b01356fffffffffffffffffffffffffffffffff811681146125db57600080fd5b60a082015292506125ef6101808b01612218565b91506125ff8b6101a08c01612408565b90509295985092959850929598565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561264f5761264f61260e565b500390565b600067ffffffffffffffff8083168185168083038211156126775761267761260e565b01949350505050565b60006020828403121561269257600080fd5b815161225c816123f9565b6000602082840312156126af57600080fd5b815167ffffffffffffffff808211156126c757600080fd5b818401915084601f8301126126db57600080fd5b8151818111156126ed576126ed6123a1565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612733576127336123a1565b8160405282815287602084870101111561274c57600080fd5b61275d8360208301602088016122aa565b979650505050505050565b600063ffffffff8083168185168083038211156126775761267761260e565b600063ffffffff808416806127c5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff808316818516818304811182151516156127f4576127f461260e565b0294935050505056fea164736f6c634300080f000a"; bytes internal constant l1StandardBridgeCode = - hex"6080604052600436106101845760003560e01c80637f46ddb2116100d65780639a2ac6d51161007f578063c0c53b8b11610059578063c0c53b8b14610529578063c89701a214610549578063e11013dd1461057657600080fd5b80639a2ac6d5146104e3578063a9f9e675146104f6578063b1a1a8821461051657600080fd5b80638f601f66116100b05780638f601f661461047257806391c49bf814610407578063927ede2d146104b857600080fd5b80637f46ddb214610407578063838b252014610432578063870876231461045257600080fd5b806335e80ab31161013857806354fd4d501161011257806354fd4d501461036c57806358a997f6146103c25780635c975abb146103e257600080fd5b806335e80ab3146102f25780633cb747bf1461031f578063540abf731461034c57600080fd5b80631532ec34116101695780631532ec34146102755780631635f5fd1461028857806333d7e2bd1461029b57600080fd5b80630166a07a1461024257806309fc88431461026257600080fd5b3661023d57333b1561021d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b61023b333362030d40604051806020016040528060008152506105a5565b005b600080fd5b34801561024e57600080fd5b5061023b61025d366004612991565b6105b8565b61023b610270366004612a42565b6109d2565b61023b610283366004612a95565b610aa9565b61023b610296366004612a95565b610abd565b3480156102a757600080fd5b506033546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102fe57600080fd5b506032546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b34801561032b57600080fd5b506003546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b34801561035857600080fd5b5061023b610367366004612b08565b61101b565b34801561037857600080fd5b506103b56040518060400160405280600581526020017f322e322e3000000000000000000000000000000000000000000000000000000081525081565b6040516102e99190612bf5565b3480156103ce57600080fd5b5061023b6103dd366004612c08565b611060565b3480156103ee57600080fd5b506103f7611134565b60405190151581526020016102e9565b34801561041357600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff166102c8565b34801561043e57600080fd5b5061023b61044d366004612b08565b6111cd565b34801561045e57600080fd5b5061023b61046d366004612c08565b611212565b34801561047e57600080fd5b506104aa61048d366004612c8b565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102e9565b3480156104c457600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166102c8565b61023b6104f1366004612cc4565b6112e6565b34801561050257600080fd5b5061023b610511366004612991565b611328565b61023b610524366004612a42565b611337565b34801561053557600080fd5b5061023b610544366004612d27565b611408565b34801561055557600080fd5b506004546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b61023b610584366004612cc4565b611607565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6105b2848434858561164a565b50505050565b60035473ffffffffffffffffffffffffffffffffffffffff163314801561068b575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa15801561064f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106739190612d72565b73ffffffffffffffffffffffffffffffffffffffff16145b61073d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610214565b610745611134565b156107ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610214565b6107b5876118a9565b15610903576107c4878761190b565b610876576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610214565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156108e657600080fd5b505af11580156108fa573d6000803e3d6000fd5b50505050610985565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054610941908490612dbe565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c1683529390529190912091909155610985908585611a2b565b6109c9878787878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611aff92505050565b50505050505050565b333b15610a61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b610aa43333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061164a92505050565b505050565b610ab68585858585610abd565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610b90575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa158015610b54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b789190612d72565b73ffffffffffffffffffffffffffffffffffffffff16145b610c42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610214565b610c4a611134565b15610cb1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610214565b610cb9611b8d565b15610d46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2063616e6e6f742062726964676520455460448201527f48207769746820637573746f6d2067617320746f6b656e0000000000000000006064820152608401610214565b823414610dd5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e742072657175697265640000000000006064820152608401610214565b3073ffffffffffffffffffffffffffffffffffffffff851603610e7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c6600000000000000000000000000000000000000000000000000000000006064820152608401610214565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610f25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e6765720000000000000000000000000000000000000000000000006064820152608401610214565b610f6785858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bcc92505050565b6000610f84855a8660405180602001604052806000815250611c3f565b905080611013576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c656400000000000000000000000000000000000000000000000000000000006064820152608401610214565b505050505050565b6109c987873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c5792505050565b333b156110ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b61101386863333888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061201092505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156111a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c89190612dd5565b905090565b6109c987873388888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061201092505050565b333b156112a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b61101386863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c5792505050565b6105b233858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506105a592505050565b6109c9878787878787876105b8565b333b156113c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b610aa433338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506105a592505050565b600054610100900460ff16158080156114285750600054600160ff909116105b806114425750303b158015611442575060005460ff166001145b6114ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610214565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561152c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6032805473ffffffffffffffffffffffffffffffffffffffff8086167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255603380549285169290911691909117905561159f8473420000000000000000000000000000000000001061201f565b80156105b257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b6105b23385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061164a92505050565b611652611b8d565b156116df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2063616e6e6f742062726964676520455460448201527f48207769746820637573746f6d2067617320746f6b656e0000000000000000006064820152608401610214565b82341461176e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c756500006064820152608401610214565b61177a85858584612109565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9287929116907f1635f5fd00000000000000000000000000000000000000000000000000000000906117dd908b908b9086908a90602401612df7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b909216825261187092918890600401612e40565b6000604051808303818588803b15801561188957600080fd5b505af115801561189d573d6000803e3d6000fd5b50505050505050505050565b60006118d5827f1d1d8b630000000000000000000000000000000000000000000000000000000061217c565b806119055750611905827fec4fc8e30000000000000000000000000000000000000000000000000000000061217c565b92915050565b6000611937837f1d1d8b630000000000000000000000000000000000000000000000000000000061217c565b156119e0578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611987573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ab9190612d72565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611905565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611987573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610aa49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261219f565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b3868686604051611b7793929190612e85565b60405180910390a46110138686868686866122ab565b600080611b98612333565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e6318484604051611c2b929190612ec3565b60405180910390a36105b2848484846123d0565b6000806000835160208501868989f195945050505050565b3415611ce5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f5374616e646172644272696467653a2063616e6e6f742073656e642076616c7560448201527f65000000000000000000000000000000000000000000000000000000000000006064820152608401610214565b611cee876118a9565b15611e3c57611cfd878761190b565b611daf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610214565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b158015611e1f57600080fd5b505af1158015611e33573d6000803e3d6000fd5b50505050611ed0565b611e5e73ffffffffffffffffffffffffffffffffffffffff881686308661243d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054611e9c908490612edc565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611ede87878787878661249b565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9216907f0166a07a0000000000000000000000000000000000000000000000000000000090611f42908b908d908c908c908c908b90602401612ef4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611fd592918790600401612e40565b600060405180830381600087803b158015611fef57600080fd5b505af1158015612003573d6000803e3d6000fd5b5050505050505050505050565b6109c987878787878787611c57565b600054610100900460ff166120b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610214565b6003805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560048054929093169116179055565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051612168929190612ec3565b60405180910390a36105b284848484612529565b600061218783612588565b8015612198575061219883836125ec565b9392505050565b6000612201826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166126bb9092919063ffffffff16565b805190915015610aa4578080602001905181019061221f9190612dd5565b610aa4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610214565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd86868660405161232393929190612e85565b60405180910390a4505050505050565b603354604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa1580156123a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c79190612f4f565b90939092509050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d848460405161242f929190612ec3565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526105b29085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611a7d565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039686868660405161251393929190612e85565b60405180910390a46110138686868686866126d2565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5848460405161242f929190612ec3565b60006125b4827f01ffc9a7000000000000000000000000000000000000000000000000000000006125ec565b801561190557506125e5827fffffffff000000000000000000000000000000000000000000000000000000006125ec565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156126a4575060208210155b80156126b05750600081115b979650505050505050565b60606126ca848460008561274a565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf86868660405161232393929190612e85565b6060824710156127dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610214565b73ffffffffffffffffffffffffffffffffffffffff85163b61285a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610214565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516128839190612f84565b60006040518083038185875af1925050503d80600081146128c0576040519150601f19603f3d011682016040523d82523d6000602084013e6128c5565b606091505b50915091506126b0828286606083156128df575081612198565b8251156128ef5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102149190612bf5565b73ffffffffffffffffffffffffffffffffffffffff8116811461294557600080fd5b50565b60008083601f84011261295a57600080fd5b50813567ffffffffffffffff81111561297257600080fd5b60208301915083602082850101111561298a57600080fd5b9250929050565b600080600080600080600060c0888a0312156129ac57600080fd5b87356129b781612923565b965060208801356129c781612923565b955060408801356129d781612923565b945060608801356129e781612923565b93506080880135925060a088013567ffffffffffffffff811115612a0a57600080fd5b612a168a828b01612948565b989b979a50959850939692959293505050565b803563ffffffff81168114612a3d57600080fd5b919050565b600080600060408486031215612a5757600080fd5b612a6084612a29565b9250602084013567ffffffffffffffff811115612a7c57600080fd5b612a8886828701612948565b9497909650939450505050565b600080600080600060808688031215612aad57600080fd5b8535612ab881612923565b94506020860135612ac881612923565b935060408601359250606086013567ffffffffffffffff811115612aeb57600080fd5b612af788828901612948565b969995985093965092949392505050565b600080600080600080600060c0888a031215612b2357600080fd5b8735612b2e81612923565b96506020880135612b3e81612923565b95506040880135612b4e81612923565b945060608801359350612b6360808901612a29565b925060a088013567ffffffffffffffff811115612a0a57600080fd5b60005b83811015612b9a578181015183820152602001612b82565b838111156105b25750506000910152565b60008151808452612bc3816020860160208601612b7f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006121986020830184612bab565b60008060008060008060a08789031215612c2157600080fd5b8635612c2c81612923565b95506020870135612c3c81612923565b945060408701359350612c5160608801612a29565b9250608087013567ffffffffffffffff811115612c6d57600080fd5b612c7989828a01612948565b979a9699509497509295939492505050565b60008060408385031215612c9e57600080fd5b8235612ca981612923565b91506020830135612cb981612923565b809150509250929050565b60008060008060608587031215612cda57600080fd5b8435612ce581612923565b9350612cf360208601612a29565b9250604085013567ffffffffffffffff811115612d0f57600080fd5b612d1b87828801612948565b95989497509550505050565b600080600060608486031215612d3c57600080fd5b8335612d4781612923565b92506020840135612d5781612923565b91506040840135612d6781612923565b809150509250925092565b600060208284031215612d8457600080fd5b815161219881612923565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612dd057612dd0612d8f565b500390565b600060208284031215612de757600080fd5b8151801515811461219857600080fd5b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152612e366080830184612bab565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84168152606060208201526000612e6f6060830185612bab565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000612eba6060830184612bab565b95945050505050565b8281526040602082015260006126ca6040830184612bab565b60008219821115612eef57612eef612d8f565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a0830152612f4360c0830184612bab565b98975050505050505050565b60008060408385031215612f6257600080fd5b8251612f6d81612923565b602084015190925060ff81168114612cb957600080fd5b60008251612f96818460208701612b7f565b919091019291505056fea164736f6c634300080f000a"; + hex"6080604052600436106101845760003560e01c80637f46ddb2116100d65780639a2ac6d51161007f578063c0c53b8b11610059578063c0c53b8b14610529578063c89701a214610549578063e11013dd1461057657600080fd5b80639a2ac6d5146104e3578063a9f9e675146104f6578063b1a1a8821461051657600080fd5b80638f601f66116100b05780638f601f661461047257806391c49bf814610407578063927ede2d146104b857600080fd5b80637f46ddb214610407578063838b252014610432578063870876231461045257600080fd5b806335e80ab31161013857806354fd4d501161011257806354fd4d501461036c57806358a997f6146103c25780635c975abb146103e257600080fd5b806335e80ab3146102f25780633cb747bf1461031f578063540abf731461034c57600080fd5b80631532ec34116101695780631532ec34146102755780631635f5fd1461028857806333d7e2bd1461029b57600080fd5b80630166a07a1461024257806309fc88431461026257600080fd5b3661023d57333b1561021d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b61023b333362030d40604051806020016040528060008152506105a5565b005b600080fd5b34801561024e57600080fd5b5061023b61025d366004612991565b6105b8565b61023b610270366004612a42565b6109d2565b61023b610283366004612a95565b610aa9565b61023b610296366004612a95565b610abd565b3480156102a757600080fd5b506033546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102fe57600080fd5b506032546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b34801561032b57600080fd5b506003546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b34801561035857600080fd5b5061023b610367366004612b08565b61101b565b34801561037857600080fd5b506103b56040518060400160405280600c81526020017f322e322e312d626574612e31000000000000000000000000000000000000000081525081565b6040516102e99190612bf5565b3480156103ce57600080fd5b5061023b6103dd366004612c08565b611060565b3480156103ee57600080fd5b506103f7611134565b60405190151581526020016102e9565b34801561041357600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff166102c8565b34801561043e57600080fd5b5061023b61044d366004612b08565b6111cd565b34801561045e57600080fd5b5061023b61046d366004612c08565b611212565b34801561047e57600080fd5b506104aa61048d366004612c8b565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102e9565b3480156104c457600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166102c8565b61023b6104f1366004612cc4565b6112e6565b34801561050257600080fd5b5061023b610511366004612991565b611328565b61023b610524366004612a42565b611337565b34801561053557600080fd5b5061023b610544366004612d27565b611408565b34801561055557600080fd5b506004546102c89073ffffffffffffffffffffffffffffffffffffffff1681565b61023b610584366004612cc4565b611607565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6105b2848434858561164a565b50505050565b60035473ffffffffffffffffffffffffffffffffffffffff163314801561068b575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa15801561064f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106739190612d72565b73ffffffffffffffffffffffffffffffffffffffff16145b61073d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610214565b610745611134565b156107ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610214565b6107b5876118a9565b15610903576107c4878761190b565b610876576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610214565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156108e657600080fd5b505af11580156108fa573d6000803e3d6000fd5b50505050610985565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054610941908490612dbe565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c1683529390529190912091909155610985908585611a2b565b6109c9878787878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611aff92505050565b50505050505050565b333b15610a61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b610aa43333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061164a92505050565b505050565b610ab68585858585610abd565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610b90575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa158015610b54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b789190612d72565b73ffffffffffffffffffffffffffffffffffffffff16145b610c42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610214565b610c4a611134565b15610cb1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610214565b610cb9611b8d565b15610d46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2063616e6e6f742062726964676520455460448201527f48207769746820637573746f6d2067617320746f6b656e0000000000000000006064820152608401610214565b823414610dd5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e742072657175697265640000000000006064820152608401610214565b3073ffffffffffffffffffffffffffffffffffffffff851603610e7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c6600000000000000000000000000000000000000000000000000000000006064820152608401610214565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610f25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e6765720000000000000000000000000000000000000000000000006064820152608401610214565b610f6785858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bcc92505050565b6000610f84855a8660405180602001604052806000815250611c3f565b905080611013576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c656400000000000000000000000000000000000000000000000000000000006064820152608401610214565b505050505050565b6109c987873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c5792505050565b333b156110ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b61101386863333888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061201092505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156111a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c89190612dd5565b905090565b6109c987873388888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061201092505050565b333b156112a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b61101386863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c5792505050565b6105b233858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506105a592505050565b6109c9878787878787876105b8565b333b156113c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610214565b610aa433338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506105a592505050565b600054610100900460ff16158080156114285750600054600160ff909116105b806114425750303b158015611442575060005460ff166001145b6114ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610214565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561152c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6032805473ffffffffffffffffffffffffffffffffffffffff8086167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255603380549285169290911691909117905561159f8473420000000000000000000000000000000000001061201f565b80156105b257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b6105b23385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061164a92505050565b611652611b8d565b156116df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2063616e6e6f742062726964676520455460448201527f48207769746820637573746f6d2067617320746f6b656e0000000000000000006064820152608401610214565b82341461176e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c756500006064820152608401610214565b61177a85858584612109565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9287929116907f1635f5fd00000000000000000000000000000000000000000000000000000000906117dd908b908b9086908a90602401612df7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b909216825261187092918890600401612e40565b6000604051808303818588803b15801561188957600080fd5b505af115801561189d573d6000803e3d6000fd5b50505050505050505050565b60006118d5827f1d1d8b630000000000000000000000000000000000000000000000000000000061217c565b806119055750611905827fec4fc8e30000000000000000000000000000000000000000000000000000000061217c565b92915050565b6000611937837f1d1d8b630000000000000000000000000000000000000000000000000000000061217c565b156119e0578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611987573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ab9190612d72565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611905565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611987573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610aa49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261219f565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b3868686604051611b7793929190612e85565b60405180910390a46110138686868686866122ab565b600080611b98612333565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e6318484604051611c2b929190612ec3565b60405180910390a36105b2848484846123d0565b6000806000835160208501868989f195945050505050565b3415611ce5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f5374616e646172644272696467653a2063616e6e6f742073656e642076616c7560448201527f65000000000000000000000000000000000000000000000000000000000000006064820152608401610214565b611cee876118a9565b15611e3c57611cfd878761190b565b611daf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610214565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b158015611e1f57600080fd5b505af1158015611e33573d6000803e3d6000fd5b50505050611ed0565b611e5e73ffffffffffffffffffffffffffffffffffffffff881686308661243d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054611e9c908490612edc565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611ede87878787878661249b565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9216907f0166a07a0000000000000000000000000000000000000000000000000000000090611f42908b908d908c908c908c908b90602401612ef4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611fd592918790600401612e40565b600060405180830381600087803b158015611fef57600080fd5b505af1158015612003573d6000803e3d6000fd5b5050505050505050505050565b6109c987878787878787611c57565b600054610100900460ff166120b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610214565b6003805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560048054929093169116179055565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051612168929190612ec3565b60405180910390a36105b284848484612529565b600061218783612588565b8015612198575061219883836125ec565b9392505050565b6000612201826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166126bb9092919063ffffffff16565b805190915015610aa4578080602001905181019061221f9190612dd5565b610aa4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610214565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd86868660405161232393929190612e85565b60405180910390a4505050505050565b603354604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa1580156123a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c79190612f4f565b90939092509050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d848460405161242f929190612ec3565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526105b29085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611a7d565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039686868660405161251393929190612e85565b60405180910390a46110138686868686866126d2565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5848460405161242f929190612ec3565b60006125b4827f01ffc9a7000000000000000000000000000000000000000000000000000000006125ec565b801561190557506125e5827fffffffff000000000000000000000000000000000000000000000000000000006125ec565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156126a4575060208210155b80156126b05750600081115b979650505050505050565b60606126ca848460008561274a565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf86868660405161232393929190612e85565b6060824710156127dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610214565b73ffffffffffffffffffffffffffffffffffffffff85163b61285a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610214565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516128839190612f84565b60006040518083038185875af1925050503d80600081146128c0576040519150601f19603f3d011682016040523d82523d6000602084013e6128c5565b606091505b50915091506126b0828286606083156128df575081612198565b8251156128ef5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102149190612bf5565b73ffffffffffffffffffffffffffffffffffffffff8116811461294557600080fd5b50565b60008083601f84011261295a57600080fd5b50813567ffffffffffffffff81111561297257600080fd5b60208301915083602082850101111561298a57600080fd5b9250929050565b600080600080600080600060c0888a0312156129ac57600080fd5b87356129b781612923565b965060208801356129c781612923565b955060408801356129d781612923565b945060608801356129e781612923565b93506080880135925060a088013567ffffffffffffffff811115612a0a57600080fd5b612a168a828b01612948565b989b979a50959850939692959293505050565b803563ffffffff81168114612a3d57600080fd5b919050565b600080600060408486031215612a5757600080fd5b612a6084612a29565b9250602084013567ffffffffffffffff811115612a7c57600080fd5b612a8886828701612948565b9497909650939450505050565b600080600080600060808688031215612aad57600080fd5b8535612ab881612923565b94506020860135612ac881612923565b935060408601359250606086013567ffffffffffffffff811115612aeb57600080fd5b612af788828901612948565b969995985093965092949392505050565b600080600080600080600060c0888a031215612b2357600080fd5b8735612b2e81612923565b96506020880135612b3e81612923565b95506040880135612b4e81612923565b945060608801359350612b6360808901612a29565b925060a088013567ffffffffffffffff811115612a0a57600080fd5b60005b83811015612b9a578181015183820152602001612b82565b838111156105b25750506000910152565b60008151808452612bc3816020860160208601612b7f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006121986020830184612bab565b60008060008060008060a08789031215612c2157600080fd5b8635612c2c81612923565b95506020870135612c3c81612923565b945060408701359350612c5160608801612a29565b9250608087013567ffffffffffffffff811115612c6d57600080fd5b612c7989828a01612948565b979a9699509497509295939492505050565b60008060408385031215612c9e57600080fd5b8235612ca981612923565b91506020830135612cb981612923565b809150509250929050565b60008060008060608587031215612cda57600080fd5b8435612ce581612923565b9350612cf360208601612a29565b9250604085013567ffffffffffffffff811115612d0f57600080fd5b612d1b87828801612948565b95989497509550505050565b600080600060608486031215612d3c57600080fd5b8335612d4781612923565b92506020840135612d5781612923565b91506040840135612d6781612923565b809150509250925092565b600060208284031215612d8457600080fd5b815161219881612923565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612dd057612dd0612d8f565b500390565b600060208284031215612de757600080fd5b8151801515811461219857600080fd5b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152612e366080830184612bab565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84168152606060208201526000612e6f6060830185612bab565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000612eba6060830184612bab565b95945050505050565b8281526040602082015260006126ca6040830184612bab565b60008219821115612eef57612eef612d8f565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a0830152612f4360c0830184612bab565b98975050505050505050565b60008060408385031215612f6257600080fd5b8251612f6d81612923565b602084015190925060ff81168114612cb957600080fd5b60008251612f96818460208701612b7f565b919091019291505056fea164736f6c634300080f000a"; bytes internal constant l1ERC721BridgeCode = - hex"608060405234801561001057600080fd5b50600436106100d45760003560e01c80635d93a3fc11610081578063927ede2d1161005b578063927ede2d14610231578063aa5574521461024f578063c89701a21461026257600080fd5b80635d93a3fc146101cc578063761f4493146102005780637f46ddb21461021357600080fd5b8063485cc955116100b2578063485cc9551461015857806354fd4d501461016b5780635c975abb146101b457600080fd5b806335e80ab3146100d95780633687011a146101235780633cb747bf14610138575b600080fd5b6032546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610136610131366004610fe1565b610282565b005b6001546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b610136610166366004611064565b61032e565b6101a76040518060400160405280600c81526020017f322e312e312b626574612e31000000000000000000000000000000000000000081525081565b60405161011a9190611108565b6101bc610518565b604051901515815260200161011a565b6101bc6101da366004611122565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b61013661020e366004611163565b6105b1565b60025473ffffffffffffffffffffffffffffffffffffffff166100f9565b60015473ffffffffffffffffffffffffffffffffffffffff166100f9565b61013661025d3660046111fb565b610a58565b6002546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b333b15610316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b6103268686333388888888610b30565b505050505050565b600054610100900460ff161580801561034e5750600054600160ff909116105b806103685750303b158015610368575060005460ff166001145b6103f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161030d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561045257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556104b083734200000000000000000000000000000000000014610e70565b801561051357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa158015610588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ac9190611272565b905090565b60015473ffffffffffffffffffffffffffffffffffffffff16331480156106865750600254600154604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691636e296e45916004808201926020929091908290030181865afa15801561064a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066e9190611294565b73ffffffffffffffffffffffffffffffffffffffff16145b610712576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f746865722062726964676500606482015260840161030d565b61071a610518565b15610781576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4c314552433732314272696467653a2070617573656400000000000000000000604482015260640161030d565b3073ffffffffffffffffffffffffffffffffffffffff881603610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c6600000000000000000000000000000000000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff1615156001146108f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c312042726964676500000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156109b557600080fd5b505af11580156109c9573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac87878787604051610a4794939291906112fa565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610afb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f74206265206164647265737328302900000000000000000000000000000000606482015260840161030d565b610b0b8787338888888888610b30565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b73ffffffffffffffffffffffffffffffffffffffff8716610bd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f742062652061646472657373283029000000000000000000000000000000606482015260840161030d565b600063761f449360e01b888a8989898888604051602401610bfa979695949392919061133a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610d3a57600080fd5b505af1158015610d4e573d6000803e3d6000fd5b50506001546002546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450633dbb202b9350610db1929091169085908990600401611397565b600060405180830381600087803b158015610dcb57600080fd5b505af1158015610ddf573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610e5d94939291906112fa565b60405180910390a4505050505050505050565b600054610100900460ff16610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161030d565b6001805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560028054929093169116179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610f7c57600080fd5b50565b803563ffffffff81168114610f9357600080fd5b919050565b60008083601f840112610faa57600080fd5b50813567ffffffffffffffff811115610fc257600080fd5b602083019150836020828501011115610fda57600080fd5b9250929050565b60008060008060008060a08789031215610ffa57600080fd5b863561100581610f5a565b9550602087013561101581610f5a565b94506040870135935061102a60608801610f7f565b9250608087013567ffffffffffffffff81111561104657600080fd5b61105289828a01610f98565b979a9699509497509295939492505050565b6000806040838503121561107757600080fd5b823561108281610f5a565b9150602083013561109281610f5a565b809150509250929050565b6000815180845260005b818110156110c3576020818501810151868301820152016110a7565b818111156110d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061111b602083018461109d565b9392505050565b60008060006060848603121561113757600080fd5b833561114281610f5a565b9250602084013561115281610f5a565b929592945050506040919091013590565b600080600080600080600060c0888a03121561117e57600080fd5b873561118981610f5a565b9650602088013561119981610f5a565b955060408801356111a981610f5a565b945060608801356111b981610f5a565b93506080880135925060a088013567ffffffffffffffff8111156111dc57600080fd5b6111e88a828b01610f98565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561121657600080fd5b873561122181610f5a565b9650602088013561123181610f5a565b9550604088013561124181610f5a565b94506060880135935061125660808901610f7f565b925060a088013567ffffffffffffffff8111156111dc57600080fd5b60006020828403121561128457600080fd5b8151801515811461111b57600080fd5b6000602082840312156112a657600080fd5b815161111b81610f5a565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006113306060830184866112b1565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261138a60c0830184866112b1565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006113c6606083018561109d565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a"; + hex"608060405234801561001057600080fd5b50600436106100d45760003560e01c80635d93a3fc11610081578063927ede2d1161005b578063927ede2d14610231578063aa5574521461024f578063c89701a21461026257600080fd5b80635d93a3fc146101cc578063761f4493146102005780637f46ddb21461021357600080fd5b8063485cc955116100b2578063485cc9551461015857806354fd4d501461016b5780635c975abb146101b457600080fd5b806335e80ab3146100d95780633687011a146101235780633cb747bf14610138575b600080fd5b6032546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610136610131366004610fe1565b610282565b005b6001546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b610136610166366004611064565b61032e565b6101a76040518060400160405280600c81526020017f322e312e312d626574612e32000000000000000000000000000000000000000081525081565b60405161011a9190611108565b6101bc610518565b604051901515815260200161011a565b6101bc6101da366004611122565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b61013661020e366004611163565b6105b1565b60025473ffffffffffffffffffffffffffffffffffffffff166100f9565b60015473ffffffffffffffffffffffffffffffffffffffff166100f9565b61013661025d3660046111fb565b610a58565b6002546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b333b15610316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b6103268686333388888888610b30565b505050505050565b600054610100900460ff161580801561034e5750600054600160ff909116105b806103685750303b158015610368575060005460ff166001145b6103f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161030d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561045257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556104b083734200000000000000000000000000000000000014610e70565b801561051357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa158015610588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ac9190611272565b905090565b60015473ffffffffffffffffffffffffffffffffffffffff16331480156106865750600254600154604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691636e296e45916004808201926020929091908290030181865afa15801561064a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066e9190611294565b73ffffffffffffffffffffffffffffffffffffffff16145b610712576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f746865722062726964676500606482015260840161030d565b61071a610518565b15610781576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4c314552433732314272696467653a2070617573656400000000000000000000604482015260640161030d565b3073ffffffffffffffffffffffffffffffffffffffff881603610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c6600000000000000000000000000000000000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff1615156001146108f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c312042726964676500000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156109b557600080fd5b505af11580156109c9573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac87878787604051610a4794939291906112fa565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610afb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f74206265206164647265737328302900000000000000000000000000000000606482015260840161030d565b610b0b8787338888888888610b30565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b73ffffffffffffffffffffffffffffffffffffffff8716610bd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f742062652061646472657373283029000000000000000000000000000000606482015260840161030d565b600063761f449360e01b888a8989898888604051602401610bfa979695949392919061133a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610d3a57600080fd5b505af1158015610d4e573d6000803e3d6000fd5b50506001546002546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450633dbb202b9350610db1929091169085908990600401611397565b600060405180830381600087803b158015610dcb57600080fd5b505af1158015610ddf573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610e5d94939291906112fa565b60405180910390a4505050505050505050565b600054610100900460ff16610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161030d565b6001805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560028054929093169116179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610f7c57600080fd5b50565b803563ffffffff81168114610f9357600080fd5b919050565b60008083601f840112610faa57600080fd5b50813567ffffffffffffffff811115610fc257600080fd5b602083019150836020828501011115610fda57600080fd5b9250929050565b60008060008060008060a08789031215610ffa57600080fd5b863561100581610f5a565b9550602087013561101581610f5a565b94506040870135935061102a60608801610f7f565b9250608087013567ffffffffffffffff81111561104657600080fd5b61105289828a01610f98565b979a9699509497509295939492505050565b6000806040838503121561107757600080fd5b823561108281610f5a565b9150602083013561109281610f5a565b809150509250929050565b6000815180845260005b818110156110c3576020818501810151868301820152016110a7565b818111156110d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061111b602083018461109d565b9392505050565b60008060006060848603121561113757600080fd5b833561114281610f5a565b9250602084013561115281610f5a565b929592945050506040919091013590565b600080600080600080600060c0888a03121561117e57600080fd5b873561118981610f5a565b9650602088013561119981610f5a565b955060408801356111a981610f5a565b945060608801356111b981610f5a565b93506080880135925060a088013567ffffffffffffffff8111156111dc57600080fd5b6111e88a828b01610f98565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561121657600080fd5b873561122181610f5a565b9650602088013561123181610f5a565b9550604088013561124181610f5a565b94506060880135935061125660808901610f7f565b925060a088013567ffffffffffffffff8111156111dc57600080fd5b60006020828403121561128457600080fd5b8151801515811461111b57600080fd5b6000602082840312156112a657600080fd5b815161111b81610f5a565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006113306060830184866112b1565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261138a60c0830184866112b1565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006113c6606083018561109d565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a"; bytes internal constant optimismPortalCode = - hex"6080604052600436106101635760003560e01c80638c3152e9116100c0578063b69ef8a811610074578063cff0ab9611610059578063cff0ab9614610444578063e965084c146104e5578063e9e05c421461057157600080fd5b8063b69ef8a814610401578063c0c53b8b1461042457600080fd5b80639bf62d82116100a55780639bf62d821461036b578063a14238e714610398578063a35d99df146103c857600080fd5b80638c3152e91461031e5780639b5f694a1461033e57600080fd5b806354fd4d50116101175780636dbffb78116100fc5780636dbffb78146102de57806371cfaa3f146102fe5780638b4c40b01461018857600080fd5b806354fd4d501461026d5780635c975abb146102b957600080fd5b806335e80ab31161014857806335e80ab314610206578063452a9320146102385780634870496f1461024d57600080fd5b8063149f2f221461018f57806333d7e2bd146101af57600080fd5b3661018a576101883334620186a060006040518060200160405280600081525061057f565b005b600080fd5b34801561019b57600080fd5b506101886101aa366004614b97565b610624565b3480156101bb57600080fd5b506037546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561021257600080fd5b506035546101dc90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561024457600080fd5b506101dc610865565b34801561025957600080fd5b50610188610268366004614ccb565b6108fd565b34801561027957600080fd5b50604080518082018252600c81527f322e382e312d626574612e310000000000000000000000000000000000000000602082015290516101fd9190614e1d565b3480156102c557600080fd5b506102ce610eaa565b60405190151581526020016101fd565b3480156102ea57600080fd5b506102ce6102f9366004614e30565b610f3d565b34801561030a57600080fd5b50610188610319366004614e58565b610ff8565b34801561032a57600080fd5b50610188610339366004614e9e565b6111ba565b34801561034a57600080fd5b506036546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561037757600080fd5b506032546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103a457600080fd5b506102ce6103b3366004614e30565b60336020526000908152604090205460ff1681565b3480156103d457600080fd5b506103e86103e3366004614edb565b611c3c565b60405167ffffffffffffffff90911681526020016101fd565b34801561040d57600080fd5b50610416611c55565b6040519081526020016101fd565b34801561043057600080fd5b5061018861043f366004614ef6565b611caf565b34801561045057600080fd5b506001546104ac906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101fd565b3480156104f157600080fd5b50610543610500366004614e30565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101fd565b61018861057f366004614f41565b8260005a9050600061058f611f19565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906105cb57503415155b15610602576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610610883489898989611fb6565b5061061b8282612162565b50505050505050565b8260005a90506000610634611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016106a6576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546106b89190614fed565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561072a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074e9190615005565b905061077273ffffffffffffffffffffffffffffffffffffffff831633308c61242f565b61077c8982614fed565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa1580156107e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080a9190615005565b14610841576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61084f8a8a8a8a8a8a611fb6565b505061085b8282612162565b5050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f8919061501e565b905090565b610905610eaa565b1561093c576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16036109a5576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6036546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810186905260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610a15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a39919061505b565b519050610a53610a4e368690038601866150c0565b61250b565b8114610ae6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f66000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000610af187612567565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610c075750805160365460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610bdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c03919061505b565b5114155b610c93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610add565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610d5c9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610d52888a615126565b8a60400135612597565b610de8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610add565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f19573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906151aa565b6036546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101839052600091610ff29173ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd7919061505b565b602001516fffffffffffffffffffffffffffffffff166125bb565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff163314611049576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61105562030d40612661565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f000000000000000000000000000000000000000000000000000000001790529051611172969594939291016151c7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526111aa91614e1d565b60405180910390a450505050565b565b6111c2610eaa565b156111f9576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461124c576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061125782612567565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610add565b603660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d39190615005565b81602001516fffffffffffffffffffffffffffffffff16101561149e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610add565b6114bd81602001516fffffffffffffffffffffffffffffffff166125bb565b61156f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610add565b60365460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a919061505b565b82518151919250146116d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610add565b6116f381602001516fffffffffffffffffffffffffffffffff166125bb565b6117a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610add565b60008381526033602052604090205460ff1615611844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610add565b6000838152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558501516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055806118cf611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016119325761192b8660400151876080015188606001518960a001516126c3565b9150611b85565b8073ffffffffffffffffffffffffffffffffffffffff16866040015173ffffffffffffffffffffffffffffffffffffffff160361199b576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606086015115611b5c578560600151603d60008282546119bb919061522c565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015611a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a519190615005565b9050611a86876040015188606001518473ffffffffffffffffffffffffffffffffffffffff166127219092919063ffffffff16565b6060870151611a95908261522c565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015611aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b239190615005565b14611b5a576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08601515115611b805761192b8660400151876080015160008960a001516126c3565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405185907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90611be790851515815260200190565b60405180910390a281158015611bfd5750326001145b15611c34576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b6000611c49826010615243565b610ff290615208615273565b600080611c60611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601611ca7574791505090565b5050603d5490565b600054610100900460ff1615808015611ccf5750600054600160ff909116105b80611ce95750303b158015611ce9575060005460ff166001145b611d75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610add565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611dd357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603680547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8781169190911790925560378054909116858316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101008584160217905560325416611e8c57603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b611e9461277c565b8015611ef757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015611f89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fad919061529f565b90939092509050565b818015611fd8575073ffffffffffffffffffffffffffffffffffffffff861615155b1561200f576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120198151611c3c565b67ffffffffffffffff168367ffffffffffffffff161015612066576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c0815111156120a4576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333281146120c5575033731111000000000000000000000000000000001111015b600086868686866040516020016120e09594939291906151c7565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516121509190614e1d565b60405180910390a45050505050505050565b600154600090612198907801000000000000000000000000000000000000000000000000900467ffffffffffffffff164361522c565b905060006121a461288f565b90506000816020015160ff16826000015163ffffffff166121c59190615308565b905082156122fc576001546000906121fc908390700100000000000000000000000000000000900467ffffffffffffffff16615370565b90506000836040015160ff168361221391906153e4565b6001546122339084906fffffffffffffffffffffffffffffffff166153e4565b61223d9190615308565b60015490915060009061228e906122679084906fffffffffffffffffffffffffffffffff166154a0565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612950565b905060018611156122bd576122ba61226782876040015160ff1660018a6122b5919061522c565b61296f565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b6001805486919060109061232f908490700100000000000000000000000000000000900467ffffffffffffffff16615273565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1613156123bc576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906123e8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615514565b905060006123fa48633b9aca006129c4565b6124049083615551565b905060005a612413908861522c565b90508082111561085b5761085b61242a828461522c565b6129db565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052611ef79085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612a04565b6000816000015182602001518360400151846060015160405160200161254a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a0880151935160009761254a979096959101615565565b6000806125a386612b10565b90506125b181868686612b42565b9695505050505050565b603654604080517ff4daa291000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163f4daa2919160048083019260209291908290030181865afa15801561262b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264f9190615005565b6126599083614fed565b421192915050565b6001805463ffffffff8316919060109061269a908490700100000000000000000000000000000000900467ffffffffffffffff16615273565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b60008060006126d3866000612b72565b905080612709576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526127779084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612489565b505050565b600054610100900460ff16612813576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610add565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff166000036111b85760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa15801561292c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906155d0565b600061296561295f8585612b90565b83612ba0565b90505b9392505050565b6000670de0b6b3a76400006129b06129878583615308565b61299990670de0b6b3a7640000615370565b6129ab85670de0b6b3a76400006153e4565b612baf565b6129ba90866153e4565b6129659190615308565b6000818310156129d45781612968565b5090919050565b6000805a90505b825a6129ee908361522c565b1015612777576129fd82615673565b91506129e2565b6000612a66826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612be09092919063ffffffff16565b8051909150156127775780806020019051810190612a8491906151aa565b612777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610add565b60608180519060200120604051602001612b2c91815260200190565b6040516020818303038152906040529050919050565b6000612b6984612b53878686612bef565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000818312156129d45781612968565b60008183126129d45781612968565b6000612968670de0b6b3a764000083612bc78661366d565b612bd191906153e4565b612bdb9190615308565b6138b1565b60606129658484600085613af0565b60606000845111612c5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610add565b6000612c6784613c86565b90506000612c7486613d72565b9050600084604051602001612c8b91815260200190565b60405160208183030381529060405290506000805b84518110156135e4576000858281518110612cbd57612cbd6156ab565b602002602001015190508451831115612d58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610add565b82600003612e115780518051602091820120604051612da692612d8092910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610add565b612f68565b805151602011612ec75780518051602091820120604051612e3b92612d8092910190815260200190565b612e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610add565b805184516020808701919091208251919092012014612f68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610add565b612f7460106001614fed565b8160200151510361315057845183036130e857612fae8160200151601081518110612fa157612fa16156ab565b6020026020010151613dd5565b96506000875111613041576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610add565b6001865161304f919061522c565b82146130dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610add565b505050505050612968565b60008584815181106130fc576130fc6156ab565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110613127576131276156ab565b6020026020010151905061313a81613e89565b9550613147600186614fed565b945050506135d1565b60028160200151510361354957600061316882613eae565b905060008160008151811061317f5761317f6156ab565b016020015160f81c905060006131966002836156da565b6131a19060026156fc565b905060006131b2848360ff16613ed2565b905060006131c08a89613ed2565b905060006131ce8383613f08565b905080835114613260576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610add565b60ff851660021480613275575060ff85166003145b15613464578082511461330a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610add565b6133248760200151600181518110612fa157612fa16156ab565b9c5060008d51116133b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610add565b60018c516133c5919061522c565b8814613453576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610add565b505050505050505050505050612968565b60ff85161580613477575060ff85166001145b156134b6576134a38760200151600181518110613496576134966156ab565b6020026020010151613e89565b99506134af818a614fed565b985061353e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610add565b5050505050506135d1565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610add565b50806135dc81615673565b915050612ca0565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610add565b60008082136136d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b600060606136e584613fbc565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136138e257506000919050565b680755bf798b4a1bf1e58212613954576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610add565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613b82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610add565b73ffffffffffffffffffffffffffffffffffffffff85163b613c00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610add565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613c29919061571f565b60006040518083038185875af1925050503d8060008114613c66576040519150601f19603f3d011682016040523d82523d6000602084013e613c6b565b606091505b5091509150613c7b828286614092565b979650505050505050565b80516060908067ffffffffffffffff811115613ca457613ca4614a8b565b604051908082528060200260200182016040528015613ce957816020015b6040805180820190915260608082526020820152815260200190600190039081613cc25790505b50915060005b81811015613d6b576040518060400160405280858381518110613d1457613d146156ab565b60200260200101518152602001613d43868481518110613d3657613d366156ab565b60200260200101516140e5565b815250838281518110613d5857613d586156ab565b6020908102919091010152600101613cef565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015613dca578060011b82018184015160001a8060041c8253600f811660018301535050600101613d9c565b509295945050505050565b60606000806000613de5856140f8565b919450925090506000816001811115613e0057613e0061573b565b14613e37576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613e418284614fed565b855114613e7a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b6985602001518484614596565b60606020826000015110613ea557613ea082613dd5565b610ff2565b610ff28261462a565b6060610ff2613ecd8360200151600081518110612fa157612fa16156ab565b613d72565b606082518210613ef15750604080516020810190915260008152610ff2565b6129688383848651613f03919061522c565b614640565b6000808251845110613f1b578251613f1e565b83515b90505b8082108015613fa55750828281518110613f3d57613f3d6156ab565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613f7c57613f7c6156ab565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15613fb557816001019150613f21565b5092915050565b6000808211614027576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606083156140a1575081612968565b8251156140b15782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610add9190614e1d565b6060610ff26140f383614818565b614885565b6000806000836000015160000361413b576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f811161416057600060016000945094509450505061458f565b60b7811161427657600061417560808361522c565b9050808760000151116141b4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214801561422c57507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614263576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061458f915050565b60bf81116143d457600061428b60b78361522c565b9050808760000151116142ca576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361432c576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614374576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61437e8184614fed565b8951116143b7576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6143c2836001614fed565b975095506000945061458f9350505050565b60f781116144395760006143e960c08361522c565b905080876000015111614428576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061458f915050565b600061444660f78361522c565b905080876000015111614485576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036144e7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c6037811161452f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6145398184614fed565b895111614572576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61457d836001614fed565b975095506001945061458f9350505050565b9193909250565b60608167ffffffffffffffff8111156145b1576145b1614a8b565b6040519080825280601f01601f1916602001820160405280156145db576020820181803683370190505b50905081156129685760006145f08486614fed565b90506020820160005b848110156146115782810151828201526020016145f9565b84811115614620576000858301525b5050509392505050565b6060610ff2826020015160008460000151614596565b60608182601f0110156146af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b82828401101561471b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b81830184511015614788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610add565b6060821580156147a7576040519150600082526020820160405261480f565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156147e05780518352602092830192016147c8565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201528151600003614867576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000614895856140f8565b9194509250905060018160018111156148b0576148b061573b565b146148e7576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516148f38385614fed565b1461492a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816149415790505093506000835b8651811015614a2f576000806149b46040518060400160405280858c60000151614998919061522c565b8152602001858c602001516149ad9190614fed565b90526140f8565b5091509150604051806040016040528083836149d09190614fed565b8152602001848b602001516149e59190614fed565b8152508885815181106149fa576149fa6156ab565b6020908102919091010152614a10600185614fed565b9350614a1c8183614fed565b614a269084614fed565b9250505061496e565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114614a5d57600080fd5b50565b803567ffffffffffffffff81168114614a7857600080fd5b919050565b8015158114614a5d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614b0157614b01614a8b565b604052919050565b600082601f830112614b1a57600080fd5b813567ffffffffffffffff811115614b3457614b34614a8b565b614b6560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614aba565b818152846020838601011115614b7a57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614bb057600080fd5b8635614bbb81614a3b565b95506020870135945060408701359350614bd760608801614a60565b92506080870135614be781614a7d565b915060a087013567ffffffffffffffff811115614c0357600080fd5b614c0f89828a01614b09565b9150509295509295509295565b600060c08284031215614c2e57600080fd5b60405160c0810167ffffffffffffffff8282108183111715614c5257614c52614a8b565b816040528293508435835260208501359150614c6d82614a3b565b81602084015260408501359150614c8382614a3b565b816040840152606085013560608401526080850135608084015260a0850135915080821115614cb157600080fd5b50614cbe85828601614b09565b60a0830152505092915050565b600080600080600085870360e0811215614ce457600080fd5b863567ffffffffffffffff80821115614cfc57600080fd5b614d088a838b01614c1c565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614d4157600080fd5b60408901955060c0890135925080831115614d5b57600080fd5b828901925089601f840112614d6f57600080fd5b8235915080821115614d8057600080fd5b508860208260051b8401011115614d9657600080fd5b959894975092955050506020019190565b60005b83811015614dc2578181015183820152602001614daa565b83811115611ef75750506000910152565b60008151808452614deb816020860160208601614da7565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006129686020830184614dd3565b600060208284031215614e4257600080fd5b5035919050565b60ff81168114614a5d57600080fd5b60008060008060808587031215614e6e57600080fd5b8435614e7981614a3b565b93506020850135614e8981614e49565b93969395505050506040820135916060013590565b600060208284031215614eb057600080fd5b813567ffffffffffffffff811115614ec757600080fd5b614ed384828501614c1c565b949350505050565b600060208284031215614eed57600080fd5b61296882614a60565b600080600060608486031215614f0b57600080fd5b8335614f1681614a3b565b92506020840135614f2681614a3b565b91506040840135614f3681614a3b565b809150509250925092565b600080600080600060a08688031215614f5957600080fd5b8535614f6481614a3b565b945060208601359350614f7960408701614a60565b92506060860135614f8981614a7d565b9150608086013567ffffffffffffffff811115614fa557600080fd5b614fb188828901614b09565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561500057615000614fbe565b500190565b60006020828403121561501757600080fd5b5051919050565b60006020828403121561503057600080fd5b815161296881614a3b565b80516fffffffffffffffffffffffffffffffff81168114614a7857600080fd5b60006060828403121561506d57600080fd5b6040516060810181811067ffffffffffffffff8211171561509057615090614a8b565b604052825181526150a36020840161503b565b60208201526150b46040840161503b565b60408201529392505050565b6000608082840312156150d257600080fd5b6040516080810181811067ffffffffffffffff821117156150f5576150f5614a8b565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff8084111561514157615141614a8b565b8360051b6020615152818301614aba565b86815291850191818101903684111561516a57600080fd5b865b8481101561519e578035868111156151845760008081fd5b61519036828b01614b09565b84525091830191830161516c565b50979650505050505050565b6000602082840312156151bc57600080fd5b815161296881614a7d565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b60488201526000825161521b816049850160208701614da7565b919091016049019695505050505050565b60008282101561523e5761523e614fbe565b500390565b600067ffffffffffffffff8083168185168183048111821515161561526a5761526a614fbe565b02949350505050565b600067ffffffffffffffff80831681851680830382111561529657615296614fbe565b01949350505050565b600080604083850312156152b257600080fd5b82516152bd81614a3b565b60208401519092506152ce81614e49565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615317576153176152d9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561536b5761536b614fbe565b500590565b6000808312837f8000000000000000000000000000000000000000000000000000000000000000018312811516156153aa576153aa614fbe565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156153de576153de614fbe565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561542557615425614fbe565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561546057615460614fbe565b6000871292508782058712848416161561547c5761547c614fbe565b8785058712818416161561549257615492614fbe565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156154da576154da614fbe565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561550e5761550e614fbe565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561554c5761554c614fbe565b500290565b600082615560576155606152d9565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526155b060c0830184614dd3565b98975050505050505050565b805163ffffffff81168114614a7857600080fd5b600060c082840312156155e257600080fd5b60405160c0810181811067ffffffffffffffff8211171561560557615605614a8b565b604052615611836155bc565b8152602083015161562181614e49565b6020820152604083015161563481614e49565b6040820152615645606084016155bc565b6060820152615656608084016155bc565b608082015261566760a0840161503b565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036156a4576156a4614fbe565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806156ed576156ed6152d9565b8060ff84160691505092915050565b600060ff821660ff84168082101561571657615716614fbe565b90039392505050565b60008251615731818460208701614da7565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a"; + hex"6080604052600436106101635760003560e01c80638c3152e9116100c0578063b69ef8a811610074578063cff0ab9611610059578063cff0ab9614610444578063e965084c146104e5578063e9e05c421461057157600080fd5b8063b69ef8a814610401578063c0c53b8b1461042457600080fd5b80639bf62d82116100a55780639bf62d821461036b578063a14238e714610398578063a35d99df146103c857600080fd5b80638c3152e91461031e5780639b5f694a1461033e57600080fd5b806354fd4d50116101175780636dbffb78116100fc5780636dbffb78146102de57806371cfaa3f146102fe5780638b4c40b01461018857600080fd5b806354fd4d501461026d5780635c975abb146102b957600080fd5b806335e80ab31161014857806335e80ab314610206578063452a9320146102385780634870496f1461024d57600080fd5b8063149f2f221461018f57806333d7e2bd146101af57600080fd5b3661018a576101883334620186a060006040518060200160405280600081525061057f565b005b600080fd5b34801561019b57600080fd5b506101886101aa366004614b97565b610624565b3480156101bb57600080fd5b506037546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561021257600080fd5b506035546101dc90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561024457600080fd5b506101dc610865565b34801561025957600080fd5b50610188610268366004614ccb565b6108fd565b34801561027957600080fd5b50604080518082018252600c81527f322e382e312d626574612e320000000000000000000000000000000000000000602082015290516101fd9190614e1d565b3480156102c557600080fd5b506102ce610eaa565b60405190151581526020016101fd565b3480156102ea57600080fd5b506102ce6102f9366004614e30565b610f3d565b34801561030a57600080fd5b50610188610319366004614e58565b610ff8565b34801561032a57600080fd5b50610188610339366004614e9e565b6111ba565b34801561034a57600080fd5b506036546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561037757600080fd5b506032546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103a457600080fd5b506102ce6103b3366004614e30565b60336020526000908152604090205460ff1681565b3480156103d457600080fd5b506103e86103e3366004614edb565b611c3c565b60405167ffffffffffffffff90911681526020016101fd565b34801561040d57600080fd5b50610416611c55565b6040519081526020016101fd565b34801561043057600080fd5b5061018861043f366004614ef6565b611caf565b34801561045057600080fd5b506001546104ac906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101fd565b3480156104f157600080fd5b50610543610500366004614e30565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101fd565b61018861057f366004614f41565b8260005a9050600061058f611f19565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906105cb57503415155b15610602576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610610883489898989611fb6565b5061061b8282612162565b50505050505050565b8260005a90506000610634611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016106a6576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546106b89190614fed565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561072a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074e9190615005565b905061077273ffffffffffffffffffffffffffffffffffffffff831633308c61242f565b61077c8982614fed565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa1580156107e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080a9190615005565b14610841576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61084f8a8a8a8a8a8a611fb6565b505061085b8282612162565b5050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f8919061501e565b905090565b610905610eaa565b1561093c576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16036109a5576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6036546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810186905260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610a15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a39919061505b565b519050610a53610a4e368690038601866150c0565b61250b565b8114610ae6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f66000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000610af187612567565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610c075750805160365460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610bdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c03919061505b565b5114155b610c93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610add565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610d5c9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610d52888a615126565b8a60400135612597565b610de8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610add565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f19573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906151aa565b6036546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101839052600091610ff29173ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd7919061505b565b602001516fffffffffffffffffffffffffffffffff166125bb565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff163314611049576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61105562030d40612661565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f000000000000000000000000000000000000000000000000000000001790529051611172969594939291016151c7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526111aa91614e1d565b60405180910390a450505050565b565b6111c2610eaa565b156111f9576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461124c576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061125782612567565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610add565b603660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d39190615005565b81602001516fffffffffffffffffffffffffffffffff16101561149e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610add565b6114bd81602001516fffffffffffffffffffffffffffffffff166125bb565b61156f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610add565b60365460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a919061505b565b82518151919250146116d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610add565b6116f381602001516fffffffffffffffffffffffffffffffff166125bb565b6117a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610add565b60008381526033602052604090205460ff1615611844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610add565b6000838152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558501516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055806118cf611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016119325761192b8660400151876080015188606001518960a001516126c3565b9150611b85565b8073ffffffffffffffffffffffffffffffffffffffff16866040015173ffffffffffffffffffffffffffffffffffffffff160361199b576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606086015115611b5c578560600151603d60008282546119bb919061522c565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015611a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a519190615005565b9050611a86876040015188606001518473ffffffffffffffffffffffffffffffffffffffff166127219092919063ffffffff16565b6060870151611a95908261522c565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015611aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b239190615005565b14611b5a576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08601515115611b805761192b8660400151876080015160008960a001516126c3565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405185907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90611be790851515815260200190565b60405180910390a281158015611bfd5750326001145b15611c34576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b6000611c49826010615243565b610ff290615208615273565b600080611c60611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601611ca7574791505090565b5050603d5490565b600054610100900460ff1615808015611ccf5750600054600160ff909116105b80611ce95750303b158015611ce9575060005460ff166001145b611d75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610add565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611dd357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603680547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8781169190911790925560378054909116858316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101008584160217905560325416611e8c57603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b611e9461277c565b8015611ef757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015611f89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fad919061529f565b90939092509050565b818015611fd8575073ffffffffffffffffffffffffffffffffffffffff861615155b1561200f576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120198151611c3c565b67ffffffffffffffff168367ffffffffffffffff161015612066576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c0815111156120a4576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333281146120c5575033731111000000000000000000000000000000001111015b600086868686866040516020016120e09594939291906151c7565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516121509190614e1d565b60405180910390a45050505050505050565b600154600090612198907801000000000000000000000000000000000000000000000000900467ffffffffffffffff164361522c565b905060006121a461288f565b90506000816020015160ff16826000015163ffffffff166121c59190615308565b905082156122fc576001546000906121fc908390700100000000000000000000000000000000900467ffffffffffffffff16615370565b90506000836040015160ff168361221391906153e4565b6001546122339084906fffffffffffffffffffffffffffffffff166153e4565b61223d9190615308565b60015490915060009061228e906122679084906fffffffffffffffffffffffffffffffff166154a0565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612950565b905060018611156122bd576122ba61226782876040015160ff1660018a6122b5919061522c565b61296f565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b6001805486919060109061232f908490700100000000000000000000000000000000900467ffffffffffffffff16615273565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1613156123bc576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906123e8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615514565b905060006123fa48633b9aca006129c4565b6124049083615551565b905060005a612413908861522c565b90508082111561085b5761085b61242a828461522c565b6129db565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052611ef79085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612a04565b6000816000015182602001518360400151846060015160405160200161254a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a0880151935160009761254a979096959101615565565b6000806125a386612b10565b90506125b181868686612b42565b9695505050505050565b603654604080517ff4daa291000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163f4daa2919160048083019260209291908290030181865afa15801561262b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264f9190615005565b6126599083614fed565b421192915050565b6001805463ffffffff8316919060109061269a908490700100000000000000000000000000000000900467ffffffffffffffff16615273565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b60008060006126d3866000612b72565b905080612709576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526127779084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612489565b505050565b600054610100900460ff16612813576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610add565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff166000036111b85760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa15801561292c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906155d0565b600061296561295f8585612b90565b83612ba0565b90505b9392505050565b6000670de0b6b3a76400006129b06129878583615308565b61299990670de0b6b3a7640000615370565b6129ab85670de0b6b3a76400006153e4565b612baf565b6129ba90866153e4565b6129659190615308565b6000818310156129d45781612968565b5090919050565b6000805a90505b825a6129ee908361522c565b1015612777576129fd82615673565b91506129e2565b6000612a66826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612be09092919063ffffffff16565b8051909150156127775780806020019051810190612a8491906151aa565b612777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610add565b60608180519060200120604051602001612b2c91815260200190565b6040516020818303038152906040529050919050565b6000612b6984612b53878686612bef565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000818312156129d45781612968565b60008183126129d45781612968565b6000612968670de0b6b3a764000083612bc78661366d565b612bd191906153e4565b612bdb9190615308565b6138b1565b60606129658484600085613af0565b60606000845111612c5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610add565b6000612c6784613c86565b90506000612c7486613d72565b9050600084604051602001612c8b91815260200190565b60405160208183030381529060405290506000805b84518110156135e4576000858281518110612cbd57612cbd6156ab565b602002602001015190508451831115612d58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610add565b82600003612e115780518051602091820120604051612da692612d8092910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610add565b612f68565b805151602011612ec75780518051602091820120604051612e3b92612d8092910190815260200190565b612e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610add565b805184516020808701919091208251919092012014612f68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610add565b612f7460106001614fed565b8160200151510361315057845183036130e857612fae8160200151601081518110612fa157612fa16156ab565b6020026020010151613dd5565b96506000875111613041576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610add565b6001865161304f919061522c565b82146130dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610add565b505050505050612968565b60008584815181106130fc576130fc6156ab565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110613127576131276156ab565b6020026020010151905061313a81613e89565b9550613147600186614fed565b945050506135d1565b60028160200151510361354957600061316882613eae565b905060008160008151811061317f5761317f6156ab565b016020015160f81c905060006131966002836156da565b6131a19060026156fc565b905060006131b2848360ff16613ed2565b905060006131c08a89613ed2565b905060006131ce8383613f08565b905080835114613260576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610add565b60ff851660021480613275575060ff85166003145b15613464578082511461330a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610add565b6133248760200151600181518110612fa157612fa16156ab565b9c5060008d51116133b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610add565b60018c516133c5919061522c565b8814613453576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610add565b505050505050505050505050612968565b60ff85161580613477575060ff85166001145b156134b6576134a38760200151600181518110613496576134966156ab565b6020026020010151613e89565b99506134af818a614fed565b985061353e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610add565b5050505050506135d1565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610add565b50806135dc81615673565b915050612ca0565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610add565b60008082136136d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b600060606136e584613fbc565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136138e257506000919050565b680755bf798b4a1bf1e58212613954576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610add565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613b82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610add565b73ffffffffffffffffffffffffffffffffffffffff85163b613c00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610add565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613c29919061571f565b60006040518083038185875af1925050503d8060008114613c66576040519150601f19603f3d011682016040523d82523d6000602084013e613c6b565b606091505b5091509150613c7b828286614092565b979650505050505050565b80516060908067ffffffffffffffff811115613ca457613ca4614a8b565b604051908082528060200260200182016040528015613ce957816020015b6040805180820190915260608082526020820152815260200190600190039081613cc25790505b50915060005b81811015613d6b576040518060400160405280858381518110613d1457613d146156ab565b60200260200101518152602001613d43868481518110613d3657613d366156ab565b60200260200101516140e5565b815250838281518110613d5857613d586156ab565b6020908102919091010152600101613cef565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015613dca578060011b82018184015160001a8060041c8253600f811660018301535050600101613d9c565b509295945050505050565b60606000806000613de5856140f8565b919450925090506000816001811115613e0057613e0061573b565b14613e37576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613e418284614fed565b855114613e7a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b6985602001518484614596565b60606020826000015110613ea557613ea082613dd5565b610ff2565b610ff28261462a565b6060610ff2613ecd8360200151600081518110612fa157612fa16156ab565b613d72565b606082518210613ef15750604080516020810190915260008152610ff2565b6129688383848651613f03919061522c565b614640565b6000808251845110613f1b578251613f1e565b83515b90505b8082108015613fa55750828281518110613f3d57613f3d6156ab565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613f7c57613f7c6156ab565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15613fb557816001019150613f21565b5092915050565b6000808211614027576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606083156140a1575081612968565b8251156140b15782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610add9190614e1d565b6060610ff26140f383614818565b614885565b6000806000836000015160000361413b576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f811161416057600060016000945094509450505061458f565b60b7811161427657600061417560808361522c565b9050808760000151116141b4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214801561422c57507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614263576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061458f915050565b60bf81116143d457600061428b60b78361522c565b9050808760000151116142ca576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361432c576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614374576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61437e8184614fed565b8951116143b7576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6143c2836001614fed565b975095506000945061458f9350505050565b60f781116144395760006143e960c08361522c565b905080876000015111614428576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061458f915050565b600061444660f78361522c565b905080876000015111614485576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036144e7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c6037811161452f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6145398184614fed565b895111614572576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61457d836001614fed565b975095506001945061458f9350505050565b9193909250565b60608167ffffffffffffffff8111156145b1576145b1614a8b565b6040519080825280601f01601f1916602001820160405280156145db576020820181803683370190505b50905081156129685760006145f08486614fed565b90506020820160005b848110156146115782810151828201526020016145f9565b84811115614620576000858301525b5050509392505050565b6060610ff2826020015160008460000151614596565b60608182601f0110156146af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b82828401101561471b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b81830184511015614788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610add565b6060821580156147a7576040519150600082526020820160405261480f565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156147e05780518352602092830192016147c8565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201528151600003614867576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000614895856140f8565b9194509250905060018160018111156148b0576148b061573b565b146148e7576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516148f38385614fed565b1461492a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816149415790505093506000835b8651811015614a2f576000806149b46040518060400160405280858c60000151614998919061522c565b8152602001858c602001516149ad9190614fed565b90526140f8565b5091509150604051806040016040528083836149d09190614fed565b8152602001848b602001516149e59190614fed565b8152508885815181106149fa576149fa6156ab565b6020908102919091010152614a10600185614fed565b9350614a1c8183614fed565b614a269084614fed565b9250505061496e565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114614a5d57600080fd5b50565b803567ffffffffffffffff81168114614a7857600080fd5b919050565b8015158114614a5d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614b0157614b01614a8b565b604052919050565b600082601f830112614b1a57600080fd5b813567ffffffffffffffff811115614b3457614b34614a8b565b614b6560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614aba565b818152846020838601011115614b7a57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614bb057600080fd5b8635614bbb81614a3b565b95506020870135945060408701359350614bd760608801614a60565b92506080870135614be781614a7d565b915060a087013567ffffffffffffffff811115614c0357600080fd5b614c0f89828a01614b09565b9150509295509295509295565b600060c08284031215614c2e57600080fd5b60405160c0810167ffffffffffffffff8282108183111715614c5257614c52614a8b565b816040528293508435835260208501359150614c6d82614a3b565b81602084015260408501359150614c8382614a3b565b816040840152606085013560608401526080850135608084015260a0850135915080821115614cb157600080fd5b50614cbe85828601614b09565b60a0830152505092915050565b600080600080600085870360e0811215614ce457600080fd5b863567ffffffffffffffff80821115614cfc57600080fd5b614d088a838b01614c1c565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614d4157600080fd5b60408901955060c0890135925080831115614d5b57600080fd5b828901925089601f840112614d6f57600080fd5b8235915080821115614d8057600080fd5b508860208260051b8401011115614d9657600080fd5b959894975092955050506020019190565b60005b83811015614dc2578181015183820152602001614daa565b83811115611ef75750506000910152565b60008151808452614deb816020860160208601614da7565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006129686020830184614dd3565b600060208284031215614e4257600080fd5b5035919050565b60ff81168114614a5d57600080fd5b60008060008060808587031215614e6e57600080fd5b8435614e7981614a3b565b93506020850135614e8981614e49565b93969395505050506040820135916060013590565b600060208284031215614eb057600080fd5b813567ffffffffffffffff811115614ec757600080fd5b614ed384828501614c1c565b949350505050565b600060208284031215614eed57600080fd5b61296882614a60565b600080600060608486031215614f0b57600080fd5b8335614f1681614a3b565b92506020840135614f2681614a3b565b91506040840135614f3681614a3b565b809150509250925092565b600080600080600060a08688031215614f5957600080fd5b8535614f6481614a3b565b945060208601359350614f7960408701614a60565b92506060860135614f8981614a7d565b9150608086013567ffffffffffffffff811115614fa557600080fd5b614fb188828901614b09565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561500057615000614fbe565b500190565b60006020828403121561501757600080fd5b5051919050565b60006020828403121561503057600080fd5b815161296881614a3b565b80516fffffffffffffffffffffffffffffffff81168114614a7857600080fd5b60006060828403121561506d57600080fd5b6040516060810181811067ffffffffffffffff8211171561509057615090614a8b565b604052825181526150a36020840161503b565b60208201526150b46040840161503b565b60408201529392505050565b6000608082840312156150d257600080fd5b6040516080810181811067ffffffffffffffff821117156150f5576150f5614a8b565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff8084111561514157615141614a8b565b8360051b6020615152818301614aba565b86815291850191818101903684111561516a57600080fd5b865b8481101561519e578035868111156151845760008081fd5b61519036828b01614b09565b84525091830191830161516c565b50979650505050505050565b6000602082840312156151bc57600080fd5b815161296881614a7d565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b60488201526000825161521b816049850160208701614da7565b919091016049019695505050505050565b60008282101561523e5761523e614fbe565b500390565b600067ffffffffffffffff8083168185168183048111821515161561526a5761526a614fbe565b02949350505050565b600067ffffffffffffffff80831681851680830382111561529657615296614fbe565b01949350505050565b600080604083850312156152b257600080fd5b82516152bd81614a3b565b60208401519092506152ce81614e49565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615317576153176152d9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561536b5761536b614fbe565b500590565b6000808312837f8000000000000000000000000000000000000000000000000000000000000000018312811516156153aa576153aa614fbe565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156153de576153de614fbe565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561542557615425614fbe565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561546057615460614fbe565b6000871292508782058712848416161561547c5761547c614fbe565b8785058712818416161561549257615492614fbe565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156154da576154da614fbe565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561550e5761550e614fbe565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561554c5761554c614fbe565b500290565b600082615560576155606152d9565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526155b060c0830184614dd3565b98975050505050505050565b805163ffffffff81168114614a7857600080fd5b600060c082840312156155e257600080fd5b60405160c0810181811067ffffffffffffffff8211171561560557615605614a8b565b604052615611836155bc565b8152602083015161562181614e49565b6020820152604083015161563481614e49565b6040820152615645606084016155bc565b6060820152615656608084016155bc565b608082015261566760a0840161503b565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036156a4576156a4614fbe565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806156ed576156ed6152d9565b8060ff84160691505092915050565b600060ff821660ff84168082101561571657615716614fbe565b90039392505050565b60008251615731818460208701614da7565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a"; bytes internal constant l2OutputOracleCode = - hex"60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec33481461049b578063e1a41bcf146104b0578063f4daa291146104c657600080fd5b8063ce5db8d614610445578063cf8e5cf01461045b578063d1de856c1461047b57600080fd5b8063a25ae557116100b0578063a25ae55714610391578063a8e4fb90146103ed578063bffa7f0f1461041a57600080fd5b806389c44cbb1461034857806393991af3146103685780639aaab6481461037e57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa5146102fc5780637f00642014610312578063887862721461033257600080fd5b806369f16eec146102a75780636abcf563146102bc5780636b4d98dd146102d157600080fd5b8063529933df11610169578063529933df146101ea578063534db0e2146101ff57806354fd4d501461025157600080fd5b80622134cc1461018f5780631c89c97d146101b35780634599c788146101d5575b600080fd5b34801561019b57600080fd5b506005545b6040519081526020015b60405180910390f35b3480156101bf57600080fd5b506101d36101ce3660046113a2565b6104db565b005b3480156101e157600080fd5b506101a06108b6565b3480156101f657600080fd5b506004546101a0565b34801561020b57600080fd5b5060065461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101aa565b34801561025d57600080fd5b5061029a6040518060400160405280600581526020017f312e382e3000000000000000000000000000000000000000000000000000000081525081565b6040516101aa9190611405565b3480156102b357600080fd5b506101a0610929565b3480156102c857600080fd5b506003546101a0565b3480156102dd57600080fd5b5060065473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561030857600080fd5b506101a060015481565b34801561031e57600080fd5b506101a061032d366004611478565b61093b565b34801561033e57600080fd5b506101a060025481565b34801561035457600080fd5b506101d3610363366004611478565b610b4f565b34801561037457600080fd5b506101a060055481565b6101d361038c366004611491565b610de9565b34801561039d57600080fd5b506103b16103ac366004611478565b61124a565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101aa565b3480156103f957600080fd5b5060075461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561042657600080fd5b5060075473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561045157600080fd5b506101a060085481565b34801561046757600080fd5b506103b1610476366004611478565b6112de565b34801561048757600080fd5b506101a0610496366004611478565b611316565b3480156104a757600080fd5b506101a0611346565b3480156104bc57600080fd5b506101a060045481565b3480156104d257600080fd5b506008546101a0565b600054610100900460ff16158080156104fb5750600054600160ff909116105b806105155750303b158015610515575060005460ff166001145b6105a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561060457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60008811610694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e2030000000000000606482015260840161059d565b60008711610724576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e2030000000000000000000000000606482015260840161059d565b428511156107db576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60048890556005879055600186905560028590556007805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556006805492861692909116919091179055600882905580156108ac57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b6003546000901561092057600380546108d1906001906114f2565b815481106108e1576108e1611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b600354600090610924906001906114f2565b60006109456108b6565b8211156109fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161059d565b600354610aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161059d565b6003546000905b80821015610b485760006002610acc8385611538565b610ad69190611550565b90508460038281548110610aec57610aec611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610b3e57610b37816001611538565b9250610b42565b8091505b50610ab6565b5092915050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610bf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161059d565b6003548110610cad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60085460038281548110610cc357610cc3611509565b6000918252602090912060016002909202010154610cf3906fffffffffffffffffffffffffffffffff16426114f2565b10610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161059d565b6000610db160035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60075473ffffffffffffffffffffffffffffffffffffffff163314610eb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b610ebe611346565b8314610f72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161059d565b42610f7c84611316565b10611009576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161059d565b83611096576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161059d565b81156111525781814014611152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161059d565b8261115c60035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e24260405161118e91815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b60408051606081018252600080825260208201819052918101919091526003828154811061127a5761127a611509565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b604080516060810182526000808252602082018190529181019190915260036113068361093b565b8154811061127a5761127a611509565b60006005546001548361132991906114f2565b611333919061158b565b6002546113409190611538565b92915050565b60006004546113536108b6565b6109249190611538565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b803573ffffffffffffffffffffffffffffffffffffffff8116811461139d57600080fd5b919050565b600080600080600080600060e0888a0312156113bd57600080fd5b873596506020880135955060408801359450606088013593506113e260808901611379565b92506113f060a08901611379565b915060c0880135905092959891949750929550565b600060208083528351808285015260005b8181101561143257858101830151858201604001528201611416565b81811115611444576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561148a57600080fd5b5035919050565b600080600080608085870312156114a757600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611504576115046114c3565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000821982111561154b5761154b6114c3565b500190565b600082611586577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156115c3576115c36114c3565b50029056fea164736f6c634300080f000a"; + hex"60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec33481461049b578063e1a41bcf146104b0578063f4daa291146104c657600080fd5b8063ce5db8d614610445578063cf8e5cf01461045b578063d1de856c1461047b57600080fd5b8063a25ae557116100b0578063a25ae55714610391578063a8e4fb90146103ed578063bffa7f0f1461041a57600080fd5b806389c44cbb1461034857806393991af3146103685780639aaab6481461037e57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa5146102fc5780637f00642014610312578063887862721461033257600080fd5b806369f16eec146102a75780636abcf563146102bc5780636b4d98dd146102d157600080fd5b8063529933df11610169578063529933df146101ea578063534db0e2146101ff57806354fd4d501461025157600080fd5b80622134cc1461018f5780631c89c97d146101b35780634599c788146101d5575b600080fd5b34801561019b57600080fd5b506005545b6040519081526020015b60405180910390f35b3480156101bf57600080fd5b506101d36101ce3660046113a2565b6104db565b005b3480156101e157600080fd5b506101a06108b6565b3480156101f657600080fd5b506004546101a0565b34801561020b57600080fd5b5060065461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101aa565b34801561025d57600080fd5b5061029a6040518060400160405280600c81526020017f312e382e312d626574612e31000000000000000000000000000000000000000081525081565b6040516101aa9190611405565b3480156102b357600080fd5b506101a0610929565b3480156102c857600080fd5b506003546101a0565b3480156102dd57600080fd5b5060065473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561030857600080fd5b506101a060015481565b34801561031e57600080fd5b506101a061032d366004611478565b61093b565b34801561033e57600080fd5b506101a060025481565b34801561035457600080fd5b506101d3610363366004611478565b610b4f565b34801561037457600080fd5b506101a060055481565b6101d361038c366004611491565b610de9565b34801561039d57600080fd5b506103b16103ac366004611478565b61124a565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101aa565b3480156103f957600080fd5b5060075461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561042657600080fd5b5060075473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561045157600080fd5b506101a060085481565b34801561046757600080fd5b506103b1610476366004611478565b6112de565b34801561048757600080fd5b506101a0610496366004611478565b611316565b3480156104a757600080fd5b506101a0611346565b3480156104bc57600080fd5b506101a060045481565b3480156104d257600080fd5b506008546101a0565b600054610100900460ff16158080156104fb5750600054600160ff909116105b806105155750303b158015610515575060005460ff166001145b6105a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561060457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60008811610694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e2030000000000000606482015260840161059d565b60008711610724576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e2030000000000000000000000000606482015260840161059d565b428511156107db576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60048890556005879055600186905560028590556007805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556006805492861692909116919091179055600882905580156108ac57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b6003546000901561092057600380546108d1906001906114f2565b815481106108e1576108e1611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b600354600090610924906001906114f2565b60006109456108b6565b8211156109fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161059d565b600354610aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161059d565b6003546000905b80821015610b485760006002610acc8385611538565b610ad69190611550565b90508460038281548110610aec57610aec611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610b3e57610b37816001611538565b9250610b42565b8091505b50610ab6565b5092915050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610bf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161059d565b6003548110610cad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60085460038281548110610cc357610cc3611509565b6000918252602090912060016002909202010154610cf3906fffffffffffffffffffffffffffffffff16426114f2565b10610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161059d565b6000610db160035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60075473ffffffffffffffffffffffffffffffffffffffff163314610eb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b610ebe611346565b8314610f72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161059d565b42610f7c84611316565b10611009576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161059d565b83611096576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161059d565b81156111525781814014611152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161059d565b8261115c60035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e24260405161118e91815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b60408051606081018252600080825260208201819052918101919091526003828154811061127a5761127a611509565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b604080516060810182526000808252602082018190529181019190915260036113068361093b565b8154811061127a5761127a611509565b60006005546001548361132991906114f2565b611333919061158b565b6002546113409190611538565b92915050565b60006004546113536108b6565b6109249190611538565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b803573ffffffffffffffffffffffffffffffffffffffff8116811461139d57600080fd5b919050565b600080600080600080600060e0888a0312156113bd57600080fd5b873596506020880135955060408801359450606088013593506113e260808901611379565b92506113f060a08901611379565b915060c0880135905092959891949750929550565b600060208083528351808285015260005b8181101561143257858101830151858201604001528201611416565b81811115611444576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561148a57600080fd5b5035919050565b600080600080608085870312156114a757600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611504576115046114c3565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000821982111561154b5761154b6114c3565b500190565b600082611586577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156115c3576115c36114c3565b50029056fea164736f6c634300080f000a"; bytes internal constant optimismPortal2Code = - hex"6080604052600436106101d15760003560e01c80637fc48504116100f7578063a35d99df11610095578063bf653a5c11610064578063bf653a5c14610697578063cff0ab96146106ca578063e9e05c421461076b578063f2b4e6171461077e57600080fd5b8063a35d99df1461059b578063a3860f48146105bb578063b69ef8a8146105db578063bb2c727e146105f057600080fd5b80638e819e54116100d15780638e819e54146104eb578063952b27971461050b5780639bf62d821461053e578063a14238e71461056b57600080fd5b80637fc48504146104ab5780638b4c40b0146101f65780638c3152e9146104cb57600080fd5b80634870496f1161016f5780635c975abb1161013e5780635c975abb1461043657806371c1566e1461044b57806371cfaa3f1461046b5780637d6be8dc1461048b57600080fd5b80634870496f1461034d5780634fd0434c1461036d578063513747ab146103af57806354fd4d50146103ea57600080fd5b80633c9f397c116101ab5780633c9f397c146102a657806343ca1c50146102d8578063452a9320146102f857806345884d321461030d57600080fd5b8063149f2f22146101fd57806333d7e2bd1461021d57806335e80ab31461027457600080fd5b366101f8576101f63334620186a06000604051806020016040528060008152506107ab565b005b600080fd5b34801561020957600080fd5b506101f6610218366004614fe6565b610850565b34801561022957600080fd5b5060375461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561028057600080fd5b5060355461024a90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156102b257600080fd5b50603b546102c39063ffffffff1681565b60405163ffffffff909116815260200161026b565b3480156102e457600080fd5b506101f66102f336600461511c565b610a91565b34801561030457600080fd5b5061024a610f31565b34801561031957600080fd5b5061033d61032836600461516e565b603a6020526000908152604090205460ff1681565b604051901515815260200161026b565b34801561035957600080fd5b506101f661036836600461518b565b610fc9565b34801561037957600080fd5b50603b5461039690640100000000900467ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161026b565b3480156103bb57600080fd5b506103dc6103ca366004615267565b6000908152603c602052604090205490565b60405190815260200161026b565b3480156103f657600080fd5b50604080518082018252600d81527f332e31312e302d626574612e32000000000000000000000000000000000000006020820152905161026b91906152f6565b34801561044257600080fd5b5061033d611531565b34801561045757600080fd5b506101f6610466366004615309565b6115c4565b34801561047757600080fd5b506101f661048636600461533d565b611c7f565b34801561049757600080fd5b506101f66104a636600461516e565b611e3f565b3480156104b757600080fd5b506101f66104c6366004615395565b611f22565b3480156104d757600080fd5b506101f66104e63660046153b2565b61200e565b3480156104f757600080fd5b506101f66105063660046153ef565b61205a565b34801561051757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000066103dc565b34801561054a57600080fd5b5060325461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561057757600080fd5b5061033d610586366004615267565b60336020526000908152604090205460ff1681565b3480156105a757600080fd5b506103966105b636600461544b565b61230f565b3480156105c757600080fd5b5061024a6105d6366004615468565b61232e565b3480156105e757600080fd5b506103dc612373565b3480156105fc57600080fd5b5061066261060b366004615309565b603960209081526000928352604080842090915290825290205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900467ffffffffffffffff1682565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff90911660208301520161026b565b3480156106a357600080fd5b507f000000000000000000000000000000000000000000000000000000000000000c6103dc565b3480156106d657600080fd5b50600154610732906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff928316602085015291169082015260600161026b565b6101f661077936600461548a565b6107ab565b34801561078a57600080fd5b5060385461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b8260005a905060006107bb6123e9565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906107f757503415155b1561082e576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61083c883489898989612486565b506108478282612632565b50505050505050565b8260005a905060006108606123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016108d2576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546108e49190615538565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610956573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097a9190615550565b905061099e73ffffffffffffffffffffffffffffffffffffffff831633308c6128ff565b6109a88982615538565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a369190615550565b14610a6d576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a7b8a8a8a8a8a8a612486565b5050610a878282612632565b5050505050505050565b610a99611531565b15610ad0576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead14610b23576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610b2e836129e1565b9050610b3a81836115c4565b6000818152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558401516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905580610bc56123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601610c2857610c218560400151866080015187606001518860a00151612a2e565b9150610e7b565b8073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610c91576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606085015115610e52578460600151603d6000828254610cb19190615569565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610d23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d479190615550565b9050610d7c866040015187606001518473ffffffffffffffffffffffffffffffffffffffff16612a8c9092919063ffffffff16565b6060860151610d8b9082615569565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e199190615550565b14610e50576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08501515115610e7657610c218560400151866080015160008860a00151612a2e565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405183907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90610edd90851515815260200190565b60405180910390a281158015610ef35750326001145b15610f2a576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fa0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615580565b905090565b610fd1611531565b15611008576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603611071576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6038546040517fbb8aa1fc00000000000000000000000000000000000000000000000000000000815260048101869052600091829173ffffffffffffffffffffffffffffffffffffffff9091169063bb8aa1fc90602401606060405180830381865afa1580156110e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611109919061559d565b925050915060008173ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561115b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117f9190615550565b603b5490915063ffffffff8481169116146111c6576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111dd6111d8368890038801886155ea565b612ae7565b8114611215576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611220896129e1565b905060018373ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611293919061567f565b60028111156112a4576112a4615650565b036112db576040517fd357347400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051602081018390526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506113a49101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f010000000000000000000000000000000000000000000000000000000000000060208301529061139a898b6156a0565b8b60400135612b26565b15156000036113df576040517fb05e92fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825273ffffffffffffffffffffffffffffffffffffffff808716825267ffffffffffffffff4281166020808501918252600088815260398252868120338252825286812095518654935190941674010000000000000000000000000000000000000000027fffffffff0000000000000000000000000000000000000000000000000000000090931693851693909317919091179093558d840151928e01519351928216939091169185917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f6291a4604051339083907f798f9f13695f8f045aa5f80ed8efebb695f3c7fe65da381969f2f28bf3c60b9790600090a3506000908152603c602090815260408220805460018101825590835291200180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115a0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615724565b600082815260396020908152604080832073ffffffffffffffffffffffffffffffffffffffff85811685529083528184208251808401845290549182168082527401000000000000000000000000000000000000000090920467ffffffffffffffff1681850152818552603a90935292205490919060ff1615611673576040517f09550c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816020015167ffffffffffffffff166000036116bb576040517f94efd49b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061173c8273ffffffffffffffffffffffffffffffffffffffff1663cf09e0d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172f9190615741565b67ffffffffffffffff1690565b90508067ffffffffffffffff16836020015167ffffffffffffffff1611611810576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e20646973707574652067616d65206372656160648201527f74696f6e2074696d657374616d70000000000000000000000000000000000000608482015260a4015b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000c836020015167ffffffffffffffff164261184b9190615569565b116118d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c20686173206e6f74206d6174757265642079657400000000000000000000006064820152608401611807565b60028273ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611925573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611949919061567f565b600281111561195a5761195a615650565b14611991576040517fa080a3c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5463ffffffff1663ffffffff16611a1b8373ffffffffffffffffffffffffffffffffffffffff1663bbdc02db6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a12919061575e565b63ffffffff1690565b63ffffffff1614611a58576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5467ffffffffffffffff64010000000090910481169082161015611b26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a20646973707574652067616d652063726560448201527f61746564206265666f7265207265737065637465642067616d6520747970652060648201527f7761732075706461746564000000000000000000000000000000000000000000608482015260a401611807565b7f0000000000000000000000000000000000000000000000000000000000000006611b958373ffffffffffffffffffffffffffffffffffffffff166319effeb46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b611ba99067ffffffffffffffff1642615569565b11611c36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f696e206169722d676170000000000000000000000000000000000000000000006064820152608401611807565b60008581526033602052604090205460ff1615610f2a576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60375473ffffffffffffffffffffffffffffffffffffffff163314611cd0576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611cdc62030d40612b4a565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f000000000000000000000000000000000000000000000000000000001790529051611df99695949392910161577b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052611e31916152f6565b60405180910390a450505050565b611e47610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611eab576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152603a602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f192c289026d59a41a27f5aea08f3969b57931b0589202d14f4368cded95d3cda9190a250565b611f2a610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f8e576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b805463ffffffff83167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090911681176401000000004267ffffffffffffffff90811682029290921793849055604051930416917f049fe9dd413cdf037cce27011cc1790c753118272f3630e6e8bdfa5e8208176090600090a350565b565b612016611531565b1561204d576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120578133610a91565b50565b600054610100900460ff161580801561207a5750600054600160ff909116105b806120945750303b158015612094575060005460ff166001145b612120576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611807565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561217e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603880547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8881169190911790925560378054909116868316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff16610100868416021790556032541661229e576032805461dead7fffffffffffffffffffffffff0000000000000000000000000000000000000000909116179055603b80547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166401000000004267ffffffffffffffff16027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000161763ffffffff84161790555b6122a6612bac565b8015610f2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600061231c8260106157e0565b61232890615208615810565b92915050565b603c602052816000526040600020818154811061234a57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169150829050565b60008061237e6123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016123c5574791505090565b5050603d5490565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015612459573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247d919061583c565b90939092509050565b8180156124a8575073ffffffffffffffffffffffffffffffffffffffff861615155b156124df576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6124e9815161230f565b67ffffffffffffffff168367ffffffffffffffff161015612536576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c081511115612574576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33328114612595575033731111000000000000000000000000000000001111015b600086868686866040516020016125b095949392919061577b565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161262091906152f6565b60405180910390a45050505050505050565b600154600090612668907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643615569565b90506000612674612cbf565b90506000816020015160ff16826000015163ffffffff16612695919061589a565b905082156127cc576001546000906126cc908390700100000000000000000000000000000000900467ffffffffffffffff16615902565b90506000836040015160ff16836126e39190615976565b6001546127039084906fffffffffffffffffffffffffffffffff16615976565b61270d919061589a565b60015490915060009061275e906127379084906fffffffffffffffffffffffffffffffff16615a32565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612d80565b9050600186111561278d5761278a61273782876040015160ff1660018a6127859190615569565b612d9f565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b600180548691906010906127ff908490700100000000000000000000000000000000900467ffffffffffffffff16615810565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff16131561288c576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906128b8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615aa6565b905060006128ca48633b9aca00612df4565b6128d49083615ae3565b905060005a6128e39088615569565b905080821115610a8757610a876128fa8284615569565b612e0b565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526129db9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612e34565b50505050565b80516020808301516040808501516060860151608087015160a08801519351600097612a11979096959101615af7565b604051602081830303815290604052805190602001209050919050565b6000806000612a3e866000612f40565b905080612a74576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052612ae29084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612959565b505050565b60008160000151826020015183604001518460600151604051602001612a11949392919093845260208401929092526040830152606082015260800190565b600080612b3286612f5e565b9050612b4081868686612f90565b9695505050505050565b6001805463ffffffff83169190601090612b83908490700100000000000000000000000000000000900467ffffffffffffffff16615810565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b600054610100900460ff16612c43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611807565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff1660000361200c5760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa158015612d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615b4e565b6000612d95612d8f8585612fc0565b83612fd0565b90505b9392505050565b6000670de0b6b3a7640000612de0612db7858361589a565b612dc990670de0b6b3a7640000615902565b612ddb85670de0b6b3a7640000615976565b612fdf565b612dea9086615976565b612d95919061589a565b600081831015612e045781612d98565b5090919050565b6000805a90505b825a612e1e9083615569565b1015612ae257612e2d82615bf0565b9150612e12565b6000612e96826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130109092919063ffffffff16565b805190915015612ae25780806020019051810190612eb49190615724565b612ae2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611807565b600080603f83619c4001026040850201603f5a021015949350505050565b60608180519060200120604051602001612f7a91815260200190565b6040516020818303038152906040529050919050565b6000612fb784612fa187868661301f565b8051602091820120825192909101919091201490565b95945050505050565b600081831215612e045781612d98565b6000818312612e045781612d98565b6000612d98670de0b6b3a764000083612ff786613a9d565b6130019190615976565b61300b919061589a565b613ce1565b6060612d958484600085613f20565b6060600084511161308c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401611807565b6000613097846140b6565b905060006130a4866141a2565b90506000846040516020016130bb91815260200190565b60405160208183030381529060405290506000805b8451811015613a145760008582815181106130ed576130ed615c28565b602002602001015190508451831115613188576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401611807565b8260000361324157805180516020918201206040516131d6926131b092910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b61323c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401611807565b613398565b8051516020116132f7578051805160209182012060405161326b926131b092910190815260200190565b61323c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401611807565b805184516020808701919091208251919092012014613398576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401611807565b6133a460106001615538565b816020015151036135805784518303613518576133de81602001516010815181106133d1576133d1615c28565b6020026020010151614205565b96506000875111613471576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401611807565b6001865161347f9190615569565b821461350d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401611807565b505050505050612d98565b600085848151811061352c5761352c615c28565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061355757613557615c28565b6020026020010151905061356a816142b9565b9550613577600186615538565b94505050613a01565b600281602001515103613979576000613598826142de565b90506000816000815181106135af576135af615c28565b016020015160f81c905060006135c6600283615c57565b6135d1906002615c79565b905060006135e2848360ff16614302565b905060006135f08a89614302565b905060006135fe8383614338565b905080835114613690576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401611807565b60ff8516600214806136a5575060ff85166003145b15613894578082511461373a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401611807565b61375487602001516001815181106133d1576133d1615c28565b9c5060008d51116137e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401611807565b60018c516137f59190615569565b8814613883576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401611807565b505050505050505050505050612d98565b60ff851615806138a7575060ff85166001145b156138e6576138d387602001516001815181106138c6576138c6615c28565b60200260200101516142b9565b99506138df818a615538565b985061396e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401611807565b505050505050613a01565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401611807565b5080613a0c81615bf0565b9150506130d0565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401611807565b6000808213613b08576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b60006060613b15846143ec565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c18213613d1257506000919050565b680755bf798b4a1bf1e58212613d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401611807565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613fb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611807565b73ffffffffffffffffffffffffffffffffffffffff85163b614030576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611807565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516140599190615c9c565b60006040518083038185875af1925050503d8060008114614096576040519150601f19603f3d011682016040523d82523d6000602084013e61409b565b606091505b50915091506140ab8282866144c2565b979650505050505050565b80516060908067ffffffffffffffff8111156140d4576140d4614eb1565b60405190808252806020026020018201604052801561411957816020015b60408051808201909152606080825260208201528152602001906001900390816140f25790505b50915060005b8181101561419b57604051806040016040528085838151811061414457614144615c28565b6020026020010151815260200161417386848151811061416657614166615c28565b6020026020010151614515565b81525083828151811061418857614188615c28565b602090810291909101015260010161411f565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b838110156141fa578060011b82018184015160001a8060041c8253600f8116600183015350506001016141cc565b509295945050505050565b6060600080600061421585614528565b91945092509050600081600181111561423057614230615650565b14614267576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6142718284615538565b8551146142aa576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fb7856020015184846149c6565b606060208260000151106142d5576142d082614205565b612328565b61232882614a5a565b60606123286142fd83602001516000815181106133d1576133d1615c28565b6141a2565b6060825182106143215750604080516020810190915260008152612328565b612d9883838486516143339190615569565b614a70565b600080825184511061434b57825161434e565b83515b90505b80821080156143d5575082828151811061436d5761436d615c28565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168483815181106143ac576143ac615c28565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156143e557816001019150614351565b5092915050565b6000808211614457576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606083156144d1575081612d98565b8251156144e15782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180791906152f6565b606061232861452383614c48565b614cb5565b6000806000836000015160000361456b576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f81116145905760006001600094509450945050506149bf565b60b781116146a65760006145a5608083615569565b9050808760000151116145e4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214801561465c57507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614693576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600195509350600092506149bf915050565b60bf81116148045760006146bb60b783615569565b9050808760000151116146fa576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361475c576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116147a4576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147ae8184615538565b8951116147e7576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147f2836001615538565b97509550600094506149bf9350505050565b60f7811161486957600061481960c083615569565b905080876000015111614858576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001955093508492506149bf915050565b600061487660f783615569565b9050808760000151116148b5576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614917576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c6037811161495f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6149698184615538565b8951116149a2576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6149ad836001615538565b97509550600194506149bf9350505050565b9193909250565b60608167ffffffffffffffff8111156149e1576149e1614eb1565b6040519080825280601f01601f191660200182016040528015614a0b576020820181803683370190505b5090508115612d98576000614a208486615538565b90506020820160005b84811015614a41578281015182820152602001614a29565b84811115614a50576000858301525b5050509392505050565b60606123288260200151600084600001516149c6565b60608182601f011015614adf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b828284011015614b4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b81830184511015614bb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401611807565b606082158015614bd75760405191506000825260208201604052614c3f565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614c10578051835260209283019201614bf8565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201528151600003614c97576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000614cc585614528565b919450925090506001816001811115614ce057614ce0615650565b14614d17576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451614d238385615538565b14614d5a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081614d715790505093506000835b8651811015614e5f57600080614de46040518060400160405280858c60000151614dc89190615569565b8152602001858c60200151614ddd9190615538565b9052614528565b509150915060405180604001604052808383614e009190615538565b8152602001848b60200151614e159190615538565b815250888581518110614e2a57614e2a615c28565b6020908102919091010152614e40600185615538565b9350614e4c8183615538565b614e569084615538565b92505050614d9e565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461205757600080fd5b67ffffffffffffffff8116811461205757600080fd5b801515811461205757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715614f0357614f03614eb1565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614f5057614f50614eb1565b604052919050565b600082601f830112614f6957600080fd5b813567ffffffffffffffff811115614f8357614f83614eb1565b614fb460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614f09565b818152846020838601011115614fc957600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614fff57600080fd5b863561500a81614e6b565b95506020870135945060408701359350606087013561502881614e8d565b9250608087013561503881614ea3565b915060a087013567ffffffffffffffff81111561505457600080fd5b61506089828a01614f58565b9150509295509295509295565b600060c0828403121561507f57600080fd5b60405160c0810167ffffffffffffffff82821081831117156150a3576150a3614eb1565b8160405282935084358352602085013591506150be82614e6b565b816020840152604085013591506150d482614e6b565b816040840152606085013560608401526080850135608084015260a085013591508082111561510257600080fd5b5061510f85828601614f58565b60a0830152505092915050565b6000806040838503121561512f57600080fd5b823567ffffffffffffffff81111561514657600080fd5b6151528582860161506d565b925050602083013561516381614e6b565b809150509250929050565b60006020828403121561518057600080fd5b8135612d9881614e6b565b600080600080600085870360e08112156151a457600080fd5b863567ffffffffffffffff808211156151bc57600080fd5b6151c88a838b0161506d565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401121561520157600080fd5b60408901955060c089013592508083111561521b57600080fd5b828901925089601f84011261522f57600080fd5b823591508082111561524057600080fd5b508860208260051b840101111561525657600080fd5b959894975092955050506020019190565b60006020828403121561527957600080fd5b5035919050565b60005b8381101561529b578181015183820152602001615283565b838111156129db5750506000910152565b600081518084526152c4816020860160208601615280565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612d9860208301846152ac565b6000806040838503121561531c57600080fd5b82359150602083013561516381614e6b565b60ff8116811461205757600080fd5b6000806000806080858703121561535357600080fd5b843561535e81614e6b565b9350602085013561536e8161532e565b93969395505050506040820135916060013590565b63ffffffff8116811461205757600080fd5b6000602082840312156153a757600080fd5b8135612d9881615383565b6000602082840312156153c457600080fd5b813567ffffffffffffffff8111156153db57600080fd5b6153e78482850161506d565b949350505050565b6000806000806080858703121561540557600080fd5b843561541081614e6b565b9350602085013561542081614e6b565b9250604085013561543081614e6b565b9150606085013561544081615383565b939692955090935050565b60006020828403121561545d57600080fd5b8135612d9881614e8d565b6000806040838503121561547b57600080fd5b50508035926020909101359150565b600080600080600060a086880312156154a257600080fd5b85356154ad81614e6b565b94506020860135935060408601356154c481614e8d565b925060608601356154d481614ea3565b9150608086013567ffffffffffffffff8111156154f057600080fd5b6154fc88828901614f58565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561554b5761554b615509565b500190565b60006020828403121561556257600080fd5b5051919050565b60008282101561557b5761557b615509565b500390565b60006020828403121561559257600080fd5b8151612d9881614e6b565b6000806000606084860312156155b257600080fd5b83516155bd81615383565b60208501519093506155ce81614e8d565b60408501519092506155df81614e6b565b809150509250925092565b6000608082840312156155fc57600080fd5b6040516080810181811067ffffffffffffffff8211171561561f5761561f614eb1565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006020828403121561569157600080fd5b815160038110612d9857600080fd5b600067ffffffffffffffff808411156156bb576156bb614eb1565b8360051b60206156cc818301614f09565b8681529185019181810190368411156156e457600080fd5b865b84811015615718578035868111156156fe5760008081fd5b61570a36828b01614f58565b8452509183019183016156e6565b50979650505050505050565b60006020828403121561573657600080fd5b8151612d9881614ea3565b60006020828403121561575357600080fd5b8151612d9881614e8d565b60006020828403121561577057600080fd5b8151612d9881615383565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b6048820152600082516157cf816049850160208701615280565b919091016049019695505050505050565b600067ffffffffffffffff8083168185168183048111821515161561580757615807615509565b02949350505050565b600067ffffffffffffffff80831681851680830382111561583357615833615509565b01949350505050565b6000806040838503121561584f57600080fd5b825161585a81614e6b565b60208401519092506151638161532e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826158a9576158a961586b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156158fd576158fd615509565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561593c5761593c615509565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561597057615970615509565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156159b7576159b7615509565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156159f2576159f2615509565b60008712925087820587128484161615615a0e57615a0e615509565b87850587128184161615615a2457615a24615509565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03841381151615615a6c57615a6c615509565b827f8000000000000000000000000000000000000000000000000000000000000000038412811615615aa057615aa0615509565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615ade57615ade615509565b500290565b600082615af257615af261586b565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152615b4260c08301846152ac565b98975050505050505050565b600060c08284031215615b6057600080fd5b615b68614ee0565b8251615b7381615383565b81526020830151615b838161532e565b60208201526040830151615b968161532e565b60408201526060830151615ba981615383565b60608201526080830151615bbc81615383565b608082015260a08301516fffffffffffffffffffffffffffffffff81168114615be457600080fd5b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615c2157615c21615509565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff831680615c6a57615c6a61586b565b8060ff84160691505092915050565b600060ff821660ff841680821015615c9357615c93615509565b90039392505050565b60008251615cae818460208701615280565b919091019291505056fea164736f6c634300080f000a"; + hex"6080604052600436106101d15760003560e01c80637fc48504116100f7578063a35d99df11610095578063bf653a5c11610064578063bf653a5c14610697578063cff0ab96146106ca578063e9e05c421461076b578063f2b4e6171461077e57600080fd5b8063a35d99df1461059b578063a3860f48146105bb578063b69ef8a8146105db578063bb2c727e146105f057600080fd5b80638e819e54116100d15780638e819e54146104eb578063952b27971461050b5780639bf62d821461053e578063a14238e71461056b57600080fd5b80637fc48504146104ab5780638b4c40b0146101f65780638c3152e9146104cb57600080fd5b80634870496f1161016f5780635c975abb1161013e5780635c975abb1461043657806371c1566e1461044b57806371cfaa3f1461046b5780637d6be8dc1461048b57600080fd5b80634870496f1461034d5780634fd0434c1461036d578063513747ab146103af57806354fd4d50146103ea57600080fd5b80633c9f397c116101ab5780633c9f397c146102a657806343ca1c50146102d8578063452a9320146102f857806345884d321461030d57600080fd5b8063149f2f22146101fd57806333d7e2bd1461021d57806335e80ab31461027457600080fd5b366101f8576101f63334620186a06000604051806020016040528060008152506107ab565b005b600080fd5b34801561020957600080fd5b506101f6610218366004614fe6565b610850565b34801561022957600080fd5b5060375461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561028057600080fd5b5060355461024a90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156102b257600080fd5b50603b546102c39063ffffffff1681565b60405163ffffffff909116815260200161026b565b3480156102e457600080fd5b506101f66102f336600461511c565b610a91565b34801561030457600080fd5b5061024a610f31565b34801561031957600080fd5b5061033d61032836600461516e565b603a6020526000908152604090205460ff1681565b604051901515815260200161026b565b34801561035957600080fd5b506101f661036836600461518b565b610fc9565b34801561037957600080fd5b50603b5461039690640100000000900467ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161026b565b3480156103bb57600080fd5b506103dc6103ca366004615267565b6000908152603c602052604090205490565b60405190815260200161026b565b3480156103f657600080fd5b50604080518082018252600d81527f332e31312e302d626574612e33000000000000000000000000000000000000006020820152905161026b91906152f6565b34801561044257600080fd5b5061033d611531565b34801561045757600080fd5b506101f6610466366004615309565b6115c4565b34801561047757600080fd5b506101f661048636600461533d565b611c7f565b34801561049757600080fd5b506101f66104a636600461516e565b611e3f565b3480156104b757600080fd5b506101f66104c6366004615395565b611f22565b3480156104d757600080fd5b506101f66104e63660046153b2565b61200e565b3480156104f757600080fd5b506101f66105063660046153ef565b61205a565b34801561051757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000066103dc565b34801561054a57600080fd5b5060325461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561057757600080fd5b5061033d610586366004615267565b60336020526000908152604090205460ff1681565b3480156105a757600080fd5b506103966105b636600461544b565b61230f565b3480156105c757600080fd5b5061024a6105d6366004615468565b61232e565b3480156105e757600080fd5b506103dc612373565b3480156105fc57600080fd5b5061066261060b366004615309565b603960209081526000928352604080842090915290825290205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900467ffffffffffffffff1682565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff90911660208301520161026b565b3480156106a357600080fd5b507f000000000000000000000000000000000000000000000000000000000000000c6103dc565b3480156106d657600080fd5b50600154610732906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff928316602085015291169082015260600161026b565b6101f661077936600461548a565b6107ab565b34801561078a57600080fd5b5060385461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b8260005a905060006107bb6123e9565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906107f757503415155b1561082e576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61083c883489898989612486565b506108478282612632565b50505050505050565b8260005a905060006108606123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016108d2576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546108e49190615538565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610956573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097a9190615550565b905061099e73ffffffffffffffffffffffffffffffffffffffff831633308c6128ff565b6109a88982615538565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a369190615550565b14610a6d576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a7b8a8a8a8a8a8a612486565b5050610a878282612632565b5050505050505050565b610a99611531565b15610ad0576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead14610b23576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610b2e836129e1565b9050610b3a81836115c4565b6000818152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558401516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905580610bc56123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601610c2857610c218560400151866080015187606001518860a00151612a2e565b9150610e7b565b8073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610c91576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606085015115610e52578460600151603d6000828254610cb19190615569565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610d23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d479190615550565b9050610d7c866040015187606001518473ffffffffffffffffffffffffffffffffffffffff16612a8c9092919063ffffffff16565b6060860151610d8b9082615569565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e199190615550565b14610e50576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08501515115610e7657610c218560400151866080015160008860a00151612a2e565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405183907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90610edd90851515815260200190565b60405180910390a281158015610ef35750326001145b15610f2a576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fa0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615580565b905090565b610fd1611531565b15611008576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603611071576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6038546040517fbb8aa1fc00000000000000000000000000000000000000000000000000000000815260048101869052600091829173ffffffffffffffffffffffffffffffffffffffff9091169063bb8aa1fc90602401606060405180830381865afa1580156110e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611109919061559d565b925050915060008173ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561115b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117f9190615550565b603b5490915063ffffffff8481169116146111c6576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111dd6111d8368890038801886155ea565b612ae7565b8114611215576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611220896129e1565b905060018373ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611293919061567f565b60028111156112a4576112a4615650565b036112db576040517fd357347400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051602081018390526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506113a49101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f010000000000000000000000000000000000000000000000000000000000000060208301529061139a898b6156a0565b8b60400135612b26565b15156000036113df576040517fb05e92fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825273ffffffffffffffffffffffffffffffffffffffff808716825267ffffffffffffffff4281166020808501918252600088815260398252868120338252825286812095518654935190941674010000000000000000000000000000000000000000027fffffffff0000000000000000000000000000000000000000000000000000000090931693851693909317919091179093558d840151928e01519351928216939091169185917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f6291a4604051339083907f798f9f13695f8f045aa5f80ed8efebb695f3c7fe65da381969f2f28bf3c60b9790600090a3506000908152603c602090815260408220805460018101825590835291200180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115a0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615724565b600082815260396020908152604080832073ffffffffffffffffffffffffffffffffffffffff85811685529083528184208251808401845290549182168082527401000000000000000000000000000000000000000090920467ffffffffffffffff1681850152818552603a90935292205490919060ff1615611673576040517f09550c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816020015167ffffffffffffffff166000036116bb576040517f94efd49b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061173c8273ffffffffffffffffffffffffffffffffffffffff1663cf09e0d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172f9190615741565b67ffffffffffffffff1690565b90508067ffffffffffffffff16836020015167ffffffffffffffff1611611810576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e20646973707574652067616d65206372656160648201527f74696f6e2074696d657374616d70000000000000000000000000000000000000608482015260a4015b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000c836020015167ffffffffffffffff164261184b9190615569565b116118d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c20686173206e6f74206d6174757265642079657400000000000000000000006064820152608401611807565b60028273ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611925573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611949919061567f565b600281111561195a5761195a615650565b14611991576040517fa080a3c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5463ffffffff1663ffffffff16611a1b8373ffffffffffffffffffffffffffffffffffffffff1663bbdc02db6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a12919061575e565b63ffffffff1690565b63ffffffff1614611a58576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5467ffffffffffffffff64010000000090910481169082161015611b26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a20646973707574652067616d652063726560448201527f61746564206265666f7265207265737065637465642067616d6520747970652060648201527f7761732075706461746564000000000000000000000000000000000000000000608482015260a401611807565b7f0000000000000000000000000000000000000000000000000000000000000006611b958373ffffffffffffffffffffffffffffffffffffffff166319effeb46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b611ba99067ffffffffffffffff1642615569565b11611c36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f696e206169722d676170000000000000000000000000000000000000000000006064820152608401611807565b60008581526033602052604090205460ff1615610f2a576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60375473ffffffffffffffffffffffffffffffffffffffff163314611cd0576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611cdc62030d40612b4a565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f000000000000000000000000000000000000000000000000000000001790529051611df99695949392910161577b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052611e31916152f6565b60405180910390a450505050565b611e47610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611eab576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152603a602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f192c289026d59a41a27f5aea08f3969b57931b0589202d14f4368cded95d3cda9190a250565b611f2a610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f8e576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b805463ffffffff83167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090911681176401000000004267ffffffffffffffff90811682029290921793849055604051930416917f049fe9dd413cdf037cce27011cc1790c753118272f3630e6e8bdfa5e8208176090600090a350565b565b612016611531565b1561204d576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120578133610a91565b50565b600054610100900460ff161580801561207a5750600054600160ff909116105b806120945750303b158015612094575060005460ff166001145b612120576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611807565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561217e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603880547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8881169190911790925560378054909116868316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff16610100868416021790556032541661229e576032805461dead7fffffffffffffffffffffffff0000000000000000000000000000000000000000909116179055603b80547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166401000000004267ffffffffffffffff16027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000161763ffffffff84161790555b6122a6612bac565b8015610f2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600061231c8260106157e0565b61232890615208615810565b92915050565b603c602052816000526040600020818154811061234a57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169150829050565b60008061237e6123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016123c5574791505090565b5050603d5490565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015612459573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247d919061583c565b90939092509050565b8180156124a8575073ffffffffffffffffffffffffffffffffffffffff861615155b156124df576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6124e9815161230f565b67ffffffffffffffff168367ffffffffffffffff161015612536576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c081511115612574576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33328114612595575033731111000000000000000000000000000000001111015b600086868686866040516020016125b095949392919061577b565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161262091906152f6565b60405180910390a45050505050505050565b600154600090612668907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643615569565b90506000612674612cbf565b90506000816020015160ff16826000015163ffffffff16612695919061589a565b905082156127cc576001546000906126cc908390700100000000000000000000000000000000900467ffffffffffffffff16615902565b90506000836040015160ff16836126e39190615976565b6001546127039084906fffffffffffffffffffffffffffffffff16615976565b61270d919061589a565b60015490915060009061275e906127379084906fffffffffffffffffffffffffffffffff16615a32565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612d80565b9050600186111561278d5761278a61273782876040015160ff1660018a6127859190615569565b612d9f565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b600180548691906010906127ff908490700100000000000000000000000000000000900467ffffffffffffffff16615810565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff16131561288c576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906128b8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615aa6565b905060006128ca48633b9aca00612df4565b6128d49083615ae3565b905060005a6128e39088615569565b905080821115610a8757610a876128fa8284615569565b612e0b565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526129db9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612e34565b50505050565b80516020808301516040808501516060860151608087015160a08801519351600097612a11979096959101615af7565b604051602081830303815290604052805190602001209050919050565b6000806000612a3e866000612f40565b905080612a74576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052612ae29084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612959565b505050565b60008160000151826020015183604001518460600151604051602001612a11949392919093845260208401929092526040830152606082015260800190565b600080612b3286612f5e565b9050612b4081868686612f90565b9695505050505050565b6001805463ffffffff83169190601090612b83908490700100000000000000000000000000000000900467ffffffffffffffff16615810565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b600054610100900460ff16612c43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611807565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff1660000361200c5760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa158015612d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615b4e565b6000612d95612d8f8585612fc0565b83612fd0565b90505b9392505050565b6000670de0b6b3a7640000612de0612db7858361589a565b612dc990670de0b6b3a7640000615902565b612ddb85670de0b6b3a7640000615976565b612fdf565b612dea9086615976565b612d95919061589a565b600081831015612e045781612d98565b5090919050565b6000805a90505b825a612e1e9083615569565b1015612ae257612e2d82615bf0565b9150612e12565b6000612e96826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130109092919063ffffffff16565b805190915015612ae25780806020019051810190612eb49190615724565b612ae2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611807565b600080603f83619c4001026040850201603f5a021015949350505050565b60608180519060200120604051602001612f7a91815260200190565b6040516020818303038152906040529050919050565b6000612fb784612fa187868661301f565b8051602091820120825192909101919091201490565b95945050505050565b600081831215612e045781612d98565b6000818312612e045781612d98565b6000612d98670de0b6b3a764000083612ff786613a9d565b6130019190615976565b61300b919061589a565b613ce1565b6060612d958484600085613f20565b6060600084511161308c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401611807565b6000613097846140b6565b905060006130a4866141a2565b90506000846040516020016130bb91815260200190565b60405160208183030381529060405290506000805b8451811015613a145760008582815181106130ed576130ed615c28565b602002602001015190508451831115613188576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401611807565b8260000361324157805180516020918201206040516131d6926131b092910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b61323c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401611807565b613398565b8051516020116132f7578051805160209182012060405161326b926131b092910190815260200190565b61323c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401611807565b805184516020808701919091208251919092012014613398576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401611807565b6133a460106001615538565b816020015151036135805784518303613518576133de81602001516010815181106133d1576133d1615c28565b6020026020010151614205565b96506000875111613471576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401611807565b6001865161347f9190615569565b821461350d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401611807565b505050505050612d98565b600085848151811061352c5761352c615c28565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061355757613557615c28565b6020026020010151905061356a816142b9565b9550613577600186615538565b94505050613a01565b600281602001515103613979576000613598826142de565b90506000816000815181106135af576135af615c28565b016020015160f81c905060006135c6600283615c57565b6135d1906002615c79565b905060006135e2848360ff16614302565b905060006135f08a89614302565b905060006135fe8383614338565b905080835114613690576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401611807565b60ff8516600214806136a5575060ff85166003145b15613894578082511461373a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401611807565b61375487602001516001815181106133d1576133d1615c28565b9c5060008d51116137e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401611807565b60018c516137f59190615569565b8814613883576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401611807565b505050505050505050505050612d98565b60ff851615806138a7575060ff85166001145b156138e6576138d387602001516001815181106138c6576138c6615c28565b60200260200101516142b9565b99506138df818a615538565b985061396e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401611807565b505050505050613a01565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401611807565b5080613a0c81615bf0565b9150506130d0565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401611807565b6000808213613b08576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b60006060613b15846143ec565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c18213613d1257506000919050565b680755bf798b4a1bf1e58212613d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401611807565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613fb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611807565b73ffffffffffffffffffffffffffffffffffffffff85163b614030576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611807565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516140599190615c9c565b60006040518083038185875af1925050503d8060008114614096576040519150601f19603f3d011682016040523d82523d6000602084013e61409b565b606091505b50915091506140ab8282866144c2565b979650505050505050565b80516060908067ffffffffffffffff8111156140d4576140d4614eb1565b60405190808252806020026020018201604052801561411957816020015b60408051808201909152606080825260208201528152602001906001900390816140f25790505b50915060005b8181101561419b57604051806040016040528085838151811061414457614144615c28565b6020026020010151815260200161417386848151811061416657614166615c28565b6020026020010151614515565b81525083828151811061418857614188615c28565b602090810291909101015260010161411f565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b838110156141fa578060011b82018184015160001a8060041c8253600f8116600183015350506001016141cc565b509295945050505050565b6060600080600061421585614528565b91945092509050600081600181111561423057614230615650565b14614267576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6142718284615538565b8551146142aa576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fb7856020015184846149c6565b606060208260000151106142d5576142d082614205565b612328565b61232882614a5a565b60606123286142fd83602001516000815181106133d1576133d1615c28565b6141a2565b6060825182106143215750604080516020810190915260008152612328565b612d9883838486516143339190615569565b614a70565b600080825184511061434b57825161434e565b83515b90505b80821080156143d5575082828151811061436d5761436d615c28565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168483815181106143ac576143ac615c28565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156143e557816001019150614351565b5092915050565b6000808211614457576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606083156144d1575081612d98565b8251156144e15782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180791906152f6565b606061232861452383614c48565b614cb5565b6000806000836000015160000361456b576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f81116145905760006001600094509450945050506149bf565b60b781116146a65760006145a5608083615569565b9050808760000151116145e4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214801561465c57507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614693576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600195509350600092506149bf915050565b60bf81116148045760006146bb60b783615569565b9050808760000151116146fa576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361475c576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116147a4576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147ae8184615538565b8951116147e7576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147f2836001615538565b97509550600094506149bf9350505050565b60f7811161486957600061481960c083615569565b905080876000015111614858576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001955093508492506149bf915050565b600061487660f783615569565b9050808760000151116148b5576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614917576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c6037811161495f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6149698184615538565b8951116149a2576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6149ad836001615538565b97509550600194506149bf9350505050565b9193909250565b60608167ffffffffffffffff8111156149e1576149e1614eb1565b6040519080825280601f01601f191660200182016040528015614a0b576020820181803683370190505b5090508115612d98576000614a208486615538565b90506020820160005b84811015614a41578281015182820152602001614a29565b84811115614a50576000858301525b5050509392505050565b60606123288260200151600084600001516149c6565b60608182601f011015614adf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b828284011015614b4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b81830184511015614bb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401611807565b606082158015614bd75760405191506000825260208201604052614c3f565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614c10578051835260209283019201614bf8565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201528151600003614c97576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000614cc585614528565b919450925090506001816001811115614ce057614ce0615650565b14614d17576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451614d238385615538565b14614d5a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081614d715790505093506000835b8651811015614e5f57600080614de46040518060400160405280858c60000151614dc89190615569565b8152602001858c60200151614ddd9190615538565b9052614528565b509150915060405180604001604052808383614e009190615538565b8152602001848b60200151614e159190615538565b815250888581518110614e2a57614e2a615c28565b6020908102919091010152614e40600185615538565b9350614e4c8183615538565b614e569084615538565b92505050614d9e565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461205757600080fd5b67ffffffffffffffff8116811461205757600080fd5b801515811461205757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715614f0357614f03614eb1565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614f5057614f50614eb1565b604052919050565b600082601f830112614f6957600080fd5b813567ffffffffffffffff811115614f8357614f83614eb1565b614fb460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614f09565b818152846020838601011115614fc957600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614fff57600080fd5b863561500a81614e6b565b95506020870135945060408701359350606087013561502881614e8d565b9250608087013561503881614ea3565b915060a087013567ffffffffffffffff81111561505457600080fd5b61506089828a01614f58565b9150509295509295509295565b600060c0828403121561507f57600080fd5b60405160c0810167ffffffffffffffff82821081831117156150a3576150a3614eb1565b8160405282935084358352602085013591506150be82614e6b565b816020840152604085013591506150d482614e6b565b816040840152606085013560608401526080850135608084015260a085013591508082111561510257600080fd5b5061510f85828601614f58565b60a0830152505092915050565b6000806040838503121561512f57600080fd5b823567ffffffffffffffff81111561514657600080fd5b6151528582860161506d565b925050602083013561516381614e6b565b809150509250929050565b60006020828403121561518057600080fd5b8135612d9881614e6b565b600080600080600085870360e08112156151a457600080fd5b863567ffffffffffffffff808211156151bc57600080fd5b6151c88a838b0161506d565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401121561520157600080fd5b60408901955060c089013592508083111561521b57600080fd5b828901925089601f84011261522f57600080fd5b823591508082111561524057600080fd5b508860208260051b840101111561525657600080fd5b959894975092955050506020019190565b60006020828403121561527957600080fd5b5035919050565b60005b8381101561529b578181015183820152602001615283565b838111156129db5750506000910152565b600081518084526152c4816020860160208601615280565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612d9860208301846152ac565b6000806040838503121561531c57600080fd5b82359150602083013561516381614e6b565b60ff8116811461205757600080fd5b6000806000806080858703121561535357600080fd5b843561535e81614e6b565b9350602085013561536e8161532e565b93969395505050506040820135916060013590565b63ffffffff8116811461205757600080fd5b6000602082840312156153a757600080fd5b8135612d9881615383565b6000602082840312156153c457600080fd5b813567ffffffffffffffff8111156153db57600080fd5b6153e78482850161506d565b949350505050565b6000806000806080858703121561540557600080fd5b843561541081614e6b565b9350602085013561542081614e6b565b9250604085013561543081614e6b565b9150606085013561544081615383565b939692955090935050565b60006020828403121561545d57600080fd5b8135612d9881614e8d565b6000806040838503121561547b57600080fd5b50508035926020909101359150565b600080600080600060a086880312156154a257600080fd5b85356154ad81614e6b565b94506020860135935060408601356154c481614e8d565b925060608601356154d481614ea3565b9150608086013567ffffffffffffffff8111156154f057600080fd5b6154fc88828901614f58565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561554b5761554b615509565b500190565b60006020828403121561556257600080fd5b5051919050565b60008282101561557b5761557b615509565b500390565b60006020828403121561559257600080fd5b8151612d9881614e6b565b6000806000606084860312156155b257600080fd5b83516155bd81615383565b60208501519093506155ce81614e8d565b60408501519092506155df81614e6b565b809150509250925092565b6000608082840312156155fc57600080fd5b6040516080810181811067ffffffffffffffff8211171561561f5761561f614eb1565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006020828403121561569157600080fd5b815160038110612d9857600080fd5b600067ffffffffffffffff808411156156bb576156bb614eb1565b8360051b60206156cc818301614f09565b8681529185019181810190368411156156e457600080fd5b865b84811015615718578035868111156156fe5760008081fd5b61570a36828b01614f58565b8452509183019183016156e6565b50979650505050505050565b60006020828403121561573657600080fd5b8151612d9881614ea3565b60006020828403121561575357600080fd5b8151612d9881614e8d565b60006020828403121561577057600080fd5b8151612d9881615383565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b6048820152600082516157cf816049850160208701615280565b919091016049019695505050505050565b600067ffffffffffffffff8083168185168183048111821515161561580757615807615509565b02949350505050565b600067ffffffffffffffff80831681851680830382111561583357615833615509565b01949350505050565b6000806040838503121561584f57600080fd5b825161585a81614e6b565b60208401519092506151638161532e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826158a9576158a961586b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156158fd576158fd615509565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561593c5761593c615509565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561597057615970615509565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156159b7576159b7615509565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156159f2576159f2615509565b60008712925087820587128484161615615a0e57615a0e615509565b87850587128184161615615a2457615a24615509565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03841381151615615a6c57615a6c615509565b827f8000000000000000000000000000000000000000000000000000000000000000038412811615615aa057615aa0615509565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615ade57615ade615509565b500290565b600082615af257615af261586b565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152615b4260c08301846152ac565b98975050505050505050565b600060c08284031215615b6057600080fd5b615b68614ee0565b8251615b7381615383565b81526020830151615b838161532e565b60208201526040830151615b968161532e565b60408201526060830151615ba981615383565b60608201526080830151615bbc81615383565b608082015260a08301516fffffffffffffffffffffffffffffffff81168114615be457600080fd5b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615c2157615c21615509565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff831680615c6a57615c6a61586b565b8060ff84160691505092915050565b600060ff821660ff841680821015615c9357615c93615509565b90039392505050565b60008251615cae818460208701615280565b919091019291505056fea164736f6c634300080f000a"; bytes internal constant disputeGameFactoryCode = - hex"6080604052600436106100e85760003560e01c80636593dc6e1161008a57806396cd97201161005957806396cd972014610313578063bb8aa1fc14610333578063c4d66de814610394578063f2fde38b146103b457600080fd5b80636593dc6e14610293578063715018a6146102c057806382ecf2f6146102d55780638da5cb5b146102e857600080fd5b8063254bd683116100c6578063254bd6831461019c5780634d1975b4146101c957806354fd4d50146101e85780635f0150cb1461023e57600080fd5b806314f6b1a3146100ed5780631b685b9e1461010f5780631e3342401461017c575b600080fd5b3480156100f957600080fd5b5061010d6101083660046110c6565b6103d4565b005b34801561011b57600080fd5b5061015261012a3660046110fd565b60656020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061010d610197366004611118565b61045e565b3480156101a857600080fd5b506101bc6101b7366004611142565b6104aa565b60405161017391906111ef565b3480156101d557600080fd5b506068545b604051908152602001610173565b3480156101f457600080fd5b506102316040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b60405161017391906112ac565b34801561024a57600080fd5b5061025e6102593660046112bf565b6106ee565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff909116602083015201610173565b34801561029f57600080fd5b506101da6102ae3660046110fd565b60666020526000908152604090205481565b3480156102cc57600080fd5b5061010d610741565b6101526102e33660046112bf565b610755565b3480156102f457600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff16610152565b34801561031f57600080fd5b506101da61032e3660046112bf565b6109ef565b34801561033f57600080fd5b5061035361034e366004611346565b610a28565b6040805163ffffffff909416845267ffffffffffffffff909216602084015273ffffffffffffffffffffffffffffffffffffffff1690820152606001610173565b3480156103a057600080fd5b5061010d6103af36600461135f565b610a91565b3480156103c057600080fd5b5061010d6103cf36600461135f565b610c2d565b6103dc610d00565b63ffffffff821660008181526065602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616908117909155905190917fff513d80e2c7fa487608f70a618dfbc0cf415699dc69588c747e8c71566c88de91a35050565b610466610d00565b63ffffffff8216600081815260666020526040808220849055518392917f74d6665c4b26d5596a5aa13d3014e0c06af4d322075a797f87b03cd4c5bc91ca91a35050565b606854606090831015806104bc575081155b6106e7575060408051600583901b8101602001909152825b8381116106e5576000606882815481106104f0576104f061137c565b600091825260209091200154905060e081901c60a082901c67ffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff831663ffffffff891683036106b6576001865101865260008173ffffffffffffffffffffffffffffffffffffffff1663609d33346040518163ffffffff1660e01b8152600401600060405180830381865afa15801561058a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d091908101906113da565b905060008273ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561061f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064391906114a5565b90506040518060a001604052808881526020018781526020018567ffffffffffffffff168152602001828152602001838152508860018a5161068591906114be565b815181106106955761069561137c565b6020026020010181905250888851106106b3575050505050506106e5565b50505b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191506104d49050565b505b9392505050565b60008060006106ff878787876109ef565b60009081526067602052604090205473ffffffffffffffffffffffffffffffffffffffff81169860a09190911c67ffffffffffffffff16975095505050505050565b610749610d00565b6107536000610d81565b565b63ffffffff841660009081526065602052604081205473ffffffffffffffffffffffffffffffffffffffff16806107c5576040517f031c6de400000000000000000000000000000000000000000000000000000000815263ffffffff871660048201526024015b60405180910390fd5b63ffffffff86166000908152606660205260409020543414610813576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006108206001436114be565b40905061088a338783888860405160200161083f9594939291906114fc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905273ffffffffffffffffffffffffffffffffffffffff841690610df8565b92508273ffffffffffffffffffffffffffffffffffffffff16638129fc1c346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156108d457600080fd5b505af11580156108e8573d6000803e3d6000fd5b505050505060006108fb888888886109ef565b60008181526067602052604090205490915015610947576040517f014f6fe5000000000000000000000000000000000000000000000000000000008152600481018290526024016107bc565b60004260a01b60e08a901b178517600083815260676020526040808220839055606880546001810182559083527fa2153420d844928b4421650203c77babc8b33d7f2e7b450e2966db0c220977530183905551919250899163ffffffff8c169173ffffffffffffffffffffffffffffffffffffffff8916917f5b565efe82411da98814f356d0e7bcb8f0219b8d970307c5afb4a6903a8b2e359190a450505050949350505050565b600084848484604051602001610a089493929190611549565b604051602081830303815290604052805190602001209050949350505050565b600080600080600080610a8160688881548110610a4757610a4761137c565b906000526020600020015460e081901c9160a082901c67ffffffffffffffff169173ffffffffffffffffffffffffffffffffffffffff1690565b9199909850909650945050505050565b600054610100900460ff1615808015610ab15750600054600160ff909116105b80610acb5750303b158015610acb575060005460ff166001145b610b57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107bc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610bb557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610bbd610e06565b610bc682610d81565b8015610c2957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b610c35610d00565b73ffffffffffffffffffffffffffffffffffffffff8116610cd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016107bc565b610ce181610d81565b50565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60335473ffffffffffffffffffffffffffffffffffffffff163314610753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107bc565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006106e760008484610ea5565b600054610100900460ff16610e9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b610753610feb565b600060608203516040830351602084035184518060208701018051600283016c5af43d3d93803e606057fd5bf3895289600d8a035278593da1005b363d3d373d3d3d3d610000806062363936013d738160481b1760218a03527f9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff603a8a035272fd6100003d81600a3d39f336602c57343d527f6062820160781b1761ff9e82106059018a03528060f01b8352606c8101604c8a038cf097505086610f715763301164256000526004601cfd5b905285527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08501527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa09092019190915292915050565b600054610100900460ff16611082576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b61075333610d81565b803563ffffffff8116811461109f57600080fd5b919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610ce157600080fd5b600080604083850312156110d957600080fd5b6110e28361108b565b915060208301356110f2816110a4565b809150509250929050565b60006020828403121561110f57600080fd5b6106e78261108b565b6000806040838503121561112b57600080fd5b6111348361108b565b946020939093013593505050565b60008060006060848603121561115757600080fd5b6111608461108b565b95602085013595506040909401359392505050565b60005b83811015611190578181015183820152602001611178565b8381111561119f576000848401525b50505050565b600081518084526111bd816020860160208601611175565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561129e578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001855281518051845287810151888501528681015167ffffffffffffffff16878501526060808201519085015260809081015160a09185018290529061128a818601836111a5565b968901969450505090860190600101611216565b509098975050505050505050565b6020815260006106e760208301846111a5565b600080600080606085870312156112d557600080fd5b6112de8561108b565b935060208501359250604085013567ffffffffffffffff8082111561130257600080fd5b818701915087601f83011261131657600080fd5b81358181111561132557600080fd5b88602082850101111561133757600080fd5b95989497505060200194505050565b60006020828403121561135857600080fd5b5035919050565b60006020828403121561137157600080fd5b81356106e7816110a4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156113ec57600080fd5b815167ffffffffffffffff8082111561140457600080fd5b818401915084601f83011261141857600080fd5b81518181111561142a5761142a6113ab565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611470576114706113ab565b8160405282815287602084870101111561148957600080fd5b61149a836020830160208801611175565b979650505050505050565b6000602082840312156114b757600080fd5b5051919050565b6000828210156114f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500390565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008660601b1681528460148201528360348201528183605483013760009101605401908152949350505050565b63ffffffff8516815283602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101939250505056fea164736f6c634300080f000a"; + hex"6080604052600436106100e85760003560e01c80636593dc6e1161008a57806396cd97201161005957806396cd972014610313578063bb8aa1fc14610333578063c4d66de814610394578063f2fde38b146103b457600080fd5b80636593dc6e14610293578063715018a6146102c057806382ecf2f6146102d55780638da5cb5b146102e857600080fd5b8063254bd683116100c6578063254bd6831461019c5780634d1975b4146101c957806354fd4d50146101e85780635f0150cb1461023e57600080fd5b806314f6b1a3146100ed5780631b685b9e1461010f5780631e3342401461017c575b600080fd5b3480156100f957600080fd5b5061010d6101083660046110c6565b6103d4565b005b34801561011b57600080fd5b5061015261012a3660046110fd565b60656020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061010d610197366004611118565b61045e565b3480156101a857600080fd5b506101bc6101b7366004611142565b6104aa565b60405161017391906111ef565b3480156101d557600080fd5b506068545b604051908152602001610173565b3480156101f457600080fd5b506102316040518060400160405280600c81526020017f312e302e312d626574612e31000000000000000000000000000000000000000081525081565b60405161017391906112ac565b34801561024a57600080fd5b5061025e6102593660046112bf565b6106ee565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff909116602083015201610173565b34801561029f57600080fd5b506101da6102ae3660046110fd565b60666020526000908152604090205481565b3480156102cc57600080fd5b5061010d610741565b6101526102e33660046112bf565b610755565b3480156102f457600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff16610152565b34801561031f57600080fd5b506101da61032e3660046112bf565b6109ef565b34801561033f57600080fd5b5061035361034e366004611346565b610a28565b6040805163ffffffff909416845267ffffffffffffffff909216602084015273ffffffffffffffffffffffffffffffffffffffff1690820152606001610173565b3480156103a057600080fd5b5061010d6103af36600461135f565b610a91565b3480156103c057600080fd5b5061010d6103cf36600461135f565b610c2d565b6103dc610d00565b63ffffffff821660008181526065602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616908117909155905190917fff513d80e2c7fa487608f70a618dfbc0cf415699dc69588c747e8c71566c88de91a35050565b610466610d00565b63ffffffff8216600081815260666020526040808220849055518392917f74d6665c4b26d5596a5aa13d3014e0c06af4d322075a797f87b03cd4c5bc91ca91a35050565b606854606090831015806104bc575081155b6106e7575060408051600583901b8101602001909152825b8381116106e5576000606882815481106104f0576104f061137c565b600091825260209091200154905060e081901c60a082901c67ffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff831663ffffffff891683036106b6576001865101865260008173ffffffffffffffffffffffffffffffffffffffff1663609d33346040518163ffffffff1660e01b8152600401600060405180830381865afa15801561058a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d091908101906113da565b905060008273ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561061f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064391906114a5565b90506040518060a001604052808881526020018781526020018567ffffffffffffffff168152602001828152602001838152508860018a5161068591906114be565b815181106106955761069561137c565b6020026020010181905250888851106106b3575050505050506106e5565b50505b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191506104d49050565b505b9392505050565b60008060006106ff878787876109ef565b60009081526067602052604090205473ffffffffffffffffffffffffffffffffffffffff81169860a09190911c67ffffffffffffffff16975095505050505050565b610749610d00565b6107536000610d81565b565b63ffffffff841660009081526065602052604081205473ffffffffffffffffffffffffffffffffffffffff16806107c5576040517f031c6de400000000000000000000000000000000000000000000000000000000815263ffffffff871660048201526024015b60405180910390fd5b63ffffffff86166000908152606660205260409020543414610813576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006108206001436114be565b40905061088a338783888860405160200161083f9594939291906114fc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905273ffffffffffffffffffffffffffffffffffffffff841690610df8565b92508273ffffffffffffffffffffffffffffffffffffffff16638129fc1c346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156108d457600080fd5b505af11580156108e8573d6000803e3d6000fd5b505050505060006108fb888888886109ef565b60008181526067602052604090205490915015610947576040517f014f6fe5000000000000000000000000000000000000000000000000000000008152600481018290526024016107bc565b60004260a01b60e08a901b178517600083815260676020526040808220839055606880546001810182559083527fa2153420d844928b4421650203c77babc8b33d7f2e7b450e2966db0c220977530183905551919250899163ffffffff8c169173ffffffffffffffffffffffffffffffffffffffff8916917f5b565efe82411da98814f356d0e7bcb8f0219b8d970307c5afb4a6903a8b2e359190a450505050949350505050565b600084848484604051602001610a089493929190611549565b604051602081830303815290604052805190602001209050949350505050565b600080600080600080610a8160688881548110610a4757610a4761137c565b906000526020600020015460e081901c9160a082901c67ffffffffffffffff169173ffffffffffffffffffffffffffffffffffffffff1690565b9199909850909650945050505050565b600054610100900460ff1615808015610ab15750600054600160ff909116105b80610acb5750303b158015610acb575060005460ff166001145b610b57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107bc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610bb557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610bbd610e06565b610bc682610d81565b8015610c2957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b610c35610d00565b73ffffffffffffffffffffffffffffffffffffffff8116610cd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016107bc565b610ce181610d81565b50565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60335473ffffffffffffffffffffffffffffffffffffffff163314610753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107bc565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006106e760008484610ea5565b600054610100900460ff16610e9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b610753610feb565b600060608203516040830351602084035184518060208701018051600283016c5af43d3d93803e606057fd5bf3895289600d8a035278593da1005b363d3d373d3d3d3d610000806062363936013d738160481b1760218a03527f9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff603a8a035272fd6100003d81600a3d39f336602c57343d527f6062820160781b1761ff9e82106059018a03528060f01b8352606c8101604c8a038cf097505086610f715763301164256000526004601cfd5b905285527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08501527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa09092019190915292915050565b600054610100900460ff16611082576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b61075333610d81565b803563ffffffff8116811461109f57600080fd5b919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610ce157600080fd5b600080604083850312156110d957600080fd5b6110e28361108b565b915060208301356110f2816110a4565b809150509250929050565b60006020828403121561110f57600080fd5b6106e78261108b565b6000806040838503121561112b57600080fd5b6111348361108b565b946020939093013593505050565b60008060006060848603121561115757600080fd5b6111608461108b565b95602085013595506040909401359392505050565b60005b83811015611190578181015183820152602001611178565b8381111561119f576000848401525b50505050565b600081518084526111bd816020860160208601611175565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561129e578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001855281518051845287810151888501528681015167ffffffffffffffff16878501526060808201519085015260809081015160a09185018290529061128a818601836111a5565b968901969450505090860190600101611216565b509098975050505050505050565b6020815260006106e760208301846111a5565b600080600080606085870312156112d557600080fd5b6112de8561108b565b935060208501359250604085013567ffffffffffffffff8082111561130257600080fd5b818701915087601f83011261131657600080fd5b81358181111561132557600080fd5b88602082850101111561133757600080fd5b95989497505060200194505050565b60006020828403121561135857600080fd5b5035919050565b60006020828403121561137157600080fd5b81356106e7816110a4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156113ec57600080fd5b815167ffffffffffffffff8082111561140457600080fd5b818401915084601f83011261141857600080fd5b81518181111561142a5761142a6113ab565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611470576114706113ab565b8160405282815287602084870101111561148957600080fd5b61149a836020830160208801611175565b979650505050505050565b6000602082840312156114b757600080fd5b5051919050565b6000828210156114f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500390565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008660601b1681528460148201528360348201528183605483013760009101605401908152949350505050565b63ffffffff8516815283602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101939250505056fea164736f6c634300080f000a"; bytes internal constant delayedWETHCode = hex"6080604052600436106101845760003560e01c8063715018a6116100d6578063a9059cbb1161007f578063dd62ed3e11610059578063dd62ed3e1461051c578063f2fde38b14610554578063f3fef3a31461057457610193565b8063a9059cbb146104a8578063cd47bde1146104c8578063d0e30db01461019357610193565b80638da5cb5b116100b05780638da5cb5b1461041757806395d89b4114610442578063977a5ec51461048857610193565b8063715018a61461039057806379502c55146103a55780637eee288d146103f757610193565b80632e1a7d4d1161013857806354fd4d501161011257806354fd4d50146102e75780636a42b8f81461033057806370a082311461036357610193565b80632e1a7d4d14610280578063313ce567146102a0578063485cc955146102c757610193565b80630ca35682116101695780630ca356821461022357806318160ddd1461024357806323b872dd1461026057610193565b806306fdde031461019b578063095ea7b3146101f357610193565b3661019357610191610594565b005b610191610594565b3480156101a757600080fd5b5060408051808201909152600d81527f577261707065642045746865720000000000000000000000000000000000000060208201525b6040516101ea91906113fd565b60405180910390f35b3480156101ff57600080fd5b5061021361020e366004611492565b6105ef565b60405190151581526020016101ea565b34801561022f57600080fd5b5061019161023e3660046114be565b610668565b34801561024f57600080fd5b50475b6040519081526020016101ea565b34801561026c57600080fd5b5061021361027b3660046114d7565b6107b9565b34801561028c57600080fd5b5061019161029b3660046114be565b6109d0565b3480156102ac57600080fd5b506102b5601281565b60405160ff90911681526020016101ea565b3480156102d357600080fd5b506101916102e2366004611518565b6109dd565b3480156102f357600080fd5b506101dd6040518060400160405280600a81526020017f312e312e302d72632e310000000000000000000000000000000000000000000081525081565b34801561033c57600080fd5b507f0000000000000000000000000000000000000000000000000000000000093a80610252565b34801561036f57600080fd5b5061025261037e366004611551565b60656020526000908152604090205481565b34801561039c57600080fd5b50610191610bb9565b3480156103b157600080fd5b506068546103d29073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ea565b34801561040357600080fd5b50610191610412366004611492565b610bcd565b34801561042357600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff166103d2565b34801561044e57600080fd5b5060408051808201909152600481527f574554480000000000000000000000000000000000000000000000000000000060208201526101dd565b34801561049457600080fd5b506101916104a3366004611492565b610c21565b3480156104b457600080fd5b506102136104c3366004611492565b610d0e565b3480156104d457600080fd5b506105076104e3366004611518565b60676020908152600092835260408084209091529082529020805460019091015482565b604080519283526020830191909152016101ea565b34801561052857600080fd5b50610252610537366004611518565b606660209081526000928352604080842090915290825290205481565b34801561056057600080fd5b5061019161056f366004611551565b610d22565b34801561058057600080fd5b5061019161058f366004611492565b610dd6565b33600090815260656020526040812080543492906105b390849061159d565b909155505060405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b33600081815260666020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106579086815260200190565b60405180910390a350600192915050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064015b60405180910390fd5b60004782106106fd57476106ff565b815b604051909150600090339083908381818185875af1925050503d8060008114610744576040519150601f19603f3d011682016040523d82523d6000602084013e610749565b606091505b50509050806107b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f44656c61796564574554483a207265636f766572206661696c6564000000000060448201526064016106e5565b505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152606560205260408120548211156107eb57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610861575073ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156108e95773ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091529020548211156108a357600080fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152606660209081526040808320338452909152812080548492906108e39084906115b5565b90915550505b73ffffffffffffffffffffffffffffffffffffffff84166000908152606560205260408120805484929061091e9084906115b5565b909155505073ffffffffffffffffffffffffffffffffffffffff83166000908152606560205260408120805484929061095890849061159d565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109be91815260200190565b60405180910390a35060019392505050565b6109da3382610dd6565b50565b600054610100900460ff16158080156109fd5750600054600160ff909116105b80610a175750303b158015610a17575060005460ff166001145b610aa3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016106e5565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610b0157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b09611120565b610b12836111bf565b606880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617905580156107b457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b610bc1611236565b610bcb60006111bf565b565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120426001820155805490918391839190610c1790849061159d565b9091555050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610ca2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064016106e5565b73ffffffffffffffffffffffffffffffffffffffff821660008181526066602090815260408083203380855290835292819020859055518481529192917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a35050565b6000610d1b3384846107b9565b9392505050565b610d2a611236565b73ffffffffffffffffffffffffffffffffffffffff8116610dcd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016106e5565b6109da816111bf565b606860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6791906115cc565b15610ece576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f44656c61796564574554483a20636f6e7472616374206973207061757365640060448201526064016106e5565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290208054821115610f8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f44656c61796564574554483a20696e73756666696369656e7420756e6c6f636b60448201527f6564207769746864726177616c0000000000000000000000000000000000000060648201526084016106e5565b6000816001015411611022576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f44656c61796564574554483a207769746864726177616c206e6f7420756e6c6f60448201527f636b65640000000000000000000000000000000000000000000000000000000060648201526084016106e5565b427f0000000000000000000000000000000000000000000000000000000000093a808260010154611053919061159d565b11156110e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f44656c61796564574554483a207769746864726177616c2064656c6179206e6f60448201527f74206d657400000000000000000000000000000000000000000000000000000060648201526084016106e5565b818160000160008282546110f591906115b5565b909155506107b49050826112b7565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff166111b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106e5565b610bcb61135d565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610bcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106e5565b336000908152606560205260409020548111156112d357600080fd5b33600090815260656020526040812080548392906112f29084906115b5565b9091555050604051339082156108fc029083906000818181858888f19350505050158015611324573d6000803e3d6000fd5b5060405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a250565b600054610100900460ff166113f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106e5565b610bcb336111bf565b600060208083528351808285015260005b8181101561142a5785810183015185820160400152820161140e565b8181111561143c576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146109da57600080fd5b600080604083850312156114a557600080fd5b82356114b081611470565b946020939093013593505050565b6000602082840312156114d057600080fd5b5035919050565b6000806000606084860312156114ec57600080fd5b83356114f781611470565b9250602084013561150781611470565b929592945050506040919091013590565b6000806040838503121561152b57600080fd5b823561153681611470565b9150602083013561154681611470565b809150509250929050565b60006020828403121561156357600080fd5b8135610d1b81611470565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115b0576115b061156e565b500190565b6000828210156115c7576115c761156e565b500390565b6000602082840312156115de57600080fd5b81518015158114610d1b57600080fdfea164736f6c634300080f000a"; bytes internal constant preimageOracleCode = @@ -69,7 +69,7 @@ contract DeploymentSummaryFaultProofsCode { bytes internal constant mipsCode = hex"608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d50146100465780637dc0d1d014610098578063e14ced32146100dc575b600080fd5b6100826040518060400160405280600a81526020017f312e312e302d72632e310000000000000000000000000000000000000000000081525081565b60405161008f91906121ee565b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000373d916d11cce55b548f7051002e76bcfbd7a85d16815260200161008f565b6100ef6100ea3660046122a3565b6100fd565b60405190815260200161008f565b6000610107612164565b6080811461011457600080fd5b6040516106001461012457600080fd5b6084871461013157600080fd5b6101a4851461013f57600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a0819052605a89013590911c6101c05260628801906101e09060018111156101f5576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b506020810181511461020657600080fd5b60200160005b602081101561023057823560e01c825260049092019160209091019060010161020c565b5050508061012001511561024e576102466103a6565b91505061039d565b6101408101805160010167ffffffffffffffff16905260006101a49050600080600061028385606001518660000151866104f7565b9250925092508163ffffffff1660001480156102a557508063ffffffff16600c145b156102bf576102b387610521565b9550505050505061039d565b6000610339866040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b6101608701518751919250610356918391906105248888886108f9565b8652805163ffffffff9081166060808901919091526020830151821660808901526040830151821660a08901528201511660c08701526103946103a6565b96505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a8401526000926102009290916062830191906001811115610453576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b60005b602081101561047a57601c8601518452602090950194600490930192600101610456565b506000835283830384a060009450806001811461049a57600395506104c2565b8280156104b257600181146104bb57600296506104c0565b600096506104c0565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b6000806000610507858786610cdf565b925050603f601a83901c8116915082165b93509350939050565b600061052b612164565b608090506000806000806105628561016001516040810151608082015160a083015160c084015160e0909401519294919390929091565b509350935093509350600080610ffa63ffffffff168663ffffffff16036105a75761059285858960e00151610d93565b63ffffffff1660e08a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03363ffffffff8716016105e05763400000009150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefe863ffffffff8716016106165760019150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef6a63ffffffff87160161066a57600161012088015260ff851661010088015261065d6103a6565b9998505050505050505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05d63ffffffff8716016107665760006040518061012001604052808763ffffffff1681526020018663ffffffff1681526020018563ffffffff16815260200189602001518152602001896040015163ffffffff1681526020018b81526020017f000000000000000000000000373d916d11cce55b548f7051002e76bcfbd7a85d73ffffffffffffffffffffffffffffffffffffffff1681526020016107386101a4600160ff16610380020190565b81528951602090910152905061074d81610e27565b8b5263ffffffff1660408b015290935091506108089050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05c63ffffffff8716016107cb57602087015160408801516107b1918791879187916105248d5161109f565b63ffffffff1660408b015260208a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff02963ffffffff871601610808576108028585611195565b90925090505b6000610882886040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b61016089015163ffffffff85811660408084019190915285821660e0909301929092526020830180518083168086526004909101831682526060808e01919091529051821660808d015291830151811660a08c0152908201511660c08a015290506108eb6103a6565b9a9950505050505050505050565b84600263ffffffff8416148061091557508263ffffffff166003145b156109675760006002856303ffffff1663ffffffff16901b896020015163f00000001617905061096189898663ffffffff1660021461095557601f610958565b60005b60ff168461124a565b50610cd4565b600080601f601087901c8116908a90601589901c166020811061098c5761098c612317565b602002015192508063ffffffff871615806109ad57508663ffffffff16601c145b156109df578a8263ffffffff16602081106109ca576109ca612317565b6020020151925050601f600b88901c16610a96565b60208763ffffffff161015610a41578663ffffffff16600c1480610a0957508663ffffffff16600d145b80610a1a57508663ffffffff16600e145b15610a2b578761ffff169250610a96565b610a3a8861ffff166010611322565b9250610a96565b60288763ffffffff16101580610a5d57508663ffffffff166022145b80610a6e57508663ffffffff166026145b15610a96578a8263ffffffff1660208110610a8b57610a8b612317565b602002015192508190505b60048763ffffffff1610158015610ab3575060088763ffffffff16105b80610ac457508663ffffffff166001145b15610ae057610ad78c8c898b8689611395565b50505050610cd4565b63ffffffff6000602089831610610b4557610b008a61ffff166010611322565b9095019463fffffffc8616610b168d828e610cdf565b915060288a63ffffffff1610158015610b3657508963ffffffff16603014155b15610b4357809250600093505b505b6000610b558b8b8b8a8a87611583565b63ffffffff1690508963ffffffff166000148015610b7a575060088963ffffffff1610155b8015610b8c5750601c8963ffffffff16105b15610c54578863ffffffff1660081480610bac57508863ffffffff166009145b15610bdf57610bd38f8f8b63ffffffff16600814610bca5786610bcd565b60005b8a61124a565b50505050505050610cd4565b8863ffffffff16600a03610c0157610bd38f8f868a63ffffffff8b1615611ca0565b8863ffffffff16600b03610c2457610bd38f8f868a63ffffffff8b161515611ca0565b60108963ffffffff1610158015610c415750601c8963ffffffff16105b15610c5457610bd38f8f8b8a8a89611d70565b8963ffffffff166038148015610c6f575063ffffffff851615155b15610c9f5760018e8663ffffffff1660208110610c8e57610c8e612317565b63ffffffff90921660209290920201525b8263ffffffff1663ffffffff14610cbe57610cbb838d83612029565b97505b610ccc8f8f86846001611ca0565b505050505050505b979650505050505050565b6000610cea826120cb565b6003831615610cf857600080fd5b6020820191358360051c8160005b601b811015610d5e5760208601953583821c6001168015610d2e5760018114610d4357610d54565b60008481526020839052604090209350610d54565b600082815260208590526040902093505b5050600101610d06565b50868114610d7457630badf00d60005260206000fd5b5050601f93909316601c0360031b9290921c63ffffffff169392505050565b6000808284610fff811615610dad57610fff811661100003015b8663ffffffff16600003610e195784935090810190636000000063ffffffff83161180610de557508463ffffffff168263ffffffff16105b80610dfb57508563ffffffff168163ffffffff16105b15610e14575063ffffffff925060169150839050610518565b610e1d565b8693505b5093509350939050565b6101008101516080820151825160009283929163ffffffff161561109857845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb01611052576000610e93866101000151876020015163fffffffc168860e00151610cdf565b606087015190915060001a600103610f1557610f0f86606001518760a0015160408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b60608701525b6000808760c0015173ffffffffffffffffffffffffffffffffffffffff1663e03110e189606001518a608001516040518363ffffffff1660e01b8152600401610f6e92919091825263ffffffff16602082015260400190565b6040805180830381865afa158015610f8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fae9190612346565b60208a015160408b01519294509092509060038216600481900384811015610fd4578094505b5083821015610fe1578193505b8460088502610100031c9450846008828660040303021b9450600180600883600403021b036001806008878560040303021b0391508119811690508581198816179650505061103f8a6020015163fffffffc168b60e0015187612029565b9298505050938601939250611098915050565b845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0161108c5784604001519350611098565b63ffffffff9350600992505b9193509193565b600080858563ffffffff8b16600114806110bf575063ffffffff8b166002145b806110d0575063ffffffff8b166004145b156110dd57889350611187565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8c160161117b57600061111d868c63fffffffc1689610cdf565b90508860038c166004038b81101561113357809b505b8b965086900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193880293841b0116911b17915060009050611187565b63ffffffff9350600992505b975097509750979350505050565b60008063ffffffff83166003036112385763ffffffff841615806111bf575063ffffffff84166005145b806111d0575063ffffffff84166003145b156111de5760009150611243565b63ffffffff8416600114806111f9575063ffffffff84166002145b8061120a575063ffffffff84166006145b8061121b575063ffffffff84166004145b156112295760019150611243565b5063ffffffff90506009611243565b5063ffffffff905060165b9250929050565b836000015160040163ffffffff16846020015163ffffffff16146112cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b835160208501805163ffffffff908116875283811690915283161561131b5780600801848463ffffffff166020811061130a5761130a612317565b63ffffffff90921660209290920201525b5050505050565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b018261137f576000611381565b815b90861663ffffffff16179250505092915050565b6000866000015160040163ffffffff16876020015163ffffffff1614611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f7400000000000000000000000060448201526064016112c6565b8463ffffffff166004148061143257508463ffffffff166005145b156114a9576000868463ffffffff166020811061145157611451612317565b602002015190508063ffffffff168363ffffffff1614801561147957508563ffffffff166004145b806114a157508063ffffffff168363ffffffff16141580156114a157508563ffffffff166005145b915050611526565b8463ffffffff166006036114c65760008260030b13159050611526565b8463ffffffff166007036114e25760008260030b139050611526565b8463ffffffff1660010361152657601f601085901c16600081900361150b5760008360030b1291505b8063ffffffff166001036115245760008360030b121591505b505b8651602088015163ffffffff168852811561156757600261154c8661ffff166010611322565b63ffffffff90811690911b8201600401166020890152611579565b60208801805160040163ffffffff1690525b5050505050505050565b600063ffffffff861615806115b0575060088663ffffffff16101580156115b05750600f8663ffffffff16105b156119b05785600881146115f357600981146115fc57600a811461160557600b811461160e57600c811461161757600d811461162057600e81146116295761162e565b6020955061162e565b6021955061162e565b602a955061162e565b602b955061162e565b6024955061162e565b6025955061162e565b602695505b508463ffffffff16600003611653575063ffffffff8216601f600688901c161b611c96565b8463ffffffff16600203611677575063ffffffff8216601f600688901c161c611c96565b8463ffffffff166003036116ab57601f600688901c166116a363ffffffff8516821c6020839003611322565b915050611c96565b8463ffffffff166004036116cb575063ffffffff8216601f84161b611c96565b8463ffffffff166006036116eb575063ffffffff8216601f84161c611c96565b8463ffffffff1660070361171357601f84166116a363ffffffff8516821c6020839003611322565b8463ffffffff16600803611728575082611c96565b8463ffffffff1660090361173d575082611c96565b8463ffffffff16600a03611752575082611c96565b8463ffffffff16600b03611767575082611c96565b8463ffffffff16600c0361177c575082611c96565b8463ffffffff16600f03611791575082611c96565b8463ffffffff166010036117a6575082611c96565b8463ffffffff166011036117bb575082611c96565b8463ffffffff166012036117d0575082611c96565b8463ffffffff166013036117e5575082611c96565b8463ffffffff166018036117fa575082611c96565b8463ffffffff1660190361180f575082611c96565b8463ffffffff16601a03611824575082611c96565b8463ffffffff16601b03611839575082611c96565b8463ffffffff166020036118505750828201611c96565b8463ffffffff166021036118675750828201611c96565b8463ffffffff1660220361187e5750818303611c96565b8463ffffffff166023036118955750818303611c96565b8463ffffffff166024036118ac5750828216611c96565b8463ffffffff166025036118c35750828217611c96565b8463ffffffff166026036118da5750828218611c96565b8463ffffffff166027036118f2575082821719611c96565b8463ffffffff16602a03611921578260030b8460030b12611914576000611917565b60015b60ff169050611c96565b8463ffffffff16602b03611949578263ffffffff168463ffffffff1610611914576000611917565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e0000000000000000000000000060448201526064016112c6565b611949565b8563ffffffff16601c03611a30578463ffffffff166002036119d55750828202611c96565b8463ffffffff16602014806119f057508463ffffffff166021145b156119ab578463ffffffff16602003611a07579219925b60005b6380000000851615611a29576401fffffffe600195861b169401611a0a565b9050611c96565b8563ffffffff16600f03611a51575065ffffffff0000601083901b16611c96565b8563ffffffff16602003611a8557611a298460031660080260180363ffffffff168363ffffffff16901c60ff166008611322565b8563ffffffff16602103611aba57611a298460021660080260100363ffffffff168363ffffffff16901c61ffff166010611322565b8563ffffffff16602203611ae8575063ffffffff60086003851602811681811b198416918316901b17611c96565b8563ffffffff16602303611afd575080611c96565b8563ffffffff16602403611b2e578360031660080260180363ffffffff168263ffffffff16901c60ff169050611c96565b8563ffffffff16602503611b60578360021660080260100363ffffffff168263ffffffff16901c61ffff169050611c96565b8563ffffffff16602603611b91575063ffffffff60086003851602601803811681811c198416918316901c17611c96565b8563ffffffff16602803611bc6575060ff63ffffffff60086003861602601803811682811b9091188316918416901b17611c96565b8563ffffffff16602903611bfc575061ffff63ffffffff60086002861602601003811682811b9091188316918416901b17611c96565b8563ffffffff16602a03611c2a575063ffffffff60086003851602811681811c198316918416901c17611c96565b8563ffffffff16602b03611c3f575081611c96565b8563ffffffff16602e03611c70575063ffffffff60086003851602601803811681811b198316918416901b17611c96565b8563ffffffff16603003611c85575080611c96565b8563ffffffff166038036119495750815b9695505050505050565b60208363ffffffff1610611d10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c696420726567697374657200000000000000000000000000000000000060448201526064016112c6565b63ffffffff831615801590611d225750805b15611d515781848463ffffffff1660208110611d4057611d40612317565b63ffffffff90921660209290920201525b5050505060208101805163ffffffff8082169093526004019091169052565b60008463ffffffff16601003611d8b57506060860151611fd1565b8463ffffffff16601103611daa5763ffffffff84166060880152611fd1565b8463ffffffff16601203611dc357506040860151611fd1565b8463ffffffff16601303611de25763ffffffff84166040880152611fd1565b8463ffffffff16601803611e165763ffffffff600385810b9085900b02602081901c821660608a0152166040880152611fd1565b8463ffffffff16601903611e475763ffffffff84811681851602602081901c821660608a0152166040880152611fd1565b8463ffffffff16601a03611f0a578260030b600003611ec2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8260030b8460030b81611ed757611ed761236a565b0763ffffffff166060880152600383810b9085900b81611ef957611ef961236a565b0563ffffffff166040880152611fd1565b8463ffffffff16601b03611fd1578263ffffffff16600003611f88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8263ffffffff168463ffffffff1681611fa357611fa361236a565b0663ffffffff908116606089015283811690851681611fc457611fc461236a565b0463ffffffff1660408801525b63ffffffff8216156120075780868363ffffffff1660208110611ff657611ff6612317565b63ffffffff90921660209290920201525b50505060208401805163ffffffff808216909652600401909416909352505050565b6000612034836120cb565b600384161561204257600080fd5b6020830192601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b8110156120c05760208601953582821c600116801561209057600181146120a5576120b6565b600085815260208390526040902094506120b6565b600082815260208690526040902094505b5050600101612068565b509095945050505050565b366103808201811015612160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f617461000000000000000000000000000000000000000000000000000000000060648201526084016112c6565b5050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915261016081016121ca6121cf565b905290565b6040518061040001604052806020906020820280368337509192915050565b600060208083528351808285015260005b8181101561221b578581018301518582016040015282016121ff565b8181111561222d576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60008083601f84011261227357600080fd5b50813567ffffffffffffffff81111561228b57600080fd5b60208301915083602082850101111561124357600080fd5b6000806000806000606086880312156122bb57600080fd5b853567ffffffffffffffff808211156122d357600080fd5b6122df89838a01612261565b909750955060208801359150808211156122f857600080fd5b5061230588828901612261565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561235957600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a"; bytes internal constant anchorStateRegistryCode = - hex"608060405234801561001057600080fd5b506004361061007d5760003560e01c80635e05fbd01161005b5780635e05fbd01461012a5780637258a8071461013d578063838c2d1e14610179578063f2b4e6171461018157600080fd5b806317cf21a91461008257806335e80ab31461009757806354fd4d50146100e1575b600080fd5b610095610090366004610b4c565b6101a7565b005b6002546100b79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61011d6040518060400160405280600a81526020017f322e302e302d72632e310000000000000000000000000000000000000000000081525081565b6040516100d89190610bea565b610095610138366004610cc6565b61061c565b61016461014b366004610df0565b6001602081905260009182526040909120805491015482565b604080519283526020830191909152016100d8565b610095610853565b7f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d6100b7565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610214573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102389190610e0d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461029c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156102ec573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526103329190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161039793929190610efb565b6040805180830381865afa1580156103b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d79190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043f576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561048c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b09190610f9f565b60028111156104c1576104c1610f70565b146104f8576040517f8f8af25f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806105788773ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610551573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105759190610fc0565b90565b81526020018673ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ec9190610fc0565b905263ffffffff909416600090815260016020818152604090922086518155959091015194019390935550505050565b600054610100900460ff161580801561063c5750600054600160ff909116105b806106565750303b158015610656575060005460ff166001145b6106e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561074457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60005b83518110156107aa57600084828151811061076457610764610fd9565b60209081029190910181015180820151905163ffffffff1660009081526001808452604090912082518155919092015191015550806107a281611008565b915050610747565b50600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055801561084e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600033905060008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108a8573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526108ee9190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161095393929190610efb565b6040805180830381865afa15801561096f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109939190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109fb576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160008563ffffffff1663ffffffff168152602001908152602001600020600101548573ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8d9190610fc0565b11610a99575050505050565b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ae6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0a9190610f9f565b6002811115610b1b57610b1b610f70565b146104f8575050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4957600080fd5b50565b600060208284031215610b5e57600080fd5b8135610b6981610b27565b9392505050565b60005b83811015610b8b578181015183820152602001610b73565b83811115610b9a576000848401525b50505050565b60008151808452610bb8816020860160208601610b70565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610b696020830184610ba0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610c4f57610c4f610bfd565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610c9c57610c9c610bfd565b604052919050565b63ffffffff81168114610b4957600080fd5b8035610cc181610b27565b919050565b6000806040808486031215610cda57600080fd5b833567ffffffffffffffff80821115610cf257600080fd5b818601915086601f830112610d0657600080fd5b8135602082821115610d1a57610d1a610bfd565b610d28818360051b01610c55565b8281528181019350606092830285018201928a841115610d4757600080fd5b948201945b83861015610dd457858b0381811215610d655760008081fd5b610d6d610c2c565b8735610d7881610ca4565b81527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201891315610daa5760008081fd5b610db2610c2c565b8886013581528989013586820152818601528652509485019493820193610d4c565b509650610de2888201610cb6565b955050505050509250929050565b600060208284031215610e0257600080fd5b8135610b6981610ca4565b600060208284031215610e1f57600080fd5b8151610b6981610b27565b600080600060608486031215610e3f57600080fd5b8351610e4a81610ca4565b60208501516040860151919450925067ffffffffffffffff80821115610e6f57600080fd5b818601915086601f830112610e8357600080fd5b815181811115610e9557610e95610bfd565b610ec660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610c55565b9150808252876020828501011115610edd57600080fd5b610eee816020840160208601610b70565b5080925050509250925092565b63ffffffff84168152826020820152606060408201526000610f206060830184610ba0565b95945050505050565b60008060408385031215610f3c57600080fd5b8251610f4781610b27565b602084015190925067ffffffffffffffff81168114610f6557600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060208284031215610fb157600080fd5b815160038110610b6957600080fd5b600060208284031215610fd257600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611060577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea164736f6c634300080f000a"; + hex"608060405234801561001057600080fd5b506004361061007d5760003560e01c80635e05fbd01161005b5780635e05fbd01461012a5780637258a8071461013d578063838c2d1e14610179578063f2b4e6171461018157600080fd5b806317cf21a91461008257806335e80ab31461009757806354fd4d50146100e1575b600080fd5b610095610090366004610b4c565b6101a7565b005b6002546100b79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61011d6040518060400160405280600c81526020017f322e302e312d626574612e31000000000000000000000000000000000000000081525081565b6040516100d89190610bea565b610095610138366004610cc6565b61061c565b61016461014b366004610df0565b6001602081905260009182526040909120805491015482565b604080519283526020830191909152016100d8565b610095610853565b7f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d6100b7565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610214573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102389190610e0d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461029c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156102ec573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526103329190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161039793929190610efb565b6040805180830381865afa1580156103b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d79190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043f576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561048c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b09190610f9f565b60028111156104c1576104c1610f70565b146104f8576040517f8f8af25f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806105788773ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610551573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105759190610fc0565b90565b81526020018673ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ec9190610fc0565b905263ffffffff909416600090815260016020818152604090922086518155959091015194019390935550505050565b600054610100900460ff161580801561063c5750600054600160ff909116105b806106565750303b158015610656575060005460ff166001145b6106e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561074457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60005b83518110156107aa57600084828151811061076457610764610fd9565b60209081029190910181015180820151905163ffffffff1660009081526001808452604090912082518155919092015191015550806107a281611008565b915050610747565b50600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055801561084e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600033905060008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108a8573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526108ee9190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161095393929190610efb565b6040805180830381865afa15801561096f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109939190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109fb576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160008563ffffffff1663ffffffff168152602001908152602001600020600101548573ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8d9190610fc0565b11610a99575050505050565b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ae6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0a9190610f9f565b6002811115610b1b57610b1b610f70565b146104f8575050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4957600080fd5b50565b600060208284031215610b5e57600080fd5b8135610b6981610b27565b9392505050565b60005b83811015610b8b578181015183820152602001610b73565b83811115610b9a576000848401525b50505050565b60008151808452610bb8816020860160208601610b70565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610b696020830184610ba0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610c4f57610c4f610bfd565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610c9c57610c9c610bfd565b604052919050565b63ffffffff81168114610b4957600080fd5b8035610cc181610b27565b919050565b6000806040808486031215610cda57600080fd5b833567ffffffffffffffff80821115610cf257600080fd5b818601915086601f830112610d0657600080fd5b8135602082821115610d1a57610d1a610bfd565b610d28818360051b01610c55565b8281528181019350606092830285018201928a841115610d4757600080fd5b948201945b83861015610dd457858b0381811215610d655760008081fd5b610d6d610c2c565b8735610d7881610ca4565b81527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201891315610daa5760008081fd5b610db2610c2c565b8886013581528989013586820152818601528652509485019493820193610d4c565b509650610de2888201610cb6565b955050505050509250929050565b600060208284031215610e0257600080fd5b8135610b6981610ca4565b600060208284031215610e1f57600080fd5b8151610b6981610b27565b600080600060608486031215610e3f57600080fd5b8351610e4a81610ca4565b60208501516040860151919450925067ffffffffffffffff80821115610e6f57600080fd5b818601915086601f830112610e8357600080fd5b815181811115610e9557610e95610bfd565b610ec660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610c55565b9150808252876020828501011115610edd57600080fd5b610eee816020840160208601610b70565b5080925050509250925092565b63ffffffff84168152826020820152606060408201526000610f206060830184610ba0565b95945050505050565b60008060408385031215610f3c57600080fd5b8251610f4781610b27565b602084015190925067ffffffffffffffff81168114610f6557600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060208284031215610fb157600080fd5b815160038110610b6957600080fd5b600060208284031215610fd257600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611060577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea164736f6c634300080f000a"; bytes internal constant acc33Code = hex"6080604052600436106102f25760003560e01c806370872aa51161018f578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b18578063fa315aa914610b3c578063fe2bbeb214610b6f57600080fd5b8063ec5e630814610a95578063eff0f59214610ac8578063f8f43ff614610af857600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a0f578063d8cc1a3c14610a42578063dabd396d14610a6257600080fd5b8063c6f0308c14610937578063cf09e0d0146109c1578063d5d44d80146109e257600080fd5b80638d450a9511610143578063bcef3b551161011d578063bcef3b55146108b7578063bd8da956146108f7578063c395e1ca1461091757600080fd5b80638d450a9514610777578063a445ece6146107aa578063bbdc02db1461087657600080fd5b80638129fc1c116101745780638129fc1c1461071a5780638980e0cc146107225780638b85902b1461073757600080fd5b806370872aa5146106f25780637b0f0adc1461070757600080fd5b80633fc8cef3116102485780635c0cba33116101fc5780636361506d116101d65780636361506d1461066c5780636b6716c0146106ac5780636f034409146106df57600080fd5b80635c0cba3314610604578063609d33341461063757806360e274641461064c57600080fd5b806354fd4d501161022d57806354fd4d501461055e57806357da950e146105b45780635a5fa2d9146105e457600080fd5b80633fc8cef314610518578063472777c61461054b57600080fd5b80632810e1d6116102aa57806337b1b2291161028457806337b1b229146104655780633a768463146104a55780633e3ac912146104d857600080fd5b80632810e1d6146103de5780632ad69aeb146103f357806330dbe5701461041357600080fd5b806319effeb4116102db57806319effeb414610339578063200d2ed21461038457806325fc2ace146103bf57600080fd5b806301935130146102f757806303c2924d14610319575b600080fd5b34801561030357600080fd5b506103176103123660046154e2565b610b9f565b005b34801561032557600080fd5b5061031761033436600461553d565b610ec0565b34801561034557600080fd5b506000546103669068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561039057600080fd5b506000546103b290700100000000000000000000000000000000900460ff1681565b60405161037b919061558e565b3480156103cb57600080fd5b506008545b60405190815260200161037b565b3480156103ea57600080fd5b506103b2611566565b3480156103ff57600080fd5b506103d061040e36600461553d565b61180b565b34801561041f57600080fd5b506001546104409073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161037b565b34801561047157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610440565b3480156104b157600080fd5b507f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe7806610440565b3480156104e457600080fd5b50600054610508907201000000000000000000000000000000000000900460ff1681565b604051901515815260200161037b565b34801561052457600080fd5b507f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92610440565b6103176105593660046155cf565b611841565b34801561056a57600080fd5b506105a76040518060400160405280600a81526020017f312e332e302d72632e310000000000000000000000000000000000000000000081525081565b60405161037b9190615666565b3480156105c057600080fd5b506008546009546105cf919082565b6040805192835260208301919091520161037b565b3480156105f057600080fd5b506103d06105ff366004615679565b611853565b34801561061057600080fd5b507f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e610440565b34801561064357600080fd5b506105a761188d565b34801561065857600080fd5b506103176106673660046156b7565b61189b565b34801561067857600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103d0565b3480156106b857600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610366565b6103176106ed3660046156e9565b611a42565b3480156106fe57600080fd5b506009546103d0565b6103176107153660046155cf565b61251b565b610317612528565b34801561072e57600080fd5b506002546103d0565b34801561074357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103d0565b34801561078357600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103d0565b3480156107b657600080fd5b506108226107c5366004615679565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff16606082015260800161037b565b34801561088257600080fd5b5060405163ffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260200161037b565b3480156108c357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103d0565b34801561090357600080fd5b50610366610912366004615679565b612a81565b34801561092357600080fd5b506103d0610932366004615728565b612c60565b34801561094357600080fd5b50610957610952366004615679565b612e43565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e00161037b565b3480156109cd57600080fd5b506000546103669067ffffffffffffffff1681565b3480156109ee57600080fd5b506103d06109fd3660046156b7565b60036020526000908152604090205481565b348015610a1b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000003856103d0565b348015610a4e57600080fd5b50610317610a5d36600461575a565b612eda565b348015610a6e57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b0610366565b348015610aa157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000046103d0565b348015610ad457600080fd5b50610508610ae3366004615679565b60046020526000908152604090205460ff1681565b348015610b0457600080fd5b50610317610b133660046155cf565b613509565b348015610b2457600080fd5b50610b2d6139c6565b60405161037b939291906157e4565b348015610b4857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000086103d0565b348015610b7b57600080fd5b50610508610b8a366004615679565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610bcb57610bcb61555f565b14610c02576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610c55576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610ca3610c9e36869003860186615838565b613a41565b14610cda576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610cef9291906158c5565b604051809103902014610d2e576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d77610d7284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613a9d92505050565b613b0a565b90506000610d9e82600881518110610d9157610d916158d5565b6020026020010151613cc0565b9050602081511115610ddc576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610e51576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610eec57610eec61555f565b14610f23576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610f3857610f386158d5565b906000526020600020906005020190506000610f5384612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b081169082161015610fbc576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611005576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561102257508515155b156110bd578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110555781611071565b600186015473ffffffffffffffffffffffffffffffffffffffff165b905061107d8187613d74565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff166060830152611160576fffffffffffffffffffffffffffffffff6040820152600181526000869003611160578195505b600086826020015163ffffffff166111789190615933565b90506000838211611189578161118b565b835b602084015190915063ffffffff165b818110156112d75760008682815481106111b6576111b66158d5565b6000918252602080832090910154808352600690915260409091205490915060ff1661120e576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611223576112236158d5565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112805750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b156112c257600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b505080806112cf9061594b565b91505061119a565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921790915584900361155b57606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558915801561145757506000547201000000000000000000000000000000000000900460ff165b156114cc5760015473ffffffffffffffffffffffffffffffffffffffff1661147f818a613d74565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff909116178855611559565b61151373ffffffffffffffffffffffffffffffffffffffff8216156114f1578161150d565b600189015473ffffffffffffffffffffffffffffffffffffffff165b89613d74565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff1660028111156115945761159461555f565b146115cb576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff1661162f576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008154811061165b5761165b6158d5565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611696576001611699565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff9091161770010000000000000000000000000000000083600281111561174a5761174a61555f565b02179055600281111561175f5761175f61555f565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e73ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156117f057600080fd5b505af1158015611804573d6000803e3d6000fd5b5050505090565b6005602052816000526040600020818154811061182757600080fd5b90600052602060002001600091509150505481565b905090565b61184e8383836001611a42565b505050565b6000818152600760209081526040808320600590925282208054825461188490610100900463ffffffff1682615983565b95945050505050565b606061183c60546020613e75565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260036020526040812080549082905590819003611900576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169063f3fef3a390604401600060405180830381600087803b15801561199057600080fd5b505af11580156119a4573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a02576040519150601f19603f3d011682016040523d82523d6000602084013e611a07565b606091505b505090508061184e576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008054700100000000000000000000000000000000900460ff166002811115611a6e57611a6e61555f565b14611aa5576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110611aba57611aba6158d5565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514611ba1576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000611c61826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580611c9c5750611c997f00000000000000000000000000000000000000000000000000000000000000046002615933565b81145b8015611ca6575084155b15611cdd576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015611d03575086155b15611d3a576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000008811115611d94576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dbf7f00000000000000000000000000000000000000000000000000000000000000046001615933565b8103611dd157611dd186888588613ec7565b34611ddb83612c60565b14611e12576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611e1d88612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b0811690821603611e85576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611eb260017f0000000000000000000000000000000000000000000000000000000000000008615983565b8303611ff0577f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f47919061599a565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb591906159b7565b611fe9907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166159d0565b9050612083565b61201b60017f0000000000000000000000000000000000000000000000000000000000000004615983565b830361205657611fe97f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1660026159fc565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b6120b7817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b67ffffffffffffffff166120d28367ffffffffffffffff1690565b67ffffffffffffffff16111561211957612116817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615612197576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c8152602001908152602001600020600160028054905061242d9190615983565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169263d0e30db09234926004808301939282900301818588803b1580156124c557600080fd5b505af11580156124d9573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b61184e8383836000611a42565b60005471010000000000000000000000000000000000900460ff161561257a576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e1690637258a807906024016040805180830381865afa15801561262e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126529190615a55565b90925090508161268e576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a146126c157639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401351161275b576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd929092169363d0e30db093926004828101939282900301818588803b158015612a3057600080fd5b505af1158015612a44573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b600080600054700100000000000000000000000000000000900460ff166002811115612aaf57612aaf61555f565b14612ae6576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110612afb57612afb6158d5565b600091825260208220600590910201805490925063ffffffff90811614612b6a57815460028054909163ffffffff16908110612b3957612b396158d5565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090612ba290700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b612bb69067ffffffffffffffff1642615983565b612bd5612b95846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16612be99190615933565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b01667ffffffffffffffff168167ffffffffffffffff1611612c365780611884565b7f00000000000000000000000000000000000000000000000000000000000004b095945050505050565b600080612cff836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000008811115612d5e576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000612d798383615aa8565b9050670de0b6b3a76400006000612db0827f0000000000000000000000000000000000000000000000000000000000000008615abc565b90506000612dce612dc9670de0b6b3a764000086615abc565b614078565b90506000612ddc84846142d3565b90506000612dea8383614322565b90506000612df782614350565b90506000612e1682612e11670de0b6b3a76400008f615abc565b614538565b90506000612e248b83614322565b9050612e30818d615abc565b9f9e505050505050505050505050505050565b60028181548110612e5357600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b60008054700100000000000000000000000000000000900460ff166002811115612f0657612f0661555f565b14612f3d576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028781548110612f5257612f526158d5565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b9050612fb17f00000000000000000000000000000000000000000000000000000000000000086001615933565b61304d826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1614613087576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561317e576130da7f00000000000000000000000000000000000000000000000000000000000000047f0000000000000000000000000000000000000000000000000000000000000008615983565b6001901b6130f9846fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff166131159190615af9565b156131525761314961313a60016fffffffffffffffffffffffffffffffff8716615b0d565b865463ffffffff166000614608565b60030154613174565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506131a8565b600385015491506131a561313a6fffffffffffffffffffffffffffffffff86166001615b36565b90505b600882901b60088a8a6040516131bf9291906158c5565b6040518091039020901b14613200576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061320b8c6146ec565b9050600061321a836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff169063e14ced3290613294908f908f908f908f908a90600401615baa565b6020604051808303816000875af11580156132b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d791906159b7565b600485015491149150600090600290613382906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b61341e896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6134289190615be4565b6134329190615c07565b60ff161590508115158103613473576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156134ca576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff1660028111156135355761353561555f565b1461356c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061357b8661471b565b9350935093509350600061359185858585614b24565b905060007f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015613600573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613624919061599a565b90506001890361371c5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a84613680367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af11580156136f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061371691906159b7565b5061155b565b600289036137485773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8489613680565b600389036137745773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8487613680565b600489036138fb5760006137ba6fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000004614bde565b6009546137c79190615933565b6137d2906001615933565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061383b57367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036054013561383d565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156138d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f491906159b7565b505061155b565b60058903613994576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000038560c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016136d3565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060613a1f61188d565b9050909192565b600081831015613a365781613a38565b825b90505b92915050565b60008160000151826020015183604001518460600151604051602001613a80949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003613aec576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000613b1a85614c8c565b919450925090506001816001811115613b3557613b3561555f565b14613b6c576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451613b788385615933565b14613baf576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081613bc65790505093506000835b8651811015613cb457600080613c396040518060400160405280858c60000151613c1d9190615983565b8152602001858c60200151613c329190615933565b9052614c8c565b509150915060405180604001604052808383613c559190615933565b8152602001848b60200151613c6a9190615933565b815250888581518110613c7f57613c7f6158d5565b6020908102919091010152613c95600185615933565b9350613ca18183615933565b613cab9084615933565b92505050613bf3565b50845250919392505050565b60606000806000613cd085614c8c565b919450925090506000816001811115613ceb57613ceb61555f565b14613d22576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613d2c8284615933565b855114613d65576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118848560200151848461512a565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff90931692839290613dc3908490615933565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd921690637eee288d90604401600060405180830381600087803b158015613e5857600080fd5b505af1158015613e6c573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b6000613ee66fffffffffffffffffffffffffffffffff84166001615b36565b90506000613ef682866001614608565b9050600086901a8380613fe25750613f2f60027f0000000000000000000000000000000000000000000000000000000000000004615af9565b6004830154600290613fd3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b613fdd9190615c07565b60ff16145b1561403a5760ff811660011480613ffc575060ff81166002145b614035576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b613e6c565b60ff811615613e6c576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b17600082136140d757631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a76400000215820261431057637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b6000816000190483118202156143405763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d7821361437e57919050565b680755bf798b4a1bf1e5821261439c5763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000613a38670de0b6b3a76400008361455086614078565b61455a9190615c29565b6145649190615ce5565b614350565b6000806145f6837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826146515761464c6fffffffffffffffffffffffffffffffff86167f00000000000000000000000000000000000000000000000000000000000000046151bf565b61466c565b61466c856fffffffffffffffffffffffffffffffff1661534b565b905060028481548110614681576146816158d5565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff8281169116146146e457815460028054909163ffffffff169081106146cf576146cf6158d5565b90600052602060002090600502019150614692565b509392505050565b60008060008060006146fd8661471b565b935093509350935061471184848484614b24565b9695505050505050565b600080600080600085905060006002828154811061473b5761473b6158d5565b600091825260209091206004600590920201908101549091507f000000000000000000000000000000000000000000000000000000000000000490614812906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff161161484c576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f000000000000000000000000000000000000000000000000000000000000000490614913906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16925082111561498857825463ffffffff166149527f00000000000000000000000000000000000000000000000000000000000000046001615933565b830361495c578391505b6002818154811061496f5761496f6158d5565b9060005260206000209060050201935080945050614850565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149f16149dc856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff161490508015614ac0576000614a29836fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff161115614a94576000614a6b614a6360016fffffffffffffffffffffffffffffffff8616615b0d565b896001614608565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a50614a9a9050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614b16565b6000614ae2614a636fffffffffffffffffffffffffffffffff85166001615b36565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614b915760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611884565b8282604051602001614bbf9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614c6b847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614ccf576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614cf4576000600160009450945094505050615123565b60b78111614e0a576000614d09608083615983565b905080876000015111614d48576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614dc057507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614df7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060019550935060009250615123915050565b60bf8111614f68576000614e1f60b783615983565b905080876000015111614e5e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614ec0576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614f08576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f128184615933565b895111614f4b576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f56836001615933565b97509550600094506151239350505050565b60f78111614fcd576000614f7d60c083615983565b905080876000015111614fbc576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600195509350849250615123915050565b6000614fda60f783615983565b905080876000015111615019576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361507b576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116150c3576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6150cd8184615933565b895111615106576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615111836001615933565b97509550600194506151239350505050565b9193909250565b60608167ffffffffffffffff81111561514557615145615809565b6040519080825280601f01601f19166020018201604052801561516f576020820181803683370190505b50905081156151b85760006151848486615933565b90506020820160005b848110156151a557828101518282015260200161518d565b848111156151b4576000858301525b5050505b9392505050565b60008161525e846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116152745763b34b5c226000526004601cfd5b61527d8361534b565b90508161531c826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611613a3b57613a38615332836001615933565b6fffffffffffffffffffffffffffffffff8316906153f0565b600081196001830116816153df827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b60008061547d847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f8401126154ab57600080fd5b50813567ffffffffffffffff8111156154c357600080fd5b6020830191508360208285010111156154db57600080fd5b9250929050565b600080600083850360a08112156154f857600080fd5b608081121561550657600080fd5b50839250608084013567ffffffffffffffff81111561552457600080fd5b61553086828701615499565b9497909650939450505050565b6000806040838503121561555057600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106155c9577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806000606084860312156155e457600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561562157602081850181015186830182015201615605565b81811115615633576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000613a3860208301846155fb565b60006020828403121561568b57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146156b457600080fd5b50565b6000602082840312156156c957600080fd5b81356151b881615692565b803580151581146156e457600080fd5b919050565b600080600080608085870312156156ff57600080fd5b84359350602085013592506040850135915061571d606086016156d4565b905092959194509250565b60006020828403121561573a57600080fd5b81356fffffffffffffffffffffffffffffffff811681146151b857600080fd5b6000806000806000806080878903121561577357600080fd5b86359550615783602088016156d4565b9450604087013567ffffffffffffffff808211156157a057600080fd5b6157ac8a838b01615499565b909650945060608901359150808211156157c557600080fd5b506157d289828a01615499565b979a9699509497509295939492505050565b63ffffffff8416815282602082015260606040820152600061188460608301846155fb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006080828403121561584a57600080fd5b6040516080810181811067ffffffffffffffff82111715615894577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561594657615946615904565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361597c5761597c615904565b5060010190565b60008282101561599557615995615904565b500390565b6000602082840312156159ac57600080fd5b81516151b881615692565b6000602082840312156159c957600080fd5b5051919050565b600067ffffffffffffffff8083168185168083038211156159f3576159f3615904565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615a2357615a23615904565b02949350505050565b600067ffffffffffffffff83811690831681811015615a4d57615a4d615904565b039392505050565b60008060408385031215615a6857600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615ab757615ab7615a79565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615af457615af4615904565b500290565b600082615b0857615b08615a79565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615a4d57615a4d615904565b60006fffffffffffffffffffffffffffffffff8083168185168083038211156159f3576159f3615904565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615bbe606083018789615b61565b8281036020840152615bd1818688615b61565b9150508260408301529695505050505050565b600060ff821660ff841680821015615bfe57615bfe615904565b90039392505050565b600060ff831680615c1a57615c1a615a79565b8060ff84160691505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615c6a57615c6a615904565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615ca557615ca5615904565b60008712925087820587128484161615615cc157615cc1615904565b87850587128184161615615cd757615cd7615904565b505050929093029392505050565b600082615cf457615cf4615a79565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615d4857615d48615904565b50059056fea164736f6c634300080f000a"; bytes internal constant acc34Code = diff --git a/packages/contracts-bedrock/test/vendor/Initializable.t.sol b/packages/contracts-bedrock/test/vendor/Initializable.t.sol index 922b1c4bd5b8..9671e024bc19 100644 --- a/packages/contracts-bedrock/test/vendor/Initializable.t.sol +++ b/packages/contracts-bedrock/test/vendor/Initializable.t.sol @@ -1,15 +1,22 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +import { LibString } from "@solady/utils/LibString.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { Executables } from "scripts/libraries/Executables.sol"; +import { Constants } from "src/libraries/Constants.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { SystemConfigInterop } from "src/L1/SystemConfigInterop.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol"; -import { ForgeArtifacts } from "scripts/libraries/ForgeArtifacts.sol"; +import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; +import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; +import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; +import { GameTypes } from "src/dispute/lib/Types.sol"; +import { ForgeArtifacts, StorageSlot } from "scripts/libraries/ForgeArtifacts.sol"; import { Process } from "scripts/libraries/Process.sol"; import "src/L1/ProtocolVersions.sol"; import "src/dispute/lib/Types.sol"; @@ -24,15 +31,19 @@ contract Initializer_Test is Bridge_Initializer { /// @notice Contains the address of an `Initializable` contract and the calldata /// used to initialize it. struct InitializeableContract { + string name; address target; bytes initCalldata; - uint8 initializedSlotVal; } - /// @notice Contains the addresses of the contracts to test as well as the calldata - /// used to initialize them. + /// @notice Array of contracts to test. InitializeableContract[] contracts; + /// @notice Mapping of nickname to actual contract name. + /// @dev Nicknames are only used when one proxy contract has multiple potential implementations + /// as can happen when a new implementation is being developed. + mapping(string => string) nicknames; + function setUp() public override { super.enableAltDA(); // Run the `Bridge_Initializer`'s `setUp()` function. @@ -44,98 +55,107 @@ contract Initializer_Test is Bridge_Initializer { // SuperchainConfigImpl contracts.push( InitializeableContract({ + name: "SuperchainConfig", target: deploy.mustGetAddress("SuperchainConfig"), - initCalldata: abi.encodeCall(superchainConfig.initialize, (address(0), false)), - initializedSlotVal: deploy.loadInitializedSlot("SuperchainConfig") + initCalldata: abi.encodeCall(superchainConfig.initialize, (address(0), false)) }) ); // SuperchainConfigProxy contracts.push( InitializeableContract({ + name: "SuperchainConfigProxy", target: address(superchainConfig), - initCalldata: abi.encodeCall(superchainConfig.initialize, (address(0), false)), - initializedSlotVal: deploy.loadInitializedSlot("SuperchainConfigProxy") + initCalldata: abi.encodeCall(superchainConfig.initialize, (address(0), false)) }) ); // L1CrossDomainMessengerImpl contracts.push( InitializeableContract({ + name: "L1CrossDomainMessenger", target: deploy.mustGetAddress("L1CrossDomainMessenger"), initCalldata: abi.encodeCall( l1CrossDomainMessenger.initialize, (superchainConfig, optimismPortal, systemConfig) - ), - initializedSlotVal: deploy.loadInitializedSlot("L1CrossDomainMessenger") + ) }) ); // L1CrossDomainMessengerProxy contracts.push( InitializeableContract({ + name: "L1CrossDomainMessengerProxy", target: address(l1CrossDomainMessenger), initCalldata: abi.encodeCall( l1CrossDomainMessenger.initialize, (superchainConfig, optimismPortal, systemConfig) - ), - initializedSlotVal: deploy.loadInitializedSlot("L1CrossDomainMessengerProxy") + ) }) ); // DisputeGameFactoryImpl contracts.push( InitializeableContract({ + name: "DisputeGameFactory", target: deploy.mustGetAddress("DisputeGameFactory"), - initCalldata: abi.encodeCall(disputeGameFactory.initialize, (address(0))), - initializedSlotVal: deploy.loadInitializedSlot("DisputeGameFactory") + initCalldata: abi.encodeCall(disputeGameFactory.initialize, (address(0))) }) ); // DisputeGameFactoryProxy contracts.push( InitializeableContract({ + name: "DisputeGameFactoryProxy", target: address(disputeGameFactory), - initCalldata: abi.encodeCall(disputeGameFactory.initialize, (address(0))), - initializedSlotVal: deploy.loadInitializedSlot("DisputeGameFactoryProxy") + initCalldata: abi.encodeCall(disputeGameFactory.initialize, (address(0))) }) ); // DelayedWETHImpl contracts.push( InitializeableContract({ + name: "DelayedWETH", target: deploy.mustGetAddress("DelayedWETH"), - initCalldata: abi.encodeCall(delayedWeth.initialize, (address(0), SuperchainConfig(address(0)))), - initializedSlotVal: deploy.loadInitializedSlot("DelayedWETH") + initCalldata: abi.encodeCall(delayedWeth.initialize, (address(0), SuperchainConfig(address(0)))) }) ); // DelayedWETHProxy contracts.push( InitializeableContract({ + name: "DelayedWETHProxy", target: address(delayedWeth), - initCalldata: abi.encodeCall(delayedWeth.initialize, (address(0), SuperchainConfig(address(0)))), - initializedSlotVal: deploy.loadInitializedSlot("DelayedWETHProxy") + initCalldata: abi.encodeCall(delayedWeth.initialize, (address(0), SuperchainConfig(address(0)))) }) ); // L2OutputOracleImpl contracts.push( InitializeableContract({ + name: "L2OutputOracle", target: deploy.mustGetAddress("L2OutputOracle"), - initCalldata: abi.encodeCall(l2OutputOracle.initialize, (0, 0, 0, 0, address(0), address(0), 0)), - initializedSlotVal: deploy.loadInitializedSlot("L2OutputOracle") + initCalldata: abi.encodeCall(l2OutputOracle.initialize, (0, 0, 0, 0, address(0), address(0), 0)) }) ); // L2OutputOracleProxy contracts.push( InitializeableContract({ + name: "L2OutputOracleProxy", target: address(l2OutputOracle), - initCalldata: abi.encodeCall(l2OutputOracle.initialize, (0, 0, 0, 0, address(0), address(0), 0)), - initializedSlotVal: deploy.loadInitializedSlot("L2OutputOracleProxy") + initCalldata: abi.encodeCall(l2OutputOracle.initialize, (0, 0, 0, 0, address(0), address(0), 0)) }) ); // OptimismPortalImpl contracts.push( InitializeableContract({ + name: "OptimismPortal", target: deploy.mustGetAddress("OptimismPortal"), - initCalldata: abi.encodeCall(optimismPortal.initialize, (l2OutputOracle, systemConfig, superchainConfig)), - initializedSlotVal: deploy.loadInitializedSlot("OptimismPortal") + initCalldata: abi.encodeCall(optimismPortal.initialize, (l2OutputOracle, systemConfig, superchainConfig)) + }) + ); + // OptimismPortalProxy + contracts.push( + InitializeableContract({ + name: "OptimismPortalProxy", + target: address(optimismPortal), + initCalldata: abi.encodeCall(optimismPortal.initialize, (l2OutputOracle, systemConfig, superchainConfig)) }) ); // OptimismPortal2Impl contracts.push( InitializeableContract({ + name: "OptimismPortal2", target: deploy.mustGetAddress("OptimismPortal2"), initCalldata: abi.encodeCall( optimismPortal2.initialize, @@ -145,21 +165,13 @@ contract Initializer_Test is Bridge_Initializer { superchainConfig, GameType.wrap(uint32(deploy.cfg().respectedGameType())) ) - ), - initializedSlotVal: deploy.loadInitializedSlot("OptimismPortal2") - }) - ); - // OptimismPortalProxy - contracts.push( - InitializeableContract({ - target: address(optimismPortal), - initCalldata: abi.encodeCall(optimismPortal.initialize, (l2OutputOracle, systemConfig, superchainConfig)), - initializedSlotVal: deploy.loadInitializedSlot("OptimismPortalProxy") + ) }) ); // SystemConfigImpl contracts.push( InitializeableContract({ + name: "SystemConfig", target: deploy.mustGetAddress("SystemConfig"), initCalldata: abi.encodeCall( systemConfig.initialize, @@ -189,13 +201,13 @@ contract Initializer_Test is Bridge_Initializer { gasPayingToken: Constants.ETHER }) ) - ), - initializedSlotVal: deploy.loadInitializedSlot("SystemConfig") + ) }) ); // SystemConfigProxy contracts.push( InitializeableContract({ + name: "SystemConfigProxy", target: address(systemConfig), initCalldata: abi.encodeCall( systemConfig.initialize, @@ -225,242 +237,283 @@ contract Initializer_Test is Bridge_Initializer { gasPayingToken: Constants.ETHER }) ) - ), - initializedSlotVal: deploy.loadInitializedSlot("SystemConfigProxy") + ) }) ); // ProtocolVersionsImpl contracts.push( InitializeableContract({ + name: "ProtocolVersions", target: deploy.mustGetAddress("ProtocolVersions"), initCalldata: abi.encodeCall( protocolVersions.initialize, (address(0), ProtocolVersion.wrap(1), ProtocolVersion.wrap(2)) - ), - initializedSlotVal: deploy.loadInitializedSlot("ProtocolVersions") + ) }) ); // ProtocolVersionsProxy contracts.push( InitializeableContract({ + name: "ProtocolVersionsProxy", target: address(protocolVersions), initCalldata: abi.encodeCall( protocolVersions.initialize, (address(0), ProtocolVersion.wrap(1), ProtocolVersion.wrap(2)) - ), - initializedSlotVal: deploy.loadInitializedSlot("ProtocolVersionsProxy") + ) }) ); // L2CrossDomainMessenger contracts.push( InitializeableContract({ + name: "L2CrossDomainMessenger", target: address(l2CrossDomainMessenger), - initCalldata: abi.encodeCall(l2CrossDomainMessenger.initialize, (l1CrossDomainMessenger)), - initializedSlotVal: deploy.loadInitializedSlot("L2CrossDomainMessenger") + initCalldata: abi.encodeCall(l2CrossDomainMessenger.initialize, (l1CrossDomainMessenger)) }) ); // L1StandardBridgeImpl contracts.push( InitializeableContract({ + name: "L1StandardBridge", target: deploy.mustGetAddress("L1StandardBridge"), initCalldata: abi.encodeCall( l1StandardBridge.initialize, (l1CrossDomainMessenger, superchainConfig, systemConfig) - ), - initializedSlotVal: deploy.loadInitializedSlot("L1StandardBridge") + ) }) ); // L1StandardBridgeProxy contracts.push( InitializeableContract({ + name: "L1StandardBridgeProxy", target: address(l1StandardBridge), initCalldata: abi.encodeCall( l1StandardBridge.initialize, (l1CrossDomainMessenger, superchainConfig, systemConfig) - ), - initializedSlotVal: deploy.loadInitializedSlot("L1StandardBridgeProxy") + ) }) ); // L2StandardBridge contracts.push( InitializeableContract({ + name: "L2StandardBridge", target: address(l2StandardBridge), - initCalldata: abi.encodeCall(l2StandardBridge.initialize, (l1StandardBridge)), - initializedSlotVal: deploy.loadInitializedSlot("L2StandardBridge") + initCalldata: abi.encodeCall(l2StandardBridge.initialize, (l1StandardBridge)) }) ); // L2StandardBridgeInterop contracts.push( InitializeableContract({ + name: "L2StandardBridgeInterop", target: address(l2StandardBridge), - initCalldata: abi.encodeCall(l2StandardBridge.initialize, (l1StandardBridge)), - initializedSlotVal: deploy.loadInitializedSlot("L2StandardBridgeInterop") + initCalldata: abi.encodeCall(l2StandardBridge.initialize, (l1StandardBridge)) }) ); // L1ERC721BridgeImpl contracts.push( InitializeableContract({ + name: "L1ERC721Bridge", target: deploy.mustGetAddress("L1ERC721Bridge"), - initCalldata: abi.encodeCall(l1ERC721Bridge.initialize, (l1CrossDomainMessenger, superchainConfig)), - initializedSlotVal: deploy.loadInitializedSlot("L1ERC721Bridge") + initCalldata: abi.encodeCall(l1ERC721Bridge.initialize, (l1CrossDomainMessenger, superchainConfig)) }) ); // L1ERC721BridgeProxy contracts.push( InitializeableContract({ + name: "L1ERC721BridgeProxy", target: address(l1ERC721Bridge), - initCalldata: abi.encodeCall(l1ERC721Bridge.initialize, (l1CrossDomainMessenger, superchainConfig)), - initializedSlotVal: deploy.loadInitializedSlot("L1ERC721BridgeProxy") + initCalldata: abi.encodeCall(l1ERC721Bridge.initialize, (l1CrossDomainMessenger, superchainConfig)) }) ); // L2ERC721Bridge contracts.push( InitializeableContract({ + name: "L2ERC721Bridge", target: address(l2ERC721Bridge), - initCalldata: abi.encodeCall(l2ERC721Bridge.initialize, (payable(address(l1ERC721Bridge)))), - initializedSlotVal: deploy.loadInitializedSlot("L2ERC721Bridge") + initCalldata: abi.encodeCall(l2ERC721Bridge.initialize, (payable(address(l1ERC721Bridge)))) }) ); // OptimismMintableERC20FactoryImpl contracts.push( InitializeableContract({ + name: "OptimismMintableERC20Factory", target: deploy.mustGetAddress("OptimismMintableERC20Factory"), - initCalldata: abi.encodeCall(l1OptimismMintableERC20Factory.initialize, (address(l1StandardBridge))), - initializedSlotVal: deploy.loadInitializedSlot("OptimismMintableERC20Factory") + initCalldata: abi.encodeCall(l1OptimismMintableERC20Factory.initialize, (address(l1StandardBridge))) }) ); // OptimismMintableERC20FactoryProxy contracts.push( InitializeableContract({ + name: "OptimismMintableERC20FactoryProxy", target: address(l1OptimismMintableERC20Factory), - initCalldata: abi.encodeCall(l1OptimismMintableERC20Factory.initialize, (address(l1StandardBridge))), - initializedSlotVal: deploy.loadInitializedSlot("OptimismMintableERC20FactoryProxy") + initCalldata: abi.encodeCall(l1OptimismMintableERC20Factory.initialize, (address(l1StandardBridge))) }) ); // DataAvailabilityChallengeImpl contracts.push( InitializeableContract({ + name: "DataAvailabilityChallenge", target: deploy.mustGetAddress("DataAvailabilityChallenge"), - initCalldata: abi.encodeCall(dataAvailabilityChallenge.initialize, (address(0), 0, 0, 0, 0)), - initializedSlotVal: deploy.loadInitializedSlot("DataAvailabilityChallenge") + initCalldata: abi.encodeCall(dataAvailabilityChallenge.initialize, (address(0), 0, 0, 0, 0)) }) ); // DataAvailabilityChallengeProxy contracts.push( InitializeableContract({ + name: "DataAvailabilityChallengeProxy", target: address(dataAvailabilityChallenge), - initCalldata: abi.encodeCall(dataAvailabilityChallenge.initialize, (address(0), 0, 0, 0, 0)), - initializedSlotVal: deploy.loadInitializedSlot("DataAvailabilityChallengeProxy") + initCalldata: abi.encodeCall(dataAvailabilityChallenge.initialize, (address(0), 0, 0, 0, 0)) }) ); + // AnchorStateRegistry + contracts.push( + InitializeableContract({ + name: "AnchorStateRegistry", + target: address(anchorStateRegistry), + initCalldata: abi.encodeCall( + anchorStateRegistry.initialize, + (new AnchorStateRegistry.StartingAnchorRoot[](1), SuperchainConfig(address(0))) + ) + }) + ); + // AnchorStateRegistryProxy + contracts.push( + InitializeableContract({ + name: "AnchorStateRegistryProxy", + target: address(anchorStateRegistry), + initCalldata: abi.encodeCall( + anchorStateRegistry.initialize, + (new AnchorStateRegistry.StartingAnchorRoot[](1), SuperchainConfig(address(0))) + ) + }) + ); + + // Nicknamed contracts. + nicknames["OptimismPortal2Proxy"] = "OptimismPortalProxy"; } /// @notice Tests that: - /// 1. All `Initializable` contracts in `src/L1` and `src/L2` are accounted for in the `contracts` array. - /// 2. The `_initialized` flag of each contract is properly set to `1`, signifying that the - /// contracts are initialized. - /// 3. The `initialize()` function of each contract cannot be called more than once. + /// 1. All `Initializable` contracts in `src/` (except periphery) are accounted for in `contracts`. + /// 2. The `_initialized` flag of each contract is properly set. + /// 3. The `initialize()` function of each contract cannot be called again. function test_cannotReinitialize_succeeds() public { - // Ensure that all L1, L2 `Initializable` contracts are accounted for, in addition to - // OptimismMintableERC20FactoryImpl, OptimismMintableERC20FactoryProxy, OptimismPortal2, - // DisputeGameFactoryImpl, DisputeGameFactoryProxy, DelayedWETHImpl, DelayedWETHProxy. - // Omitting OptimismSuperchainERC20 due to using OZ v5 Initializable. - assertEq(_getNumInitializable(), contracts.length); - - // Attempt to re-initialize all contracts within the `contracts` array. - for (uint256 i; i < contracts.length; i++) { - InitializeableContract memory _contract = contracts[i]; - uint256 size; - address target = _contract.target; - assembly { - size := extcodesize(target) - } - // Assert that the contract is already initialized. - assertEq(_contract.initializedSlotVal, 1); + // Collect exclusions. + string[] memory excludes = new string[](6); + // TODO: Neither of these contracts are labeled properly in the deployment script. Both are + // currently being labeled as their non-interop versions. Remove these exclusions once + // the deployment script is fixed. + excludes[0] = "src/L1/SystemConfigInterop.sol"; + excludes[1] = "src/L1/OptimismPortalInterop.sol"; + // Contract is currently not being deployed as part of the standard deployment script. + excludes[2] = "src/L2/OptimismSuperchainERC20.sol"; + // Periphery contracts don't get deployed as part of the standard deployment script. + excludes[3] = "src/periphery/*"; + // TODO: Deployment script is currently "broken" in the sense that it doesn't properly + // label the FaultDisputeGame and PermissionedDisputeGame contracts and instead + // simply deploys them anonymously. Means that functions like "getInitializedSlot" + // don't work properly. Remove these exclusions once the deployment script is fixed. + excludes[4] = "src/dispute/FaultDisputeGame.sol"; + excludes[5] = "src/dispute/PermissionedDisputeGame.sol"; - // Then, attempt to re-initialize the contract. This should fail. - (bool success, bytes memory returnData) = _contract.target.call(_contract.initCalldata); - assertFalse(success); - assertEq(_extractErrorString(returnData), "Initializable: contract is already initialized"); - } - } + // Get all contract names in the src directory, minus the excluded contracts. + string[] memory contractNames = ForgeArtifacts.getContractNames("src/*", excludes); - /// @dev Returns the number of contracts that are `Initializable` in `src/L1` and `src/L2`. - /// For L1 contracts, implementations are considered in addition to proxies - function _getNumInitializable() internal returns (uint256 numContracts_) { - string[] memory command = new string[](3); - command[0] = Executables.bash; - command[1] = "-c"; - // Start by getting L1 contracts - command[2] = string.concat( - Executables.find, - " src/L1 -type f -exec basename {} \\;", - " | ", - Executables.sed, - " 's/\\.[^.]*$//'", - " | ", - Executables.jq, - " -R -s 'split(\"\n\")[:-1]'" - ); - string[] memory l1ContractNames = abi.decode(vm.parseJson(string(Process.run(command))), (string[])); + // Iterate over all contracts to assert that they are accounted for in the `contracts + // array. All contracts that have an `initialize()` function must be accounted for in the + // `contracts` array or an error will be thrown. If the contract is proxied, both the + // implementation and the proxy must be accounted for in the `contracts` array. + for (uint256 i; i < contractNames.length; i++) { + string memory contractName = contractNames[i]; + string memory contractKind = ForgeArtifacts.getContractKind(contractName); - for (uint256 i; i < l1ContractNames.length; i++) { - string memory contractName = l1ContractNames[i]; - string memory contractAbi = ForgeArtifacts.getAbi(contractName); + // Filter out non-contracts. + if (!LibString.eq(contractKind, "contract")) { + continue; + } - // Query the contract's ABI for an `initialize()` function. + // Construct the query for the initialize function in the contract's ABI. + string[] memory command = new string[](3); + command[0] = Executables.bash; + command[1] = "-c"; command[2] = string.concat( Executables.echo, " '", - contractAbi, + ForgeArtifacts.getAbi(contractName), "'", " | ", Executables.jq, " '.[] | select(.name == \"initialize\" and .type == \"function\")'" ); - bytes memory res = Process.run(command); - // If the contract has an `initialize()` function, the resulting query will be non-empty. - // In this case, increment the number of `Initializable` contracts. - if (res.length > 0) { - // Count Proxy + Impl - numContracts_ += 2; + // If the contract does not have an `initialize()` function, skip it. + if (Process.run(command).length == 0) { + continue; + } + + // Check if this contract is in the contracts array. + assertTrue( + _hasMatchingContract(contractName), string.concat("Missing ", contractName, " from contracts array") + ); + + // If the contract is proxied, check that the proxy is in the contracts array. + // Skip predeployed contracts for now since we don't yet keep track of the + // implementations inside of the deploy script. + // TODO: We should add support for this in the future so that we can properly check that + // the implementations for predeployed contracts are initialized too. + if (ForgeArtifacts.isProxiedContract(contractName) && !ForgeArtifacts.isPredeployedContract(contractName)) { + assertTrue( + _hasMatchingContract(string.concat(contractName, "Proxy")), + string.concat("Missing ", contractName, "Proxy from contracts array") + ); } } - // Then get L2 contracts - command[2] = string.concat( - Executables.find, - " src/L2 -type f -exec basename {} \\;", - " | ", - Executables.sed, - " 's/\\.[^.]*$//'", - " | ", - Executables.jq, - " -R -s 'split(\"\n\")[:-1]'" - ); - string[] memory l2ContractNames = abi.decode(vm.parseJson(string(Process.run(command))), (string[])); + // Attempt to re-initialize all contracts within the `contracts` array. + for (uint256 i; i < contracts.length; i++) { + InitializeableContract memory _contract = contracts[i]; + string memory name = _getRealContractName(_contract.name); - for (uint256 i; i < l2ContractNames.length; i++) { - string memory contractName = l2ContractNames[i]; - string memory contractAbi = ForgeArtifacts.getAbi(contractName); + // Grab the value of the "initialized" storage slot. Must handle special case for the + // FaultDisputeGame and PermissionedDisputeGame contracts since these have a different + // name for the "initialized" storage slot and are currently not properly labeled in + // the deployment script. + // TODO: Update deployment script to properly label the dispute game contracts. + uint8 initializedSlotVal; + if (LibString.eq(name, "FaultDisputeGame") || LibString.eq(name, "PermissionedDisputeGame")) { + StorageSlot memory slot = ForgeArtifacts.getInitializedSlot(name); + bytes32 slotVal = vm.load(_contract.target, bytes32(vm.parseUint(slot.slot))); + initializedSlotVal = uint8((uint256(slotVal) >> (slot.offset * 8)) & 0xFF); + } else { + initializedSlotVal = deploy.loadInitializedSlot(name); + } - // Query the contract's ABI for an `initialize()` function. - command[2] = string.concat( - Executables.echo, - " '", - contractAbi, - "'", - " | ", - Executables.jq, - " '.[] | select(.name == \"initialize\" and .type == \"function\")'" + // Assert that the contract is already initialized. + assertTrue( + // Either 1 for initialized or type(uint8).max for initializer disabled. + initializedSlotVal == 1 || initializedSlotVal == type(uint8).max, + "Initializable: contract is not initialized" ); - bytes memory res = Process.run(command); - // If the contract has an `initialize()` function, the resulting query will be non-empty. - // In this case, increment the number of `Initializable` contracts. - if (res.length > 0) { - numContracts_++; + // Then, attempt to re-initialize the contract. This should fail. + (bool success, bytes memory returnData) = _contract.target.call(_contract.initCalldata); + assertFalse(success); + assertEq(_extractErrorString(returnData), "Initializable: contract is already initialized"); + } + } + + /// @dev Returns true if the contract with the given name is in the `contracts` array. + /// @param _name The name of the contract to check. + /// @return matching_ True if the contract is in the `contracts` array, false otherwise. + function _hasMatchingContract(string memory _name) internal view returns (bool matching_) { + for (uint256 i; i < contracts.length; i++) { + if (LibString.eq(contracts[i].name, _getRealContractName(_name))) { + matching_ = true; } } } + /// @dev Returns the real name of the contract, including any nicknames. + /// @param _name The name of the contract. + /// @return real_ The real name of the contract. + function _getRealContractName(string memory _name) internal view returns (string memory real_) { + real_ = bytes(nicknames[_name]).length > 0 ? nicknames[_name] : _name; + } + /// @dev Extracts the revert string from returndata encoded in the form of `Error(string)`. function _extractErrorString(bytes memory _returnData) internal pure returns (string memory error_) { // The first 4 bytes of the return data should be the selector for `Error(string)`. If not, revert. From e7e5229ca027165bb9a010fbe9559718c50f0dd2 Mon Sep 17 00:00:00 2001 From: Matt Solomon Date: Thu, 5 Sep 2024 13:34:20 -0700 Subject: [PATCH 044/264] Update VERSIONING.md (#11761) --- packages/contracts-bedrock/VERSIONING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/VERSIONING.md b/packages/contracts-bedrock/VERSIONING.md index 213fae3a6074..fefc2211b3e5 100644 --- a/packages/contracts-bedrock/VERSIONING.md +++ b/packages/contracts-bedrock/VERSIONING.md @@ -81,7 +81,9 @@ To accommodate this, once contract changes are ready for governance approval, th - After merge, the new commit on the `proposal/op-contracts/vX.Y.Z` branch is the commit hash that will be tagged as `op-contracts/vX.Y.Z-rc.1`, used to deploy the contracts, and proposed to governance. - Sometimes additional release candidates are needed before proposal—see [Additional Release Candidates](#additional-release-candidates) for more information on this flow. - Once the governance approval is posted, any lock on contracts on `develop` is released. -- Once governance approves the proposal, merge the proposal branch into `develop` and set the version of all contracts to the appropriate `X.Y.Z` after considering any changes made to `develop` since the release candidate was created. +- Once governance approves the proposal: + - Create the official `op-contracts/vX.Y.Z` off of this `proposal/op-contracts/vX.Y.Z` branch. It should be at the same commit as the most recent release candidate. + - Merge the proposal branch into `develop` and set the version of all contracts to the appropriate `X.Y.Z` after considering any changes made to `develop` since the release candidate was created. - See [Merging Back to Develop After Governance Approval](#merging-back-to-develop-after-governance-approval) for more information on how to choose the resulting contract versions when merging back into `develop`. ### Additional Release Candidates From f85f18940fd01ec187d18431c9ccda9fb4545d1a Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Thu, 5 Sep 2024 16:15:39 -0600 Subject: [PATCH 045/264] Fix contracts-bedrock-docker-publish build (#11755) The build stage name was accidentally removed, which [broke](https://app.circleci.com/pipelines/github/ethereum-optimism/optimism/63237/workflows/e6a2d738-132f-4e10-9da2-c265b364c771/jobs/2627291) the job. --- ops/docker/Dockerfile.packages | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ops/docker/Dockerfile.packages b/ops/docker/Dockerfile.packages index f4f110244f5f..bdcb917d21d3 100644 --- a/ops/docker/Dockerfile.packages +++ b/ops/docker/Dockerfile.packages @@ -34,7 +34,7 @@ RUN git submodule update --init --recursive \ && just build \ && echo $(git rev-parse HEAD) > .gitcommit -FROM --platform=linux/amd64 debian:bookworm-20240812-slim +FROM --platform=linux/amd64 debian:bookworm-20240812-slim as contracts-bedrock RUN apt-get update && apt-get install -y \ curl \ From ac19f2f9831c530022064ba2b75f1e3036aa71ea Mon Sep 17 00:00:00 2001 From: protolambda Date: Thu, 5 Sep 2024 16:59:43 -0600 Subject: [PATCH 046/264] op-node: op-node interop block verification (devnet-1 scope) (#11611) * op-node: experimental interop block verification * op-node: supervisor RPC init * op-e2e/actions: test interop safety checks * op-e2e/op-node: test fixes * op-node: update comments * op-node: unit-test interop deriver, trigger cross-safe updates on driver step, to poll for supervisor safety changes * op-node: add more comments, fix flag description * op-e2e: fix rebase, add missing argument --- op-e2e/actions/altda_test.go | 4 +- op-e2e/actions/batch_queue_test.go | 3 +- op-e2e/actions/interop_test.go | 123 ++++++++++++ op-e2e/actions/l2_sequencer.go | 6 +- op-e2e/actions/l2_sequencer_test.go | 26 ++- op-e2e/actions/l2_verifier.go | 17 +- op-e2e/actions/l2_verifier_test.go | 17 +- op-e2e/actions/reorg_test.go | 4 +- op-e2e/actions/sync_test.go | 26 ++- op-node/flags/flags.go | 8 + op-node/node/client.go | 26 +++ op-node/node/config.go | 12 +- op-node/node/node.go | 18 +- op-node/rollup/driver/driver.go | 10 + op-node/rollup/driver/state.go | 6 + op-node/rollup/engine/engine_controller.go | 54 +++++- op-node/rollup/engine/events.go | 185 ++++++++++++++++++- op-node/rollup/engine/payload_success.go | 19 +- op-node/rollup/interop/interop.go | 161 ++++++++++++++++ op-node/rollup/interop/interop_test.go | 136 ++++++++++++++ op-node/rollup/status/status.go | 8 + op-node/service.go | 17 +- op-service/eth/sync_status.go | 7 + op-service/sources/supervisor_client.go | 37 ++++ op-service/testutils/mock_interop_backend.go | 28 +++ 25 files changed, 903 insertions(+), 55 deletions(-) create mode 100644 op-e2e/actions/interop_test.go create mode 100644 op-node/rollup/interop/interop.go create mode 100644 op-node/rollup/interop/interop_test.go create mode 100644 op-service/sources/supervisor_client.go create mode 100644 op-service/testutils/mock_interop_backend.go diff --git a/op-e2e/actions/altda_test.go b/op-e2e/actions/altda_test.go index 14889edabc88..ab18ff77e098 100644 --- a/op-e2e/actions/altda_test.go +++ b/op-e2e/actions/altda_test.go @@ -81,7 +81,7 @@ func NewL2AltDA(t Testing, params ...AltDAParam) *L2AltDA { daMgr := altda.NewAltDAWithStorage(log, altDACfg, storage, &altda.NoopMetrics{}) - sequencer := NewL2Sequencer(t, log, l1F, miner.BlobStore(), daMgr, engCl, sd.RollupCfg, 0) + sequencer := NewL2Sequencer(t, log, l1F, miner.BlobStore(), daMgr, engCl, sd.RollupCfg, 0, nil) miner.ActL1SetFeeRecipient(common.Address{'A'}) sequencer.ActL2PipelineFull(t) @@ -139,7 +139,7 @@ func (a *L2AltDA) NewVerifier(t Testing) *L2Verifier { daMgr := altda.NewAltDAWithStorage(a.log, a.altDACfg, a.storage, &altda.NoopMetrics{}) - verifier := NewL2Verifier(t, a.log, l1F, a.miner.BlobStore(), daMgr, engCl, a.sd.RollupCfg, &sync.Config{}, safedb.Disabled) + verifier := NewL2Verifier(t, a.log, l1F, a.miner.BlobStore(), daMgr, engCl, a.sd.RollupCfg, &sync.Config{}, safedb.Disabled, nil) return verifier } diff --git a/op-e2e/actions/batch_queue_test.go b/op-e2e/actions/batch_queue_test.go index 40ff0a2da2af..69c9957d134b 100644 --- a/op-e2e/actions/batch_queue_test.go +++ b/op-e2e/actions/batch_queue_test.go @@ -88,7 +88,8 @@ func TestDeriveChainFromNearL1Genesis(gt *testing.T) { // This is the same situation as if op-node restarted at this point. l2Cl, err := sources.NewEngineClient(seqEngine.RPCClient(), logger, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(gt, err) - verifier := NewL2Verifier(t, logger, sequencer.l1, miner.BlobStore(), altda.Disabled, l2Cl, sequencer.rollupCfg, sequencer.syncCfg, safedb.Disabled) + verifier := NewL2Verifier(t, logger, sequencer.l1, miner.BlobStore(), altda.Disabled, + l2Cl, sequencer.rollupCfg, sequencer.syncCfg, safedb.Disabled, nil) verifier.ActL2PipelineFull(t) // Should not get stuck in a reset loop forever require.EqualValues(gt, l2BlockNum, seqEngine.l2Chain.CurrentSafeBlock().Number.Uint64()) require.EqualValues(gt, l2BlockNum, seqEngine.l2Chain.CurrentFinalBlock().Number.Uint64()) diff --git a/op-e2e/actions/interop_test.go b/op-e2e/actions/interop_test.go new file mode 100644 index 000000000000..8890f86a0067 --- /dev/null +++ b/op-e2e/actions/interop_test.go @@ -0,0 +1,123 @@ +package actions + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-node/rollup/interop" + "github.com/ethereum-optimism/optimism/op-node/rollup/sync" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/testutils" + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" +) + +var _ interop.InteropBackend = (*testutils.MockInteropBackend)(nil) + +func TestInteropVerifier(gt *testing.T) { + t := NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + sd := e2eutils.Setup(t, dp, defaultAlloc) + // Temporary work-around: interop needs to be active, for cross-safety to not be instant. + // The state genesis in this test is pre-interop however. + sd.RollupCfg.InteropTime = new(uint64) + logger := testlog.Logger(t, log.LevelDebug) + seqMockBackend := &testutils.MockInteropBackend{} + l1Miner, seqEng, seq := setupSequencerTest(t, sd, logger, + WithVerifierOpts(WithInteropBackend(seqMockBackend))) + + batcher := NewL2Batcher(logger, sd.RollupCfg, DefaultBatcherCfg(dp), + seq.RollupClient(), l1Miner.EthClient(), seqEng.EthClient(), seqEng.EngineClient(t, sd.RollupCfg)) + + verMockBackend := &testutils.MockInteropBackend{} + _, ver := setupVerifier(t, sd, logger, + l1Miner.L1Client(t, sd.RollupCfg), l1Miner.BlobStore(), &sync.Config{}, + WithInteropBackend(verMockBackend)) + + seq.ActL2PipelineFull(t) + ver.ActL2PipelineFull(t) + + l2ChainID := types.ChainIDFromBig(sd.RollupCfg.L2ChainID) + seqMockBackend.ExpectCheckBlock(l2ChainID, 1, types.Unsafe, nil) + // create an unsafe L2 block + seq.ActL2StartBlock(t) + seq.ActL2EndBlock(t) + seq.ActL2PipelineFull(t) + seqMockBackend.AssertExpectations(t) + status := seq.SyncStatus() + require.Equal(t, uint64(1), status.UnsafeL2.Number) + require.Equal(t, uint64(0), status.CrossUnsafeL2.Number) + require.Equal(t, uint64(0), status.LocalSafeL2.Number) + require.Equal(t, uint64(0), status.SafeL2.Number) + + // promote it to cross-unsafe in the backend + // and see if the node picks up on it + seqMockBackend.ExpectCheckBlock(l2ChainID, 1, types.CrossUnsafe, nil) + seq.ActInteropBackendCheck(t) + seq.ActL2PipelineFull(t) + seqMockBackend.AssertExpectations(t) + status = seq.SyncStatus() + require.Equal(t, uint64(1), status.UnsafeL2.Number) + require.Equal(t, uint64(1), status.CrossUnsafeL2.Number, "cross unsafe now") + require.Equal(t, uint64(0), status.LocalSafeL2.Number) + require.Equal(t, uint64(0), status.SafeL2.Number) + + // submit all new L2 blocks + batcher.ActSubmitAll(t) + // new L1 block with L2 batch + l1Miner.ActL1StartBlock(12)(t) + l1Miner.ActL1IncludeTx(sd.RollupCfg.Genesis.SystemConfig.BatcherAddr)(t) + l1Miner.ActL1EndBlock(t) + + // Sync the L1 block, to verify the L2 block as local-safe. + seqMockBackend.ExpectCheckBlock(l2ChainID, 1, types.CrossUnsafe, nil) // not cross-safe yet + seq.ActL1HeadSignal(t) + seq.ActL2PipelineFull(t) + seqMockBackend.AssertExpectations(t) + + status = seq.SyncStatus() + require.Equal(t, uint64(1), status.UnsafeL2.Number) + require.Equal(t, uint64(1), status.CrossUnsafeL2.Number) + require.Equal(t, uint64(1), status.LocalSafeL2.Number, "local safe changed") + require.Equal(t, uint64(0), status.SafeL2.Number) + + // Now mark it as cross-safe + seqMockBackend.ExpectCheckBlock(l2ChainID, 1, types.CrossSafe, nil) + seq.ActInteropBackendCheck(t) + seq.ActL2PipelineFull(t) + seqMockBackend.AssertExpectations(t) + + status = seq.SyncStatus() + require.Equal(t, uint64(1), status.UnsafeL2.Number) + require.Equal(t, uint64(1), status.CrossUnsafeL2.Number) + require.Equal(t, uint64(1), status.LocalSafeL2.Number) + require.Equal(t, uint64(1), status.SafeL2.Number, "cross-safe reached") + require.Equal(t, uint64(0), status.FinalizedL2.Number) + + // The verifier might not see the L2 block that was just derived from L1 as cross-verified yet. + verMockBackend.ExpectCheckBlock(l2ChainID, 1, types.Unsafe, nil) // for the local unsafe check + verMockBackend.ExpectCheckBlock(l2ChainID, 1, types.Unsafe, nil) // for the local safe check + ver.ActL1HeadSignal(t) + ver.ActL2PipelineFull(t) + verMockBackend.AssertExpectations(t) + status = ver.SyncStatus() + require.Equal(t, uint64(1), status.UnsafeL2.Number, "synced the block") + require.Equal(t, uint64(0), status.CrossUnsafeL2.Number, "not cross-verified yet") + require.Equal(t, uint64(1), status.LocalSafeL2.Number, "derived from L1, thus local-safe") + require.Equal(t, uint64(0), status.SafeL2.Number, "not yet cross-safe") + require.Equal(t, uint64(0), status.FinalizedL2.Number) + + // signal that L1 finalized; the cross-safe block we have should get finalized too + l1Miner.ActL1SafeNext(t) + l1Miner.ActL1FinalizeNext(t) + seq.ActL1SafeSignal(t) + seq.ActL1FinalizedSignal(t) + seq.ActL2PipelineFull(t) + seqMockBackend.AssertExpectations(t) + + status = seq.SyncStatus() + require.Equal(t, uint64(1), status.FinalizedL2.Number, "finalized the block") +} diff --git a/op-e2e/actions/l2_sequencer.go b/op-e2e/actions/l2_sequencer.go index 7211537bc50c..a4626749b18a 100644 --- a/op-e2e/actions/l2_sequencer.go +++ b/op-e2e/actions/l2_sequencer.go @@ -19,6 +19,7 @@ import ( "github.com/ethereum-optimism/optimism/op-node/rollup/driver" "github.com/ethereum-optimism/optimism/op-node/rollup/engine" "github.com/ethereum-optimism/optimism/op-node/rollup/event" + "github.com/ethereum-optimism/optimism/op-node/rollup/interop" "github.com/ethereum-optimism/optimism/op-node/rollup/sequencing" "github.com/ethereum-optimism/optimism/op-node/rollup/sync" "github.com/ethereum-optimism/optimism/op-service/eth" @@ -50,8 +51,9 @@ type L2Sequencer struct { } func NewL2Sequencer(t Testing, log log.Logger, l1 derive.L1Fetcher, blobSrc derive.L1BlobsFetcher, - altDASrc driver.AltDAIface, eng L2API, cfg *rollup.Config, seqConfDepth uint64) *L2Sequencer { - ver := NewL2Verifier(t, log, l1, blobSrc, altDASrc, eng, cfg, &sync.Config{}, safedb.Disabled) + altDASrc driver.AltDAIface, eng L2API, cfg *rollup.Config, seqConfDepth uint64, + interopBackend interop.InteropBackend) *L2Sequencer { + ver := NewL2Verifier(t, log, l1, blobSrc, altDASrc, eng, cfg, &sync.Config{}, safedb.Disabled, interopBackend) attrBuilder := derive.NewFetchingAttributesBuilder(cfg, l1, eng) seqConfDepthL1 := confdepth.NewConfDepth(seqConfDepth, ver.syncStatus.L1Head, l1) l1OriginSelector := &MockL1OriginSelector{ diff --git a/op-e2e/actions/l2_sequencer_test.go b/op-e2e/actions/l2_sequencer_test.go index 6b8ec800408e..87cf95eaa425 100644 --- a/op-e2e/actions/l2_sequencer_test.go +++ b/op-e2e/actions/l2_sequencer_test.go @@ -37,8 +37,30 @@ func EngineWithP2P() EngineOption { } } -func setupSequencerTest(t Testing, sd *e2eutils.SetupData, log log.Logger) (*L1Miner, *L2Engine, *L2Sequencer) { +type sequencerCfg struct { + verifierCfg +} + +func defaultSequencerConfig() *sequencerCfg { + return &sequencerCfg{verifierCfg: *defaultVerifierCfg()} +} + +type SequencerOpt func(opts *sequencerCfg) + +func WithVerifierOpts(opts ...VerifierOpt) SequencerOpt { + return func(cfg *sequencerCfg) { + for _, opt := range opts { + opt(&cfg.verifierCfg) + } + } +} + +func setupSequencerTest(t Testing, sd *e2eutils.SetupData, log log.Logger, opts ...SequencerOpt) (*L1Miner, *L2Engine, *L2Sequencer) { jwtPath := e2eutils.WriteDefaultJWT(t) + cfg := defaultSequencerConfig() + for _, opt := range opts { + opt(cfg) + } miner := NewL1Miner(t, log.New("role", "l1-miner"), sd.L1Cfg) @@ -48,7 +70,7 @@ func setupSequencerTest(t Testing, sd *e2eutils.SetupData, log log.Logger) (*L1M l2Cl, err := sources.NewEngineClient(engine.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(t, err) - sequencer := NewL2Sequencer(t, log.New("role", "sequencer"), l1F, miner.BlobStore(), altda.Disabled, l2Cl, sd.RollupCfg, 0) + sequencer := NewL2Sequencer(t, log.New("role", "sequencer"), l1F, miner.BlobStore(), altda.Disabled, l2Cl, sd.RollupCfg, 0, cfg.interopBackend) return miner, engine, sequencer } diff --git a/op-e2e/actions/l2_verifier.go b/op-e2e/actions/l2_verifier.go index 5cc09c76c4e4..03de1a674f1c 100644 --- a/op-e2e/actions/l2_verifier.go +++ b/op-e2e/actions/l2_verifier.go @@ -23,6 +23,7 @@ import ( "github.com/ethereum-optimism/optimism/op-node/rollup/engine" "github.com/ethereum-optimism/optimism/op-node/rollup/event" "github.com/ethereum-optimism/optimism/op-node/rollup/finality" + "github.com/ethereum-optimism/optimism/op-node/rollup/interop" "github.com/ethereum-optimism/optimism/op-node/rollup/status" "github.com/ethereum-optimism/optimism/op-node/rollup/sync" "github.com/ethereum-optimism/optimism/op-service/client" @@ -84,7 +85,10 @@ type safeDB interface { node.SafeDBReader } -func NewL2Verifier(t Testing, log log.Logger, l1 derive.L1Fetcher, blobsSrc derive.L1BlobsFetcher, altDASrc driver.AltDAIface, eng L2API, cfg *rollup.Config, syncCfg *sync.Config, safeHeadListener safeDB) *L2Verifier { +func NewL2Verifier(t Testing, log log.Logger, l1 derive.L1Fetcher, + blobsSrc derive.L1BlobsFetcher, altDASrc driver.AltDAIface, + eng L2API, cfg *rollup.Config, syncCfg *sync.Config, safeHeadListener safeDB, + interopBackend interop.InteropBackend) *L2Verifier { ctx, cancel := context.WithCancel(context.Background()) t.Cleanup(cancel) @@ -104,6 +108,10 @@ func NewL2Verifier(t Testing, log log.Logger, l1 derive.L1Fetcher, blobsSrc deri }, } + if interopBackend != nil { + sys.Register("interop", interop.NewInteropDeriver(log, cfg, ctx, interopBackend, eng), opts) + } + metrics := &testutils.TestDerivationMetrics{} ec := engine.NewEngineController(eng, log, metrics, cfg, syncCfg, sys.Register("engine-controller", nil, opts)) @@ -316,6 +324,13 @@ func (s *L2Verifier) ActL1FinalizedSignal(t Testing) { require.Equal(t, finalized, s.syncStatus.SyncStatus().FinalizedL1) } +func (s *L2Verifier) ActInteropBackendCheck(t Testing) { + s.synchronousEvents.Emit(engine.CrossUpdateRequestEvent{ + CrossUnsafe: true, + CrossSafe: true, + }) +} + func (s *L2Verifier) OnEvent(ev event.Event) bool { switch x := ev.(type) { case rollup.L1TemporaryErrorEvent: diff --git a/op-e2e/actions/l2_verifier_test.go b/op-e2e/actions/l2_verifier_test.go index 328801214e04..f8f751ca6b7a 100644 --- a/op-e2e/actions/l2_verifier_test.go +++ b/op-e2e/actions/l2_verifier_test.go @@ -3,20 +3,22 @@ package actions import ( "testing" - altda "github.com/ethereum-optimism/optimism/op-alt-da" - "github.com/ethereum-optimism/optimism/op-node/node/safedb" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/require" + altda "github.com/ethereum-optimism/optimism/op-alt-da" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-node/node/safedb" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/ethereum-optimism/optimism/op-node/rollup/interop" "github.com/ethereum-optimism/optimism/op-node/rollup/sync" "github.com/ethereum-optimism/optimism/op-service/testlog" ) type verifierCfg struct { safeHeadListener safeDB + interopBackend interop.InteropBackend } type VerifierOpt func(opts *verifierCfg) @@ -27,13 +29,20 @@ func WithSafeHeadListener(l safeDB) VerifierOpt { } } +func WithInteropBackend(b interop.InteropBackend) VerifierOpt { + return func(opts *verifierCfg) { + opts.interopBackend = b + } +} + func defaultVerifierCfg() *verifierCfg { return &verifierCfg{ safeHeadListener: safedb.Disabled, } } -func setupVerifier(t Testing, sd *e2eutils.SetupData, log log.Logger, l1F derive.L1Fetcher, blobSrc derive.L1BlobsFetcher, syncCfg *sync.Config, opts ...VerifierOpt) (*L2Engine, *L2Verifier) { +func setupVerifier(t Testing, sd *e2eutils.SetupData, log log.Logger, + l1F derive.L1Fetcher, blobSrc derive.L1BlobsFetcher, syncCfg *sync.Config, opts ...VerifierOpt) (*L2Engine, *L2Verifier) { cfg := defaultVerifierCfg() for _, opt := range opts { opt(cfg) @@ -41,7 +50,7 @@ func setupVerifier(t Testing, sd *e2eutils.SetupData, log log.Logger, l1F derive jwtPath := e2eutils.WriteDefaultJWT(t) engine := NewL2Engine(t, log.New("role", "verifier-engine"), sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath, EngineWithP2P()) engCl := engine.EngineClient(t, sd.RollupCfg) - verifier := NewL2Verifier(t, log.New("role", "verifier"), l1F, blobSrc, altda.Disabled, engCl, sd.RollupCfg, syncCfg, cfg.safeHeadListener) + verifier := NewL2Verifier(t, log.New("role", "verifier"), l1F, blobSrc, altda.Disabled, engCl, sd.RollupCfg, syncCfg, cfg.safeHeadListener, cfg.interopBackend) return engine, verifier } diff --git a/op-e2e/actions/reorg_test.go b/op-e2e/actions/reorg_test.go index 4036d9fb131c..271b69cb1b29 100644 --- a/op-e2e/actions/reorg_test.go +++ b/op-e2e/actions/reorg_test.go @@ -613,7 +613,7 @@ func RestartOpGeth(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { engRpc := &rpcWrapper{seqEng.RPCClient()} l2Cl, err := sources.NewEngineClient(engRpc, log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(t, err) - sequencer := NewL2Sequencer(t, log, l1F, miner.BlobStore(), altda.Disabled, l2Cl, sd.RollupCfg, 0) + sequencer := NewL2Sequencer(t, log, l1F, miner.BlobStore(), altda.Disabled, l2Cl, sd.RollupCfg, 0, nil) batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), sequencer.RollupClient(), miner.EthClient(), seqEng.EthClient(), seqEng.EngineClient(t, sd.RollupCfg)) @@ -701,7 +701,7 @@ func ConflictingL2Blocks(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { require.NoError(t, err) l1F, err := sources.NewL1Client(miner.RPCClient(), log, nil, sources.L1ClientDefaultConfig(sd.RollupCfg, false, sources.RPCKindStandard)) require.NoError(t, err) - altSequencer := NewL2Sequencer(t, log, l1F, miner.BlobStore(), altda.Disabled, altSeqEngCl, sd.RollupCfg, 0) + altSequencer := NewL2Sequencer(t, log, l1F, miner.BlobStore(), altda.Disabled, altSeqEngCl, sd.RollupCfg, 0, nil) altBatcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), altSequencer.RollupClient(), miner.EthClient(), altSeqEng.EthClient(), altSeqEng.EngineClient(t, sd.RollupCfg)) diff --git a/op-e2e/actions/sync_test.go b/op-e2e/actions/sync_test.go index 78297a5a8135..5f78739631cc 100644 --- a/op-e2e/actions/sync_test.go +++ b/op-e2e/actions/sync_test.go @@ -819,7 +819,7 @@ func TestELSyncTransitionsToCLSyncAfterNodeRestart(gt *testing.T) { PrepareELSyncedNode(t, miner, sequencer, seqEng, verifier, verEng, seqEngCl, batcher, dp) // Create a new verifier which is essentially a new op-node with the sync mode of ELSync and default geth engine kind. - verifier = NewL2Verifier(t, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), altda.Disabled, verifier.eng, sd.RollupCfg, &sync.Config{SyncMode: sync.ELSync}, defaultVerifierCfg().safeHeadListener) + verifier = NewL2Verifier(t, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), altda.Disabled, verifier.eng, sd.RollupCfg, &sync.Config{SyncMode: sync.ELSync}, defaultVerifierCfg().safeHeadListener, nil) // Build another 10 L1 blocks on the sequencer for i := 0; i < 10; i++ { @@ -861,7 +861,7 @@ func TestForcedELSyncCLAfterNodeRestart(gt *testing.T) { PrepareELSyncedNode(t, miner, sequencer, seqEng, verifier, verEng, seqEngCl, batcher, dp) // Create a new verifier which is essentially a new op-node with the sync mode of ELSync and erigon engine kind. - verifier2 := NewL2Verifier(t, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), altda.Disabled, verifier.eng, sd.RollupCfg, &sync.Config{SyncMode: sync.ELSync, SupportsPostFinalizationELSync: true}, defaultVerifierCfg().safeHeadListener) + verifier2 := NewL2Verifier(t, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), altda.Disabled, verifier.eng, sd.RollupCfg, &sync.Config{SyncMode: sync.ELSync, SupportsPostFinalizationELSync: true}, defaultVerifierCfg().safeHeadListener, nil) // Build another 10 L1 blocks on the sequencer for i := 0; i < 10; i++ { @@ -1039,12 +1039,19 @@ func TestSpanBatchAtomicity_Consolidation(gt *testing.T) { verifier.l2PipelineIdle = false for !verifier.l2PipelineIdle { // wait for next pending block - verifier.ActL2EventsUntil(t, event.Any( - event.Is[engine2.PendingSafeUpdateEvent], event.Is[derive.DeriverIdleEvent]), 1000, false) + verifier.ActL2EventsUntil(t, func(ev event.Event) bool { + if event.Is[engine2.SafeDerivedEvent](ev) { // safe updates should only happen once the pending-safe reaches the target. + t.Fatal("unexpected next safe update") + } + return event.Any(event.Is[engine2.PendingSafeUpdateEvent], event.Is[derive.DeriverIdleEvent])(ev) + }, 1000, false) if verifier.L2PendingSafe().Number < targetHeadNumber { // If the span batch is not fully processed, the safe head must not advance. require.Equal(t, verifier.L2Safe().Number, uint64(0)) } else { + // Make sure we do the post-processing of what safety updates might happen + // after the pending-safe event, before the next pending-safe event. + verifier.ActL2EventsUntil(t, event.Is[engine2.PendingSafeUpdateEvent], 100, true) // Once the span batch is fully processed, the safe head must advance to the end of span batch. require.Equal(t, verifier.L2Safe().Number, targetHeadNumber) require.Equal(t, verifier.L2Safe(), verifier.L2PendingSafe()) @@ -1088,12 +1095,19 @@ func TestSpanBatchAtomicity_ForceAdvance(gt *testing.T) { verifier.l2PipelineIdle = false for !verifier.l2PipelineIdle { // wait for next pending block - verifier.ActL2EventsUntil(t, event.Any( - event.Is[engine2.PendingSafeUpdateEvent], event.Is[derive.DeriverIdleEvent]), 1000, false) + verifier.ActL2EventsUntil(t, func(ev event.Event) bool { + if event.Is[engine2.SafeDerivedEvent](ev) { // safe updates should only happen once the pending-safe reaches the target. + t.Fatal("unexpected next safe update") + } + return event.Any(event.Is[engine2.PendingSafeUpdateEvent], event.Is[derive.DeriverIdleEvent])(ev) + }, 1000, false) if verifier.L2PendingSafe().Number < targetHeadNumber { // If the span batch is not fully processed, the safe head must not advance. require.Equal(t, verifier.L2Safe().Number, uint64(0)) } else { + // Make sure we do the post-processing of what safety updates might happen + // after the pending-safe event, before the next pending-safe event. + verifier.ActL2EventsUntil(t, event.Is[engine2.PendingSafeUpdateEvent], 100, true) // Once the span batch is fully processed, the safe head must advance to the end of span batch. require.Equal(t, verifier.L2Safe().Number, targetHeadNumber) require.Equal(t, verifier.L2Safe(), verifier.L2PendingSafe()) diff --git a/op-node/flags/flags.go b/op-node/flags/flags.go index b3af25d66143..dcb1597ce6e5 100644 --- a/op-node/flags/flags.go +++ b/op-node/flags/flags.go @@ -73,6 +73,13 @@ var ( EnvVars: prefixEnvVars("L1_BEACON"), Category: RollupCategory, } + SupervisorAddr = &cli.StringFlag{ + Name: "supervisor", + Usage: "RPC address of interop supervisor service for cross-chain safety verification." + + "Applies only to Interop-enabled networks.", + Hidden: true, // hidden for now during early testing. + EnvVars: prefixEnvVars("SUPERVISOR"), + } /* Optional Flags */ BeaconHeader = &cli.StringFlag{ Name: "l1.beacon-header", @@ -374,6 +381,7 @@ var requiredFlags = []cli.Flag{ } var optionalFlags = []cli.Flag{ + SupervisorAddr, BeaconAddr, BeaconHeader, BeaconFallbackAddrs, diff --git a/op-node/node/client.go b/op-node/node/client.go index a1c4754616c5..caa290ddbbe8 100644 --- a/op-node/node/client.go +++ b/op-node/node/client.go @@ -230,3 +230,29 @@ func parseHTTPHeader(headerStr string) (http.Header, error) { h.Add(s[0], s[1]) return h, nil } + +type SupervisorEndpointSetup interface { + SupervisorClient(ctx context.Context, log log.Logger) (*sources.SupervisorClient, error) + Check() error +} + +type SupervisorEndpointConfig struct { + SupervisorAddr string +} + +var _ SupervisorEndpointSetup = (*SupervisorEndpointConfig)(nil) + +func (cfg *SupervisorEndpointConfig) Check() error { + if cfg.SupervisorAddr == "" { + return errors.New("supervisor RPC address is not set") + } + return nil +} + +func (cfg *SupervisorEndpointConfig) SupervisorClient(ctx context.Context, log log.Logger) (*sources.SupervisorClient, error) { + cl, err := client.NewRPC(ctx, log, cfg.SupervisorAddr) + if err != nil { + return nil, fmt.Errorf("failed to dial supervisor RPC: %w", err) + } + return sources.NewSupervisorClient(cl), nil +} diff --git a/op-node/node/config.go b/op-node/node/config.go index d52da967f14a..a78b55853aa2 100644 --- a/op-node/node/config.go +++ b/op-node/node/config.go @@ -23,6 +23,8 @@ type Config struct { Beacon L1BeaconEndpointSetup + Supervisor SupervisorEndpointSetup + Driver driver.Config Rollup rollup.Config @@ -130,12 +132,20 @@ func (cfg *Config) Check() error { } if cfg.Rollup.EcotoneTime != nil { if cfg.Beacon == nil { - return fmt.Errorf("the Ecotone upgrade is scheduled but no L1 Beacon API endpoint is configured") + return fmt.Errorf("the Ecotone upgrade is scheduled (timestamp = %d) but no L1 Beacon API endpoint is configured", *cfg.Rollup.EcotoneTime) } if err := cfg.Beacon.Check(); err != nil { return fmt.Errorf("misconfigured L1 Beacon API endpoint: %w", err) } } + if cfg.Rollup.InteropTime != nil { + if cfg.Supervisor == nil { + return fmt.Errorf("the Interop upgrade is scheduled (timestamp = %d) but no supervisor RPC endpoint is configured", *cfg.Rollup.InteropTime) + } + if err := cfg.Supervisor.Check(); err != nil { + return fmt.Errorf("misconfigured supervisor RPC endpoint: %w", err) + } + } if err := cfg.Rollup.Check(); err != nil { return fmt.Errorf("rollup config error: %w", err) } diff --git a/op-node/node/node.go b/op-node/node/node.go index c60121f7d168..13142bdf3343 100644 --- a/op-node/node/node.go +++ b/op-node/node/node.go @@ -70,6 +70,8 @@ type OpNode struct { beacon *sources.L1BeaconClient + supervisor *sources.SupervisorClient + // some resources cannot be stopped directly, like the p2p gossipsub router (not our design), // and depend on this ctx to be closed. resourcesCtx context.Context @@ -379,6 +381,14 @@ func (n *OpNode) initL2(ctx context.Context, cfg *Config) error { return err } + if cfg.Rollup.InteropTime != nil { + cl, err := cfg.Supervisor.SupervisorClient(ctx, n.log) + if err != nil { + return fmt.Errorf("failed to setup supervisor RPC client: %w", err) + } + n.supervisor = cl + } + var sequencerConductor conductor.SequencerConductor = &conductor.NoOpConductor{} if cfg.ConductorEnabled { sequencerConductor = NewConductorClient(cfg, n.log, n.metrics) @@ -400,7 +410,8 @@ func (n *OpNode) initL2(ctx context.Context, cfg *Config) error { } else { n.safeDB = safedb.Disabled } - n.l2Driver = driver.NewDriver(&cfg.Driver, &cfg.Rollup, n.l2Source, n.l1Source, n.beacon, n, n, n.log, n.metrics, cfg.ConfigPersistence, n.safeDB, &cfg.Sync, sequencerConductor, altDA) + n.l2Driver = driver.NewDriver(&cfg.Driver, &cfg.Rollup, n.l2Source, n.l1Source, + n.supervisor, n.beacon, n, n, n.log, n.metrics, cfg.ConfigPersistence, n.safeDB, &cfg.Sync, sequencerConductor, altDA) return nil } @@ -684,6 +695,11 @@ func (n *OpNode) Stop(ctx context.Context) error { n.l2Source.Close() } + // close the supervisor RPC client + if n.supervisor != nil { + n.supervisor.Close() + } + // close L1 data source if n.l1Source != nil { n.l1Source.Close() diff --git a/op-node/rollup/driver/driver.go b/op-node/rollup/driver/driver.go index 3a3272387821..8c4c975c87cf 100644 --- a/op-node/rollup/driver/driver.go +++ b/op-node/rollup/driver/driver.go @@ -17,6 +17,7 @@ import ( "github.com/ethereum-optimism/optimism/op-node/rollup/engine" "github.com/ethereum-optimism/optimism/op-node/rollup/event" "github.com/ethereum-optimism/optimism/op-node/rollup/finality" + "github.com/ethereum-optimism/optimism/op-node/rollup/interop" "github.com/ethereum-optimism/optimism/op-node/rollup/sequencing" "github.com/ethereum-optimism/optimism/op-node/rollup/status" "github.com/ethereum-optimism/optimism/op-node/rollup/sync" @@ -155,6 +156,7 @@ func NewDriver( cfg *rollup.Config, l2 L2Chain, l1 L1Chain, + supervisor interop.InteropBackend, // may be nil pre-interop. l1Blobs derive.L1BlobsFetcher, altSync AltSync, network Network, @@ -181,6 +183,14 @@ func NewDriver( opts := event.DefaultRegisterOpts() + // If interop is scheduled we start the driver. + // It will then be ready to pick up verification work + // as soon as we reach the upgrade time (if the upgrade is not already active). + if cfg.InteropTime != nil { + interopDeriver := interop.NewInteropDeriver(log, cfg, driverCtx, supervisor, l2) + sys.Register("interop", interopDeriver, opts) + } + statusTracker := status.NewStatusTracker(log, metrics) sys.Register("status", statusTracker, opts) diff --git a/op-node/rollup/driver/state.go b/op-node/rollup/driver/state.go index f851291bcb9c..73374dbf8055 100644 --- a/op-node/rollup/driver/state.go +++ b/op-node/rollup/driver/state.go @@ -465,6 +465,12 @@ func (s *SyncDeriver) SyncStep() { // Upon the pending-safe signal the attributes deriver can then ask the pipeline // to generate new attributes, if no attributes are known already. s.Emitter.Emit(engine.PendingSafeRequestEvent{}) + + // If interop is configured, we have to run the engine events, + // to ensure cross-L2 safety is continuously verified against the interop-backend. + if s.Config.InteropTime != nil { + s.Emitter.Emit(engine.CrossUpdateRequestEvent{}) + } } // ResetDerivationPipeline forces a reset of the derivation pipeline. diff --git a/op-node/rollup/engine/engine_controller.go b/op-node/rollup/engine/engine_controller.go index d8db9cad949c..f2266382a206 100644 --- a/op-node/rollup/engine/engine_controller.go +++ b/op-node/rollup/engine/engine_controller.go @@ -56,12 +56,27 @@ type EngineController struct { emitter event.Emitter // Block Head State - unsafeHead eth.L2BlockRef - pendingSafeHead eth.L2BlockRef // L2 block processed from the middle of a span batch, but not marked as the safe block yet. - safeHead eth.L2BlockRef - finalizedHead eth.L2BlockRef + unsafeHead eth.L2BlockRef + // Cross-verified unsafeHead, always equal to unsafeHead pre-interop + crossUnsafeHead eth.L2BlockRef + // Pending localSafeHead + // L2 block processed from the middle of a span batch, + // but not marked as the safe block yet. + pendingSafeHead eth.L2BlockRef + // Derived from L1, and known to be a completed span-batch, + // but not cross-verified yet. + localSafeHead eth.L2BlockRef + // Derived from L1 and cross-verified to have cross-safe dependencies. + safeHead eth.L2BlockRef + // Derived from finalized L1 data, + // and cross-verified to only have finalized dependencies. + finalizedHead eth.L2BlockRef + // The unsafe head to roll back to, + // after the pendingSafeHead fails to become safe. + // This is changing in the Holocene fork. backupUnsafeHead eth.L2BlockRef - needFCUCall bool + + needFCUCall bool // Track when the rollup node changes the forkchoice to restore previous // known unsafe chain. e.g. Unsafe Reorg caused by Invalid span batch. // This update does not retry except engine returns non-input error @@ -96,10 +111,18 @@ func (e *EngineController) UnsafeL2Head() eth.L2BlockRef { return e.unsafeHead } +func (e *EngineController) CrossUnsafeL2Head() eth.L2BlockRef { + return e.crossUnsafeHead +} + func (e *EngineController) PendingSafeL2Head() eth.L2BlockRef { return e.pendingSafeHead } +func (e *EngineController) LocalSafeL2Head() eth.L2BlockRef { + return e.localSafeHead +} + func (e *EngineController) SafeL2Head() eth.L2BlockRef { return e.safeHead } @@ -131,14 +154,20 @@ func (e *EngineController) SetPendingSafeL2Head(r eth.L2BlockRef) { e.pendingSafeHead = r } -// SetSafeHead implements LocalEngineControl. +// SetLocalSafeHead sets the local-safe head. +func (e *EngineController) SetLocalSafeHead(r eth.L2BlockRef) { + e.metrics.RecordL2Ref("l2_local_safe", r) + e.localSafeHead = r +} + +// SetSafeHead sets the cross-safe head. func (e *EngineController) SetSafeHead(r eth.L2BlockRef) { e.metrics.RecordL2Ref("l2_safe", r) e.safeHead = r e.needFCUCall = true } -// SetUnsafeHead implements LocalEngineControl. +// SetUnsafeHead sets the local-unsafe head. func (e *EngineController) SetUnsafeHead(r eth.L2BlockRef) { e.metrics.RecordL2Ref("l2_unsafe", r) e.unsafeHead = r @@ -146,6 +175,12 @@ func (e *EngineController) SetUnsafeHead(r eth.L2BlockRef) { e.chainSpec.CheckForkActivation(e.log, r) } +// SetCrossUnsafeHead the cross-unsafe head. +func (e *EngineController) SetCrossUnsafeHead(r eth.L2BlockRef) { + e.metrics.RecordL2Ref("l2_cross_unsafe", r) + e.crossUnsafeHead = r +} + // SetBackupUnsafeL2Head implements LocalEngineControl. func (e *EngineController) SetBackupUnsafeL2Head(r eth.L2BlockRef, triggerReorg bool) { e.metrics.RecordL2Ref("l2_backup_unsafe", r) @@ -310,7 +345,11 @@ func (e *EngineController) InsertUnsafePayload(ctx context.Context, envelope *et if e.syncStatus == syncStatusFinishedELButNotFinalized { fc.SafeBlockHash = envelope.ExecutionPayload.BlockHash fc.FinalizedBlockHash = envelope.ExecutionPayload.BlockHash + e.SetUnsafeHead(ref) // ensure that the unsafe head stays ahead of safe/finalized labels. + e.emitter.Emit(UnsafeUpdateEvent{Ref: ref}) + e.SetLocalSafeHead(ref) e.SetSafeHead(ref) + e.emitter.Emit(CrossSafeUpdateEvent{LocalSafe: ref, CrossSafe: ref}) e.SetFinalizedHead(ref) } logFn := e.logSyncProgressMaybe() @@ -336,6 +375,7 @@ func (e *EngineController) InsertUnsafePayload(ctx context.Context, envelope *et } e.SetUnsafeHead(ref) e.needFCUCall = false + e.emitter.Emit(UnsafeUpdateEvent{Ref: ref}) if e.syncStatus == syncStatusFinishedELButNotFinalized { e.log.Info("Finished EL sync", "sync_duration", e.clock.Since(e.elStart), "finalized_block", ref.ID().String()) diff --git a/op-node/rollup/engine/events.go b/op-node/rollup/engine/events.go index 325118825fce..b5e010280ebc 100644 --- a/op-node/rollup/engine/events.go +++ b/op-node/rollup/engine/events.go @@ -40,6 +40,55 @@ func (ev ForkchoiceUpdateEvent) String() string { return "forkchoice-update" } +// PromoteUnsafeEvent signals that the given block may now become a canonical unsafe block. +// This is pre-forkchoice update; the change may not be reflected yet in the EL. +// Note that the legacy pre-event-refactor code-path (processing P2P blocks) does fire this, +// but manually, duplicate with the newer events processing code-path. +// See EngineController.InsertUnsafePayload. +type PromoteUnsafeEvent struct { + Ref eth.L2BlockRef +} + +func (ev PromoteUnsafeEvent) String() string { + return "promote-unsafe" +} + +// RequestCrossUnsafeEvent signals that a CrossUnsafeUpdateEvent is needed. +type RequestCrossUnsafeEvent struct{} + +func (ev RequestCrossUnsafeEvent) String() string { + return "request-cross-unsafe" +} + +// UnsafeUpdateEvent signals that the given block is now considered safe. +// This is pre-forkchoice update; the change may not be reflected yet in the EL. +type UnsafeUpdateEvent struct { + Ref eth.L2BlockRef +} + +func (ev UnsafeUpdateEvent) String() string { + return "unsafe-update" +} + +// PromoteCrossUnsafeEvent signals that the given block may be promoted to cross-unsafe. +type PromoteCrossUnsafeEvent struct { + Ref eth.L2BlockRef +} + +func (ev PromoteCrossUnsafeEvent) String() string { + return "promote-cross-unsafe" +} + +// CrossUnsafeUpdateEvent signals that the given block is now considered cross-unsafe. +type CrossUnsafeUpdateEvent struct { + CrossUnsafe eth.L2BlockRef + LocalUnsafe eth.L2BlockRef +} + +func (ev CrossUnsafeUpdateEvent) String() string { + return "cross-unsafe-update" +} + type PendingSafeUpdateEvent struct { PendingSafe eth.L2BlockRef Unsafe eth.L2BlockRef // tip, added to the signal, to determine if there are existing blocks to consolidate @@ -60,7 +109,54 @@ func (ev PromotePendingSafeEvent) String() string { return "promote-pending-safe" } -// SafeDerivedEvent signals that a block was determined to be safe, and derived from the given L1 block +// PromoteLocalSafeEvent signals that a block can be promoted to local-safe. +type PromoteLocalSafeEvent struct { + Ref eth.L2BlockRef + DerivedFrom eth.L1BlockRef +} + +func (ev PromoteLocalSafeEvent) String() string { + return "promote-local-safe" +} + +// RequestCrossSafeEvent signals that a CrossSafeUpdate is needed. +type RequestCrossSafeEvent struct{} + +func (ev RequestCrossSafeEvent) String() string { + return "request-cross-safe-update" +} + +type CrossSafeUpdateEvent struct { + CrossSafe eth.L2BlockRef + LocalSafe eth.L2BlockRef +} + +func (ev CrossSafeUpdateEvent) String() string { + return "cross-safe-update" +} + +// LocalSafeUpdateEvent signals that a block is now considered to be local-safe. +type LocalSafeUpdateEvent struct { + Ref eth.L2BlockRef + DerivedFrom eth.L1BlockRef +} + +func (ev LocalSafeUpdateEvent) String() string { + return "local-safe-update" +} + +// PromoteSafeEvent signals that a block can be promoted to cross-safe. +type PromoteSafeEvent struct { + Ref eth.L2BlockRef + DerivedFrom eth.L1BlockRef +} + +func (ev PromoteSafeEvent) String() string { + return "promote-safe" +} + +// SafeDerivedEvent signals that a block was determined to be safe, and derived from the given L1 block. +// This is signaled upon successful processing of PromoteSafeEvent. type SafeDerivedEvent struct { Safe eth.L2BlockRef DerivedFrom eth.L1BlockRef @@ -133,6 +229,16 @@ func (ev PromoteFinalizedEvent) String() string { return "promote-finalized" } +// CrossUpdateRequestEvent triggers update events to be emitted, repeating the current state. +type CrossUpdateRequestEvent struct { + CrossUnsafe bool + CrossSafe bool +} + +func (ev CrossUpdateRequestEvent) String() string { + return "cross-update-request" +} + type EngDeriver struct { metrics Metrics @@ -234,6 +340,36 @@ func (d *EngDeriver) OnEvent(ev event.Event) bool { "safeHead", x.Safe, "unsafe", x.Unsafe, "safe_timestamp", x.Safe.Time, "unsafe_timestamp", x.Unsafe.Time) d.emitter.Emit(EngineResetConfirmedEvent(x)) + case PromoteUnsafeEvent: + // Backup unsafeHead when new block is not built on original unsafe head. + if d.ec.unsafeHead.Number >= x.Ref.Number { + d.ec.SetBackupUnsafeL2Head(d.ec.unsafeHead, false) + } + d.ec.SetUnsafeHead(x.Ref) + d.emitter.Emit(UnsafeUpdateEvent(x)) + case UnsafeUpdateEvent: + // pre-interop everything that is local-unsafe is also immediately cross-unsafe. + if !d.cfg.IsInterop(x.Ref.Time) { + d.emitter.Emit(PromoteCrossUnsafeEvent(x)) + } + // Try to apply the forkchoice changes + d.emitter.Emit(TryUpdateEngineEvent{}) + case PromoteCrossUnsafeEvent: + d.ec.SetCrossUnsafeHead(x.Ref) + d.emitter.Emit(CrossUnsafeUpdateEvent{ + CrossUnsafe: x.Ref, + LocalUnsafe: d.ec.UnsafeL2Head(), + }) + case RequestCrossUnsafeEvent: + d.emitter.Emit(CrossUnsafeUpdateEvent{ + CrossUnsafe: d.ec.CrossUnsafeL2Head(), + LocalUnsafe: d.ec.UnsafeL2Head(), + }) + case RequestCrossSafeEvent: + d.emitter.Emit(CrossSafeUpdateEvent{ + CrossSafe: d.ec.SafeL2Head(), + LocalSafe: d.ec.LocalSafeL2Head(), + }) case PendingSafeRequestEvent: d.emitter.Emit(PendingSafeUpdateEvent{ PendingSafe: d.ec.PendingSafeL2Head(), @@ -249,12 +385,30 @@ func (d *EngDeriver) OnEvent(ev event.Event) bool { Unsafe: d.ec.UnsafeL2Head(), }) } - if x.Safe && x.Ref.Number > d.ec.SafeL2Head().Number { - d.ec.SetSafeHead(x.Ref) - d.emitter.Emit(SafeDerivedEvent{Safe: x.Ref, DerivedFrom: x.DerivedFrom}) - // Try to apply the forkchoice changes - d.emitter.Emit(TryUpdateEngineEvent{}) + if x.Safe && x.Ref.Number > d.ec.LocalSafeL2Head().Number { + d.emitter.Emit(PromoteLocalSafeEvent{ + Ref: x.Ref, + DerivedFrom: x.DerivedFrom, + }) + } + case PromoteLocalSafeEvent: + d.ec.SetLocalSafeHead(x.Ref) + d.emitter.Emit(LocalSafeUpdateEvent(x)) + case LocalSafeUpdateEvent: + // pre-interop everything that is local-safe is also immediately cross-safe. + if !d.cfg.IsInterop(x.Ref.Time) { + d.emitter.Emit(PromoteSafeEvent(x)) } + case PromoteSafeEvent: + d.ec.SetSafeHead(x.Ref) + // Finalizer can pick up this safe cross-block now + d.emitter.Emit(SafeDerivedEvent{Safe: x.Ref, DerivedFrom: x.DerivedFrom}) + d.emitter.Emit(CrossSafeUpdateEvent{ + CrossSafe: d.ec.SafeL2Head(), + LocalSafe: d.ec.LocalSafeL2Head(), + }) + // Try to apply the forkchoice changes + d.emitter.Emit(TryUpdateEngineEvent{}) case PromoteFinalizedEvent: if x.Ref.Number < d.ec.Finalized().Number { d.log.Error("Cannot rewind finality,", "ref", x.Ref, "finalized", d.ec.Finalized()) @@ -267,6 +421,19 @@ func (d *EngDeriver) OnEvent(ev event.Event) bool { d.ec.SetFinalizedHead(x.Ref) // Try to apply the forkchoice changes d.emitter.Emit(TryUpdateEngineEvent{}) + case CrossUpdateRequestEvent: + if x.CrossUnsafe { + d.emitter.Emit(CrossUnsafeUpdateEvent{ + CrossUnsafe: d.ec.CrossUnsafeL2Head(), + LocalUnsafe: d.ec.UnsafeL2Head(), + }) + } + if x.CrossSafe { + d.emitter.Emit(CrossSafeUpdateEvent{ + CrossSafe: d.ec.SafeL2Head(), + LocalSafe: d.ec.LocalSafeL2Head(), + }) + } case BuildStartEvent: d.onBuildStart(x) case BuildStartedEvent: @@ -295,6 +462,8 @@ type ResetEngineControl interface { SetUnsafeHead(eth.L2BlockRef) SetSafeHead(eth.L2BlockRef) SetFinalizedHead(eth.L2BlockRef) + SetLocalSafeHead(ref eth.L2BlockRef) + SetCrossUnsafeHead(ref eth.L2BlockRef) SetBackupUnsafeL2Head(block eth.L2BlockRef, triggerReorg bool) SetPendingSafeL2Head(eth.L2BlockRef) } @@ -302,8 +471,10 @@ type ResetEngineControl interface { // ForceEngineReset is not to be used. The op-program needs it for now, until event processing is adopted there. func ForceEngineReset(ec ResetEngineControl, x ForceEngineResetEvent) { ec.SetUnsafeHead(x.Unsafe) - ec.SetSafeHead(x.Safe) + ec.SetLocalSafeHead(x.Safe) ec.SetPendingSafeL2Head(x.Safe) ec.SetFinalizedHead(x.Finalized) + ec.SetSafeHead(x.Safe) + ec.SetCrossUnsafeHead(x.Safe) ec.SetBackupUnsafeL2Head(eth.L2BlockRef{}, false) } diff --git a/op-node/rollup/engine/payload_success.go b/op-node/rollup/engine/payload_success.go index cdd2ee2d030b..7bb4a38307e1 100644 --- a/op-node/rollup/engine/payload_success.go +++ b/op-node/rollup/engine/payload_success.go @@ -19,23 +19,14 @@ func (ev PayloadSuccessEvent) String() string { } func (eq *EngDeriver) onPayloadSuccess(ev PayloadSuccessEvent) { - - // Backup unsafeHead when new block is not built on original unsafe head. - if eq.ec.unsafeHead.Number >= ev.Ref.Number { - eq.ec.SetBackupUnsafeL2Head(eq.ec.unsafeHead, false) - } - eq.ec.SetUnsafeHead(ev.Ref) + eq.emitter.Emit(PromoteUnsafeEvent{Ref: ev.Ref}) // If derived from L1, then it can be considered (pending) safe if ev.DerivedFrom != (eth.L1BlockRef{}) { - if ev.IsLastInSpan { - eq.ec.SetSafeHead(ev.Ref) - eq.emitter.Emit(SafeDerivedEvent{Safe: ev.Ref, DerivedFrom: ev.DerivedFrom}) - } - eq.ec.SetPendingSafeL2Head(ev.Ref) - eq.emitter.Emit(PendingSafeUpdateEvent{ - PendingSafe: eq.ec.PendingSafeL2Head(), - Unsafe: eq.ec.UnsafeL2Head(), + eq.emitter.Emit(PromotePendingSafeEvent{ + Ref: ev.Ref, + Safe: ev.IsLastInSpan, + DerivedFrom: ev.DerivedFrom, }) } diff --git a/op-node/rollup/interop/interop.go b/op-node/rollup/interop/interop.go new file mode 100644 index 000000000000..c6c170478f21 --- /dev/null +++ b/op-node/rollup/interop/interop.go @@ -0,0 +1,161 @@ +package interop + +import ( + "context" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-node/rollup/engine" + "github.com/ethereum-optimism/optimism/op-node/rollup/event" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" +) + +const checkBlockTimeout = time.Second * 10 + +type InteropBackend interface { + CheckBlock(ctx context.Context, + chainID types.ChainID, blockHash common.Hash, blockNumber uint64) (types.SafetyLevel, error) +} + +type L2Source interface { + L2BlockRefByNumber(context.Context, uint64) (eth.L2BlockRef, error) +} + +// InteropDeriver watches for update events (either real changes to block safety, +// or updates published upon request), checks if there is some local data to cross-verify, +// and then checks with the interop-backend, to try to promote to cross-verified safety. +type InteropDeriver struct { + log log.Logger + cfg *rollup.Config + + // we cache the chainID, + // to not continuously convert from the type in the rollup-config to this type. + chainID types.ChainID + + driverCtx context.Context + + // L2 blockhash -> derived from L1 block ref. + // Added to when a block is local-safe. + // Removed from when it is promoted to cross-safe. + derivedFrom map[common.Hash]eth.L1BlockRef + + backend InteropBackend + l2 L2Source + + emitter event.Emitter + + mu sync.Mutex +} + +var _ event.Deriver = (*InteropDeriver)(nil) +var _ event.AttachEmitter = (*InteropDeriver)(nil) + +func NewInteropDeriver(log log.Logger, cfg *rollup.Config, + driverCtx context.Context, backend InteropBackend, l2 L2Source) *InteropDeriver { + return &InteropDeriver{ + log: log, + cfg: cfg, + chainID: types.ChainIDFromBig(cfg.L2ChainID), + driverCtx: driverCtx, + derivedFrom: make(map[common.Hash]eth.L1BlockRef), + backend: backend, + l2: l2, + } +} + +func (d *InteropDeriver) AttachEmitter(em event.Emitter) { + d.emitter = em +} + +func (d *InteropDeriver) OnEvent(ev event.Event) bool { + d.mu.Lock() + defer d.mu.Unlock() + + switch x := ev.(type) { + case engine.UnsafeUpdateEvent: + d.emitter.Emit(engine.RequestCrossUnsafeEvent{}) + case engine.CrossUnsafeUpdateEvent: + if x.CrossUnsafe.Number >= x.LocalUnsafe.Number { + break // nothing left to promote + } + // Pre-interop the engine itself handles promotion to cross-unsafe. + // Check if the next block (still unsafe) can be promoted to cross-unsafe. + if !d.cfg.IsInterop(d.cfg.TimestampForBlock(x.CrossUnsafe.Number + 1)) { + return false + } + ctx, cancel := context.WithTimeout(d.driverCtx, checkBlockTimeout) + defer cancel() + candidate, err := d.l2.L2BlockRefByNumber(ctx, x.CrossUnsafe.Number+1) + if err != nil { + d.log.Warn("Failed to fetch next cross-unsafe candidate", "err", err) + break + } + blockSafety, err := d.backend.CheckBlock(ctx, d.chainID, candidate.Hash, candidate.Number) + if err != nil { + d.log.Warn("Failed to check interop safety of unsafe block", "err", err) + break + } + switch blockSafety { + case types.CrossUnsafe, types.CrossSafe, types.CrossFinalized: + // Hold off on promoting higher than cross-unsafe, + // this will happen once we verify it to be local-safe first. + d.emitter.Emit(engine.PromoteCrossUnsafeEvent{Ref: candidate}) + } + case engine.LocalSafeUpdateEvent: + d.derivedFrom[x.Ref.Hash] = x.DerivedFrom + d.emitter.Emit(engine.RequestCrossSafeEvent{}) + case engine.CrossSafeUpdateEvent: + if x.CrossSafe.Number >= x.LocalSafe.Number { + break // nothing left to promote + } + // Pre-interop the engine itself handles promotion to cross-safe. + // Check if the next block (not yet cross-safe) can be promoted to cross-safe. + if !d.cfg.IsInterop(d.cfg.TimestampForBlock(x.CrossSafe.Number + 1)) { + return false + } + ctx, cancel := context.WithTimeout(d.driverCtx, checkBlockTimeout) + defer cancel() + candidate, err := d.l2.L2BlockRefByNumber(ctx, x.CrossSafe.Number+1) + if err != nil { + d.log.Warn("Failed to fetch next cross-safe candidate", "err", err) + break + } + blockSafety, err := d.backend.CheckBlock(ctx, d.chainID, candidate.Hash, candidate.Number) + if err != nil { + d.log.Warn("Failed to check interop safety of local-safe block", "err", err) + break + } + derivedFrom, ok := d.derivedFrom[candidate.Hash] + if !ok { + break + } + switch blockSafety { + case types.CrossSafe: + // TODO(#11673): once we have interop reorg support, we need to clean stale blocks also. + delete(d.derivedFrom, candidate.Hash) + d.emitter.Emit(engine.PromoteSafeEvent{ + Ref: candidate, + DerivedFrom: derivedFrom, + }) + case types.Finalized: + // TODO(#11673): once we have interop reorg support, we need to clean stale blocks also. + delete(d.derivedFrom, candidate.Hash) + d.emitter.Emit(engine.PromoteSafeEvent{ + Ref: candidate, + DerivedFrom: derivedFrom, + }) + d.emitter.Emit(engine.PromoteFinalizedEvent{ + Ref: candidate, + }) + } + // no reorg support yet; the safe L2 head will finalize eventually, no exceptions + default: + return false + } + return true +} diff --git a/op-node/rollup/interop/interop_test.go b/op-node/rollup/interop/interop_test.go new file mode 100644 index 000000000000..62b71140770e --- /dev/null +++ b/op-node/rollup/interop/interop_test.go @@ -0,0 +1,136 @@ +package interop + +import ( + "context" + "math/big" + "math/rand" // nosemgrep + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-node/rollup/engine" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/testutils" + supervisortypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" +) + +func TestInteropDeriver(t *testing.T) { + logger := testlog.Logger(t, log.LevelInfo) + l2Source := &testutils.MockL2Client{} + emitter := &testutils.MockEmitter{} + interopBackend := &testutils.MockInteropBackend{} + cfg := &rollup.Config{ + InteropTime: new(uint64), + L2ChainID: big.NewInt(42), + } + chainID := supervisortypes.ChainIDFromBig(cfg.L2ChainID) + interopDeriver := NewInteropDeriver(logger, cfg, context.Background(), interopBackend, l2Source) + interopDeriver.AttachEmitter(emitter) + rng := rand.New(rand.NewSource(123)) + + t.Run("unsafe blocks trigger cross-unsafe check attempts", func(t *testing.T) { + emitter.ExpectOnce(engine.RequestCrossUnsafeEvent{}) + interopDeriver.OnEvent(engine.UnsafeUpdateEvent{ + Ref: testutils.RandomL2BlockRef(rng), + }) + emitter.AssertExpectations(t) + }) + t.Run("establish cross-unsafe", func(t *testing.T) { + crossUnsafe := testutils.RandomL2BlockRef(rng) + firstLocalUnsafe := testutils.NextRandomL2Ref(rng, 2, crossUnsafe, crossUnsafe.L1Origin) + lastLocalUnsafe := testutils.NextRandomL2Ref(rng, 2, firstLocalUnsafe, firstLocalUnsafe.L1Origin) + interopBackend.ExpectCheckBlock( + chainID, firstLocalUnsafe.Number, supervisortypes.CrossUnsafe, nil) + emitter.ExpectOnce(engine.PromoteCrossUnsafeEvent{ + Ref: firstLocalUnsafe, + }) + l2Source.ExpectL2BlockRefByNumber(firstLocalUnsafe.Number, firstLocalUnsafe, nil) + interopDeriver.OnEvent(engine.CrossUnsafeUpdateEvent{ + CrossUnsafe: crossUnsafe, + LocalUnsafe: lastLocalUnsafe, + }) + interopBackend.AssertExpectations(t) + emitter.AssertExpectations(t) + l2Source.AssertExpectations(t) + }) + t.Run("deny cross-unsafe", func(t *testing.T) { + crossUnsafe := testutils.RandomL2BlockRef(rng) + firstLocalUnsafe := testutils.NextRandomL2Ref(rng, 2, crossUnsafe, crossUnsafe.L1Origin) + lastLocalUnsafe := testutils.NextRandomL2Ref(rng, 2, firstLocalUnsafe, firstLocalUnsafe.L1Origin) + interopBackend.ExpectCheckBlock( + chainID, firstLocalUnsafe.Number, supervisortypes.Unsafe, nil) + l2Source.ExpectL2BlockRefByNumber(firstLocalUnsafe.Number, firstLocalUnsafe, nil) + interopDeriver.OnEvent(engine.CrossUnsafeUpdateEvent{ + CrossUnsafe: crossUnsafe, + LocalUnsafe: lastLocalUnsafe, + }) + interopBackend.AssertExpectations(t) + // no cross-unsafe promote event is expected + emitter.AssertExpectations(t) + l2Source.AssertExpectations(t) + }) + t.Run("register local-safe", func(t *testing.T) { + derivedFrom := testutils.RandomBlockRef(rng) + localSafe := testutils.RandomL2BlockRef(rng) + emitter.ExpectOnce(engine.RequestCrossSafeEvent{}) + interopDeriver.OnEvent(engine.LocalSafeUpdateEvent{ + Ref: localSafe, + DerivedFrom: derivedFrom, + }) + require.Contains(t, interopDeriver.derivedFrom, localSafe.Hash) + require.Equal(t, derivedFrom, interopDeriver.derivedFrom[localSafe.Hash]) + emitter.AssertExpectations(t) + }) + t.Run("establish cross-safe", func(t *testing.T) { + derivedFrom := testutils.RandomBlockRef(rng) + crossSafe := testutils.RandomL2BlockRef(rng) + firstLocalSafe := testutils.NextRandomL2Ref(rng, 2, crossSafe, crossSafe.L1Origin) + lastLocalSafe := testutils.NextRandomL2Ref(rng, 2, firstLocalSafe, firstLocalSafe.L1Origin) + emitter.ExpectOnce(engine.RequestCrossSafeEvent{}) + // The local safe block must be known, for the derived-from mapping to work + interopDeriver.OnEvent(engine.LocalSafeUpdateEvent{ + Ref: firstLocalSafe, + DerivedFrom: derivedFrom, + }) + interopBackend.ExpectCheckBlock( + chainID, firstLocalSafe.Number, supervisortypes.CrossSafe, nil) + emitter.ExpectOnce(engine.PromoteSafeEvent{ + Ref: firstLocalSafe, + DerivedFrom: derivedFrom, + }) + l2Source.ExpectL2BlockRefByNumber(firstLocalSafe.Number, firstLocalSafe, nil) + interopDeriver.OnEvent(engine.CrossSafeUpdateEvent{ + CrossSafe: crossSafe, + LocalSafe: lastLocalSafe, + }) + interopBackend.AssertExpectations(t) + emitter.AssertExpectations(t) + l2Source.AssertExpectations(t) + }) + t.Run("deny cross-safe", func(t *testing.T) { + derivedFrom := testutils.RandomBlockRef(rng) + crossSafe := testutils.RandomL2BlockRef(rng) + firstLocalSafe := testutils.NextRandomL2Ref(rng, 2, crossSafe, crossSafe.L1Origin) + lastLocalSafe := testutils.NextRandomL2Ref(rng, 2, firstLocalSafe, firstLocalSafe.L1Origin) + emitter.ExpectOnce(engine.RequestCrossSafeEvent{}) + // The local safe block must be known, for the derived-from mapping to work + interopDeriver.OnEvent(engine.LocalSafeUpdateEvent{ + Ref: firstLocalSafe, + DerivedFrom: derivedFrom, + }) + interopBackend.ExpectCheckBlock( + chainID, firstLocalSafe.Number, supervisortypes.Safe, nil) + l2Source.ExpectL2BlockRefByNumber(firstLocalSafe.Number, firstLocalSafe, nil) + interopDeriver.OnEvent(engine.CrossSafeUpdateEvent{ + CrossSafe: crossSafe, + LocalSafe: lastLocalSafe, + }) + interopBackend.AssertExpectations(t) + // no cross-safe promote event is expected + emitter.AssertExpectations(t) + l2Source.AssertExpectations(t) + }) +} diff --git a/op-node/rollup/status/status.go b/op-node/rollup/status/status.go index b14f93843f72..65121b1294aa 100644 --- a/op-node/rollup/status/status.go +++ b/op-node/rollup/status/status.go @@ -69,6 +69,14 @@ func (st *StatusTracker) OnEvent(ev event.Event) bool { case engine.PendingSafeUpdateEvent: st.data.UnsafeL2 = x.Unsafe st.data.PendingSafeL2 = x.PendingSafe + case engine.CrossUnsafeUpdateEvent: + st.data.CrossUnsafeL2 = x.CrossUnsafe + st.data.UnsafeL2 = x.LocalUnsafe + case engine.LocalSafeUpdateEvent: + st.data.LocalSafeL2 = x.Ref + case engine.CrossSafeUpdateEvent: + st.data.SafeL2 = x.CrossSafe + st.data.LocalSafeL2 = x.LocalSafe case derive.DeriverL1StatusEvent: st.data.CurrentL1 = x.Origin case L1UnsafeEvent: diff --git a/op-node/service.go b/op-node/service.go index 723c6febb321..b24e2a638335 100644 --- a/op-node/service.go +++ b/op-node/service.go @@ -82,11 +82,12 @@ func NewConfig(ctx *cli.Context, log log.Logger) (*node.Config, error) { } cfg := &node.Config{ - L1: l1Endpoint, - L2: l2Endpoint, - Rollup: *rollupConfig, - Driver: *driverConfig, - Beacon: NewBeaconEndpointConfig(ctx), + L1: l1Endpoint, + L2: l2Endpoint, + Rollup: *rollupConfig, + Driver: *driverConfig, + Beacon: NewBeaconEndpointConfig(ctx), + Supervisor: NewSupervisorEndpointConfig(ctx), RPC: node.RPCConfig{ ListenAddr: ctx.String(flags.RPCListenAddr.Name), ListenPort: ctx.Int(flags.RPCListenPort.Name), @@ -129,6 +130,12 @@ func NewConfig(ctx *cli.Context, log log.Logger) (*node.Config, error) { return cfg, nil } +func NewSupervisorEndpointConfig(ctx *cli.Context) node.SupervisorEndpointSetup { + return &node.SupervisorEndpointConfig{ + SupervisorAddr: ctx.String(flags.SupervisorAddr.Name), + } +} + func NewBeaconEndpointConfig(ctx *cli.Context) node.L1BeaconEndpointSetup { return &node.L1BeaconEndpointConfig{ BeaconAddr: ctx.String(flags.BeaconAddr.Name), diff --git a/op-service/eth/sync_status.go b/op-service/eth/sync_status.go index e6dae130de7f..f9db1f672b82 100644 --- a/op-service/eth/sync_status.go +++ b/op-service/eth/sync_status.go @@ -22,13 +22,20 @@ type SyncStatus struct { // pointing to block data that has not been submitted to L1 yet. // The sequencer is building this, and verifiers may also be ahead of the // SafeL2 block if they sync blocks via p2p or other offchain sources. + // This is considered to only be local-unsafe post-interop, see CrossUnsafe for cross-L2 guarantees. UnsafeL2 L2BlockRef `json:"unsafe_l2"` // SafeL2 points to the L2 block that was derived from the L1 chain. // This point may still reorg if the L1 chain reorgs. + // This is considered to be cross-safe post-interop, see LocalSafe to ignore cross-L2 guarantees. SafeL2 L2BlockRef `json:"safe_l2"` // FinalizedL2 points to the L2 block that was derived fully from // finalized L1 information, thus irreversible. FinalizedL2 L2BlockRef `json:"finalized_l2"` // PendingSafeL2 points to the L2 block processed from the batch, but not consolidated to the safe block yet. PendingSafeL2 L2BlockRef `json:"pending_safe_l2"` + // CrossUnsafeL2 is an unsafe L2 block, that has been verified to match cross-L2 dependencies. + // Pre-interop every unsafe L2 block is also cross-unsafe. + CrossUnsafeL2 L2BlockRef `json:"cross_unsafe_l2"` + // LocalSafeL2 is an L2 block derived from L1, not yet verified to have valid cross-L2 dependencies. + LocalSafeL2 L2BlockRef `json:"local_safe_l2"` } diff --git a/op-service/sources/supervisor_client.go b/op-service/sources/supervisor_client.go new file mode 100644 index 000000000000..a13ea4782471 --- /dev/null +++ b/op-service/sources/supervisor_client.go @@ -0,0 +1,37 @@ +package sources + +import ( + "context" + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + + "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" +) + +type SupervisorClient struct { + client client.RPC +} + +func NewSupervisorClient(client client.RPC) *SupervisorClient { + return &SupervisorClient{ + client: client, + } +} + +func (cl *SupervisorClient) CheckBlock(ctx context.Context, + chainID types.ChainID, blockHash common.Hash, blockNumber uint64) (types.SafetyLevel, error) { + var result types.SafetyLevel + err := cl.client.CallContext(ctx, &result, "interop_checkBlock", + (*hexutil.U256)(&chainID), blockHash, hexutil.Uint64(blockNumber)) + if err != nil { + return types.Unsafe, fmt.Errorf("failed to check Block %s:%d (chain %s): %w", blockHash, blockNumber, chainID, err) + } + return result, nil +} + +func (cl *SupervisorClient) Close() { + cl.client.Close() +} diff --git a/op-service/testutils/mock_interop_backend.go b/op-service/testutils/mock_interop_backend.go new file mode 100644 index 000000000000..970627ff750f --- /dev/null +++ b/op-service/testutils/mock_interop_backend.go @@ -0,0 +1,28 @@ +package testutils + +import ( + "context" + + "github.com/stretchr/testify/mock" + + "github.com/ethereum/go-ethereum/common" + + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" +) + +type MockInteropBackend struct { + Mock mock.Mock +} + +func (m *MockInteropBackend) ExpectCheckBlock(chainID types.ChainID, blockNumber uint64, safety types.SafetyLevel, err error) { + m.Mock.On("CheckBlock", chainID, blockNumber).Once().Return(safety, &err) +} + +func (m *MockInteropBackend) CheckBlock(ctx context.Context, chainID types.ChainID, blockHash common.Hash, blockNumber uint64) (types.SafetyLevel, error) { + result := m.Mock.MethodCalled("CheckBlock", chainID, blockNumber) + return result.Get(0).(types.SafetyLevel), *result.Get(1).(*error) +} + +func (m *MockInteropBackend) AssertExpectations(t mock.TestingT) { + m.Mock.AssertExpectations(t) +} From 67ba188eb3672fbcb90f66ea2d4647aabfc22a43 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Fri, 6 Sep 2024 13:10:34 +1000 Subject: [PATCH 047/264] cannon: Support binary serialisation for snapshots (#11718) * cannon: Add serialize utils for binary formats and automatic binary/json detection. * cannon: Support reading and writing states as binary or JSON * cannon: Generate mt prestate as gzipped binary. Use different versions for singlethreaded and multithreaded states. * cannon: Improve comments for serialization * cannon: Review feedback * cannon: Introduce reader and writer helpers to simplify code. --- Makefile | 4 +- cannon/cmd/load_elf.go | 5 +- cannon/cmd/run.go | 5 +- cannon/cmd/witness.go | 6 +- cannon/mipsevm/iface.go | 3 + cannon/mipsevm/memory/memory.go | 42 +++++ cannon/mipsevm/multithreaded/instrumented.go | 4 +- cannon/mipsevm/multithreaded/state.go | 163 ++++++++++++++++++ cannon/mipsevm/multithreaded/state_test.go | 152 ++++++++++++++++ cannon/mipsevm/multithreaded/thread.go | 50 ++++++ cannon/mipsevm/singlethreaded/instrumented.go | 4 +- cannon/mipsevm/singlethreaded/state.go | 126 ++++++++++++++ cannon/mipsevm/singlethreaded/state_test.go | 69 ++++++++ cannon/mipsevm/versions/state.go | 8 + cannon/serialize/binary.go | 75 ++++++++ cannon/serialize/binary_test.go | 93 ++++++++++ cannon/serialize/detect.go | 26 +++ cannon/serialize/detect_test.go | 56 ++++++ cannon/serialize/reader.go | 60 +++++++ cannon/serialize/reader_test.go | 48 ++++++ cannon/serialize/writer.go | 44 +++++ cannon/serialize/writer_test.go | 102 +++++++++++ op-service/jsonutil/json.go | 6 +- 23 files changed, 1135 insertions(+), 16 deletions(-) create mode 100644 cannon/mipsevm/versions/state.go create mode 100644 cannon/serialize/binary.go create mode 100644 cannon/serialize/binary_test.go create mode 100644 cannon/serialize/detect.go create mode 100644 cannon/serialize/detect_test.go create mode 100644 cannon/serialize/reader.go create mode 100644 cannon/serialize/reader_test.go create mode 100644 cannon/serialize/writer.go create mode 100644 cannon/serialize/writer_test.go diff --git a/Makefile b/Makefile index 5431c5ff383d..a59b06a42de2 100644 --- a/Makefile +++ b/Makefile @@ -146,8 +146,8 @@ cannon-prestate: op-program cannon ## Generates prestate using cannon and op-pro .PHONY: cannon-prestate cannon-prestate-mt: op-program cannon ## Generates prestate using cannon and op-program in the multithreaded cannon format - ./cannon/bin/cannon load-elf --type mt --path op-program/bin/op-program-client.elf --out op-program/bin/prestate-mt.json --meta op-program/bin/meta-mt.json - ./cannon/bin/cannon run --type mt --proof-at '=0' --stop-at '=1' --input op-program/bin/prestate-mt.json --meta op-program/bin/meta-mt.json --proof-fmt 'op-program/bin/%d-mt.json' --output "" + ./cannon/bin/cannon load-elf --type cannon-mt --path op-program/bin/op-program-client.elf --out op-program/bin/prestate-mt.bin.gz --meta op-program/bin/meta-mt.json + ./cannon/bin/cannon run --type cannon-mt --proof-at '=0' --stop-at '=1' --input op-program/bin/prestate-mt.bin.gz --meta op-program/bin/meta-mt.json --proof-fmt 'op-program/bin/%d-mt.json' --output "" mv op-program/bin/0-mt.json op-program/bin/prestate-proof-mt.json .PHONY: cannon-prestate diff --git a/cannon/cmd/load_elf.go b/cannon/cmd/load_elf.go index 39e389ff23ca..fc337a2d189c 100644 --- a/cannon/cmd/load_elf.go +++ b/cannon/cmd/load_elf.go @@ -6,6 +6,7 @@ import ( "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" + "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/urfave/cli/v2" "github.com/ethereum-optimism/optimism/cannon/mipsevm/program" @@ -51,14 +52,14 @@ func LoadELF(ctx *cli.Context) error { return program.LoadELF(f, singlethreaded.CreateInitialState) } writeState = func(path string, state mipsevm.FPVMState) error { - return jsonutil.WriteJSON[*singlethreaded.State](path, state.(*singlethreaded.State), OutFilePerm) + return serialize.Write[*singlethreaded.State](path, state.(*singlethreaded.State), OutFilePerm) } } else if vmType == mtVMType { createInitialState = func(f *elf.File) (mipsevm.FPVMState, error) { return program.LoadELF(f, multithreaded.CreateInitialState) } writeState = func(path string, state mipsevm.FPVMState) error { - return jsonutil.WriteJSON[*multithreaded.State](path, state.(*multithreaded.State), OutFilePerm) + return serialize.Write[*multithreaded.State](path, state.(*multithreaded.State), OutFilePerm) } } else { return fmt.Errorf("invalid VM type: %q", vmType) diff --git a/cannon/cmd/run.go b/cannon/cmd/run.go index a806778578aa..67b85380cee5 100644 --- a/cannon/cmd/run.go +++ b/cannon/cmd/run.go @@ -11,6 +11,7 @@ import ( "time" "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" + "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/log" @@ -454,7 +455,7 @@ func Run(ctx *cli.Context) error { } if snapshotAt(state) { - if err := jsonutil.WriteJSON(fmt.Sprintf(snapshotFmt, step), state, OutFilePerm); err != nil { + if err := serialize.Write(fmt.Sprintf(snapshotFmt, step), state, OutFilePerm); err != nil { return fmt.Errorf("failed to write state snapshot: %w", err) } } @@ -511,7 +512,7 @@ func Run(ctx *cli.Context) error { vm.Traceback() } - if err := jsonutil.WriteJSON(ctx.Path(RunOutputFlag.Name), state, OutFilePerm); err != nil { + if err := serialize.Write(ctx.Path(RunOutputFlag.Name), state, OutFilePerm); err != nil { return fmt.Errorf("failed to write state output: %w", err) } if debugInfoFile := ctx.Path(RunDebugInfoFlag.Name); debugInfoFile != "" { diff --git a/cannon/cmd/witness.go b/cannon/cmd/witness.go index eda5fbca5fa0..58fa4a34307a 100644 --- a/cannon/cmd/witness.go +++ b/cannon/cmd/witness.go @@ -6,10 +6,10 @@ import ( "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" + "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/urfave/cli/v2" "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" - "github.com/ethereum-optimism/optimism/op-service/jsonutil" ) var ( @@ -33,12 +33,12 @@ func Witness(ctx *cli.Context) error { if vmType, err := vmTypeFromString(ctx); err != nil { return err } else if vmType == cannonVMType { - state, err = jsonutil.LoadJSON[singlethreaded.State](input) + state, err = serialize.Load[singlethreaded.State](input) if err != nil { return fmt.Errorf("invalid input state (%v): %w", input, err) } } else if vmType == mtVMType { - state, err = jsonutil.LoadJSON[multithreaded.State](input) + state, err = serialize.Load[multithreaded.State](input) if err != nil { return fmt.Errorf("invalid input state (%v): %w", input, err) } diff --git a/cannon/mipsevm/iface.go b/cannon/mipsevm/iface.go index 5cbab811ca89..9663a8a6ccdd 100644 --- a/cannon/mipsevm/iface.go +++ b/cannon/mipsevm/iface.go @@ -1,6 +1,7 @@ package mipsevm import ( + "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -8,6 +9,8 @@ import ( ) type FPVMState interface { + serialize.Serializable + GetMemory() *memory.Memory // GetHeap returns the current memory address at the top of the heap diff --git a/cannon/mipsevm/memory/memory.go b/cannon/mipsevm/memory/memory.go index e02720a2c0d6..c7100ea22b53 100644 --- a/cannon/mipsevm/memory/memory.go +++ b/cannon/mipsevm/memory/memory.go @@ -286,6 +286,48 @@ func (m *Memory) SetMemoryRange(addr uint32, r io.Reader) error { } } +// Serialize writes the memory in a simple binary format which can be read again using Deserialize +// The format is a simple concatenation of fields, with prefixed item count for repeating items and using big endian +// encoding for numbers. +// +// len(PageCount) uint32 +// For each page (order is arbitrary): +// +// page index uint32 +// page Data [PageSize]byte +func (m *Memory) Serialize(out io.Writer) error { + if err := binary.Write(out, binary.BigEndian, uint32(m.PageCount())); err != nil { + return err + } + for pageIndex, page := range m.pages { + if err := binary.Write(out, binary.BigEndian, pageIndex); err != nil { + return err + } + if _, err := out.Write(page.Data[:]); err != nil { + return err + } + } + return nil +} + +func (m *Memory) Deserialize(in io.Reader) error { + var pageCount uint32 + if err := binary.Read(in, binary.BigEndian, &pageCount); err != nil { + return err + } + for i := uint32(0); i < pageCount; i++ { + var pageIndex uint32 + if err := binary.Read(in, binary.BigEndian, &pageIndex); err != nil { + return err + } + page := m.AllocPage(pageIndex) + if _, err := io.ReadFull(in, page.Data[:]); err != nil { + return err + } + } + return nil +} + type memReader struct { m *Memory addr uint32 diff --git a/cannon/mipsevm/multithreaded/instrumented.go b/cannon/mipsevm/multithreaded/instrumented.go index 21fb5d9f7657..0d3e17efd4b6 100644 --- a/cannon/mipsevm/multithreaded/instrumented.go +++ b/cannon/mipsevm/multithreaded/instrumented.go @@ -3,13 +3,13 @@ package multithreaded import ( "io" + "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/cannon/mipsevm/exec" "github.com/ethereum-optimism/optimism/cannon/mipsevm/program" - "github.com/ethereum-optimism/optimism/op-service/jsonutil" ) type InstrumentedState struct { @@ -41,7 +41,7 @@ func NewInstrumentedState(state *State, po mipsevm.PreimageOracle, stdOut, stdEr } func NewInstrumentedStateFromFile(stateFile string, po mipsevm.PreimageOracle, stdOut, stdErr io.Writer, log log.Logger) (*InstrumentedState, error) { - state, err := jsonutil.LoadJSON[State](stateFile) + state, err := serialize.Load[State](stateFile) if err != nil { return nil, err } diff --git a/cannon/mipsevm/multithreaded/state.go b/cannon/mipsevm/multithreaded/state.go index 17d54c241a5e..8f6f3eb2ac0d 100644 --- a/cannon/mipsevm/multithreaded/state.go +++ b/cannon/mipsevm/multithreaded/state.go @@ -3,7 +3,10 @@ package multithreaded import ( "encoding/binary" "fmt" + "io" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/versions" + "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" @@ -219,6 +222,166 @@ func (s *State) ThreadCount() int { return len(s.LeftThreadStack) + len(s.RightThreadStack) } +// Serialize writes the state in a simple binary format which can be read again using Deserialize +// The format is a simple concatenation of fields, with prefixed item count for repeating items and using big endian +// encoding for numbers. +// +// StateVersion uint8(1) +// Memory As per Memory.Serialize +// PreimageKey [32]byte +// PreimageOffset uint32 +// Heap uint32 +// ExitCode uint8 +// Exited uint8 - 0 for false, 1 for true +// Step uint64 +// StepsSinceLastContextSwitch uint64 +// Wakeup uint32 +// TraverseRight uint8 - 0 for false, 1 for true +// NextThreadId uint32 +// len(LeftThreadStack) uint32 +// LeftThreadStack entries as per ThreadState.Serialize +// len(RightThreadStack) uint32 +// RightThreadStack entries as per ThreadState.Serialize +// len(LastHint) uint32 (0 when LastHint is nil) +// LastHint []byte +func (s *State) Serialize(out io.Writer) error { + bout := serialize.NewBinaryWriter(out) + if err := bout.WriteUInt(versions.VersionMultiThreaded); err != nil { + return err + } + + if err := s.Memory.Serialize(out); err != nil { + return err + } + if err := bout.WriteHash(s.PreimageKey); err != nil { + return err + } + if err := bout.WriteUInt(s.PreimageOffset); err != nil { + return err + } + if err := bout.WriteUInt(s.Heap); err != nil { + return err + } + if err := bout.WriteUInt(s.ExitCode); err != nil { + return err + } + if err := bout.WriteBool(s.Exited); err != nil { + return err + } + if err := bout.WriteUInt(s.Step); err != nil { + return err + } + if err := bout.WriteUInt(s.StepsSinceLastContextSwitch); err != nil { + return err + } + if err := bout.WriteUInt(s.Wakeup); err != nil { + return err + } + if err := bout.WriteBool(s.TraverseRight); err != nil { + return err + } + if err := bout.WriteUInt(s.NextThreadId); err != nil { + return err + } + + if err := bout.WriteUInt(uint32(len(s.LeftThreadStack))); err != nil { + return err + } + for _, stack := range s.LeftThreadStack { + if err := stack.Serialize(out); err != nil { + return err + } + } + if err := bout.WriteUInt(uint32(len(s.RightThreadStack))); err != nil { + return err + } + for _, stack := range s.RightThreadStack { + if err := stack.Serialize(out); err != nil { + return err + } + } + if err := bout.WriteBytes(s.LastHint); err != nil { + return err + } + + return nil +} + +func (s *State) Deserialize(in io.Reader) error { + bin := serialize.NewBinaryReader(in) + var version versions.StateVersion + if err := bin.ReadUInt(&version); err != nil { + return err + } + if version != versions.VersionMultiThreaded { + return fmt.Errorf("invalid state encoding version %d", version) + } + s.Memory = memory.NewMemory() + if err := s.Memory.Deserialize(in); err != nil { + return err + } + if err := bin.ReadHash(&s.PreimageKey); err != nil { + return err + } + if err := bin.ReadUInt(&s.PreimageOffset); err != nil { + return err + } + if err := bin.ReadUInt(&s.Heap); err != nil { + return err + } + if err := bin.ReadUInt(&s.ExitCode); err != nil { + return err + } + if err := bin.ReadBool(&s.Exited); err != nil { + return err + } + if err := bin.ReadUInt(&s.Step); err != nil { + return err + } + if err := bin.ReadUInt(&s.StepsSinceLastContextSwitch); err != nil { + return err + } + if err := bin.ReadUInt(&s.Wakeup); err != nil { + return err + } + if err := bin.ReadBool(&s.TraverseRight); err != nil { + return err + } + + if err := bin.ReadUInt(&s.NextThreadId); err != nil { + return err + } + + var leftThreadStackSize uint32 + if err := bin.ReadUInt(&leftThreadStackSize); err != nil { + return err + } + s.LeftThreadStack = make([]*ThreadState, leftThreadStackSize) + for i := range s.LeftThreadStack { + s.LeftThreadStack[i] = &ThreadState{} + if err := s.LeftThreadStack[i].Deserialize(in); err != nil { + return err + } + } + + var rightThreadStackSize uint32 + if err := bin.ReadUInt(&rightThreadStackSize); err != nil { + return err + } + s.RightThreadStack = make([]*ThreadState, rightThreadStackSize) + for i := range s.RightThreadStack { + s.RightThreadStack[i] = &ThreadState{} + if err := s.RightThreadStack[i].Deserialize(in); err != nil { + return err + } + } + + if err := bin.ReadBytes((*[]byte)(&s.LastHint)); err != nil { + return err + } + return nil +} + type StateWitness []byte func (sw StateWitness) StateHash() (common.Hash, error) { diff --git a/cannon/mipsevm/multithreaded/state_test.go b/cannon/mipsevm/multithreaded/state_test.go index c267416b8ae4..7aa3580f58ff 100644 --- a/cannon/mipsevm/multithreaded/state_test.go +++ b/cannon/mipsevm/multithreaded/state_test.go @@ -1,10 +1,14 @@ package multithreaded import ( + "bytes" "debug/elf" "encoding/json" "testing" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/memory" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -123,6 +127,154 @@ func TestState_JSONCodec(t *testing.T) { require.Equal(t, state.LastHint, newState.LastHint) } +func TestState_Binary(t *testing.T) { + elfProgram, err := elf.Open("../../testdata/example/bin/hello.elf") + require.NoError(t, err, "open ELF file") + state, err := program.LoadELF(elfProgram, CreateInitialState) + require.NoError(t, err, "load ELF into state") + // Set a few additional fields + state.PreimageKey = crypto.Keccak256Hash([]byte{1, 2, 3, 4}) + state.PreimageOffset = 4 + state.Heap = 555 + state.Step = 99_999 + state.StepsSinceLastContextSwitch = 123 + state.Exited = true + state.ExitCode = 2 + state.LastHint = []byte{11, 12, 13} + + buf := new(bytes.Buffer) + err = state.Serialize(buf) + require.NoError(t, err) + + newState := new(State) + require.NoError(t, newState.Deserialize(bytes.NewReader(buf.Bytes()))) + + require.Equal(t, state.PreimageKey, newState.PreimageKey) + require.Equal(t, state.PreimageOffset, newState.PreimageOffset) + require.Equal(t, state.Heap, newState.Heap) + require.Equal(t, state.ExitCode, newState.ExitCode) + require.Equal(t, state.Exited, newState.Exited) + require.Equal(t, state.Memory.MerkleRoot(), newState.Memory.MerkleRoot()) + require.Equal(t, state.Step, newState.Step) + require.Equal(t, state.StepsSinceLastContextSwitch, newState.StepsSinceLastContextSwitch) + require.Equal(t, state.Wakeup, newState.Wakeup) + require.Equal(t, state.TraverseRight, newState.TraverseRight) + require.Equal(t, state.LeftThreadStack, newState.LeftThreadStack) + require.Equal(t, state.RightThreadStack, newState.RightThreadStack) + require.Equal(t, state.NextThreadId, newState.NextThreadId) + require.Equal(t, state.LastHint, newState.LastHint) +} + +func TestSerializeStateRoundTrip(t *testing.T) { + // Construct a test case with populated fields + mem := memory.NewMemory() + mem.AllocPage(5) + p := mem.AllocPage(123) + p.Data[2] = 0x01 + state := &State{ + Memory: mem, + PreimageKey: common.Hash{0xFF}, + PreimageOffset: 5, + Heap: 0xc0ffee, + ExitCode: 1, + Exited: true, + Step: 0xdeadbeef, + StepsSinceLastContextSwitch: 334, + Wakeup: 42, + TraverseRight: true, + LeftThreadStack: []*ThreadState{ + { + ThreadId: 45, + ExitCode: 46, + Exited: true, + FutexAddr: 47, + FutexVal: 48, + FutexTimeoutStep: 49, + Cpu: mipsevm.CpuScalars{ + PC: 0xFF, + NextPC: 0xFF + 4, + LO: 0xbeef, + HI: 0xbabe, + }, + Registers: [32]uint32{ + 0xdeadbeef, + 0xdeadbeef, + 0xc0ffee, + 0xbeefbabe, + 0xdeadc0de, + 0xbadc0de, + 0xdeaddead, + }, + }, + { + ThreadId: 55, + ExitCode: 56, + Exited: false, + FutexAddr: 57, + FutexVal: 58, + FutexTimeoutStep: 59, + Cpu: mipsevm.CpuScalars{ + PC: 0xEE, + NextPC: 0xEE + 4, + LO: 0xeeef, + HI: 0xeabe, + }, + Registers: [32]uint32{ + 0xabcdef, + 0x123456, + }, + }, + }, + RightThreadStack: []*ThreadState{ + { + ThreadId: 65, + ExitCode: 66, + Exited: false, + FutexAddr: 67, + FutexVal: 68, + FutexTimeoutStep: 69, + Cpu: mipsevm.CpuScalars{ + PC: 0xdd, + NextPC: 0xdd + 4, + LO: 0xdeef, + HI: 0xdabe, + }, + Registers: [32]uint32{ + 0x654321, + }, + }, + { + ThreadId: 75, + ExitCode: 76, + Exited: true, + FutexAddr: 77, + FutexVal: 78, + FutexTimeoutStep: 79, + Cpu: mipsevm.CpuScalars{ + PC: 0xcc, + NextPC: 0xcc + 4, + LO: 0xceef, + HI: 0xcabe, + }, + Registers: [32]uint32{ + 0x987653, + 0xfedbca, + }, + }, + }, + NextThreadId: 489, + LastHint: hexutil.Bytes{1, 2, 3, 4, 5}, + } + + ser := new(bytes.Buffer) + err := state.Serialize(ser) + require.NoError(t, err, "must serialize state") + state2 := &State{} + err = state2.Deserialize(ser) + require.NoError(t, err, "must deserialize state") + require.Equal(t, state, state2, "must roundtrip state") +} + func TestState_EmptyThreadsRoot(t *testing.T) { data := [64]byte{} expectedEmptyRoot := crypto.Keccak256Hash(data[:]) diff --git a/cannon/mipsevm/multithreaded/thread.go b/cannon/mipsevm/multithreaded/thread.go index fd91900d3e83..f811a52be467 100644 --- a/cannon/mipsevm/multithreaded/thread.go +++ b/cannon/mipsevm/multithreaded/thread.go @@ -2,6 +2,7 @@ package multithreaded import ( "encoding/binary" + "io" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" @@ -74,6 +75,55 @@ func (t *ThreadState) serializeThread() []byte { return out } +// Serialize writes the ThreadState in a simple binary format which can be read again using Deserialize +// The format exactly matches the serialization generated by serializeThread used for thread proofs. +func (t *ThreadState) Serialize(out io.Writer) error { + _, err := out.Write(t.serializeThread()) + return err +} + +func (t *ThreadState) Deserialize(in io.Reader) error { + if err := binary.Read(in, binary.BigEndian, &t.ThreadId); err != nil { + return err + } + if err := binary.Read(in, binary.BigEndian, &t.ExitCode); err != nil { + return err + } + var exited uint8 + if err := binary.Read(in, binary.BigEndian, &exited); err != nil { + return err + } + t.Exited = exited != 0 + if err := binary.Read(in, binary.BigEndian, &t.FutexAddr); err != nil { + return err + } + if err := binary.Read(in, binary.BigEndian, &t.FutexVal); err != nil { + return err + } + if err := binary.Read(in, binary.BigEndian, &t.FutexTimeoutStep); err != nil { + return err + } + if err := binary.Read(in, binary.BigEndian, &t.Cpu.PC); err != nil { + return err + } + if err := binary.Read(in, binary.BigEndian, &t.Cpu.NextPC); err != nil { + return err + } + if err := binary.Read(in, binary.BigEndian, &t.Cpu.LO); err != nil { + return err + } + if err := binary.Read(in, binary.BigEndian, &t.Cpu.HI); err != nil { + return err + } + // Read the registers as big endian uint32s + for i := range t.Registers { + if err := binary.Read(in, binary.BigEndian, &t.Registers[i]); err != nil { + return err + } + } + return nil +} + func computeThreadRoot(prevStackRoot common.Hash, threadToPush *ThreadState) common.Hash { hashedThread := crypto.Keccak256Hash(threadToPush.serializeThread()) diff --git a/cannon/mipsevm/singlethreaded/instrumented.go b/cannon/mipsevm/singlethreaded/instrumented.go index 89331f31dcae..03e2b724ead3 100644 --- a/cannon/mipsevm/singlethreaded/instrumented.go +++ b/cannon/mipsevm/singlethreaded/instrumented.go @@ -6,7 +6,7 @@ import ( "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/cannon/mipsevm/exec" "github.com/ethereum-optimism/optimism/cannon/mipsevm/program" - "github.com/ethereum-optimism/optimism/op-service/jsonutil" + "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/ethereum/go-ethereum/common/hexutil" ) @@ -48,7 +48,7 @@ func NewInstrumentedState(state *State, po mipsevm.PreimageOracle, stdOut, stdEr } func NewInstrumentedStateFromFile(stateFile string, po mipsevm.PreimageOracle, stdOut, stdErr io.Writer, meta *program.Metadata) (*InstrumentedState, error) { - state, err := jsonutil.LoadJSON[State](stateFile) + state, err := serialize.Load[State](stateFile) if err != nil { return nil, err } diff --git a/cannon/mipsevm/singlethreaded/state.go b/cannon/mipsevm/singlethreaded/state.go index 638dcf6f3b6b..5eaac8cd940b 100644 --- a/cannon/mipsevm/singlethreaded/state.go +++ b/cannon/mipsevm/singlethreaded/state.go @@ -4,7 +4,10 @@ import ( "encoding/binary" "encoding/json" "fmt" + "io" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/versions" + "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" @@ -177,6 +180,129 @@ func (s *State) EncodeWitness() ([]byte, common.Hash) { return out, stateHashFromWitness(out) } +// Serialize writes the state in a simple binary format which can be read again using Deserialize +// The format is a simple concatenation of fields, with prefixed item count for repeating items and using big endian +// encoding for numbers. +// +// StateVersion uint8(0) +// Memory As per Memory.Serialize +// PreimageKey [32]byte +// PreimageOffset uint32 +// Cpu.PC uint32 +// Cpu.NextPC uint32 +// Cpu.LO uint32 +// Cpu.HI uint32 +// Heap uint32 +// ExitCode uint8 +// Exited uint8 - 0 for false, 1 for true +// Step uint64 +// Registers [32]uint32 +// len(LastHint) uint32 (0 when LastHint is nil) +// LastHint []byte +func (s *State) Serialize(out io.Writer) error { + bout := serialize.NewBinaryWriter(out) + if err := bout.WriteUInt(versions.VersionSingleThreaded); err != nil { + return err + } + + if err := s.Memory.Serialize(out); err != nil { + return err + } + if err := bout.WriteHash(s.PreimageKey); err != nil { + return err + } + if err := bout.WriteUInt(s.PreimageOffset); err != nil { + return err + } + if err := bout.WriteUInt(s.Cpu.PC); err != nil { + return err + } + if err := bout.WriteUInt(s.Cpu.NextPC); err != nil { + return err + } + if err := bout.WriteUInt(s.Cpu.LO); err != nil { + return err + } + if err := bout.WriteUInt(s.Cpu.HI); err != nil { + return err + } + if err := bout.WriteUInt(s.Heap); err != nil { + return err + } + if err := bout.WriteUInt(s.ExitCode); err != nil { + return err + } + if err := bout.WriteBool(s.Exited); err != nil { + return err + } + if err := bout.WriteUInt(s.Step); err != nil { + return err + } + for _, r := range s.Registers { + if err := bout.WriteUInt(r); err != nil { + return err + } + } + if err := bout.WriteBytes(s.LastHint); err != nil { + return err + } + return nil +} + +func (s *State) Deserialize(in io.Reader) error { + bin := serialize.NewBinaryReader(in) + var version versions.StateVersion + if err := bin.ReadUInt(&version); err != nil { + return err + } + if version != versions.VersionSingleThreaded { + return fmt.Errorf("invalid state encoding version %d", version) + } + s.Memory = memory.NewMemory() + if err := s.Memory.Deserialize(in); err != nil { + return err + } + if err := bin.ReadHash(&s.PreimageKey); err != nil { + return err + } + if err := bin.ReadUInt(&s.PreimageOffset); err != nil { + return err + } + if err := bin.ReadUInt(&s.Cpu.PC); err != nil { + return err + } + if err := bin.ReadUInt(&s.Cpu.NextPC); err != nil { + return err + } + if err := bin.ReadUInt(&s.Cpu.LO); err != nil { + return err + } + if err := bin.ReadUInt(&s.Cpu.HI); err != nil { + return err + } + if err := bin.ReadUInt(&s.Heap); err != nil { + return err + } + if err := bin.ReadUInt(&s.ExitCode); err != nil { + return err + } + if err := bin.ReadBool(&s.Exited); err != nil { + return err + } + if err := bin.ReadUInt(&s.Step); err != nil { + return err + } + for i := range s.Registers { + if err := bin.ReadUInt(&s.Registers[i]); err != nil { + return err + } + } + if err := bin.ReadBytes((*[]byte)(&s.LastHint)); err != nil { + return err + } + return nil +} + type StateWitness []byte func (sw StateWitness) StateHash() (common.Hash, error) { diff --git a/cannon/mipsevm/singlethreaded/state_test.go b/cannon/mipsevm/singlethreaded/state_test.go index 27588f8b67ed..c3dfd5cd41af 100644 --- a/cannon/mipsevm/singlethreaded/state_test.go +++ b/cannon/mipsevm/singlethreaded/state_test.go @@ -1,9 +1,12 @@ package singlethreaded import ( + "bytes" "debug/elf" "testing" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/require" @@ -79,3 +82,69 @@ func TestStateJSONCodec(t *testing.T) { require.Equal(t, state.Registers, newState.Registers) require.Equal(t, state.Step, newState.Step) } + +func TestStateBinaryCodec(t *testing.T) { + elfProgram, err := elf.Open("../../testdata/example/bin/hello.elf") + require.NoError(t, err, "open ELF file") + state, err := program.LoadELF(elfProgram, CreateInitialState) + require.NoError(t, err, "load ELF into state") + + buf := new(bytes.Buffer) + err = state.Serialize(buf) + require.NoError(t, err) + + newState := new(State) + require.NoError(t, newState.Deserialize(bytes.NewReader(buf.Bytes()))) + + require.Equal(t, state.PreimageKey, newState.PreimageKey) + require.Equal(t, state.PreimageOffset, newState.PreimageOffset) + require.Equal(t, state.Cpu, newState.Cpu) + require.Equal(t, state.Heap, newState.Heap) + require.Equal(t, state.ExitCode, newState.ExitCode) + require.Equal(t, state.Exited, newState.Exited) + require.Equal(t, state.Memory.PageCount(), newState.Memory.PageCount()) + require.Equal(t, state.Memory.MerkleRoot(), newState.Memory.MerkleRoot()) + require.Equal(t, state.Registers, newState.Registers) + require.Equal(t, state.Step, newState.Step) +} + +func TestSerializeStateRoundTrip(t *testing.T) { + // Construct a test case with populated fields + mem := memory.NewMemory() + mem.AllocPage(5) + p := mem.AllocPage(123) + p.Data[2] = 0x01 + state := &State{ + Memory: mem, + PreimageKey: common.Hash{0xFF}, + PreimageOffset: 5, + Cpu: mipsevm.CpuScalars{ + PC: 0xFF, + NextPC: 0xFF + 4, + LO: 0xbeef, + HI: 0xbabe, + }, + Heap: 0xc0ffee, + ExitCode: 1, + Exited: true, + Step: 0xdeadbeef, + Registers: [32]uint32{ + 0xdeadbeef, + 0xdeadbeef, + 0xc0ffee, + 0xbeefbabe, + 0xdeadc0de, + 0xbadc0de, + 0xdeaddead, + }, + LastHint: hexutil.Bytes{1, 2, 3, 4, 5}, + } + + ser := new(bytes.Buffer) + err := state.Serialize(ser) + require.NoError(t, err, "must serialize state") + state2 := &State{} + err = state2.Deserialize(ser) + require.NoError(t, err, "must deserialize state") + require.Equal(t, state, state2, "must roundtrip state") +} diff --git a/cannon/mipsevm/versions/state.go b/cannon/mipsevm/versions/state.go new file mode 100644 index 000000000000..6e1a6b2fb4e1 --- /dev/null +++ b/cannon/mipsevm/versions/state.go @@ -0,0 +1,8 @@ +package versions + +type StateVersion uint8 + +const ( + VersionSingleThreaded StateVersion = iota + VersionMultiThreaded +) diff --git a/cannon/serialize/binary.go b/cannon/serialize/binary.go new file mode 100644 index 000000000000..c36bc279f1da --- /dev/null +++ b/cannon/serialize/binary.go @@ -0,0 +1,75 @@ +package serialize + +import ( + "errors" + "fmt" + "io" + "os" + "reflect" + + "github.com/ethereum-optimism/optimism/op-service/ioutil" +) + +// Serializable defines functionality for a type that may be serialized to raw bytes. +type Serializable interface { + // Serialize encodes the type as raw bytes. + Serialize(out io.Writer) error + + // Deserialize decodes raw bytes into the type. + Deserialize(in io.Reader) error +} + +func LoadSerializedBinary[X any](inputPath string) (*X, error) { + if inputPath == "" { + return nil, errors.New("no path specified") + } + var f io.ReadCloser + f, err := ioutil.OpenDecompressed(inputPath) + if err != nil { + return nil, fmt.Errorf("failed to open file %q: %w", inputPath, err) + } + defer f.Close() + + var x X + serializable, ok := reflect.ValueOf(&x).Interface().(Serializable) + if !ok { + return nil, fmt.Errorf("%T is not a Serializable", x) + } + err = serializable.Deserialize(f) + if err != nil { + return nil, err + } + return &x, nil +} + +func WriteSerializedBinary(outputPath string, value Serializable, perm os.FileMode) error { + if outputPath == "" { + return nil + } + var out io.Writer + finish := func() error { return nil } + if outputPath == "-" { + out = os.Stdout + } else { + f, err := ioutil.NewAtomicWriterCompressed(outputPath, perm) + if err != nil { + return fmt.Errorf("failed to create temp file when writing: %w", err) + } + // Ensure we close the stream without renaming even if failures occur. + defer func() { + _ = f.Abort() + }() + out = f + // Closing the file causes it to be renamed to the final destination + // so make sure we handle any errors it returns + finish = f.Close + } + err := value.Serialize(out) + if err != nil { + return fmt.Errorf("failed to write binary: %w", err) + } + if err := finish(); err != nil { + return fmt.Errorf("failed to finish write: %w", err) + } + return nil +} diff --git a/cannon/serialize/binary_test.go b/cannon/serialize/binary_test.go new file mode 100644 index 000000000000..0f5794608f98 --- /dev/null +++ b/cannon/serialize/binary_test.go @@ -0,0 +1,93 @@ +package serialize + +import ( + "encoding/binary" + "io" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestRoundTripBinary(t *testing.T) { + dir := t.TempDir() + file := filepath.Join(dir, "test.bin") + data := &serializableTestData{A: []byte{0xde, 0xad}, B: 3} + err := WriteSerializedBinary(file, data, 0644) + require.NoError(t, err) + + hasGzip, err := hasGzipHeader(file) + require.NoError(t, err) + require.False(t, hasGzip) + + result, err := LoadSerializedBinary[serializableTestData](file) + require.NoError(t, err) + require.EqualValues(t, data, result) +} + +func TestRoundTripBinaryWithGzip(t *testing.T) { + dir := t.TempDir() + file := filepath.Join(dir, "test.bin.gz") + data := &serializableTestData{A: []byte{0xde, 0xad}, B: 3} + err := WriteSerializedBinary(file, data, 0644) + require.NoError(t, err) + + hasGzip, err := hasGzipHeader(file) + require.NoError(t, err) + require.True(t, hasGzip) + + result, err := LoadSerializedBinary[serializableTestData](file) + require.NoError(t, err) + require.EqualValues(t, data, result) +} + +func hasGzipHeader(filename string) (bool, error) { + file, err := os.Open(filename) + if err != nil { + return false, err + } + defer file.Close() + + header := make([]byte, 2) + _, err = file.Read(header) + if err != nil { + return false, err + } + + // Gzip header magic numbers: 1F 8B + return header[0] == 0x1F && header[1] == 0x8B, nil +} + +type serializableTestData struct { + A []byte + B uint8 +} + +func (s *serializableTestData) Serialize(w io.Writer) error { + if err := binary.Write(w, binary.BigEndian, uint64(len(s.A))); err != nil { + return err + } + if _, err := w.Write(s.A); err != nil { + return err + } + if err := binary.Write(w, binary.BigEndian, s.B); err != nil { + return err + } + return nil +} + +func (s *serializableTestData) Deserialize(in io.Reader) error { + var lenA uint64 + if err := binary.Read(in, binary.BigEndian, &lenA); err != nil { + return err + } + s.A = make([]byte, lenA) + if _, err := io.ReadFull(in, s.A); err != nil { + return err + } + if err := binary.Read(in, binary.BigEndian, &s.B); err != nil { + return err + } + return nil +} diff --git a/cannon/serialize/detect.go b/cannon/serialize/detect.go new file mode 100644 index 000000000000..f84d2c1e0a73 --- /dev/null +++ b/cannon/serialize/detect.go @@ -0,0 +1,26 @@ +package serialize + +import ( + "os" + "strings" + + "github.com/ethereum-optimism/optimism/op-service/jsonutil" +) + +func Load[X any](inputPath string) (*X, error) { + if isBinary(inputPath) { + return LoadSerializedBinary[X](inputPath) + } + return jsonutil.LoadJSON[X](inputPath) +} + +func Write[X Serializable](outputPath string, x X, perm os.FileMode) error { + if isBinary(outputPath) { + return WriteSerializedBinary(outputPath, x, perm) + } + return jsonutil.WriteJSON[X](outputPath, x, perm) +} + +func isBinary(path string) bool { + return strings.HasSuffix(path, ".bin") || strings.HasSuffix(path, ".bin.gz") +} diff --git a/cannon/serialize/detect_test.go b/cannon/serialize/detect_test.go new file mode 100644 index 000000000000..032844e1800b --- /dev/null +++ b/cannon/serialize/detect_test.go @@ -0,0 +1,56 @@ +package serialize + +import ( + "io" + "path/filepath" + "testing" + + "github.com/ethereum-optimism/optimism/op-service/ioutil" + "github.com/stretchr/testify/require" +) + +func TestRoundtrip(t *testing.T) { + tests := []struct { + filename string + expectJSON bool + expectGzip bool + }{ + {filename: "test.json", expectJSON: true, expectGzip: false}, + {filename: "test.json.gz", expectJSON: true, expectGzip: true}, + {filename: "test.foo", expectJSON: true, expectGzip: false}, + {filename: "test.foo.gz", expectJSON: true, expectGzip: true}, + {filename: "test.bin", expectJSON: false, expectGzip: false}, + {filename: "test.bin.gz", expectJSON: false, expectGzip: true}, + } + + for _, test := range tests { + test := test + t.Run(test.filename, func(t *testing.T) { + path := filepath.Join(t.TempDir(), test.filename) + + data := &serializableTestData{A: []byte{0xde, 0xad}, B: 3} + err := Write[*serializableTestData](path, data, 0644) + require.NoError(t, err) + + hasGzip, err := hasGzipHeader(path) + require.NoError(t, err) + require.Equal(t, test.expectGzip, hasGzip) + + decompressed, err := ioutil.OpenDecompressed(path) + require.NoError(t, err) + defer decompressed.Close() + start := make([]byte, 1) + _, err = io.ReadFull(decompressed, start) + require.NoError(t, err) + if test.expectJSON { + require.Equal(t, "{", string(start)) + } else { + require.NotEqual(t, "{", string(start)) + } + + result, err := Load[serializableTestData](path) + require.NoError(t, err) + require.EqualValues(t, data, result) + }) + } +} diff --git a/cannon/serialize/reader.go b/cannon/serialize/reader.go new file mode 100644 index 000000000000..53f4440659a4 --- /dev/null +++ b/cannon/serialize/reader.go @@ -0,0 +1,60 @@ +package serialize + +import ( + "encoding/binary" + "fmt" + "io" + + "github.com/ethereum/go-ethereum/common" +) + +// BinaryReader provides methods to decode content written by BinaryWriter. +type BinaryReader struct { + in io.Reader +} + +func NewBinaryReader(in io.Reader) *BinaryReader { + return &BinaryReader{in: in} +} + +func (r *BinaryReader) ReadUInt(target any) error { + return binary.Read(r.in, binary.BigEndian, target) +} + +func (r *BinaryReader) ReadHash(target *common.Hash) error { + _, err := io.ReadFull(r.in, target[:]) + return err +} + +func (r *BinaryReader) ReadBool(target *bool) error { + var v uint8 + if err := r.ReadUInt(&v); err != nil { + return err + } + switch v { + case 0: + *target = false + case 1: + *target = true + default: + return fmt.Errorf("invalid boolean value: %v", v) + } + return nil +} + +func (r *BinaryReader) ReadBytes(target *[]byte) error { + var size uint32 + if err := r.ReadUInt(&size); err != nil { + return err + } + if size == 0 { + *target = nil + return nil + } + data := make([]byte, size) + if _, err := io.ReadFull(r.in, data); err != nil { + return err + } + *target = data + return nil +} diff --git a/cannon/serialize/reader_test.go b/cannon/serialize/reader_test.go new file mode 100644 index 000000000000..0d6b8678c592 --- /dev/null +++ b/cannon/serialize/reader_test.go @@ -0,0 +1,48 @@ +package serialize + +import ( + "bytes" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestRoundTripWithReader(t *testing.T) { + // Test that reader can read the data written by BinaryWriter. + // The writer tests check that the generated data is what is expected, so simply check that the reader correctly + // parses a range of data here rather than duplicating the expected binary serialization. + buf := new(bytes.Buffer) + out := NewBinaryWriter(buf) + require.NoError(t, out.WriteBool(true)) + require.NoError(t, out.WriteBool(false)) + require.NoError(t, out.WriteUInt(uint8(5))) + require.NoError(t, out.WriteUInt(uint32(76))) + require.NoError(t, out.WriteUInt(uint64(24824424))) + expectedHash := common.HexToHash("0x5a8f75b8e1c1529d1d1c596464d17b99763604f4c00b280436fc0dffacc60efd") + require.NoError(t, out.WriteHash(expectedHash)) + expectedBytes := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9} + require.NoError(t, out.WriteBytes(expectedBytes)) + + in := NewBinaryReader(buf) + var b bool + require.NoError(t, in.ReadBool(&b)) + require.True(t, b) + require.NoError(t, in.ReadBool(&b)) + require.False(t, b) + var vUInt8 uint8 + require.NoError(t, in.ReadUInt(&vUInt8)) + require.Equal(t, uint8(5), vUInt8) + var vUInt32 uint32 + require.NoError(t, in.ReadUInt(&vUInt32)) + require.Equal(t, uint32(76), vUInt32) + var vUInt64 uint64 + require.NoError(t, in.ReadUInt(&vUInt64)) + require.Equal(t, uint64(24824424), vUInt64) + var hash common.Hash + require.NoError(t, in.ReadHash(&hash)) + require.Equal(t, expectedHash, hash) + var data []byte + require.NoError(t, in.ReadBytes(&data)) + require.Equal(t, expectedBytes, data) +} diff --git a/cannon/serialize/writer.go b/cannon/serialize/writer.go new file mode 100644 index 000000000000..a8790115a11c --- /dev/null +++ b/cannon/serialize/writer.go @@ -0,0 +1,44 @@ +package serialize + +import ( + "encoding/binary" + "io" + + "github.com/ethereum/go-ethereum/common" +) + +// BinaryWriter writes a simple binary format which can be read again using BinaryReader. +// The format is a simple concatenation of values, with prefixed length for variable length items. +// All numbers are encoded using big endian. +type BinaryWriter struct { + out io.Writer +} + +func NewBinaryWriter(out io.Writer) *BinaryWriter { + return &BinaryWriter{out: out} +} + +func (w *BinaryWriter) WriteUInt(v any) error { + return binary.Write(w.out, binary.BigEndian, v) +} + +func (w *BinaryWriter) WriteHash(v common.Hash) error { + _, err := w.out.Write(v[:]) + return err +} + +func (w *BinaryWriter) WriteBool(v bool) error { + if v { + return w.WriteUInt(uint8(1)) + } else { + return w.WriteUInt(uint8(0)) + } +} + +func (w *BinaryWriter) WriteBytes(v []byte) error { + if err := w.WriteUInt(uint32(len(v))); err != nil { + return err + } + _, err := w.out.Write(v) + return err +} diff --git a/cannon/serialize/writer_test.go b/cannon/serialize/writer_test.go new file mode 100644 index 000000000000..d37b18da094f --- /dev/null +++ b/cannon/serialize/writer_test.go @@ -0,0 +1,102 @@ +package serialize + +import ( + "bytes" + "fmt" + "math" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestUInt(t *testing.T) { + tests := []struct { + name string + val any + expected []byte + }{ + {name: "uint8-zero", val: uint8(0), expected: []byte{0}}, + {name: "uint8-one", val: uint8(1), expected: []byte{1}}, + {name: "uint8-big", val: uint8(156), expected: []byte{156}}, + {name: "uint8-max", val: uint8(math.MaxUint8), expected: []byte{255}}, + + {name: "uint16-zero", val: uint16(0), expected: []byte{0, 0}}, + {name: "uint16-one", val: uint16(1), expected: []byte{0, 1}}, + {name: "uint16-big", val: uint16(1283), expected: []byte{5, 3}}, + {name: "uint16-max", val: uint16(math.MaxUint16), expected: []byte{255, 255}}, + + {name: "uint32-zero", val: uint32(0), expected: []byte{0, 0, 0, 0}}, + {name: "uint32-one", val: uint32(1), expected: []byte{0, 0, 0, 1}}, + {name: "uint32-big", val: uint32(1283424245), expected: []byte{0x4c, 0x7f, 0x7f, 0xf5}}, + {name: "uint32-max", val: uint32(math.MaxUint32), expected: []byte{255, 255, 255, 255}}, + + {name: "uint64-zero", val: uint64(0), expected: []byte{0, 0, 0, 0, 0, 0, 0, 0}}, + {name: "uint64-one", val: uint64(1), expected: []byte{0, 0, 0, 0, 0, 0, 0, 1}}, + {name: "uint64-big", val: uint64(1283424245242429284), expected: []byte{0x11, 0xcf, 0xa3, 0x8d, 0x19, 0xcc, 0x7f, 0x64}}, + {name: "uint64-max", val: uint64(math.MaxUint64), expected: []byte{255, 255, 255, 255, 255, 255, 255, 255}}, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + out := new(bytes.Buffer) + bout := NewBinaryWriter(out) + require.NoError(t, bout.WriteUInt(test.val)) + result := out.Bytes() + require.Equal(t, test.expected, result) + }) + } +} + +func TestWriteHash(t *testing.T) { + out := new(bytes.Buffer) + bout := NewBinaryWriter(out) + hash := common.HexToHash("0x5a8f75b8e1c1529d1d1c596464d17b99763604f4c00b280436fc0dffacc60efd") + require.NoError(t, bout.WriteHash(hash)) + + result := out.Bytes() + require.Equal(t, hash[:], result) +} + +func TestWriteBool(t *testing.T) { + for _, val := range []bool{true, false} { + val := val + t.Run(fmt.Sprintf("%t", val), func(t *testing.T) { + out := new(bytes.Buffer) + bout := NewBinaryWriter(out) + require.NoError(t, bout.WriteBool(val)) + + result := out.Bytes() + require.Len(t, result, 1) + if val { + require.Equal(t, result[0], uint8(1)) + } else { + require.Equal(t, result[0], uint8(0)) + } + }) + } +} + +func TestWriteBytes(t *testing.T) { + tests := []struct { + name string + val []byte + expected []byte + }{ + {name: "nil", val: nil, expected: []byte{0, 0, 0, 0}}, + {name: "empty", val: []byte{}, expected: []byte{0, 0, 0, 0}}, + {name: "non-empty", val: []byte{1, 2, 3, 4, 5}, expected: []byte{0, 0, 0, 5, 1, 2, 3, 4, 5}}, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + out := new(bytes.Buffer) + bout := NewBinaryWriter(out) + require.NoError(t, bout.WriteBytes(test.val)) + + result := out.Bytes() + require.Equal(t, test.expected, result) + }) + } +} diff --git a/op-service/jsonutil/json.go b/op-service/jsonutil/json.go index 94dcfd91c252..922e8ff79350 100644 --- a/op-service/jsonutil/json.go +++ b/op-service/jsonutil/json.go @@ -38,7 +38,9 @@ func WriteJSON[X any](outputPath string, value X, perm os.FileMode) error { } var out io.Writer finish := func() error { return nil } - if outputPath != "-" { + if outputPath == "-" { + out = os.Stdout + } else { f, err := ioutil.NewAtomicWriterCompressed(outputPath, perm) if err != nil { return fmt.Errorf("failed to open output file: %w", err) @@ -51,8 +53,6 @@ func WriteJSON[X any](outputPath string, value X, perm os.FileMode) error { // Closing the file causes it to be renamed to the final destination // so make sure we handle any errors it returns finish = f.Close - } else { - out = os.Stdout } enc := json.NewEncoder(out) enc.SetIndent("", " ") From 31444eb3128d9ee9b4352828337ad89085d659cc Mon Sep 17 00:00:00 2001 From: protolambda Date: Thu, 5 Sep 2024 21:15:19 -0600 Subject: [PATCH 048/264] op-node: sanity-check the forkchoice updates (#11780) --- op-node/rollup/engine/build_start.go | 5 +++++ op-node/rollup/engine/engine_controller.go | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/op-node/rollup/engine/build_start.go b/op-node/rollup/engine/build_start.go index c1f9df5a98d6..22c178d36cd0 100644 --- a/op-node/rollup/engine/build_start.go +++ b/op-node/rollup/engine/build_start.go @@ -34,6 +34,11 @@ func (eq *EngDeriver) onBuildStart(ev BuildStartEvent) { SafeL2Head: eq.ec.safeHead, FinalizedL2Head: eq.ec.finalizedHead, } + if fcEvent.UnsafeL2Head.Number < fcEvent.FinalizedL2Head.Number { + err := fmt.Errorf("invalid block-building pre-state, unsafe head %s is behind finalized head %s", fcEvent.UnsafeL2Head, fcEvent.FinalizedL2Head) + eq.emitter.Emit(rollup.CriticalErrorEvent{Err: err}) // make the node exit, things are very wrong. + return + } fc := eth.ForkchoiceState{ HeadBlockHash: fcEvent.UnsafeL2Head.Hash, SafeBlockHash: fcEvent.SafeL2Head.Hash, diff --git a/op-node/rollup/engine/engine_controller.go b/op-node/rollup/engine/engine_controller.go index f2266382a206..a5d4b5c4e881 100644 --- a/op-node/rollup/engine/engine_controller.go +++ b/op-node/rollup/engine/engine_controller.go @@ -269,6 +269,11 @@ func (e *EngineController) TryUpdateEngine(ctx context.Context) error { if e.IsEngineSyncing() { e.log.Warn("Attempting to update forkchoice state while EL syncing") } + if e.unsafeHead.Number < e.finalizedHead.Number { + err := fmt.Errorf("invalid forkchoice state, unsafe head %s is behind finalized head %s", e.unsafeHead, e.finalizedHead) + e.emitter.Emit(rollup.CriticalErrorEvent{Err: err}) // make the node exit, things are very wrong. + return err + } fc := eth.ForkchoiceState{ HeadBlockHash: e.unsafeHead.Hash, SafeBlockHash: e.safeHead.Hash, From 247b3992554fa6868c5718945f09d2bb85adfb2b Mon Sep 17 00:00:00 2001 From: Josh Klopfenstein Date: Fri, 6 Sep 2024 00:55:45 -0500 Subject: [PATCH 049/264] Use local logger in data source (#11756) There may be other places where a global logger is used, but this instance is particularly important because one message warns the user of a misconfiguration that otherwise manifests in a seemingly unrelated bug (rollbacks on unsafe block consolidation). --- op-node/rollup/derive/blob_data_source.go | 6 +++--- op-node/rollup/derive/blob_data_source_test.go | 13 ++++++++----- op-node/rollup/derive/calldata_source.go | 2 +- op-node/rollup/derive/data_source.go | 6 +++--- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/op-node/rollup/derive/blob_data_source.go b/op-node/rollup/derive/blob_data_source.go index 7780b6065063..2c4626941b8b 100644 --- a/op-node/rollup/derive/blob_data_source.go +++ b/op-node/rollup/derive/blob_data_source.go @@ -86,7 +86,7 @@ func (ds *BlobDataSource) open(ctx context.Context) ([]blobOrCalldata, error) { return nil, NewTemporaryError(fmt.Errorf("failed to open blob data source: %w", err)) } - data, hashes := dataAndHashesFromTxs(txs, &ds.dsCfg, ds.batcherAddr) + data, hashes := dataAndHashesFromTxs(txs, &ds.dsCfg, ds.batcherAddr, ds.log) if len(hashes) == 0 { // there are no blobs to fetch so we can return immediately @@ -115,13 +115,13 @@ func (ds *BlobDataSource) open(ctx context.Context) ([]blobOrCalldata, error) { // dataAndHashesFromTxs extracts calldata and datahashes from the input transactions and returns them. It // creates a placeholder blobOrCalldata element for each returned blob hash that must be populated // by fillBlobPointers after blob bodies are retrieved. -func dataAndHashesFromTxs(txs types.Transactions, config *DataSourceConfig, batcherAddr common.Address) ([]blobOrCalldata, []eth.IndexedBlobHash) { +func dataAndHashesFromTxs(txs types.Transactions, config *DataSourceConfig, batcherAddr common.Address, logger log.Logger) ([]blobOrCalldata, []eth.IndexedBlobHash) { data := []blobOrCalldata{} var hashes []eth.IndexedBlobHash blobIndex := 0 // index of each blob in the block's blob sidecar for _, tx := range txs { // skip any non-batcher transactions - if !isValidBatchTx(tx, config.l1Signer, config.batchInboxAddress, batcherAddr) { + if !isValidBatchTx(tx, config.l1Signer, config.batchInboxAddress, batcherAddr, logger) { blobIndex += len(tx.BlobHashes()) continue } diff --git a/op-node/rollup/derive/blob_data_source_test.go b/op-node/rollup/derive/blob_data_source_test.go index aa9ef82cb991..e5e31dc957b9 100644 --- a/op-node/rollup/derive/blob_data_source_test.go +++ b/op-node/rollup/derive/blob_data_source_test.go @@ -13,7 +13,9 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testutils" + "github.com/ethereum/go-ethereum/log" ) func TestDataAndHashesFromTxs(t *testing.T) { @@ -23,6 +25,7 @@ func TestDataAndHashesFromTxs(t *testing.T) { publicKey, _ := privateKey.Public().(*ecdsa.PublicKey) batcherAddr := crypto.PubkeyToAddress(*publicKey) batchInboxAddr := testutils.RandomAddress(rng) + logger := testlog.Logger(t, log.LvlInfo) chainId := new(big.Int).SetUint64(rng.Uint64()) signer := types.NewCancunSigner(chainId) @@ -42,7 +45,7 @@ func TestDataAndHashesFromTxs(t *testing.T) { } calldataTx, _ := types.SignNewTx(privateKey, signer, txData) txs := types.Transactions{calldataTx} - data, blobHashes := dataAndHashesFromTxs(txs, &config, batcherAddr) + data, blobHashes := dataAndHashesFromTxs(txs, &config, batcherAddr, logger) require.Equal(t, 1, len(data)) require.Equal(t, 0, len(blobHashes)) @@ -57,14 +60,14 @@ func TestDataAndHashesFromTxs(t *testing.T) { } blobTx, _ := types.SignNewTx(privateKey, signer, blobTxData) txs = types.Transactions{blobTx} - data, blobHashes = dataAndHashesFromTxs(txs, &config, batcherAddr) + data, blobHashes = dataAndHashesFromTxs(txs, &config, batcherAddr, logger) require.Equal(t, 1, len(data)) require.Equal(t, 1, len(blobHashes)) require.Nil(t, data[0].calldata) // try again with both the blob & calldata transactions and make sure both are picked up txs = types.Transactions{blobTx, calldataTx} - data, blobHashes = dataAndHashesFromTxs(txs, &config, batcherAddr) + data, blobHashes = dataAndHashesFromTxs(txs, &config, batcherAddr, logger) require.Equal(t, 2, len(data)) require.Equal(t, 1, len(blobHashes)) require.NotNil(t, data[1].calldata) @@ -72,7 +75,7 @@ func TestDataAndHashesFromTxs(t *testing.T) { // make sure blob tx to the batch inbox is ignored if not signed by the batcher blobTx, _ = types.SignNewTx(testutils.RandomKey(), signer, blobTxData) txs = types.Transactions{blobTx} - data, blobHashes = dataAndHashesFromTxs(txs, &config, batcherAddr) + data, blobHashes = dataAndHashesFromTxs(txs, &config, batcherAddr, logger) require.Equal(t, 0, len(data)) require.Equal(t, 0, len(blobHashes)) @@ -81,7 +84,7 @@ func TestDataAndHashesFromTxs(t *testing.T) { blobTxData.To = testutils.RandomAddress(rng) blobTx, _ = types.SignNewTx(privateKey, signer, blobTxData) txs = types.Transactions{blobTx} - data, blobHashes = dataAndHashesFromTxs(txs, &config, batcherAddr) + data, blobHashes = dataAndHashesFromTxs(txs, &config, batcherAddr, logger) require.Equal(t, 0, len(data)) require.Equal(t, 0, len(blobHashes)) } diff --git a/op-node/rollup/derive/calldata_source.go b/op-node/rollup/derive/calldata_source.go index 0a5d7915770d..0e8147261e93 100644 --- a/op-node/rollup/derive/calldata_source.go +++ b/op-node/rollup/derive/calldata_source.go @@ -79,7 +79,7 @@ func (ds *CalldataSource) Next(ctx context.Context) (eth.Data, error) { func DataFromEVMTransactions(dsCfg DataSourceConfig, batcherAddr common.Address, txs types.Transactions, log log.Logger) []eth.Data { out := []eth.Data{} for _, tx := range txs { - if isValidBatchTx(tx, dsCfg.l1Signer, dsCfg.batchInboxAddress, batcherAddr) { + if isValidBatchTx(tx, dsCfg.l1Signer, dsCfg.batchInboxAddress, batcherAddr, log) { out = append(out, tx.Data()) } } diff --git a/op-node/rollup/derive/data_source.go b/op-node/rollup/derive/data_source.go index b4ab76dc64bc..8d064a7cdb8c 100644 --- a/op-node/rollup/derive/data_source.go +++ b/op-node/rollup/derive/data_source.go @@ -93,19 +93,19 @@ type DataSourceConfig struct { // isValidBatchTx returns true if: // 1. the transaction has a To() address that matches the batch inbox address, and // 2. the transaction has a valid signature from the batcher address -func isValidBatchTx(tx *types.Transaction, l1Signer types.Signer, batchInboxAddr, batcherAddr common.Address) bool { +func isValidBatchTx(tx *types.Transaction, l1Signer types.Signer, batchInboxAddr, batcherAddr common.Address, logger log.Logger) bool { to := tx.To() if to == nil || *to != batchInboxAddr { return false } seqDataSubmitter, err := l1Signer.Sender(tx) // optimization: only derive sender if To is correct if err != nil { - log.Warn("tx in inbox with invalid signature", "hash", tx.Hash(), "err", err) + logger.Warn("tx in inbox with invalid signature", "hash", tx.Hash(), "err", err) return false } // some random L1 user might have sent a transaction to our batch inbox, ignore them if seqDataSubmitter != batcherAddr { - log.Warn("tx in inbox with unauthorized submitter", "addr", seqDataSubmitter, "hash", tx.Hash(), "err", err) + logger.Warn("tx in inbox with unauthorized submitter", "addr", seqDataSubmitter, "hash", tx.Hash(), "err", err) return false } return true From 85c79a559f1ef923d484b4d5738f1f78f7aa449b Mon Sep 17 00:00:00 2001 From: Blaine Malone Date: Fri, 6 Sep 2024 13:42:44 +0100 Subject: [PATCH 050/264] fix: small typo fixes to DeploySuperchain.s.sol. (#11758) * fix: small typo fixes to DeploySuperchain.s.sol. * fix: semgrep Javadoc-style comments are not allowed. * style: remove extra space --------- Co-authored-by: Matt Solomon --- .../scripts/DeploySuperchain.s.sol | 94 +++++++++---------- 1 file changed, 46 insertions(+), 48 deletions(-) diff --git a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol index f90208ce81bd..0bd69f7498a8 100644 --- a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol +++ b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol @@ -11,53 +11,51 @@ import { Proxy } from "src/universal/Proxy.sol"; import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; import { Solarray } from "scripts/libraries/Solarray.sol"; -/** - * This comment block defines the requirements and rationale for the architecture used in this forge - * script, along with other scripts that are being written as new Superchain-first deploy scripts to - * complement the OP Stack Manager. The script architecture is a bit different than a standard forge - * deployment script. - * - * There are three categories of users that are expected to interact with the scripts: - * 1. End users that want to run live contract deployments. - * 2. Solidity developers that want to use or test these script in a standard forge test environment. - * 3. Go developers that want to run the deploy scripts as part of e2e testing with other aspects of the OP Stack. - * - * We want each user to interact with the scripts in the way that's simplest for their use case: - * 1. End users: TOML input files that define config, and TOML output files with all output data. - * 2. Solidity developers: Direct calls to the script with input structs and output structs. - * 3. Go developers: The forge scripts can be executed directly in Go. - * - * The following architecture is used to meet the requirements of each user. We use this file's - * `DeploySuperchain` script as an example, but it applies to other scripts as well. - * - * This `DeploySuperchain.s.sol` file contains three contracts: - * 1. `DeploySuperchainInput`: Responsible for parsing, storing, and exposing the input data. - * 2. `DeploySuperchainOutput`: Responsible for storing and exposing the output data. - * 3. `DeploySuperchain`: The core script that executes the deployment. It reads inputs from the - * input contract, and writes outputs to the output contract. - * - * Because the core script performs calls to the input and output contracts, Go developers can - * intercept calls to these addresses (analogous to how forge intercepts calls to the `Vm` address - * to execute cheatcodes), to avoid the need for file I/O or hardcoding the input/output structs. - * - * Public getter methods on the input and output contracts allow individual fields to be accessed - * in a strong, type-safe manner (as opposed to a single struct getter where the caller may - * inadvertently transpose two addresses, for example). - * - * Each deployment step in the core deploy script is modularized into its own function that performs - * the deploy and sets the output on the Output contract, allowing for easy composition and testing - * of deployment steps. The output setter methods requires keying off the four-byte selector of the - * each output field's getter method, ensuring that the output is set for the correct field and - * minimizing the amount of boilerplate needed for each output field. - * - * This script doubles as a reference for documenting the pattern used and therefore contains - * comments explaining the patterns used. Other scripts are not expected to have this level of - * documentation. - * - * Additionally, we intentionally use "Input" and "Output" terminology to clearly distinguish these - * scripts from the existing ones that "Config" and "Artifacts" terminology. - */ +// This comment block defines the requirements and rationale for the architecture used in this forge +// script, along with other scripts that are being written as new Superchain-first deploy scripts to +// complement the OP Stack Manager. The script architecture is a bit different than a standard forge +// deployment script. +// +// There are three categories of users that are expected to interact with the scripts: +// 1. End users that want to run live contract deployments. +// 2. Solidity developers that want to use or test these scripts in a standard forge test environment. +// 3. Go developers that want to run the deploy scripts as part of e2e testing with other aspects of the OP Stack. +// +// We want each user to interact with the scripts in the way that's simplest for their use case: +// 1. End users: TOML input files that define config, and TOML output files with all output data. +// 2. Solidity developers: Direct calls to the script with input structs and output structs. +// 3. Go developers: The forge scripts can be executed directly in Go. +// +// The following architecture is used to meet the requirements of each user. We use this file's +// `DeploySuperchain` script as an example, but it applies to other scripts as well. +// +// This `DeploySuperchain.s.sol` file contains three contracts: +// 1. `DeploySuperchainInput`: Responsible for parsing, storing, and exposing the input data. +// 2. `DeploySuperchainOutput`: Responsible for storing and exposing the output data. +// 3. `DeploySuperchain`: The core script that executes the deployment. It reads inputs from the +// input contract, and writes outputs to the output contract. +// +// Because the core script performs calls to the input and output contracts, Go developers can +// intercept calls to these addresses (analogous to how forge intercepts calls to the `Vm` address +// to execute cheatcodes), to avoid the need for file I/O or hardcoding the input/output structs. +// +// Public getter methods on the input and output contracts allow individual fields to be accessed +// in a strong, type-safe manner (as opposed to a single struct getter where the caller may +// inadvertently transpose two addresses, for example). +// +// Each deployment step in the core deploy script is modularized into its own function that performs +// the deploy and sets the output on the Output contract, allowing for easy composition and testing +// of deployment steps. The output setter methods requires keying off the four-byte selector of +// each output field's getter method, ensuring that the output is set for the correct field and +// minimizing the amount of boilerplate needed for each output field. +// +// This script doubles as a reference for documenting the pattern used and therefore contains +// comments explaining the patterns used. Other scripts are not expected to have this level of +// documentation. +// +// Additionally, we intentionally use "Input" and "Output" terminology to clearly distinguish these +// scripts from the existing ones that use the "Config" and "Artifacts" terminology. contract DeploySuperchainInput is CommonBase { // The input struct contains all the input data required for the deployment. // The fields must be in alphabetical order for vm.parseToml to work. @@ -238,7 +236,7 @@ contract DeploySuperchainOutput is CommonBase { // For all broadcasts in this script we explicitly specify the deployer as `msg.sender` because for // testing we deploy this script from a test contract. If we provide no argument, the foundry -// default sender is be the broadcaster during test, but the broadcaster needs to be the deployer +// default sender would be the broadcaster during test, but the broadcaster needs to be the deployer // since they are set to the initial proxy admin owner. contract DeploySuperchain is Script { // -------- Core Deployment Methods -------- @@ -300,7 +298,7 @@ contract DeploySuperchain is Script { function deploySuperchainProxyAdmin(DeploySuperchainInput, DeploySuperchainOutput _dso) public { // Deploy the proxy admin, with the owner set to the deployer. // We explicitly specify the deployer as `msg.sender` because for testing we deploy this script from a test - // contract. If we provide no argument, the foundry default sender is be the broadcaster during test, but the + // contract. If we provide no argument, the foundry default sender would be the broadcaster during test, but the // broadcaster needs to be the deployer since they are set to the initial proxy admin owner. vm.broadcast(msg.sender); ProxyAdmin superchainProxyAdmin = new ProxyAdmin(msg.sender); From 873a4eabb6b898d03879737e37902e8c409e4820 Mon Sep 17 00:00:00 2001 From: mbaxter Date: Fri, 6 Sep 2024 11:29:52 -0400 Subject: [PATCH 051/264] cannon: Port audit fixes (#11697) * cannon: Require boolean exited field to be encoded as 0 or 1 * cannon: Port mmap solidity tests for MTCannon * cannon: Port srav solidity tests * cannon: Run semver-lock, snapshot tasks * cannon: Cut extra validation on thread.exited * cannon: Run semver lock * cannon: Update IMIPS2 interface --- packages/contracts-bedrock/semver-lock.json | 4 +- .../snapshots/abi/MIPS2.json | 5 + .../contracts-bedrock/src/cannon/MIPS2.sol | 13 +- .../src/cannon/interfaces/IMIPS2.sol | 2 + .../src/cannon/libraries/MIPSState.sol | 8 + .../contracts-bedrock/test/cannon/MIPS.t.sol | 2 +- .../contracts-bedrock/test/cannon/MIPS2.t.sol | 195 +++++++++++++++++- 7 files changed, 221 insertions(+), 8 deletions(-) diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index c6cd7a701729..7bbd76d0c50e 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -148,8 +148,8 @@ "sourceCodeHash": "0xb6e219e8c2d81d75c48a1459907609e9096fe032a7447c88cd3e0d134752ac8e" }, "src/cannon/MIPS2.sol": { - "initCodeHash": "0x36b7c32cf9eba05e6db44910a25c800b801c075f8e053eca9515c6e0e4d8a902", - "sourceCodeHash": "0xa307c44a2d67bc84e75f4b7341345ed236da2e63c1f3f442416f14cd262126bf" + "initCodeHash": "0xf5e2bca4ba0c504ffa68f1ce5fbf4349b1fa892034777d77803d9111aed279fa", + "sourceCodeHash": "0xe8d06d4e2c3cf6e0682e4c152429cd61f0fd963acb1190df1bba1727d90ef6b7" }, "src/cannon/PreimageOracle.sol": { "initCodeHash": "0xce7a1c3265e457a05d17b6d1a2ef93c4639caac3733c9cf88bfd192eae2c5788", diff --git a/packages/contracts-bedrock/snapshots/abi/MIPS2.json b/packages/contracts-bedrock/snapshots/abi/MIPS2.json index c45a8711640c..9782bf01819c 100644 --- a/packages/contracts-bedrock/snapshots/abi/MIPS2.json +++ b/packages/contracts-bedrock/snapshots/abi/MIPS2.json @@ -51,5 +51,10 @@ ], "stateMutability": "view", "type": "function" + }, + { + "inputs": [], + "name": "InvalidExitedValue", + "type": "error" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/src/cannon/MIPS2.sol b/packages/contracts-bedrock/src/cannon/MIPS2.sol index a1bcea86edb8..2f1e10e8b20e 100644 --- a/packages/contracts-bedrock/src/cannon/MIPS2.sol +++ b/packages/contracts-bedrock/src/cannon/MIPS2.sol @@ -51,8 +51,8 @@ contract MIPS2 is ISemver { } /// @notice The semantic version of the MIPS2 contract. - /// @custom:semver 1.0.0-beta.5 - string public constant version = "1.0.0-beta.5"; + /// @custom:semver 1.0.0-beta.6 + string public constant version = "1.0.0-beta.6"; /// @notice The preimage oracle contract. IPreimageOracle internal immutable ORACLE; @@ -91,7 +91,7 @@ contract MIPS2 is ISemver { unchecked { State memory state; ThreadState memory thread; - + uint32 exited; assembly { if iszero(eq(state, STATE_MEM_OFFSET)) { // expected state mem offset check @@ -131,6 +131,7 @@ contract MIPS2 is ISemver { c, m := putField(c, m, 4) // heap c, m := putField(c, m, 1) // exitCode c, m := putField(c, m, 1) // exited + exited := mload(sub(m, 32)) c, m := putField(c, m, 8) // step c, m := putField(c, m, 8) // stepsSinceLastContextSwitch c, m := putField(c, m, 4) // wakeup @@ -139,6 +140,7 @@ contract MIPS2 is ISemver { c, m := putField(c, m, 32) // rightThreadStack c, m := putField(c, m, 4) // nextThreadID } + st.assertExitedIsValid(exited); if (state.exited) { // thread state is unchanged @@ -459,6 +461,7 @@ contract MIPS2 is ISemver { /// @notice Computes the hash of the MIPS state. /// @return out_ The hashed MIPS state. function outputState() internal returns (bytes32 out_) { + uint32 exited; assembly { // copies 'size' bytes, right-aligned in word at 'from', to 'to', incl. trailing data function copyMem(from, to, size) -> fromOut, toOut { @@ -481,7 +484,7 @@ contract MIPS2 is ISemver { from, to := copyMem(from, to, 4) // heap let exitCode := mload(from) from, to := copyMem(from, to, 1) // exitCode - let exited := mload(from) + exited := mload(from) from, to := copyMem(from, to, 1) // exited from, to := copyMem(from, to, 8) // step from, to := copyMem(from, to, 8) // stepsSinceLastContextSwitch @@ -516,6 +519,8 @@ contract MIPS2 is ISemver { out_ := keccak256(start, sub(to, start)) out_ := or(and(not(shl(248, 0xFF)), out_), shl(248, status)) } + + st.assertExitedIsValid(exited); } /// @notice Updates the current thread stack root via inner thread root in calldata diff --git a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol index ea7033aea907..2d53020f45ac 100644 --- a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol +++ b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol @@ -6,5 +6,7 @@ import { ISemver } from "src/universal/ISemver.sol"; /// @title IMIPS2 /// @notice Interface for the MIPS2 contract. interface IMIPS2 is ISemver { + error InvalidExitedValue(); + function step(bytes memory _stateData, bytes memory _proof, bytes32 _localContext) external returns (bytes32); } diff --git a/packages/contracts-bedrock/src/cannon/libraries/MIPSState.sol b/packages/contracts-bedrock/src/cannon/libraries/MIPSState.sol index d4431765c5b0..2f76a2e0dda5 100644 --- a/packages/contracts-bedrock/src/cannon/libraries/MIPSState.sol +++ b/packages/contracts-bedrock/src/cannon/libraries/MIPSState.sol @@ -1,6 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +import { InvalidExitedValue } from "src/cannon/libraries/CannonErrors.sol"; + library MIPSState { struct CpuScalars { uint32 pc; @@ -8,4 +10,10 @@ library MIPSState { uint32 lo; uint32 hi; } + + function assertExitedIsValid(uint32 exited) internal pure { + if (exited > 1) { + revert InvalidExitedValue(); + } + } } diff --git a/packages/contracts-bedrock/test/cannon/MIPS.t.sol b/packages/contracts-bedrock/test/cannon/MIPS.t.sol index 8e4c858b0ce6..7cbee449d363 100644 --- a/packages/contracts-bedrock/test/cannon/MIPS.t.sol +++ b/packages/contracts-bedrock/test/cannon/MIPS.t.sol @@ -65,7 +65,6 @@ contract MIPS_Test is CommonTest { /// invalid (anything greater than 1). /// @param _exited Value to set the exited field to. function testFuzz_step_invalidExitedValue_fails(uint8 _exited) external { - // Assume // Make sure the value of _exited is invalid. _exited = uint8(bound(uint256(_exited), 2, type(uint8).max)); @@ -77,6 +76,7 @@ contract MIPS_Test is CommonTest { // Compute the encoded state and manipulate it. bytes memory enc = encodeState(state); assembly { + // Push offset by an additional 32 bytes (0x20) to account for length prefix mstore8(add(add(enc, 0x20), 89), _exited) } diff --git a/packages/contracts-bedrock/test/cannon/MIPS2.t.sol b/packages/contracts-bedrock/test/cannon/MIPS2.t.sol index dc377dcea8fa..82ac77ab920a 100644 --- a/packages/contracts-bedrock/test/cannon/MIPS2.t.sol +++ b/packages/contracts-bedrock/test/cannon/MIPS2.t.sol @@ -5,7 +5,9 @@ import { CommonTest } from "test/setup/CommonTest.sol"; import { MIPS2 } from "src/cannon/MIPS2.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { MIPSSyscalls as sys } from "src/cannon/libraries/MIPSSyscalls.sol"; +import { MIPSInstructions as ins } from "src/cannon/libraries/MIPSInstructions.sol"; import "src/dispute/lib/Types.sol"; +import { InvalidExitedValue } from "src/cannon/libraries/CannonErrors.sol"; contract ThreadStack { bytes32 internal constant EMPTY_THREAD_ROOT = hex"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5"; @@ -191,6 +193,34 @@ contract MIPS2_Test is CommonTest { assertNotEq(post, bytes32(0)); } + /// @notice Tests that the mips step function fails when the value of the exited field is + /// invalid (anything greater than 1). + /// @param _exited Value to set the exited field to. + function testFuzz_step_invalidExitedValueInState_fails(uint8 _exited) external { + // Make sure the value of _exited is invalid. + _exited = uint8(bound(uint256(_exited), 2, type(uint8).max)); + + // Setup state + uint32 insn = encodespec(17, 18, 8, 0x20); // Arbitrary instruction: add t0, s1, s2 + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = + constructMIPSState(0, insn, 0x4, 0); + + // Set up step data + bytes memory encodedThread = encodeThread(thread); + bytes memory threadWitness = abi.encodePacked(encodedThread, EMPTY_THREAD_ROOT); + bytes memory proofData = bytes.concat(threadWitness, memProof); + bytes memory stateData = encodeState(state); + assembly { + // Manipulate state data + // Push offset by an additional 32 bytes (0x20) to account for length prefix + mstore8(add(add(stateData, 0x20), 73), _exited) + } + + // Call the step function and expect a revert. + vm.expectRevert(InvalidExitedValue.selector); + mips.step(stateData, proofData, 0); + } + function test_invalidThreadWitness_reverts() public { MIPS2.State memory state; MIPS2.ThreadState memory thread; @@ -1076,6 +1106,166 @@ contract MIPS2_Test is CommonTest { assertEq(postState, outputState(expect), "unexpected post state"); } + function test_mmap_succeeds_simple() external { + uint32 insn = 0x0000000c; // syscall + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = + constructMIPSState(0, insn, 0x4, 0); + + state.heap = 4096; + thread.nextPC = 4; + thread.registers[2] = sys.SYS_MMAP; // syscall num + thread.registers[4] = 0x0; // a0 + thread.registers[5] = 4095; // a1 + updateThreadStacks(state, thread); + + // Set up step data + bytes memory threadWitness = abi.encodePacked(encodeThread(thread), EMPTY_THREAD_ROOT); + bytes memory encodedState = encodeState(state); + + MIPS2.State memory expect = copyState(state); + MIPS2.ThreadState memory expectThread = copyThread(thread); + expect.memRoot = state.memRoot; + expect.step = state.step + 1; + expect.stepsSinceLastContextSwitch = state.stepsSinceLastContextSwitch + 1; + expect.heap = state.heap + 4096; + expectThread.pc = thread.nextPC; + expectThread.nextPC = thread.nextPC + 4; + expectThread.registers[2] = state.heap; // return old heap + expectThread.registers[7] = 0; // No error + updateThreadStacks(expect, expectThread); + + bytes32 postState = mips.step(encodedState, bytes.concat(threadWitness, memProof), 0); + assertEq(postState, outputState(expect), "unexpected post state"); + } + + function test_mmap_succeeds_justWithinMemLimit() external { + uint32 insn = 0x0000000c; // syscall + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = + constructMIPSState(0, insn, 0x4, 0); + + state.heap = sys.HEAP_END - 4096; // Set up to increase heap to its limit + thread.nextPC = 4; + thread.registers[2] = sys.SYS_MMAP; // syscall num + thread.registers[4] = 0x0; // a0 + thread.registers[5] = 4095; // a1 + updateThreadStacks(state, thread); + + // Set up step data + bytes memory threadWitness = abi.encodePacked(encodeThread(thread), EMPTY_THREAD_ROOT); + bytes memory encodedState = encodeState(state); + + MIPS2.State memory expect = copyState(state); + MIPS2.ThreadState memory expectThread = copyThread(thread); + expect.memRoot = state.memRoot; + expect.step += 1; + expect.stepsSinceLastContextSwitch += 1; + expect.heap = sys.HEAP_END; + expectThread.pc = thread.nextPC; + expectThread.nextPC = thread.nextPC + 4; + expectThread.registers[2] = state.heap; // Return the old heap value + expectThread.registers[7] = 0; // No error + updateThreadStacks(expect, expectThread); + + bytes32 postState = mips.step(encodedState, bytes.concat(threadWitness, memProof), 0); + assertEq(postState, outputState(expect), "unexpected post state"); + } + + function test_mmap_fails() external { + uint32 insn = 0x0000000c; // syscall + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = + constructMIPSState(0, insn, 0x4, 0); + + state.heap = sys.HEAP_END - 4096; // Set up to increase heap beyond its limit + thread.nextPC = 4; + thread.registers[2] = sys.SYS_MMAP; // syscall num + thread.registers[4] = 0x0; // a0 + thread.registers[5] = 4097; // a1 + updateThreadStacks(state, thread); + + // Set up step data + bytes memory threadWitness = abi.encodePacked(encodeThread(thread), EMPTY_THREAD_ROOT); + bytes memory encodedState = encodeState(state); + + MIPS2.State memory expect = copyState(state); + MIPS2.ThreadState memory expectThread = copyThread(thread); + expect.memRoot = state.memRoot; + expect.step += 1; + expect.stepsSinceLastContextSwitch += 1; + expectThread.pc = thread.nextPC; + expectThread.nextPC = thread.nextPC + 4; + expectThread.registers[2] = sys.SYS_ERROR_SIGNAL; // signal an stdError + expectThread.registers[7] = sys.EINVAL; // Return error value + expectThread.registers[4] = thread.registers[4]; // a0 + expectThread.registers[5] = thread.registers[5]; // a1 + updateThreadStacks(expect, expectThread); + + bytes32 postState = mips.step(encodedState, bytes.concat(threadWitness, memProof), 0); + assertEq(postState, outputState(expect), "unexpected post state"); + } + + function test_srav_succeeds() external { + uint32 insn = encodespec(0xa, 0x9, 0x8, 7); // srav t0, t1, t2 + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = + constructMIPSState(0, insn, 0x4, 0); + thread.registers[9] = 0xdeafbeef; // t1 + thread.registers[10] = 12; // t2 + updateThreadStacks(state, thread); + + // Set up step data + bytes memory threadWitness = abi.encodePacked(encodeThread(thread), EMPTY_THREAD_ROOT); + bytes memory encodedState = encodeState(state); + + MIPS2.State memory expect = copyState(state); + MIPS2.ThreadState memory expectThread = copyThread(thread); + expect.memRoot = state.memRoot; + expect.step += 1; + expect.stepsSinceLastContextSwitch += 1; + expectThread.pc = thread.nextPC; + expectThread.nextPC = thread.nextPC + 4; + expectThread.registers[8] = 0xfffdeafb; // t0 + updateThreadStacks(expect, expectThread); + + bytes32 postState = mips.step(encodedState, bytes.concat(threadWitness, memProof), 0); + assertEq(postState, outputState(expect), "unexpected post state"); + } + + /// @notice Tests that the SRAV instruction succeeds when it includes extra bits in the shift + /// amount beyond the lower 5 bits that are actually used for the shift. Extra bits + /// need to be ignored but the instruction should still succeed. + /// @param _rs Value to set in the shift register $rs. + function testFuzz_srav_withExtraBits_succeeds(uint32 _rs) external { + // Assume + // Force _rs to have more than 5 bits set. + _rs = uint32(bound(uint256(_rs), 0x20, type(uint32).max)); + + uint32 insn = encodespec(0xa, 0x9, 0x8, 7); // srav t0, t1, t2 + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = + constructMIPSState(0, insn, 0x4, 0); + thread.registers[9] = 0xdeadbeef; // t1 + thread.registers[10] = _rs; // t2 + updateThreadStacks(state, thread); + + // Set up step data + bytes memory threadWitness = abi.encodePacked(encodeThread(thread), EMPTY_THREAD_ROOT); + bytes memory encodedState = encodeState(state); + + // Calculate shamt + uint32 shamt = thread.registers[10] & 0x1F; + + MIPS2.State memory expect = copyState(state); + MIPS2.ThreadState memory expectThread = copyThread(thread); + expect.memRoot = state.memRoot; + expect.step += 1; + expect.stepsSinceLastContextSwitch += 1; + expectThread.pc = thread.nextPC; + expectThread.nextPC = thread.nextPC + 4; + expectThread.registers[8] = ins.signExtend(thread.registers[9] >> shamt, 32 - shamt); // t0 + updateThreadStacks(expect, expectThread); + + bytes32 postState = mips.step(encodedState, bytes.concat(threadWitness, memProof), 0); + assertEq(postState, outputState(expect), "unexpected post state"); + } + function test_add_succeeds() public { uint32 insn = encodespec(17, 18, 8, 0x20); // add t0, s1, s2 (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = @@ -2175,8 +2365,11 @@ contract MIPS2_Test is CommonTest { } } - function outputState(MIPS2.State memory state) internal pure returns (bytes32 out_) { + event ExpectedOutputState(bytes encoded, MIPS2.State state); + + function outputState(MIPS2.State memory state) internal returns (bytes32 out_) { bytes memory enc = encodeState(state); + emit ExpectedOutputState(enc, state); VMStatus status = vmStatus(state); out_ = keccak256(enc); assembly { From ccf9d3e251a2d1669454082512039f10924a7ed9 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Fri, 6 Sep 2024 12:16:42 -0400 Subject: [PATCH 052/264] ci: pull cached artifacts for contracts tests (#11771) Contracts tests don't need to recompile if we can just use the artifacts instead. --- .circleci/config.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index f1308ae13080..9e093aa1d923 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -543,6 +543,10 @@ jobs: name: print forge version command: forge --version working_directory: packages/contracts-bedrock + - run: + name: pull cached artifacts + command: bash scripts/ops/pull-artifacts.sh + working_directory: packages/contracts-bedrock - run: name: run tests command: just test From afcc51a4e89d5189930ce5b6701f7ceb0b1db10d Mon Sep 17 00:00:00 2001 From: Matt Solomon Date: Fri, 6 Sep 2024 11:07:12 -0700 Subject: [PATCH 053/264] test: more blueprint tests (#11782) * test: more blueprint tests * address PR feedback --- .../src/libraries/Blueprint.sol | 18 +- .../test/libraries/Blueprint.t.sol | 236 ++++++++++++++++-- 2 files changed, 228 insertions(+), 26 deletions(-) diff --git a/packages/contracts-bedrock/src/libraries/Blueprint.sol b/packages/contracts-bedrock/src/libraries/Blueprint.sol index 84e41346775a..2e0979e1c6bf 100644 --- a/packages/contracts-bedrock/src/libraries/Blueprint.sol +++ b/packages/contracts-bedrock/src/libraries/Blueprint.sol @@ -28,7 +28,7 @@ library Blueprint { /// @notice Thrown when parsing a blueprint preamble and the preamble data is not empty. /// We do not use the preamble data, so it's expected to be empty. - error UnexpectedPreambleData(); + error UnexpectedPreambleData(bytes data); /// @notice Thrown during deployment if the ERC version is not supported. error UnsupportedERCVersion(uint8 version); @@ -37,6 +37,9 @@ library Blueprint { /// which will deploy a corresponding blueprint contract (with no data section). Based on the /// reference implementation in https://eips.ethereum.org/EIPS/eip-5202. function blueprintDeployerBytecode(bytes memory _initcode) internal pure returns (bytes memory) { + // Check that the initcode is not empty. + if (_initcode.length == 0) revert EmptyInitcode(); + bytes memory blueprintPreamble = hex"FE7100"; // ERC-5202 preamble. bytes memory blueprintBytecode = bytes.concat(blueprintPreamble, _initcode); @@ -89,12 +92,18 @@ library Blueprint { return Preamble(ercVersion, preambleData, initcode); } + /// @notice Parses the code at the given `_target` as a blueprint and deploys the resulting initcode. + /// This version of `deployFrom` is used when the initcode requires no constructor arguments. + function deployFrom(address _target, bytes32 _salt) internal returns (address) { + return deployFrom(_target, _salt, new bytes(0)); + } + /// @notice Parses the code at the given `_target` as a blueprint and deploys the resulting initcode /// with the given `_data` appended, i.e. `_data` is the ABI-encoded constructor arguments. function deployFrom(address _target, bytes32 _salt, bytes memory _data) internal returns (address newContract_) { Preamble memory preamble = parseBlueprintPreamble(address(_target).code); if (preamble.ercVersion != 0) revert UnsupportedERCVersion(preamble.ercVersion); - if (preamble.preambleData.length != 0) revert UnexpectedPreambleData(); + if (preamble.preambleData.length != 0) revert UnexpectedPreambleData(preamble.preambleData); bytes memory initcode = bytes.concat(preamble.initcode, _data); assembly ("memory-safe") { @@ -103,11 +112,6 @@ library Blueprint { if (newContract_ == address(0)) revert DeploymentFailed(); } - /// @notice Parses the code at the given `_target` as a blueprint and deploys the resulting initcode. - function deployFrom(address _target, bytes32 _salt) internal returns (address) { - return deployFrom(_target, _salt, new bytes(0)); - } - /// @notice Convert a bytes array to a uint256. function bytesToUint(bytes memory _b) internal pure returns (uint256) { if (_b.length > 32) revert BytesArrayTooLong(); diff --git a/packages/contracts-bedrock/test/libraries/Blueprint.t.sol b/packages/contracts-bedrock/test/libraries/Blueprint.t.sol index 419e68f95666..94a30ab99fb0 100644 --- a/packages/contracts-bedrock/test/libraries/Blueprint.t.sol +++ b/packages/contracts-bedrock/test/libraries/Blueprint.t.sol @@ -4,43 +4,241 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; import { Blueprint } from "src/libraries/Blueprint.sol"; +// Used to test that constructor args are appended properly when deploying from a blueprint. +contract ConstructorArgMock { + uint256 public x; + bytes public y; + + constructor(uint256 _x, bytes memory _y) { + x = _x; + y = _y; + } +} + +// Foundry cheatcodes operate on the next call, and since all library methods are internal we would +// just JUMP to them if called directly in the test. Therefore we wrap the library in a contract. +contract BlueprintHarness { + function blueprintDeployerBytecode(bytes memory _initcode) public pure returns (bytes memory) { + return Blueprint.blueprintDeployerBytecode(_initcode); + } + + function parseBlueprintPreamble(bytes memory _bytecode) public pure returns (Blueprint.Preamble memory) { + return Blueprint.parseBlueprintPreamble(_bytecode); + } + + function deployFrom(address _blueprint, bytes32 _salt) public returns (address) { + return Blueprint.deployFrom(_blueprint, _salt); + } + + function deployFrom(address _blueprint, bytes32 _salt, bytes memory _args) public returns (address) { + return Blueprint.deployFrom(_blueprint, _salt, _args); + } + + function bytesToUint(bytes memory _bytes) public pure returns (uint256) { + return Blueprint.bytesToUint(_bytes); + } +} + contract Blueprint_Test is Test { - // TODO add tests that things revert if an address has no code. + BlueprintHarness blueprint; + + function setUp() public { + blueprint = new BlueprintHarness(); + } + + function deployWithCreate2(bytes memory _initcode, bytes32 _salt) public returns (address addr_) { + assembly ("memory-safe") { + addr_ := create2(0, add(_initcode, 0x20), mload(_initcode), _salt) + } + require(addr_ != address(0), "deployWithCreate2: deployment failed"); + } + + // --- We start with the test cases from ERC-5202 --- + + // An example (and trivial!) blueprint contract with no data section, whose initcode is just the STOP instruction. + function test_ERC5202_trivialBlueprint_succeeds() public view { + bytes memory bytecode = hex"FE710000"; + Blueprint.Preamble memory preamble = blueprint.parseBlueprintPreamble(bytecode); + + assertEq(preamble.ercVersion, 0, "100"); + assertEq(preamble.preambleData, hex"", "200"); + assertEq(preamble.initcode, hex"00", "300"); + } + + // An example blueprint contract whose initcode is the trivial STOP instruction and whose data + // section contains the byte 0xFF repeated seven times. + function test_ERC5202_blueprintWithDataSection_succeeds() public view { + // Here, 0xFE71 is the magic header, 0x01 means version 0 + 1 length bit, 0x07 encodes the + // length in bytes of the data section. These are followed by the data section, and then the + // initcode. For illustration, this code with delimiters would be: + // 0xFE71|01|07|FFFFFFFFFFFFFF|00 + bytes memory bytecode = hex"FE710107FFFFFFFFFFFFFF00"; + Blueprint.Preamble memory preamble = blueprint.parseBlueprintPreamble(bytecode); + + assertEq(preamble.ercVersion, 0, "100"); + assertEq(preamble.preambleData, hex"FFFFFFFFFFFFFF", "200"); + assertEq(preamble.initcode, hex"00", "300"); + } + + // An example blueprint whose initcode is the trivial STOP instruction and whose data section + // contains the byte 0xFF repeated 256 times. + function test_ERC5202_blueprintWithLargeDataSection_succeeds() public view { + // Delimited, this would be 0xFE71|02|0100|FF...FF|00 + bytes memory bytecode = + hex"FE71020100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00"; + Blueprint.Preamble memory preamble = blueprint.parseBlueprintPreamble(bytecode); + + assertEq(preamble.ercVersion, 0, "100"); + assertEq(preamble.preambleData.length, 256, "200"); + for (uint256 i = 0; i < 256; i++) { + assertEq(preamble.preambleData[i], bytes1(0xFF), string.concat("300-", vm.toString(i))); + } + assertEq(preamble.initcode, hex"00", "400"); + } - function test_roundtrip_succeeds(bytes memory _initcode) public { + // --- Now we add a generic roundtrip test --- + + // Test that a roundtrip from initcode to blueprint to initcode succeeds, i.e. the invariant + // here is that `parseBlueprintPreamble(blueprintDeployerBytecode(x)) = x`. + function testFuzz_roundtrip_succeeds(bytes memory _initcode) public { vm.assume(_initcode.length > 0); // Convert the initcode to match the ERC-5202 blueprint format. - bytes memory blueprintInitcode = Blueprint.blueprintDeployerBytecode(_initcode); + bytes memory blueprintInitcode = blueprint.blueprintDeployerBytecode(_initcode); // Deploy the blueprint. - address blueprintAddress; - assembly ("memory-safe") { - blueprintAddress := create2(0, add(blueprintInitcode, 0x20), mload(blueprintInitcode), 0) - } - require(blueprintAddress != address(0), "DeployImplementations: create2 failed"); + address blueprintAddress = deployWithCreate2(blueprintInitcode, bytes32(0)); // Read the blueprint code from the deployed code. bytes memory blueprintCode = address(blueprintAddress).code; - // Parse the blueprint preamble. - Blueprint.Preamble memory preamble = Blueprint.parseBlueprintPreamble(blueprintCode); + // Parse the blueprint preamble and ensure it matches the expected values. + Blueprint.Preamble memory preamble = blueprint.parseBlueprintPreamble(blueprintCode); assertEq(preamble.ercVersion, 0, "100"); assertEq(preamble.preambleData, hex"", "200"); assertEq(preamble.initcode, _initcode, "300"); } - function test_bytesToUint_succeeds() public pure { + // --- Lastly, function-specific unit tests --- + + function test_blueprintDeployerBytecode_emptyInitcode_reverts() public { + bytes memory initcode = ""; + vm.expectRevert(Blueprint.EmptyInitcode.selector); + blueprint.blueprintDeployerBytecode(initcode); + } + + function test_parseBlueprintPreamble_notABlueprint_reverts() public { + // Length too short. + bytes memory invalidBytecode = hex"01"; + vm.expectRevert(Blueprint.NotABlueprint.selector); + blueprint.parseBlueprintPreamble(invalidBytecode); + + // First byte is not 0xFE. + invalidBytecode = hex"0071"; + vm.expectRevert(Blueprint.NotABlueprint.selector); + blueprint.parseBlueprintPreamble(invalidBytecode); + + // Second byte is not 0x71. + invalidBytecode = hex"FE00"; + vm.expectRevert(Blueprint.NotABlueprint.selector); + blueprint.parseBlueprintPreamble(invalidBytecode); + } + + function test_parseBlueprintPreamble_reservedBitsSet_reverts() public { + bytes memory invalidBytecode = hex"FE7103"; + vm.expectRevert(Blueprint.ReservedBitsSet.selector); + blueprint.parseBlueprintPreamble(invalidBytecode); + } + + function test_parseBlueprintPreamble_emptyInitcode_reverts() public { + bytes memory invalidBytecode = hex"FE7100"; + vm.expectRevert(Blueprint.EmptyInitcode.selector); + blueprint.parseBlueprintPreamble(invalidBytecode); + } + + function testFuzz_deployFrom_succeeds(bytes memory _initcode, bytes32 _salt) public { + vm.assume(_initcode.length > 0); + vm.assume(_initcode[0] != 0xef); // https://eips.ethereum.org/EIPS/eip-3541 + + // This deployBytecode prefix is the same bytecode used in `blueprintDeployerBytecode`, and + // it ensures that whatever initcode the fuzzer generates is actually deployable. + bytes memory deployBytecode = bytes.concat(hex"61", bytes2(uint16(_initcode.length)), hex"3d81600a3d39f3"); + bytes memory initcode = bytes.concat(deployBytecode, _initcode); + bytes memory blueprintInitcode = blueprint.blueprintDeployerBytecode(initcode); + + // Deploy the blueprint. + address blueprintAddress = deployWithCreate2(blueprintInitcode, _salt); + + // Deploy from the blueprint. + address deployedContract = Blueprint.deployFrom(blueprintAddress, _salt); + + // Verify the deployment worked. + assertTrue(deployedContract != address(0), "100"); + assertTrue(deployedContract.code.length > 0, "200"); + assertEq(keccak256(deployedContract.code), keccak256(_initcode), "300"); + } + + // Here we deploy a simple mock contract to test that constructor args are appended properly. + function testFuzz_deployFrom_withConstructorArgs_succeeds(uint256 _x, bytes memory _y, bytes32 _salt) public { + bytes memory blueprintInitcode = blueprint.blueprintDeployerBytecode(type(ConstructorArgMock).creationCode); + + // Deploy the blueprint. + address blueprintAddress = deployWithCreate2(blueprintInitcode, _salt); + + // Deploy from the blueprint. + bytes memory args = abi.encode(_x, _y); + address deployedContract = blueprint.deployFrom(blueprintAddress, _salt, args); + + // Verify the deployment worked. + assertTrue(deployedContract != address(0), "100"); + assertTrue(deployedContract.code.length > 0, "200"); + assertEq(keccak256(deployedContract.code), keccak256(type(ConstructorArgMock).runtimeCode), "300"); + assertEq(ConstructorArgMock(deployedContract).x(), _x, "400"); + assertEq(ConstructorArgMock(deployedContract).y(), _y, "500"); + } + + function test_deployFrom_unsupportedERCVersion_reverts() public { + bytes32 salt = bytes32(0); + address blueprintAddress = makeAddr("blueprint"); + + bytes memory invalidBlueprintCode = hex"FE710400"; // ercVersion = uint8(0x04 & 0xfc) >> 2 = 1 + vm.etch(blueprintAddress, invalidBlueprintCode); + vm.expectRevert(abi.encodeWithSelector(Blueprint.UnsupportedERCVersion.selector, 1)); + blueprint.deployFrom(blueprintAddress, salt); + + invalidBlueprintCode = hex"FE71B000"; // ercVersion = uint8(0xB0 & 0xfc) >> 2 = 44 + vm.etch(blueprintAddress, invalidBlueprintCode); + vm.expectRevert(abi.encodeWithSelector(Blueprint.UnsupportedERCVersion.selector, 44)); + blueprint.deployFrom(blueprintAddress, salt); + } + + function test_deployFrom_unexpectedPreambleData_reverts() public { + bytes32 salt = bytes32(0); + address blueprintAddress = makeAddr("blueprint"); + + // Create invalid blueprint code with non-empty preamble data + bytes memory invalidBlueprintCode = hex"FE7101030102030001020304"; + vm.etch(blueprintAddress, invalidBlueprintCode); + + // Expect revert with UnexpectedPreambleData error + vm.expectRevert(abi.encodeWithSelector(Blueprint.UnexpectedPreambleData.selector, hex"010203")); + blueprint.deployFrom(blueprintAddress, salt); + } + + function test_bytesToUint_succeeds() public view { // These test cases (and the logic for bytesToUint) are taken from forge-std. - assertEq(3, Blueprint.bytesToUint(hex"03")); - assertEq(2, Blueprint.bytesToUint(hex"02")); - assertEq(255, Blueprint.bytesToUint(hex"ff")); - assertEq(29625, Blueprint.bytesToUint(hex"73b9")); + assertEq(3, blueprint.bytesToUint(hex"03")); + assertEq(2, blueprint.bytesToUint(hex"02")); + assertEq(255, blueprint.bytesToUint(hex"ff")); + assertEq(29625, blueprint.bytesToUint(hex"73b9")); // Additional test cases. - assertEq(0, Blueprint.bytesToUint(hex"")); - assertEq(0, Blueprint.bytesToUint(hex"00")); - assertEq(14545064521499334880, Blueprint.bytesToUint(hex"c9da731e871ad8e0")); - assertEq(type(uint256).max, Blueprint.bytesToUint(bytes.concat(bytes32(type(uint256).max)))); + assertEq(0, blueprint.bytesToUint(hex"")); + assertEq(0, blueprint.bytesToUint(hex"00")); + assertEq(3, blueprint.bytesToUint(hex"0003")); + assertEq(3145731, blueprint.bytesToUint(hex"300003")); + assertEq(14545064521499334880, blueprint.bytesToUint(hex"c9da731e871ad8e0")); + assertEq(14545064521499334880, blueprint.bytesToUint(hex"00c9da731e871ad8e0")); + assertEq(type(uint256).max, blueprint.bytesToUint(bytes.concat(bytes32(type(uint256).max)))); } } From 49a4e9faa772d2064d45c974cfc83f1484c14ccf Mon Sep 17 00:00:00 2001 From: protolambda Date: Fri, 6 Sep 2024 15:08:40 -0600 Subject: [PATCH 054/264] op-chain-ops: prep / utils for interop genesis work (#11790) --- op-chain-ops/devkeys/devkeys.go | 16 +++++- op-chain-ops/script/precompile.go | 59 +++++++++++++++++++- op-chain-ops/script/precompile_test.go | 22 ++++++++ op-chain-ops/script/script.go | 77 ++++++++++++++++++++++---- op-chain-ops/srcmap/solutil.go | 4 ++ 5 files changed, 162 insertions(+), 16 deletions(-) diff --git a/op-chain-ops/devkeys/devkeys.go b/op-chain-ops/devkeys/devkeys.go index b4fefe04e598..c79739500ffa 100644 --- a/op-chain-ops/devkeys/devkeys.go +++ b/op-chain-ops/devkeys/devkeys.go @@ -55,18 +55,26 @@ type SuperchainOperatorRole uint64 const ( // SuperchainDeployerKey is the deployer of the superchain contracts. SuperchainDeployerKey SuperchainOperatorRole = 0 + // SuperchainProxyAdminOwner is the key that owns the superchain ProxyAdmin + SuperchainProxyAdminOwner SuperchainOperatorRole = 1 // SuperchainConfigGuardianKey is the Guardian of the SuperchainConfig. - SuperchainConfigGuardianKey SuperchainOperatorRole = 1 + SuperchainConfigGuardianKey SuperchainOperatorRole = 2 + // SuperchainProtocolVersionsOwner is the key that can make ProtocolVersions changes. + SuperchainProtocolVersionsOwner SuperchainOperatorRole = 3 // DependencySetManagerKey is the key used to manage the dependency set of a superchain. - DependencySetManagerKey SuperchainOperatorRole = 2 + DependencySetManagerKey SuperchainOperatorRole = 4 ) func (role SuperchainOperatorRole) String() string { switch role { case SuperchainDeployerKey: return "superchain-deployer" + case SuperchainProxyAdminOwner: + return "superchain-proxy-admin-owner" case SuperchainConfigGuardianKey: return "superchain-config-guardian" + case SuperchainProtocolVersionsOwner: + return "superchain-protocol-versions-owner" case DependencySetManagerKey: return "dependency-set-manager" default: @@ -122,6 +130,8 @@ const ( L1FeeVaultRecipientRole ChainOperatorRole = 8 // SequencerFeeVaultRecipientRole is the key that receives form the SequencerFeeVault predeploy SequencerFeeVaultRecipientRole ChainOperatorRole = 9 + // SystemConfigOwner is the key that can make SystemConfig changes. + SystemConfigOwner ChainOperatorRole = 10 ) func (role ChainOperatorRole) String() string { @@ -146,6 +156,8 @@ func (role ChainOperatorRole) String() string { return "l1-fee-vault-recipient" case SequencerFeeVaultRecipientRole: return "sequencer-fee-vault-recipient" + case SystemConfigOwner: + return "system-config-owner" default: return fmt.Sprintf("unknown-operator-%d", uint64(role)) } diff --git a/op-chain-ops/script/precompile.go b/op-chain-ops/script/precompile.go index 56094b9c2e0b..2dcea6601883 100644 --- a/op-chain-ops/script/precompile.go +++ b/op-chain-ops/script/precompile.go @@ -10,11 +10,15 @@ import ( "strings" "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" ) +var setterFnSig = "set(bytes4,address)" +var setterFnBytes4 = bytes4(setterFnSig) + // precompileFunc is a prepared function to perform a method call / field read with ABI decoding/encoding. type precompileFunc struct { goName string @@ -52,12 +56,20 @@ func rightPad32(data []byte) []byte { return append(out, make([]byte, 32-(len(out)%32))...) } +type settableField struct { + name string + value *reflect.Value +} + // Precompile is a wrapper around a Go object, making it a precompile. type Precompile[E any] struct { Precompile E fieldsOnly bool + fieldSetter bool + settable map[[4]byte]*settableField + // abiMethods is effectively the jump-table for 4-byte ABI calls to the precompile. abiMethods map[[4]byte]*precompileFunc } @@ -70,6 +82,10 @@ func WithFieldsOnly[E any](p *Precompile[E]) { p.fieldsOnly = true } +func WithFieldSetter[E any](p *Precompile[E]) { + p.fieldSetter = true +} + // NewPrecompile wraps a Go object into a Precompile. // All exported fields and methods will have a corresponding ABI interface. // Fields with a tag `evm:"-"` will be ignored, or can override their ABI name to x with this tag: `evm:"x"`. @@ -80,9 +96,11 @@ func WithFieldsOnly[E any](p *Precompile[E]) { // All precompile methods have 0 gas cost. func NewPrecompile[E any](e E, opts ...PrecompileOption[E]) (*Precompile[E], error) { out := &Precompile[E]{ - Precompile: e, - abiMethods: make(map[[4]byte]*precompileFunc), - fieldsOnly: false, + Precompile: e, + abiMethods: make(map[[4]byte]*precompileFunc), + fieldsOnly: false, + fieldSetter: false, + settable: make(map[[4]byte]*settableField), } for _, opt := range opts { opt(out) @@ -96,6 +114,8 @@ func NewPrecompile[E any](e E, opts ...PrecompileOption[E]) (*Precompile[E], err if err := out.setupFields(&elemVal); err != nil { return nil, fmt.Errorf("failed to setup fields of precompile: %w", err) } + // create setter that can handle of the fields + out.setupFieldSetter() return out, nil } @@ -496,9 +516,42 @@ func (p *Precompile[E]) setupStructField(fieldDef *reflect.StructField, fieldVal abiSignature: methodSig, fn: fn, } + // register field as settable + if p.fieldSetter && fieldDef.Type.AssignableTo(typeFor[common.Address]()) { + p.settable[byte4Sig] = &settableField{ + name: fieldDef.Name, + value: fieldVal, + } + } return nil } +func (p *Precompile[E]) setupFieldSetter() { + if !p.fieldSetter { + return + } + p.abiMethods[setterFnBytes4] = &precompileFunc{ + goName: "__fieldSetter___", + abiSignature: setterFnSig, + fn: func(input []byte) ([]byte, error) { + if len(input) != 32*2 { + return nil, fmt.Errorf("cannot set address field to %d bytes", len(input)) + } + if [32 - 4]byte(input[4:32]) != ([32 - 4]byte{}) { + return nil, fmt.Errorf("unexpected selector content, input: %x", input[:]) + } + selector := [4]byte(input[:4]) + f, ok := p.settable[selector] + if !ok { + return nil, fmt.Errorf("unknown address field selector 0x%x", selector) + } + addr := common.Address(input[32*2-20 : 32*2]) + f.value.Set(reflect.ValueOf(addr)) + return nil, nil + }, + } +} + // RequiredGas is part of the vm.PrecompiledContract interface, and all system precompiles use 0 gas. func (p *Precompile[E]) RequiredGas(input []byte) uint64 { return 0 diff --git a/op-chain-ops/script/precompile_test.go b/op-chain-ops/script/precompile_test.go index ba2f02202ec3..a207c1221f9f 100644 --- a/op-chain-ops/script/precompile_test.go +++ b/op-chain-ops/script/precompile_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" ) @@ -119,3 +120,24 @@ func TestPrecompile(t *testing.T) { require.NoError(t, err) require.Equal(t, b32((42+100+7)*3), out) } + +type DeploymentExample struct { + FooBar common.Address +} + +func TestDeploymentOutputPrecompile(t *testing.T) { + e := &DeploymentExample{} + p, err := NewPrecompile[*DeploymentExample](e, WithFieldSetter[*DeploymentExample]) + require.NoError(t, err) + + addr := common.Address{0: 0x42, 19: 0xaa} + fooBarSelector := bytes4("fooBar()") + var input []byte + input = append(input, setterFnBytes4[:]...) + input = append(input, rightPad32(fooBarSelector[:])...) + input = append(input, leftPad32(addr[:])...) + out, err := p.Run(input) + require.NoError(t, err) + require.Empty(t, out) + require.Equal(t, addr, e.FooBar) +} diff --git a/op-chain-ops/script/script.go b/op-chain-ops/script/script.go index 5950e1db02e3..16ee8f7a94da 100644 --- a/op-chain-ops/script/script.go +++ b/op-chain-ops/script/script.go @@ -29,6 +29,9 @@ import ( "github.com/ethereum-optimism/optimism/op-chain-ops/srcmap" ) +// jumpHistory is the amount of successful jumps to track for debugging. +const jumpHistory = 5 + // CallFrame encodes the scope context of the current call type CallFrame struct { Depth int @@ -39,7 +42,9 @@ type CallFrame struct { // Reverts often happen in generated code. // We want to fallback to logging the source-map position of // the non-generated code, i.e. the origin of the last successful jump. - LastJumpPC uint64 + // And beyond that, a short history of the latest jumps is useful for debugging. + // This is a list of program-counters at the time of the jump (i.e. before raching JUMPDEST). + LastJumps []uint64 Ctx *vm.ScopeContext @@ -79,6 +84,8 @@ type Host struct { // src-maps are disabled if this is nil. srcFS *foundry.SourceMapFS srcMaps map[common.Address]*srcmap.SourceMap + + onLabel []func(name string, addr common.Address) } // NewHost creates a Host that can load contracts from the given Artifacts FS, @@ -378,11 +385,10 @@ func (h *Host) onOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpCo // We do this here, instead of onEnter, to capture an initialized scope. if len(h.callStack) == 0 || h.callStack[len(h.callStack)-1].Depth < depth { h.callStack = append(h.callStack, CallFrame{ - Depth: depth, - LastOp: vm.OpCode(op), - LastPC: pc, - LastJumpPC: pc, - Ctx: scopeCtx, + Depth: depth, + LastOp: vm.OpCode(op), + LastPC: pc, + Ctx: scopeCtx, }) } // Sanity check that top of the call-stack matches the scope context now @@ -391,7 +397,11 @@ func (h *Host) onOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpCo } cf := &h.callStack[len(h.callStack)-1] if vm.OpCode(op) == vm.JUMPDEST { // remember the last PC before successful jump - cf.LastJumpPC = cf.LastPC + cf.LastJumps = append(cf.LastJumps, cf.LastPC) + if len(cf.LastJumps) > jumpHistory { + copy(cf.LastJumps[:], cf.LastJumps[len(cf.LastJumps)-jumpHistory:]) + cf.LastJumps = cf.LastJumps[:jumpHistory] + } } cf.LastOp = vm.OpCode(op) cf.LastPC = pc @@ -527,10 +537,14 @@ func (h *Host) EnforceMaxCodeSize(v bool) { func (h *Host) LogCallStack() { for _, cf := range h.callStack { callsite := "" - if srcMap, ok := h.srcMaps[cf.Ctx.Address()]; ok { + srcMap, ok := h.srcMaps[cf.Ctx.Address()] + if !ok && cf.Ctx.Contract.CodeAddr != nil { // if delegate-call, we might know the implementation code. + srcMap, ok = h.srcMaps[*cf.Ctx.Contract.CodeAddr] + } + if ok { callsite = srcMap.FormattedInfo(cf.LastPC) - if callsite == "unknown:0:0" { - callsite = srcMap.FormattedInfo(cf.LastJumpPC) + if callsite == "unknown:0:0" && len(cf.LastJumps) > 0 { + callsite = srcMap.FormattedInfo(cf.LastJumps[len(cf.LastJumps)-1]) } } input := cf.Ctx.CallInput() @@ -538,9 +552,14 @@ func (h *Host) LogCallStack() { if len(input) >= 4 { byte4 = fmt.Sprintf("0x%x", input[:4]) } - h.log.Debug("callframe", "depth", cf.Depth, "input", hexutil.Bytes(input), "pc", cf.LastPC, "op", cf.LastOp) + h.log.Debug("callframe input", "depth", cf.Depth, "input", hexutil.Bytes(input), "pc", cf.LastPC, "op", cf.LastOp) h.log.Warn("callframe", "depth", cf.Depth, "byte4", byte4, "addr", cf.Ctx.Address(), "callsite", callsite, "label", h.labels[cf.Ctx.Address()]) + if srcMap != nil { + for _, jmpPC := range cf.LastJumps { + h.log.Debug("recent jump", "depth", cf.Depth, "callsite", srcMap.FormattedInfo(jmpPC), "pc", jmpPC) + } + } } } @@ -548,4 +567,40 @@ func (h *Host) LogCallStack() { func (h *Host) Label(addr common.Address, label string) { h.log.Debug("labeling", "addr", addr, "label", label) h.labels[addr] = label + + for _, fn := range h.onLabel { + fn(label, addr) + } +} + +// NewScriptAddress creates a new address for the ScriptDeployer account, and bumps the nonce. +func (h *Host) NewScriptAddress() common.Address { + deployer := ScriptDeployer + deployNonce := h.state.GetNonce(deployer) + // compute address of script contract to be deployed + addr := crypto.CreateAddress(deployer, deployNonce) + h.state.SetNonce(deployer, deployNonce+1) + return addr +} + +func (h *Host) ChainID() *big.Int { + return new(big.Int).Set(h.chainCfg.ChainID) +} + +func (h *Host) Artifacts() *foundry.ArtifactsFS { + return h.af +} + +// RememberOnLabel links the contract source-code of srcFile upon a given label +func (h *Host) RememberOnLabel(label, srcFile, contract string) error { + artifact, err := h.af.ReadArtifact(srcFile, contract) + if err != nil { + return fmt.Errorf("failed to read artifact %s (contract %s) for label %q", srcFile, contract, label) + } + h.onLabel = append(h.onLabel, func(v string, addr common.Address) { + if label == v { + h.RememberArtifact(addr, artifact, contract) + } + }) + return nil } diff --git a/op-chain-ops/srcmap/solutil.go b/op-chain-ops/srcmap/solutil.go index 284299762f62..6566144a819b 100644 --- a/op-chain-ops/srcmap/solutil.go +++ b/op-chain-ops/srcmap/solutil.go @@ -120,6 +120,10 @@ type SourceMap struct { // This location is the source file-path, the line number, and column number. // This may return an error, as the source-file is lazy-loaded to calculate the position data. func (s *SourceMap) Info(pc uint64) (source string, line uint32, col uint32, err error) { + if pc >= uint64(len(s.Instr)) { + source = "invalid" + return + } instr := s.Instr[pc] if instr.F < 0 || instr == (InstrMapping{}) { return "generated", 0, 0, nil From 8733626fdab3148f61d596c47bd1f48f22a6dfc5 Mon Sep 17 00:00:00 2001 From: Axel Kingsley Date: Fri, 6 Sep 2024 16:28:52 -0500 Subject: [PATCH 055/264] Add Maintenance Trigger for Cascading Updates (#11619) --- op-supervisor/supervisor/backend/db/db.go | 67 +++++++++++++++-------- 1 file changed, 45 insertions(+), 22 deletions(-) diff --git a/op-supervisor/supervisor/backend/db/db.go b/op-supervisor/supervisor/backend/db/db.go index c5948dde0b0c..b0c2bd5f99f9 100644 --- a/op-supervisor/supervisor/backend/db/db.go +++ b/op-supervisor/supervisor/backend/db/db.go @@ -40,8 +40,9 @@ type HeadsStorage interface { // ChainsDB is a database that stores logs and heads for multiple chains. // it implements the ChainsStorage interface. type ChainsDB struct { - logDBs map[types.ChainID]LogStorage - heads HeadsStorage + logDBs map[types.ChainID]LogStorage + heads HeadsStorage + maintenanceReady chan struct{} } func NewChainsDB(logDBs map[types.ChainID]LogStorage, heads HeadsStorage) *ChainsDB { @@ -67,10 +68,6 @@ func (db *ChainsDB) Resume() error { // for now it does not prevent multiple instances of this process from running func (db *ChainsDB) StartCrossHeadMaintenance(ctx context.Context) { go func() { - // create three safety checkers, one for each safety level - unsafeChecker := NewSafetyChecker(Unsafe, db) - safeChecker := NewSafetyChecker(Safe, db) - finalizedChecker := NewSafetyChecker(Finalized, db) // run the maintenance loop every 10 seconds for now ticker := time.NewTicker(time.Second * 10) for { @@ -78,14 +75,10 @@ func (db *ChainsDB) StartCrossHeadMaintenance(ctx context.Context) { case <-ctx.Done(): return case <-ticker.C: - for _, checker := range []SafetyChecker{ - unsafeChecker, - safeChecker, - finalizedChecker} { - if err := db.UpdateCrossHeads(checker); err != nil { - log.Error("failed to update cross-heads", "err", err, "safety", checker.Name()) - // we should consider exiting if an error is encountered, as the path forward is unclear - } + db.RequestMaintenance() + case <-db.maintenanceReady: + if err := db.updateAllHeads(); err != nil { + log.Error("failed to update cross-heads", "err", err) } } } @@ -101,17 +94,37 @@ func (db *ChainsDB) Check(chain types.ChainID, blockNum uint64, logIdx uint32, l return logDB.Contains(blockNum, logIdx, logHash) } -// UpdateCrossSafeHeads updates the cross-heads of all chains -// this is an example of how to use the SafetyChecker to update the cross-heads -func (db *ChainsDB) UpdateCrossSafeHeads() error { - checker := NewSafetyChecker(Safe, db) - return db.UpdateCrossHeads(checker) +// RequestMaintenance requests that the maintenance loop update the cross-heads +// it does not block if maintenance is already scheduled +func (db *ChainsDB) RequestMaintenance() { + select { + case db.maintenanceReady <- struct{}{}: + return + default: + return + } +} + +// updateAllHeads updates the cross-heads of all safety levels +// it is called by the maintenance loop +func (db *ChainsDB) updateAllHeads() error { + // create three safety checkers, one for each safety level + unsafeChecker := NewSafetyChecker(Unsafe, db) + safeChecker := NewSafetyChecker(Safe, db) + finalizedChecker := NewSafetyChecker(Finalized, db) + for _, checker := range []SafetyChecker{ + unsafeChecker, + safeChecker, + finalizedChecker} { + if err := db.UpdateCrossHeads(checker); err != nil { + return fmt.Errorf("failed to update cross-heads for safety level %v: %w", checker.Name(), err) + } + } + return nil } // UpdateCrossHeadsForChain updates the cross-head for a single chain. // the provided checker controls which heads are considered. -// TODO: we should invert control and have the underlying logDB call their own update -// for now, monolithic control is fine. There may be a stronger reason to refactor if the API needs it. func (db *ChainsDB) UpdateCrossHeadsForChain(chainID types.ChainID, checker SafetyChecker) error { // start with the xsafe head of the chain xHead := checker.CrossHeadForChain(chainID) @@ -122,6 +135,8 @@ func (db *ChainsDB) UpdateCrossHeadsForChain(chainID types.ChainID, checker Safe if err != nil { return fmt.Errorf("failed to rewind cross-safe head for chain %v: %w", chainID, err) } + // track if we updated the cross-head + updated := false // advance the logDB through all executing messages we can // this loop will break: // - when we reach the local head @@ -149,6 +164,7 @@ func (db *ChainsDB) UpdateCrossHeadsForChain(chainID types.ChainID, checker Safe } // if all is well, prepare the x-head update to this point xHead = i.Index() + updated = true } // have the checker create an update to the x-head in question, and apply that update @@ -156,6 +172,12 @@ func (db *ChainsDB) UpdateCrossHeadsForChain(chainID types.ChainID, checker Safe if err != nil { return fmt.Errorf("failed to update cross-head for chain %v: %w", chainID, err) } + // if any chain was updated, we can trigger a maintenance request + // this allows for the maintenance loop to handle cascading updates + // instead of waiting for the next scheduled update + if updated { + db.RequestMaintenance() + } return nil } @@ -165,7 +187,8 @@ func (db *ChainsDB) UpdateCrossHeadsForChain(chainID types.ChainID, checker Safe func (db *ChainsDB) UpdateCrossHeads(checker SafetyChecker) error { currentHeads := db.heads.Current() for chainID := range currentHeads.Chains { - if err := db.UpdateCrossHeadsForChain(chainID, checker); err != nil { + err := db.UpdateCrossHeadsForChain(chainID, checker) + if err != nil { return err } } From 4562b601b1391c627c09cd1fd15a10a65956853b Mon Sep 17 00:00:00 2001 From: Sebastian Stammler Date: Sat, 7 Sep 2024 01:12:03 +0200 Subject: [PATCH 056/264] Update and cleanup CODEOWNERS with expert teams (#11786) --- .github/CODEOWNERS | 62 ++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 35 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 23ac0fa26cf5..0d55c426dc98 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,27 +1,29 @@ -# Packages -/packages/contracts-bedrock @ethereum-optimism/contract-reviewers -/packages/sdk @ethereum-optimism/devxpod +# Monorepo - default to go-reviewers +* @ethereum-optimism/go-reviewers + +# OP Stack general +/bedrock-devnet @ethereum-optimism/go-reviewers @ethereum-optimism/op-stack +/op-alt-da @ethereum-optimism/go-reviewers @ethereum-optimism/op-stack +/op-batcher @ethereum-optimism/go-reviewers @ethereum-optimism/op-stack +/op-chain-ops @ethereum-optimism/go-reviewers @ethereum-optimism/op-stack +/op-e2e @ethereum-optimism/go-reviewers @ethereum-optimism/op-stack +/op-node @ethereum-optimism/go-reviewers @ethereum-optimism/op-stack +/op-proposer @ethereum-optimism/go-reviewers @ethereum-optimism/op-stack +/op-wheel @ethereum-optimism/go-reviewers @ethereum-optimism/op-stack +/ops-bedrock @ethereum-optimism/go-reviewers @ethereum-optimism/op-stack + +# Expert areas +/op-node/rollup @ethereum-optimism/go-reviewers @ethereum-optimism/consensus + +/op-supervisor @ethereum-optimism/go-reviewers @ethereum-optimism/interop -# Bedrock codebases -/bedrock-devnet @ethereum-optimism/go-reviewers -/cannon @ethereum-optimism/go-reviewers -/op-batcher @ethereum-optimism/go-reviewers -/op-bootnode @ethereum-optimism/go-reviewers -/op-chain-ops @ethereum-optimism/go-reviewers -/op-challenger @ethereum-optimism/go-reviewers -/op-dispute-mon @ethereum-optimism/go-reviewers -/op-e2e @ethereum-optimism/go-reviewers -/op-node @ethereum-optimism/go-reviewers -/op-node/rollup @protolambda @ajsutton -/op-alt-da @ethereum-optimism/go-reviewers -/op-preimage @ethereum-optimism/go-reviewers -/op-program @ethereum-optimism/go-reviewers -/op-proposer @ethereum-optimism/go-reviewers -/op-service @ethereum-optimism/go-reviewers -/op-supervisor @ethereum-optimism/go-reviewers -/op-wheel @ethereum-optimism/go-reviewers -/ops-bedrock @ethereum-optimism/go-reviewers -/op-conductor @0x00101010 @zhwrd @mslipper +/op-conductor @ethereum-optimism/go-reviewers @ethereum-optimism/op-conductor + +/cannon @ethereum-optimism/go-reviewers @ethereum-optimism/proofs +/op-dispute-mon @ethereum-optimism/go-reviewers @ethereum-optimism/proofs +/op-challenger @ethereum-optimism/go-reviewers @ethereum-optimism/proofs +/op-preimage @ethereum-optimism/go-reviewers @ethereum-optimism/proofs +/op-program @ethereum-optimism/go-reviewers @ethereum-optimism/proofs # Ops /.circleci @ethereum-optimism/monorepo-ops-reviewers @@ -29,15 +31,5 @@ /ops @ethereum-optimism/monorepo-ops-reviewers /docker-bake.hcl @ethereum-optimism/monorepo-ops-reviewers -# Misc -/proxyd @ethereum-optimism/infra-reviewers -/infra @ethereum-optimism/infra-reviewers -/specs @ethereum-optimism/contract-reviewers @ethereum-optimism/go-reviewers - -# Don't add owners if only package.json is updated -/packages/*/package.json -/*/package.json - -# JavaScript Releases -/packages/*/CHANGELOG.md @ethereum-optimism/release-managers -/*/CHANGELOG.md @ethereum-optimism/release-managers +# Contracts +/packages/contracts-bedrock @ethereum-optimism/contract-reviewers From 75c73266b29776f016c77aa53d4bd6d4e3be0877 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Sat, 7 Sep 2024 01:13:18 +0200 Subject: [PATCH 057/264] Catch 'header not found' string in L2BlockRefByLabel (#11759) --- op-service/sources/l2_client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op-service/sources/l2_client.go b/op-service/sources/l2_client.go index 304a94a0a292..078385d40510 100644 --- a/op-service/sources/l2_client.go +++ b/op-service/sources/l2_client.go @@ -102,7 +102,7 @@ func (s *L2Client) L2BlockRefByLabel(ctx context.Context, label eth.BlockLabel) if err != nil { // Both geth and erigon like to serve non-standard errors for the safe and finalized heads, correct that. // This happens when the chain just started and nothing is marked as safe/finalized yet. - if strings.Contains(err.Error(), "block not found") || strings.Contains(err.Error(), "Unknown block") || strings.Contains(err.Error(), "unknown block") { + if strings.Contains(err.Error(), "block not found") || strings.Contains(err.Error(), "Unknown block") || strings.Contains(err.Error(), "unknown block") || strings.Contains(err.Error(), "header not found") { err = ethereum.NotFound } // w%: wrap to preserve ethereum.NotFound case From f954cbb8dcb050c5fcf3421c092ea218561524b2 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Fri, 6 Sep 2024 19:32:38 -0400 Subject: [PATCH 058/264] ci: speed up CI by up to 50% (#11794) Introduces a number of improvements to CI that significantly reduce overal CI time by up to 50% of the previous time. --- .circleci/config.yml | 279 +++++++++++------- packages/contracts-bedrock/justfile | 5 + .../scripts/checks/check-snapshots.sh | 9 +- 3 files changed, 186 insertions(+), 107 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9e093aa1d923..f4fe234bb34a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -134,7 +134,7 @@ jobs: cannon-go-lint-and-test: docker: - image: <> - resource_class: medium + resource_class: xlarge steps: - checkout - check-changed: @@ -158,7 +158,7 @@ jobs: command: | mkdir -p /testlogs gotestsum --format=testname --junitfile=/tmp/test-results/cannon.xml --jsonfile=/testlogs/log.json \ - -- -parallel=2 -coverpkg=github.com/ethereum-optimism/optimism/cannon/... -coverprofile=coverage.out ./... + -- -parallel=8 -coverpkg=github.com/ethereum-optimism/optimism/cannon/... -coverprofile=coverage.out ./... working_directory: cannon - run: name: upload Cannon coverage @@ -168,6 +168,7 @@ jobs: - store_artifacts: path: /testlogs when: always + cannon-build-test-vectors: docker: - image: <> @@ -181,21 +182,19 @@ jobs: command: python3 maketests.py && git diff --exit-code working_directory: cannon/mipsevm/tests/open_mips_tests - pnpm-monorepo: + contracts-bedrock-build: docker: - image: <> resource_class: xlarge + parameters: + build_command: + type: string + default: just prebuild && forge build --deny-warnings steps: - checkout -# - run: # temporarily disabled, to update ci-builder. -# name: "Check L1 geth version" -# command: ./ops/scripts/geth-version-checker.sh || (echo "geth version is wrong, update ci-builder"; false) - install-contracts-dependencies - - restore_cache: - name: Restore Go modules cache - key: gomod-{{ checksum "go.sum" }} - run: - name: print forge version + name: Print forge version command: forge --version - run: name: Pull artifacts @@ -203,10 +202,39 @@ jobs: working_directory: packages/contracts-bedrock - run: name: Build contracts + command: << parameters.build_command >> environment: FOUNDRY_PROFILE: ci - command: just build working_directory: packages/contracts-bedrock + - persist_to_workspace: + root: "." + paths: + - ".git" + - "packages/contracts-bedrock/lib" + - "packages/contracts-bedrock/cache" + - "packages/contracts-bedrock/artifacts" + - "packages/contracts-bedrock/forge-artifacts" + - notify-failures-on-develop + + build-devnet-allocs: + docker: + - image: <> + resource_class: xlarge + steps: + - checkout + - attach_workspace: { at: "." } + - install-contracts-dependencies +# - run: # temporarily disabled, to update ci-builder. +# name: "Check L1 geth version" +# command: ./ops/scripts/geth-version-checker.sh || (echo "geth version is wrong, update ci-builder"; false) + - restore_cache: + name: Restore Go modules cache + key: gomod-allocs-{{ checksum "go.sum" }} + - restore_cache: + name: Restore Go build cache + keys: + - golang-build-cache-allocs-{{ checksum "go.sum" }} + - golang-build-cache-allocs- - run: name: Generate L2OO allocs command: DEVNET_L2OO="true" make devnet-allocs @@ -228,12 +256,19 @@ jobs: - run: name: Generate default allocs command: make devnet-allocs + - save_cache: + name: Save Go modules cache + key: gomod-allocs-{{ checksum "go.sum" }} + paths: + - "/go/pkg/mod" + - save_cache: + name: Save Go build cache + key: golang-build-cache-allocs-{{ checksum "go.sum" }} + paths: + - "/root/.cache/go-build" - persist_to_workspace: root: "." paths: - - "packages/contracts-bedrock/cache" - - "packages/contracts-bedrock/artifacts" - - "packages/contracts-bedrock/forge-artifacts" - ".devnet/allocs-l1.json" - ".devnet/allocs-l2-delta.json" - ".devnet/allocs-l2-ecotone.json" @@ -530,11 +565,21 @@ jobs: docker: - image: <> resource_class: xlarge + parallelism: 4 steps: - checkout + - attach_workspace: { at: "." } + - install-contracts-dependencies - check-changed: patterns: contracts-bedrock,op-node - - install-contracts-dependencies + - restore_cache: + name: Restore Go modules cache + key: gomod-{{ checksum "go.sum" }} + - restore_cache: + name: Restore Go build cache + keys: + - golang-build-cache-contracts-bedrock-tests-{{ checksum "go.sum" }} + - golang-build-cache-contracts-bedrock-tests- - run: name: print dependencies command: just dep-status @@ -544,12 +589,14 @@ jobs: command: forge --version working_directory: packages/contracts-bedrock - run: - name: pull cached artifacts - command: bash scripts/ops/pull-artifacts.sh + name: build go-ffi + command: just build-go-ffi working_directory: packages/contracts-bedrock - run: name: run tests - command: just test + command: | + TESTS=$(forge test --list | grep -E '^\s{4}' | awk '{print $1}' | circleci tests split --split-by=timings | paste -sd "|" -) + forge test --match-test "$TESTS" environment: FOUNDRY_PROFILE: ci working_directory: packages/contracts-bedrock @@ -561,6 +608,11 @@ jobs: FOUNDRY_PROFILE: ci working_directory: packages/contracts-bedrock when: on_fail + - save_cache: + name: Save Go build cache + key: golang-build-cache-contracts-bedrock-tests-{{ checksum "go.sum" }} + paths: + - "/root/.cache/go-build" contracts-bedrock-checks: docker: @@ -577,13 +629,6 @@ jobs: - run: name: forge version command: forge --version - - run: - name: solc warnings check - command: | - forge build --force --deny-warnings || echo "export SOLC_WARNINGS_CHECK=1" >> "$BASH_ENV" - environment: - FOUNDRY_PROFILE: ci - working_directory: packages/contracts-bedrock - run: # Semver lock must come second because one of the later steps may modify the cache & force a contracts rebuild. name: semver lock @@ -617,7 +662,7 @@ jobs: - run: name: snapshots command: | - just snapshots-check || echo "export SNAPSHOTS_STATUS=1" >> "$BASH_ENV" + just snapshots-check-no-build || echo "export SNAPSHOTS_STATUS=1" >> "$BASH_ENV" working_directory: packages/contracts-bedrock - run: name: kontrol deployment @@ -643,10 +688,6 @@ jobs: echo "Linting failed, see job output for details." FAILED=1 fi - if [[ "$SOLC_WARNINGS_CHECK" -ne 0 ]]; then - echo "Solidity emitted warnings, see job output for details." - FAILED=1 - fi if [[ "$GAS_SNAPSHOT_STATUS" -ne 0 ]]; then echo "Gas snapshot failed, see job output for details." FAILED=1 @@ -683,18 +724,19 @@ jobs: exit 1 fi - contracts-bedrock-validate-spaces: + contracts-bedrock-validate-spacers: docker: - image: <> resource_class: medium steps: - checkout - attach_workspace: { at: "." } + - install-contracts-dependencies - check-changed: patterns: contracts-bedrock - run: name: validate spacers - command: just validate-spacers + command: just validate-spacers-no-build working_directory: packages/contracts-bedrock todo-issues: @@ -736,13 +778,16 @@ jobs: key: gomod-{{ checksum "go.sum" }} - restore_cache: name: Restore Go build cache - key: golang-build-cache + keys: + - golang-build-cache-fuzz-golang-{{ checksum "go.sum" }} + - golang-build-cache-fuzz-golang- - run: name: Fuzz command: make fuzz working_directory: "<>" - save_cache: - key: golang-build-cache + name: Save Go build cache + key: golang-build-cache-fuzz-golang-{{ checksum "go.sum" }} paths: - "/root/.cache/go-build" @@ -764,9 +809,15 @@ jobs: name: Restore Go modules cache key: gomod-{{ checksum "go.sum" }} - restore_cache: - key: golang-build-cache + name: Restore Go build cache + keys: + - golang-build-cache-lint-{{ checksum "go.sum" }} + - golang-build-cache-lint- - restore_cache: - key: golang-lint-cache + name: Restore Go lint cache + keys: + - golang-lint-cache-{{ checksum "go.sum" }} + - golang-lint-cache- - run: name: run Go linter command: | @@ -775,11 +826,13 @@ jobs: make lint-go working_directory: . - save_cache: - key: golang-build-cache + name: Save Go build cache + key: golang-build-cache-lint-{{ checksum "go.sum" }} paths: - "/root/.cache/go-build" - save_cache: - key: golang-lint-cache + name: Save Go lint cache + key: golang-lint-cache-{{ checksum "go.sum" }} paths: - "/root/.cache/golangci-lint" @@ -797,9 +850,10 @@ jobs: name: Restore Go modules cache key: gomod-{{ checksum "go.sum" }} - restore_cache: + name: Restore Go build cache keys: - - golang-build-cache-<> - - golang-build-cache- + - golang-build-cache-test-<>-{{ checksum "go.sum" }} + - golang-build-cache-test- - run: name: prep results dir command: mkdir -p /tmp/test-results && mkdir -p /testlogs @@ -810,7 +864,8 @@ jobs: -- -parallel=8 -coverpkg=github.com/ethereum-optimism/optimism/... -coverprofile=coverage.out ./... working_directory: <> - save_cache: - key: golang-build-cache-<> + name: Save Go build cache + key: golang-build-cache-test-<>-{{ checksum "go.sum" }} paths: - "/root/.cache/go-build" # TODO(CLI-148): Fix codecov @@ -882,7 +937,9 @@ jobs: key: gomod-{{ checksum "go.sum" }} - restore_cache: name: Restore Go build cache - key: golang-build-cache + keys: + - golang-build-cache-e2e-{{ checksum "go.sum" }} + - golang-build-cache-e2e- - attach_workspace: at: /tmp/workspace - run: @@ -923,6 +980,11 @@ jobs: when: always - store_test_results: path: /tmp/test-results + - save_cache: + name: Save Go build cache + key: golang-build-cache-e2e-{{ checksum "go.sum" }} + paths: + - "/root/.cache/go-build" - when: condition: "<>" steps: @@ -985,10 +1047,19 @@ jobs: name: Restore Go modules cache key: gomod-{{ checksum "go.sum" }} - restore_cache: - key: golang-build-cache + name: Restore Go build cache + keys: + - golang-build-cache-cannon-prestate-{{ checksum "go.sum" }} + - golang-build-cache-cannon-prestate- + - run: + name: Build cannon + command: make cannon + - run: + name: Build op-program + command: make op-program - restore_cache: + name: Restore cannon prestate cache key: cannon-prestate-{{ checksum "./cannon/bin/cannon" }}-{{ checksum "op-program/bin/op-program-client.elf" }} - name: Load cannon prestate cache - run: name: generate cannon prestate command: make cannon-prestate @@ -999,6 +1070,11 @@ jobs: - "op-program/bin/prestate.json" - "op-program/bin/meta.json" - "op-program/bin/prestate-proof.json" + - save_cache: + name: Save Go build cache + key: golang-build-cache-cannon-prestate-{{ checksum "go.sum" }} + paths: + - "/root/.cache/go-build" - persist_to_workspace: root: . paths: @@ -1057,34 +1133,6 @@ jobs: - notify-failures-on-develop: mentions: "@proofs-squad" - - devnet-allocs: - docker: - - image: <> - resource_class: xlarge - steps: - - checkout - - restore_cache: - name: Restore Go modules cache - key: gomod-{{ checksum "go.sum" }} - - restore_cache: - key: golang-build-cache - - install-contracts-dependencies - - run: - name: generate devnet allocs - command: make devnet-allocs - - persist_to_workspace: - root: . - paths: - - ".devnet/allocs-l2-delta.json" - - ".devnet/allocs-l2-ecotone.json" - - ".devnet/allocs-l2-fjord.json" - - ".devnet/allocs-l2-granite.json" - - ".devnet/allocs-l1.json" - - ".devnet/addresses.json" - - "packages/contracts-bedrock/deploy-config/devnetL1.json" - - "packages/contracts-bedrock/deployments/devnetL1" - devnet: machine: image: <> @@ -1099,6 +1147,9 @@ jobs: DEVNET_ALTDA: 'false' steps: - checkout + - attach_workspace: { at: "." } + - check-changed: + patterns: op-(.+),packages,ops-bedrock,bedrock-devnet - when: condition: equal: ['altda', <>] @@ -1116,8 +1167,14 @@ jobs: - run: name: Set GENERIC_ALTDA = true command: echo 'export GENERIC_ALTDA=true' >> $BASH_ENV - - check-changed: - patterns: op-(.+),packages,ops-bedrock,bedrock-devnet + - restore_cache: + name: Restore Go modules cache + key: gomod-{{ checksum "go.sum" }} + - restore_cache: + name: Restore Go build cache + keys: + - golang-build-cache-devnet-{{ checksum "go.sum" }} + - golang-build-cache-devnet- - run: name: Install latest golang command: | @@ -1152,8 +1209,6 @@ jobs: curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to $HOME/bin --tag "${VER}" echo 'export PATH="${PATH}:$HOME/bin"' >> $BASH_ENV - install-contracts-dependencies - - attach_workspace: - at: "." - when: condition: not: @@ -1178,10 +1233,6 @@ jobs: docker tag "$IMAGE_BASE_PREFIX/op-batcher:<>" "$IMAGE_BASE_PREFIX/op-batcher:devnet" docker tag "$IMAGE_BASE_PREFIX/op-challenger:<>" "$IMAGE_BASE_PREFIX/op-challenger:devnet" docker tag "$IMAGE_BASE_PREFIX/da-server:<>" "$IMAGE_BASE_PREFIX/da-server:devnet" - - run: - name: Build contracts - working_directory: packages/contracts-bedrock - command: just build - run: name: Bring up the stack command: | @@ -1255,6 +1306,11 @@ jobs: ls -R forge-artifacts || echo "No forge artifacts found" when: on_fail working_directory: packages/contracts-bedrock + - save_cache: + name: Save Go build cache + key: golang-build-cache-devnet-{{ checksum "go.sum" }} + paths: + - /home/circleci/.cache/go-build semgrep-scan: parameters: @@ -1322,13 +1378,6 @@ jobs: - run: name: "Go mod tidy" command: make mod-tidy && git diff --exit-code - - run: - name: run Go linter - command: | - # Identify how many cores it defaults to - golangci-lint --help | grep concurrency - make lint-go - working_directory: . - save_cache: key: << parameters.key >>-{{ checksum "<< parameters.file >>" }} name: Save Go modules cache @@ -1367,12 +1416,17 @@ jobs: name: Restore Go modules cache key: gomod-{{ checksum "go.sum" }} - restore_cache: - key: golang-build-cache + key: golang-build-cache-op-program-compat-{{ checksum "go.sum" }} - run: name: compat-sepolia command: | make verify-compat working_directory: op-program + - save_cache: + name: Save Go build cache + key: golang-build-cache-op-program-compat-{{ checksum "go.sum" }} + paths: + - "/root/.cache/go-build" check-generated-mocks-op-node: docker: @@ -1491,18 +1545,30 @@ workflows: - not: equal: [ scheduled_pipeline, << pipeline.trigger_source >> ] jobs: - - pnpm-monorepo: - name: pnpm-monorepo - - contracts-bedrock-tests + - go-mod-download + - contracts-bedrock-build + - contracts-bedrock-build: + name: contracts-bedrock-build-skip-tests + build_command: forge build --skip test + - contracts-bedrock-tests: + requires: + - contracts-bedrock-build + - go-mod-download - contracts-bedrock-coverage - contracts-bedrock-checks: requires: - - pnpm-monorepo - - contracts-bedrock-validate-spaces: + - contracts-bedrock-build-skip-tests + - contracts-bedrock-validate-spacers: requires: - - pnpm-monorepo + - contracts-bedrock-build-skip-tests + - build-devnet-allocs: + requires: + - contracts-bedrock-build-skip-tests + - go-mod-download - semgrep-scan - - go-mod-download + - go-lint: + requires: + - go-mod-download - fuzz-golang: name: op-challenger-fuzz package_name: op-challenger @@ -1528,13 +1594,13 @@ workflows: package_name: cannon on_changes: cannon,packages/contracts-bedrock/src/cannon uses_artifacts: true - requires: ["go-mod-download", "pnpm-monorepo"] + requires: ["go-mod-download", "build-devnet-allocs"] - fuzz-golang: name: op-e2e-fuzz package_name: op-e2e on_changes: op-e2e,packages/contracts-bedrock/src uses_artifacts: true - requires: ["go-mod-download", "pnpm-monorepo"] + requires: ["go-mod-download", "build-devnet-allocs"] - go-test: name: op-batcher-tests module: op-batcher @@ -1585,7 +1651,7 @@ workflows: parallelism: 4 requires: - go-mod-download - - pnpm-monorepo + - build-devnet-allocs - go-e2e-test: name: op-e2e-action-tests<< matrix.variant >> matrix: @@ -1596,14 +1662,14 @@ workflows: parallelism: 1 requires: - go-mod-download - - pnpm-monorepo + - build-devnet-allocs - go-e2e-test: name: op-e2e-fault-proof-tests module: op-e2e target: test-fault-proofs parallelism: 4 requires: - - pnpm-monorepo + - build-devnet-allocs - cannon-prestate - op-program-compat: requires: @@ -1684,7 +1750,7 @@ workflows: parameters: variant: ["default", "altda", "altda-generic"] requires: - - pnpm-monorepo + - build-devnet-allocs - op-batcher-docker-build - op-proposer-docker-build - op-node-docker-build @@ -1695,7 +1761,7 @@ workflows: - check-generated-mocks-op-service - cannon-go-lint-and-test: requires: - - pnpm-monorepo + - build-devnet-allocs - cannon-build-test-vectors - shellcheck/check: name: shell-check @@ -1963,10 +2029,13 @@ workflows: - cannon-prestate: requires: - go-mod-download - - pnpm-monorepo: - name: pnpm-monorepo + - contracts-bedrock-build: requires: - go-mod-download + - build-devnet-allocs: + name: build-devnet-allocs + requires: + - contracts-bedrock-build - go-e2e-test: name: op-e2e-cannon-tests module: op-e2e @@ -1975,7 +2044,7 @@ workflows: notify: true mentions: "@proofs-squad" requires: - - pnpm-monorepo + - build-devnet-allocs - cannon-prestate context: - slack diff --git a/packages/contracts-bedrock/justfile b/packages/contracts-bedrock/justfile index 995c4b71eb71..69a737d4430d 100644 --- a/packages/contracts-bedrock/justfile +++ b/packages/contracts-bedrock/justfile @@ -79,6 +79,11 @@ snapshots-no-build: snapshots-abi-storage # Builds contracts and then generates core snapshots. snapshots: build snapshots-no-build +# Checks if the snapshots are up to date without building. +snapshots-check-no-build: + ./scripts/checks/check-snapshots.sh --no-build + +# Checks if the snapshots are up to date. snapshots-check: ./scripts/checks/check-snapshots.sh diff --git a/packages/contracts-bedrock/scripts/checks/check-snapshots.sh b/packages/contracts-bedrock/scripts/checks/check-snapshots.sh index de23be7fe299..66a04dc331d4 100755 --- a/packages/contracts-bedrock/scripts/checks/check-snapshots.sh +++ b/packages/contracts-bedrock/scripts/checks/check-snapshots.sh @@ -1,8 +1,13 @@ #!/usr/bin/env bash set -euo pipefail -# Generate the snapshots -just snapshots +# Check for the --no-build flag +# Generate snapshots +if [ "$1" == "--no-build" ]; then + just snapshots-no-build +else + just snapshots +fi # Check if the generated `snapshots` files are different from the committed versions if git diff --exit-code snapshots > /dev/null; then From 1824499d16bfb69c5a38192cc218ed7f8d067a54 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2024 17:40:28 -0600 Subject: [PATCH 059/264] dependabot(gomod): bump github.com/prometheus/client_golang (#11764) Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.20.2 to 1.20.3. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/v1.20.3/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.20.2...v1.20.3) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 95845e360db8..c36042e3cd8c 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,7 @@ require ( github.com/onsi/gomega v1.34.1 github.com/pkg/errors v0.9.1 github.com/pkg/profile v1.7.0 - github.com/prometheus/client_golang v1.20.2 + github.com/prometheus/client_golang v1.20.3 github.com/protolambda/ctxlock v0.1.0 github.com/stretchr/testify v1.9.0 github.com/urfave/cli/v2 v2.27.4 diff --git a/go.sum b/go.sum index fcbc2cc0172e..88c6c189a9bf 100644 --- a/go.sum +++ b/go.sum @@ -642,8 +642,8 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.20.2 h1:5ctymQzZlyOON1666svgwn3s6IKWgfbjsejTMiXIyjg= -github.com/prometheus/client_golang v1.20.2/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4= +github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= From 52336b43a6ba72990383f4baa6a7d6619731ef5d Mon Sep 17 00:00:00 2001 From: clabby Date: Fri, 6 Sep 2024 22:35:12 -0400 Subject: [PATCH 060/264] fix(challenger): `asterisc-kona` trace type (#11789) --- op-challenger/cmd/main_test.go | 143 +++++++++++++----- op-challenger/flags/flags.go | 26 +++- op-challenger/game/fault/register.go | 2 +- op-challenger/game/fault/register_task.go | 30 ++++ .../fault/trace/vm/kona_server_executor.go | 12 +- op-challenger/game/fault/types/types.go | 4 +- op-challenger/runner/factory.go | 4 +- 7 files changed, 171 insertions(+), 50 deletions(-) diff --git a/op-challenger/cmd/main_test.go b/op-challenger/cmd/main_test.go index 926f38eced51..529711bbf660 100644 --- a/op-challenger/cmd/main_test.go +++ b/op-challenger/cmd/main_test.go @@ -264,66 +264,117 @@ func TestPollInterval(t *testing.T) { }) } -func TestAsteriscRequiredArgs(t *testing.T) { - for _, traceType := range []types.TraceType{types.TraceTypeAsterisc} { - traceType := traceType - t.Run(fmt.Sprintf("TestAsteriscBin-%v", traceType), func(t *testing.T) { - t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-bin")) - }) +func TestAsteriscOpProgramRequiredArgs(t *testing.T) { + traceType := types.TraceTypeAsterisc + t.Run(fmt.Sprintf("TestAsteriscServer-%v", traceType), func(t *testing.T) { + t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { + configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-server")) + }) - t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag asterisc-bin is required", addRequiredArgsExcept(traceType, "--asterisc-bin")) - }) + t.Run("Required", func(t *testing.T) { + verifyArgsInvalid(t, "flag asterisc-server is required", addRequiredArgsExcept(traceType, "--asterisc-server")) + }) - t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--asterisc-bin", "--asterisc-bin=./asterisc")) - require.Equal(t, "./asterisc", cfg.Asterisc.VmBin) - }) + t.Run("Valid", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--asterisc-server", "--asterisc-server=./op-program")) + require.Equal(t, "./op-program", cfg.Asterisc.Server) }) + }) - t.Run(fmt.Sprintf("TestAsteriscServer-%v", traceType), func(t *testing.T) { - t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-server")) - }) + t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestate-%v", traceType), func(t *testing.T) { + t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { + configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-prestate")) + }) - t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag asterisc-server is required", addRequiredArgsExcept(traceType, "--asterisc-server")) - }) + t.Run("Required", func(t *testing.T) { + verifyArgsInvalid(t, "flag asterisc-prestates-url or asterisc-prestate is required", addRequiredArgsExcept(traceType, "--asterisc-prestate")) + }) - t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--asterisc-server", "--asterisc-server=./op-program")) - require.Equal(t, "./op-program", cfg.Asterisc.Server) - }) + t.Run("Valid", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--asterisc-prestate", "--asterisc-prestate=./pre.json")) + require.Equal(t, "./pre.json", cfg.AsteriscAbsolutePreState) }) + }) - t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestate-%v", traceType), func(t *testing.T) { - t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-prestate")) - }) + t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestateBaseURL-%v", traceType), func(t *testing.T) { + t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { + configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-prestates-url")) + }) - t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag asterisc-prestates-url or asterisc-prestate is required", addRequiredArgsExcept(traceType, "--asterisc-prestate")) - }) + t.Run("Required", func(t *testing.T) { + verifyArgsInvalid(t, "flag asterisc-prestates-url or asterisc-prestate is required", addRequiredArgsExcept(traceType, "--asterisc-prestate")) + }) - t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--asterisc-prestate", "--asterisc-prestate=./pre.json")) - require.Equal(t, "./pre.json", cfg.AsteriscAbsolutePreState) - }) + t.Run("Valid", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--asterisc-prestates-url", "--asterisc-prestates-url=http://localhost/bar")) + require.Equal(t, "http://localhost/bar", cfg.AsteriscAbsolutePreStateBaseURL.String()) }) + }) +} - t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestateBaseURL-%v", traceType), func(t *testing.T) { +func TestAsteriscKonaRequiredArgs(t *testing.T) { + traceType := types.TraceTypeAsteriscKona + t.Run(fmt.Sprintf("TestAsteriscServer-%v", traceType), func(t *testing.T) { + t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { + configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-kona-server")) + }) + + t.Run("Required", func(t *testing.T) { + verifyArgsInvalid(t, "flag asterisc-kona-server is required", addRequiredArgsExcept(traceType, "--asterisc-kona-server")) + }) + + t.Run("Valid", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--asterisc-kona-server", "--asterisc-kona-server=./kona-host")) + require.Equal(t, "./kona-host", cfg.AsteriscKona.Server) + }) + }) + + t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestate-%v", traceType), func(t *testing.T) { + t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { + configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-kona-prestate")) + }) + + t.Run("Required", func(t *testing.T) { + verifyArgsInvalid(t, "flag asterisc-kona-prestates-url or asterisc-kona-prestate is required", addRequiredArgsExcept(traceType, "--asterisc-kona-prestate")) + }) + + t.Run("Valid", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--asterisc-kona-prestate", "--asterisc-kona-prestate=./pre.json")) + require.Equal(t, "./pre.json", cfg.AsteriscKonaAbsolutePreState) + }) + }) + + t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestateBaseURL-%v", traceType), func(t *testing.T) { + t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { + configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-kona-prestates-url")) + }) + + t.Run("Required", func(t *testing.T) { + verifyArgsInvalid(t, "flag asterisc-kona-prestates-url or asterisc-kona-prestate is required", addRequiredArgsExcept(traceType, "--asterisc-kona-prestate")) + }) + + t.Run("Valid", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--asterisc-kona-prestates-url", "--asterisc-kona-prestates-url=http://localhost/bar")) + require.Equal(t, "http://localhost/bar", cfg.AsteriscKonaAbsolutePreStateBaseURL.String()) + }) + }) +} + +func TestAsteriscBaseRequiredArgs(t *testing.T) { + for _, traceType := range []types.TraceType{types.TraceTypeAsterisc, types.TraceTypeAsteriscKona} { + traceType := traceType + t.Run(fmt.Sprintf("TestAsteriscBin-%v", traceType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-prestates-url")) + configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-bin")) }) t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag asterisc-prestates-url or asterisc-prestate is required", addRequiredArgsExcept(traceType, "--asterisc-prestate")) + verifyArgsInvalid(t, "flag asterisc-bin is required", addRequiredArgsExcept(traceType, "--asterisc-bin")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--asterisc-prestates-url", "--asterisc-prestates-url=http://localhost/bar")) - require.Equal(t, "http://localhost/bar", cfg.AsteriscAbsolutePreStateBaseURL.String()) + cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--asterisc-bin", "--asterisc-bin=./asterisc")) + require.Equal(t, "./asterisc", cfg.Asterisc.VmBin) }) }) @@ -853,6 +904,8 @@ func requiredArgs(traceType types.TraceType) map[string]string { addRequiredCannonArgs(args) case types.TraceTypeAsterisc: addRequiredAsteriscArgs(args) + case types.TraceTypeAsteriscKona: + addRequiredAsteriscKonaArgs(args) } return args } @@ -873,6 +926,14 @@ func addRequiredAsteriscArgs(args map[string]string) { args["--l2-eth-rpc"] = l2EthRpc } +func addRequiredAsteriscKonaArgs(args map[string]string) { + args["--asterisc-network"] = asteriscNetwork + args["--asterisc-bin"] = asteriscBin + args["--asterisc-kona-server"] = asteriscServer + args["--asterisc-kona-prestate"] = asteriscPreState + args["--l2-eth-rpc"] = l2EthRpc +} + func toArgList(req map[string]string) []string { var combined []string for name, value := range req { diff --git a/op-challenger/flags/flags.go b/op-challenger/flags/flags.go index df62b48aa413..00c731c95fe6 100644 --- a/op-challenger/flags/flags.go +++ b/op-challenger/flags/flags.go @@ -327,7 +327,7 @@ func CheckCannonFlags(ctx *cli.Context) error { return nil } -func CheckAsteriscFlags(ctx *cli.Context) error { +func CheckAsteriscBaseFlags(ctx *cli.Context) error { if ctx.IsSet(AsteriscNetworkFlag.Name) && ctx.IsSet(flags.NetworkFlagName) { return fmt.Errorf("flag %v can not be used with %v", AsteriscNetworkFlag.Name, flags.NetworkFlagName) } @@ -350,6 +350,13 @@ func CheckAsteriscFlags(ctx *cli.Context) error { if !ctx.IsSet(AsteriscBinFlag.Name) { return fmt.Errorf("flag %s is required", AsteriscBinFlag.Name) } + return nil +} + +func CheckAsteriscFlags(ctx *cli.Context) error { + if err := CheckAsteriscBaseFlags(ctx); err != nil { + return err + } if !ctx.IsSet(AsteriscServerFlag.Name) { return fmt.Errorf("flag %s is required", AsteriscServerFlag.Name) } @@ -359,6 +366,19 @@ func CheckAsteriscFlags(ctx *cli.Context) error { return nil } +func CheckAsteriscKonaFlags(ctx *cli.Context) error { + if err := CheckAsteriscBaseFlags(ctx); err != nil { + return err + } + if !ctx.IsSet(AsteriscKonaServerFlag.Name) { + return fmt.Errorf("flag %s is required", AsteriscKonaServerFlag.Name) + } + if !ctx.IsSet(AsteriscKonaPreStateFlag.Name) && !ctx.IsSet(AsteriscKonaPreStatesURLFlag.Name) { + return fmt.Errorf("flag %s or %s is required", AsteriscKonaPreStatesURLFlag.Name, AsteriscKonaPreStateFlag.Name) + } + return nil +} + func CheckRequired(ctx *cli.Context, traceTypes []types.TraceType) error { for _, f := range requiredFlags { if !ctx.IsSet(f.Names()[0]) { @@ -379,6 +399,10 @@ func CheckRequired(ctx *cli.Context, traceTypes []types.TraceType) error { if err := CheckAsteriscFlags(ctx); err != nil { return err } + case types.TraceTypeAsteriscKona: + if err := CheckAsteriscKonaFlags(ctx); err != nil { + return err + } case types.TraceTypeAlphabet, types.TraceTypeFast: default: return fmt.Errorf("invalid trace type %v. must be one of %v", traceType, types.TraceTypes) diff --git a/op-challenger/game/fault/register.go b/op-challenger/game/fault/register.go index a76f456f16f3..088bd0b0aede 100644 --- a/op-challenger/game/fault/register.go +++ b/op-challenger/game/fault/register.go @@ -77,7 +77,7 @@ func RegisterGameTypes( registerTasks = append(registerTasks, NewAsteriscRegisterTask(faultTypes.AsteriscGameType, cfg, m, vm.NewOpProgramServerExecutor())) } if cfg.TraceTypeEnabled(faultTypes.TraceTypeAsteriscKona) { - registerTasks = append(registerTasks, NewAsteriscRegisterTask(faultTypes.AsteriscKonaGameType, cfg, m, vm.NewKonaServerExecutor())) + registerTasks = append(registerTasks, NewAsteriscKonaRegisterTask(faultTypes.AsteriscKonaGameType, cfg, m, vm.NewKonaServerExecutor())) } if cfg.TraceTypeEnabled(faultTypes.TraceTypeFast) { registerTasks = append(registerTasks, NewAlphabetRegisterTask(faultTypes.FastGameType)) diff --git a/op-challenger/game/fault/register_task.go b/op-challenger/game/fault/register_task.go index 40acfecce22b..4e5ee1062504 100644 --- a/op-challenger/game/fault/register_task.go +++ b/op-challenger/game/fault/register_task.go @@ -107,6 +107,36 @@ func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m } } +func NewAsteriscKonaRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor) *RegisterTask { + return &RegisterTask{ + gameType: gameType, + getPrestateProvider: cachePrestates( + gameType, + m, + cfg.AsteriscKonaAbsolutePreStateBaseURL, + cfg.AsteriscKonaAbsolutePreState, + filepath.Join(cfg.Datadir, "asterisc-kona-prestates"), + func(path string) faultTypes.PrestateProvider { + return vm.NewPrestateProvider(path, asterisc.NewStateConverter()) + }), + newTraceAccessor: func( + logger log.Logger, + m metrics.Metricer, + l2Client utils.L2HeaderSource, + prestateProvider faultTypes.PrestateProvider, + vmPrestateProvider faultTypes.PrestateProvider, + rollupClient outputs.OutputRollupClient, + dir string, + l1Head eth.BlockID, + splitDepth faultTypes.Depth, + prestateBlock uint64, + poststateBlock uint64) (*trace.Accessor, error) { + provider := vmPrestateProvider.(*vm.PrestateProvider) + return outputs.NewOutputAsteriscTraceAccessor(logger, m, cfg.AsteriscKona, serverExecutor, l2Client, prestateProvider, provider.PrestatePath(), rollupClient, dir, l1Head, splitDepth, prestateBlock, poststateBlock) + }, + } +} + func NewAlphabetRegisterTask(gameType faultTypes.GameType) *RegisterTask { return &RegisterTask{ gameType: gameType, diff --git a/op-challenger/game/fault/trace/vm/kona_server_executor.go b/op-challenger/game/fault/trace/vm/kona_server_executor.go index ac5b0fbb0fe0..5dc3a03a6365 100644 --- a/op-challenger/game/fault/trace/vm/kona_server_executor.go +++ b/op-challenger/game/fault/trace/vm/kona_server_executor.go @@ -8,8 +8,7 @@ import ( "github.com/ethereum-optimism/optimism/op-node/chaincfg" ) -type KonaServerExecutor struct { -} +type KonaServerExecutor struct{} var _ OracleServerExecutor = (*KonaServerExecutor)(nil) @@ -23,7 +22,7 @@ func (s *KonaServerExecutor) OracleCommand(cfg Config, dataDir string, inputs ut } chainCfg := chaincfg.ChainByName(cfg.Network) - return []string{ + args := []string{ cfg.Server, "--server", "--l1-node-address", cfg.L1, "--l1-beacon-address", cfg.L1Beacon, @@ -35,5 +34,10 @@ func (s *KonaServerExecutor) OracleCommand(cfg Config, dataDir string, inputs ut "--l2-output-root", inputs.L2OutputRoot.Hex(), "--l2-claim", inputs.L2Claim.Hex(), "--l2-block-number", inputs.L2BlockNumber.Text(10), - }, nil + } + if cfg.RollupConfigPath != "" { + args = append(args, "--rollup-config-path", cfg.RollupConfigPath) + } + + return args, nil } diff --git a/op-challenger/game/fault/types/types.go b/op-challenger/game/fault/types/types.go index 93c8b19bd542..46227668e928 100644 --- a/op-challenger/game/fault/types/types.go +++ b/op-challenger/game/fault/types/types.go @@ -67,7 +67,7 @@ const ( TraceTypePermissioned TraceType = "permissioned" ) -var TraceTypes = []TraceType{TraceTypeAlphabet, TraceTypeCannon, TraceTypePermissioned, TraceTypeAsterisc, TraceTypeFast} +var TraceTypes = []TraceType{TraceTypeAlphabet, TraceTypeCannon, TraceTypePermissioned, TraceTypeAsterisc, TraceTypeAsteriscKona, TraceTypeFast} func (t TraceType) String() string { return string(t) @@ -104,6 +104,8 @@ func (t TraceType) GameType() GameType { return PermissionedGameType case TraceTypeAsterisc: return AsteriscGameType + case TraceTypeAsteriscKona: + return AsteriscKonaGameType case TraceTypeFast: return FastGameType case TraceTypeAlphabet: diff --git a/op-challenger/runner/factory.go b/op-challenger/runner/factory.go index 59188210d8e5..23b297392e98 100644 --- a/op-challenger/runner/factory.go +++ b/op-challenger/runner/factory.go @@ -45,12 +45,12 @@ func createTraceProvider( return asterisc.NewTraceProvider(logger, m, cfg.Asterisc, vmConfig, prestateProvider, prestate, localInputs, dir, 42), nil case types.TraceTypeAsteriscKona: vmConfig := vm.NewKonaServerExecutor() - prestate, err := getPrestate(prestateHash, cfg.AsteriscAbsolutePreStateBaseURL, cfg.AsteriscAbsolutePreState, dir) + prestate, err := getPrestate(prestateHash, cfg.AsteriscKonaAbsolutePreStateBaseURL, cfg.AsteriscKonaAbsolutePreState, dir) if err != nil { return nil, err } prestateProvider := vm.NewPrestateProvider(prestate, asterisc.NewStateConverter()) - return asterisc.NewTraceProvider(logger, m, cfg.Asterisc, vmConfig, prestateProvider, prestate, localInputs, dir, 42), nil + return asterisc.NewTraceProvider(logger, m, cfg.AsteriscKona, vmConfig, prestateProvider, prestate, localInputs, dir, 42), nil } return nil, errors.New("invalid trace type") } From fb735d6de7eccaea57f927de1995d730b5177106 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2024 20:44:59 -0600 Subject: [PATCH 061/264] dependabot(gomod): bump golang.org/x/crypto from 0.26.0 to 0.27.0 (#11765) * dependabot(gomod): bump golang.org/x/crypto from 0.26.0 to 0.27.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.26.0 to 0.27.0. - [Commits](https://github.com/golang/crypto/compare/v0.26.0...v0.27.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * deps: update --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Mark Tyneway --- cannon/testdata/example/alloc/go.mod | 4 ++-- cannon/testdata/example/alloc/go.sum | 8 ++++---- cannon/testdata/example/claim/go.mod | 4 ++-- cannon/testdata/example/claim/go.sum | 8 ++++---- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/cannon/testdata/example/alloc/go.mod b/cannon/testdata/example/alloc/go.mod index 4068cbf1ddf6..d4d3c23faf2d 100644 --- a/cannon/testdata/example/alloc/go.mod +++ b/cannon/testdata/example/alloc/go.mod @@ -7,8 +7,8 @@ toolchain go1.21.1 require github.com/ethereum-optimism/optimism v0.0.0 require ( - golang.org/x/crypto v0.26.0 // indirect - golang.org/x/sys v0.24.0 // indirect + golang.org/x/crypto v0.27.0 // indirect + golang.org/x/sys v0.25.0 // indirect ) replace github.com/ethereum-optimism/optimism v0.0.0 => ../../../.. diff --git a/cannon/testdata/example/alloc/go.sum b/cannon/testdata/example/alloc/go.sum index 7fb6c4a685ae..c319c5651633 100644 --- a/cannon/testdata/example/alloc/go.sum +++ b/cannon/testdata/example/alloc/go.sum @@ -4,9 +4,9 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/cannon/testdata/example/claim/go.mod b/cannon/testdata/example/claim/go.mod index 8b88d2cf5c32..c70d9906f06c 100644 --- a/cannon/testdata/example/claim/go.mod +++ b/cannon/testdata/example/claim/go.mod @@ -7,8 +7,8 @@ toolchain go1.21.1 require github.com/ethereum-optimism/optimism v0.0.0 require ( - golang.org/x/crypto v0.26.0 // indirect - golang.org/x/sys v0.24.0 // indirect + golang.org/x/crypto v0.27.0 // indirect + golang.org/x/sys v0.25.0 // indirect ) replace github.com/ethereum-optimism/optimism v0.0.0 => ../../../.. diff --git a/cannon/testdata/example/claim/go.sum b/cannon/testdata/example/claim/go.sum index 7fb6c4a685ae..c319c5651633 100644 --- a/cannon/testdata/example/claim/go.sum +++ b/cannon/testdata/example/claim/go.sum @@ -4,9 +4,9 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/go.mod b/go.mod index c36042e3cd8c..c600dbac5db8 100644 --- a/go.mod +++ b/go.mod @@ -43,10 +43,10 @@ require ( github.com/protolambda/ctxlock v0.1.0 github.com/stretchr/testify v1.9.0 github.com/urfave/cli/v2 v2.27.4 - golang.org/x/crypto v0.26.0 + golang.org/x/crypto v0.27.0 golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa golang.org/x/sync v0.8.0 - golang.org/x/term v0.23.0 + golang.org/x/term v0.24.0 golang.org/x/time v0.6.0 ) @@ -224,8 +224,8 @@ require ( go.uber.org/zap v1.27.0 // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.24.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect diff --git a/go.sum b/go.sum index 88c6c189a9bf..bf4985669419 100644 --- a/go.sum +++ b/go.sum @@ -826,8 +826,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= @@ -953,8 +953,8 @@ golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -963,8 +963,8 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -977,8 +977,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 747c9e7d982d04795dac147a865558bae903710b Mon Sep 17 00:00:00 2001 From: Axel Kingsley Date: Fri, 6 Sep 2024 22:14:42 -0500 Subject: [PATCH 062/264] Add Admin RPC for Adding New Chain Monitors (#11792) * Add Admin RPC for Adding New Chain Monitors * Update op-supervisor/supervisor/backend/db/db.go --------- Co-authored-by: protolambda --- op-supervisor/supervisor/backend/backend.go | 117 ++++++++++++------ op-supervisor/supervisor/backend/db/db.go | 8 ++ op-supervisor/supervisor/backend/mock.go | 4 + op-supervisor/supervisor/frontend/frontend.go | 6 + 4 files changed, 99 insertions(+), 36 deletions(-) diff --git a/op-supervisor/supervisor/backend/backend.go b/op-supervisor/supervisor/backend/backend.go index 9270300e5385..ffc2c97e165c 100644 --- a/op-supervisor/supervisor/backend/backend.go +++ b/op-supervisor/supervisor/backend/backend.go @@ -25,11 +25,16 @@ import ( ) type SupervisorBackend struct { + ctx context.Context started atomic.Bool logger log.Logger + m Metrics + dataDir string - chainMonitors []*source.ChainMonitor + chainMonitors map[types.ChainID]*source.ChainMonitor db *db.ChainsDB + + maintenanceCancel context.CancelFunc } var _ frontend.Backend = (*SupervisorBackend)(nil) @@ -37,53 +42,70 @@ var _ frontend.Backend = (*SupervisorBackend)(nil) var _ io.Closer = (*SupervisorBackend)(nil) func NewSupervisorBackend(ctx context.Context, logger log.Logger, m Metrics, cfg *config.Config) (*SupervisorBackend, error) { + // attempt to prepare the data directory if err := prepDataDir(cfg.Datadir); err != nil { return nil, err } + + // create the head tracker headTracker, err := heads.NewHeadTracker(filepath.Join(cfg.Datadir, "heads.json")) if err != nil { return nil, fmt.Errorf("failed to load existing heads: %w", err) } - logDBs := make(map[types.ChainID]db.LogStorage) - chainRPCs := make(map[types.ChainID]string) - chainClients := make(map[types.ChainID]client.RPC) + + // create the chains db + db := db.NewChainsDB(map[types.ChainID]db.LogStorage{}, headTracker) + + // create an empty map of chain monitors + chainMonitors := make(map[types.ChainID]*source.ChainMonitor, len(cfg.L2RPCs)) + + // create the supervisor backend + super := &SupervisorBackend{ + logger: logger, + m: m, + dataDir: cfg.Datadir, + chainMonitors: chainMonitors, + db: db, + } + + // from the RPC strings, have the supervisor backend create a chain monitor for _, rpc := range cfg.L2RPCs { - rpcClient, chainID, err := createRpcClient(ctx, logger, rpc) + err := super.addFromRPC(ctx, logger, rpc) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to add chain monitor for rpc %v: %w", rpc, err) } - cm := newChainMetrics(chainID, m) - path, err := prepLogDBPath(chainID, cfg.Datadir) - if err != nil { - return nil, fmt.Errorf("failed to create datadir for chain %v: %w", chainID, err) - } - logDB, err := logs.NewFromFile(logger, cm, path) - if err != nil { - return nil, fmt.Errorf("failed to create logdb for chain %v at %v: %w", chainID, path, err) - } - logDBs[chainID] = logDB - chainRPCs[chainID] = rpc - chainClients[chainID] = rpcClient - } - chainsDB := db.NewChainsDB(logDBs, headTracker) - if err := chainsDB.Resume(); err != nil { - return nil, fmt.Errorf("failed to resume chains db: %w", err) } + return super, nil +} - chainMonitors := make([]*source.ChainMonitor, 0, len(cfg.L2RPCs)) - for chainID, rpc := range chainRPCs { - cm := newChainMetrics(chainID, m) - monitor, err := source.NewChainMonitor(ctx, logger, cm, chainID, rpc, chainClients[chainID], chainsDB) - if err != nil { - return nil, fmt.Errorf("failed to create monitor for rpc %v: %w", rpc, err) - } - chainMonitors = append(chainMonitors, monitor) +// addFromRPC adds a chain monitor to the supervisor backend from an rpc endpoint +// it does not expect to be called after the backend has been started +func (su *SupervisorBackend) addFromRPC(ctx context.Context, logger log.Logger, rpc string) error { + // create the rpc client, which yields the chain id + rpcClient, chainID, err := createRpcClient(su.ctx, logger, rpc) + if err != nil { + return err } - return &SupervisorBackend{ - logger: logger, - chainMonitors: chainMonitors, - db: chainsDB, - }, nil + // create metrics and a logdb for the chain + cm := newChainMetrics(chainID, su.m) + path, err := prepLogDBPath(chainID, su.dataDir) + if err != nil { + return fmt.Errorf("failed to create datadir for chain %v: %w", chainID, err) + } + logDB, err := logs.NewFromFile(logger, cm, path) + if err != nil { + return fmt.Errorf("failed to create logdb for chain %v at %v: %w", chainID, path, err) + } + monitor, err := source.NewChainMonitor(ctx, logger, cm, chainID, rpc, rpcClient, su.db) + if err != nil { + return fmt.Errorf("failed to create monitor for rpc %v: %w", rpc, err) + } + if su.chainMonitors[chainID] != nil { + return fmt.Errorf("chain monitor for chain %v already exists", chainID) + } + su.chainMonitors[chainID] = monitor + su.db.AddLogDB(chainID, logDB) + return nil } func createRpcClient(ctx context.Context, logger log.Logger, rpc string) (client.RPC, types.ChainID, error) { @@ -99,9 +121,14 @@ func createRpcClient(ctx context.Context, logger log.Logger, rpc string) (client } func (su *SupervisorBackend) Start(ctx context.Context) error { + // ensure we only start once if !su.started.CompareAndSwap(false, true) { return errors.New("already started") } + // initiate "Resume" on the chains db, which rewinds the database to the last block that is guaranteed to have been fully recorded + if err := su.db.Resume(); err != nil { + return fmt.Errorf("failed to resume chains db: %w", err) + } // start chain monitors for _, monitor := range su.chainMonitors { if err := monitor.Start(); err != nil { @@ -109,7 +136,9 @@ func (su *SupervisorBackend) Start(ctx context.Context) error { } } // start db maintenance loop - su.db.StartCrossHeadMaintenance(ctx) + maintinenceCtx, cancel := context.WithCancel(ctx) + su.db.StartCrossHeadMaintenance(maintinenceCtx) + su.maintenanceCancel = cancel return nil } @@ -117,12 +146,16 @@ func (su *SupervisorBackend) Stop(ctx context.Context) error { if !su.started.CompareAndSwap(true, false) { return errors.New("already stopped") } + // signal the maintenance loop to stop + su.maintenanceCancel() + // collect errors from stopping chain monitors var errs error for _, monitor := range su.chainMonitors { if err := monitor.Stop(); err != nil { errs = errors.Join(errs, fmt.Errorf("failed to stop chain monitor: %w", err)) } } + // close the database if err := su.db.Close(); err != nil { errs = errors.Join(errs, fmt.Errorf("failed to close database: %w", err)) } @@ -134,6 +167,18 @@ func (su *SupervisorBackend) Close() error { return nil } +// AddL2RPC adds a new L2 chain to the supervisor backend +// it stops and restarts the backend to add the new chain +func (su *SupervisorBackend) AddL2RPC(ctx context.Context, rpc string) error { + if err := su.Stop(ctx); err != nil { + return fmt.Errorf("failed to stop backend: %w", err) + } + if err := su.addFromRPC(ctx, su.logger, rpc); err != nil { + return fmt.Errorf("failed to add chain monitor: %w", err) + } + return su.Start(ctx) +} + func (su *SupervisorBackend) CheckMessage(identifier types.Identifier, payloadHash common.Hash) (types.SafetyLevel, error) { chainID := identifier.ChainID blockNum := identifier.BlockNumber diff --git a/op-supervisor/supervisor/backend/db/db.go b/op-supervisor/supervisor/backend/db/db.go index b0c2bd5f99f9..27ece73cc77b 100644 --- a/op-supervisor/supervisor/backend/db/db.go +++ b/op-supervisor/supervisor/backend/db/db.go @@ -52,9 +52,17 @@ func NewChainsDB(logDBs map[types.ChainID]LogStorage, heads HeadsStorage) *Chain } } +func (db *ChainsDB) AddLogDB(chain types.ChainID, logDB LogStorage) { + if db.logDBs[chain] != nil { + log.Warn("overwriting existing logDB for chain", "chain", chain) + } + db.logDBs[chain] = logDB +} + // Resume prepares the chains db to resume recording events after a restart. // It rewinds the database to the last block that is guaranteed to have been fully recorded to the database // to ensure it can resume recording from the first log of the next block. +// TODO(#11793): we can rename this to something more descriptive like "PrepareWithRollback" func (db *ChainsDB) Resume() error { for chain, logStore := range db.logDBs { if err := Resume(logStore); err != nil { diff --git a/op-supervisor/supervisor/backend/mock.go b/op-supervisor/supervisor/backend/mock.go index 71c77b235525..e62c7b950b7c 100644 --- a/op-supervisor/supervisor/backend/mock.go +++ b/op-supervisor/supervisor/backend/mock.go @@ -39,6 +39,10 @@ func (m *MockBackend) Stop(ctx context.Context) error { return nil } +func (m *MockBackend) AddL2RPC(ctx context.Context, rpc string) error { + return nil +} + func (m *MockBackend) CheckMessage(identifier types.Identifier, payloadHash common.Hash) (types.SafetyLevel, error) { return types.CrossUnsafe, nil } diff --git a/op-supervisor/supervisor/frontend/frontend.go b/op-supervisor/supervisor/frontend/frontend.go index 421b231e128e..41fb84e511cd 100644 --- a/op-supervisor/supervisor/frontend/frontend.go +++ b/op-supervisor/supervisor/frontend/frontend.go @@ -12,6 +12,7 @@ import ( type AdminBackend interface { Start(ctx context.Context) error Stop(ctx context.Context) error + AddL2RPC(ctx context.Context, rpc string) error } type QueryBackend interface { @@ -61,3 +62,8 @@ func (a *AdminFrontend) Start(ctx context.Context) error { func (a *AdminFrontend) Stop(ctx context.Context) error { return a.Supervisor.Stop(ctx) } + +// AddL2RPC adds a new L2 chain to the supervisor backend +func (a *AdminFrontend) AddL2RPC(ctx context.Context, rpc string) error { + return a.Supervisor.AddL2RPC(ctx, rpc) +} From 4fbe14f1c43de80b0ac79469e363351da160211a Mon Sep 17 00:00:00 2001 From: protolambda Date: Sat, 7 Sep 2024 16:26:00 -0600 Subject: [PATCH 063/264] semgrep: try to fix CI timeout (#11798) --- .circleci/config.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f4fe234bb34a..e23186e5a234 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1322,10 +1322,6 @@ jobs: SEMGREP_REPO_URL: << pipeline.project.git_url >> SEMGREP_BRANCH: << pipeline.git.branch >> SEMGREP_COMMIT: << pipeline.git.revision >> - - # Change job timeout (default is 1800 seconds; set to 0 to disable) - SEMGREP_TIMEOUT: 3000 - docker: - image: returntocorp/semgrep resource_class: medium @@ -1349,7 +1345,15 @@ jobs: echo 'export SEMGREP_REPO_NAME=$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME' >> $BASH_ENV - run: name: "Semgrep scan" - command: semgrep ci + # --time shows which rules take the most time + # --max-memory (in MiB) limits memory usage + # (defaults to 5GB, but medium runner only has 4GB, so we conservatively limit it to 3GB) + # --timeout (in seconds) limits the time per rule and file. + # SEMGREP_TIMEOUT is the same, but docs have conflicting defaults (5s in CLI flag, 1800 in some places) + # https://semgrep.dev/docs/troubleshooting/semgrep-app#if-the-job-is-aborted-due-to-taking-too-long + command: semgrep ci --time --timeout=100 --max-memory=3000 + # If semgrep hangs, stop the scan after 20m, to prevent a useless 5h job + no_output_timeout: 20m - notify-failures-on-develop go-mod-download: From 9170e93e9d833bf2e80163464c40e8874335ffa2 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Sat, 7 Sep 2024 22:29:05 -0400 Subject: [PATCH 064/264] maint: move existing interfaces to folders (#11749) Moves any existing interfaces that are not already inside of their corresponding /interfaces folders into those folders. --- packages/contracts-bedrock/semver-lock.json | 142 +++++++++--------- packages/contracts-bedrock/src/EAS/EAS.sol | 2 +- .../src/EAS/SchemaRegistry.sol | 2 +- .../src/L1/DataAvailabilityChallenge.sol | 2 +- .../src/L1/DelayedVetoable.sol | 6 +- .../src/L1/L1CrossDomainMessenger.sol | 2 +- .../src/L1/L1ERC721Bridge.sol | 2 +- .../src/L1/L1StandardBridge.sol | 2 +- .../src/L1/L2OutputOracle.sol | 2 +- .../src/L1/OPStackManager.sol | 2 +- .../src/L1/OptimismPortal.sol | 2 +- .../src/L1/OptimismPortal2.sol | 2 +- .../src/L1/ProtocolVersions.sol | 2 +- .../src/L1/SuperchainConfig.sol | 2 +- .../contracts-bedrock/src/L1/SystemConfig.sol | 2 +- .../contracts-bedrock/src/L2/BaseFeeVault.sol | 2 +- .../contracts-bedrock/src/L2/CrossL2Inbox.sol | 4 +- .../contracts-bedrock/src/L2/ETHLiquidity.sol | 6 +- .../src/L2/GasPriceOracle.sol | 2 +- packages/contracts-bedrock/src/L2/L1Block.sol | 2 +- .../contracts-bedrock/src/L2/L1FeeVault.sol | 2 +- .../src/L2/L2CrossDomainMessenger.sol | 2 +- .../src/L2/L2ERC721Bridge.sol | 4 +- .../src/L2/L2StandardBridge.sol | 2 +- .../src/L2/L2StandardBridgeInterop.sol | 2 +- .../src/L2/L2ToL1MessagePasser.sol | 2 +- .../src/L2/L2ToL2CrossDomainMessenger.sol | 4 +- .../src/L2/OptimismSuperchainERC20.sol | 6 +- .../src/L2/SequencerFeeVault.sol | 2 +- .../src/L2/SuperchainWETH.sol | 10 +- packages/contracts-bedrock/src/L2/WETH.sol | 6 +- .../src/L2/{ => interfaces}/ICrossL2Inbox.sol | 0 .../IL2ToL2CrossDomainMessenger.sol | 0 .../IOptimismERC20Factory.sol | 0 .../IOptimismSuperchainERC20.sol | 0 .../L2/{ => interfaces}/ISuperchainERC20.sol | 0 .../src/Safe/DeputyGuardianModule.sol | 6 +- .../src/Safe/LivenessGuard.sol | 6 +- .../src/Safe/LivenessModule.sol | 6 +- .../contracts-bedrock/src/cannon/MIPS.sol | 6 +- .../contracts-bedrock/src/cannon/MIPS2.sol | 2 +- .../src/cannon/PreimageOracle.sol | 6 +- .../src/cannon/interfaces/IMIPS.sol | 2 +- .../src/cannon/interfaces/IMIPS2.sol | 2 +- .../src/dispute/AnchorStateRegistry.sol | 2 +- .../src/dispute/DisputeGameFactory.sol | 2 +- .../src/dispute/FaultDisputeGame.sol | 6 +- .../src/dispute/weth/DelayedWETH.sol | 2 +- .../src/legacy/DeployerWhitelist.sol | 2 +- .../src/legacy/L1BlockNumber.sol | 2 +- .../src/legacy/LegacyMessagePasser.sol | 2 +- .../legacy/interfaces/IDeployerWhitelist.sol | 2 +- .../src/legacy/interfaces/IL1BlockNumber.sol | 2 +- .../interfaces/ILegacyMessagePasser.sol | 2 +- .../periphery/op-nft/AttestationStation.sol | 6 +- .../src/periphery/op-nft/Optimist.sol | 6 +- .../periphery/op-nft/OptimistAllowlist.sol | 6 +- .../src/periphery/op-nft/OptimistInviter.sol | 6 +- .../src/universal/OptimismMintableERC20.sol | 8 +- .../OptimismMintableERC20Factory.sol | 4 +- .../src/universal/OptimismMintableERC721.sol | 8 +- .../OptimismMintableERC721Factory.sol | 6 +- .../src/universal/StandardBridge.sol | 2 +- .../src/universal/StorageSetter.sol | 6 +- .../IOptimismMintableERC20.sol | 0 .../IOptimismMintableERC721.sol | 0 .../universal/{ => interfaces}/ISemver.sol | 0 .../test/L2/CrossL2Inbox.t.sol | 2 +- .../test/L2/L2StandardBridgeInterop.t.sol | 2 +- .../test/L2/OptimismSuperchainERC20.t.sol | 4 +- .../test/L2/SuperchainWETH.t.sol | 2 +- .../invariants/OptimismSuperchainERC20.t.sol | 2 +- .../test/invariants/SuperchainWETH.t.sol | 2 +- .../universal/OptimismMintableERC20.t.sol | 2 +- 74 files changed, 183 insertions(+), 183 deletions(-) rename packages/contracts-bedrock/src/L2/{ => interfaces}/ICrossL2Inbox.sol (100%) rename packages/contracts-bedrock/src/L2/{ => interfaces}/IL2ToL2CrossDomainMessenger.sol (100%) rename packages/contracts-bedrock/src/L2/{ => interfaces}/IOptimismERC20Factory.sol (100%) rename packages/contracts-bedrock/src/L2/{ => interfaces}/IOptimismSuperchainERC20.sol (100%) rename packages/contracts-bedrock/src/L2/{ => interfaces}/ISuperchainERC20.sol (100%) rename packages/contracts-bedrock/src/universal/{ => interfaces}/IOptimismMintableERC20.sol (100%) rename packages/contracts-bedrock/src/universal/{ => interfaces}/IOptimismMintableERC721.sol (100%) rename packages/contracts-bedrock/src/universal/{ => interfaces}/ISemver.sol (100%) diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 7bbd76d0c50e..1fc5131c4581 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -1,47 +1,47 @@ { "src/EAS/EAS.sol": { "initCodeHash": "0xf96d1ebc530ed95e2dffebcfa2b4a1f18103235e6352d97838b77b7a2c14567b", - "sourceCodeHash": "0xfaeb13f74d79a5fa8539ab3c9b8b8053b05cec78317aaf132bdeedb4018541cd" + "sourceCodeHash": "0x1902e1528cc6ff04a181036d9f1da70bd3f861b6cf1bb844d916501af5f40127" }, "src/EAS/SchemaRegistry.sol": { "initCodeHash": "0x06ae2c0b39c215b7fa450d382916ce6f5c6f9f2d630e572db6b72d688255b3fd", - "sourceCodeHash": "0x7e716bd2827a8f696c9345ec01ed037559447540771ffbcf3eba38f57b085a20" + "sourceCodeHash": "0x9ec99e63a991691e8756a663edf2ccfbe9b91161c134e24f38298da61ecd66dd" }, "src/L1/DataAvailabilityChallenge.sol": { "initCodeHash": "0xcc96cf2e4d841adb7ecb9dd84abeb0893dd62d913c0d47ab5b66a893c6e47e88", - "sourceCodeHash": "0x9d791696967f50c7a7b35b1fef3b00adaa61846623cc284e3a2b8599b77909ae" + "sourceCodeHash": "0x3260f2721af58ab77d4eae50365f3afe021a03b6383139e69779ac40f511b792" }, "src/L1/DelayedVetoable.sol": { - "initCodeHash": "0x84f78e56211500a768b2c5bbafde8e7b411bd64c237297370d7d22326b68357c", - "sourceCodeHash": "0xc59b8574531162e016d7342aeb6e79d05574e90dbea6c0e5ede35b65010ad894" + "initCodeHash": "0xd504ab0568719a0fb960ebe73d0437645f5c4bd8f6619219858209ef002516dd", + "sourceCodeHash": "0x1806db090be1a0bd8cba1b0b44a4f1c28a3cfc58a174a025fc292163bfff8cee" }, "src/L1/L1CrossDomainMessenger.sol": { "initCodeHash": "0x48db42620b9f16e0dec2355f4076314f82fd0f60ef04c10cdbc266eac9472515", - "sourceCodeHash": "0xdfdbc9849a5147bb1f9ffd1d886fc0399016c3dccaabaa61fc6735c1b4af774b" + "sourceCodeHash": "0xca37e50dd6c1aa86bbc5f9ec640410bf234cd911158ba91af984fd2ed94c19c5" }, "src/L1/L1ERC721Bridge.sol": { "initCodeHash": "0xda80d225e332f9ab38d5f3ae655df3eea1dd56dbb523036a25c78859d2931ada", - "sourceCodeHash": "0xa4e78a2440fb560366e84e5f0ba59932ee564ff47ac3aa9a2c489fff4d6fd061" + "sourceCodeHash": "0xcef23f69992fa6cb5ad051858dbec924a06fa3b7b44f03caa2415804d6ce7bd0" }, "src/L1/L1StandardBridge.sol": { "initCodeHash": "0x2868b09ecbe9f2bbc885605c2886b4c79f1c8e4171626c63776603b1b84698a8", - "sourceCodeHash": "0xfde1de7fa0f0d4840768abab775901c07e16ab59835a20e7a8ef512fa85acfcb" + "sourceCodeHash": "0x35f27059e5a7421ddf6394f9739a8c9f434de17e1736644695791c19b8240e74" }, "src/L1/L2OutputOracle.sol": { "initCodeHash": "0x433fac9de52d8ce8fc3471b78ef6cc9cff1019f480c9ad91b6e09ab8738a8edb", - "sourceCodeHash": "0xf0c0655221c36cfe918818ca300cca74a3713be3da090b2072eb81ba29c59e38" + "sourceCodeHash": "0xc11a2a514a051bdc82b21ec39c7b923145d384629adb1efc52b534f3c686f6a0" }, "src/L1/OPStackManager.sol": { "initCodeHash": "0x67bf02405bf1ca7d78c4215c350ad9c5c7b4cece35d9fab837f279d65f995c5d", - "sourceCodeHash": "0xf5db686a001aeb47cab09bb377ae226e872c806b4f5eff869d4dd6367f47c471" + "sourceCodeHash": "0x8e272e707e383d516b8f1cce0ea29ff46a0eb448c8386fa146e6a43f3100042a" }, "src/L1/OptimismPortal.sol": { "initCodeHash": "0x6bf59539298b20221de6c51db21016be8d3278bdbe0be1cdd49638dc828e003e", - "sourceCodeHash": "0x9ca40fb207eae615087f07041d4ce5349c74d7beebae1c74181c91a8631162bb" + "sourceCodeHash": "0xad97b31e3855ad0af82a0fc80db9773b7eacc85215611854dcc54f60f97f06bf" }, "src/L1/OptimismPortal2.sol": { "initCodeHash": "0x414ad1fdb6296ac32fc67ce01288b6e67bedd2ed239d7eb8ed40c7f55f9021f2", - "sourceCodeHash": "0x1af32dcddecb37ccc875edbc10203cac04319953de04bd3cba02a1740a6a0827" + "sourceCodeHash": "0xa70bdc0bb666baa731ab32c79a7b8b15cee23bd46ddfec5f259eaf19b5653fe1" }, "src/L1/OptimismPortalInterop.sol": { "initCodeHash": "0x9222fba222d1ab66898eef09ecea3ea757e64c8ae98def4da7808cd7cc8f39a8", @@ -49,15 +49,15 @@ }, "src/L1/ProtocolVersions.sol": { "initCodeHash": "0x8f033874dd8b36615b2209d553660dcff1ff91ca2bad3ca1de7b441dbfba4842", - "sourceCodeHash": "0xc823fcc6ddb4be71b5177b46748415fe5d54c2970696a00db896bec615b482d6" + "sourceCodeHash": "0x5a7e91e02224e02a5a4bbf0fea7e9bd4a1168e2fe5e787023c9a75bcb6c26204" }, "src/L1/SuperchainConfig.sol": { "initCodeHash": "0xfca12d9016c746e5c275b186e0ca40cfd65cf45a5665aab7589a669fea3abb47", - "sourceCodeHash": "0x4dc2a082013a7d7b76c74d15b4e9c755b0c99511ee3dd3cb4e42e9a269575135" + "sourceCodeHash": "0x39489a85bc3a5c8560f82d41b31bf7fe22f5b648f4ed538f61695a73092ea9eb" }, "src/L1/SystemConfig.sol": { "initCodeHash": "0x2fc36af5b3c493a423a19e0b597f6ff230b756b861b68099f3192d69b6088dc0", - "sourceCodeHash": "0xd7b18e0acf8363edcffcf38cdfdc21b9a4b8eba4656b6c6524a4629bb09c9aef" + "sourceCodeHash": "0xacffbb4e73d39a642adc24baaa50c92604f4c0b04ff31287e24a46bda5277033" }, "src/L1/SystemConfigInterop.sol": { "initCodeHash": "0xc5a3ffc59dd7bf1ef238087414cfa04b37f0d83fc9a4f5e6d62a1059a23359f3", @@ -65,23 +65,23 @@ }, "src/L2/BaseFeeVault.sol": { "initCodeHash": "0x3bfcd57e25ad54b66c374f63e24e33a6cf107044aa8f5f69ef21202c380b5c5b", - "sourceCodeHash": "0x0861b8415b4657a3aee4ab5e019c42204730597ca2d6355f34e8cf7a76d3ce27" + "sourceCodeHash": "0x2dc2284cf7c68e743da50e4113e96ffeab435de2390aeba2eab2f1e8ca411ce9" }, "src/L2/CrossL2Inbox.sol": { "initCodeHash": "0x926ec5b92a5ff032c00ae13f1156332cb43b98b89573467e9ddfab6fce9f3e95", - "sourceCodeHash": "0xdb08fd714670d13c9c9a191f7ba07e9a208d94db379103c1f0f3812ed805f2cd" + "sourceCodeHash": "0xd5d3f9f1ff7d15367e200832d3257514c6e8cf3cf64703111111982c0ea4840b" }, "src/L2/ETHLiquidity.sol": { - "initCodeHash": "0x98177562fca0de0dfea5313c9acefe2fdbd73dee5ce6c1232055601f208f0177", - "sourceCodeHash": "0x6dc23ceeed5a63fdc98ba8e5099df1822f3eeaa8c82afb1fa3235ff68a37b274" + "initCodeHash": "0x1d9958d75fd502f018408ed5585d541b156435ac9c163009135b866d66f8f6ee", + "sourceCodeHash": "0xdd96f3fd6199dbdd8f3e480a517431b5884ea60078639ee8471df703593bf2ac" }, "src/L2/GasPriceOracle.sol": { "initCodeHash": "0xa1aae095643272e2dd08f8121dd4425cc8d4fd798cd39db63e4b957863efa8c1", - "sourceCodeHash": "0xa170fff280d94991082efffa40b6daa3dd9eff7fe6c5b1bc31e40bc128bff94e" + "sourceCodeHash": "0xaef30eab756a3804a241f57c8bb787179376477f6344a6ae49771d532153c9d3" }, "src/L2/L1Block.sol": { "initCodeHash": "0xb12c0560e4e0aed12df5f65a1bc2b302afd183601c149285a26eafe5e4c20c0e", - "sourceCodeHash": "0x69c652c2920e6a6226f3f8f3e6ea3a977c7b15f9efb11916858613e8c8d6903b" + "sourceCodeHash": "0x30aef5ac102e3655651ff821ce560ecf0da0914456379b784f5652fe09c37aa3" }, "src/L2/L1BlockInterop.sol": { "initCodeHash": "0xd2afdf64b0232264e4996e0557523c108c2f12a9b6d2de45dfd961f7a1c927e3", @@ -89,134 +89,134 @@ }, "src/L2/L1FeeVault.sol": { "initCodeHash": "0x3bfcd57e25ad54b66c374f63e24e33a6cf107044aa8f5f69ef21202c380b5c5b", - "sourceCodeHash": "0x35dc3bb4ab3d02cf9c1e12b0f6796d7eda9d314598bfdecab2812fe9159f443c" + "sourceCodeHash": "0x927cc729bf5c9f209112df597f649493f276c4c50e17a57f7da02c2be266b192" }, "src/L2/L2CrossDomainMessenger.sol": { "initCodeHash": "0xe7090ce8119fe373d930baa68c1df585953b7f6e8beea2a0084589d394bcab64", - "sourceCodeHash": "0x22033cd1923c9d52d9520de773b332ae179528065e4b8f5e37a9aaf59d140735" + "sourceCodeHash": "0xea51d4b7a96c3a4c06d73c214208775b6845d5f696198c169ef7c14ea005d451" }, "src/L2/L2ERC721Bridge.sol": { "initCodeHash": "0x827077e1a0ce6c8f9ee1196c409ea77d831efd440992b3969b05259083cdf0bd", - "sourceCodeHash": "0xd3c25187a46c7f42dfbbcb54e45b11101acc99c014e013ef8e5b9e868220f525" + "sourceCodeHash": "0xaef911601556f93deac78cb3329fdcc1507ea248c3986548e76997938c43391b" }, "src/L2/L2StandardBridge.sol": { "initCodeHash": "0x01692b613e3d4e649d877a0fd8f0798a26401ba8ccc4cda0e61f1f9079729320", - "sourceCodeHash": "0x09cf9e0d84c8d29fbf9c3288a38807edcd7c456427e222e1fd1f7aa4dbf73352" + "sourceCodeHash": "0x3efb2dabff452f5d2584839d1460183cb8aecd5456fbfa3a72d80de40df783b7" }, "src/L2/L2StandardBridgeInterop.sol": { "initCodeHash": "0x5c9ef6b0817f715d1b8b097f3fc19e33bc54453426ca12bb48e4cea143076339", - "sourceCodeHash": "0xd28d1a4bf6c66fa26f180988b26ea564afa024f8181eca6c23e5dc5dfd5757cd" + "sourceCodeHash": "0x5a2d206477d6ba84e93bf0e1545a5cf2c93a6bb80529c07927f53915bde298bf" }, "src/L2/L2ToL1MessagePasser.sol": { "initCodeHash": "0x13fe3729beb9ed966c97bef09acb9fe5043fe651d453145073d05f2567fa988d", - "sourceCodeHash": "0xe4e768c5f60111188979a334b684a4d9c9267375cfa991897432b5a415bea516" + "sourceCodeHash": "0xd08a2e6514dbd44e16aa312a1b27b2841a9eab5622cbd05a39c30f543fad673c" }, "src/L2/L2ToL2CrossDomainMessenger.sol": { "initCodeHash": "0x3e4337542234c732a55e60fc20dcb1ad639ff2fb378e3f29e94b4059df9a637b", - "sourceCodeHash": "0x5d266f4f380cee7a267f000af16ed2fb9399fda773a7e4543d3dc1c9df982a65" + "sourceCodeHash": "0x4b806cc85cead74c8df34ab08f4b6c6a95a1a387a335ec8a7cb2de4ea4e1cf41" }, "src/L2/OptimismSuperchainERC20.sol": { "initCodeHash": "0xdd16dbc0ccbbac53ec2d4273f06334960a907a9f20b7c40300833227ee31d0de", - "sourceCodeHash": "0x8566ff63d42f48ddae977c436dae4773e43f2223800c6a0eb9e4c6cf95b19d77" + "sourceCodeHash": "0x910d43a17800df64dbc104f69ef1f900ca761cec4949c01d1c1126fde5268349" }, "src/L2/SequencerFeeVault.sol": { "initCodeHash": "0x2e6551705e493bacba8cffe22e564d5c401ae5bb02577a5424e0d32784e13e74", - "sourceCodeHash": "0x846ff8fcc1091aa262cda06f93a6e1a57ae885206fe124bcf23550436a16597e" + "sourceCodeHash": "0xd56922cb04597dea469c65e5a49d4b3c50c171e603601e6f41da9517cae0b11a" }, "src/L2/SuperchainWETH.sol": { - "initCodeHash": "0x599e948350c70d699f8a8be945abffd126097de97fade056d29767128320fe75", - "sourceCodeHash": "0x3df29ee1321418914d88ce303b521bf8267ef234b919870b26639d08d7f806bd" + "initCodeHash": "0x3131295bdf487120be7db6b9866d9192db32f379bbeff8f03ac61ebabdb62031", + "sourceCodeHash": "0x031aaacafaa27ad6648876cf06ba0c71d01f600897b58a9bd92ce17f7098a718" }, "src/L2/WETH.sol": { - "initCodeHash": "0xde72ae96910e95249623c2d695749847e4c4adeaf96a7a35033afd77318a528a", - "sourceCodeHash": "0xbe200a6cb297a3ca1a7d174a9c886e3f17eb8edf617ad014a2ac4f6c2e2ac7f1" + "initCodeHash": "0x789916977b4930eb266f2187a100bc432c12b76e3872931be673a7ef2773507a", + "sourceCodeHash": "0x3f7bd622a788b8d00fe1631b14b761488eedccf56879f7ea2d610dd5ce81efbe" }, "src/Safe/DeputyGuardianModule.sol": { - "initCodeHash": "0xfe20f758f29c2ccef175aeac966183329440f838558d0d1529b9a895b2ac541c", - "sourceCodeHash": "0x6295b93d1adbfe9cdda1a5750aac97aabf34addf384dcdae86362ffa9e22e593" + "initCodeHash": "0xce6cd0e4f21693a32e7a8ef463b8233b0dde83bdb426f5adc3eef822d4de7bec", + "sourceCodeHash": "0x45fdf6b414a6eae662392051a5e0acc5b95f23ca33f739ddfb35ae2e7ce81728" }, "src/Safe/LivenessGuard.sol": { - "initCodeHash": "0xf54289de5cef7ba0044e0d63310937fa231d6528aac91e13e531c845af42afac", - "sourceCodeHash": "0xea3872d8f196ae3c863363dfa4b57803cb2a24b0c100244d8f861891e901e03f" + "initCodeHash": "0xfd74ff89e7b689b38ab97515d64429ffaf6c0cd1ea6488c6a4743a0665419c85", + "sourceCodeHash": "0xcfeadabe8da944fb64d85c9c971ee364baddcc6aa5b5a0701049669ce372cd90" }, "src/Safe/LivenessModule.sol": { - "initCodeHash": "0xde144889fe7d98dbf300a98f5331edd535086a4af8ae6d88ca190c7f4c754a2d", - "sourceCodeHash": "0x3ff4a3f21202478935412d47fd5ef7f94a170402ddc50e5c062013ce5544c83f" + "initCodeHash": "0xcfccdd9e423c95a0ddc6e09ccb6333d5fc8429ed2b8fc872f1290d392ae13aad", + "sourceCodeHash": "0x255a3f78036745feb57da2e16a93a83fe3f52944fec42029da9b9eaa147db11c" }, "src/cannon/MIPS.sol": { - "initCodeHash": "0x958942c497e15ca698064c2d7876c4f5751664fad3fd72092bae6e61a1ab3698", - "sourceCodeHash": "0xb6e219e8c2d81d75c48a1459907609e9096fe032a7447c88cd3e0d134752ac8e" + "initCodeHash": "0x9a30f51e5516230f8a1a2a757fb992ef3283041f5cc5220dd0891ce815527dfb", + "sourceCodeHash": "0x368963e339be2dbf8f623f9458e870e061725fce20e5a4004e48c03273de7236" }, "src/cannon/MIPS2.sol": { "initCodeHash": "0xf5e2bca4ba0c504ffa68f1ce5fbf4349b1fa892034777d77803d9111aed279fa", - "sourceCodeHash": "0xe8d06d4e2c3cf6e0682e4c152429cd61f0fd963acb1190df1bba1727d90ef6b7" + "sourceCodeHash": "0x3c3716ac78180fc71d67b0f849b2ec28891b2e065d33d4d70b4b7279a12d4b66" }, "src/cannon/PreimageOracle.sol": { - "initCodeHash": "0xce7a1c3265e457a05d17b6d1a2ef93c4639caac3733c9cf88bfd192eae2c5788", - "sourceCodeHash": "0x0a3cd959b361f1da998365da8b3c14362007d73b36196cced0606a9f082e63a8" + "initCodeHash": "0xd321f266b19eca87e2f915e4cf1c973ed9beba39d1336df01c4957c72e3783f3", + "sourceCodeHash": "0x050b2f007715f27e9872d1f6dc7bd340cdf08ea11737548c17968ea2e94e75cc" }, "src/dispute/AnchorStateRegistry.sol": { "initCodeHash": "0x6198f305686e6fdfd94db7aeb840a12e263036dcdc234550db49d3f0b87039a8", - "sourceCodeHash": "0x178e5c971252a9eb4b5c3fb28be1e15911c0b5aa6d27c852b73777877475f046" + "sourceCodeHash": "0x384d4e7067d423dc32b8588341b61a504a28505aa5ed7dd76f115991be072ee0" }, "src/dispute/DisputeGameFactory.sol": { "initCodeHash": "0xc1a10f65287c414076b68a7de6c238b91bc6252213187bdef35657d0f00f9382", - "sourceCodeHash": "0x5a31133388bbb0d3621993b72a5a292108f99299f9cad8bc8e709b13e1ae0bc2" + "sourceCodeHash": "0x3d391c58420abe60d8486136a57d7f9c7137f722c80a8d884305617eb31566ef" }, "src/dispute/FaultDisputeGame.sol": { - "initCodeHash": "0x8705f00408ff4405723bf59e2dce61a90aa49d8094da1c96a3652a2ebb169519", - "sourceCodeHash": "0x3df123ab9a19f7c097510afb191099e7c3098ab892111a13c8f061ab0f0e57a0" + "initCodeHash": "0xbeec6747b5d189a75528426ad9e2b329051953f69f2fc86bdad8cae22e33f659", + "sourceCodeHash": "0x6e7aab50fab2d42c7c3f67e4b0f0b74444d29409f275cf758915c7b76d31528f" }, "src/dispute/weth/DelayedWETH.sol": { "initCodeHash": "0x3e687c928b6c890b91c82584ccb1fec47b025b8e58cd9cbfa65229b38b304bae", - "sourceCodeHash": "0x7bec41daedccca173b93974f90ff2b345ac87305b29e242a386f7605b1208df9" + "sourceCodeHash": "0x7ebe0d9771fc8adfd97386972a571eb1753065a202d4711c0b9587d99f3bd261" }, "src/legacy/DeployerWhitelist.sol": { "initCodeHash": "0x0b8177ed75b69eddbb9ce6537683f69a9935efed86a1d6faa8feaafbd151c1bd", - "sourceCodeHash": "0xaf70fdfbe98a5794cc83c2baa0ef4346592c67ffade186852030010827c2d2d2" + "sourceCodeHash": "0xc8fe9571fcf8fcb51a4dcb00ffa97f43a9ce811c323c4926e710b28c90a9005f" }, "src/legacy/L1BlockNumber.sol": { "initCodeHash": "0xfc43380228388659578368ec31b4581404ad3f3d30f3fcedccd461b1feaeebb4", - "sourceCodeHash": "0x20c8f204aa7bcdf88c48d3f067c4c4c8e8c827e0ba7b7c4a21e6f8d8225561f5" + "sourceCodeHash": "0x1dbbf96cf6514bfa7b553cebaec1da2f32b9b154cd80134adb7c129ee109da74" }, "src/legacy/LegacyMessagePasser.sol": { "initCodeHash": "0xefc6ed9e325c2d614ea0d28c3eabfff1b345f7c6054e90253c6a091c29508267", - "sourceCodeHash": "0x6ccc02c966d1548c38754f665e650763fe8e17326e76b5438398680937e37f8f" + "sourceCodeHash": "0xaa08a61448f485b277af57251d2089cc6a80ce0a763bf7184d48ffed5034ef69" }, "src/periphery/op-nft/AttestationStation.sol": { - "initCodeHash": "0xf9b8ff2ecdcaca2b1521a96f0ebaea2d77aeb986ff1b9b7d82fb0cbc63f9169a", - "sourceCodeHash": "0x81ba07ca8d0bedf3b0d0ff054d68fcc6dca52a4da0ca5c8624cee92f20a87c37" + "initCodeHash": "0x2e665d9ee554430980f64bcb6d2611a1cb03dbacfd58bb0d6f5d32951a267bde", + "sourceCodeHash": "0xe0bc805b22c7d04b5a9444cddd4c0e1bcb3006c69c03610494277ab2cc83f553" }, "src/periphery/op-nft/Optimist.sol": { - "initCodeHash": "0x468354be7d17863a587b1f1daf220c17697e57c76cba8e0082d7afec4aafea49", - "sourceCodeHash": "0x3ceeaab5b013968b226b3c97e202a3af4946590763b2002d1bc36ae8776c78fe" + "initCodeHash": "0x8fccdef5fb6e6d51215b39acc449faad8ba15416699c9b3af77866f4297805a3", + "sourceCodeHash": "0xfa9354827b642803e10415ed30ca789be1bd23d88fac14f7adaa65c6eb1c1643" }, "src/periphery/op-nft/OptimistAllowlist.sol": { - "initCodeHash": "0xbe1a89f077473c298ce96be5eb5e5a0ec97968f24c7ef843e1f9fee1c57087e4", - "sourceCodeHash": "0x077967c4c1b99396481c91464237e696f12974c864470b2ef39ffa3756a58ac0" + "initCodeHash": "0x166dd3fc18cb238895f2faa7fdd635af48ce2c54e21ed2d6dae857c3731c4d6c", + "sourceCodeHash": "0x3a5f61046f729c9a70274b8b2a739382987ec5eb77705b259e8a3210a5f43462" }, "src/periphery/op-nft/OptimistInviter.sol": { - "initCodeHash": "0xefc67e1be541adfc92f9a5bef36746477299f5e76a4601c12f802af52fb02253", - "sourceCodeHash": "0x323f707d4cebc38f59f9241098a1d7e5e790ffcaf1719065edabf4cb794ac745" + "initCodeHash": "0x28dfa6676702a7abd19609cc773158d1f958210bc0a38c008d67a002dc1df862", + "sourceCodeHash": "0x3a0a294932d6deba043f6a2b46b4e8477ee96e7fb054d7e7229a43ce4352c68d" }, "src/universal/OptimismMintableERC20.sol": { - "initCodeHash": "0x7c6e1cf86cf8622d8beceafa3610ff88eceb3b0fafff0491bfa26a7b876c4d9a", - "sourceCodeHash": "0x52737b23e99bf79dd2c23196b3298e80aa41f740efc6adc7916e696833eb546a" + "initCodeHash": "0xfc77e4db406c232d8b84a3f77b939fb08fa27852faa5f4b0d78d998402caf308", + "sourceCodeHash": "0xd7957c662ef03fc0cc3440a6ec6737a55f90b52a977262a260cd99fe96494267" }, "src/universal/OptimismMintableERC20Factory.sol": { - "initCodeHash": "0x66df8ec6699dbedc70da57358ec6031d1d90b3d6672990380f4eb3dbd9cf5385", - "sourceCodeHash": "0x1fc420719e4a6bc1f53dfc4a0ddaa14f129c16c0e99f98f253a2e3c85b72a540" + "initCodeHash": "0x1cc94179ce28fb34c8e28b8d2015b95588e93a45730dae9ee7da859a9f66e0e6", + "sourceCodeHash": "0x46d1d4a9ed1b1f4c60d42bf6c9982ffc72cbd759a4aae5246f89ccbb8699c2a1" }, "src/universal/OptimismMintableERC721.sol": { - "initCodeHash": "0xb400f430acf4d65bee9635e4935a6e1e3a0284fc50aea40ad8b7818dc826f31c", - "sourceCodeHash": "0xd4bb4d1e16f545976302109ab0234ae785afa52de820553d67ebd9f147e4b994" + "initCodeHash": "0x5a995fc043f8268a6d5c6284ad85b0de21328cd47277114aeba2c03484deaf91", + "sourceCodeHash": "0xbf186922941d49e75d25bcac2a480c3e3ffed9bdd79a3fdca5a6c79bcbe94735" }, "src/universal/OptimismMintableERC721Factory.sol": { - "initCodeHash": "0x5504069cb1377405bf5c6f1b37ea02057fdb452cf85922cc83dffd5390cad7da", - "sourceCodeHash": "0xf8f2f0f6bc3cdbacbb1ef8b3fa31897a1eb749af0ba14b19b0cbc1cf0e6271f8" + "initCodeHash": "0x9c6181eff40822a78562a30eaefb338c0841284e3b1036371348d185ec5e285f", + "sourceCodeHash": "0x8be6e661af4b8079567fb2cd368e0f6bf9c11185472c5a75bec1172820d553e0" }, "src/universal/StorageSetter.sol": { - "initCodeHash": "0xb656d2aa6aff3e6435e747a0c23236d1b66f1f5c0b45e4b1a10d290a90223c5a", - "sourceCodeHash": "0xebfc968e6b78d7ea355547d427300739f14d000a11ff35f29d9ded3ddb7882da" + "initCodeHash": "0x00b8b883597e67e5c3548e7ba4139ed720893c0acb217dd170bec520cefdfab5", + "sourceCodeHash": "0xf63aff9c38f4c5e9cdbd1f910bc002e16008a592d26c0dcc67929e0024638edd" } } \ No newline at end of file diff --git a/packages/contracts-bedrock/src/EAS/EAS.sol b/packages/contracts-bedrock/src/EAS/EAS.sol index 5307199be3b4..384ffdd0eb02 100644 --- a/packages/contracts-bedrock/src/EAS/EAS.sol +++ b/packages/contracts-bedrock/src/EAS/EAS.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.19; import { Address } from "@openzeppelin/contracts/utils/Address.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { EIP1271Verifier } from "src/EAS/eip1271/EIP1271Verifier.sol"; import { ISchemaResolver } from "src/EAS/resolver/ISchemaResolver.sol"; diff --git a/packages/contracts-bedrock/src/EAS/SchemaRegistry.sol b/packages/contracts-bedrock/src/EAS/SchemaRegistry.sol index 1a1d7c44553e..cfed1a928dba 100644 --- a/packages/contracts-bedrock/src/EAS/SchemaRegistry.sol +++ b/packages/contracts-bedrock/src/EAS/SchemaRegistry.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.19; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ISchemaResolver } from "src/EAS/resolver/ISchemaResolver.sol"; import { EMPTY_UID, MAX_GAP } from "src/EAS/Common.sol"; import { ISchemaRegistry, SchemaRecord } from "src/EAS/ISchemaRegistry.sol"; diff --git a/packages/contracts-bedrock/src/L1/DataAvailabilityChallenge.sol b/packages/contracts-bedrock/src/L1/DataAvailabilityChallenge.sol index ef4f473bc6a3..fa45c47b2d09 100644 --- a/packages/contracts-bedrock/src/L1/DataAvailabilityChallenge.sol +++ b/packages/contracts-bedrock/src/L1/DataAvailabilityChallenge.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { SafeCall } from "src/libraries/SafeCall.sol"; /// @dev An enum representing the status of a DA challenge. diff --git a/packages/contracts-bedrock/src/L1/DelayedVetoable.sol b/packages/contracts-bedrock/src/L1/DelayedVetoable.sol index abb40b9ce90f..113f8a03bea2 100644 --- a/packages/contracts-bedrock/src/L1/DelayedVetoable.sol +++ b/packages/contracts-bedrock/src/L1/DelayedVetoable.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @title DelayedVetoable /// @notice This contract enables a delay before a call is forwarded to a target contract, and during the delay period @@ -68,8 +68,8 @@ contract DelayedVetoable is ISemver { } /// @notice Semantic version. - /// @custom:semver 1.0.0 - string public constant version = "1.0.0"; + /// @custom:semver 1.0.1-beta.1 + string public constant version = "1.0.1-beta.1"; /// @notice Sets the target admin during contract deployment. /// @param vetoer_ Address of the vetoer. diff --git a/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol index 8ed2cde08f36..56d8218ac08c 100644 --- a/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol +++ b/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.15; import { Predeploys } from "src/libraries/Predeploys.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; diff --git a/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol b/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol index c080a67205dd..014a501f58c9 100644 --- a/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol +++ b/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.15; import { ERC721Bridge } from "src/universal/ERC721Bridge.sol"; import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol"; diff --git a/packages/contracts-bedrock/src/L1/L1StandardBridge.sol b/packages/contracts-bedrock/src/L1/L1StandardBridge.sol index 9b5610cf3a1d..107be4851e1e 100644 --- a/packages/contracts-bedrock/src/L1/L1StandardBridge.sol +++ b/packages/contracts-bedrock/src/L1/L1StandardBridge.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; import { Predeploys } from "src/libraries/Predeploys.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol"; diff --git a/packages/contracts-bedrock/src/L1/L2OutputOracle.sol b/packages/contracts-bedrock/src/L1/L2OutputOracle.sol index d329ff3eb1c9..b964664ab0cb 100644 --- a/packages/contracts-bedrock/src/L1/L2OutputOracle.sol +++ b/packages/contracts-bedrock/src/L1/L2OutputOracle.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { Types } from "src/libraries/Types.sol"; import { Constants } from "src/libraries/Constants.sol"; diff --git a/packages/contracts-bedrock/src/L1/OPStackManager.sol b/packages/contracts-bedrock/src/L1/OPStackManager.sol index b7da7bb358fb..bd798aa530b9 100644 --- a/packages/contracts-bedrock/src/L1/OPStackManager.sol +++ b/packages/contracts-bedrock/src/L1/OPStackManager.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; /// @custom:proxied true diff --git a/packages/contracts-bedrock/src/L1/OptimismPortal.sol b/packages/contracts-bedrock/src/L1/OptimismPortal.sol index b7515eed00cf..94931bdd2910 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortal.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortal.sol @@ -12,7 +12,7 @@ import { Hashing } from "src/libraries/Hashing.sol"; import { SecureMerkleTrie } from "src/libraries/trie/SecureMerkleTrie.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { L1Block } from "src/L2/L1Block.sol"; diff --git a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol index dda3df0d7400..ea1c4b602512 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol @@ -12,7 +12,7 @@ import { Hashing } from "src/libraries/Hashing.sol"; import { SecureMerkleTrie } from "src/libraries/trie/SecureMerkleTrie.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { Constants } from "src/libraries/Constants.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; diff --git a/packages/contracts-bedrock/src/L1/ProtocolVersions.sol b/packages/contracts-bedrock/src/L1/ProtocolVersions.sol index d6976b911d24..f988d43e1697 100644 --- a/packages/contracts-bedrock/src/L1/ProtocolVersions.sol +++ b/packages/contracts-bedrock/src/L1/ProtocolVersions.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { Storage } from "src/libraries/Storage.sol"; import { Constants } from "src/libraries/Constants.sol"; diff --git a/packages/contracts-bedrock/src/L1/SuperchainConfig.sol b/packages/contracts-bedrock/src/L1/SuperchainConfig.sol index cae10b331f6c..51b13936c81b 100644 --- a/packages/contracts-bedrock/src/L1/SuperchainConfig.sol +++ b/packages/contracts-bedrock/src/L1/SuperchainConfig.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { Storage } from "src/libraries/Storage.sol"; /// @custom:proxied true diff --git a/packages/contracts-bedrock/src/L1/SystemConfig.sol b/packages/contracts-bedrock/src/L1/SystemConfig.sol index 892d5dd2c2ab..d1dc30fb75ec 100644 --- a/packages/contracts-bedrock/src/L1/SystemConfig.sol +++ b/packages/contracts-bedrock/src/L1/SystemConfig.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { Storage } from "src/libraries/Storage.sol"; import { Constants } from "src/libraries/Constants.sol"; diff --git a/packages/contracts-bedrock/src/L2/BaseFeeVault.sol b/packages/contracts-bedrock/src/L2/BaseFeeVault.sol index f423cbe58dfe..2ae63efd599b 100644 --- a/packages/contracts-bedrock/src/L2/BaseFeeVault.sol +++ b/packages/contracts-bedrock/src/L2/BaseFeeVault.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { FeeVault } from "src/universal/FeeVault.sol"; /// @custom:proxied true diff --git a/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol b/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol index 3c5a9a814e67..d662fec3f28c 100644 --- a/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol +++ b/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol @@ -3,8 +3,8 @@ pragma solidity 0.8.25; import { Predeploys } from "src/libraries/Predeploys.sol"; import { TransientContext, TransientReentrancyAware } from "src/libraries/TransientContext.sol"; -import { ISemver } from "src/universal/ISemver.sol"; -import { ICrossL2Inbox } from "src/L2/ICrossL2Inbox.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { ICrossL2Inbox } from "src/L2/interfaces/ICrossL2Inbox.sol"; import { SafeCall } from "src/libraries/SafeCall.sol"; import { IDependencySet } from "src/L2/interfaces/IDependencySet.sol"; diff --git a/packages/contracts-bedrock/src/L2/ETHLiquidity.sol b/packages/contracts-bedrock/src/L2/ETHLiquidity.sol index 4dd4c4b57eb5..881b2b28a45a 100644 --- a/packages/contracts-bedrock/src/L2/ETHLiquidity.sol +++ b/packages/contracts-bedrock/src/L2/ETHLiquidity.sol @@ -5,7 +5,7 @@ import { Unauthorized, NotCustomGasToken } from "src/libraries/errors/CommonErro import { Predeploys } from "src/libraries/Predeploys.sol"; import { L1Block } from "src/L2/L1Block.sol"; import { SafeSend } from "src/universal/SafeSend.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @title ETHLiquidity /// @notice The ETHLiquidity contract allows other contracts to access ETH liquidity without @@ -18,8 +18,8 @@ contract ETHLiquidity is ISemver { event LiquidityMinted(address indexed caller, uint256 value); /// @notice Semantic version. - /// @custom:semver 1.0.0-beta.1 - string public constant version = "1.0.0-beta.1"; + /// @custom:semver 1.0.0-beta.2 + string public constant version = "1.0.0-beta.2"; /// @notice Allows an address to lock ETH liquidity into this contract. function burn() external payable { diff --git a/packages/contracts-bedrock/src/L2/GasPriceOracle.sol b/packages/contracts-bedrock/src/L2/GasPriceOracle.sol index 8a2c20a5c325..63a58038eab5 100644 --- a/packages/contracts-bedrock/src/L2/GasPriceOracle.sol +++ b/packages/contracts-bedrock/src/L2/GasPriceOracle.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { L1Block } from "src/L2/L1Block.sol"; import { Constants } from "src/libraries/Constants.sol"; diff --git a/packages/contracts-bedrock/src/L2/L1Block.sol b/packages/contracts-bedrock/src/L2/L1Block.sol index 16e2f6b26746..f3c86e248c2c 100644 --- a/packages/contracts-bedrock/src/L2/L1Block.sol +++ b/packages/contracts-bedrock/src/L2/L1Block.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { Constants } from "src/libraries/Constants.sol"; import { GasPayingToken, IGasToken } from "src/libraries/GasPayingToken.sol"; import "src/libraries/L1BlockErrors.sol"; diff --git a/packages/contracts-bedrock/src/L2/L1FeeVault.sol b/packages/contracts-bedrock/src/L2/L1FeeVault.sol index c8beba84afa1..d62db2a25c3b 100644 --- a/packages/contracts-bedrock/src/L2/L1FeeVault.sol +++ b/packages/contracts-bedrock/src/L2/L1FeeVault.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { FeeVault } from "src/universal/FeeVault.sol"; /// @custom:proxied true diff --git a/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol index b3e25c763343..23c71d3109dd 100644 --- a/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol +++ b/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.15; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; import { Constants } from "src/libraries/Constants.sol"; import { L1Block } from "src/L2/L1Block.sol"; diff --git a/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol b/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol index 1a1c9fd0f4e8..66fa24c3ef49 100644 --- a/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol +++ b/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol @@ -4,9 +4,9 @@ pragma solidity 0.8.15; import { ERC721Bridge } from "src/universal/ERC721Bridge.sol"; import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; -import { IOptimismMintableERC721 } from "src/universal/IOptimismMintableERC721.sol"; +import { IOptimismMintableERC721 } from "src/universal/interfaces/IOptimismMintableERC721.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { Constants } from "src/libraries/Constants.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; diff --git a/packages/contracts-bedrock/src/L2/L2StandardBridge.sol b/packages/contracts-bedrock/src/L2/L2StandardBridge.sol index 55ffc3d541fe..4ba8c62f863c 100644 --- a/packages/contracts-bedrock/src/L2/L2StandardBridge.sol +++ b/packages/contracts-bedrock/src/L2/L2StandardBridge.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; import { Predeploys } from "src/libraries/Predeploys.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { L1Block } from "src/L2/L1Block.sol"; diff --git a/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol b/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol index 2aad93a67e6c..f7a82fc2af3f 100644 --- a/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol +++ b/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol @@ -5,7 +5,7 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; -import { IOptimismERC20Factory } from "src/L2/IOptimismERC20Factory.sol"; +import { IOptimismERC20Factory } from "src/L2/interfaces/IOptimismERC20Factory.sol"; /// @notice Thrown when the decimals of the tokens are not the same. error InvalidDecimals(); diff --git a/packages/contracts-bedrock/src/L2/L2ToL1MessagePasser.sol b/packages/contracts-bedrock/src/L2/L2ToL1MessagePasser.sol index 460b66ebc051..94b8213983e1 100644 --- a/packages/contracts-bedrock/src/L2/L2ToL1MessagePasser.sol +++ b/packages/contracts-bedrock/src/L2/L2ToL1MessagePasser.sol @@ -5,7 +5,7 @@ import { Types } from "src/libraries/Types.sol"; import { Hashing } from "src/libraries/Hashing.sol"; import { Encoding } from "src/libraries/Encoding.sol"; import { Burn } from "src/libraries/Burn.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000016 diff --git a/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol index d827e4feb86e..4570e8191ca6 100644 --- a/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol +++ b/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol @@ -4,8 +4,8 @@ pragma solidity 0.8.25; import { Encoding } from "src/libraries/Encoding.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { CrossL2Inbox } from "src/L2/CrossL2Inbox.sol"; -import { IL2ToL2CrossDomainMessenger } from "src/L2/IL2ToL2CrossDomainMessenger.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { SafeCall } from "src/libraries/SafeCall.sol"; import { TransientReentrancyAware } from "src/libraries/TransientContext.sol"; diff --git a/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol b/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol index 75c6e22b3771..731657e900fc 100644 --- a/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol +++ b/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.25; -import { IOptimismSuperchainERC20Extension } from "src/L2/IOptimismSuperchainERC20.sol"; +import { IOptimismSuperchainERC20Extension } from "src/L2/interfaces/IOptimismSuperchainERC20.sol"; import { ERC20 } from "@solady/tokens/ERC20.sol"; -import { IL2ToL2CrossDomainMessenger } from "src/L2/IL2ToL2CrossDomainMessenger.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { Initializable } from "@openzeppelin/contracts-v5/proxy/utils/Initializable.sol"; import { ERC165 } from "@openzeppelin/contracts-v5/utils/introspection/ERC165.sol"; diff --git a/packages/contracts-bedrock/src/L2/SequencerFeeVault.sol b/packages/contracts-bedrock/src/L2/SequencerFeeVault.sol index 208c8f367677..fecbb7e1b7cd 100644 --- a/packages/contracts-bedrock/src/L2/SequencerFeeVault.sol +++ b/packages/contracts-bedrock/src/L2/SequencerFeeVault.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { FeeVault } from "src/universal/FeeVault.sol"; /// @custom:proxied true diff --git a/packages/contracts-bedrock/src/L2/SuperchainWETH.sol b/packages/contracts-bedrock/src/L2/SuperchainWETH.sol index 7080460254fc..d471882b5385 100644 --- a/packages/contracts-bedrock/src/L2/SuperchainWETH.sol +++ b/packages/contracts-bedrock/src/L2/SuperchainWETH.sol @@ -5,10 +5,10 @@ import { WETH98 } from "src/dispute/weth/WETH98.sol"; import { Unauthorized, NotCustomGasToken } from "src/libraries/errors/CommonErrors.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { L1Block } from "src/L2/L1Block.sol"; -import { IL2ToL2CrossDomainMessenger } from "src/L2/IL2ToL2CrossDomainMessenger.sol"; +import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; import { ETHLiquidity } from "src/L2/ETHLiquidity.sol"; -import { ISuperchainERC20Extensions } from "src/L2/ISuperchainERC20.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISuperchainERC20Extensions } from "src/L2/interfaces/ISuperchainERC20.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @title SuperchainWETH /// @notice SuperchainWETH is a version of WETH that can be freely transfrered between chains @@ -16,8 +16,8 @@ import { ISemver } from "src/universal/ISemver.sol"; /// do not use a custom gas token. contract SuperchainWETH is WETH98, ISuperchainERC20Extensions, ISemver { /// @notice Semantic version. - /// @custom:semver 1.0.0-beta.1 - string public constant version = "1.0.0-beta.1"; + /// @custom:semver 1.0.0-beta.2 + string public constant version = "1.0.0-beta.2"; /// @inheritdoc WETH98 function deposit() public payable override { diff --git a/packages/contracts-bedrock/src/L2/WETH.sol b/packages/contracts-bedrock/src/L2/WETH.sol index 42b957f45e95..db4df18932b3 100644 --- a/packages/contracts-bedrock/src/L2/WETH.sol +++ b/packages/contracts-bedrock/src/L2/WETH.sol @@ -4,13 +4,13 @@ pragma solidity 0.8.15; import { WETH98 } from "src/dispute/weth/WETH98.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { L1Block } from "src/L2/L1Block.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @title WETH contract that reads the name and symbol from the L1Block contract. /// Allows for nice rendering of token names for chains using custom gas token. contract WETH is WETH98, ISemver { - /// @custom:semver 1.0.0 - string public constant version = "1.0.0"; + /// @custom:semver 1.0.0-beta.1 + string public constant version = "1.0.0-beta.1"; /// @notice Returns the name of the wrapped native asset. Will be "Wrapped Ether" /// if the native asset is Ether. diff --git a/packages/contracts-bedrock/src/L2/ICrossL2Inbox.sol b/packages/contracts-bedrock/src/L2/interfaces/ICrossL2Inbox.sol similarity index 100% rename from packages/contracts-bedrock/src/L2/ICrossL2Inbox.sol rename to packages/contracts-bedrock/src/L2/interfaces/ICrossL2Inbox.sol diff --git a/packages/contracts-bedrock/src/L2/IL2ToL2CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol similarity index 100% rename from packages/contracts-bedrock/src/L2/IL2ToL2CrossDomainMessenger.sol rename to packages/contracts-bedrock/src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol diff --git a/packages/contracts-bedrock/src/L2/IOptimismERC20Factory.sol b/packages/contracts-bedrock/src/L2/interfaces/IOptimismERC20Factory.sol similarity index 100% rename from packages/contracts-bedrock/src/L2/IOptimismERC20Factory.sol rename to packages/contracts-bedrock/src/L2/interfaces/IOptimismERC20Factory.sol diff --git a/packages/contracts-bedrock/src/L2/IOptimismSuperchainERC20.sol b/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20.sol similarity index 100% rename from packages/contracts-bedrock/src/L2/IOptimismSuperchainERC20.sol rename to packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20.sol diff --git a/packages/contracts-bedrock/src/L2/ISuperchainERC20.sol b/packages/contracts-bedrock/src/L2/interfaces/ISuperchainERC20.sol similarity index 100% rename from packages/contracts-bedrock/src/L2/ISuperchainERC20.sol rename to packages/contracts-bedrock/src/L2/interfaces/ISuperchainERC20.sol diff --git a/packages/contracts-bedrock/src/Safe/DeputyGuardianModule.sol b/packages/contracts-bedrock/src/Safe/DeputyGuardianModule.sol index 485af22738eb..abb3a7aaa9ca 100644 --- a/packages/contracts-bedrock/src/Safe/DeputyGuardianModule.sol +++ b/packages/contracts-bedrock/src/Safe/DeputyGuardianModule.sol @@ -8,7 +8,7 @@ import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol" import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { Unauthorized } from "src/libraries/PortalErrors.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; @@ -45,8 +45,8 @@ contract DeputyGuardianModule is ISemver { address internal immutable DEPUTY_GUARDIAN; /// @notice Semantic version. - /// @custom:semver 2.0.0-rc.1 - string public constant version = "2.0.0-rc.1"; + /// @custom:semver 2.0.1-beta.1 + string public constant version = "2.0.1-beta.1"; // Constructor to initialize the Safe and baseModule instances constructor(Safe _safe, SuperchainConfig _superchainConfig, address _deputyGuardian) { diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index 59b431de126a..f6bfb6aaf8eb 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -5,7 +5,7 @@ import { GnosisSafe as Safe } from "safe-contracts/GnosisSafe.sol"; import { Guard as BaseGuard } from "safe-contracts/base/GuardManager.sol"; import { SafeSigners } from "src/Safe/SafeSigners.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; /// @title LivenessGuard @@ -25,8 +25,8 @@ contract LivenessGuard is ISemver, BaseGuard { event OwnerRecorded(address owner); /// @notice Semantic version. - /// @custom:semver 1.0.0 - string public constant version = "1.0.0"; + /// @custom:semver 1.0.1-beta.1 + string public constant version = "1.0.1-beta.1"; /// @notice The safe account for which this contract will be the guard. Safe internal immutable SAFE; diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 17ec33f1a884..cf0eab99b8c2 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -5,7 +5,7 @@ import { GnosisSafe as Safe } from "safe-contracts/GnosisSafe.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; import { OwnerManager } from "safe-contracts/base/OwnerManager.sol"; import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @title LivenessModule /// @notice This module is intended to be used in conjunction with the LivenessGuard. In the event @@ -53,8 +53,8 @@ contract LivenessModule is ISemver { uint256 internal constant GUARD_STORAGE_SLOT = 0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8; /// @notice Semantic version. - /// @custom:semver 1.1.0 - string public constant version = "1.2.0"; + /// @custom:semver 1.2.1-beta.1 + string public constant version = "1.2.1-beta.1"; // Constructor to initialize the Safe and baseModule instances constructor( diff --git a/packages/contracts-bedrock/src/cannon/MIPS.sol b/packages/contracts-bedrock/src/cannon/MIPS.sol index 3ecbf2a2751e..a81abf5cc734 100644 --- a/packages/contracts-bedrock/src/cannon/MIPS.sol +++ b/packages/contracts-bedrock/src/cannon/MIPS.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { IPreimageOracle } from "./interfaces/IPreimageOracle.sol"; import { PreimageKeyLib } from "./PreimageKeyLib.sol"; import { MIPSInstructions as ins } from "src/cannon/libraries/MIPSInstructions.sol"; @@ -44,8 +44,8 @@ contract MIPS is ISemver { } /// @notice The semantic version of the MIPS contract. - /// @custom:semver 1.1.0-rc.1 - string public constant version = "1.1.0-rc.1"; + /// @custom:semver 1.1.1-beta.1 + string public constant version = "1.1.1-beta.1"; /// @notice The preimage oracle contract. IPreimageOracle internal immutable ORACLE; diff --git a/packages/contracts-bedrock/src/cannon/MIPS2.sol b/packages/contracts-bedrock/src/cannon/MIPS2.sol index 2f1e10e8b20e..da6c56b6f207 100644 --- a/packages/contracts-bedrock/src/cannon/MIPS2.sol +++ b/packages/contracts-bedrock/src/cannon/MIPS2.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { IPreimageOracle } from "./interfaces/IPreimageOracle.sol"; import { MIPSMemory } from "src/cannon/libraries/MIPSMemory.sol"; import { MIPSSyscalls as sys } from "src/cannon/libraries/MIPSSyscalls.sol"; diff --git a/packages/contracts-bedrock/src/cannon/PreimageOracle.sol b/packages/contracts-bedrock/src/cannon/PreimageOracle.sol index e144e43d8d4c..c3a43f02c441 100644 --- a/packages/contracts-bedrock/src/cannon/PreimageOracle.sol +++ b/packages/contracts-bedrock/src/cannon/PreimageOracle.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { IPreimageOracle } from "./interfaces/IPreimageOracle.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { PreimageKeyLib } from "./PreimageKeyLib.sol"; import { LibKeccak } from "@lib-keccak/LibKeccak.sol"; import "src/cannon/libraries/CannonErrors.sol"; @@ -31,8 +31,8 @@ contract PreimageOracle is IPreimageOracle, ISemver { uint256 public constant PRECOMPILE_CALL_RESERVED_GAS = 100_000; /// @notice The semantic version of the Preimage Oracle contract. - /// @custom:semver 1.1.2-rc.1 - string public constant version = "1.1.2-rc.1"; + /// @custom:semver 1.1.3-beta.1 + string public constant version = "1.1.3-beta.1"; //////////////////////////////////////////////////////////////// // Authorized Preimage Parts // diff --git a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS.sol b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS.sol index 9617ddb9c010..e98628c3eb5a 100644 --- a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS.sol +++ b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol"; /// @title IMIPS diff --git a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol index 2d53020f45ac..0e4f9b5eaa55 100644 --- a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol +++ b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @title IMIPS2 /// @notice Interface for the MIPS2 contract. diff --git a/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol b/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol index 3d456eb0fd38..9ac81302991a 100644 --- a/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol +++ b/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; diff --git a/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol b/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol index 90b5754486f9..b9d384dd4483 100644 --- a/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol +++ b/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; import { LibClone } from "@solady/utils/LibClone.sol"; import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol"; diff --git a/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol b/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol index d9153a0b7601..a798df792b4f 100644 --- a/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol +++ b/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol @@ -13,7 +13,7 @@ import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistr import { Clone } from "@solady/utils/Clone.sol"; import { Types } from "src/libraries/Types.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { Types } from "src/libraries/Types.sol"; import { Hashing } from "src/libraries/Hashing.sol"; @@ -70,8 +70,8 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { uint256 internal constant HEADER_BLOCK_NUMBER_INDEX = 8; /// @notice Semantic version. - /// @custom:semver 1.3.0-rc.1 - string public constant version = "1.3.0-rc.1"; + /// @custom:semver 1.3.1-beta.1 + string public constant version = "1.3.1-beta.1"; /// @notice The starting timestamp of the game Timestamp public createdAt; diff --git a/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol b/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol index 2f875ced7865..144d8d451798 100644 --- a/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol +++ b/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; import { IWETH } from "src/dispute/interfaces/IWETH.sol"; diff --git a/packages/contracts-bedrock/src/legacy/DeployerWhitelist.sol b/packages/contracts-bedrock/src/legacy/DeployerWhitelist.sol index 38a506c2b251..a7a6313edf4b 100644 --- a/packages/contracts-bedrock/src/legacy/DeployerWhitelist.sol +++ b/packages/contracts-bedrock/src/legacy/DeployerWhitelist.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @custom:legacy true /// @custom:proxied true diff --git a/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol b/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol index 634361c51524..9e98a76b18b1 100644 --- a/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol +++ b/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; import { L1Block } from "src/L2/L1Block.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @custom:legacy true /// @custom:proxied true diff --git a/packages/contracts-bedrock/src/legacy/LegacyMessagePasser.sol b/packages/contracts-bedrock/src/legacy/LegacyMessagePasser.sol index 59a3f9fa3cd7..b90d1263f7a9 100644 --- a/packages/contracts-bedrock/src/legacy/LegacyMessagePasser.sol +++ b/packages/contracts-bedrock/src/legacy/LegacyMessagePasser.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @custom:legacy true /// @custom:proxied true diff --git a/packages/contracts-bedrock/src/legacy/interfaces/IDeployerWhitelist.sol b/packages/contracts-bedrock/src/legacy/interfaces/IDeployerWhitelist.sol index 6914eefabb3d..050748f1786e 100644 --- a/packages/contracts-bedrock/src/legacy/interfaces/IDeployerWhitelist.sol +++ b/packages/contracts-bedrock/src/legacy/interfaces/IDeployerWhitelist.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @title IDeployerWhitelist /// @notice Interface for the DeployerWhitelist contract. diff --git a/packages/contracts-bedrock/src/legacy/interfaces/IL1BlockNumber.sol b/packages/contracts-bedrock/src/legacy/interfaces/IL1BlockNumber.sol index 1b59b53e396f..7634cc67c690 100644 --- a/packages/contracts-bedrock/src/legacy/interfaces/IL1BlockNumber.sol +++ b/packages/contracts-bedrock/src/legacy/interfaces/IL1BlockNumber.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @title IL1BlockNumber /// @notice Interface for the L1BlockNumber contract. diff --git a/packages/contracts-bedrock/src/legacy/interfaces/ILegacyMessagePasser.sol b/packages/contracts-bedrock/src/legacy/interfaces/ILegacyMessagePasser.sol index 79e03871f236..a5fde0fdb65d 100644 --- a/packages/contracts-bedrock/src/legacy/interfaces/ILegacyMessagePasser.sol +++ b/packages/contracts-bedrock/src/legacy/interfaces/ILegacyMessagePasser.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @title ILegacyMessagePasser /// @notice Interface for the LegacyMessagePasser contract. diff --git a/packages/contracts-bedrock/src/periphery/op-nft/AttestationStation.sol b/packages/contracts-bedrock/src/periphery/op-nft/AttestationStation.sol index b9af730a71d4..4d15862d4358 100644 --- a/packages/contracts-bedrock/src/periphery/op-nft/AttestationStation.sol +++ b/packages/contracts-bedrock/src/periphery/op-nft/AttestationStation.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @title AttestationStation /// @author Optimism Collective @@ -29,8 +29,8 @@ contract AttestationStation is ISemver { event AttestationCreated(address indexed creator, address indexed about, bytes32 indexed key, bytes val); /// @notice Semantic version. - /// @custom:semver 1.2.0 - string public constant version = "1.2.0"; + /// @custom:semver 1.2.1-beta.1 + string public constant version = "1.2.1-beta.1"; /// @notice Allows anyone to create an attestation. /// @param _about Address that the attestation is about. diff --git a/packages/contracts-bedrock/src/periphery/op-nft/Optimist.sol b/packages/contracts-bedrock/src/periphery/op-nft/Optimist.sol index 74d04b087d86..b15c0f00044c 100644 --- a/packages/contracts-bedrock/src/periphery/op-nft/Optimist.sol +++ b/packages/contracts-bedrock/src/periphery/op-nft/Optimist.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ERC721BurnableUpgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol"; import { AttestationStation } from "src/periphery/op-nft/AttestationStation.sol"; @@ -26,8 +26,8 @@ contract Optimist is ERC721BurnableUpgradeable, ISemver { OptimistAllowlist public immutable OPTIMIST_ALLOWLIST; /// @notice Semantic version. - /// @custom:semver 2.1.0 - string public constant version = "2.1.0"; + /// @custom:semver 2.1.1-beta.1 + string public constant version = "2.1.1-beta.1"; /// @param _name Token name. /// @param _symbol Token symbol. diff --git a/packages/contracts-bedrock/src/periphery/op-nft/OptimistAllowlist.sol b/packages/contracts-bedrock/src/periphery/op-nft/OptimistAllowlist.sol index b8212a37c674..ffa46116a4c5 100644 --- a/packages/contracts-bedrock/src/periphery/op-nft/OptimistAllowlist.sol +++ b/packages/contracts-bedrock/src/periphery/op-nft/OptimistAllowlist.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { AttestationStation } from "src/periphery/op-nft/AttestationStation.sol"; import { OptimistConstants } from "src/periphery/op-nft/libraries/OptimistConstants.sol"; @@ -31,8 +31,8 @@ contract OptimistAllowlist is ISemver { address public immutable OPTIMIST_INVITER; /// @notice Semantic version. - /// @custom:semver 1.1.0 - string public constant version = "1.1.0"; + /// @custom:semver 1.1.1-beta.1 + string public constant version = "1.1.1-beta.1"; /// @param _attestationStation Address of the AttestationStation contract. /// @param _allowlistAttestor Address of the allowlist attestor. diff --git a/packages/contracts-bedrock/src/periphery/op-nft/OptimistInviter.sol b/packages/contracts-bedrock/src/periphery/op-nft/OptimistInviter.sol index 222405d77c33..ae0ab9d92657 100644 --- a/packages/contracts-bedrock/src/periphery/op-nft/OptimistInviter.sol +++ b/packages/contracts-bedrock/src/periphery/op-nft/OptimistInviter.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { OptimistConstants } from "src/periphery/op-nft/libraries/OptimistConstants.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { AttestationStation } from "src/periphery/op-nft/AttestationStation.sol"; import { SignatureChecker } from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; import { EIP712Upgradeable } from "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol"; @@ -88,8 +88,8 @@ contract OptimistInviter is ISemver, EIP712Upgradeable { mapping(address => uint256) public inviteCounts; /// @notice Semantic version. - /// @custom:semver 1.1.0 - string public constant version = "1.1.0"; + /// @custom:semver 1.1.1-beta.1 + string public constant version = "1.1.1-beta.1"; /// @param _inviteGranter Address of the invite granter. /// @param _attestationStation Address of the AttestationStation contract. diff --git a/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol b/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol index 43ddd65424f8..dd207caf167f 100644 --- a/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol +++ b/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol @@ -3,8 +3,8 @@ pragma solidity 0.8.15; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; -import { ILegacyMintableERC20, IOptimismMintableERC20 } from "src/universal/IOptimismMintableERC20.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ILegacyMintableERC20, IOptimismMintableERC20 } from "src/universal/interfaces/IOptimismMintableERC20.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @title OptimismMintableERC20 /// @notice OptimismMintableERC20 is a standard extension of the base ERC20 token contract designed @@ -39,8 +39,8 @@ contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, } /// @notice Semantic version. - /// @custom:semver 1.3.0 - string public constant version = "1.3.0"; + /// @custom:semver 1.3.1-beta.1 + string public constant version = "1.3.1-beta.1"; /// @param _bridge Address of the L2 standard bridge. /// @param _remoteToken Address of the corresponding L1 token. diff --git a/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol b/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol index 7f1a2717a449..790c1f828dfb 100644 --- a/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol +++ b/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol @@ -2,9 +2,9 @@ pragma solidity 0.8.15; import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; -import { IOptimismERC20Factory } from "src/L2/IOptimismERC20Factory.sol"; +import { IOptimismERC20Factory } from "src/L2/interfaces/IOptimismERC20Factory.sol"; /// @custom:proxied true /// @custom:predeployed 0x4200000000000000000000000000000000000012 diff --git a/packages/contracts-bedrock/src/universal/OptimismMintableERC721.sol b/packages/contracts-bedrock/src/universal/OptimismMintableERC721.sol index 025b5b14bde3..63e8f72460f0 100644 --- a/packages/contracts-bedrock/src/universal/OptimismMintableERC721.sol +++ b/packages/contracts-bedrock/src/universal/OptimismMintableERC721.sol @@ -5,8 +5,8 @@ import { ERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extension import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; -import { IOptimismMintableERC721 } from "src/universal/IOptimismMintableERC721.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { IOptimismMintableERC721 } from "src/universal/interfaces/IOptimismMintableERC721.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @title OptimismMintableERC721 /// @notice This contract is the remote representation for some token that lives on another network, @@ -32,8 +32,8 @@ contract OptimismMintableERC721 is ERC721Enumerable, IOptimismMintableERC721, IS } /// @notice Semantic version. - /// @custom:semver 1.3.0 - string public constant version = "1.3.0"; + /// @custom:semver 1.3.1-beta.1 + string public constant version = "1.3.1-beta.1"; /// @param _bridge Address of the bridge on this network. /// @param _remoteChainId Chain ID where the remote token is deployed. diff --git a/packages/contracts-bedrock/src/universal/OptimismMintableERC721Factory.sol b/packages/contracts-bedrock/src/universal/OptimismMintableERC721Factory.sol index 9d9cd62c48d6..bb84504868f3 100644 --- a/packages/contracts-bedrock/src/universal/OptimismMintableERC721Factory.sol +++ b/packages/contracts-bedrock/src/universal/OptimismMintableERC721Factory.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { OptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol"; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @title OptimismMintableERC721Factory /// @notice Factory contract for creating OptimismMintableERC721 contracts. @@ -23,8 +23,8 @@ contract OptimismMintableERC721Factory is ISemver { event OptimismMintableERC721Created(address indexed localToken, address indexed remoteToken, address deployer); /// @notice Semantic version. - /// @custom:semver 1.4.0 - string public constant version = "1.4.0"; + /// @custom:semver 1.4.1-beta.1 + string public constant version = "1.4.1-beta.1"; /// @notice The semver MUST be bumped any time that there is a change in /// the OptimismMintableERC721 token contract since this contract diff --git a/packages/contracts-bedrock/src/universal/StandardBridge.sol b/packages/contracts-bedrock/src/universal/StandardBridge.sol index 140aba531e61..92440fdbad38 100644 --- a/packages/contracts-bedrock/src/universal/StandardBridge.sol +++ b/packages/contracts-bedrock/src/universal/StandardBridge.sol @@ -6,7 +6,7 @@ import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC16 import { Address } from "@openzeppelin/contracts/utils/Address.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { SafeCall } from "src/libraries/SafeCall.sol"; -import { IOptimismMintableERC20, ILegacyMintableERC20 } from "src/universal/IOptimismMintableERC20.sol"; +import { IOptimismMintableERC20, ILegacyMintableERC20 } from "src/universal/interfaces/IOptimismMintableERC20.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; diff --git a/packages/contracts-bedrock/src/universal/StorageSetter.sol b/packages/contracts-bedrock/src/universal/StorageSetter.sol index 53b8ab2affd5..b7f7614b4ea0 100644 --- a/packages/contracts-bedrock/src/universal/StorageSetter.sol +++ b/packages/contracts-bedrock/src/universal/StorageSetter.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { ISemver } from "src/universal/ISemver.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { Storage } from "src/libraries/Storage.sol"; /// @title StorageSetter @@ -16,8 +16,8 @@ contract StorageSetter is ISemver { } /// @notice Semantic version. - /// @custom:semver 1.2.0 - string public constant version = "1.2.0"; + /// @custom:semver 1.2.1-beta.1 + string public constant version = "1.2.1-beta.1"; /// @notice Stores a bytes32 `_value` at `_slot`. Any storage slots that /// are packed should be set through this interface. diff --git a/packages/contracts-bedrock/src/universal/IOptimismMintableERC20.sol b/packages/contracts-bedrock/src/universal/interfaces/IOptimismMintableERC20.sol similarity index 100% rename from packages/contracts-bedrock/src/universal/IOptimismMintableERC20.sol rename to packages/contracts-bedrock/src/universal/interfaces/IOptimismMintableERC20.sol diff --git a/packages/contracts-bedrock/src/universal/IOptimismMintableERC721.sol b/packages/contracts-bedrock/src/universal/interfaces/IOptimismMintableERC721.sol similarity index 100% rename from packages/contracts-bedrock/src/universal/IOptimismMintableERC721.sol rename to packages/contracts-bedrock/src/universal/interfaces/IOptimismMintableERC721.sol diff --git a/packages/contracts-bedrock/src/universal/ISemver.sol b/packages/contracts-bedrock/src/universal/interfaces/ISemver.sol similarity index 100% rename from packages/contracts-bedrock/src/universal/ISemver.sol rename to packages/contracts-bedrock/src/universal/interfaces/ISemver.sol diff --git a/packages/contracts-bedrock/test/L2/CrossL2Inbox.t.sol b/packages/contracts-bedrock/test/L2/CrossL2Inbox.t.sol index 12b24ae1d479..51759c7ce9b8 100644 --- a/packages/contracts-bedrock/test/L2/CrossL2Inbox.t.sol +++ b/packages/contracts-bedrock/test/L2/CrossL2Inbox.t.sol @@ -18,7 +18,7 @@ import { NotDepositor, InteropStartAlreadySet } from "src/L2/CrossL2Inbox.sol"; -import { ICrossL2Inbox } from "src/L2/ICrossL2Inbox.sol"; +import { ICrossL2Inbox } from "src/L2/interfaces/ICrossL2Inbox.sol"; /// @title CrossL2InboxWithModifiableTransientStorage /// @dev CrossL2Inbox contract with methods to modify the transient storage. diff --git a/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol b/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol index 0fe37f2cf7c2..57c95147314d 100644 --- a/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol +++ b/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol @@ -16,7 +16,7 @@ import { } from "src/L2/L2StandardBridgeInterop.sol"; import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; -import { IOptimismMintableERC20 } from "src/universal/IOptimismMintableERC20.sol"; +import { IOptimismMintableERC20 } from "src/universal/interfaces/IOptimismMintableERC20.sol"; import { ILegacyMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; // TODO: Replace Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY with optimismSuperchainERC20Factory diff --git a/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20.t.sol b/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20.t.sol index 84580fdd8687..0e82aca948a2 100644 --- a/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20.t.sol +++ b/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20.t.sol @@ -7,7 +7,7 @@ import { Test } from "forge-std/Test.sol"; // Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; import { IERC20 } from "@openzeppelin/contracts-v5/token/ERC20/IERC20.sol"; -import { IL2ToL2CrossDomainMessenger } from "src/L2/IL2ToL2CrossDomainMessenger.sol"; +import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; import { ERC1967Proxy } from "@openzeppelin/contracts-v5/proxy/ERC1967/ERC1967Proxy.sol"; import { Initializable } from "@openzeppelin/contracts-v5/proxy/utils/Initializable.sol"; import { IERC165 } from "@openzeppelin/contracts-v5/utils/introspection/IERC165.sol"; @@ -21,7 +21,7 @@ import { OnlyBridge, ZeroAddress } from "src/L2/OptimismSuperchainERC20.sol"; -import { ISuperchainERC20Extensions } from "src/L2/ISuperchainERC20.sol"; +import { ISuperchainERC20Extensions } from "src/L2/interfaces/ISuperchainERC20.sol"; /// @title OptimismSuperchainERC20Test /// @notice Contract for testing the OptimismSuperchainERC20 contract. diff --git a/packages/contracts-bedrock/test/L2/SuperchainWETH.t.sol b/packages/contracts-bedrock/test/L2/SuperchainWETH.t.sol index d75734b2c776..f01a90f7aec0 100644 --- a/packages/contracts-bedrock/test/L2/SuperchainWETH.t.sol +++ b/packages/contracts-bedrock/test/L2/SuperchainWETH.t.sol @@ -7,7 +7,7 @@ import { CommonTest } from "test/setup/CommonTest.sol"; // Contract imports import { Unauthorized, NotCustomGasToken } from "src/libraries/errors/CommonErrors.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; -import { IL2ToL2CrossDomainMessenger } from "src/L2/IL2ToL2CrossDomainMessenger.sol"; +import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; import { ETHLiquidity } from "src/L2/ETHLiquidity.sol"; /// @title SuperchainWETH_Test diff --git a/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20.t.sol b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20.t.sol index 70081560c59f..673df66a4c20 100644 --- a/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20.t.sol +++ b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20.t.sol @@ -8,7 +8,7 @@ import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; // Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; import { OptimismSuperchainERC20 } from "src/L2/OptimismSuperchainERC20.sol"; -import { IL2ToL2CrossDomainMessenger } from "src/L2/IL2ToL2CrossDomainMessenger.sol"; +import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; /// @title OptimismSuperchainERC20_User /// @notice Actor contract that interacts with the OptimismSuperchainERC20 contract. diff --git a/packages/contracts-bedrock/test/invariants/SuperchainWETH.t.sol b/packages/contracts-bedrock/test/invariants/SuperchainWETH.t.sol index aeb250bcc36a..4d3d39724f1f 100644 --- a/packages/contracts-bedrock/test/invariants/SuperchainWETH.t.sol +++ b/packages/contracts-bedrock/test/invariants/SuperchainWETH.t.sol @@ -6,7 +6,7 @@ import { Vm } from "forge-std/Vm.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { SuperchainWETH } from "src/L2/SuperchainWETH.sol"; -import { IL2ToL2CrossDomainMessenger } from "src/L2/IL2ToL2CrossDomainMessenger.sol"; +import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; import { CommonTest } from "test/setup/CommonTest.sol"; diff --git a/packages/contracts-bedrock/test/universal/OptimismMintableERC20.t.sol b/packages/contracts-bedrock/test/universal/OptimismMintableERC20.t.sol index 985b7bad8eb9..fcacc13a05f7 100644 --- a/packages/contracts-bedrock/test/universal/OptimismMintableERC20.t.sol +++ b/packages/contracts-bedrock/test/universal/OptimismMintableERC20.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; -import { ILegacyMintableERC20, IOptimismMintableERC20 } from "src/universal/IOptimismMintableERC20.sol"; +import { ILegacyMintableERC20, IOptimismMintableERC20 } from "src/universal/interfaces/IOptimismMintableERC20.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; contract OptimismMintableERC20_Test is Bridge_Initializer { From 40750a58e7a4a6f06370d18dfe6c6eab309012d9 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Mon, 9 Sep 2024 07:54:31 +1000 Subject: [PATCH 065/264] op-challenger: Support binary and JSON snapshots (#11754) * op-challenger: Support loading json or binary cannon states. * op-challenger: Use binary cannon snapshots * op-challenger: Support downloading prestates in multiple formats. * op-challenger: Verify newly downloaded snapshots. * op-e2e: Update test to handle binary snapshots correctly. * op-e2e: Remove unused parameter * op-challenger: Add more varied data to the test cannon state. * op-challenger: Add more varied data to the test cannon state. --- op-challenger/config/config.go | 15 +-- op-challenger/flags/flags.go | 1 + op-challenger/game/fault/register_task.go | 15 ++- .../game/fault/trace/asterisc/provider.go | 7 +- .../fault/trace/asterisc/provider_test.go | 2 +- ...{state_test.go => state_converter_test.go} | 0 .../game/fault/trace/cannon/provider.go | 8 +- .../game/fault/trace/cannon/provider_test.go | 2 +- .../fault/trace/cannon/state_converter.go | 19 +--- ...{state_test.go => state_converter_test.go} | 27 ++++++ .../fault/trace/cannon/test_data/state.json | 20 ++-- .../game/fault/trace/prestates/multi.go | 62 ++++++++++--- .../game/fault/trace/prestates/multi_test.go | 92 +++++++++++++++++-- .../game/fault/trace/prestates/source.go | 10 +- .../game/fault/trace/utils/preimage.go | 1 - op-challenger/game/fault/trace/vm/executor.go | 21 +++-- .../game/fault/trace/vm/executor_test.go | 18 +++- .../game/fault/trace/vm/prestates.go | 34 +++++-- op-challenger/runner/factory.go | 20 ++-- op-e2e/faultproofs/cannon_benchmark_test.go | 2 +- op-e2e/faultproofs/precompile_test.go | 26 +----- 21 files changed, 284 insertions(+), 118 deletions(-) rename op-challenger/game/fault/trace/asterisc/{state_test.go => state_converter_test.go} (100%) rename op-challenger/game/fault/trace/cannon/{state_test.go => state_converter_test.go} (59%) diff --git a/op-challenger/config/config.go b/op-challenger/config/config.go index a9937a68af86..e8a245936f33 100644 --- a/op-challenger/config/config.go +++ b/op-challenger/config/config.go @@ -139,13 +139,14 @@ func NewConfig( Datadir: datadir, Cannon: vm.Config{ - VmType: types.TraceTypeCannon, - L1: l1EthRpc, - L1Beacon: l1BeaconApi, - L2: l2EthRpc, - SnapshotFreq: DefaultCannonSnapshotFreq, - InfoFreq: DefaultCannonInfoFreq, - DebugInfo: true, + VmType: types.TraceTypeCannon, + L1: l1EthRpc, + L1Beacon: l1BeaconApi, + L2: l2EthRpc, + SnapshotFreq: DefaultCannonSnapshotFreq, + InfoFreq: DefaultCannonInfoFreq, + DebugInfo: true, + BinarySnapshots: true, }, Asterisc: vm.Config{ VmType: types.TraceTypeAsterisc, diff --git a/op-challenger/flags/flags.go b/op-challenger/flags/flags.go index 00c731c95fe6..38e59d350cec 100644 --- a/op-challenger/flags/flags.go +++ b/op-challenger/flags/flags.go @@ -578,6 +578,7 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro SnapshotFreq: ctx.Uint(CannonSnapshotFreqFlag.Name), InfoFreq: ctx.Uint(CannonInfoFreqFlag.Name), DebugInfo: true, + BinarySnapshots: true, }, CannonAbsolutePreState: ctx.String(CannonPreStateFlag.Name), CannonAbsolutePreStateBaseURL: cannonPrestatesURL, diff --git a/op-challenger/game/fault/register_task.go b/op-challenger/game/fault/register_task.go index 4e5ee1062504..3b438ad8eea2 100644 --- a/op-challenger/game/fault/register_task.go +++ b/op-challenger/game/fault/register_task.go @@ -48,16 +48,18 @@ type RegisterTask struct { } func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor) *RegisterTask { + stateConverter := cannon.NewStateConverter() return &RegisterTask{ gameType: gameType, getPrestateProvider: cachePrestates( gameType, + stateConverter, m, cfg.CannonAbsolutePreStateBaseURL, cfg.CannonAbsolutePreState, filepath.Join(cfg.Datadir, "cannon-prestates"), func(path string) faultTypes.PrestateProvider { - return vm.NewPrestateProvider(path, cannon.NewStateConverter()) + return vm.NewPrestateProvider(path, stateConverter) }), newTraceAccessor: func( logger log.Logger, @@ -78,16 +80,18 @@ func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m c } func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor) *RegisterTask { + stateConverter := asterisc.NewStateConverter() return &RegisterTask{ gameType: gameType, getPrestateProvider: cachePrestates( gameType, + stateConverter, m, cfg.AsteriscAbsolutePreStateBaseURL, cfg.AsteriscAbsolutePreState, filepath.Join(cfg.Datadir, "asterisc-prestates"), func(path string) faultTypes.PrestateProvider { - return vm.NewPrestateProvider(path, asterisc.NewStateConverter()) + return vm.NewPrestateProvider(path, stateConverter) }), newTraceAccessor: func( logger log.Logger, @@ -108,16 +112,18 @@ func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m } func NewAsteriscKonaRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor) *RegisterTask { + stateConverter := asterisc.NewStateConverter() return &RegisterTask{ gameType: gameType, getPrestateProvider: cachePrestates( gameType, + stateConverter, m, cfg.AsteriscKonaAbsolutePreStateBaseURL, cfg.AsteriscKonaAbsolutePreState, filepath.Join(cfg.Datadir, "asterisc-kona-prestates"), func(path string) faultTypes.PrestateProvider { - return vm.NewPrestateProvider(path, asterisc.NewStateConverter()) + return vm.NewPrestateProvider(path, stateConverter) }), newTraceAccessor: func( logger log.Logger, @@ -162,13 +168,14 @@ func NewAlphabetRegisterTask(gameType faultTypes.GameType) *RegisterTask { func cachePrestates( gameType faultTypes.GameType, + stateConverter vm.StateConverter, m caching.Metrics, prestateBaseURL *url.URL, preStatePath string, prestateDir string, newPrestateProvider func(path string) faultTypes.PrestateProvider, ) func(prestateHash common.Hash) (faultTypes.PrestateProvider, error) { - prestateSource := prestates.NewPrestateSource(prestateBaseURL, preStatePath, prestateDir) + prestateSource := prestates.NewPrestateSource(prestateBaseURL, preStatePath, prestateDir, stateConverter) prestateProviderCache := prestates.NewPrestateProviderCache(m, fmt.Sprintf("prestates-%v", gameType), func(prestateHash common.Hash) (faultTypes.PrestateProvider, error) { prestatePath, err := prestateSource.PrestatePath(prestateHash) if err != nil { diff --git a/op-challenger/game/fault/trace/asterisc/provider.go b/op-challenger/game/fault/trace/asterisc/provider.go index 78ae250290b6..2e9393010364 100644 --- a/op-challenger/game/fault/trace/asterisc/provider.go +++ b/op-challenger/game/fault/trace/asterisc/provider.go @@ -28,6 +28,7 @@ type AsteriscTraceProvider struct { gameDepth types.Depth preimageLoader *utils.PreimageLoader stateConverter vm.StateConverter + cfg vm.Config types.PrestateProvider @@ -48,6 +49,7 @@ func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, vmCfg vm. }), PrestateProvider: prestateProvider, stateConverter: NewStateConverter(), + cfg: cfg, } } @@ -122,7 +124,7 @@ func (p *AsteriscTraceProvider) loadProof(ctx context.Context, i uint64) (*utils file, err = ioutil.OpenDecompressed(path) if errors.Is(err, os.ErrNotExist) { // Expected proof wasn't generated, check if we reached the end of execution - proof, step, exited, err := p.stateConverter.ConvertStateToProof(filepath.Join(p.dir, vm.FinalState)) + proof, step, exited, err := p.stateConverter.ConvertStateToProof(vm.FinalStatePath(p.dir, p.cfg.BinarySnapshots)) if err != nil { return nil, err } @@ -171,6 +173,7 @@ func NewTraceProviderForTest(logger log.Logger, m vm.Metricer, cfg *config.Confi return kvstore.NewFileKV(vm.PreimageDir(dir)) }), stateConverter: NewStateConverter(), + cfg: cfg.Asterisc, } return &AsteriscTraceProviderForTest{p} } @@ -181,7 +184,7 @@ func (p *AsteriscTraceProviderForTest) FindStep(ctx context.Context, start uint6 return 0, fmt.Errorf("generate asterisc trace (until preimage read): %w", err) } // Load the step from the state asterisc finished with - _, step, exited, err := p.stateConverter.ConvertStateToProof(filepath.Join(p.dir, vm.FinalState)) + _, step, exited, err := p.stateConverter.ConvertStateToProof(vm.FinalStatePath(p.dir, p.cfg.BinarySnapshots)) if err != nil { return 0, fmt.Errorf("failed to load final state: %w", err) } diff --git a/op-challenger/game/fault/trace/asterisc/provider_test.go b/op-challenger/game/fault/trace/asterisc/provider_test.go index d467bbb668dc..ce80b3403dac 100644 --- a/op-challenger/game/fault/trace/asterisc/provider_test.go +++ b/op-challenger/game/fault/trace/asterisc/provider_test.go @@ -243,7 +243,7 @@ func (e *stubGenerator) GenerateProof(ctx context.Context, dir string, i uint64) var err error if e.finalState != nil && e.finalState.Step <= i { // Requesting a trace index past the end of the trace - proofFile = filepath.Join(dir, vm.FinalState) + proofFile = vm.FinalStatePath(dir, false) data, err = json.Marshal(e.finalState) if err != nil { return err diff --git a/op-challenger/game/fault/trace/asterisc/state_test.go b/op-challenger/game/fault/trace/asterisc/state_converter_test.go similarity index 100% rename from op-challenger/game/fault/trace/asterisc/state_test.go rename to op-challenger/game/fault/trace/asterisc/state_converter_test.go diff --git a/op-challenger/game/fault/trace/cannon/provider.go b/op-challenger/game/fault/trace/cannon/provider.go index ce3cd8cceb96..4d691e0225b9 100644 --- a/op-challenger/game/fault/trace/cannon/provider.go +++ b/op-challenger/game/fault/trace/cannon/provider.go @@ -29,6 +29,7 @@ type CannonTraceProvider struct { gameDepth types.Depth preimageLoader *utils.PreimageLoader stateConverter vm.StateConverter + cfg vm.Config types.PrestateProvider @@ -49,6 +50,7 @@ func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, vmCfg vm. }), PrestateProvider: prestateProvider, stateConverter: &StateConverter{}, + cfg: cfg, } } @@ -122,7 +124,7 @@ func (p *CannonTraceProvider) loadProof(ctx context.Context, i uint64) (*utils.P // Try opening the file again now and it should exist. file, err = ioutil.OpenDecompressed(path) if errors.Is(err, os.ErrNotExist) { - proof, stateStep, exited, err := p.stateConverter.ConvertStateToProof(filepath.Join(p.dir, vm.FinalState)) + proof, stateStep, exited, err := p.stateConverter.ConvertStateToProof(vm.FinalStatePath(p.dir, p.cfg.BinarySnapshots)) if err != nil { return nil, fmt.Errorf("cannot create proof from final state: %w", err) } @@ -170,6 +172,7 @@ func NewTraceProviderForTest(logger log.Logger, m vm.Metricer, cfg *config.Confi return kvstore.NewFileKV(vm.PreimageDir(dir)) }), stateConverter: NewStateConverter(), + cfg: cfg.Cannon, } return &CannonTraceProviderForTest{p} } @@ -180,7 +183,8 @@ func (p *CannonTraceProviderForTest) FindStep(ctx context.Context, start uint64, return 0, fmt.Errorf("generate cannon trace (until preimage read): %w", err) } // Load the step from the state cannon finished with - _, step, exited, err := p.stateConverter.ConvertStateToProof(filepath.Join(p.dir, vm.FinalState)) + + _, step, exited, err := p.stateConverter.ConvertStateToProof(vm.FinalStatePath(p.dir, p.cfg.BinarySnapshots)) if err != nil { return 0, fmt.Errorf("failed to load final state: %w", err) } diff --git a/op-challenger/game/fault/trace/cannon/provider_test.go b/op-challenger/game/fault/trace/cannon/provider_test.go index c650bd6ef818..82edc5562623 100644 --- a/op-challenger/game/fault/trace/cannon/provider_test.go +++ b/op-challenger/game/fault/trace/cannon/provider_test.go @@ -261,7 +261,7 @@ func (e *stubGenerator) GenerateProof(ctx context.Context, dir string, i uint64) var err error if e.finalState != nil && e.finalState.Step <= i { // Requesting a trace index past the end of the trace - proofFile = filepath.Join(dir, vm.FinalState) + proofFile = vm.FinalStatePath(dir, false) data, err = json.Marshal(e.finalState) if err != nil { return err diff --git a/op-challenger/game/fault/trace/cannon/state_converter.go b/op-challenger/game/fault/trace/cannon/state_converter.go index e11b0ee53caa..36b1b2040889 100644 --- a/op-challenger/game/fault/trace/cannon/state_converter.go +++ b/op-challenger/game/fault/trace/cannon/state_converter.go @@ -1,13 +1,11 @@ package cannon import ( - "encoding/json" "fmt" - "io" "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" + "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" - "github.com/ethereum-optimism/optimism/op-service/ioutil" ) type StateConverter struct { @@ -36,18 +34,5 @@ func (c *StateConverter) ConvertStateToProof(statePath string) (*utils.ProofData } func parseState(path string) (*singlethreaded.State, error) { - file, err := ioutil.OpenDecompressed(path) - if err != nil { - return nil, fmt.Errorf("cannot open state file (%v): %w", path, err) - } - return parseStateFromReader(file) -} - -func parseStateFromReader(in io.ReadCloser) (*singlethreaded.State, error) { - defer in.Close() - var state singlethreaded.State - if err := json.NewDecoder(in).Decode(&state); err != nil { - return nil, fmt.Errorf("invalid mipsevm state: %w", err) - } - return &state, nil + return serialize.Load[singlethreaded.State](path) } diff --git a/op-challenger/game/fault/trace/cannon/state_test.go b/op-challenger/game/fault/trace/cannon/state_converter_test.go similarity index 59% rename from op-challenger/game/fault/trace/cannon/state_test.go rename to op-challenger/game/fault/trace/cannon/state_converter_test.go index ce4757a35671..58e7eb1b829d 100644 --- a/op-challenger/game/fault/trace/cannon/state_test.go +++ b/op-challenger/game/fault/trace/cannon/state_converter_test.go @@ -8,6 +8,7 @@ import ( "path/filepath" "testing" + "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/stretchr/testify/require" "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" @@ -48,4 +49,30 @@ func TestLoadState(t *testing.T) { require.NoError(t, json.Unmarshal(testState, &expected)) require.Equal(t, &expected, state) }) + + t.Run("Binary", func(t *testing.T) { + var expected singlethreaded.State + require.NoError(t, json.Unmarshal(testState, &expected)) + + dir := t.TempDir() + path := filepath.Join(dir, "state.bin") + require.NoError(t, serialize.Write[*singlethreaded.State](path, &expected, 0644)) + + state, err := parseState(path) + require.NoError(t, err) + require.Equal(t, &expected, state) + }) + + t.Run("BinaryGzip", func(t *testing.T) { + var expected singlethreaded.State + require.NoError(t, json.Unmarshal(testState, &expected)) + + dir := t.TempDir() + path := filepath.Join(dir, "state.bin.gz") + require.NoError(t, serialize.Write[*singlethreaded.State](path, &expected, 0644)) + + state, err := parseState(path) + require.NoError(t, err) + require.Equal(t, &expected, state) + }) } diff --git a/op-challenger/game/fault/trace/cannon/test_data/state.json b/op-challenger/game/fault/trace/cannon/test_data/state.json index 30cd1ccdcf0c..82f67624ce03 100644 --- a/op-challenger/game/fault/trace/cannon/test_data/state.json +++ b/op-challenger/game/fault/trace/cannon/test_data/state.json @@ -1,14 +1,14 @@ { - "memory": [], + "memory": [{"index":10,"data":"eJzswAENAAAAwiD7p7bHBwMAAADyHgAA//8QAAAB"}], "preimageKey": "0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", - "preimageOffset": 0, - "pc": 0, + "preimageOffset": 42, + "pc": 94, "nextPC": 1, - "lo": 0, - "hi": 0, - "heap": 0, - "exit": 0, - "exited": false, - "step": 0, - "registers": [] + "lo": 3, + "hi": 5, + "heap": 4, + "exit": 1, + "exited": true, + "step": 8849, + "registers": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2147471360,0,0] } diff --git a/op-challenger/game/fault/trace/prestates/multi.go b/op-challenger/game/fault/trace/prestates/multi.go index ccc22c6d5d4a..5a770fbe1258 100644 --- a/op-challenger/game/fault/trace/prestates/multi.go +++ b/op-challenger/game/fault/trace/prestates/multi.go @@ -9,43 +9,64 @@ import ( "os" "path/filepath" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/ethereum/go-ethereum/common" ) var ( ErrPrestateUnavailable = errors.New("prestate unavailable") + + // supportedFileTypes lists, in preferred order, the prestate file types to attempt to download + supportedFileTypes = []string{".bin.gz", ".json.gz", ".json"} ) type MultiPrestateProvider struct { - baseUrl *url.URL - dataDir string + baseUrl *url.URL + dataDir string + stateConverter vm.StateConverter } -func NewMultiPrestateProvider(baseUrl *url.URL, dataDir string) *MultiPrestateProvider { +func NewMultiPrestateProvider(baseUrl *url.URL, dataDir string, stateConverter vm.StateConverter) *MultiPrestateProvider { return &MultiPrestateProvider{ - baseUrl: baseUrl, - dataDir: dataDir, + baseUrl: baseUrl, + dataDir: dataDir, + stateConverter: stateConverter, } } func (m *MultiPrestateProvider) PrestatePath(hash common.Hash) (string, error) { - path := filepath.Join(m.dataDir, hash.Hex()+".json.gz") - if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) { - if err := m.fetchPrestate(hash, path); err != nil { - return "", fmt.Errorf("failed to fetch prestate: %w", err) + // First try to find a previously downloaded prestate + for _, fileType := range supportedFileTypes { + path := filepath.Join(m.dataDir, hash.Hex()+fileType) + if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) { + continue // File doesn't exist, try the next file type + } else if err != nil { + return "", fmt.Errorf("error checking for existing prestate %v in file %v: %w", hash, path, err) + } + return path, nil // Found an existing file so use it + } + + // Didn't find any available files, try to download one + var combinedErr error // Keep a track of each download attempt so we can report them if none work + for _, fileType := range supportedFileTypes { + path := filepath.Join(m.dataDir, hash.Hex()+fileType) + if err := m.fetchPrestate(hash, fileType, path); errors.Is(err, ErrPrestateUnavailable) { + combinedErr = errors.Join(combinedErr, err) + continue // Didn't find prestate in this format, try the next + } else if err != nil { + return "", fmt.Errorf("error downloading prestate %v to file %v: %w", hash, path, err) } - } else if err != nil { - return "", fmt.Errorf("error checking for existing prestate %v: %w", hash, err) + return path, nil // Successfully downloaded a prestate so use it } - return path, nil + return "", errors.Join(ErrPrestateUnavailable, combinedErr) } -func (m *MultiPrestateProvider) fetchPrestate(hash common.Hash, dest string) error { +func (m *MultiPrestateProvider) fetchPrestate(hash common.Hash, fileType string, dest string) error { if err := os.MkdirAll(m.dataDir, 0755); err != nil { return fmt.Errorf("error creating prestate dir: %w", err) } - prestateUrl := m.baseUrl.JoinPath(hash.Hex() + ".json") + prestateUrl := m.baseUrl.JoinPath(hash.Hex() + fileType) resp, err := http.Get(prestateUrl.String()) if err != nil { return fmt.Errorf("failed to fetch prestate from %v: %w", prestateUrl, err) @@ -54,7 +75,8 @@ func (m *MultiPrestateProvider) fetchPrestate(hash common.Hash, dest string) err if resp.StatusCode != http.StatusOK { return fmt.Errorf("%w from url %v: status %v", ErrPrestateUnavailable, prestateUrl, resp.StatusCode) } - out, err := ioutil.NewAtomicWriterCompressed(dest, 0o644) + tmpFile := dest + ".tmp" + fileType // Preserve the file type extension so compression is applied correctly + out, err := ioutil.NewAtomicWriterCompressed(tmpFile, 0o644) if err != nil { return fmt.Errorf("failed to open atomic writer for %v: %w", dest, err) } @@ -68,5 +90,15 @@ func (m *MultiPrestateProvider) fetchPrestate(hash common.Hash, dest string) err if err := out.Close(); err != nil { return fmt.Errorf("failed to close file %v: %w", dest, err) } + // Verify the prestate actually matches the expected hash before moving it into the final destination + proof, _, _, err := m.stateConverter.ConvertStateToProof(dest) + if err != nil || proof.ClaimValue != hash { + // Treat invalid prestates as unavailable. Often servers return a 404 page with 200 status code + _ = os.Remove(tmpFile) // Best effort attempt to clean up the temporary file + return fmt.Errorf("invalid prestate from url: %v, ignoring: %w", prestateUrl, errors.Join(ErrPrestateUnavailable, err)) + } + if err := os.Rename(tmpFile, dest); err != nil { + return fmt.Errorf("failed to move temp file to final destination: %w", err) + } return nil } diff --git a/op-challenger/game/fault/trace/prestates/multi_test.go b/op-challenger/game/fault/trace/prestates/multi_test.go index 2f825d98da4e..ff979ae50074 100644 --- a/op-challenger/game/fault/trace/prestates/multi_test.go +++ b/op-challenger/game/fault/trace/prestates/multi_test.go @@ -1,14 +1,17 @@ package prestates import ( + "errors" "io" "net/http" "net/http/httptest" "net/url" "os" "path/filepath" + "strings" "testing" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" @@ -20,8 +23,8 @@ func TestDownloadPrestate(t *testing.T) { _, _ = w.Write([]byte(r.URL.Path)) })) defer server.Close() - provider := NewMultiPrestateProvider(parseURL(t, server.URL), dir) hash := common.Hash{0xaa} + provider := NewMultiPrestateProvider(parseURL(t, server.URL), dir, &stubStateConverter{hash: hash}) path, err := provider.PrestatePath(hash) require.NoError(t, err) in, err := ioutil.OpenDecompressed(path) @@ -29,7 +32,7 @@ func TestDownloadPrestate(t *testing.T) { defer in.Close() content, err := io.ReadAll(in) require.NoError(t, err) - require.Equal(t, "/"+hash.Hex()+".json", string(content)) + require.Equal(t, "/"+hash.Hex()+".bin.gz", string(content)) } func TestCreateDirectory(t *testing.T) { @@ -39,8 +42,8 @@ func TestCreateDirectory(t *testing.T) { _, _ = w.Write([]byte(r.URL.Path)) })) defer server.Close() - provider := NewMultiPrestateProvider(parseURL(t, server.URL), dir) hash := common.Hash{0xaa} + provider := NewMultiPrestateProvider(parseURL(t, server.URL), dir, &stubStateConverter{hash: hash}) path, err := provider.PrestatePath(hash) require.NoError(t, err) in, err := ioutil.OpenDecompressed(path) @@ -48,13 +51,13 @@ func TestCreateDirectory(t *testing.T) { defer in.Close() content, err := io.ReadAll(in) require.NoError(t, err) - require.Equal(t, "/"+hash.Hex()+".json", string(content)) + require.Equal(t, "/"+hash.Hex()+".bin.gz", string(content)) } func TestExistingPrestate(t *testing.T) { dir := t.TempDir() - provider := NewMultiPrestateProvider(parseURL(t, "http://127.0.0.1:1"), dir) hash := common.Hash{0xaa} + provider := NewMultiPrestateProvider(parseURL(t, "http://127.0.0.1:1"), dir, &stubStateConverter{hash: hash}) expectedFile := filepath.Join(dir, hash.Hex()+".json.gz") err := ioutil.WriteCompressedBytes(expectedFile, []byte("expected content"), os.O_WRONLY|os.O_CREATE, 0o644) require.NoError(t, err) @@ -72,16 +75,84 @@ func TestExistingPrestate(t *testing.T) { func TestMissingPrestate(t *testing.T) { dir := t.TempDir() + var requests []string server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + requests = append(requests, r.URL.Path) w.WriteHeader(404) })) defer server.Close() - provider := NewMultiPrestateProvider(parseURL(t, server.URL), dir) hash := common.Hash{0xaa} + provider := NewMultiPrestateProvider(parseURL(t, server.URL), dir, &stubStateConverter{hash: hash}) path, err := provider.PrestatePath(hash) require.ErrorIs(t, err, ErrPrestateUnavailable) _, err = os.Stat(path) require.ErrorIs(t, err, os.ErrNotExist) + expectedRequests := []string{ + "/" + hash.Hex() + ".bin.gz", + "/" + hash.Hex() + ".json.gz", + "/" + hash.Hex() + ".json", + } + require.Equal(t, expectedRequests, requests) +} + +func TestStorePrestateWithCorrectExtension(t *testing.T) { + extensions := []string{".bin.gz", ".json.gz", ".json"} + for _, ext := range extensions { + ext := ext + t.Run(ext, func(t *testing.T) { + dir := t.TempDir() + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if !strings.HasSuffix(r.URL.Path, ext) { + w.WriteHeader(404) + return + } + _, _ = w.Write([]byte("content")) + })) + defer server.Close() + hash := common.Hash{0xaa} + provider := NewMultiPrestateProvider(parseURL(t, server.URL), dir, &stubStateConverter{hash: hash}) + path, err := provider.PrestatePath(hash) + require.NoError(t, err) + require.Truef(t, strings.HasSuffix(path, ext), "Expected path %v to have extension %v", path, ext) + in, err := ioutil.OpenDecompressed(path) + require.NoError(t, err) + defer in.Close() + content, err := io.ReadAll(in) + require.NoError(t, err) + require.Equal(t, "content", string(content)) + }) + } +} + +func TestDetectInvalidPrestate(t *testing.T) { + dir := t.TempDir() + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, _ = w.Write([]byte("content")) + })) + defer server.Close() + hash := common.Hash{0xaa} + provider := NewMultiPrestateProvider(parseURL(t, server.URL), dir, &stubStateConverter{hash: hash, err: errors.New("boom")}) + _, err := provider.PrestatePath(hash) + require.ErrorIs(t, err, ErrPrestateUnavailable) + entries, err := os.ReadDir(dir) + require.NoError(t, err) + require.Empty(t, entries, "should not leave any files in temp dir") +} + +func TestDetectPrestateWithWrongHash(t *testing.T) { + dir := t.TempDir() + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, _ = w.Write([]byte("content")) + })) + defer server.Close() + hash := common.Hash{0xaa} + actualHash := common.Hash{0xbb} + provider := NewMultiPrestateProvider(parseURL(t, server.URL), dir, &stubStateConverter{hash: actualHash}) + _, err := provider.PrestatePath(hash) + require.ErrorIs(t, err, ErrPrestateUnavailable) + entries, err := os.ReadDir(dir) + require.NoError(t, err) + require.Empty(t, entries, "should not leave any files in temp dir") } func parseURL(t *testing.T, str string) *url.URL { @@ -89,3 +160,12 @@ func parseURL(t *testing.T, str string) *url.URL { require.NoError(t, err) return parsed } + +type stubStateConverter struct { + err error + hash common.Hash +} + +func (s *stubStateConverter) ConvertStateToProof(path string) (*utils.ProofData, uint64, bool, error) { + return &utils.ProofData{ClaimValue: s.hash}, 0, false, s.err +} diff --git a/op-challenger/game/fault/trace/prestates/source.go b/op-challenger/game/fault/trace/prestates/source.go index c59763560b11..a4c9839ad1e5 100644 --- a/op-challenger/game/fault/trace/prestates/source.go +++ b/op-challenger/game/fault/trace/prestates/source.go @@ -1,10 +1,14 @@ package prestates -import "net/url" +import ( + "net/url" -func NewPrestateSource(baseURL *url.URL, path string, localDir string) PrestateSource { + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" +) + +func NewPrestateSource(baseURL *url.URL, path string, localDir string, stateConverter vm.StateConverter) PrestateSource { if baseURL != nil { - return NewMultiPrestateProvider(baseURL, localDir) + return NewMultiPrestateProvider(baseURL, localDir, stateConverter) } else { return NewSinglePrestateSource(path) } diff --git a/op-challenger/game/fault/trace/utils/preimage.go b/op-challenger/game/fault/trace/utils/preimage.go index 0c14882fa774..6428821ec3fd 100644 --- a/op-challenger/game/fault/trace/utils/preimage.go +++ b/op-challenger/game/fault/trace/utils/preimage.go @@ -23,7 +23,6 @@ const ( ) var ( - ErrInvalidScalarValue = errors.New("invalid scalar value") ErrInvalidBlobKeyPreimage = errors.New("invalid blob key preimage") ) diff --git a/op-challenger/game/fault/trace/vm/executor.go b/op-challenger/game/fault/trace/vm/executor.go index 65c18d67d221..d2f80899b3e1 100644 --- a/op-challenger/game/fault/trace/vm/executor.go +++ b/op-challenger/game/fault/trace/vm/executor.go @@ -28,11 +28,12 @@ type Metricer interface { type Config struct { // VM Configuration - VmType types.TraceType - VmBin string // Path to the vm executable to run when generating trace data - SnapshotFreq uint // Frequency of snapshots to create when executing (in VM instructions) - InfoFreq uint // Frequency of progress log messages (in VM instructions) - DebugInfo bool + VmType types.TraceType + VmBin string // Path to the vm executable to run when generating trace data + SnapshotFreq uint // Frequency of snapshots to create when executing (in VM instructions) + InfoFreq uint // Frequency of progress log messages (in VM instructions) + DebugInfo bool // Whether to record debug info from the execution + BinarySnapshots bool // Whether to use binary snapshots instead of JSON // Host Configuration L1 string @@ -82,13 +83,13 @@ func (e *Executor) GenerateProof(ctx context.Context, dir string, i uint64) erro // The proof is stored at the specified directory. func (e *Executor) DoGenerateProof(ctx context.Context, dir string, begin uint64, end uint64, extraVmArgs ...string) error { snapshotDir := filepath.Join(dir, SnapsDir) - start, err := e.selectSnapshot(e.logger, snapshotDir, e.absolutePreState, begin) + start, err := e.selectSnapshot(e.logger, snapshotDir, e.absolutePreState, begin, e.cfg.BinarySnapshots) if err != nil { return fmt.Errorf("find starting snapshot: %w", err) } proofDir := filepath.Join(dir, utils.ProofsDir) dataDir := PreimageDir(dir) - lastGeneratedState := filepath.Join(dir, FinalState) + lastGeneratedState := FinalStatePath(dir, e.cfg.BinarySnapshots) args := []string{ "run", "--input", start, @@ -98,7 +99,11 @@ func (e *Executor) DoGenerateProof(ctx context.Context, dir string, begin uint64 "--proof-at", "=" + strconv.FormatUint(end, 10), "--proof-fmt", filepath.Join(proofDir, "%d.json.gz"), "--snapshot-at", "%" + strconv.FormatUint(uint64(e.cfg.SnapshotFreq), 10), - "--snapshot-fmt", filepath.Join(snapshotDir, "%d.json.gz"), + } + if e.cfg.BinarySnapshots { + args = append(args, "--snapshot-fmt", filepath.Join(snapshotDir, "%d.bin.gz")) + } else { + args = append(args, "--snapshot-fmt", filepath.Join(snapshotDir, "%d.json.gz")) } if end < math.MaxUint64 { args = append(args, "--stop-at", "="+strconv.FormatUint(end+1, 10)) diff --git a/op-challenger/game/fault/trace/vm/executor_test.go b/op-challenger/game/fault/trace/vm/executor_test.go index 695f9bf9fceb..f7738036e774 100644 --- a/op-challenger/game/fault/trace/vm/executor_test.go +++ b/op-challenger/game/fault/trace/vm/executor_test.go @@ -43,7 +43,7 @@ func TestGenerateProof(t *testing.T) { captureExec := func(t *testing.T, cfg Config, proofAt uint64) (string, string, map[string]string) { m := &stubVmMetrics{} executor := NewExecutor(testlog.Logger(t, log.LevelInfo), m, cfg, NewOpProgramServerExecutor(), prestate, inputs) - executor.selectSnapshot = func(logger log.Logger, dir string, absolutePreState string, i uint64) (string, error) { + executor.selectSnapshot = func(logger log.Logger, dir string, absolutePreState string, i uint64, binary bool) (string, error) { return input, nil } var binary string @@ -82,7 +82,7 @@ func TestGenerateProof(t *testing.T) { require.Equal(t, input, args["--input"]) require.Contains(t, args, "--meta") require.Equal(t, "", args["--meta"]) - require.Equal(t, filepath.Join(dir, FinalState), args["--output"]) + require.Equal(t, FinalStatePath(dir, cfg.BinarySnapshots), args["--output"]) require.Equal(t, "=150000000", args["--proof-at"]) require.Equal(t, "=150000001", args["--stop-at"]) require.Equal(t, "%500", args["--snapshot-at"]) @@ -128,6 +128,20 @@ func TestGenerateProof(t *testing.T) { // so expect that it will be omitted. We'll ultimately want asterisc to execute until the program exits. require.NotContains(t, args, "--stop-at") }) + + t.Run("BinarySnapshots", func(t *testing.T) { + cfg.Network = "mainnet" + cfg.BinarySnapshots = true + _, _, args := captureExec(t, cfg, 100) + require.Equal(t, filepath.Join(dir, SnapsDir, "%d.bin.gz"), args["--snapshot-fmt"]) + }) + + t.Run("JsonSnapshots", func(t *testing.T) { + cfg.Network = "mainnet" + cfg.BinarySnapshots = false + _, _, args := captureExec(t, cfg, 100) + require.Equal(t, filepath.Join(dir, SnapsDir, "%d.json.gz"), args["--snapshot-fmt"]) + }) } type stubVmMetrics struct { diff --git a/op-challenger/game/fault/trace/vm/prestates.go b/op-challenger/game/fault/trace/vm/prestates.go index c51dda7de1e5..b54d86ed9cca 100644 --- a/op-challenger/game/fault/trace/vm/prestates.go +++ b/op-challenger/game/fault/trace/vm/prestates.go @@ -14,16 +14,26 @@ import ( "github.com/ethereum/go-ethereum/log" ) -type SnapshotSelect func(logger log.Logger, dir string, absolutePreState string, i uint64) (string, error) +type SnapshotSelect func(logger log.Logger, dir string, absolutePreState string, i uint64, binary bool) (string, error) type CmdExecutor func(ctx context.Context, l log.Logger, binary string, args ...string) error const ( - SnapsDir = "snapshots" - PreimagesDir = "preimages" - FinalState = "final.json.gz" + SnapsDir = "snapshots" + PreimagesDir = "preimages" + finalStateJson = "final.json.gz" + finalStateBinary = "final.bin.gz" ) -var snapshotNameRegexp = regexp.MustCompile(`^[0-9]+\.json.gz$`) +func FinalStatePath(dir string, binarySnapshots bool) string { + filename := finalStateJson + if binarySnapshots { + filename = finalStateBinary + } + return filepath.Join(dir, filename) +} + +var snapshotJsonNameRegexp = regexp.MustCompile(`^[0-9]+\.json\.gz$`) +var snapshotBinaryNameRegexp = regexp.MustCompile(`^[0-9]+\.bin\.gz$`) func PreimageDir(dir string) string { return filepath.Join(dir, PreimagesDir) @@ -43,7 +53,13 @@ func RunCmd(ctx context.Context, l log.Logger, binary string, args ...string) er // FindStartingSnapshot finds the closest snapshot before the specified traceIndex in snapDir. // If no suitable snapshot can be found it returns absolutePreState. -func FindStartingSnapshot(logger log.Logger, snapDir string, absolutePreState string, traceIndex uint64) (string, error) { +func FindStartingSnapshot(logger log.Logger, snapDir string, absolutePreState string, traceIndex uint64, binarySnapshots bool) (string, error) { + suffix := ".json.gz" + nameRegexp := snapshotJsonNameRegexp + if binarySnapshots { + suffix = ".bin.gz" + nameRegexp = snapshotBinaryNameRegexp + } // Find the closest snapshot to start from entries, err := os.ReadDir(snapDir) if err != nil { @@ -59,11 +75,11 @@ func FindStartingSnapshot(logger log.Logger, snapDir string, absolutePreState st continue } name := entry.Name() - if !snapshotNameRegexp.MatchString(name) { + if !nameRegexp.MatchString(name) { logger.Warn("Unexpected file in snapshots dir", "parent", snapDir, "child", entry.Name()) continue } - index, err := strconv.ParseUint(name[0:len(name)-len(".json.gz")], 10, 64) + index, err := strconv.ParseUint(name[0:len(name)-len(suffix)], 10, 64) if err != nil { logger.Error("Unable to parse trace index of snapshot file", "parent", snapDir, "child", entry.Name()) continue @@ -75,7 +91,7 @@ func FindStartingSnapshot(logger log.Logger, snapDir string, absolutePreState st if bestSnap == 0 { return absolutePreState, nil } - startFrom := fmt.Sprintf("%v/%v.json.gz", snapDir, bestSnap) + startFrom := fmt.Sprintf("%v/%v%v", snapDir, bestSnap, suffix) return startFrom, nil } diff --git a/op-challenger/runner/factory.go b/op-challenger/runner/factory.go index 23b297392e98..90e7e885b5aa 100644 --- a/op-challenger/runner/factory.go +++ b/op-challenger/runner/factory.go @@ -29,37 +29,41 @@ func createTraceProvider( switch traceType { case types.TraceTypeCannon: vmConfig := vm.NewOpProgramServerExecutor() - prestate, err := getPrestate(prestateHash, cfg.CannonAbsolutePreStateBaseURL, cfg.CannonAbsolutePreState, dir) + stateConverter := cannon.NewStateConverter() + prestate, err := getPrestate(prestateHash, cfg.CannonAbsolutePreStateBaseURL, cfg.CannonAbsolutePreState, dir, stateConverter) if err != nil { return nil, err } - prestateProvider := vm.NewPrestateProvider(prestate, cannon.NewStateConverter()) + prestateProvider := vm.NewPrestateProvider(prestate, stateConverter) return cannon.NewTraceProvider(logger, m, cfg.Cannon, vmConfig, prestateProvider, prestate, localInputs, dir, 42), nil case types.TraceTypeAsterisc: vmConfig := vm.NewOpProgramServerExecutor() - prestate, err := getPrestate(prestateHash, cfg.AsteriscAbsolutePreStateBaseURL, cfg.AsteriscAbsolutePreState, dir) + stateConverter := asterisc.NewStateConverter() + prestate, err := getPrestate(prestateHash, cfg.AsteriscAbsolutePreStateBaseURL, cfg.AsteriscAbsolutePreState, dir, stateConverter) if err != nil { return nil, err } - prestateProvider := vm.NewPrestateProvider(prestate, asterisc.NewStateConverter()) + prestateProvider := vm.NewPrestateProvider(prestate, stateConverter) return asterisc.NewTraceProvider(logger, m, cfg.Asterisc, vmConfig, prestateProvider, prestate, localInputs, dir, 42), nil case types.TraceTypeAsteriscKona: vmConfig := vm.NewKonaServerExecutor() - prestate, err := getPrestate(prestateHash, cfg.AsteriscKonaAbsolutePreStateBaseURL, cfg.AsteriscKonaAbsolutePreState, dir) + stateConverter := asterisc.NewStateConverter() + prestate, err := getPrestate(prestateHash, cfg.AsteriscKonaAbsolutePreStateBaseURL, cfg.AsteriscKonaAbsolutePreState, dir, stateConverter) if err != nil { return nil, err } - prestateProvider := vm.NewPrestateProvider(prestate, asterisc.NewStateConverter()) + prestateProvider := vm.NewPrestateProvider(prestate, stateConverter) return asterisc.NewTraceProvider(logger, m, cfg.AsteriscKona, vmConfig, prestateProvider, prestate, localInputs, dir, 42), nil } return nil, errors.New("invalid trace type") } -func getPrestate(prestateHash common.Hash, prestateBaseUrl *url.URL, prestatePath string, dataDir string) (string, error) { +func getPrestate(prestateHash common.Hash, prestateBaseUrl *url.URL, prestatePath string, dataDir string, stateConverter vm.StateConverter) (string, error) { prestateSource := prestates.NewPrestateSource( prestateBaseUrl, prestatePath, - filepath.Join(dataDir, "prestates")) + filepath.Join(dataDir, "prestates"), + stateConverter) prestate, err := prestateSource.PrestatePath(prestateHash) if err != nil { diff --git a/op-e2e/faultproofs/cannon_benchmark_test.go b/op-e2e/faultproofs/cannon_benchmark_test.go index a4e167481087..57bb0581ac4e 100644 --- a/op-e2e/faultproofs/cannon_benchmark_test.go +++ b/op-e2e/faultproofs/cannon_benchmark_test.go @@ -93,7 +93,7 @@ func TestBenchmarkCannon_FPP(t *testing.T) { L2BlockNumber: l2ClaimBlockNumber, } debugfile := path.Join(t.TempDir(), "debug.json") - runCannon(t, ctx, sys, inputs, "sequencer", "--debug-info", debugfile) + runCannon(t, ctx, sys, inputs, "--debug-info", debugfile) data, err := os.ReadFile(debugfile) require.NoError(t, err) var debuginfo mipsevm.DebugInfo diff --git a/op-e2e/faultproofs/precompile_test.go b/op-e2e/faultproofs/precompile_test.go index ba60d45802e9..37b02aa3858d 100644 --- a/op-e2e/faultproofs/precompile_test.go +++ b/op-e2e/faultproofs/precompile_test.go @@ -2,13 +2,12 @@ package faultproofs import ( "context" - "encoding/json" - "fmt" "math" "math/big" "path/filepath" "testing" + "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" @@ -25,7 +24,6 @@ import ( "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" - "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/ethereum-optimism/optimism/op-service/testlog" ) @@ -130,7 +128,7 @@ func TestPrecompiles(t *testing.T) { L2OutputRoot: common.Hash(l2OutputRoot), L2BlockNumber: l2ClaimBlockNumber, } - runCannon(t, ctx, sys, inputs, "sequencer") + runCannon(t, ctx, sys, inputs) }) t.Run("DisputePrecompile-"+test.name, func(t *testing.T) { @@ -242,10 +240,10 @@ func TestGranitePrecompiles(t *testing.T) { L2OutputRoot: common.Hash(l2OutputRoot), L2BlockNumber: l2ClaimBlockNumber, } - runCannon(t, ctx, sys, inputs, "sequencer") + runCannon(t, ctx, sys, inputs) } -func runCannon(t *testing.T, ctx context.Context, sys *op_e2e.System, inputs utils.LocalGameInputs, l2Node string, extraVmArgs ...string) { +func runCannon(t *testing.T, ctx context.Context, sys *op_e2e.System, inputs utils.LocalGameInputs, extraVmArgs ...string) { l1Endpoint := sys.NodeEndpoint("l1").RPC() l1Beacon := sys.L1BeaconEndpoint().RestHTTP() rollupEndpoint := sys.RollupEndpoint("sequencer").RPC() @@ -263,23 +261,9 @@ func runCannon(t *testing.T, ctx context.Context, sys *op_e2e.System, inputs uti err := executor.DoGenerateProof(ctx, proofsDir, math.MaxUint, math.MaxUint, extraVmArgs...) require.NoError(t, err, "failed to generate proof") - state, err := parseState(filepath.Join(proofsDir, "final.json.gz")) + state, err := serialize.Load[singlethreaded.State](vm.FinalStatePath(proofsDir, cfg.Cannon.BinarySnapshots)) require.NoError(t, err, "failed to parse state") require.True(t, state.Exited, "cannon did not exit") require.Zero(t, state.ExitCode, "cannon failed with exit code %d", state.ExitCode) t.Logf("Completed in %d steps", state.Step) } - -func parseState(path string) (*singlethreaded.State, error) { - file, err := ioutil.OpenDecompressed(path) - if err != nil { - return nil, fmt.Errorf("cannot open state file (%v): %w", path, err) - } - defer file.Close() - var state singlethreaded.State - err = json.NewDecoder(file).Decode(&state) - if err != nil { - return nil, fmt.Errorf("invalid mipsevm state (%v): %w", path, err) - } - return &state, nil -} From c27aead5bef2127adcc2b30a685c72389dad22e6 Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Mon, 9 Sep 2024 09:19:03 -0600 Subject: [PATCH 066/264] Remove hardcoded entrypoint (#11801) Removes the `ENTRYPOINT` directive in the `contracts-bedrock` image. While convenient, using `ENTRYPOINT` makes building tooling on top of the image much harder since the entrypoint cannot be overridden without providing special flags to Docker. It is easier to use a dummy `CMD` instead that directs users to call specific tools when running the container. Functionally, this means users will run `docker run just ` instead of `docker run ` if they want to use the Justfile. --- ops/docker/Dockerfile.packages | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ops/docker/Dockerfile.packages b/ops/docker/Dockerfile.packages index bdcb917d21d3..dbd496afc8af 100644 --- a/ops/docker/Dockerfile.packages +++ b/ops/docker/Dockerfile.packages @@ -70,8 +70,4 @@ COPY --from=base /opt/optimism/versions.json /opt/optimism/versions.json WORKDIR /opt/optimism/packages/contracts-bedrock -# Set "just" as entrypoint, so the default args (the Dockerfile CMD) -# are passed in to it. This was previously "pnpm run" + "deploy". -ENTRYPOINT ["just"] - -CMD ["deploy"] +CMD ["echo", "Override this command to use this image."] From e0f85896ab372b525e92ea3eb8314137012df9dd Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Mon, 9 Sep 2024 10:17:42 -0600 Subject: [PATCH 067/264] Allow cheatcodes on DeploySuperchain.s.sol (#11802) We need to add these calls otherwise calling `DeploySuperchain.s.sol` as a script with input/output files fails. --- packages/contracts-bedrock/scripts/DeploySuperchain.s.sol | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol index 0bd69f7498a8..2a6c104e66e5 100644 --- a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol +++ b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol @@ -381,6 +381,8 @@ contract DeploySuperchain is Script { (dsi_, dso_) = getIOContracts(); vm.etch(address(dsi_), type(DeploySuperchainInput).runtimeCode); vm.etch(address(dso_), type(DeploySuperchainOutput).runtimeCode); + vm.allowCheatcodes(address(dsi_)); + vm.allowCheatcodes(address(dso_)); } function getIOContracts() public view returns (DeploySuperchainInput dsi_, DeploySuperchainOutput dso_) { From c05f5adda536d6c24109613b51c01e0be859cef6 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Tue, 10 Sep 2024 02:22:50 +1000 Subject: [PATCH 068/264] op-program: Add recent op-program versions to reproducibility check (#11560) * op-program: Add recent op-program versions to reproducibility check * Add 1.3.1-rc.2 --- .circleci/config.yml | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e23186e5a234..7a57f627a28d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1112,6 +1112,16 @@ jobs: echo 'export EXPECTED_PRESTATE_HASH="0x03e69d3de5155f4a80da99dd534561cbddd4f9dd56c9ecc704d6886625711d2b"' >> $BASH_ENV elif [[ "<>" == "1.2.0" ]]; then echo 'export EXPECTED_PRESTATE_HASH="0x03617abec0b255dc7fc7a0513a2c2220140a1dcd7a1c8eca567659bd67e05cea"' >> $BASH_ENV + elif [[ "<>" == "1.3.0-rc.1" ]]; then + echo 'export EXPECTED_PRESTATE_HASH="0x0367c4aa897bffbded0b523f277ca892298dc3c691baf37bc2099b86024f9673"' >> $BASH_ENV + elif [[ "<>" == "1.3.0-rc.2" ]]; then + echo 'export EXPECTED_PRESTATE_HASH="0x0385c3f8ee78491001d92b90b07d0cf387b7b52ab9b83b4d87c994e92cf823ba"' >> $BASH_ENV + elif [[ "<>" == "1.3.0-rc.3" ]]; then + echo 'export EXPECTED_PRESTATE_HASH="0x030de10d9da911a2b180ecfae2aeaba8758961fc28262ce989458c6f9a547922"' >> $BASH_ENV + elif [[ "<>" == "1.3.1-rc.1" ]]; then + echo 'export EXPECTED_PRESTATE_HASH="0x03e806a2859a875267a563462a06d4d1d1b455a9efee959a46e21e54b6caf69a"' >> $BASH_ENV + elif [[ "<>" == "1.3.1-rc.2" ]]; then + echo 'export EXPECTED_PRESTATE_HASH="0x038512e02c4c3f7bdaec27d00edf55b7155e0905301e1a88083e4e0a6764d54c"' >> $BASH_ENV else echo "Unknown prestate version <>" exit 1 @@ -2206,6 +2216,17 @@ workflows: - preimage-reproducibility: matrix: parameters: - version: ["0.1.0", "0.2.0", "0.3.0", "1.0.0", "1.1.0", "1.2.0"] + version: + - "0.1.0" + - "0.2.0" + - "0.3.0" + - "1.0.0" + - "1.1.0" + - "1.2.0" + - "1.3.0-rc.1" + - "1.3.0-rc.2" + - "1.3.0-rc.3" + - "1.3.1-rc.1" + - "1.3.1-rc.2" context: slack From 8404e91bff2da0285b0e60e7dee23ecc994c6ac3 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Mon, 9 Sep 2024 13:51:54 -0400 Subject: [PATCH 069/264] ci: update contracts tests to split by file (#11797) Contracts tests were being split by test name which meant that Circle CI wouldn't be able to (eventually) be able to properly split these files by timings. Updates the CI job to split by file instead. --- .circleci/config.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7a57f627a28d..5a79a26081f4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -595,8 +595,16 @@ jobs: - run: name: run tests command: | - TESTS=$(forge test --list | grep -E '^\s{4}' | awk '{print $1}' | circleci tests split --split-by=timings | paste -sd "|" -) - forge test --match-test "$TESTS" + # Find all test files + TEST_FILES=$(find ./test -name "*.t.sol") + # Split the tests by timings + TEST_FILES=$(echo "$TEST_FILES" | circleci tests split --split-by=timings) + # Strip the leading "./test/" from each file path + TEST_FILES=$(echo "$TEST_FILES" | sed 's|./test/||') + # Generate the match path + MATCH_PATH="./test/{$(echo "$TEST_FILES" | paste -sd "," -)}" + # Run the tests + forge test --match-path "$MATCH_PATH" environment: FOUNDRY_PROFILE: ci working_directory: packages/contracts-bedrock From dc2490bb3daaee0a7051d17503b011220a9cfad4 Mon Sep 17 00:00:00 2001 From: zhiqiangxu <652732310@qq.com> Date: Tue, 10 Sep 2024 03:14:03 +0800 Subject: [PATCH 070/264] fix `ReadPreimage` (#11805) * avoid out of bound for TrackingPreimageOracleReader.ReadPreimage * use p.GetPreimage --- cannon/mipsevm/exec/preimage.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cannon/mipsevm/exec/preimage.go b/cannon/mipsevm/exec/preimage.go index f8039447d483..117ebeb810cc 100644 --- a/cannon/mipsevm/exec/preimage.go +++ b/cannon/mipsevm/exec/preimage.go @@ -49,7 +49,7 @@ func (p *TrackingPreimageOracleReader) ReadPreimage(key [32]byte, offset uint32) preimage := p.lastPreimage if key != p.lastPreimageKey { p.lastPreimageKey = key - data := p.po.GetPreimage(key) + data := p.GetPreimage(key) // add the length prefix preimage = make([]byte, 0, 8+len(data)) preimage = binary.BigEndian.AppendUint64(preimage, uint64(len(data))) @@ -57,6 +57,9 @@ func (p *TrackingPreimageOracleReader) ReadPreimage(key [32]byte, offset uint32) p.lastPreimage = preimage } p.lastPreimageOffset = offset + if offset > uint32(len(preimage)) { + return + } datLen = uint32(copy(dat[:], preimage[offset:])) return } From f46bea7bd6eb999d6170c7ffebd5510374618652 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Tue, 10 Sep 2024 06:09:05 +1000 Subject: [PATCH 071/264] op-program: Add a script to build cannon prestates for all tagged op-program releases. (#11559) --- op-program/scripts/build-prestates.sh | 39 +++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100755 op-program/scripts/build-prestates.sh diff --git a/op-program/scripts/build-prestates.sh b/op-program/scripts/build-prestates.sh new file mode 100755 index 000000000000..5394c7a135e0 --- /dev/null +++ b/op-program/scripts/build-prestates.sh @@ -0,0 +1,39 @@ +#!/bin/bash +set -euo pipefail +SCRIPTS_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) + +TMP_DIR=$(mktemp -d) +function cleanup() { + rm -rf "${TMP_DIR}" +} +trap cleanup EXIT +echo "Using temp dir: ${TMP_DIR}" +cd "${TMP_DIR}" + +# Need to check out a fresh copy of the monorepo so we can switch to specific tags without it also affecting the +# contents of this script (which is checked into the repo). +git clone https://github.com/ethereum-optimism/optimism --recurse-submodules + +STATES_DIR="${SCRIPTS_DIR}/../temp/states" +LOGS_DIR="${SCRIPTS_DIR}/../temp/logs" +REPO_DIR="${TMP_DIR}/optimism" +BIN_DIR="${REPO_DIR}/op-program/bin/" + +mkdir -p "${STATES_DIR}" "${LOGS_DIR}" + +cd "${REPO_DIR}" + +VERSIONS=$(git tag | grep 'op-program\/v') + +for VERSION in ${VERSIONS} +do + LOG_FILE="${LOGS_DIR}/build-$(echo "${VERSION}" | cut -c 12-).txt" + echo "Building Version: ${VERSION} Logs: ${LOG_FILE}" + git checkout "${VERSION}" > "${LOG_FILE}" 2>&1 + make reproducible-prestate >> "${LOG_FILE}" 2>&1 + HASH=$(cat "${BIN_DIR}/prestate-proof.json" | jq -r .pre) + cp "${BIN_DIR}/prestate.json" "${STATES_DIR}/${HASH}.json" + echo "Built ${VERSION}: ${HASH}" +done + +echo "All prestates successfully built and available in ${STATES_DIR}" From 4428d1070fc7a6c3f072d56afa8a3a26a46a9e09 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Tue, 10 Sep 2024 06:12:56 +1000 Subject: [PATCH 072/264] op-dispute-mon: Identify unclaimed credits based on the withdrawal request timestamp (#11488) --- op-dispute-mon/mon/bonds/monitor.go | 28 ++---- op-dispute-mon/mon/bonds/monitor_test.go | 57 +++--------- op-dispute-mon/mon/service.go | 4 +- op-dispute-mon/mon/withdrawals.go | 38 ++++++-- op-dispute-mon/mon/withdrawals_test.go | 105 +++++++++++++++++++---- 5 files changed, 136 insertions(+), 96 deletions(-) diff --git a/op-dispute-mon/mon/bonds/monitor.go b/op-dispute-mon/mon/bonds/monitor.go index efa7804d3408..2ce23dc472e7 100644 --- a/op-dispute-mon/mon/bonds/monitor.go +++ b/op-dispute-mon/mon/bonds/monitor.go @@ -17,22 +17,19 @@ type RClock interface { type BondMetrics interface { RecordCredit(expectation metrics.CreditExpectation, count int) RecordBondCollateral(addr common.Address, required *big.Int, available *big.Int) - RecordHonestWithdrawableAmounts(map[common.Address]*big.Int) } type Bonds struct { - logger log.Logger - clock RClock - metrics BondMetrics - honestActors types.HonestActors + logger log.Logger + clock RClock + metrics BondMetrics } -func NewBonds(logger log.Logger, metrics BondMetrics, honestActors types.HonestActors, clock RClock) *Bonds { +func NewBonds(logger log.Logger, metrics BondMetrics, clock RClock) *Bonds { return &Bonds{ - logger: logger, - clock: clock, - metrics: metrics, - honestActors: honestActors, + logger: logger, + clock: clock, + metrics: metrics, } } @@ -50,10 +47,6 @@ func (b *Bonds) CheckBonds(games []*types.EnrichedGameData) { func (b *Bonds) checkCredits(games []*types.EnrichedGameData) { creditMetrics := make(map[metrics.CreditExpectation]int) - honestWithdrawableAmounts := make(map[common.Address]*big.Int) - for address := range b.honestActors { - honestWithdrawableAmounts[address] = big.NewInt(0) - } for _, game := range games { // Check if the max duration has been reached for this game @@ -101,12 +94,6 @@ func (b *Bonds) checkCredits(games []*types.EnrichedGameData) { } comparison := actual.Cmp(expected) if maxDurationReached { - if actual.Cmp(big.NewInt(0)) > 0 && b.honestActors.Contains(recipient) { - total := honestWithdrawableAmounts[recipient] - total = new(big.Int).Add(total, actual) - honestWithdrawableAmounts[recipient] = total - b.logger.Warn("Found unclaimed credit", "recipient", recipient, "game", game.Proxy, "amount", actual) - } if comparison > 0 { creditMetrics[metrics.CreditAboveWithdrawable] += 1 b.logger.Warn("Credit above expected amount", "recipient", recipient, "expected", expected, "actual", actual, "game", game.Proxy, "withdrawable", "withdrawable") @@ -136,5 +123,4 @@ func (b *Bonds) checkCredits(games []*types.EnrichedGameData) { b.metrics.RecordCredit(metrics.CreditBelowNonWithdrawable, creditMetrics[metrics.CreditBelowNonWithdrawable]) b.metrics.RecordCredit(metrics.CreditEqualNonWithdrawable, creditMetrics[metrics.CreditEqualNonWithdrawable]) b.metrics.RecordCredit(metrics.CreditAboveNonWithdrawable, creditMetrics[metrics.CreditAboveNonWithdrawable]) - b.metrics.RecordHonestWithdrawableAmounts(honestWithdrawableAmounts) } diff --git a/op-dispute-mon/mon/bonds/monitor_test.go b/op-dispute-mon/mon/bonds/monitor_test.go index 5fd766b87061..dbeddd74d9c7 100644 --- a/op-dispute-mon/mon/bonds/monitor_test.go +++ b/op-dispute-mon/mon/bonds/monitor_test.go @@ -17,10 +17,7 @@ import ( ) var ( - frozen = time.Unix(int64(time.Hour.Seconds()), 0) - honestActor1 = common.Address{0x11, 0xaa} - honestActor2 = common.Address{0x22, 0xbb} - honestActor3 = common.Address{0x33, 0xcc} + frozen = time.Unix(int64(time.Hour.Seconds()), 0) ) func TestCheckBonds(t *testing.T) { @@ -64,8 +61,8 @@ func TestCheckBonds(t *testing.T) { } func TestCheckRecipientCredit(t *testing.T) { - addr1 := honestActor1 - addr2 := honestActor2 + addr1 := common.Address{0x11, 0xaa} + addr2 := common.Address{0x22, 0xbb} addr3 := common.Address{0x3c} addr4 := common.Address{0x4d} notRootPosition := types.NewPositionFromGIndex(big.NewInt(2)) @@ -349,14 +346,6 @@ func TestCheckRecipientCredit(t *testing.T) { require.Equal(t, 2, m.credits[metrics.CreditEqualNonWithdrawable], "CreditEqualNonWithdrawable") require.Equal(t, 2, m.credits[metrics.CreditAboveNonWithdrawable], "CreditAboveNonWithdrawable") - require.Len(t, m.honestWithdrawable, 3) - requireBigInt := func(name string, expected, actual *big.Int) { - require.Truef(t, expected.Cmp(actual) == 0, "Expected %v withdrawable to be %v but was %v", name, expected, actual) - } - requireBigInt("honest addr1", m.honestWithdrawable[addr1], big.NewInt(19)) - requireBigInt("honest addr2", m.honestWithdrawable[addr2], big.NewInt(13)) - requireBigInt("honest addr3", m.honestWithdrawable[honestActor3], big.NewInt(0)) - // Logs from game1 // addr1 is correct so has no logs // addr2 is below expected before max duration, so warn about early withdrawal @@ -382,18 +371,8 @@ func TestCheckRecipientCredit(t *testing.T) { testlog.NewAttributesFilter("withdrawable", "non_withdrawable"))) // Logs from game 2 - // addr1 is below expected - no warning as withdrawals may now be possible, but has unclaimed credit - require.NotNil(t, logs.FindLog( - testlog.NewLevelFilter(log.LevelWarn), - testlog.NewMessageFilter("Found unclaimed credit"), - testlog.NewAttributesFilter("game", game2.Proxy.Hex()), - testlog.NewAttributesFilter("recipient", addr1.Hex()))) - // addr2 is correct but has unclaimed credit - require.NotNil(t, logs.FindLog( - testlog.NewLevelFilter(log.LevelWarn), - testlog.NewMessageFilter("Found unclaimed credit"), - testlog.NewAttributesFilter("game", game2.Proxy.Hex()), - testlog.NewAttributesFilter("recipient", addr2.Hex()))) + // addr1 is below expected - no warning as withdrawals may now be possible + // addr2 is correct // addr3 is above expected - warn require.NotNil(t, logs.FindLog( testlog.NewLevelFilter(log.LevelWarn), @@ -422,18 +401,8 @@ func TestCheckRecipientCredit(t *testing.T) { testlog.NewAttributesFilter("withdrawable", "non_withdrawable"))) // Logs from game 4 - // addr1 is correct but has unclaimed credit - require.NotNil(t, logs.FindLog( - testlog.NewLevelFilter(log.LevelWarn), - testlog.NewMessageFilter("Found unclaimed credit"), - testlog.NewAttributesFilter("game", game4.Proxy.Hex()), - testlog.NewAttributesFilter("recipient", addr1.Hex()))) - // addr2 is below expected before max duration, no log because withdrawals may be possible but warn about unclaimed - require.NotNil(t, logs.FindLog( - testlog.NewLevelFilter(log.LevelWarn), - testlog.NewMessageFilter("Found unclaimed credit"), - testlog.NewAttributesFilter("game", game4.Proxy.Hex()), - testlog.NewAttributesFilter("recipient", addr2.Hex()))) + // addr1 is correct + // addr2 is below expected before max duration, no log because withdrawals may be possible // addr3 is not involved so no logs // addr4 is above expected before max duration, so warn require.NotNil(t, logs.FindLog( @@ -450,19 +419,13 @@ func setupBondMetricsTest(t *testing.T) (*Bonds, *stubBondMetrics, *testlog.Capt credits: make(map[metrics.CreditExpectation]int), recorded: make(map[common.Address]Collateral), } - honestActors := monTypes.NewHonestActors([]common.Address{honestActor1, honestActor2, honestActor3}) - bonds := NewBonds(logger, metrics, honestActors, clock.NewDeterministicClock(frozen)) + bonds := NewBonds(logger, metrics, clock.NewDeterministicClock(frozen)) return bonds, metrics, logs } type stubBondMetrics struct { - credits map[metrics.CreditExpectation]int - recorded map[common.Address]Collateral - honestWithdrawable map[common.Address]*big.Int -} - -func (s *stubBondMetrics) RecordHonestWithdrawableAmounts(values map[common.Address]*big.Int) { - s.honestWithdrawable = values + credits map[metrics.CreditExpectation]int + recorded map[common.Address]Collateral } func (s *stubBondMetrics) RecordBondCollateral(addr common.Address, required *big.Int, available *big.Int) { diff --git a/op-dispute-mon/mon/service.go b/op-dispute-mon/mon/service.go index e637b23d63b0..8ce97b7b8dd9 100644 --- a/op-dispute-mon/mon/service.go +++ b/op-dispute-mon/mon/service.go @@ -116,7 +116,7 @@ func (s *Service) initResolutionMonitor() { } func (s *Service) initWithdrawalMonitor() { - s.withdrawals = NewWithdrawalMonitor(s.logger, s.metrics) + s.withdrawals = NewWithdrawalMonitor(s.logger, s.cl, s.metrics, s.honestActors) } func (s *Service) initGameCallerCreator() { @@ -145,7 +145,7 @@ func (s *Service) initForecast(cfg *config.Config) { } func (s *Service) initBonds() { - s.bonds = bonds.NewBonds(s.logger, s.metrics, s.honestActors, s.cl) + s.bonds = bonds.NewBonds(s.logger, s.metrics, s.cl) } func (s *Service) initOutputRollupClient(ctx context.Context, cfg *config.Config) error { diff --git a/op-dispute-mon/mon/withdrawals.go b/op-dispute-mon/mon/withdrawals.go index 5563b099afe5..1c7e9da2f9af 100644 --- a/op-dispute-mon/mon/withdrawals.go +++ b/op-dispute-mon/mon/withdrawals.go @@ -1,6 +1,9 @@ package mon import ( + "math/big" + "time" + "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" @@ -8,25 +11,35 @@ import ( type WithdrawalMetrics interface { RecordWithdrawalRequests(delayedWeth common.Address, matches bool, count int) + RecordHonestWithdrawableAmounts(map[common.Address]*big.Int) } type WithdrawalMonitor struct { - logger log.Logger - metrics WithdrawalMetrics + logger log.Logger + clock RClock + metrics WithdrawalMetrics + honestActors types.HonestActors } -func NewWithdrawalMonitor(logger log.Logger, metrics WithdrawalMetrics) *WithdrawalMonitor { +func NewWithdrawalMonitor(logger log.Logger, clock RClock, metrics WithdrawalMetrics, honestActors types.HonestActors) *WithdrawalMonitor { return &WithdrawalMonitor{ - logger: logger, - metrics: metrics, + logger: logger, + clock: clock, + metrics: metrics, + honestActors: honestActors, } } func (w *WithdrawalMonitor) CheckWithdrawals(games []*types.EnrichedGameData) { + now := w.clock.Now() // Use a consistent time for all checks matching := make(map[common.Address]int) divergent := make(map[common.Address]int) + honestWithdrawableAmounts := make(map[common.Address]*big.Int) + for address := range w.honestActors { + honestWithdrawableAmounts[address] = big.NewInt(0) + } for _, game := range games { - matches, diverges := w.validateGameWithdrawals(game) + matches, diverges := w.validateGameWithdrawals(game, now, honestWithdrawableAmounts) matching[game.WETHContract] += matches divergent[game.WETHContract] += diverges } @@ -36,9 +49,10 @@ func (w *WithdrawalMonitor) CheckWithdrawals(games []*types.EnrichedGameData) { for contract, count := range divergent { w.metrics.RecordWithdrawalRequests(contract, false, count) } + w.metrics.RecordHonestWithdrawableAmounts(honestWithdrawableAmounts) } -func (w *WithdrawalMonitor) validateGameWithdrawals(game *types.EnrichedGameData) (int, int) { +func (w *WithdrawalMonitor) validateGameWithdrawals(game *types.EnrichedGameData, now time.Time, honestWithdrawableAmounts map[common.Address]*big.Int) (int, int) { matching := 0 divergent := 0 for recipient, withdrawalAmount := range game.WithdrawalRequests { @@ -48,6 +62,16 @@ func (w *WithdrawalMonitor) validateGameWithdrawals(game *types.EnrichedGameData divergent++ w.logger.Error("Withdrawal request amount does not match credit", "game", game.Proxy, "recipient", recipient, "credit", game.Credits[recipient], "withdrawal", game.WithdrawalRequests[recipient].Amount) } + + if withdrawalAmount.Amount.Cmp(big.NewInt(0)) > 0 && w.honestActors.Contains(recipient) { + if time.Unix(withdrawalAmount.Timestamp.Int64(), 0).Add(game.WETHDelay).Before(now) { + // Credits are withdrawable + total := honestWithdrawableAmounts[recipient] + total = new(big.Int).Add(total, withdrawalAmount.Amount) + honestWithdrawableAmounts[recipient] = total + w.logger.Warn("Found unclaimed credit", "recipient", recipient, "game", game.Proxy, "amount", withdrawalAmount.Amount) + } + } } return matching, divergent } diff --git a/op-dispute-mon/mon/withdrawals_test.go b/op-dispute-mon/mon/withdrawals_test.go index f598ea38df97..ad17493adf65 100644 --- a/op-dispute-mon/mon/withdrawals_test.go +++ b/op-dispute-mon/mon/withdrawals_test.go @@ -3,9 +3,12 @@ package mon import ( "math/big" "testing" + "time" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + "github.com/ethereum-optimism/optimism/op-challenger/game/types" monTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum-optimism/optimism/op-service/clock" "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" @@ -15,58 +18,76 @@ import ( var ( weth1 = common.Address{0x1a} weth2 = common.Address{0x2b} + + honestActor1 = common.Address{0x11, 0xaa} + honestActor2 = common.Address{0x22, 0xbb} + honestActor3 = common.Address{0x33, 0xcc} + dishonestActor4 = common.Address{0x44, 0xdd} + + nowUnix = int64(10_000) ) func makeGames() []*monTypes.EnrichedGameData { weth1Balance := big.NewInt(4200) weth2Balance := big.NewInt(6000) + game1 := &monTypes.EnrichedGameData{ + GameMetadata: types.GameMetadata{Proxy: common.Address{0x11, 0x11, 0x11}}, Credits: map[common.Address]*big.Int{ - common.Address{0x01}: big.NewInt(3), - common.Address{0x02}: big.NewInt(1), + honestActor1: big.NewInt(3), + honestActor2: big.NewInt(1), }, WithdrawalRequests: map[common.Address]*contracts.WithdrawalRequest{ - common.Address{0x01}: &contracts.WithdrawalRequest{Amount: big.NewInt(3)}, - common.Address{0x02}: &contracts.WithdrawalRequest{Amount: big.NewInt(1)}, + honestActor1: {Amount: big.NewInt(3), Timestamp: big.NewInt(nowUnix - 101)}, // Claimable + honestActor2: {Amount: big.NewInt(1), Timestamp: big.NewInt(nowUnix - 99)}, // Not claimable }, WETHContract: weth1, ETHCollateral: weth1Balance, + WETHDelay: 100 * time.Second, } game2 := &monTypes.EnrichedGameData{ + GameMetadata: types.GameMetadata{Proxy: common.Address{0x22, 0x22, 0x22}}, Credits: map[common.Address]*big.Int{ - common.Address{0x01}: big.NewInt(46), - common.Address{0x02}: big.NewInt(1), + honestActor1: big.NewInt(46), + honestActor2: big.NewInt(1), }, WithdrawalRequests: map[common.Address]*contracts.WithdrawalRequest{ - common.Address{0x01}: &contracts.WithdrawalRequest{Amount: big.NewInt(3)}, - common.Address{0x02}: &contracts.WithdrawalRequest{Amount: big.NewInt(1)}, + honestActor1: {Amount: big.NewInt(3), Timestamp: big.NewInt(nowUnix - 501)}, // Claimable + honestActor2: {Amount: big.NewInt(1), Timestamp: big.NewInt(nowUnix)}, // Not claimable }, WETHContract: weth2, ETHCollateral: weth2Balance, + WETHDelay: 500 * time.Second, } game3 := &monTypes.EnrichedGameData{ + GameMetadata: types.GameMetadata{Proxy: common.Address{0x33, 0x33, 0x33}}, Credits: map[common.Address]*big.Int{ - common.Address{0x03}: big.NewInt(2), - common.Address{0x04}: big.NewInt(4), + honestActor3: big.NewInt(2), + dishonestActor4: big.NewInt(4), }, WithdrawalRequests: map[common.Address]*contracts.WithdrawalRequest{ - common.Address{0x03}: &contracts.WithdrawalRequest{Amount: big.NewInt(2)}, - common.Address{0x04}: &contracts.WithdrawalRequest{Amount: big.NewInt(4)}, + honestActor3: {Amount: big.NewInt(2), Timestamp: big.NewInt(nowUnix - 1)}, // Claimable + dishonestActor4: {Amount: big.NewInt(4), Timestamp: big.NewInt(nowUnix - 5)}, // Claimable }, WETHContract: weth2, ETHCollateral: weth2Balance, + WETHDelay: 0 * time.Second, } return []*monTypes.EnrichedGameData{game1, game2, game3} } func TestCheckWithdrawals(t *testing.T) { - logger := testlog.Logger(t, log.LvlInfo) + now := time.Unix(nowUnix, 0) + cl := clock.NewDeterministicClock(now) + logger, logs := testlog.CaptureLogger(t, log.LvlInfo) metrics := &stubWithdrawalsMetrics{ matching: make(map[common.Address]int), divergent: make(map[common.Address]int), } - withdrawals := NewWithdrawalMonitor(logger, metrics) - withdrawals.CheckWithdrawals(makeGames()) + honestActors := monTypes.NewHonestActors([]common.Address{honestActor1, honestActor2, honestActor3}) + withdrawals := NewWithdrawalMonitor(logger, cl, metrics, honestActors) + games := makeGames() + withdrawals.CheckWithdrawals(games) require.Equal(t, metrics.matchCalls, 2) require.Equal(t, metrics.divergeCalls, 2) @@ -80,13 +101,59 @@ func TestCheckWithdrawals(t *testing.T) { require.Equal(t, metrics.matching[weth2], 3) require.Equal(t, metrics.divergent[weth1], 0) require.Equal(t, metrics.divergent[weth2], 1) + + require.Len(t, metrics.honestWithdrawable, 3) + requireBigInt := func(name string, expected, actual *big.Int) { + require.Truef(t, expected.Cmp(actual) == 0, "Expected %v withdrawable to be %v but was %v", name, expected, actual) + } + requireBigInt("honest addr1", big.NewInt(6), metrics.honestWithdrawable[honestActor1]) + requireBigInt("honest addr2", big.NewInt(0), metrics.honestWithdrawable[honestActor2]) + requireBigInt("honest addr3", big.NewInt(2), metrics.honestWithdrawable[honestActor3]) + require.Nil(t, metrics.honestWithdrawable[dishonestActor4], "should only report withdrawable credits for honest actors") + + findUnclaimedCreditWarning := func(game common.Address, actor common.Address) *testlog.CapturedRecord { + return logs.FindLog( + testlog.NewLevelFilter(log.LevelWarn), + testlog.NewMessageFilter("Found unclaimed credit"), + testlog.NewAttributesFilter("game", game.Hex()), + testlog.NewAttributesFilter("recipient", actor.Hex())) + } + requireUnclaimedWarning := func(game common.Address, actor common.Address) { + require.NotNil(t, findUnclaimedCreditWarning(game, actor)) + } + noUnclaimedWarning := func(game common.Address, actor common.Address) { + require.Nil(t, findUnclaimedCreditWarning(game, actor)) + } + // Game 1, unclaimed for honestActor1 only + requireUnclaimedWarning(games[0].Proxy, honestActor1) + noUnclaimedWarning(games[0].Proxy, honestActor2) + noUnclaimedWarning(games[0].Proxy, honestActor3) + noUnclaimedWarning(games[0].Proxy, dishonestActor4) + + // Game 2, unclaimed for honestActor1 only + requireUnclaimedWarning(games[1].Proxy, honestActor1) + noUnclaimedWarning(games[1].Proxy, honestActor2) + noUnclaimedWarning(games[1].Proxy, honestActor3) + noUnclaimedWarning(games[1].Proxy, dishonestActor4) + + // Game 3, unclaimed for honestActor3 only + // dishonestActor4 has unclaimed credits but we don't track them + noUnclaimedWarning(games[2].Proxy, honestActor1) + noUnclaimedWarning(games[2].Proxy, honestActor2) + requireUnclaimedWarning(games[2].Proxy, honestActor3) + noUnclaimedWarning(games[2].Proxy, dishonestActor4) } type stubWithdrawalsMetrics struct { - matchCalls int - divergeCalls int - matching map[common.Address]int - divergent map[common.Address]int + matchCalls int + divergeCalls int + matching map[common.Address]int + divergent map[common.Address]int + honestWithdrawable map[common.Address]*big.Int +} + +func (s *stubWithdrawalsMetrics) RecordHonestWithdrawableAmounts(honestWithdrawable map[common.Address]*big.Int) { + s.honestWithdrawable = honestWithdrawable } func (s *stubWithdrawalsMetrics) RecordWithdrawalRequests(addr common.Address, matches bool, count int) { From a0d319530b1a47f7eebb06848ffd0c7e45fb540d Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Tue, 10 Sep 2024 07:48:11 +1000 Subject: [PATCH 073/264] cannon: Fix path used when verifying a downloaded state (#11813) --- op-challenger/game/fault/trace/prestates/multi.go | 2 +- op-challenger/game/fault/trace/prestates/multi_test.go | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/op-challenger/game/fault/trace/prestates/multi.go b/op-challenger/game/fault/trace/prestates/multi.go index 5a770fbe1258..8178def730b9 100644 --- a/op-challenger/game/fault/trace/prestates/multi.go +++ b/op-challenger/game/fault/trace/prestates/multi.go @@ -91,7 +91,7 @@ func (m *MultiPrestateProvider) fetchPrestate(hash common.Hash, fileType string, return fmt.Errorf("failed to close file %v: %w", dest, err) } // Verify the prestate actually matches the expected hash before moving it into the final destination - proof, _, _, err := m.stateConverter.ConvertStateToProof(dest) + proof, _, _, err := m.stateConverter.ConvertStateToProof(tmpFile) if err != nil || proof.ClaimValue != hash { // Treat invalid prestates as unavailable. Often servers return a 404 page with 200 status code _ = os.Remove(tmpFile) // Best effort attempt to clean up the temporary file diff --git a/op-challenger/game/fault/trace/prestates/multi_test.go b/op-challenger/game/fault/trace/prestates/multi_test.go index ff979ae50074..830a704b09c1 100644 --- a/op-challenger/game/fault/trace/prestates/multi_test.go +++ b/op-challenger/game/fault/trace/prestates/multi_test.go @@ -167,5 +167,9 @@ type stubStateConverter struct { } func (s *stubStateConverter) ConvertStateToProof(path string) (*utils.ProofData, uint64, bool, error) { + // Return an error if we're given the wrong path + if _, err := os.Stat(path); err != nil { + return nil, 0, false, err + } return &utils.ProofData{ClaimValue: s.hash}, 0, false, s.err } From f64d817692c0e7ed95e151679ea472adff1fdb84 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Tue, 10 Sep 2024 09:28:32 +1000 Subject: [PATCH 074/264] op-service: Make target destination when writing JSON/binary explicit (#11800) Avoids being surprised by the special handling for - and empty string output paths. --- cannon/cmd/load_elf.go | 3 +- cannon/cmd/run.go | 5 +- cannon/serialize/binary.go | 32 ++---- cannon/serialize/binary_test.go | 5 +- cannon/serialize/detect.go | 5 +- op-node/cmd/genesis/cmd.go | 7 +- op-service/ioutil/streams.go | 52 +++++++++ op-service/ioutil/streams_test.go | 100 ++++++++++++++++++ op-service/jsonutil/json.go | 32 ++---- op-service/jsonutil/json_test.go | 9 +- .../supervisor/backend/db/heads/heads.go | 3 +- 11 files changed, 192 insertions(+), 61 deletions(-) create mode 100644 op-service/ioutil/streams.go create mode 100644 op-service/ioutil/streams_test.go diff --git a/cannon/cmd/load_elf.go b/cannon/cmd/load_elf.go index fc337a2d189c..512d4922d17a 100644 --- a/cannon/cmd/load_elf.go +++ b/cannon/cmd/load_elf.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" "github.com/ethereum-optimism/optimism/cannon/serialize" + "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/urfave/cli/v2" "github.com/ethereum-optimism/optimism/cannon/mipsevm/program" @@ -93,7 +94,7 @@ func LoadELF(ctx *cli.Context) error { if err != nil { return fmt.Errorf("failed to compute program metadata: %w", err) } - if err := jsonutil.WriteJSON[*program.Metadata](ctx.Path(LoadELFMetaFlag.Name), meta, OutFilePerm); err != nil { + if err := jsonutil.WriteJSON[*program.Metadata](meta, ioutil.ToStdOutOrFileOrNoop(ctx.Path(LoadELFMetaFlag.Name), OutFilePerm)); err != nil { return fmt.Errorf("failed to output metadata: %w", err) } return writeState(ctx.Path(LoadELFOutFlag.Name), state) diff --git a/cannon/cmd/run.go b/cannon/cmd/run.go index 67b85380cee5..5993f0424c24 100644 --- a/cannon/cmd/run.go +++ b/cannon/cmd/run.go @@ -12,6 +12,7 @@ import ( "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" "github.com/ethereum-optimism/optimism/cannon/serialize" + "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/log" @@ -478,7 +479,7 @@ func Run(ctx *cli.Context) error { proof.OracleValue = witness.PreimageValue proof.OracleOffset = witness.PreimageOffset } - if err := jsonutil.WriteJSON(fmt.Sprintf(proofFmt, step), proof, OutFilePerm); err != nil { + if err := jsonutil.WriteJSON(proof, ioutil.ToStdOutOrFileOrNoop(fmt.Sprintf(proofFmt, step), OutFilePerm)); err != nil { return fmt.Errorf("failed to write proof data: %w", err) } } else { @@ -516,7 +517,7 @@ func Run(ctx *cli.Context) error { return fmt.Errorf("failed to write state output: %w", err) } if debugInfoFile := ctx.Path(RunDebugInfoFlag.Name); debugInfoFile != "" { - if err := jsonutil.WriteJSON(debugInfoFile, vm.GetDebugInfo(), OutFilePerm); err != nil { + if err := jsonutil.WriteJSON(vm.GetDebugInfo(), ioutil.ToStdOutOrFileOrNoop(debugInfoFile, OutFilePerm)); err != nil { return fmt.Errorf("failed to write benchmark data: %w", err) } } diff --git a/cannon/serialize/binary.go b/cannon/serialize/binary.go index c36bc279f1da..62ca54cc2e3a 100644 --- a/cannon/serialize/binary.go +++ b/cannon/serialize/binary.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" "io" - "os" "reflect" "github.com/ethereum-optimism/optimism/op-service/ioutil" @@ -42,33 +41,20 @@ func LoadSerializedBinary[X any](inputPath string) (*X, error) { return &x, nil } -func WriteSerializedBinary(outputPath string, value Serializable, perm os.FileMode) error { - if outputPath == "" { - return nil +func WriteSerializedBinary(value Serializable, target ioutil.OutputTarget) error { + out, closer, abort, err := target() + if err != nil { + return err } - var out io.Writer - finish := func() error { return nil } - if outputPath == "-" { - out = os.Stdout - } else { - f, err := ioutil.NewAtomicWriterCompressed(outputPath, perm) - if err != nil { - return fmt.Errorf("failed to create temp file when writing: %w", err) - } - // Ensure we close the stream without renaming even if failures occur. - defer func() { - _ = f.Abort() - }() - out = f - // Closing the file causes it to be renamed to the final destination - // so make sure we handle any errors it returns - finish = f.Close + if out == nil { + return nil // Nothing to write to so skip generating content entirely } - err := value.Serialize(out) + defer abort() + err = value.Serialize(out) if err != nil { return fmt.Errorf("failed to write binary: %w", err) } - if err := finish(); err != nil { + if err := closer.Close(); err != nil { return fmt.Errorf("failed to finish write: %w", err) } return nil diff --git a/cannon/serialize/binary_test.go b/cannon/serialize/binary_test.go index 0f5794608f98..95700b537c40 100644 --- a/cannon/serialize/binary_test.go +++ b/cannon/serialize/binary_test.go @@ -7,6 +7,7 @@ import ( "path/filepath" "testing" + "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/stretchr/testify/require" ) @@ -14,7 +15,7 @@ func TestRoundTripBinary(t *testing.T) { dir := t.TempDir() file := filepath.Join(dir, "test.bin") data := &serializableTestData{A: []byte{0xde, 0xad}, B: 3} - err := WriteSerializedBinary(file, data, 0644) + err := WriteSerializedBinary(data, ioutil.ToAtomicFile(file, 0644)) require.NoError(t, err) hasGzip, err := hasGzipHeader(file) @@ -30,7 +31,7 @@ func TestRoundTripBinaryWithGzip(t *testing.T) { dir := t.TempDir() file := filepath.Join(dir, "test.bin.gz") data := &serializableTestData{A: []byte{0xde, 0xad}, B: 3} - err := WriteSerializedBinary(file, data, 0644) + err := WriteSerializedBinary(data, ioutil.ToAtomicFile(file, 0644)) require.NoError(t, err) hasGzip, err := hasGzipHeader(file) diff --git a/cannon/serialize/detect.go b/cannon/serialize/detect.go index f84d2c1e0a73..aae13791826f 100644 --- a/cannon/serialize/detect.go +++ b/cannon/serialize/detect.go @@ -4,6 +4,7 @@ import ( "os" "strings" + "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/ethereum-optimism/optimism/op-service/jsonutil" ) @@ -16,9 +17,9 @@ func Load[X any](inputPath string) (*X, error) { func Write[X Serializable](outputPath string, x X, perm os.FileMode) error { if isBinary(outputPath) { - return WriteSerializedBinary(outputPath, x, perm) + return WriteSerializedBinary(x, ioutil.ToStdOutOrFileOrNoop(outputPath, perm)) } - return jsonutil.WriteJSON[X](outputPath, x, perm) + return jsonutil.WriteJSON[X](x, ioutil.ToStdOutOrFileOrNoop(outputPath, perm)) } func isBinary(path string) bool { diff --git a/op-node/cmd/genesis/cmd.go b/op-node/cmd/genesis/cmd.go index 6d11fd8e7f5e..109d239b87d5 100644 --- a/op-node/cmd/genesis/cmd.go +++ b/op-node/cmd/genesis/cmd.go @@ -5,6 +5,7 @@ import ( "fmt" "time" + "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/ethereum-optimism/optimism/op-service/retry" "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/urfave/cli/v2" @@ -120,7 +121,7 @@ var Subcommands = cli.Commands{ return err } - return jsonutil.WriteJSON(ctx.String(outfileL1Flag.Name), l1Genesis, 0o666) + return jsonutil.WriteJSON(l1Genesis, ioutil.ToStdOutOrFileOrNoop(ctx.String(outfileL1Flag.Name), 0o666)) }, }, { @@ -204,10 +205,10 @@ var Subcommands = cli.Commands{ return fmt.Errorf("generated rollup config does not pass validation: %w", err) } - if err := jsonutil.WriteJSON(ctx.String(outfileL2Flag.Name), l2Genesis, 0o666); err != nil { + if err := jsonutil.WriteJSON(l2Genesis, ioutil.ToAtomicFile(ctx.String(outfileL2Flag.Name), 0o666)); err != nil { return err } - return jsonutil.WriteJSON(ctx.String(outfileRollupFlag.Name), rollupConfig, 0o666) + return jsonutil.WriteJSON(rollupConfig, ioutil.ToAtomicFile(ctx.String(outfileRollupFlag.Name), 0o666)) }, }, } diff --git a/op-service/ioutil/streams.go b/op-service/ioutil/streams.go new file mode 100644 index 000000000000..91f122906db0 --- /dev/null +++ b/op-service/ioutil/streams.go @@ -0,0 +1,52 @@ +package ioutil + +import ( + "io" + "os" +) + +var ( + stdOutStream OutputTarget = func() (io.Writer, io.Closer, Aborter, error) { + return os.Stdout, &noopCloser{}, func() {}, nil + } +) + +type Aborter func() + +type OutputTarget func() (io.Writer, io.Closer, Aborter, error) + +func NoOutputStream() OutputTarget { + return func() (io.Writer, io.Closer, Aborter, error) { + return nil, nil, nil, nil + } +} + +func ToAtomicFile(path string, perm os.FileMode) OutputTarget { + return func() (io.Writer, io.Closer, Aborter, error) { + f, err := NewAtomicWriterCompressed(path, perm) + if err != nil { + return nil, nil, nil, err + } + return f, f, func() { _ = f.Abort() }, nil + } +} + +func ToStdOut() OutputTarget { + return stdOutStream +} + +func ToStdOutOrFileOrNoop(outputPath string, perm os.FileMode) OutputTarget { + if outputPath == "" { + return NoOutputStream() + } else if outputPath == "-" { + return ToStdOut() + } else { + return ToAtomicFile(outputPath, perm) + } +} + +type noopCloser struct{} + +func (c *noopCloser) Close() error { + return nil +} diff --git a/op-service/ioutil/streams_test.go b/op-service/ioutil/streams_test.go new file mode 100644 index 000000000000..cbbed7e62171 --- /dev/null +++ b/op-service/ioutil/streams_test.go @@ -0,0 +1,100 @@ +package ioutil + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNoOutputStream(t *testing.T) { + writer, closer, aborter, err := NoOutputStream()() + require.NoError(t, err) + require.Nil(t, writer) + require.Nil(t, closer) + require.Nil(t, aborter) +} + +func TestToStdOut(t *testing.T) { + writer, closer, aborter, err := ToStdOut()() + require.NoError(t, err) + require.Same(t, os.Stdout, writer) + + // Should not close StdOut + require.NoError(t, closer.Close()) + _, err = os.Stdout.WriteString("TestToStdOut After Close\n") + require.NoError(t, err) + + aborter() + _, err = os.Stdout.WriteString("TestToStdOut After Abort\n") + require.NoError(t, err) +} + +func TestToAtomicFile(t *testing.T) { + t.Run("Abort", func(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, "test.txt") + writer, closer, aborter, err := ToAtomicFile(path, 0o644)() + defer closer.Close() + require.NoError(t, err) + + expected := []byte("test") + _, err = writer.Write(expected) + require.NoError(t, err) + aborter() + + _, err = os.Stat(path) + require.ErrorIs(t, err, os.ErrNotExist, "Should not have written file") + }) + + t.Run("Close", func(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, "test.txt") + writer, closer, _, err := ToAtomicFile(path, 0o644)() + defer closer.Close() + require.NoError(t, err) + + expected := []byte("test") + _, err = writer.Write(expected) + require.NoError(t, err) + + _, err = os.Stat(path) + require.ErrorIs(t, err, os.ErrNotExist, "Target file should not exist prior to Close") + + require.NoError(t, closer.Close()) + actual, err := os.ReadFile(path) + require.NoError(t, err) + require.Equal(t, expected, actual) + }) +} + +func TestToStdOutOrFileOrNoop(t *testing.T) { + t.Run("EmptyOutputPath", func(t *testing.T) { + writer, _, _, err := ToStdOutOrFileOrNoop("", 0o644)() + require.NoError(t, err) + require.Nil(t, writer, "Should use no output stream") + }) + + t.Run("StdOut", func(t *testing.T) { + writer, _, _, err := ToStdOutOrFileOrNoop("-", 0o644)() + require.NoError(t, err) + require.Same(t, os.Stdout, writer, "Should use std out") + }) + + t.Run("File", func(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, "test.txt") + writer, closer, _, err := ToStdOutOrFileOrNoop(path, 0o644)() + defer closer.Close() + require.NoError(t, err) + + expected := []byte("test") + _, err = writer.Write(expected) + require.NoError(t, err) + require.NoError(t, closer.Close()) + actual, err := os.ReadFile(path) + require.NoError(t, err) + require.Equal(t, expected, actual) + }) +} diff --git a/op-service/jsonutil/json.go b/op-service/jsonutil/json.go index 922e8ff79350..5f2a8596a6be 100644 --- a/op-service/jsonutil/json.go +++ b/op-service/jsonutil/json.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "os" "github.com/ethereum-optimism/optimism/op-service/ioutil" ) @@ -32,38 +31,25 @@ func LoadJSON[X any](inputPath string) (*X, error) { return &state, nil } -func WriteJSON[X any](outputPath string, value X, perm os.FileMode) error { - if outputPath == "" { - return nil +func WriteJSON[X any](value X, target ioutil.OutputTarget) error { + out, closer, abort, err := target() + if err != nil { + return err } - var out io.Writer - finish := func() error { return nil } - if outputPath == "-" { - out = os.Stdout - } else { - f, err := ioutil.NewAtomicWriterCompressed(outputPath, perm) - if err != nil { - return fmt.Errorf("failed to open output file: %w", err) - } - // Ensure we close the stream without renaming even if failures occur. - defer func() { - _ = f.Abort() - }() - out = f - // Closing the file causes it to be renamed to the final destination - // so make sure we handle any errors it returns - finish = f.Close + if out == nil { + return nil // No output stream selected so skip generating the content entirely } + defer abort() enc := json.NewEncoder(out) enc.SetIndent("", " ") if err := enc.Encode(value); err != nil { return fmt.Errorf("failed to encode to JSON: %w", err) } - _, err := out.Write([]byte{'\n'}) + _, err = out.Write([]byte{'\n'}) if err != nil { return fmt.Errorf("failed to append new-line: %w", err) } - if err := finish(); err != nil { + if err := closer.Close(); err != nil { return fmt.Errorf("failed to finish write: %w", err) } return nil diff --git a/op-service/jsonutil/json_test.go b/op-service/jsonutil/json_test.go index 9a143d0c2579..b8da7d8de70f 100644 --- a/op-service/jsonutil/json_test.go +++ b/op-service/jsonutil/json_test.go @@ -7,6 +7,7 @@ import ( "path/filepath" "testing" + "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/stretchr/testify/require" ) @@ -14,7 +15,7 @@ func TestRoundTripJSON(t *testing.T) { dir := t.TempDir() file := filepath.Join(dir, "test.json") data := &jsonTestData{A: "yay", B: 3} - err := WriteJSON(file, data, 0o755) + err := WriteJSON(data, ioutil.ToAtomicFile(file, 0o755)) require.NoError(t, err) // Confirm the file is uncompressed @@ -33,7 +34,7 @@ func TestRoundTripJSONWithGzip(t *testing.T) { dir := t.TempDir() file := filepath.Join(dir, "test.json.gz") data := &jsonTestData{A: "yay", B: 3} - err := WriteJSON(file, data, 0o755) + err := WriteJSON(data, ioutil.ToAtomicFile(file, 0o755)) require.NoError(t, err) // Confirm the file isn't raw JSON @@ -87,7 +88,7 @@ func TestLoadJSONWithExtraDataAppended(t *testing.T) { require.NoError(t, err) // Write primary json payload + extra data to the file - err = WriteJSON(file, data, 0o755) + err = WriteJSON(data, ioutil.ToAtomicFile(file, 0o755)) require.NoError(t, err) err = appendDataToFile(file, extraData) require.NoError(t, err) @@ -130,7 +131,7 @@ func TestLoadJSONWithTrailingWhitespace(t *testing.T) { data := &jsonTestData{A: "yay", B: 3} // Write primary json payload + extra data to the file - err := WriteJSON(file, data, 0o755) + err := WriteJSON(data, ioutil.ToAtomicFile(file, 0o755)) require.NoError(t, err) err = appendDataToFile(file, tc.extraData) require.NoError(t, err) diff --git a/op-supervisor/supervisor/backend/db/heads/heads.go b/op-supervisor/supervisor/backend/db/heads/heads.go index 65d1cb42abcc..7504806c0435 100644 --- a/op-supervisor/supervisor/backend/db/heads/heads.go +++ b/op-supervisor/supervisor/backend/db/heads/heads.go @@ -7,6 +7,7 @@ import ( "os" "sync" + "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/ethereum-optimism/optimism/op-service/jsonutil" ) @@ -58,7 +59,7 @@ func (t *HeadTracker) Current() *Heads { } func (t *HeadTracker) write(heads *Heads) error { - if err := jsonutil.WriteJSON(t.path, heads, 0o644); err != nil { + if err := jsonutil.WriteJSON(heads, ioutil.ToAtomicFile(t.path, 0o644)); err != nil { return fmt.Errorf("failed to write new heads: %w", err) } return nil From af78eddecbf64c7a0f0d06979b2c32cbc511bcb5 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Mon, 9 Sep 2024 19:46:32 -0400 Subject: [PATCH 075/264] maint: add interface for L2OutputOracle (#11817) First in a series of PRs adding interfaces for L2 contracts. Since each of these changes involves touching a lot of other contracts it seemed easier to split this up into several PRs for legibility. --- .../invariant-docs/OptimismPortal.md | 8 +-- .../scripts/deploy/ChainAssertions.sol | 4 +- .../scripts/deploy/Deploy.s.sol | 31 +++++++---- packages/contracts-bedrock/semver-lock.json | 4 +- .../snapshots/abi/OptimismPortal.json | 4 +- .../storageLayout/OptimismPortal.json | 2 +- .../src/L1/L2OutputOracle.sol | 7 ++- .../src/L1/OptimismPortal.sol | 8 +-- .../src/L1/interfaces/IL2OutputOracle.sol | 53 +++++++++++++++++++ .../test/L1/L2OutputOracle.t.sol | 3 +- .../test/L1/OptimismPortal.t.sol | 16 +++--- packages/contracts-bedrock/test/Specs.t.sol | 3 +- .../dispute/PermissionedDisputeGame.t.sol | 1 - .../test/invariants/L2OutputOracle.t.sol | 8 +-- .../test/invariants/OptimismPortal.t.sol | 1 - .../contracts-bedrock/test/setup/Setup.sol | 6 +-- .../test/vendor/Initializable.t.sol | 1 - 17 files changed, 115 insertions(+), 45 deletions(-) create mode 100644 packages/contracts-bedrock/src/L1/interfaces/IL2OutputOracle.sol diff --git a/packages/contracts-bedrock/invariant-docs/OptimismPortal.md b/packages/contracts-bedrock/invariant-docs/OptimismPortal.md index 07347e58bd77..c13d0212128d 100644 --- a/packages/contracts-bedrock/invariant-docs/OptimismPortal.md +++ b/packages/contracts-bedrock/invariant-docs/OptimismPortal.md @@ -1,21 +1,21 @@ # `OptimismPortal` Invariants ## Deposits of any value should always succeed unless `_to` = `address(0)` or `_isCreation` = `true`. -**Test:** [`OptimismPortal.t.sol#L149`](../test/invariants/OptimismPortal.t.sol#L149) +**Test:** [`OptimismPortal.t.sol#L148`](../test/invariants/OptimismPortal.t.sol#L148) All deposits, barring creation transactions and transactions sent to `address(0)`, should always succeed. ## `finalizeWithdrawalTransaction` should revert if the finalization period has not elapsed. -**Test:** [`OptimismPortal.t.sol#L172`](../test/invariants/OptimismPortal.t.sol#L172) +**Test:** [`OptimismPortal.t.sol#L171`](../test/invariants/OptimismPortal.t.sol#L171) A withdrawal that has been proven should not be able to be finalized until after the finalization period has elapsed. ## `finalizeWithdrawalTransaction` should revert if the withdrawal has already been finalized. -**Test:** [`OptimismPortal.t.sol#L202`](../test/invariants/OptimismPortal.t.sol#L202) +**Test:** [`OptimismPortal.t.sol#L201`](../test/invariants/OptimismPortal.t.sol#L201) Ensures that there is no chain of calls that can be made that allows a withdrawal to be finalized twice. ## A withdrawal should **always** be able to be finalized `FINALIZATION_PERIOD_SECONDS` after it was successfully proven. -**Test:** [`OptimismPortal.t.sol#L231`](../test/invariants/OptimismPortal.t.sol#L231) +**Test:** [`OptimismPortal.t.sol#L230`](../test/invariants/OptimismPortal.t.sol#L230) This invariant asserts that there is no chain of calls that can be made that will prevent a withdrawal from being finalized exactly `FINALIZATION_PERIOD_SECONDS` after it was successfully proven. \ No newline at end of file diff --git a/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol b/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol index 2a9f78940577..ce10bb0993f7 100644 --- a/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol +++ b/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol @@ -8,7 +8,7 @@ import { Deployer } from "scripts/deploy/Deployer.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { Constants } from "src/libraries/Constants.sol"; import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; -import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; +import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; import { ProtocolVersion, ProtocolVersions } from "src/L1/ProtocolVersions.sol"; @@ -245,7 +245,7 @@ library ChainAssertions { view { console.log("Running chain assertions on the L2OutputOracle"); - L2OutputOracle oracle = L2OutputOracle(_contracts.L2OutputOracle); + IL2OutputOracle oracle = IL2OutputOracle(_contracts.L2OutputOracle); // Check that the contract is initialized assertSlotValueIsOne({ _contractAddress: address(oracle), _slot: 0, _offset: 0 }); diff --git a/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol b/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol index 6c70faab1e79..659eb2b338dd 100644 --- a/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol @@ -25,7 +25,7 @@ import { OptimismPortalInterop } from "src/L1/OptimismPortalInterop.sol"; import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol"; import { ResolvedDelegateProxy } from "src/legacy/ResolvedDelegateProxy.sol"; import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; -import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; +import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; @@ -697,11 +697,7 @@ contract Deploy is Deployer { /// @notice Deploy the L2OutputOracle function deployL2OutputOracle() public broadcast returns (address addr_) { - console.log("Deploying L2OutputOracle implementation"); - L2OutputOracle oracle = new L2OutputOracle{ salt: _implSalt() }(); - - save("L2OutputOracle", address(oracle)); - console.log("L2OutputOracle deployed at %s", address(oracle)); + IL2OutputOracle oracle = IL2OutputOracle(_deploy("L2OutputOracle", hex"")); // Override the `L2OutputOracle` contract to the deployed implementation. This is necessary // to check the `L2OutputOracle` implementation alongside dependent contracts, which @@ -1235,7 +1231,7 @@ contract Deploy is Deployer { _proxy: payable(l2OutputOracleProxy), _implementation: l2OutputOracle, _innerCallData: abi.encodeCall( - L2OutputOracle.initialize, + IL2OutputOracle.initialize, ( cfg.l2OutputOracleSubmissionInterval(), cfg.l2BlockTime(), @@ -1248,7 +1244,7 @@ contract Deploy is Deployer { ) }); - L2OutputOracle oracle = L2OutputOracle(l2OutputOracleProxy); + IL2OutputOracle oracle = IL2OutputOracle(l2OutputOracleProxy); string memory version = oracle.version(); console.log("L2OutputOracle version: %s", version); @@ -1275,7 +1271,7 @@ contract Deploy is Deployer { _innerCallData: abi.encodeCall( OptimismPortal.initialize, ( - L2OutputOracle(l2OutputOracleProxy), + IL2OutputOracle(l2OutputOracleProxy), SystemConfig(systemConfigProxy), SuperchainConfig(superchainConfigProxy) ) @@ -1615,4 +1611,21 @@ contract Deploy is Deployer { require(dac.bondSize() == daBondSize); require(dac.resolverRefundPercentage() == daResolverRefundPercentage); } + + /// @notice Deploys a contract via CREATE2. + /// @param _name The name of the contract. + /// @param _constructorParams The constructor parameters. + function _deploy(string memory _name, bytes memory _constructorParams) internal returns (address addr_) { + console.log("Deploying %s", _name); + bytes32 salt = _implSalt(); + bytes memory initCode = abi.encodePacked(vm.getCode(_name), _constructorParams); + address preComputedAddress = vm.computeCreate2Address(salt, keccak256(initCode)); + require(preComputedAddress.code.length == 0, "Deploy: contract already deployed"); + assembly { + addr_ := create2(0, add(initCode, 0x20), mload(initCode), salt) + } + require(addr_ != address(0), "deployment failed"); + save(_name, addr_); + console.log("%s deployed at %s", _name, addr_); + } } diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 1fc5131c4581..96db34d38ed1 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -29,7 +29,7 @@ }, "src/L1/L2OutputOracle.sol": { "initCodeHash": "0x433fac9de52d8ce8fc3471b78ef6cc9cff1019f480c9ad91b6e09ab8738a8edb", - "sourceCodeHash": "0xc11a2a514a051bdc82b21ec39c7b923145d384629adb1efc52b534f3c686f6a0" + "sourceCodeHash": "0xde4df0f9633dc0cdb1c9f634003ea5b0f7c5c1aebc407bc1b2f44c0ecf938649" }, "src/L1/OPStackManager.sol": { "initCodeHash": "0x67bf02405bf1ca7d78c4215c350ad9c5c7b4cece35d9fab837f279d65f995c5d", @@ -37,7 +37,7 @@ }, "src/L1/OptimismPortal.sol": { "initCodeHash": "0x6bf59539298b20221de6c51db21016be8d3278bdbe0be1cdd49638dc828e003e", - "sourceCodeHash": "0xad97b31e3855ad0af82a0fc80db9773b7eacc85215611854dcc54f60f97f06bf" + "sourceCodeHash": "0x07f6f4c0cc14be4aeb9a29ec4a238ea3748d5cb6b244e0054845a18308c16ab5" }, "src/L1/OptimismPortal2.sol": { "initCodeHash": "0x414ad1fdb6296ac32fc67ce01288b6e67bedd2ed239d7eb8ed40c7f55f9021f2", diff --git a/packages/contracts-bedrock/snapshots/abi/OptimismPortal.json b/packages/contracts-bedrock/snapshots/abi/OptimismPortal.json index 88531b87da44..12ab9e26b9b3 100644 --- a/packages/contracts-bedrock/snapshots/abi/OptimismPortal.json +++ b/packages/contracts-bedrock/snapshots/abi/OptimismPortal.json @@ -179,7 +179,7 @@ { "inputs": [ { - "internalType": "contract L2OutputOracle", + "internalType": "contract IL2OutputOracle", "name": "_l2Oracle", "type": "address" }, @@ -223,7 +223,7 @@ "name": "l2Oracle", "outputs": [ { - "internalType": "contract L2OutputOracle", + "internalType": "contract IL2OutputOracle", "name": "", "type": "address" } diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal.json b/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal.json index 6eff1d1a0790..3795f987b280 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal.json @@ -67,7 +67,7 @@ "label": "l2Oracle", "offset": 0, "slot": "54", - "type": "contract L2OutputOracle" + "type": "contract IL2OutputOracle" }, { "bytes": "20", diff --git a/packages/contracts-bedrock/src/L1/L2OutputOracle.sol b/packages/contracts-bedrock/src/L1/L2OutputOracle.sol index b964664ab0cb..fb8d681227bf 100644 --- a/packages/contracts-bedrock/src/L1/L2OutputOracle.sol +++ b/packages/contracts-bedrock/src/L1/L2OutputOracle.sol @@ -1,11 +1,16 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Contracts import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; -import { ISemver } from "src/universal/interfaces/ISemver.sol"; + +// Libraries import { Types } from "src/libraries/Types.sol"; import { Constants } from "src/libraries/Constants.sol"; +// Interfaces +import { ISemver } from "src/universal/interfaces/ISemver.sol"; + /// @custom:proxied true /// @title L2OutputOracle /// @notice The L2OutputOracle contains an array of L2 state outputs, where each output is a diff --git a/packages/contracts-bedrock/src/L1/OptimismPortal.sol b/packages/contracts-bedrock/src/L1/OptimismPortal.sol index 94931bdd2910..517131d400cc 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortal.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortal.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import { SafeCall } from "src/libraries/SafeCall.sol"; -import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; +import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { Constants } from "src/libraries/Constants.sol"; @@ -68,7 +68,7 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver { /// @notice Contract of the L2OutputOracle. /// @custom:network-specific - L2OutputOracle public l2Oracle; + IL2OutputOracle public l2Oracle; /// @notice Contract of the SystemConfig. /// @custom:network-specific @@ -136,7 +136,7 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver { /// @notice Constructs the OptimismPortal contract. constructor() { initialize({ - _l2Oracle: L2OutputOracle(address(0)), + _l2Oracle: IL2OutputOracle(address(0)), _systemConfig: SystemConfig(address(0)), _superchainConfig: SuperchainConfig(address(0)) }); @@ -147,7 +147,7 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver { /// @param _systemConfig Contract of the SystemConfig. /// @param _superchainConfig Contract of the SuperchainConfig. function initialize( - L2OutputOracle _l2Oracle, + IL2OutputOracle _l2Oracle, SystemConfig _systemConfig, SuperchainConfig _superchainConfig ) diff --git a/packages/contracts-bedrock/src/L1/interfaces/IL2OutputOracle.sol b/packages/contracts-bedrock/src/L1/interfaces/IL2OutputOracle.sol new file mode 100644 index 000000000000..22b66ee22264 --- /dev/null +++ b/packages/contracts-bedrock/src/L1/interfaces/IL2OutputOracle.sol @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { Types } from "src/libraries/Types.sol"; + +interface IL2OutputOracle { + event Initialized(uint8 version); + event OutputProposed( + bytes32 indexed outputRoot, uint256 indexed l2OutputIndex, uint256 indexed l2BlockNumber, uint256 l1Timestamp + ); + event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex); + + function CHALLENGER() external view returns (address); + function FINALIZATION_PERIOD_SECONDS() external view returns (uint256); + function L2_BLOCK_TIME() external view returns (uint256); + function PROPOSER() external view returns (address); + function SUBMISSION_INTERVAL() external view returns (uint256); + function challenger() external view returns (address); + function computeL2Timestamp(uint256 _l2BlockNumber) external view returns (uint256); + function deleteL2Outputs(uint256 _l2OutputIndex) external; + function finalizationPeriodSeconds() external view returns (uint256); + function getL2Output(uint256 _l2OutputIndex) external view returns (Types.OutputProposal memory); + function getL2OutputAfter(uint256 _l2BlockNumber) external view returns (Types.OutputProposal memory); + function getL2OutputIndexAfter(uint256 _l2BlockNumber) external view returns (uint256); + function initialize( + uint256 _submissionInterval, + uint256 _l2BlockTime, + uint256 _startingBlockNumber, + uint256 _startingTimestamp, + address _proposer, + address _challenger, + uint256 _finalizationPeriodSeconds + ) + external; + function l2BlockTime() external view returns (uint256); + function latestBlockNumber() external view returns (uint256); + function latestOutputIndex() external view returns (uint256); + function nextBlockNumber() external view returns (uint256); + function nextOutputIndex() external view returns (uint256); + function proposeL2Output( + bytes32 _outputRoot, + uint256 _l2BlockNumber, + bytes32 _l1BlockHash, + uint256 _l1BlockNumber + ) + external + payable; + function proposer() external view returns (address); + function startingBlockNumber() external view returns (uint256); + function startingTimestamp() external view returns (uint256); + function submissionInterval() external view returns (uint256); + function version() external view returns (string memory); +} diff --git a/packages/contracts-bedrock/test/L1/L2OutputOracle.t.sol b/packages/contracts-bedrock/test/L1/L2OutputOracle.t.sol index 3d89809e9b30..7acca0fae187 100644 --- a/packages/contracts-bedrock/test/L1/L2OutputOracle.t.sol +++ b/packages/contracts-bedrock/test/L1/L2OutputOracle.t.sol @@ -16,11 +16,12 @@ import { Proxy } from "src/universal/Proxy.sol"; // Target contract import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; +import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; contract L2OutputOracle_constructor_Test is CommonTest { /// @dev Tests that constructor sets the initial values correctly. function test_constructor_succeeds() external { - L2OutputOracle oracleImpl = new L2OutputOracle(); + IL2OutputOracle oracleImpl = IL2OutputOracle(address(new L2OutputOracle())); assertEq(oracleImpl.SUBMISSION_INTERVAL(), 1); assertEq(oracleImpl.submissionInterval(), 1); diff --git a/packages/contracts-bedrock/test/L1/OptimismPortal.t.sol b/packages/contracts-bedrock/test/L1/OptimismPortal.t.sol index 474c052a4016..49991aee21f5 100644 --- a/packages/contracts-bedrock/test/L1/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/L1/OptimismPortal.t.sol @@ -18,7 +18,7 @@ import { Constants } from "src/libraries/Constants.sol"; import { Proxy } from "src/universal/Proxy.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; -import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; +import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { L1Block } from "src/L2/L1Block.sol"; @@ -403,7 +403,7 @@ contract OptimismPortal_Test is CommonTest { uint256 ts = block.timestamp; vm.mockCall( address(optimismPortal.l2Oracle()), - abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), + abi.encodeWithSelector(IL2OutputOracle.getL2Output.selector), abi.encode(Types.OutputProposal(bytes32(uint256(1)), uint128(ts), uint128(startingBlockNumber))) ); @@ -831,7 +831,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is CommonTest { // this case we just use bytes32(uint256(1)). vm.mockCall( address(optimismPortal.l2Oracle()), - abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), + abi.encodeWithSelector(IL2OutputOracle.getL2Output.selector), abi.encode(bytes32(uint256(1)), _proposedBlockNumber) ); @@ -886,7 +886,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is CommonTest { // to finalize the withdrawal. vm.mockCall( address(optimismPortal.l2Oracle()), - abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), + abi.encodeWithSelector(IL2OutputOracle.getL2Output.selector), abi.encode( Types.OutputProposal(bytes32(uint256(0)), uint128(block.timestamp), uint128(_proposedBlockNumber)) ) @@ -917,7 +917,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is CommonTest { // finalization period. vm.mockCall( address(optimismPortal.l2Oracle()), - abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), + abi.encodeWithSelector(IL2OutputOracle.getL2Output.selector), abi.encode(Types.OutputProposal(_outputRoot, uint128(block.timestamp + 1), uint128(_proposedBlockNumber))) ); @@ -953,7 +953,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is CommonTest { uint256 recentTimestamp = block.timestamp - 1; vm.mockCall( address(optimismPortal.l2Oracle()), - abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), + abi.encodeWithSelector(IL2OutputOracle.getL2Output.selector), abi.encode(Types.OutputProposal(_outputRoot, uint128(recentTimestamp), uint128(_proposedBlockNumber))) ); @@ -1005,7 +1005,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is CommonTest { vm.mockCall( address(optimismPortal.l2Oracle()), - abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), + abi.encodeWithSelector(IL2OutputOracle.getL2Output.selector), abi.encode( Types.OutputProposal( Hashing.hashOutputRootProof(outputRootProof), @@ -1054,7 +1054,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is CommonTest { uint256 finalizedTimestamp = block.timestamp - l2OutputOracle.FINALIZATION_PERIOD_SECONDS() - 1; vm.mockCall( address(optimismPortal.l2Oracle()), - abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), + abi.encodeWithSelector(IL2OutputOracle.getL2Output.selector), abi.encode(Types.OutputProposal(outputRoot, uint128(finalizedTimestamp), uint128(_proposedBlockNumber))) ); diff --git a/packages/contracts-bedrock/test/Specs.t.sol b/packages/contracts-bedrock/test/Specs.t.sol index ecba915d9cf2..6fac763938fb 100644 --- a/packages/contracts-bedrock/test/Specs.t.sol +++ b/packages/contracts-bedrock/test/Specs.t.sol @@ -907,10 +907,11 @@ contract Specification_Test is CommonTest { /// @notice Ensures that there's an auth spec for every L1 contract function. function testContractAuth() public { - string[] memory pathExcludes = new string[](3); + string[] memory pathExcludes = new string[](4); pathExcludes[0] = "src/dispute/interfaces/*"; pathExcludes[1] = "src/dispute/lib/*"; pathExcludes[2] = "src/Safe/SafeSigners.sol"; + pathExcludes[3] = "src/L1/interfaces/*"; Abi[] memory abis = ForgeArtifacts.getContractFunctionAbis( "src/{L1,dispute,governance,Safe,universal/ProxyAdmin.sol}", pathExcludes ); diff --git a/packages/contracts-bedrock/test/dispute/PermissionedDisputeGame.t.sol b/packages/contracts-bedrock/test/dispute/PermissionedDisputeGame.t.sol index 5d3fc6f70f79..7e118b1efb53 100644 --- a/packages/contracts-bedrock/test/dispute/PermissionedDisputeGame.t.sol +++ b/packages/contracts-bedrock/test/dispute/PermissionedDisputeGame.t.sol @@ -7,7 +7,6 @@ import { DisputeGameFactory_Init } from "test/dispute/DisputeGameFactory.t.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; -import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { PreimageKeyLib } from "src/cannon/PreimageKeyLib.sol"; diff --git a/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol b/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol index 5152d7688be2..95eac249a5ba 100644 --- a/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol +++ b/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol @@ -2,14 +2,14 @@ pragma solidity 0.8.15; import { CommonTest } from "test/setup/CommonTest.sol"; -import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; +import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; import { Vm } from "forge-std/Vm.sol"; contract L2OutputOracle_Proposer { - L2OutputOracle internal oracle; + IL2OutputOracle internal oracle; Vm internal vm; - constructor(L2OutputOracle _oracle, Vm _vm) { + constructor(IL2OutputOracle _oracle, Vm _vm) { oracle = _oracle; vm = _vm; } @@ -36,7 +36,7 @@ contract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is CommonTest { super.setUp(); // Create a proposer actor. - actor = new L2OutputOracle_Proposer(l2OutputOracle, vm); + actor = new L2OutputOracle_Proposer(IL2OutputOracle(address(l2OutputOracle)), vm); // Set the target contract to the proposer actor. targetContract(address(actor)); diff --git a/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol b/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol index 804de4320286..0dc020f9d7fa 100644 --- a/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol @@ -5,7 +5,6 @@ import { StdUtils } from "forge-std/Test.sol"; import { Vm } from "forge-std/Vm.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol"; -import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { Constants } from "src/libraries/Constants.sol"; diff --git a/packages/contracts-bedrock/test/setup/Setup.sol b/packages/contracts-bedrock/test/setup/Setup.sol index 325281f890df..a39c996d7bfe 100644 --- a/packages/contracts-bedrock/test/setup/Setup.sol +++ b/packages/contracts-bedrock/test/setup/Setup.sol @@ -29,7 +29,7 @@ import { Deploy } from "scripts/deploy/Deploy.s.sol"; import { Fork, LATEST_FORK } from "scripts/libraries/Config.sol"; import { L2Genesis, L1Dependencies } from "scripts/L2Genesis.s.sol"; import { OutputMode, Fork, ForkUtils } from "scripts/libraries/Config.sol"; -import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; +import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; @@ -69,7 +69,7 @@ contract Setup { OptimismPortal2 optimismPortal2; DisputeGameFactory disputeGameFactory; DelayedWETH delayedWeth; - L2OutputOracle l2OutputOracle; + IL2OutputOracle l2OutputOracle; SystemConfig systemConfig; L1StandardBridge l1StandardBridge; L1CrossDomainMessenger l1CrossDomainMessenger; @@ -135,7 +135,7 @@ contract Setup { optimismPortal2 = OptimismPortal2(deploy.mustGetAddress("OptimismPortalProxy")); disputeGameFactory = DisputeGameFactory(deploy.mustGetAddress("DisputeGameFactoryProxy")); delayedWeth = DelayedWETH(deploy.mustGetAddress("DelayedWETHProxy")); - l2OutputOracle = L2OutputOracle(deploy.mustGetAddress("L2OutputOracleProxy")); + l2OutputOracle = IL2OutputOracle(deploy.mustGetAddress("L2OutputOracleProxy")); systemConfig = SystemConfig(deploy.mustGetAddress("SystemConfigProxy")); l1StandardBridge = L1StandardBridge(deploy.mustGetAddress("L1StandardBridgeProxy")); l1CrossDomainMessenger = L1CrossDomainMessenger(deploy.mustGetAddress("L1CrossDomainMessengerProxy")); diff --git a/packages/contracts-bedrock/test/vendor/Initializable.t.sol b/packages/contracts-bedrock/test/vendor/Initializable.t.sol index 9671e024bc19..1f3ab1951ae3 100644 --- a/packages/contracts-bedrock/test/vendor/Initializable.t.sol +++ b/packages/contracts-bedrock/test/vendor/Initializable.t.sol @@ -6,7 +6,6 @@ import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { Executables } from "scripts/libraries/Executables.sol"; import { Constants } from "src/libraries/Constants.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { SystemConfigInterop } from "src/L1/SystemConfigInterop.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; From 21161265426f80b742c5cadcafbb092612e3c43d Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Tue, 10 Sep 2024 10:00:30 +1000 Subject: [PATCH 076/264] cannon: Autodetect VM type from state (#11803) * cannon: Autodetect VM type from state in run command * cannon: Autodetect VM type from state in witness command * cannon: Remove vm type flag from run and witness * cannon: Only peek the version byte * cannon: Move all version handling to VersionedState, simplify a lot and forbid serializing multithreaded states to JSON * cannon: Rename method * op-challenger: Update cannon state parsing to use version detecting methods * cannon: Move CreateVM to FPVMState for simplicity Test read/write/create for VersionedState * cannon: Readd detect_test * cannon: Remove json names from multithreaded.State. Multithreaded states always use binary serialization. * cannon: Move vmtype to load_elf since it is no longer shared. * cannon: Ensure metadata is available and sleepCheck used even if debug is disabled. * op-challenger: Update canon state loading test to cover multiple state versions. --- Makefile | 2 +- cannon/cmd/load_elf.go | 41 +++-- cannon/cmd/run.go | 55 ++----- cannon/cmd/vmtype.go | 29 ---- cannon/cmd/witness.go | 26 +--- cannon/mipsevm/exec/stack.go | 7 +- cannon/mipsevm/iface.go | 16 ++ cannon/mipsevm/multithreaded/instrumented.go | 20 +-- .../multithreaded/instrumented_test.go | 6 +- cannon/mipsevm/multithreaded/stack.go | 6 +- cannon/mipsevm/multithreaded/state.go | 45 +++--- cannon/mipsevm/program/metadata.go | 8 +- cannon/mipsevm/singlethreaded/instrumented.go | 21 +-- cannon/mipsevm/singlethreaded/state.go | 17 +-- .../mipsevm/tests/evm_multithreaded_test.go | 2 +- cannon/mipsevm/tests/helpers.go | 6 +- cannon/mipsevm/versions/state.go | 97 ++++++++++++ cannon/mipsevm/versions/state_test.go | 76 +++++++++ cannon/serialize/binary.go | 11 +- cannon/serialize/detect.go | 11 +- cannon/serialize/detect_test.go | 6 +- .../fault/trace/cannon/state_converter.go | 10 +- .../trace/cannon/state_converter_test.go | 144 ++++++++++-------- .../fault/trace/cannon/test_data/invalid.json | 3 - .../fault/trace/cannon/test_data/state.json | 14 -- op-e2e/faultproofs/precompile_test.go | 11 +- 26 files changed, 397 insertions(+), 293 deletions(-) delete mode 100644 cannon/cmd/vmtype.go create mode 100644 cannon/mipsevm/versions/state_test.go delete mode 100644 op-challenger/game/fault/trace/cannon/test_data/invalid.json delete mode 100644 op-challenger/game/fault/trace/cannon/test_data/state.json diff --git a/Makefile b/Makefile index a59b06a42de2..7450895a079a 100644 --- a/Makefile +++ b/Makefile @@ -147,7 +147,7 @@ cannon-prestate: op-program cannon ## Generates prestate using cannon and op-pro cannon-prestate-mt: op-program cannon ## Generates prestate using cannon and op-program in the multithreaded cannon format ./cannon/bin/cannon load-elf --type cannon-mt --path op-program/bin/op-program-client.elf --out op-program/bin/prestate-mt.bin.gz --meta op-program/bin/meta-mt.json - ./cannon/bin/cannon run --type cannon-mt --proof-at '=0' --stop-at '=1' --input op-program/bin/prestate-mt.bin.gz --meta op-program/bin/meta-mt.json --proof-fmt 'op-program/bin/%d-mt.json' --output "" + ./cannon/bin/cannon run --proof-at '=0' --stop-at '=1' --input op-program/bin/prestate-mt.bin.gz --meta op-program/bin/meta-mt.json --proof-fmt 'op-program/bin/%d-mt.json' --output "" mv op-program/bin/0-mt.json op-program/bin/prestate-proof-mt.json .PHONY: cannon-prestate diff --git a/cannon/cmd/load_elf.go b/cannon/cmd/load_elf.go index 512d4922d17a..8a1fbacbfcce 100644 --- a/cannon/cmd/load_elf.go +++ b/cannon/cmd/load_elf.go @@ -6,6 +6,7 @@ import ( "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/versions" "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/urfave/cli/v2" @@ -16,6 +17,12 @@ import ( ) var ( + LoadELFVMTypeFlag = &cli.StringFlag{ + Name: "type", + Usage: "VM type to create state for. Options are 'cannon' (default), 'cannon-mt'", + Value: "cannon", + Required: false, + } LoadELFPathFlag = &cli.PathFlag{ Name: "path", Usage: "Path to 32-bit big-endian MIPS ELF file", @@ -42,9 +49,25 @@ var ( } ) +type VMType string + +var ( + cannonVMType VMType = "cannon" + mtVMType VMType = "cannon-mt" +) + +func vmTypeFromString(ctx *cli.Context) (VMType, error) { + if vmTypeStr := ctx.String(LoadELFVMTypeFlag.Name); vmTypeStr == string(cannonVMType) { + return cannonVMType, nil + } else if vmTypeStr == string(mtVMType) { + return mtVMType, nil + } else { + return "", fmt.Errorf("unknown VM type %q", vmTypeStr) + } +} + func LoadELF(ctx *cli.Context) error { var createInitialState func(f *elf.File) (mipsevm.FPVMState, error) - var writeState func(path string, state mipsevm.FPVMState) error if vmType, err := vmTypeFromString(ctx); err != nil { return err @@ -52,16 +75,10 @@ func LoadELF(ctx *cli.Context) error { createInitialState = func(f *elf.File) (mipsevm.FPVMState, error) { return program.LoadELF(f, singlethreaded.CreateInitialState) } - writeState = func(path string, state mipsevm.FPVMState) error { - return serialize.Write[*singlethreaded.State](path, state.(*singlethreaded.State), OutFilePerm) - } } else if vmType == mtVMType { createInitialState = func(f *elf.File) (mipsevm.FPVMState, error) { return program.LoadELF(f, multithreaded.CreateInitialState) } - writeState = func(path string, state mipsevm.FPVMState) error { - return serialize.Write[*multithreaded.State](path, state.(*multithreaded.State), OutFilePerm) - } } else { return fmt.Errorf("invalid VM type: %q", vmType) } @@ -97,7 +114,13 @@ func LoadELF(ctx *cli.Context) error { if err := jsonutil.WriteJSON[*program.Metadata](meta, ioutil.ToStdOutOrFileOrNoop(ctx.Path(LoadELFMetaFlag.Name), OutFilePerm)); err != nil { return fmt.Errorf("failed to output metadata: %w", err) } - return writeState(ctx.Path(LoadELFOutFlag.Name), state) + + // Ensure the state is written with appropriate version information + versionedState, err := versions.NewFromState(state) + if err != nil { + return fmt.Errorf("failed to create versioned state: %w", err) + } + return serialize.Write(ctx.Path(LoadELFOutFlag.Name), versionedState, OutFilePerm) } var LoadELFCommand = &cli.Command{ @@ -106,7 +129,7 @@ var LoadELFCommand = &cli.Command{ Description: "Load ELF file into Cannon JSON state, optionally patch out functions", Action: LoadELF, Flags: []cli.Flag{ - VMTypeFlag, + LoadELFVMTypeFlag, LoadELFPathFlag, LoadELFPatchFlag, LoadELFOutFlag, diff --git a/cannon/cmd/run.go b/cannon/cmd/run.go index 5993f0424c24..2fe67fc3e44c 100644 --- a/cannon/cmd/run.go +++ b/cannon/cmd/run.go @@ -10,7 +10,7 @@ import ( "strings" "time" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/versions" "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/ethereum/go-ethereum/common" @@ -21,7 +21,6 @@ import ( "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/cannon/mipsevm/program" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" preimage "github.com/ethereum-optimism/optimism/op-preimage" "github.com/ethereum-optimism/optimism/op-service/jsonutil" ) @@ -279,11 +278,6 @@ func Run(ctx *cli.Context) error { defer profile.Start(profile.NoShutdownHook, profile.ProfilePath("."), profile.CPUProfile).Stop() } - vmType, err := vmTypeFromString(ctx) - if err != nil { - return err - } - guestLogger := Logger(os.Stderr, log.LevelInfo) outLog := &mipsevm.LoggingWriter{Log: guestLogger.With("module", "guest", "stream", "stdout")} errLog := &mipsevm.LoggingWriter{Log: guestLogger.With("module", "guest", "stream", "stderr")} @@ -373,42 +367,19 @@ func Run(ctx *cli.Context) error { } } - var vm mipsevm.FPVM - var debugProgram bool - if vmType == cannonVMType { - l.Info("Using cannon VM") - cannon, err := singlethreaded.NewInstrumentedStateFromFile(ctx.Path(RunInputFlag.Name), po, outLog, errLog, meta) - if err != nil { - return err - } - debugProgram = ctx.Bool(RunDebugFlag.Name) - if debugProgram { - if metaPath := ctx.Path(RunMetaFlag.Name); metaPath == "" { - return fmt.Errorf("cannot enable debug mode without a metadata file") - } - if err := cannon.InitDebug(); err != nil { - return fmt.Errorf("failed to initialize debug mode: %w", err) - } - } - vm = cannon - } else if vmType == mtVMType { - l.Info("Using cannon multithreaded VM") - cannon, err := multithreaded.NewInstrumentedStateFromFile(ctx.Path(RunInputFlag.Name), po, outLog, errLog, l) - if err != nil { - return err + state, err := versions.LoadStateFromFile(ctx.Path(RunInputFlag.Name)) + if err != nil { + return fmt.Errorf("failed to load state: %w", err) + } + vm := state.CreateVM(l, po, outLog, errLog, meta) + debugProgram := ctx.Bool(RunDebugFlag.Name) + if debugProgram { + if metaPath := ctx.Path(RunMetaFlag.Name); metaPath == "" { + return fmt.Errorf("cannot enable debug mode without a metadata file") } - debugProgram = ctx.Bool(RunDebugFlag.Name) - if debugProgram { - if metaPath := ctx.Path(RunMetaFlag.Name); metaPath == "" { - return fmt.Errorf("cannot enable debug mode without a metadata file") - } - if err := cannon.InitDebug(meta); err != nil { - return fmt.Errorf("failed to initialize debug mode: %w", err) - } + if err := vm.InitDebug(); err != nil { + return fmt.Errorf("failed to initialize debug mode: %w", err) } - vm = cannon - } else { - return fmt.Errorf("unknown VM type %q", vmType) } proofFmt := ctx.String(RunProofFmtFlag.Name) @@ -421,7 +392,6 @@ func Run(ctx *cli.Context) error { start := time.Now() - state := vm.GetState() startStep := state.GetStep() for !state.GetExited() { @@ -530,7 +500,6 @@ var RunCommand = &cli.Command{ Description: "Run VM step(s) and generate proof data to replicate onchain. See flags to match when to output a proof, a snapshot, or to stop early.", Action: Run, Flags: []cli.Flag{ - VMTypeFlag, RunInputFlag, RunOutputFlag, RunProofAtFlag, diff --git a/cannon/cmd/vmtype.go b/cannon/cmd/vmtype.go deleted file mode 100644 index 0efc22370c94..000000000000 --- a/cannon/cmd/vmtype.go +++ /dev/null @@ -1,29 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/urfave/cli/v2" -) - -type VMType string - -var cannonVMType VMType = "cannon" -var mtVMType VMType = "cannon-mt" - -var VMTypeFlag = &cli.StringFlag{ - Name: "type", - Usage: "VM type to create state for. Options are 'cannon' (default), 'cannon-mt'", - Value: "cannon", - Required: false, -} - -func vmTypeFromString(ctx *cli.Context) (VMType, error) { - if vmTypeStr := ctx.String(VMTypeFlag.Name); vmTypeStr == string(cannonVMType) { - return cannonVMType, nil - } else if vmTypeStr == string(mtVMType) { - return mtVMType, nil - } else { - return "", fmt.Errorf("unknown VM type %q", vmTypeStr) - } -} diff --git a/cannon/cmd/witness.go b/cannon/cmd/witness.go index 58fa4a34307a..a4f2e60ab6a6 100644 --- a/cannon/cmd/witness.go +++ b/cannon/cmd/witness.go @@ -4,12 +4,8 @@ import ( "fmt" "os" - "github.com/ethereum-optimism/optimism/cannon/mipsevm" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" - "github.com/ethereum-optimism/optimism/cannon/serialize" + factory "github.com/ethereum-optimism/optimism/cannon/mipsevm/versions" "github.com/urfave/cli/v2" - - "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" ) var ( @@ -29,23 +25,10 @@ var ( func Witness(ctx *cli.Context) error { input := ctx.Path(WitnessInputFlag.Name) output := ctx.Path(WitnessOutputFlag.Name) - var state mipsevm.FPVMState - if vmType, err := vmTypeFromString(ctx); err != nil { - return err - } else if vmType == cannonVMType { - state, err = serialize.Load[singlethreaded.State](input) - if err != nil { - return fmt.Errorf("invalid input state (%v): %w", input, err) - } - } else if vmType == mtVMType { - state, err = serialize.Load[multithreaded.State](input) - if err != nil { - return fmt.Errorf("invalid input state (%v): %w", input, err) - } - } else { - return fmt.Errorf("invalid VM type: %q", vmType) + state, err := factory.LoadStateFromFile(input) + if err != nil { + return fmt.Errorf("invalid input state (%v): %w", input, err) } - witness, h := state.EncodeWitness() if output != "" { if err := os.WriteFile(output, witness, 0755); err != nil { @@ -62,7 +45,6 @@ var WitnessCommand = &cli.Command{ Description: "Convert a Cannon JSON state into a binary witness. The hash of the witness is written to stdout", Action: Witness, Flags: []cli.Flag{ - VMTypeFlag, WitnessInputFlag, WitnessOutputFlag, }, diff --git a/cannon/mipsevm/exec/stack.go b/cannon/mipsevm/exec/stack.go index 378c07b558c0..06e919c0352f 100644 --- a/cannon/mipsevm/exec/stack.go +++ b/cannon/mipsevm/exec/stack.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/ethereum-optimism/optimism/cannon/mipsevm" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/program" ) type StackTracker interface { @@ -31,10 +30,10 @@ type StackTrackerImpl struct { stack []uint32 caller []uint32 - meta *program.Metadata + meta mipsevm.Metadata } -func NewStackTracker(state mipsevm.FPVMState, meta *program.Metadata) (*StackTrackerImpl, error) { +func NewStackTracker(state mipsevm.FPVMState, meta mipsevm.Metadata) (*StackTrackerImpl, error) { if meta == nil { return nil, errors.New("metadata is nil") } @@ -42,7 +41,7 @@ func NewStackTracker(state mipsevm.FPVMState, meta *program.Metadata) (*StackTra } // NewStackTrackerUnsafe creates a new TraceableStackTracker without verifying meta is not nil -func NewStackTrackerUnsafe(state mipsevm.FPVMState, meta *program.Metadata) *StackTrackerImpl { +func NewStackTrackerUnsafe(state mipsevm.FPVMState, meta mipsevm.Metadata) *StackTrackerImpl { return &StackTrackerImpl{state: state, meta: meta} } diff --git a/cannon/mipsevm/iface.go b/cannon/mipsevm/iface.go index 9663a8a6ccdd..8e8d758e9048 100644 --- a/cannon/mipsevm/iface.go +++ b/cannon/mipsevm/iface.go @@ -1,9 +1,12 @@ package mipsevm import ( + "io" + "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/cannon/mipsevm/memory" ) @@ -52,6 +55,16 @@ type FPVMState interface { // EncodeWitness returns the witness for the current state and the state hash EncodeWitness() (witness []byte, hash common.Hash) + + // CreateVM creates a FPVM that can operate on this state. + CreateVM(logger log.Logger, po PreimageOracle, stdOut, stdErr io.Writer, meta Metadata) FPVM +} + +type SymbolMatcher func(addr uint32) bool + +type Metadata interface { + LookupSymbol(addr uint32) string + CreateSymbolMatcher(name string) SymbolMatcher } type FPVM interface { @@ -73,6 +86,9 @@ type FPVM interface { // GetDebugInfo returns debug information about the VM GetDebugInfo() *DebugInfo + // InitDebug initializes the debug mode of the VM + InitDebug() error + // LookupSymbol returns the symbol located at the specified address. // May return an empty string if there's no symbol table available. LookupSymbol(addr uint32) string diff --git a/cannon/mipsevm/multithreaded/instrumented.go b/cannon/mipsevm/multithreaded/instrumented.go index 0d3e17efd4b6..1928e26004b1 100644 --- a/cannon/mipsevm/multithreaded/instrumented.go +++ b/cannon/mipsevm/multithreaded/instrumented.go @@ -3,13 +3,11 @@ package multithreaded import ( "io" - "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/cannon/mipsevm/exec" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/program" ) type InstrumentedState struct { @@ -23,12 +21,12 @@ type InstrumentedState struct { stackTracker ThreadedStackTracker preimageOracle *exec.TrackingPreimageOracleReader - meta *program.Metadata + meta mipsevm.Metadata } var _ mipsevm.FPVM = (*InstrumentedState)(nil) -func NewInstrumentedState(state *State, po mipsevm.PreimageOracle, stdOut, stdErr io.Writer, log log.Logger) *InstrumentedState { +func NewInstrumentedState(state *State, po mipsevm.PreimageOracle, stdOut, stdErr io.Writer, log log.Logger, meta mipsevm.Metadata) *InstrumentedState { return &InstrumentedState{ state: state, log: log, @@ -37,24 +35,16 @@ func NewInstrumentedState(state *State, po mipsevm.PreimageOracle, stdOut, stdEr memoryTracker: exec.NewMemoryTracker(state.Memory), stackTracker: &NoopThreadedStackTracker{}, preimageOracle: exec.NewTrackingPreimageOracleReader(po), + meta: meta, } } -func NewInstrumentedStateFromFile(stateFile string, po mipsevm.PreimageOracle, stdOut, stdErr io.Writer, log log.Logger) (*InstrumentedState, error) { - state, err := serialize.Load[State](stateFile) - if err != nil { - return nil, err - } - return NewInstrumentedState(state, po, stdOut, stdErr, log), nil -} - -func (m *InstrumentedState) InitDebug(meta *program.Metadata) error { - stackTracker, err := NewThreadedStackTracker(m.state, meta) +func (m *InstrumentedState) InitDebug() error { + stackTracker, err := NewThreadedStackTracker(m.state, m.meta) if err != nil { return err } m.stackTracker = stackTracker - m.meta = meta return nil } diff --git a/cannon/mipsevm/multithreaded/instrumented_test.go b/cannon/mipsevm/multithreaded/instrumented_test.go index c60db57dcfdb..800bdf836c63 100644 --- a/cannon/mipsevm/multithreaded/instrumented_test.go +++ b/cannon/mipsevm/multithreaded/instrumented_test.go @@ -15,7 +15,7 @@ import ( ) func vmFactory(state *State, po mipsevm.PreimageOracle, stdOut, stdErr io.Writer, log log.Logger) mipsevm.FPVM { - return NewInstrumentedState(state, po, stdOut, stdErr, log) + return NewInstrumentedState(state, po, stdOut, stdErr, log, nil) } func TestInstrumentedState_OpenMips(t *testing.T) { @@ -36,7 +36,7 @@ func TestInstrumentedState_MultithreadedProgram(t *testing.T) { oracle := testutil.StaticOracle(t, []byte{}) var stdOutBuf, stdErrBuf bytes.Buffer - us := NewInstrumentedState(state, oracle, io.MultiWriter(&stdOutBuf, os.Stdout), io.MultiWriter(&stdErrBuf, os.Stderr), testutil.CreateLogger()) + us := NewInstrumentedState(state, oracle, io.MultiWriter(&stdOutBuf, os.Stdout), io.MultiWriter(&stdErrBuf, os.Stderr), testutil.CreateLogger(), nil) for i := 0; i < 1_000_000; i++ { if us.GetState().GetExited() { break @@ -61,7 +61,7 @@ func TestInstrumentedState_Alloc(t *testing.T) { oracle := testutil.AllocOracle(t, numAllocs) // completes in ~870 M steps - us := NewInstrumentedState(state, oracle, os.Stdout, os.Stderr, testutil.CreateLogger()) + us := NewInstrumentedState(state, oracle, os.Stdout, os.Stderr, testutil.CreateLogger(), nil) for i := 0; i < 20_000_000_000; i++ { if us.GetState().GetExited() { break diff --git a/cannon/mipsevm/multithreaded/stack.go b/cannon/mipsevm/multithreaded/stack.go index ab710267fbe8..4fc32c221ee8 100644 --- a/cannon/mipsevm/multithreaded/stack.go +++ b/cannon/mipsevm/multithreaded/stack.go @@ -3,8 +3,8 @@ package multithreaded import ( "errors" + "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/cannon/mipsevm/exec" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/program" ) type ThreadedStackTracker interface { @@ -21,14 +21,14 @@ var _ ThreadedStackTracker = (*ThreadedStackTrackerImpl)(nil) func (n *NoopThreadedStackTracker) DropThread(threadId uint32) {} type ThreadedStackTrackerImpl struct { - meta *program.Metadata + meta mipsevm.Metadata state *State trackersByThreadId map[uint32]exec.TraceableStackTracker } var _ ThreadedStackTracker = (*ThreadedStackTrackerImpl)(nil) -func NewThreadedStackTracker(state *State, meta *program.Metadata) (*ThreadedStackTrackerImpl, error) { +func NewThreadedStackTracker(state *State, meta mipsevm.Metadata) (*ThreadedStackTrackerImpl, error) { if meta == nil { return nil, errors.New("metadata is nil") } diff --git a/cannon/mipsevm/multithreaded/state.go b/cannon/mipsevm/multithreaded/state.go index 8f6f3eb2ac0d..d0bf4bf5dd82 100644 --- a/cannon/mipsevm/multithreaded/state.go +++ b/cannon/mipsevm/multithreaded/state.go @@ -5,11 +5,11 @@ import ( "fmt" "io" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/versions" "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/cannon/mipsevm/exec" @@ -35,27 +35,27 @@ const ( ) type State struct { - Memory *memory.Memory `json:"memory"` + Memory *memory.Memory - PreimageKey common.Hash `json:"preimageKey"` - PreimageOffset uint32 `json:"preimageOffset"` // note that the offset includes the 8-byte length prefix + PreimageKey common.Hash + PreimageOffset uint32 // note that the offset includes the 8-byte length prefix - Heap uint32 `json:"heap"` // to handle mmap growth + Heap uint32 // to handle mmap growth - ExitCode uint8 `json:"exit"` - Exited bool `json:"exited"` + ExitCode uint8 + Exited bool - Step uint64 `json:"step"` - StepsSinceLastContextSwitch uint64 `json:"stepsSinceLastContextSwitch"` - Wakeup uint32 `json:"wakeup"` + Step uint64 + StepsSinceLastContextSwitch uint64 + Wakeup uint32 - TraverseRight bool `json:"traverseRight"` - LeftThreadStack []*ThreadState `json:"leftThreadStack"` - RightThreadStack []*ThreadState `json:"rightThreadStack"` - NextThreadId uint32 `json:"nextThreadId"` + TraverseRight bool + LeftThreadStack []*ThreadState + RightThreadStack []*ThreadState + NextThreadId uint32 // LastHint is optional metadata, and not part of the VM state itself. - LastHint hexutil.Bytes `json:"lastHint,omitempty"` + LastHint hexutil.Bytes } var _ mipsevm.FPVMState = (*State)(nil) @@ -87,6 +87,11 @@ func CreateInitialState(pc, heapStart uint32) *State { return state } +func (s *State) CreateVM(logger log.Logger, po mipsevm.PreimageOracle, stdOut, stdErr io.Writer, meta mipsevm.Metadata) mipsevm.FPVM { + logger.Info("Using cannon multithreaded VM") + return NewInstrumentedState(s, po, stdOut, stdErr, logger, meta) +} + func (s *State) GetCurrentThread() *ThreadState { activeStack := s.getActiveThreadStack() @@ -246,9 +251,6 @@ func (s *State) ThreadCount() int { // LastHint []byte func (s *State) Serialize(out io.Writer) error { bout := serialize.NewBinaryWriter(out) - if err := bout.WriteUInt(versions.VersionMultiThreaded); err != nil { - return err - } if err := s.Memory.Serialize(out); err != nil { return err @@ -309,13 +311,6 @@ func (s *State) Serialize(out io.Writer) error { func (s *State) Deserialize(in io.Reader) error { bin := serialize.NewBinaryReader(in) - var version versions.StateVersion - if err := bin.ReadUInt(&version); err != nil { - return err - } - if version != versions.VersionMultiThreaded { - return fmt.Errorf("invalid state encoding version %d", version) - } s.Memory = memory.NewMemory() if err := s.Memory.Deserialize(in); err != nil { return err diff --git a/cannon/mipsevm/program/metadata.go b/cannon/mipsevm/program/metadata.go index e90cbe14815c..fb34da7694c7 100644 --- a/cannon/mipsevm/program/metadata.go +++ b/cannon/mipsevm/program/metadata.go @@ -4,6 +4,8 @@ import ( "debug/elf" "fmt" "sort" + + "github.com/ethereum-optimism/optimism/cannon/mipsevm" ) type Symbol struct { @@ -16,6 +18,8 @@ type Metadata struct { Symbols []Symbol `json:"symbols"` } +var _ mipsevm.Metadata = (*Metadata)(nil) + func MakeMetadata(elfProgram *elf.File) (*Metadata, error) { syms, err := elfProgram.Symbols() if err != nil { @@ -50,9 +54,7 @@ func (m *Metadata) LookupSymbol(addr uint32) string { return out.Name } -type SymbolMatcher func(addr uint32) bool - -func (m *Metadata) CreateSymbolMatcher(name string) SymbolMatcher { +func (m *Metadata) CreateSymbolMatcher(name string) mipsevm.SymbolMatcher { for _, s := range m.Symbols { if s.Name == name { start := s.Start diff --git a/cannon/mipsevm/singlethreaded/instrumented.go b/cannon/mipsevm/singlethreaded/instrumented.go index 03e2b724ead3..800cc1a92f7a 100644 --- a/cannon/mipsevm/singlethreaded/instrumented.go +++ b/cannon/mipsevm/singlethreaded/instrumented.go @@ -5,14 +5,12 @@ import ( "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/cannon/mipsevm/exec" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/program" - "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/ethereum/go-ethereum/common/hexutil" ) type InstrumentedState struct { - meta *program.Metadata - sleepCheck program.SymbolMatcher + meta mipsevm.Metadata + sleepCheck mipsevm.SymbolMatcher state *State @@ -27,16 +25,14 @@ type InstrumentedState struct { var _ mipsevm.FPVM = (*InstrumentedState)(nil) -func NewInstrumentedState(state *State, po mipsevm.PreimageOracle, stdOut, stdErr io.Writer, meta *program.Metadata) *InstrumentedState { - var sleepCheck program.SymbolMatcher +func NewInstrumentedState(state *State, po mipsevm.PreimageOracle, stdOut, stdErr io.Writer, meta mipsevm.Metadata) *InstrumentedState { + var sleepCheck mipsevm.SymbolMatcher if meta == nil { sleepCheck = func(addr uint32) bool { return false } } else { sleepCheck = meta.CreateSymbolMatcher("runtime.notesleep") } - return &InstrumentedState{ - meta: meta, sleepCheck: sleepCheck, state: state, stdOut: stdOut, @@ -44,17 +40,10 @@ func NewInstrumentedState(state *State, po mipsevm.PreimageOracle, stdOut, stdEr memoryTracker: exec.NewMemoryTracker(state.Memory), stackTracker: &exec.NoopStackTracker{}, preimageOracle: exec.NewTrackingPreimageOracleReader(po), + meta: meta, } } -func NewInstrumentedStateFromFile(stateFile string, po mipsevm.PreimageOracle, stdOut, stdErr io.Writer, meta *program.Metadata) (*InstrumentedState, error) { - state, err := serialize.Load[State](stateFile) - if err != nil { - return nil, err - } - return NewInstrumentedState(state, po, stdOut, stdErr, meta), nil -} - func (m *InstrumentedState) InitDebug() error { stackTracker, err := exec.NewStackTracker(m.state, m.meta) if err != nil { diff --git a/cannon/mipsevm/singlethreaded/state.go b/cannon/mipsevm/singlethreaded/state.go index 5eaac8cd940b..e0be88d99857 100644 --- a/cannon/mipsevm/singlethreaded/state.go +++ b/cannon/mipsevm/singlethreaded/state.go @@ -6,11 +6,11 @@ import ( "fmt" "io" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/versions" "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/cannon/mipsevm/memory" @@ -68,6 +68,11 @@ func CreateInitialState(pc, heapStart uint32) *State { return state } +func (s *State) CreateVM(logger log.Logger, po mipsevm.PreimageOracle, stdOut, stdErr io.Writer, meta mipsevm.Metadata) mipsevm.FPVM { + logger.Info("Using cannon VM") + return NewInstrumentedState(s, po, stdOut, stdErr, meta) +} + type stateMarshaling struct { Memory *memory.Memory `json:"memory"` PreimageKey common.Hash `json:"preimageKey"` @@ -201,9 +206,6 @@ func (s *State) EncodeWitness() ([]byte, common.Hash) { // LastHint []byte func (s *State) Serialize(out io.Writer) error { bout := serialize.NewBinaryWriter(out) - if err := bout.WriteUInt(versions.VersionSingleThreaded); err != nil { - return err - } if err := s.Memory.Serialize(out); err != nil { return err @@ -251,13 +253,6 @@ func (s *State) Serialize(out io.Writer) error { func (s *State) Deserialize(in io.Reader) error { bin := serialize.NewBinaryReader(in) - var version versions.StateVersion - if err := bin.ReadUInt(&version); err != nil { - return err - } - if version != versions.VersionSingleThreaded { - return fmt.Errorf("invalid state encoding version %d", version) - } s.Memory = memory.NewMemory() if err := s.Memory.Deserialize(in); err != nil { return err diff --git a/cannon/mipsevm/tests/evm_multithreaded_test.go b/cannon/mipsevm/tests/evm_multithreaded_test.go index 76f9b9462dc2..2730e8294a88 100644 --- a/cannon/mipsevm/tests/evm_multithreaded_test.go +++ b/cannon/mipsevm/tests/evm_multithreaded_test.go @@ -48,7 +48,7 @@ func TestEVM_SysClone_FlagHandling(t *testing.T) { var err error var stepWitness *mipsevm.StepWitness - us := multithreaded.NewInstrumentedState(state, nil, os.Stdout, os.Stderr, nil) + us := multithreaded.NewInstrumentedState(state, nil, os.Stdout, os.Stderr, nil, nil) if !c.valid { // The VM should exit stepWitness, err = us.Step(true) diff --git a/cannon/mipsevm/tests/helpers.go b/cannon/mipsevm/tests/helpers.go index 5b75a03c6bc4..d96940972a65 100644 --- a/cannon/mipsevm/tests/helpers.go +++ b/cannon/mipsevm/tests/helpers.go @@ -31,7 +31,7 @@ func multiThreadedVmFactory(po mipsevm.PreimageOracle, stdOut, stdErr io.Writer, for _, opt := range opts { opt(mutator) } - return multithreaded.NewInstrumentedState(state, po, stdOut, stdErr, log) + return multithreaded.NewInstrumentedState(state, po, stdOut, stdErr, log, nil) } type ElfVMFactory func(t require.TestingT, elfFile string, po mipsevm.PreimageOracle, stdOut, stdErr io.Writer, log log.Logger) mipsevm.FPVM @@ -45,8 +45,8 @@ func singleThreadElfVmFactory(t require.TestingT, elfFile string, po mipsevm.Pre func multiThreadElfVmFactory(t require.TestingT, elfFile string, po mipsevm.PreimageOracle, stdOut, stdErr io.Writer, log log.Logger) mipsevm.FPVM { state, meta := testutil.LoadELFProgram(t, elfFile, multithreaded.CreateInitialState, false) - fpvm := multithreaded.NewInstrumentedState(state, po, stdOut, stdErr, log) - require.NoError(t, fpvm.InitDebug(meta)) + fpvm := multithreaded.NewInstrumentedState(state, po, stdOut, stdErr, log, meta) + require.NoError(t, fpvm.InitDebug()) return fpvm } diff --git a/cannon/mipsevm/versions/state.go b/cannon/mipsevm/versions/state.go index 6e1a6b2fb4e1..fcf7b1864f38 100644 --- a/cannon/mipsevm/versions/state.go +++ b/cannon/mipsevm/versions/state.go @@ -1,8 +1,105 @@ package versions +import ( + "encoding/json" + "errors" + "fmt" + "io" + + "github.com/ethereum-optimism/optimism/cannon/mipsevm" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" + "github.com/ethereum-optimism/optimism/cannon/serialize" + "github.com/ethereum-optimism/optimism/op-service/jsonutil" +) + type StateVersion uint8 const ( VersionSingleThreaded StateVersion = iota VersionMultiThreaded ) + +var ( + ErrUnknownVersion = errors.New("unknown version") + ErrJsonNotSupported = errors.New("json not supported") +) + +func LoadStateFromFile(path string) (*VersionedState, error) { + if !serialize.IsBinaryFile(path) { + // Always use singlethreaded for JSON states + state, err := jsonutil.LoadJSON[singlethreaded.State](path) + if err != nil { + return nil, err + } + return NewFromState(state) + } + return serialize.LoadSerializedBinary[VersionedState](path) +} + +func NewFromState(state mipsevm.FPVMState) (*VersionedState, error) { + switch state := state.(type) { + case *singlethreaded.State: + return &VersionedState{ + Version: VersionSingleThreaded, + FPVMState: state, + }, nil + case *multithreaded.State: + return &VersionedState{ + Version: VersionMultiThreaded, + FPVMState: state, + }, nil + default: + return nil, fmt.Errorf("%w: %T", ErrUnknownVersion, state) + } +} + +// VersionedState deserializes a FPVMState and implements VersionedState based on the version of that state. +// It does this based on the version byte read in Deserialize +type VersionedState struct { + Version StateVersion + mipsevm.FPVMState +} + +func (s *VersionedState) Serialize(w io.Writer) error { + bout := serialize.NewBinaryWriter(w) + if err := bout.WriteUInt(s.Version); err != nil { + return err + } + return s.FPVMState.Serialize(w) +} + +func (s *VersionedState) Deserialize(in io.Reader) error { + bin := serialize.NewBinaryReader(in) + if err := bin.ReadUInt(&s.Version); err != nil { + return err + } + + switch s.Version { + case VersionSingleThreaded: + state := &singlethreaded.State{} + if err := state.Deserialize(in); err != nil { + return err + } + s.FPVMState = state + return nil + case VersionMultiThreaded: + state := &multithreaded.State{} + if err := state.Deserialize(in); err != nil { + return err + } + s.FPVMState = state + return nil + default: + return fmt.Errorf("%w: %d", ErrUnknownVersion, s.Version) + } +} + +// MarshalJSON marshals the underlying state without adding version prefix. +// JSON states are always assumed to be single threaded +func (s *VersionedState) MarshalJSON() ([]byte, error) { + if s.Version != VersionSingleThreaded { + return nil, fmt.Errorf("%w for type %T", ErrJsonNotSupported, s.FPVMState) + } + return json.Marshal(s.FPVMState) +} diff --git a/cannon/mipsevm/versions/state_test.go b/cannon/mipsevm/versions/state_test.go new file mode 100644 index 000000000000..7fb36cd5734c --- /dev/null +++ b/cannon/mipsevm/versions/state_test.go @@ -0,0 +1,76 @@ +package versions + +import ( + "path/filepath" + "testing" + + "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" + "github.com/ethereum-optimism/optimism/cannon/serialize" + "github.com/stretchr/testify/require" +) + +func TestNewFromState(t *testing.T) { + t.Run("singlethreaded", func(t *testing.T) { + actual, err := NewFromState(singlethreaded.CreateEmptyState()) + require.NoError(t, err) + require.IsType(t, &singlethreaded.State{}, actual.FPVMState) + require.Equal(t, VersionSingleThreaded, actual.Version) + }) + + t.Run("multithreaded", func(t *testing.T) { + actual, err := NewFromState(multithreaded.CreateEmptyState()) + require.NoError(t, err) + require.IsType(t, &multithreaded.State{}, actual.FPVMState) + require.Equal(t, VersionMultiThreaded, actual.Version) + }) +} + +func TestLoadStateFromFile(t *testing.T) { + t.Run("SinglethreadedFromJSON", func(t *testing.T) { + expected, err := NewFromState(singlethreaded.CreateEmptyState()) + require.NoError(t, err) + + path := writeToFile(t, "state.json", expected) + actual, err := LoadStateFromFile(path) + require.NoError(t, err) + require.Equal(t, expected, actual) + }) + + t.Run("SinglethreadedFromBinary", func(t *testing.T) { + expected, err := NewFromState(singlethreaded.CreateEmptyState()) + require.NoError(t, err) + + path := writeToFile(t, "state.bin.gz", expected) + actual, err := LoadStateFromFile(path) + require.NoError(t, err) + require.Equal(t, expected, actual) + }) + + t.Run("MultithreadedFromBinary", func(t *testing.T) { + expected, err := NewFromState(multithreaded.CreateEmptyState()) + require.NoError(t, err) + + path := writeToFile(t, "state.bin.gz", expected) + actual, err := LoadStateFromFile(path) + require.NoError(t, err) + require.Equal(t, expected, actual) + }) +} + +func TestMultithreadedDoesNotSupportJSON(t *testing.T) { + state, err := NewFromState(multithreaded.CreateEmptyState()) + require.NoError(t, err) + + dir := t.TempDir() + path := filepath.Join(dir, "test.json") + err = serialize.Write(path, state, 0o644) + require.ErrorIs(t, err, ErrJsonNotSupported) +} + +func writeToFile(t *testing.T, filename string, data serialize.Serializable) string { + dir := t.TempDir() + path := filepath.Join(dir, filename) + require.NoError(t, serialize.Write(path, data, 0o644)) + return path +} diff --git a/cannon/serialize/binary.go b/cannon/serialize/binary.go index 62ca54cc2e3a..aeaf14c5b493 100644 --- a/cannon/serialize/binary.go +++ b/cannon/serialize/binary.go @@ -9,13 +9,16 @@ import ( "github.com/ethereum-optimism/optimism/op-service/ioutil" ) +// Deserializable defines functionality for a type that may be deserialized from raw bytes. +type Deserializable interface { + // Deserialize decodes raw bytes into the type. + Deserialize(in io.Reader) error +} + // Serializable defines functionality for a type that may be serialized to raw bytes. type Serializable interface { // Serialize encodes the type as raw bytes. Serialize(out io.Writer) error - - // Deserialize decodes raw bytes into the type. - Deserialize(in io.Reader) error } func LoadSerializedBinary[X any](inputPath string) (*X, error) { @@ -30,7 +33,7 @@ func LoadSerializedBinary[X any](inputPath string) (*X, error) { defer f.Close() var x X - serializable, ok := reflect.ValueOf(&x).Interface().(Serializable) + serializable, ok := reflect.ValueOf(&x).Interface().(Deserializable) if !ok { return nil, fmt.Errorf("%T is not a Serializable", x) } diff --git a/cannon/serialize/detect.go b/cannon/serialize/detect.go index aae13791826f..13cf3aef849e 100644 --- a/cannon/serialize/detect.go +++ b/cannon/serialize/detect.go @@ -8,20 +8,13 @@ import ( "github.com/ethereum-optimism/optimism/op-service/jsonutil" ) -func Load[X any](inputPath string) (*X, error) { - if isBinary(inputPath) { - return LoadSerializedBinary[X](inputPath) - } - return jsonutil.LoadJSON[X](inputPath) -} - func Write[X Serializable](outputPath string, x X, perm os.FileMode) error { - if isBinary(outputPath) { + if IsBinaryFile(outputPath) { return WriteSerializedBinary(x, ioutil.ToStdOutOrFileOrNoop(outputPath, perm)) } return jsonutil.WriteJSON[X](x, ioutil.ToStdOutOrFileOrNoop(outputPath, perm)) } -func isBinary(path string) bool { +func IsBinaryFile(path string) bool { return strings.HasSuffix(path, ".bin") || strings.HasSuffix(path, ".bin.gz") } diff --git a/cannon/serialize/detect_test.go b/cannon/serialize/detect_test.go index 032844e1800b..22ac747a1044 100644 --- a/cannon/serialize/detect_test.go +++ b/cannon/serialize/detect_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-service/ioutil" + "github.com/ethereum-optimism/optimism/op-service/jsonutil" "github.com/stretchr/testify/require" ) @@ -42,13 +43,16 @@ func TestRoundtrip(t *testing.T) { start := make([]byte, 1) _, err = io.ReadFull(decompressed, start) require.NoError(t, err) + var load func(path string) (*serializableTestData, error) if test.expectJSON { + load = jsonutil.LoadJSON[serializableTestData] require.Equal(t, "{", string(start)) } else { + load = LoadSerializedBinary[serializableTestData] require.NotEqual(t, "{", string(start)) } - result, err := Load[serializableTestData](path) + result, err := load(path) require.NoError(t, err) require.EqualValues(t, data, result) }) diff --git a/op-challenger/game/fault/trace/cannon/state_converter.go b/op-challenger/game/fault/trace/cannon/state_converter.go index 36b1b2040889..248676cc326e 100644 --- a/op-challenger/game/fault/trace/cannon/state_converter.go +++ b/op-challenger/game/fault/trace/cannon/state_converter.go @@ -3,8 +3,8 @@ package cannon import ( "fmt" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" - "github.com/ethereum-optimism/optimism/cannon/serialize" + "github.com/ethereum-optimism/optimism/cannon/mipsevm" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/versions" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" ) @@ -30,9 +30,9 @@ func (c *StateConverter) ConvertStateToProof(statePath string) (*utils.ProofData OracleKey: nil, OracleValue: nil, OracleOffset: 0, - }, state.Step, state.Exited, nil + }, state.GetStep(), state.GetExited(), nil } -func parseState(path string) (*singlethreaded.State, error) { - return serialize.Load[singlethreaded.State](path) +func parseState(path string) (mipsevm.FPVMState, error) { + return versions.LoadStateFromFile(path) } diff --git a/op-challenger/game/fault/trace/cannon/state_converter_test.go b/op-challenger/game/fault/trace/cannon/state_converter_test.go index 58e7eb1b829d..c0c0182529ff 100644 --- a/op-challenger/game/fault/trace/cannon/state_converter_test.go +++ b/op-challenger/game/fault/trace/cannon/state_converter_test.go @@ -1,78 +1,96 @@ package cannon import ( - "compress/gzip" _ "embed" - "encoding/json" - "os" "path/filepath" "testing" + "github.com/ethereum-optimism/optimism/cannon/mipsevm" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/versions" "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/stretchr/testify/require" "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" ) -//go:embed test_data/state.json -var testState []byte - func TestLoadState(t *testing.T) { - t.Run("Uncompressed", func(t *testing.T) { - dir := t.TempDir() - path := filepath.Join(dir, "state.json") - require.NoError(t, os.WriteFile(path, testState, 0644)) - - state, err := parseState(path) - require.NoError(t, err) - - var expected singlethreaded.State - require.NoError(t, json.Unmarshal(testState, &expected)) - require.Equal(t, &expected, state) - }) - - t.Run("Gzipped", func(t *testing.T) { - dir := t.TempDir() - path := filepath.Join(dir, "state.json.gz") - f, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644) - require.NoError(t, err) - defer f.Close() - writer := gzip.NewWriter(f) - _, err = writer.Write(testState) - require.NoError(t, err) - require.NoError(t, writer.Close()) - - state, err := parseState(path) - require.NoError(t, err) - - var expected singlethreaded.State - require.NoError(t, json.Unmarshal(testState, &expected)) - require.Equal(t, &expected, state) - }) - - t.Run("Binary", func(t *testing.T) { - var expected singlethreaded.State - require.NoError(t, json.Unmarshal(testState, &expected)) - - dir := t.TempDir() - path := filepath.Join(dir, "state.bin") - require.NoError(t, serialize.Write[*singlethreaded.State](path, &expected, 0644)) - - state, err := parseState(path) - require.NoError(t, err) - require.Equal(t, &expected, state) - }) - - t.Run("BinaryGzip", func(t *testing.T) { - var expected singlethreaded.State - require.NoError(t, json.Unmarshal(testState, &expected)) - - dir := t.TempDir() - path := filepath.Join(dir, "state.bin.gz") - require.NoError(t, serialize.Write[*singlethreaded.State](path, &expected, 0644)) - - state, err := parseState(path) - require.NoError(t, err) - require.Equal(t, &expected, state) - }) + tests := []struct { + name string + creator func() mipsevm.FPVMState + supportsJSON bool + }{ + { + name: "singlethreaded", + creator: func() mipsevm.FPVMState { return singlethreaded.CreateInitialState(234, 82) }, + supportsJSON: true, + }, + { + name: "multithreaded", + creator: func() mipsevm.FPVMState { return multithreaded.CreateInitialState(982, 492) }, + supportsJSON: false, + }, + } + for _, test := range tests { + test := test + loadExpectedState := func(t *testing.T) *versions.VersionedState { + state, err := versions.NewFromState(test.creator()) + require.NoError(t, err) + return state + } + t.Run(test.name, func(t *testing.T) { + t.Run("Uncompressed", func(t *testing.T) { + if !test.supportsJSON { + t.Skip("JSON not supported by state version") + } + expected := loadExpectedState(t) + path := writeState(t, "state.json", expected) + + state, err := parseState(path) + require.NoError(t, err) + + require.Equal(t, expected, state) + }) + + t.Run("Gzipped", func(t *testing.T) { + if !test.supportsJSON { + t.Skip("JSON not supported by state version") + } + expected := loadExpectedState(t) + path := writeState(t, "state.json.gz", expected) + + state, err := parseState(path) + require.NoError(t, err) + + require.Equal(t, expected, state) + }) + + t.Run("Binary", func(t *testing.T) { + expected := loadExpectedState(t) + + path := writeState(t, "state.bin", expected) + + state, err := parseState(path) + require.NoError(t, err) + require.Equal(t, expected, state) + }) + + t.Run("BinaryGzip", func(t *testing.T) { + expected := loadExpectedState(t) + + path := writeState(t, "state.bin.gz", expected) + + state, err := parseState(path) + require.NoError(t, err) + require.Equal(t, expected, state) + }) + }) + } +} + +func writeState(t *testing.T, filename string, state *versions.VersionedState) string { + dir := t.TempDir() + path := filepath.Join(dir, filename) + require.NoError(t, serialize.Write(path, state, 0644)) + return path } diff --git a/op-challenger/game/fault/trace/cannon/test_data/invalid.json b/op-challenger/game/fault/trace/cannon/test_data/invalid.json deleted file mode 100644 index 06a76bf5b23d..000000000000 --- a/op-challenger/game/fault/trace/cannon/test_data/invalid.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "preimageKey": 1 -} diff --git a/op-challenger/game/fault/trace/cannon/test_data/state.json b/op-challenger/game/fault/trace/cannon/test_data/state.json deleted file mode 100644 index 82f67624ce03..000000000000 --- a/op-challenger/game/fault/trace/cannon/test_data/state.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "memory": [{"index":10,"data":"eJzswAENAAAAwiD7p7bHBwMAAADyHgAA//8QAAAB"}], - "preimageKey": "0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", - "preimageOffset": 42, - "pc": 94, - "nextPC": 1, - "lo": 3, - "hi": 5, - "heap": 4, - "exit": 1, - "exited": true, - "step": 8849, - "registers": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2147471360,0,0] -} diff --git a/op-e2e/faultproofs/precompile_test.go b/op-e2e/faultproofs/precompile_test.go index 37b02aa3858d..116864c06e67 100644 --- a/op-e2e/faultproofs/precompile_test.go +++ b/op-e2e/faultproofs/precompile_test.go @@ -7,7 +7,7 @@ import ( "path/filepath" "testing" - "github.com/ethereum-optimism/optimism/cannon/serialize" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/versions" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" @@ -15,7 +15,6 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/stretchr/testify/require" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" "github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" @@ -261,9 +260,9 @@ func runCannon(t *testing.T, ctx context.Context, sys *op_e2e.System, inputs uti err := executor.DoGenerateProof(ctx, proofsDir, math.MaxUint, math.MaxUint, extraVmArgs...) require.NoError(t, err, "failed to generate proof") - state, err := serialize.Load[singlethreaded.State](vm.FinalStatePath(proofsDir, cfg.Cannon.BinarySnapshots)) + state, err := versions.LoadStateFromFile(vm.FinalStatePath(proofsDir, cfg.Cannon.BinarySnapshots)) require.NoError(t, err, "failed to parse state") - require.True(t, state.Exited, "cannon did not exit") - require.Zero(t, state.ExitCode, "cannon failed with exit code %d", state.ExitCode) - t.Logf("Completed in %d steps", state.Step) + require.True(t, state.GetExited(), "cannon did not exit") + require.Zero(t, state.GetExitCode(), "cannon failed with exit code %d", state.GetExitCode()) + t.Logf("Completed in %d steps", state.GetStep()) } From dc5cf529a30bf651fabf34d7c4b54f863ef96929 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Tue, 10 Sep 2024 11:24:33 +1000 Subject: [PATCH 077/264] op-challenger: Release agent resources once game is complete (#11820) --- op-challenger/game/fault/player.go | 12 +++++++++--- op-challenger/game/fault/player_test.go | 5 +++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/op-challenger/game/fault/player.go b/op-challenger/game/fault/player.go index cede89217c59..5ab187707557 100644 --- a/op-challenger/game/fault/player.go +++ b/op-challenger/game/fault/player.go @@ -64,6 +64,10 @@ type GameContract interface { GetL1Head(ctx context.Context) (common.Hash, error) } +var actNoop = func(ctx context.Context) error { + return nil +} + type resourceCreator func(ctx context.Context, logger log.Logger, gameDepth types.Depth, dir string) (types.TraceAccessor, error) func NewGamePlayer( @@ -98,9 +102,7 @@ func NewGamePlayer( prestateValidators: validators, status: status, // Act function does nothing because the game is already complete - act: func(ctx context.Context) error { - return nil - }, + act: actNoop, }, nil } @@ -195,6 +197,10 @@ func (g *GamePlayer) ProgressGame(ctx context.Context) gameTypes.GameStatus { } g.logGameStatus(ctx, status) g.status = status + if status != gameTypes.GameStatusInProgress { + // Release the agent as we will no longer need to act on this game. + g.act = actNoop + } return status } diff --git a/op-challenger/game/fault/player_test.go b/op-challenger/game/fault/player_test.go index 0c662ac63883..7c05525a8823 100644 --- a/op-challenger/game/fault/player_test.go +++ b/op-challenger/game/fault/player_test.go @@ -90,6 +90,11 @@ func TestDoNotActOnCompleteGame(t *testing.T) { fetched = game.ProgressGame(context.Background()) require.Equal(t, 1, gameState.callCount, "does not act after game is complete") require.Equal(t, status, fetched) + + // Should have replaced the act function with a noop so callCount doesn't update even when called directly + // This allows the agent resources to be GC'd + require.NoError(t, game.act(context.Background())) + require.Equal(t, 1, gameState.callCount) }) } } From 7e97b67d43f2d89021eb49b01b55e22097d18d40 Mon Sep 17 00:00:00 2001 From: Michael de Hoog Date: Mon, 9 Sep 2024 15:58:55 -1000 Subject: [PATCH 078/264] Fix race condition in sequencer stopping logic (#11769) * Fix race condition in sequencer stopping logic * Add channel to signal that latestHead has been updated * Fix test * Store latest sealed separately, as latest gets cleared by engine.PayloadSuccessEvent * Cleanup tests * Add assertions on latest block ref variables * Re-check if sequencer is active --- op-node/rollup/sequencing/sequencer.go | 43 +++++++++++++++++--- op-node/rollup/sequencing/sequencer_test.go | 45 +++++++++++++++++++++ 2 files changed, 83 insertions(+), 5 deletions(-) diff --git a/op-node/rollup/sequencing/sequencer.go b/op-node/rollup/sequencing/sequencer.go index 16fbca759513..e488300b49f8 100644 --- a/op-node/rollup/sequencing/sequencer.go +++ b/op-node/rollup/sequencing/sequencer.go @@ -111,8 +111,11 @@ type Sequencer struct { nextAction time.Time nextActionOK bool - latest BuildingState - latestHead eth.L2BlockRef + latest BuildingState + latestSealed eth.L2BlockRef + latestHead eth.L2BlockRef + + latestHeadSet chan struct{} // toBlockRef converts a payload to a block-ref, and is only configurable for test-purposes toBlockRef func(rollupCfg *rollup.Config, payload *eth.ExecutionPayload) (eth.L2BlockRef, error) @@ -283,6 +286,7 @@ func (d *Sequencer) onBuildSealed(x engine.BuildSealedEvent) { Ref: x.Ref, }) d.latest.Ref = x.Ref + d.latestSealed = x.Ref } func (d *Sequencer) onPayloadSealInvalid(x engine.PayloadSealInvalidEvent) { @@ -425,7 +429,7 @@ func (d *Sequencer) onForkchoiceUpdate(x engine.ForkchoiceUpdateEvent) { d.log.Debug("Sequencer is processing forkchoice update", "unsafe", x.UnsafeL2Head, "latest", d.latestHead) if !d.active.Load() { - d.latestHead = x.UnsafeL2Head + d.setLatestHead(x.UnsafeL2Head) return } // If the safe head has fallen behind by a significant number of blocks, delay creating new blocks @@ -456,7 +460,15 @@ func (d *Sequencer) onForkchoiceUpdate(x engine.ForkchoiceUpdateEvent) { d.nextAction = now } } - d.latestHead = x.UnsafeL2Head + d.setLatestHead(x.UnsafeL2Head) +} + +func (d *Sequencer) setLatestHead(head eth.L2BlockRef) { + d.latestHead = head + if d.latestHeadSet != nil { + close(d.latestHeadSet) + d.latestHeadSet = nil + } } // StartBuildingBlock initiates a block building job on top of the given L2 head, safe and finalized blocks, and using the provided l1Origin. @@ -646,12 +658,33 @@ func (d *Sequencer) forceStart() error { return nil } -func (d *Sequencer) Stop(ctx context.Context) (hash common.Hash, err error) { +func (d *Sequencer) Stop(ctx context.Context) (common.Hash, error) { if err := d.l.LockCtx(ctx); err != nil { return common.Hash{}, err } + + if !d.active.Load() { + d.l.Unlock() + return common.Hash{}, ErrSequencerAlreadyStopped + } + + // ensure latestHead has been updated to the latest sealed/gossiped block before stopping the sequencer + for d.latestHead.Hash != d.latestSealed.Hash { + latestHeadSet := make(chan struct{}) + d.latestHeadSet = latestHeadSet + d.l.Unlock() + select { + case <-ctx.Done(): + return common.Hash{}, ctx.Err() + case <-latestHeadSet: + } + if err := d.l.LockCtx(ctx); err != nil { + return common.Hash{}, err + } + } defer d.l.Unlock() + // Stop() may have been called twice, so check if we are active after reacquiring the lock if !d.active.Load() { return common.Hash{}, ErrSequencerAlreadyStopped } diff --git a/op-node/rollup/sequencing/sequencer_test.go b/op-node/rollup/sequencing/sequencer_test.go index 3341cf0bcb08..7b410e644ad2 100644 --- a/op-node/rollup/sequencing/sequencer_test.go +++ b/op-node/rollup/sequencing/sequencer_test.go @@ -170,11 +170,37 @@ func TestSequencer_StartStop(t *testing.T) { require.True(t, deps.asyncGossip.started, "async gossip is always started on initialization") require.False(t, deps.seqState.active, "sequencer not active yet") + // latest refs should all be empty + require.Equal(t, common.Hash{}, seq.latest.Ref.Hash) + require.Equal(t, common.Hash{}, seq.latestSealed.Hash) + require.Equal(t, common.Hash{}, seq.latestHead.Hash) + + // update the latestSealed + envelope := ð.ExecutionPayloadEnvelope{ + ExecutionPayload: ð.ExecutionPayload{}, + } + emitter.ExpectOnce(engine.PayloadProcessEvent{ + Envelope: envelope, + Ref: eth.L2BlockRef{Hash: common.Hash{0xaa}}, + }) + seq.OnEvent(engine.BuildSealedEvent{ + Envelope: envelope, + Ref: eth.L2BlockRef{Hash: common.Hash{0xaa}}, + }) + require.Equal(t, common.Hash{0xaa}, seq.latest.Ref.Hash) + require.Equal(t, common.Hash{0xaa}, seq.latestSealed.Hash) + require.Equal(t, common.Hash{}, seq.latestHead.Hash) + + // update latestHead + emitter.AssertExpectations(t) seq.OnEvent(engine.ForkchoiceUpdateEvent{ UnsafeL2Head: eth.L2BlockRef{Hash: common.Hash{0xaa}}, SafeL2Head: eth.L2BlockRef{}, FinalizedL2Head: eth.L2BlockRef{}, }) + require.Equal(t, common.Hash{0xaa}, seq.latest.Ref.Hash) + require.Equal(t, common.Hash{0xaa}, seq.latestSealed.Hash) + require.Equal(t, common.Hash{0xaa}, seq.latestHead.Hash) require.False(t, seq.Active()) // no action scheduled @@ -346,6 +372,25 @@ func TestSequencer_StaleBuild(t *testing.T) { _, ok = seq.NextAction() require.False(t, ok, "optimistically published, but not ready to sequence next, until local processing completes") + // attempting to stop block building here should timeout, because the sealed block is different from the latestHead + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + _, err := seq.Stop(ctx) + require.Error(t, err, "stop should have timed out") + require.ErrorIs(t, err, ctx.Err()) + + // reset latestSealed to the previous head + emitter.ExpectOnce(engine.PayloadProcessEvent{ + Envelope: payloadEnvelope, + Ref: head, + }) + seq.OnEvent(engine.BuildSealedEvent{ + Info: payloadInfo, + Envelope: payloadEnvelope, + Ref: head, + }) + emitter.AssertExpectations(t) + // Now we stop the block building, // before successful local processing of the committed block! stopHead, err := seq.Stop(context.Background()) From 7f3d6ef5ffc2b9a48cb5e7d340e01b877f6047f1 Mon Sep 17 00:00:00 2001 From: Brian Bland Date: Mon, 9 Sep 2024 20:12:15 -0700 Subject: [PATCH 079/264] feat: Add nested directory data format for op-program kvstore (#11795) * feat: Add nested directory data format for op-program kvstore * Review feedback: Update error message Co-authored-by: Adrian Sutton * op-program: Make directory preimage format the default. --------- Co-authored-by: Adrian Sutton Co-authored-by: Adrian Sutton --- op-program/host/config/config.go | 2 +- op-program/host/flags/flags.go | 2 +- op-program/host/host.go | 2 + op-program/host/kvstore/directory.go | 86 +++++++++++++++++++++++ op-program/host/kvstore/directory_test.go | 28 ++++++++ op-program/host/kvstore/file_test.go | 4 +- op-program/host/types/types.go | 7 +- 7 files changed, 124 insertions(+), 7 deletions(-) create mode 100644 op-program/host/kvstore/directory.go create mode 100644 op-program/host/kvstore/directory_test.go diff --git a/op-program/host/config/config.go b/op-program/host/config/config.go index dd9a2dff15ca..c39a4b9697f3 100644 --- a/op-program/host/config/config.go +++ b/op-program/host/config/config.go @@ -139,7 +139,7 @@ func NewConfig( L2ClaimBlockNumber: l2ClaimBlockNum, L1RPCKind: sources.RPCKindStandard, IsCustomChainConfig: isCustomConfig, - DataFormat: types.DataFormatFile, + DataFormat: types.DataFormatDirectory, } } diff --git a/op-program/host/flags/flags.go b/op-program/host/flags/flags.go index c46422876d63..5eb633c7202f 100644 --- a/op-program/host/flags/flags.go +++ b/op-program/host/flags/flags.go @@ -40,7 +40,7 @@ var ( Name: "data.format", Usage: fmt.Sprintf("Format to use for preimage data storage. Available formats: %s", openum.EnumString(types.SupportedDataFormats)), EnvVars: prefixEnvVars("DATA_FORMAT"), - Value: string(types.DataFormatFile), + Value: string(types.DataFormatDirectory), } L2NodeAddr = &cli.StringFlag{ Name: "l2", diff --git a/op-program/host/host.go b/op-program/host/host.go index a2ee245adede..886205aca396 100644 --- a/op-program/host/host.go +++ b/op-program/host/host.go @@ -158,6 +158,8 @@ func PreimageServer(ctx context.Context, logger log.Logger, cfg *config.Config, switch cfg.DataFormat { case types.DataFormatFile: kv = kvstore.NewFileKV(cfg.DataDir) + case types.DataFormatDirectory: + kv = kvstore.NewDirectoryKV(cfg.DataDir) case types.DataFormatPebble: kv = kvstore.NewPebbleKV(cfg.DataDir) default: diff --git a/op-program/host/kvstore/directory.go b/op-program/host/kvstore/directory.go new file mode 100644 index 000000000000..28ef957b0f27 --- /dev/null +++ b/op-program/host/kvstore/directory.go @@ -0,0 +1,86 @@ +package kvstore + +import ( + "encoding/hex" + "errors" + "fmt" + "io" + "os" + "path" + "sync" + + "github.com/ethereum/go-ethereum/common" +) + +// DirectoryKV is a disk-backed key-value store, every key-value pair is a hex-encoded .txt file, with the value as content. +// DirectoryKV is safe for concurrent use with a single DirectoryKV instance. +// DirectoryKV is safe for concurrent use between different DirectoryKV instances of the same disk directory as long as the +// file system supports atomic renames. +type DirectoryKV struct { + sync.RWMutex + path string +} + +// NewDirectoryKV creates a DirectoryKV that puts/gets pre-images as files in the given directory path. +// The path must exist, or subsequent Put/Get calls will error when it does not. +func NewDirectoryKV(path string) *DirectoryKV { + return &DirectoryKV{path: path} +} + +// pathKey returns the file path for the given key. +// This is composed of the first characters of the non-0x-prefixed hex key as a directory, and the rest as the file name. +func (d *DirectoryKV) pathKey(k common.Hash) string { + key := k.String() + dir, name := key[2:6], key[6:] + return path.Join(d.path, dir, name+".txt") +} + +func (d *DirectoryKV) Put(k common.Hash, v []byte) error { + d.Lock() + defer d.Unlock() + f, err := openTempFile(d.path, k.String()+".txt.*") + if err != nil { + return fmt.Errorf("failed to open temp file for pre-image %s: %w", k, err) + } + defer os.Remove(f.Name()) // Clean up the temp file if it doesn't actually get moved into place + if _, err := f.Write([]byte(hex.EncodeToString(v))); err != nil { + _ = f.Close() + return fmt.Errorf("failed to write pre-image %s to disk: %w", k, err) + } + if err := f.Close(); err != nil { + return fmt.Errorf("failed to close temp pre-image %s file: %w", k, err) + } + + targetFile := d.pathKey(k) + if err := os.MkdirAll(path.Dir(targetFile), 0777); err != nil { + return fmt.Errorf("failed to create parent directory for pre-image %s: %w", f.Name(), err) + } + if err := os.Rename(f.Name(), targetFile); err != nil { + return fmt.Errorf("failed to move temp file %v to final destination %v: %w", f.Name(), targetFile, err) + } + return nil +} + +func (d *DirectoryKV) Get(k common.Hash) ([]byte, error) { + d.RLock() + defer d.RUnlock() + f, err := os.OpenFile(d.pathKey(k), os.O_RDONLY, filePermission) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + return nil, ErrNotFound + } + return nil, fmt.Errorf("failed to open pre-image file %s: %w", k, err) + } + defer f.Close() // fine to ignore closing error here + dat, err := io.ReadAll(f) + if err != nil { + return nil, fmt.Errorf("failed to read pre-image from file %s: %w", k, err) + } + return hex.DecodeString(string(dat)) +} + +func (d *DirectoryKV) Close() error { + return nil +} + +var _ KV = (*DirectoryKV)(nil) diff --git a/op-program/host/kvstore/directory_test.go b/op-program/host/kvstore/directory_test.go new file mode 100644 index 000000000000..efbf0ea20c5a --- /dev/null +++ b/op-program/host/kvstore/directory_test.go @@ -0,0 +1,28 @@ +package kvstore + +import ( + "path/filepath" + "testing" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/require" +) + +func TestDirectoryKV(t *testing.T) { + tmp := t.TempDir() // automatically removed by testing cleanup + kv := NewDirectoryKV(tmp) + t.Cleanup(func() { // Can't use defer because kvTest runs tests in parallel. + require.NoError(t, kv.Close()) + }) + kvTest(t, kv) +} + +func TestDirectoryKV_CreateMissingDirectory(t *testing.T) { + tmp := t.TempDir() + dir := filepath.Join(tmp, "data") + kv := NewDirectoryKV(dir) + defer kv.Close() + val := []byte{1, 2, 3, 4} + key := crypto.Keccak256Hash(val) + require.NoError(t, kv.Put(key, val)) +} diff --git a/op-program/host/kvstore/file_test.go b/op-program/host/kvstore/file_test.go index b30517db2faa..7dc34b708cfa 100644 --- a/op-program/host/kvstore/file_test.go +++ b/op-program/host/kvstore/file_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/require" ) -func TestDiskKV(t *testing.T) { +func TestFileKV(t *testing.T) { tmp := t.TempDir() // automatically removed by testing cleanup kv := NewFileKV(tmp) t.Cleanup(func() { // Can't use defer because kvTest runs tests in parallel. @@ -17,7 +17,7 @@ func TestDiskKV(t *testing.T) { kvTest(t, kv) } -func TestCreateMissingDirectory(t *testing.T) { +func TestFileKV_CreateMissingDirectory(t *testing.T) { tmp := t.TempDir() dir := filepath.Join(tmp, "data") kv := NewFileKV(dir) diff --git a/op-program/host/types/types.go b/op-program/host/types/types.go index 104dafe2dbc4..7cb24b55f65d 100644 --- a/op-program/host/types/types.go +++ b/op-program/host/types/types.go @@ -3,8 +3,9 @@ package types type DataFormat string const ( - DataFormatFile DataFormat = "file" - DataFormatPebble DataFormat = "pebble" + DataFormatFile DataFormat = "file" + DataFormatDirectory DataFormat = "directory" + DataFormatPebble DataFormat = "pebble" ) -var SupportedDataFormats = []DataFormat{DataFormatFile, DataFormatPebble} +var SupportedDataFormats = []DataFormat{DataFormatFile, DataFormatDirectory, DataFormatPebble} From e2356c353dc78b914990eb55c0a2767712391ae8 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Tue, 10 Sep 2024 13:49:07 +1000 Subject: [PATCH 080/264] Revert "op-program: Make directory preimage format the default." (#11823) --- op-program/host/config/config.go | 2 +- op-program/host/flags/flags.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/op-program/host/config/config.go b/op-program/host/config/config.go index c39a4b9697f3..dd9a2dff15ca 100644 --- a/op-program/host/config/config.go +++ b/op-program/host/config/config.go @@ -139,7 +139,7 @@ func NewConfig( L2ClaimBlockNumber: l2ClaimBlockNum, L1RPCKind: sources.RPCKindStandard, IsCustomChainConfig: isCustomConfig, - DataFormat: types.DataFormatDirectory, + DataFormat: types.DataFormatFile, } } diff --git a/op-program/host/flags/flags.go b/op-program/host/flags/flags.go index 5eb633c7202f..c46422876d63 100644 --- a/op-program/host/flags/flags.go +++ b/op-program/host/flags/flags.go @@ -40,7 +40,7 @@ var ( Name: "data.format", Usage: fmt.Sprintf("Format to use for preimage data storage. Available formats: %s", openum.EnumString(types.SupportedDataFormats)), EnvVars: prefixEnvVars("DATA_FORMAT"), - Value: string(types.DataFormatDirectory), + Value: string(types.DataFormatFile), } L2NodeAddr = &cli.StringFlag{ Name: "l2", From 219ebe00b10cb197311c28100de15e7b4a9f5503 Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Tue, 10 Sep 2024 00:16:03 -0600 Subject: [PATCH 081/264] Add broadcast API to Go forge scripts (#11826) * Add broadcast API to Go forge scripts Adds a hooks-based API to collect transactions broadcasted via `vm.broadcast(*)` in the Go-based Forge scripts. Users pass an `OnBroadcast` hook to the host, which will be called with a `Broadcast` struct with the following fields whenever a transaction needs to be emitted: ```go type Broadcast struct { From common.Address To common.Address Calldata []byte Value *big.Int } ``` This API lets us layer on custom transaction management in the future which will be helpful for `op-deployer`. As part of this PR, I changed the internal `callStack` data structure to contain pointers to `CallFrame`s rather than passing by value. I discovered a bug where the pranked sender was not being cleared in subsequent calls due to an ineffectual assignment error. I took a look at the implementation and there are many places where assignments to call frames within the stack happen after converting the value to a reference, so converting the stack to store pointers in the first place both simplified the code and eliminated a class of errors in the future. I updated the public API methods to return copies of the internal structs to prevent accidental mutation. * Code review updates * moar review updates * fix bug with staticcall --- op-chain-ops/script/prank.go | 40 ++++++++++++- op-chain-ops/script/script.go | 55 +++++++++++++++-- op-chain-ops/script/script_test.go | 59 +++++++++++++++++++ .../testdata/scripts/ScriptExample.s.sol | 51 ++++++++++++++++ .../ScriptExample.s.sol/ScriptExample.json | 2 +- .../ScriptExample.s.sol/Vm.json | 2 +- .../ScriptExample.s.sol/console.json | 2 +- 7 files changed, 199 insertions(+), 12 deletions(-) diff --git a/op-chain-ops/script/prank.go b/op-chain-ops/script/prank.go index 816c59033690..49214fdb7888 100644 --- a/op-chain-ops/script/prank.go +++ b/op-chain-ops/script/prank.go @@ -1,6 +1,7 @@ package script import ( + "bytes" "errors" "math/big" @@ -69,7 +70,7 @@ func (h *Host) Prank(msgSender *common.Address, txOrigin *common.Address, repeat h.log.Warn("no call stack") return nil // cannot prank while not in a call. } - cf := &h.callStack[len(h.callStack)-1] + cf := h.callStack[len(h.callStack)-1] if cf.Prank != nil { if cf.Prank.Broadcast && !broadcast { return errors.New("you have an active broadcast; broadcasting and pranks are not compatible") @@ -98,7 +99,7 @@ func (h *Host) StopPrank(broadcast bool) error { if len(h.callStack) == 0 { return nil } - cf := &h.callStack[len(h.callStack)-1] + cf := h.callStack[len(h.callStack)-1] if cf.Prank == nil { if broadcast { return errors.New("no broadcast in progress to stop") @@ -127,7 +128,7 @@ func (h *Host) CallerMode() CallerMode { if len(h.callStack) == 0 { return CallerModeNone } - cf := &h.callStack[len(h.callStack)-1] + cf := h.callStack[len(h.callStack)-1] if cf.Prank != nil { if cf.Prank.Broadcast { if cf.Prank.Repeat { @@ -157,3 +158,36 @@ const ( CallerModePrank CallerModeRecurrentPrank ) + +// Broadcast captures a transaction that was selected to be broadcasted +// via vm.broadcast(). Actually submitting the transaction is left up +// to other tools. +type Broadcast struct { + From common.Address + To common.Address + Calldata []byte + Value *big.Int +} + +// NewBroadcastFromCtx creates a Broadcast from a VM context. This method +// is preferred to manually creating the struct since it correctly handles +// data that must be copied prior to being returned to prevent accidental +// mutation. +func NewBroadcastFromCtx(ctx *vm.ScopeContext) Broadcast { + // Consistently return nil for zero values in order + // for tests to have a deterministic value to compare + // against. + value := ctx.CallValue().ToBig() + if value.Cmp(common.Big0) == 0 { + value = nil + } + + // Need to clone CallInput() below since it's used within + // the VM itself elsewhere. + return Broadcast{ + From: ctx.Caller(), + To: ctx.Address(), + Calldata: bytes.Clone(ctx.CallInput()), + Value: value, + } +} diff --git a/op-chain-ops/script/script.go b/op-chain-ops/script/script.go index 16ee8f7a94da..a9c98679ab3d 100644 --- a/op-chain-ops/script/script.go +++ b/op-chain-ops/script/script.go @@ -3,6 +3,7 @@ package script import ( "bytes" "encoding/binary" + "encoding/hex" "encoding/json" "fmt" "math/big" @@ -69,7 +70,7 @@ type Host struct { precompiles map[common.Address]vm.PrecompiledContract - callStack []CallFrame + callStack []*CallFrame // serializerStates are in-progress JSON payloads by name, // for the serializeX family of cheat codes, see: @@ -86,12 +87,34 @@ type Host struct { srcMaps map[common.Address]*srcmap.SourceMap onLabel []func(name string, addr common.Address) + + hooks *Hooks +} + +type HostOption func(h *Host) + +type BroadcastHook func(broadcast Broadcast) + +type Hooks struct { + OnBroadcast BroadcastHook +} + +func WithBroadcastHook(hook BroadcastHook) HostOption { + return func(h *Host) { + h.hooks.OnBroadcast = hook + } } // NewHost creates a Host that can load contracts from the given Artifacts FS, // and with an EVM initialized to the given executionContext. // Optionally src-map loading may be enabled, by providing a non-nil srcFS to read sources from. -func NewHost(logger log.Logger, fs *foundry.ArtifactsFS, srcFS *foundry.SourceMapFS, executionContext Context) *Host { +func NewHost( + logger log.Logger, + fs *foundry.ArtifactsFS, + srcFS *foundry.SourceMapFS, + executionContext Context, + options ...HostOption, +) *Host { h := &Host{ log: logger, af: fs, @@ -101,6 +124,13 @@ func NewHost(logger log.Logger, fs *foundry.ArtifactsFS, srcFS *foundry.SourceMa precompiles: make(map[common.Address]vm.PrecompiledContract), srcFS: srcFS, srcMaps: make(map[common.Address]*srcmap.SourceMap), + hooks: &Hooks{ + OnBroadcast: func(broadcast Broadcast) {}, + }, + } + + for _, opt := range options { + opt(h) } // Init a default chain config, with all the mainnet L1 forks activated @@ -361,6 +391,19 @@ func (h *Host) unwindCallstack(depth int) { if len(h.callStack) > 1 { parentCallFrame := h.callStack[len(h.callStack)-2] if parentCallFrame.Prank != nil { + if parentCallFrame.Prank.Broadcast && parentCallFrame.LastOp != vm.STATICCALL { + currentFrame := h.callStack[len(h.callStack)-1] + bcast := NewBroadcastFromCtx(currentFrame.Ctx) + h.hooks.OnBroadcast(bcast) + h.log.Debug( + "called broadcast hook", + "from", bcast.From, + "to", bcast.To, + "calldata", hex.EncodeToString(bcast.Calldata), + "value", bcast.Value, + ) + } + // While going back to the parent, restore the tx.origin. // It will later be re-applied on sub-calls if the prank persists (if Repeat == true). if parentCallFrame.Prank.Origin != nil { @@ -372,7 +415,7 @@ func (h *Host) unwindCallstack(depth int) { } } // Now pop the call-frame - h.callStack[len(h.callStack)-1] = CallFrame{} // don't hold on to the underlying call-frame resources + h.callStack[len(h.callStack)-1] = nil // don't hold on to the underlying call-frame resources h.callStack = h.callStack[:len(h.callStack)-1] } } @@ -384,7 +427,7 @@ func (h *Host) onOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpCo // Check if we are entering a new depth, add it to the call-stack if so. // We do this here, instead of onEnter, to capture an initialized scope. if len(h.callStack) == 0 || h.callStack[len(h.callStack)-1].Depth < depth { - h.callStack = append(h.callStack, CallFrame{ + h.callStack = append(h.callStack, &CallFrame{ Depth: depth, LastOp: vm.OpCode(op), LastPC: pc, @@ -395,7 +438,7 @@ func (h *Host) onOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpCo if len(h.callStack) == 0 || h.callStack[len(h.callStack)-1].Ctx != scopeCtx { panic("scope context changed without call-frame pop/push") } - cf := &h.callStack[len(h.callStack)-1] + cf := h.callStack[len(h.callStack)-1] if vm.OpCode(op) == vm.JUMPDEST { // remember the last PC before successful jump cf.LastJumps = append(cf.LastJumps, cf.LastPC) if len(cf.LastJumps) > jumpHistory { @@ -429,7 +472,7 @@ func (h *Host) CurrentCall() CallFrame { if len(h.callStack) == 0 { return CallFrame{} } - return h.callStack[len(h.callStack)-1] + return *h.callStack[len(h.callStack)-1] } // MsgSender returns the msg.sender of the current active EVM call-frame, diff --git a/op-chain-ops/script/script_test.go b/op-chain-ops/script/script_test.go index c0c69a26fefc..075761756081 100644 --- a/op-chain-ops/script/script_test.go +++ b/op-chain-ops/script/script_test.go @@ -1,8 +1,13 @@ package script import ( + "fmt" + "strings" "testing" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/holiman/uint256" "github.com/stretchr/testify/require" @@ -35,3 +40,57 @@ func TestScript(t *testing.T) { // and a second time, to see if we can revisit the host state. require.NoError(t, h.cheatcodes.Precompile.DumpState("noop")) } + +func TestScriptBroadcast(t *testing.T) { + logger := testlog.Logger(t, log.LevelDebug) + af := foundry.OpenArtifactsDir("./testdata/test-artifacts") + + mustEncodeCalldata := func(method, input string) []byte { + packer, err := abi.JSON(strings.NewReader(fmt.Sprintf(`[{"type":"function","name":"%s","inputs":[{"type":"string","name":"input"}]}]`, method))) + require.NoError(t, err) + + data, err := packer.Pack(method, input) + require.NoError(t, err) + return data + } + + senderAddr := common.HexToAddress("0x5b73C5498c1E3b4dbA84de0F1833c4a029d90519") + expBroadcasts := []Broadcast{ + { + From: senderAddr, + To: senderAddr, + Calldata: mustEncodeCalldata("call1", "single_call1"), + }, + { + From: senderAddr, + To: senderAddr, + Calldata: mustEncodeCalldata("call1", "startstop_call1"), + }, + { + From: senderAddr, + To: senderAddr, + Calldata: mustEncodeCalldata("call2", "startstop_call2"), + }, + { + From: senderAddr, + To: senderAddr, + Calldata: mustEncodeCalldata("nested1", "nested"), + }, + } + + scriptContext := DefaultContext + var broadcasts []Broadcast + hook := func(broadcast Broadcast) { + broadcasts = append(broadcasts, broadcast) + } + h := NewHost(logger, af, nil, scriptContext, WithBroadcastHook(hook)) + addr, err := h.LoadContract("ScriptExample.s.sol", "ScriptExample") + require.NoError(t, err) + + require.NoError(t, h.EnableCheats()) + + input := bytes4("runBroadcast()") + returnData, _, err := h.Call(scriptContext.Sender, addr, input[:], DefaultFoundryGasLimit, uint256.NewInt(0)) + require.NoError(t, err, "call failed: %x", string(returnData)) + require.EqualValues(t, expBroadcasts, broadcasts) +} diff --git a/op-chain-ops/script/testdata/scripts/ScriptExample.s.sol b/op-chain-ops/script/testdata/scripts/ScriptExample.s.sol index 4c1dcf6275f2..954cab960a88 100644 --- a/op-chain-ops/script/testdata/scripts/ScriptExample.s.sol +++ b/op-chain-ops/script/testdata/scripts/ScriptExample.s.sol @@ -8,6 +8,9 @@ interface Vm { function parseJsonKeys(string calldata json, string calldata key) external pure returns (string[] memory keys); function startPrank(address msgSender) external; function stopPrank() external; + function broadcast() external; + function startBroadcast() external; + function stopBroadcast() external; } // console is a minimal version of the console2 lib. @@ -64,6 +67,9 @@ contract ScriptExample { address internal constant VM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code")))); Vm internal constant vm = Vm(VM_ADDRESS); + // @notice counter variable to force non-pure calls. + uint256 public counter; + /// @notice example function, runs through basic cheat-codes and console logs. function run() public { bool x = vm.envOr("EXAMPLE_BOOL", false); @@ -90,9 +96,54 @@ contract ScriptExample { console.log("done!"); } + /// @notice example function, to test vm.broadcast with. + function runBroadcast() public { + console.log("testing single"); + vm.broadcast(); + this.call1("single_call1"); + this.call2("single_call2"); + + console.log("testing start/stop"); + vm.startBroadcast(); + this.call1("startstop_call1"); + this.call2("startstop_call2"); + this.callPure("startstop_pure"); + vm.stopBroadcast(); + this.call1("startstop_call3"); + + console.log("testing nested"); + vm.startBroadcast(); + this.nested1("nested"); + vm.stopBroadcast(); + } + /// @notice example external function, to force a CALL, and test vm.startPrank with. function hello(string calldata _v) external view { console.log(_v); console.log("hello msg.sender", address(msg.sender)); } + + function call1(string calldata _v) external { + counter++; + console.log(_v); + } + + function call2(string calldata _v) external { + counter++; + console.log(_v); + } + + function nested1(string calldata _v) external { + counter++; + this.nested2(_v); + } + + function nested2(string calldata _v) external { + counter++; + console.log(_v); + } + + function callPure(string calldata _v) external pure { + console.log(_v); + } } diff --git a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/ScriptExample.json b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/ScriptExample.json index aab5ca4e2642..fb6f32b277af 100644 --- a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/ScriptExample.json +++ b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/ScriptExample.json @@ -1 +1 @@ -{"abi":[{"type":"function","name":"hello","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"view"},{"type":"function","name":"run","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"bytecode":{"object":"0x608060405234801561001057600080fd5b50611079806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063a777d0dc1461003b578063c040622614610050575b600080fd5b61004e610049366004610c26565b610058565b005b61004e6100da565b61009782828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061092d92505050565b6100d66040518060400160405280601081526020017f68656c6c6f206d73672e73656e64657200000000000000000000000000000000815250336109bf565b5050565b604080517f4777f3cf0000000000000000000000000000000000000000000000000000000081526004810191909152600c60448201527f4558414d504c455f424f4f4c0000000000000000000000000000000000000000606482015260006024820181905290737109709ecfa91a80626ff3989d68f67f5b1dd12d90634777f3cf90608401602060405180830381865afa15801561017c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101a09190610c98565b90506101e16040518060400160405280601381526020017f626f6f6c2076616c75652066726f6d20656e760000000000000000000000000081525082610a50565b6102206040518060400160405280600d81526020017f636f6e7472616374206164647200000000000000000000000000000000000000815250306109bf565b604080518082018252600e81527f636f6e7472616374206e6f6e6365000000000000000000000000000000000000602082015290517f2d0335ab0000000000000000000000000000000000000000000000000000000081523060048201526102f39190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab906024015b602060405180830381865afa1580156102c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102e49190610cc1565b67ffffffffffffffff16610ae1565b6103326040518060400160405280600b81526020017f73656e6465722061646472000000000000000000000000000000000000000000815250336109bf565b604080518082018252600c81527f73656e646572206e6f6e63650000000000000000000000000000000000000000602082015290517f2d0335ab0000000000000000000000000000000000000000000000000000000081523360048201526103b99190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab906024016102a3565b60408051808201825260208082527f7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d9082015290517f213e4198000000000000000000000000000000000000000000000000000000008152600090737109709ecfa91a80626ff3989d68f67f5b1dd12d9063213e41989061043e908590600401610d65565b600060405180830381865afa15801561045b573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526104a19190810190610e35565b90506105176040518060400160405280600481526020017f6b65797300000000000000000000000000000000000000000000000000000000815250826000815181106104ef576104ef610f69565b60200260200101518360018151811061050a5761050a610f69565b6020026020010151610b72565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f66726f6d206f726967696e616c000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b15801561059457600080fd5b505afa1580156105a8573d6000803e3d6000fd5b50506040517f06447d5600000000000000000000000000000000000000000000000000000000815260426004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d92506306447d569150602401600060405180830381600087803b15801561061257600080fd5b505af1158015610626573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b20310000000000000000000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b1580156106a757600080fd5b505afa1580156106bb573d6000803e3d6000fd5b505050506106fe6040518060400160405280601781526020017f706172656e742073636f7065206d73672e73656e646572000000000000000000815250336109bf565b61073d6040518060400160405280601a81526020017f706172656e742073636f706520636f6e74726163742e61646472000000000000815250306109bf565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b203200000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b1580156107ba57600080fd5b505afa1580156107ce573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166390c5013b6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561083d57600080fd5b505af1158015610851573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f66726f6d206f726967696e616c20616761696e00000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b1580156108d257600080fd5b505afa1580156108e6573d6000803e3d6000fd5b505050506109286040518060400160405280600581526020017f646f6e652100000000000000000000000000000000000000000000000000000081525061092d565b505050565b6109bc816040516024016109419190610f98565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f41304fac00000000000000000000000000000000000000000000000000000000179052610c01565b50565b6100d682826040516024016109d5929190610fab565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f319af33300000000000000000000000000000000000000000000000000000000179052610c01565b6100d68282604051602401610a66929190610fe3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fc3b5563500000000000000000000000000000000000000000000000000000000179052610c01565b6100d68282604051602401610af7929190611007565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb60e72cc00000000000000000000000000000000000000000000000000000000179052610c01565b610928838383604051602401610b8a93929190611029565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f2ced7cef000000000000000000000000000000000000000000000000000000001790525b6109bc8180516a636f6e736f6c652e6c6f67602083016000808483855afa5050505050565b60008060208385031215610c3957600080fd5b823567ffffffffffffffff80821115610c5157600080fd5b818501915085601f830112610c6557600080fd5b813581811115610c7457600080fd5b866020828501011115610c8657600080fd5b60209290920196919550909350505050565b600060208284031215610caa57600080fd5b81518015158114610cba57600080fd5b9392505050565b600060208284031215610cd357600080fd5b815167ffffffffffffffff81168114610cba57600080fd5b60005b83811015610d06578181015183820152602001610cee565b83811115610d15576000848401525b50505050565b60008151808452610d33816020860160208601610ceb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b604081526000610d786040830184610d1b565b8281036020840152600c81527f2e726f6f745f6b65795b305d000000000000000000000000000000000000000060208201526040810191505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610e2d57610e2d610db7565b604052919050565b60006020808385031215610e4857600080fd5b825167ffffffffffffffff80821115610e6057600080fd5b8185019150601f8681840112610e7557600080fd5b825182811115610e8757610e87610db7565b8060051b610e96868201610de6565b918252848101860191868101908a841115610eb057600080fd5b87870192505b83831015610f5b57825186811115610ece5760008081fd5b8701603f81018c13610ee05760008081fd5b88810151604088821115610ef657610ef6610db7565b610f258b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08a85011601610de6565b8281528e82848601011115610f3a5760008081fd5b610f49838d8301848701610ceb565b85525050509187019190870190610eb6565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602081526000610cba6020830184610d1b565b604081526000610fbe6040830185610d1b565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b604081526000610ff66040830185610d1b565b905082151560208301529392505050565b60408152600061101a6040830185610d1b565b90508260208301529392505050565b60608152600061103c6060830186610d1b565b828103602084015261104e8186610d1b565b905082810360408401526110628185610d1b565b969550505050505056fea164736f6c634300080f000a","sourceMap":"2318:1449:0:-:0;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063a777d0dc1461003b578063c040622614610050575b600080fd5b61004e610049366004610c26565b610058565b005b61004e6100da565b61009782828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061092d92505050565b6100d66040518060400160405280601081526020017f68656c6c6f206d73672e73656e64657200000000000000000000000000000000815250336109bf565b5050565b604080517f4777f3cf0000000000000000000000000000000000000000000000000000000081526004810191909152600c60448201527f4558414d504c455f424f4f4c0000000000000000000000000000000000000000606482015260006024820181905290737109709ecfa91a80626ff3989d68f67f5b1dd12d90634777f3cf90608401602060405180830381865afa15801561017c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101a09190610c98565b90506101e16040518060400160405280601381526020017f626f6f6c2076616c75652066726f6d20656e760000000000000000000000000081525082610a50565b6102206040518060400160405280600d81526020017f636f6e7472616374206164647200000000000000000000000000000000000000815250306109bf565b604080518082018252600e81527f636f6e7472616374206e6f6e6365000000000000000000000000000000000000602082015290517f2d0335ab0000000000000000000000000000000000000000000000000000000081523060048201526102f39190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab906024015b602060405180830381865afa1580156102c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102e49190610cc1565b67ffffffffffffffff16610ae1565b6103326040518060400160405280600b81526020017f73656e6465722061646472000000000000000000000000000000000000000000815250336109bf565b604080518082018252600c81527f73656e646572206e6f6e63650000000000000000000000000000000000000000602082015290517f2d0335ab0000000000000000000000000000000000000000000000000000000081523360048201526103b99190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab906024016102a3565b60408051808201825260208082527f7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d9082015290517f213e4198000000000000000000000000000000000000000000000000000000008152600090737109709ecfa91a80626ff3989d68f67f5b1dd12d9063213e41989061043e908590600401610d65565b600060405180830381865afa15801561045b573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526104a19190810190610e35565b90506105176040518060400160405280600481526020017f6b65797300000000000000000000000000000000000000000000000000000000815250826000815181106104ef576104ef610f69565b60200260200101518360018151811061050a5761050a610f69565b6020026020010151610b72565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f66726f6d206f726967696e616c000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b15801561059457600080fd5b505afa1580156105a8573d6000803e3d6000fd5b50506040517f06447d5600000000000000000000000000000000000000000000000000000000815260426004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d92506306447d569150602401600060405180830381600087803b15801561061257600080fd5b505af1158015610626573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b20310000000000000000000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b1580156106a757600080fd5b505afa1580156106bb573d6000803e3d6000fd5b505050506106fe6040518060400160405280601781526020017f706172656e742073636f7065206d73672e73656e646572000000000000000000815250336109bf565b61073d6040518060400160405280601a81526020017f706172656e742073636f706520636f6e74726163742e61646472000000000000815250306109bf565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b203200000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b1580156107ba57600080fd5b505afa1580156107ce573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166390c5013b6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561083d57600080fd5b505af1158015610851573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f66726f6d206f726967696e616c20616761696e00000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b1580156108d257600080fd5b505afa1580156108e6573d6000803e3d6000fd5b505050506109286040518060400160405280600581526020017f646f6e652100000000000000000000000000000000000000000000000000000081525061092d565b505050565b6109bc816040516024016109419190610f98565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f41304fac00000000000000000000000000000000000000000000000000000000179052610c01565b50565b6100d682826040516024016109d5929190610fab565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f319af33300000000000000000000000000000000000000000000000000000000179052610c01565b6100d68282604051602401610a66929190610fe3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fc3b5563500000000000000000000000000000000000000000000000000000000179052610c01565b6100d68282604051602401610af7929190611007565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb60e72cc00000000000000000000000000000000000000000000000000000000179052610c01565b610928838383604051602401610b8a93929190611029565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f2ced7cef000000000000000000000000000000000000000000000000000000001790525b6109bc8180516a636f6e736f6c652e6c6f67602083016000808483855afa5050505050565b60008060208385031215610c3957600080fd5b823567ffffffffffffffff80821115610c5157600080fd5b818501915085601f830112610c6557600080fd5b813581811115610c7457600080fd5b866020828501011115610c8657600080fd5b60209290920196919550909350505050565b600060208284031215610caa57600080fd5b81518015158114610cba57600080fd5b9392505050565b600060208284031215610cd357600080fd5b815167ffffffffffffffff81168114610cba57600080fd5b60005b83811015610d06578181015183820152602001610cee565b83811115610d15576000848401525b50505050565b60008151808452610d33816020860160208601610ceb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b604081526000610d786040830184610d1b565b8281036020840152600c81527f2e726f6f745f6b65795b305d000000000000000000000000000000000000000060208201526040810191505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610e2d57610e2d610db7565b604052919050565b60006020808385031215610e4857600080fd5b825167ffffffffffffffff80821115610e6057600080fd5b8185019150601f8681840112610e7557600080fd5b825182811115610e8757610e87610db7565b8060051b610e96868201610de6565b918252848101860191868101908a841115610eb057600080fd5b87870192505b83831015610f5b57825186811115610ece5760008081fd5b8701603f81018c13610ee05760008081fd5b88810151604088821115610ef657610ef6610db7565b610f258b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08a85011601610de6565b8281528e82848601011115610f3a5760008081fd5b610f49838d8301848701610ceb565b85525050509187019190870190610eb6565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602081526000610cba6020830184610d1b565b604081526000610fbe6040830185610d1b565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b604081526000610ff66040830185610d1b565b905082151560208301529392505050565b60408152600061101a6040830185610d1b565b90508260208301529392505050565b60608152600061103c6060830186610d1b565b828103602084015261104e8186610d1b565b905082810360408401526110628185610d1b565b969550505050505056fea164736f6c634300080f000a","sourceMap":"2318:1449:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3622:143;;;;;;:::i;:::-;;:::i;:::-;;2578:949;;;:::i;3622:143::-;3681:15;3693:2;;3681:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3681:11:0;;-1:-1:-1;;;3681:15:0:i;:::-;3706:52;;;;;;;;;;;;;;;;;;3746:10;3706:11;:52::i;:::-;3622:143;;:::o;2578:949::-;2619:31;;;;;;;;;817:21:1;;;;874:2;854:18;;;847:30;913:14;893:18;;;886:42;2610:6:0;980:20:1;;;973:52;;;2610:6:0;2619:8;;;;945:19:1;;2619:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2610:40;;2660:37;;;;;;;;;;;;;;;;;;2695:1;2660:11;:37::i;:::-;2708:43;;;;;;;;;;;;;;;;;;2745:4;2708:11;:43::i;:::-;2761:57;;;;;;;;;;;;;;;;2791:26;;;;;2811:4;2791:26;;;1464:74:1;2761:57:0;;;2791:11;;;;1437:18:1;;2791:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2761:57;;:11;:57::i;:::-;2828:47;;;;;;;;;;;;;;;;;;2863:10;2828:11;:47::i;:::-;2885:61;;;;;;;;;;;;;;;;2913:32;;;;;2933:10;2913:32;;;1464:74:1;2885:61:0;;;2913:11;;;;1437:18:1;;2913:32:0;1318:226:1;2885:61:0;2957:55;;;;;;;;;;;;;;;;;3045:38;;;;;2957:18;;3045:16;;;;:38;;2957:55;;3045:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3022:61;;3093:37;;;;;;;;;;;;;;;;;;3113:4;3118:1;3113:7;;;;;;;;:::i;:::-;;;;;;;3122:4;3127:1;3122:7;;;;;;;;:::i;:::-;;;;;;;3093:11;:37::i;:::-;3141:27;;;;;5650:2:1;3141:27:0;;;5632:21:1;5689:2;5669:18;;;5662:30;5728:15;5708:18;;;5701:43;3141:4:0;;:10;;5761:18:1;;3141:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3178:37:0;;;;;3208:4;3178:37;;;1464:74:1;3178:13:0;;-1:-1:-1;3178:13:0;;-1:-1:-1;1437:18:1;;3178:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3225:26:0;;;;;5992:2:1;3225:26:0;;;5974:21:1;6031:2;6011:18;;;6004:30;6070:14;6050:18;;;6043:42;3225:4:0;;-1:-1:-1;3225:10:0;;-1:-1:-1;6102:18:1;;3225:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3261:59;;;;;;;;;;;;;;;;;;3308:10;3261:11;:59::i;:::-;3330:56;;;;;;;;;;;;;;;;;;3380:4;3330:11;:56::i;:::-;3396:26;;;;;6333:2:1;3396:26:0;;;6315:21:1;6372:2;6352:18;;;6345:30;6411:14;6391:18;;;6384:42;3396:4:0;;:10;;6443:18:1;;3396:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2411:28;2403:37;;3432:12;;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3456:33:0;;;;;6674:2:1;3456:33:0;;;6656:21:1;6713:2;6693:18;;;6686:30;6752:21;6732:18;;;6725:49;3456:4:0;;-1:-1:-1;3456:10:0;;-1:-1:-1;6791:18:1;;3456:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3500:20;;;;;;;;;;;;;;;;;;:11;:20::i;:::-;2600:927;;;2578:949::o;1435:121::-;1490:59;1545:2;1506:42;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1490:15;:59::i;:::-;1435:121;:::o;1858:145::-;1925:71;1988:2;1992;1941:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1925:15;:71::i;1562:139::-;1626:68;1686:2;1690;1642:51;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1626:15;:68::i;1707:145::-;1774:71;1837:2;1841;1790:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1774:15;:71::i;2009:179::-;2100:81;2169:2;2173;2177;2116:64;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;910:133;981:55;1028:7;1147:14;;633:42;1320:2;1307:16;;1123:21;;1147:14;1307:16;633:42;1356:5;1345:68;1336:77;;1273:150;;1049:380;:::o;14:592:1:-;85:6;93;146:2;134:9;125:7;121:23;117:32;114:52;;;162:1;159;152:12;114:52;202:9;189:23;231:18;272:2;264:6;261:14;258:34;;;288:1;285;278:12;258:34;326:6;315:9;311:22;301:32;;371:7;364:4;360:2;356:13;352:27;342:55;;393:1;390;383:12;342:55;433:2;420:16;459:2;451:6;448:14;445:34;;;475:1;472;465:12;445:34;520:7;515:2;506:6;502:2;498:15;494:24;491:37;488:57;;;541:1;538;531:12;488:57;572:2;564:11;;;;;594:6;;-1:-1:-1;14:592:1;;-1:-1:-1;;;;14:592:1:o;1036:277::-;1103:6;1156:2;1144:9;1135:7;1131:23;1127:32;1124:52;;;1172:1;1169;1162:12;1124:52;1204:9;1198:16;1257:5;1250:13;1243:21;1236:5;1233:32;1223:60;;1279:1;1276;1269:12;1223:60;1302:5;1036:277;-1:-1:-1;;;1036:277:1:o;1549:288::-;1618:6;1671:2;1659:9;1650:7;1646:23;1642:32;1639:52;;;1687:1;1684;1677:12;1639:52;1719:9;1713:16;1769:18;1762:5;1758:30;1751:5;1748:41;1738:69;;1803:1;1800;1793:12;1842:258;1914:1;1924:113;1938:6;1935:1;1932:13;1924:113;;;2014:11;;;2008:18;1995:11;;;1988:39;1960:2;1953:10;1924:113;;;2055:6;2052:1;2049:13;2046:48;;;2090:1;2081:6;2076:3;2072:16;2065:27;2046:48;;1842:258;;;:::o;2105:317::-;2147:3;2185:5;2179:12;2212:6;2207:3;2200:19;2228:63;2284:6;2277:4;2272:3;2268:14;2261:4;2254:5;2250:16;2228:63;:::i;:::-;2336:2;2324:15;2341:66;2320:88;2311:98;;;;2411:4;2307:109;;2105:317;-1:-1:-1;;2105:317:1:o;2427:493::-;2677:2;2666:9;2659:21;2640:4;2703:45;2744:2;2733:9;2729:18;2721:6;2703:45;:::i;:::-;2796:9;2788:6;2784:22;2779:2;2768:9;2764:18;2757:50;2831:2;2823:6;2816:18;2867:14;2862:2;2854:6;2850:15;2843:39;2911:2;2903:6;2899:15;2891:23;;;2427:493;;;;:::o;2925:184::-;2977:77;2974:1;2967:88;3074:4;3071:1;3064:15;3098:4;3095:1;3088:15;3114:334;3185:2;3179:9;3241:2;3231:13;;3246:66;3227:86;3215:99;;3344:18;3329:34;;3365:22;;;3326:62;3323:88;;;3391:18;;:::i;:::-;3427:2;3420:22;3114:334;;-1:-1:-1;3114:334:1:o;3453:1801::-;3558:6;3589:2;3632;3620:9;3611:7;3607:23;3603:32;3600:52;;;3648:1;3645;3638:12;3600:52;3681:9;3675:16;3710:18;3751:2;3743:6;3740:14;3737:34;;;3767:1;3764;3757:12;3737:34;3805:6;3794:9;3790:22;3780:32;;3831:4;3871:7;3866:2;3862;3858:11;3854:25;3844:53;;3893:1;3890;3883:12;3844:53;3922:2;3916:9;3944:2;3940;3937:10;3934:36;;;3950:18;;:::i;:::-;3996:2;3993:1;3989:10;4019:28;4043:2;4039;4035:11;4019:28;:::i;:::-;4081:15;;;4151:11;;;4147:20;;;4112:12;;;;4179:19;;;4176:39;;;4211:1;4208;4201:12;4176:39;4243:2;4239;4235:11;4224:22;;4255:969;4271:6;4266:3;4263:15;4255:969;;;4350:3;4344:10;4386:2;4373:11;4370:19;4367:109;;;4430:1;4459:2;4455;4448:14;4367:109;4499:20;;4554:2;4546:11;;4542:25;-1:-1:-1;4532:123:1;;4609:1;4638:2;4634;4627:14;4532:123;4693:2;4689;4685:11;4679:18;4721:2;4747;4742:3;4739:11;4736:37;;;4753:18;;:::i;:::-;4799:111;4906:2;4837:66;4832:2;4827:3;4823:12;4819:85;4815:94;4799:111;:::i;:::-;4937:3;4930:5;4923:18;4984:7;4978:3;4972;4968:2;4964:12;4960:22;4957:35;4954:128;;;5034:1;5064:3;5059;5052:16;4954:128;5095:56;5147:3;5142:2;5135:5;5131:14;5125:3;5121:2;5117:12;5095:56;:::i;:::-;5164:18;;-1:-1:-1;;;4288:12:1;;;;5202;;;;4255:969;;;5243:5;3453:1801;-1:-1:-1;;;;;;;;;;3453:1801:1:o;5259:184::-;5311:77;5308:1;5301:88;5408:4;5405:1;5398:15;5432:4;5429:1;5422:15;6820:220;6969:2;6958:9;6951:21;6932:4;6989:45;7030:2;7019:9;7015:18;7007:6;6989:45;:::i;7045:340::-;7222:2;7211:9;7204:21;7185:4;7242:45;7283:2;7272:9;7268:18;7260:6;7242:45;:::i;:::-;7234:53;;7335:42;7327:6;7323:55;7318:2;7307:9;7303:18;7296:83;7045:340;;;;;:::o;7390:301::-;7561:2;7550:9;7543:21;7524:4;7581:45;7622:2;7611:9;7607:18;7599:6;7581:45;:::i;:::-;7573:53;;7676:6;7669:14;7662:22;7657:2;7646:9;7642:18;7635:50;7390:301;;;;;:::o;7696:291::-;7873:2;7862:9;7855:21;7836:4;7893:45;7934:2;7923:9;7919:18;7911:6;7893:45;:::i;:::-;7885:53;;7974:6;7969:2;7958:9;7954:18;7947:34;7696:291;;;;;:::o;7992:546::-;8237:2;8226:9;8219:21;8200:4;8263:45;8304:2;8293:9;8289:18;8281:6;8263:45;:::i;:::-;8356:9;8348:6;8344:22;8339:2;8328:9;8324:18;8317:50;8390:33;8416:6;8408;8390:33;:::i;:::-;8376:47;;8471:9;8463:6;8459:22;8454:2;8443:9;8439:18;8432:50;8499:33;8525:6;8517;8499:33;:::i;:::-;8491:41;7992:546;-1:-1:-1;;;;;;7992:546:1:o","linkReferences":{}},"methodIdentifiers":{"hello(string)":"a777d0dc","run()":"c0406226"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"hello\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"run\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"title\":\"ScriptExample\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"hello(string)\":{\"notice\":\"example external function, to force a CALL, and test vm.startPrank with.\"},\"run()\":{\"notice\":\"example function, runs through basic cheat-codes and console logs.\"}},\"notice\":\"ScriptExample is an example script. The Go forge script code tests that it can run this.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"ScriptExample\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x531a2ad96c1a2c0bbfa9ab0e1195cd32551b0c10e16e7d256ce5e4c0289a8089\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://24dc6c71502c01f43fb5e113786e377c3b4cafabd5c506067d229fcdd7b037fa\",\"dweb:/ipfs/QmZ9AuxNx9Ygescfg5M4p6Abc2CCwCMZpX5xU32Fz1r4kY\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"view","type":"function","name":"hello"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"run"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{"hello(string)":{"notice":"example external function, to force a CALL, and test vm.startPrank with."},"run()":{"notice":"example function, runs through basic cheat-codes and console logs."}},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"ScriptExample"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x531a2ad96c1a2c0bbfa9ab0e1195cd32551b0c10e16e7d256ce5e4c0289a8089","urls":["bzz-raw://24dc6c71502c01f43fb5e113786e377c3b4cafabd5c506067d229fcdd7b037fa","dweb:/ipfs/QmZ9AuxNx9Ygescfg5M4p6Abc2CCwCMZpX5xU32Fz1r4kY"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[],"types":{}},"userdoc":{"version":1,"kind":"user","methods":{"hello(string)":{"notice":"example external function, to force a CALL, and test vm.startPrank with."},"run()":{"notice":"example function, runs through basic cheat-codes and console logs."}},"notice":"ScriptExample is an example script. The Go forge script code tests that it can run this."},"devdoc":{"version":1,"kind":"dev","title":"ScriptExample"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":383,"exportedSymbols":{"ScriptExample":[382],"Vm":[36],"console":[173]},"nodeType":"SourceUnit","src":"32:3736:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":36,"nodeType":"ContractDefinition","src":"120:393:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":36,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":36,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":36,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":36,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":36,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[36],"name":"Vm","nameLocation":"130:2:0","scope":383,"usedErrors":[]},{"id":173,"nodeType":"ContractDefinition","src":"568:1622:0","nodes":[{"id":42,"nodeType":"VariableDeclaration","src":"590:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"607:15:0","scope":173,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":37,"name":"address","nodeType":"ElementaryTypeName","src":"590:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":40,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"633:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":39,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"625:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":38,"name":"address","nodeType":"ElementaryTypeName","src":"625:7:0","typeDescriptions":{}}},"id":41,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"625:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":59,"nodeType":"FunctionDefinition","src":"683:221:0","nodes":[],"body":{"id":58,"nodeType":"Block","src":"842:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"861:37:0","statements":[{"nodeType":"YulAssignment","src":"875:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"884:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"875:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":48,"isOffset":false,"isSlot":false,"src":"884:4:0","valueSize":1},{"declaration":55,"isOffset":false,"isSlot":false,"src":"875:5:0","valueSize":1}],"id":57,"nodeType":"InlineAssembly","src":"852:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"692:25:0","parameters":{"id":49,"nodeType":"ParameterList","parameters":[{"constant":false,"id":48,"mutability":"mutable","name":"fnIn","nameLocation":"764:4:0","nodeType":"VariableDeclaration","scope":59,"src":"727:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":47,"nodeType":"FunctionTypeName","parameterTypes":{"id":45,"nodeType":"ParameterList","parameters":[{"constant":false,"id":44,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":47,"src":"736:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":43,"name":"bytes","nodeType":"ElementaryTypeName","src":"736:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"735:14:0"},"returnParameterTypes":{"id":46,"nodeType":"ParameterList","parameters":[],"src":"764:0:0"},"src":"727:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"717:57:0"},"returnParameters":{"id":56,"nodeType":"ParameterList","parameters":[{"constant":false,"id":55,"mutability":"mutable","name":"fnOut","nameLocation":"835:5:0","nodeType":"VariableDeclaration","scope":59,"src":"798:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":54,"nodeType":"FunctionTypeName","parameterTypes":{"id":52,"nodeType":"ParameterList","parameters":[{"constant":false,"id":51,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":54,"src":"807:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":50,"name":"bytes","nodeType":"ElementaryTypeName","src":"807:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"806:14:0"},"returnParameterTypes":{"id":53,"nodeType":"ParameterList","parameters":[],"src":"835:0:0"},"src":"798:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"797:44:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":71,"nodeType":"FunctionDefinition","src":"910:133:0","nodes":[],"body":{"id":70,"nodeType":"Block","src":"971:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":67,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":61,"src":"1028:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":65,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":87,"src":"1007:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":64,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":59,"src":"981:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":66,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"981:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":68,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"981:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":69,"nodeType":"ExpressionStatement","src":"981:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"919:15:0","parameters":{"id":62,"nodeType":"ParameterList","parameters":[{"constant":false,"id":61,"mutability":"mutable","name":"payload","nameLocation":"948:7:0","nodeType":"VariableDeclaration","scope":71,"src":"935:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":60,"name":"bytes","nodeType":"ElementaryTypeName","src":"935:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"934:22:0"},"returnParameters":{"id":63,"nodeType":"ParameterList","parameters":[],"src":"971:0:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":87,"nodeType":"FunctionDefinition","src":"1049:380:0","nodes":[],"body":{"id":86,"nodeType":"Block","src":"1113:316:0","nodes":[],"statements":[{"assignments":[77],"declarations":[{"constant":false,"id":77,"mutability":"mutable","name":"payloadLength","nameLocation":"1131:13:0","nodeType":"VariableDeclaration","scope":86,"src":"1123:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":76,"name":"uint256","nodeType":"ElementaryTypeName","src":"1123:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":80,"initialValue":{"expression":{"id":78,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":73,"src":"1147:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":79,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1147:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1123:38:0"},{"assignments":[82],"declarations":[{"constant":false,"id":82,"mutability":"mutable","name":"consoleAddress","nameLocation":"1179:14:0","nodeType":"VariableDeclaration","scope":86,"src":"1171:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":81,"name":"address","nodeType":"ElementaryTypeName","src":"1171:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":84,"initialValue":{"id":83,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":42,"src":"1196:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1171:40:0"},{"AST":{"nodeType":"YulBlock","src":"1273:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1287:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1311:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1320:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1307:3:0"},"nodeType":"YulFunctionCall","src":"1307:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1291:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1336:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1356:3:0"},"nodeType":"YulFunctionCall","src":"1356:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1363:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1379:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1393:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1408:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1411:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1345:10:0"},"nodeType":"YulFunctionCall","src":"1345:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1340:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":82,"isOffset":false,"isSlot":false,"src":"1363:14:0","valueSize":1},{"declaration":73,"isOffset":false,"isSlot":false,"src":"1311:7:0","valueSize":1},{"declaration":77,"isOffset":false,"isSlot":false,"src":"1393:13:0","valueSize":1}],"id":85,"nodeType":"InlineAssembly","src":"1264:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1058:19:0","parameters":{"id":74,"nodeType":"ParameterList","parameters":[{"constant":false,"id":73,"mutability":"mutable","name":"payload","nameLocation":"1091:7:0","nodeType":"VariableDeclaration","scope":87,"src":"1078:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":72,"name":"bytes","nodeType":"ElementaryTypeName","src":"1078:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1077:22:0"},"returnParameters":{"id":75,"nodeType":"ParameterList","parameters":[],"src":"1113:0:0"},"scope":173,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":101,"nodeType":"FunctionDefinition","src":"1435:121:0","nodes":[],"body":{"id":100,"nodeType":"Block","src":"1480:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":95,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1530:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":96,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":89,"src":"1545:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":93,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1506:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":94,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1506:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":97,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1506:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":92,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":71,"src":"1490:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":98,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1490:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":99,"nodeType":"ExpressionStatement","src":"1490:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1444:3:0","parameters":{"id":90,"nodeType":"ParameterList","parameters":[{"constant":false,"id":89,"mutability":"mutable","name":"p0","nameLocation":"1462:2:0","nodeType":"VariableDeclaration","scope":101,"src":"1448:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":88,"name":"string","nodeType":"ElementaryTypeName","src":"1448:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1447:18:0"},"returnParameters":{"id":91,"nodeType":"ParameterList","parameters":[],"src":"1480:0:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":118,"nodeType":"FunctionDefinition","src":"1562:139:0","nodes":[],"body":{"id":117,"nodeType":"Block","src":"1616:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":111,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1666:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":112,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":103,"src":"1686:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":113,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":105,"src":"1690:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":109,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1642:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":110,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1642:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":114,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1642:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":108,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":71,"src":"1626:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":115,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1626:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":116,"nodeType":"ExpressionStatement","src":"1626:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1571:3:0","parameters":{"id":106,"nodeType":"ParameterList","parameters":[{"constant":false,"id":103,"mutability":"mutable","name":"p0","nameLocation":"1589:2:0","nodeType":"VariableDeclaration","scope":118,"src":"1575:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":102,"name":"string","nodeType":"ElementaryTypeName","src":"1575:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":105,"mutability":"mutable","name":"p1","nameLocation":"1598:2:0","nodeType":"VariableDeclaration","scope":118,"src":"1593:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":104,"name":"bool","nodeType":"ElementaryTypeName","src":"1593:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1574:27:0"},"returnParameters":{"id":107,"nodeType":"ParameterList","parameters":[],"src":"1616:0:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":135,"nodeType":"FunctionDefinition","src":"1707:145:0","nodes":[],"body":{"id":134,"nodeType":"Block","src":"1764:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":128,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1814:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":129,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":120,"src":"1837:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":130,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":122,"src":"1841:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":126,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1790:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":127,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1790:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":131,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1790:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":125,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":71,"src":"1774:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":132,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1774:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":133,"nodeType":"ExpressionStatement","src":"1774:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1716:3:0","parameters":{"id":123,"nodeType":"ParameterList","parameters":[{"constant":false,"id":120,"mutability":"mutable","name":"p0","nameLocation":"1734:2:0","nodeType":"VariableDeclaration","scope":135,"src":"1720:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":119,"name":"string","nodeType":"ElementaryTypeName","src":"1720:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":122,"mutability":"mutable","name":"p1","nameLocation":"1746:2:0","nodeType":"VariableDeclaration","scope":135,"src":"1738:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":121,"name":"uint256","nodeType":"ElementaryTypeName","src":"1738:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1719:30:0"},"returnParameters":{"id":124,"nodeType":"ParameterList","parameters":[],"src":"1764:0:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":152,"nodeType":"FunctionDefinition","src":"1858:145:0","nodes":[],"body":{"id":151,"nodeType":"Block","src":"1915:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":145,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1965:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":146,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":137,"src":"1988:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":147,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":139,"src":"1992:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":143,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1941:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":144,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1941:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":148,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1941:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":142,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":71,"src":"1925:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":149,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1925:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":150,"nodeType":"ExpressionStatement","src":"1925:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1867:3:0","parameters":{"id":140,"nodeType":"ParameterList","parameters":[{"constant":false,"id":137,"mutability":"mutable","name":"p0","nameLocation":"1885:2:0","nodeType":"VariableDeclaration","scope":152,"src":"1871:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":136,"name":"string","nodeType":"ElementaryTypeName","src":"1871:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":139,"mutability":"mutable","name":"p1","nameLocation":"1897:2:0","nodeType":"VariableDeclaration","scope":152,"src":"1889:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":138,"name":"address","nodeType":"ElementaryTypeName","src":"1889:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1870:30:0"},"returnParameters":{"id":141,"nodeType":"ParameterList","parameters":[],"src":"1915:0:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":172,"nodeType":"FunctionDefinition","src":"2009:179:0","nodes":[],"body":{"id":171,"nodeType":"Block","src":"2090:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":164,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2140:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":165,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":154,"src":"2169:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":166,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":156,"src":"2173:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":167,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":158,"src":"2177:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":162,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2116:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":163,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2116:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":168,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2116:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":161,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":71,"src":"2100:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":169,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2100:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":170,"nodeType":"ExpressionStatement","src":"2100:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2018:3:0","parameters":{"id":159,"nodeType":"ParameterList","parameters":[{"constant":false,"id":154,"mutability":"mutable","name":"p0","nameLocation":"2036:2:0","nodeType":"VariableDeclaration","scope":172,"src":"2022:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":153,"name":"string","nodeType":"ElementaryTypeName","src":"2022:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":156,"mutability":"mutable","name":"p1","nameLocation":"2054:2:0","nodeType":"VariableDeclaration","scope":172,"src":"2040:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":155,"name":"string","nodeType":"ElementaryTypeName","src":"2040:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":158,"mutability":"mutable","name":"p2","nameLocation":"2072:2:0","nodeType":"VariableDeclaration","scope":172,"src":"2058:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":157,"name":"string","nodeType":"ElementaryTypeName","src":"2058:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2021:54:0"},"returnParameters":{"id":160,"nodeType":"ParameterList","parameters":[],"src":"2090:0:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[173],"name":"console","nameLocation":"576:7:0","scope":383,"usedErrors":[]},{"id":382,"nodeType":"ContractDefinition","src":"2318:1449:0","nodes":[{"id":188,"nodeType":"VariableDeclaration","src":"2348:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2374:10:0","scope":382,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":175,"name":"address","nodeType":"ElementaryTypeName","src":"2348:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":183,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2421:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":182,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2411:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":184,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2411:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":181,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2403:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":180,"name":"uint256","nodeType":"ElementaryTypeName","src":"2403:7:0","typeDescriptions":{}}},"id":185,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2403:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":179,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2395:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":178,"name":"uint160","nodeType":"ElementaryTypeName","src":"2395:7:0","typeDescriptions":{}}},"id":186,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2395:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":177,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2387:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":176,"name":"address","nodeType":"ElementaryTypeName","src":"2387:7:0","typeDescriptions":{}}},"id":187,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2387:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":194,"nodeType":"VariableDeclaration","src":"2448:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2469:2:0","scope":382,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"},"typeName":{"id":190,"nodeType":"UserDefinedTypeName","pathNode":{"id":189,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":36,"src":"2448:2:0"},"referencedDeclaration":36,"src":"2448:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"value":{"arguments":[{"id":192,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":188,"src":"2477:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":191,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":36,"src":"2474:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$36_$","typeString":"type(contract Vm)"}},"id":193,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2474:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"visibility":"internal"},{"id":357,"nodeType":"FunctionDefinition","src":"2578:949:0","nodes":[],"body":{"id":356,"nodeType":"Block","src":"2600:927:0","nodes":[],"statements":[{"assignments":[199],"declarations":[{"constant":false,"id":199,"mutability":"mutable","name":"x","nameLocation":"2615:1:0","nodeType":"VariableDeclaration","scope":356,"src":"2610:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":198,"name":"bool","nodeType":"ElementaryTypeName","src":"2610:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":205,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2628:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":203,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2644:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":200,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":194,"src":"2619:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"id":201,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2619:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":204,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2619:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2610:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":209,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2672:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":210,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":199,"src":"2695:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":206,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2660:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":208,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":118,"src":"2660:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":211,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2660:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":212,"nodeType":"ExpressionStatement","src":"2660:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":216,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2720:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":219,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"2745:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}],"id":218,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2737:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":217,"name":"address","nodeType":"ElementaryTypeName","src":"2737:7:0","typeDescriptions":{}}},"id":220,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2737:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":213,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2708:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":215,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":152,"src":"2708:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":221,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2708:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":222,"nodeType":"ExpressionStatement","src":"2708:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":226,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2773:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":231,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"2811:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}],"id":230,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2803:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":229,"name":"address","nodeType":"ElementaryTypeName","src":"2803:7:0","typeDescriptions":{}}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2803:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":227,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":194,"src":"2791:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"id":228,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"2791:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":233,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2791:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":223,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2761:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":225,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":135,"src":"2761:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":234,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2761:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":235,"nodeType":"ExpressionStatement","src":"2761:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":239,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2840:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":242,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"2863:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":243,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"2863:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":241,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2855:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":240,"name":"address","nodeType":"ElementaryTypeName","src":"2855:7:0","typeDescriptions":{}}},"id":244,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2855:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":236,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2828:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":238,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":152,"src":"2828:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":245,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2828:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":246,"nodeType":"ExpressionStatement","src":"2828:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":250,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2897:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":255,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"2933:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":256,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"2933:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":254,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2925:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":253,"name":"address","nodeType":"ElementaryTypeName","src":"2925:7:0","typeDescriptions":{}}},"id":257,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2925:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":251,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":194,"src":"2913:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"id":252,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"2913:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":258,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2913:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":247,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2885:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":135,"src":"2885:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":259,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2885:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":260,"nodeType":"ExpressionStatement","src":"2885:61:0"},{"assignments":[262],"declarations":[{"constant":false,"id":262,"mutability":"mutable","name":"json","nameLocation":"2971:4:0","nodeType":"VariableDeclaration","scope":356,"src":"2957:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":261,"name":"string","nodeType":"ElementaryTypeName","src":"2957:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":264,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":263,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2978:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"2957:55:0"},{"assignments":[269],"declarations":[{"constant":false,"id":269,"mutability":"mutable","name":"keys","nameLocation":"3038:4:0","nodeType":"VariableDeclaration","scope":356,"src":"3022:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":267,"name":"string","nodeType":"ElementaryTypeName","src":"3022:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":268,"nodeType":"ArrayTypeName","src":"3022:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":275,"initialValue":{"arguments":[{"id":272,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":262,"src":"3062:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":273,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3068:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":270,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":194,"src":"3045:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"id":271,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3045:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":274,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3045:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3022:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":279,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3105:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":280,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":269,"src":"3113:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":282,"indexExpression":{"hexValue":"30","id":281,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3118:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3113:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":283,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":269,"src":"3122:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":285,"indexExpression":{"hexValue":"31","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3127:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3122:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":276,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"3093:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":278,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":172,"src":"3093:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":286,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3093:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":287,"nodeType":"ExpressionStatement","src":"3093:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":291,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3152:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":288,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3141:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}},"id":290,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":381,"src":"3141:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":292,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3141:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":293,"nodeType":"ExpressionStatement","src":"3141:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":301,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3208:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":300,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3200:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":299,"name":"uint160","nodeType":"ElementaryTypeName","src":"3200:7:0","typeDescriptions":{}}},"id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3200:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":298,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3192:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":297,"name":"address","nodeType":"ElementaryTypeName","src":"3192:7:0","typeDescriptions":{}}},"id":303,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3192:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":294,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":194,"src":"3178:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"id":296,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3178:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":304,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3178:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":305,"nodeType":"ExpressionStatement","src":"3178:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":309,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3236:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":306,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3225:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}},"id":308,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":381,"src":"3225:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":310,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3225:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":311,"nodeType":"ExpressionStatement","src":"3225:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":315,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3273:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":318,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3308:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":319,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3308:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":317,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3300:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":316,"name":"address","nodeType":"ElementaryTypeName","src":"3300:7:0","typeDescriptions":{}}},"id":320,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3300:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":312,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"3261:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":314,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":152,"src":"3261:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":321,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3261:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":322,"nodeType":"ExpressionStatement","src":"3261:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":326,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3342:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":329,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3380:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}],"id":328,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3372:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":327,"name":"address","nodeType":"ElementaryTypeName","src":"3372:7:0","typeDescriptions":{}}},"id":330,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3372:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":323,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"3330:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":152,"src":"3330:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3330:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":332,"nodeType":"ExpressionStatement","src":"3330:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":336,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3407:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":333,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3396:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}},"id":335,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":381,"src":"3396:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":337,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3396:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":338,"nodeType":"ExpressionStatement","src":"3396:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":339,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":194,"src":"3432:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3432:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3432:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3432:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3467:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":344,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3456:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":381,"src":"3456:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":348,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3456:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":349,"nodeType":"ExpressionStatement","src":"3456:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":353,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3512:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":350,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"3500:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":101,"src":"3500:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":354,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3500:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":355,"nodeType":"ExpressionStatement","src":"3500:20:0"}]},"documentation":{"id":195,"nodeType":"StructuredDocumentation","src":"2495:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2587:3:0","parameters":{"id":196,"nodeType":"ParameterList","parameters":[],"src":"2590:2:0"},"returnParameters":{"id":197,"nodeType":"ParameterList","parameters":[],"src":"2600:0:0"},"scope":382,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":381,"nodeType":"FunctionDefinition","src":"3622:143:0","nodes":[],"body":{"id":380,"nodeType":"Block","src":"3671:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":366,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":360,"src":"3693:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":363,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"3681:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":365,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":101,"src":"3681:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":367,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3681:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":368,"nodeType":"ExpressionStatement","src":"3681:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":372,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3718:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":375,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3746:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":376,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3746:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":374,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3738:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":373,"name":"address","nodeType":"ElementaryTypeName","src":"3738:7:0","typeDescriptions":{}}},"id":377,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3738:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":369,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"3706:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":371,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":152,"src":"3706:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":378,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3706:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":379,"nodeType":"ExpressionStatement","src":"3706:52:0"}]},"documentation":{"id":358,"nodeType":"StructuredDocumentation","src":"3533:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"3631:5:0","parameters":{"id":361,"nodeType":"ParameterList","parameters":[{"constant":false,"id":360,"mutability":"mutable","name":"_v","nameLocation":"3653:2:0","nodeType":"VariableDeclaration","scope":381,"src":"3637:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":359,"name":"string","nodeType":"ElementaryTypeName","src":"3637:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"3636:20:0"},"returnParameters":{"id":362,"nodeType":"ParameterList","parameters":[],"src":"3671:0:0"},"scope":382,"stateMutability":"view","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[],"contractKind":"contract","documentation":{"id":174,"nodeType":"StructuredDocumentation","src":"2192:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[382],"name":"ScriptExample","nameLocation":"2327:13:0","scope":383,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file +{"abi":[{"type":"function","name":"call1","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"call2","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"counter","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"hello","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"view"},{"type":"function","name":"nested1","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"nested2","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"run","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"runBroadcast","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"bytecode":{"object":"0x608060405234801561001057600080fd5b5061196c806100206000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063a777d0dc1161005b578063a777d0dc146100d0578063bef03abc146100e3578063c0406226146100eb578063dbf1282f146100a857600080fd5b806361bc221a1461008d5780637e79255d146100a85780638d3ef7ca146100a8578063a76ccdfa146100bd575b600080fd5b61009660005481565b60405190815260200160405180910390f35b6100bb6100b6366004611471565b6100f3565b005b6100bb6100cb366004611471565b61014a565b6100bb6100de366004611471565b6101d2565b6100bb610250565b6100bb610925565b600080549080610102836114e3565b919050555061014682828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061117892505050565b5050565b600080549080610159836114e3565b90915550506040517fdbf1282f000000000000000000000000000000000000000000000000000000008152309063dbf1282f9061019c9085908590600401611542565b600060405180830381600087803b1580156101b657600080fd5b505af11580156101ca573d6000803e3d6000fd5b505050505050565b61021182828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061117892505050565b6101466040518060400160405280601081526020017f68656c6c6f206d73672e73656e646572000000000000000000000000000000008152503361120a565b61028e6040518060400160405280600e81526020017f74657374696e672073696e676c65000000000000000000000000000000000000815250611178565b7f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff1663afc980406040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156102f957600080fd5b505af115801561030d573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f73696e676c655f63616c6c3100000000000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b15801561039057600080fd5b505af11580156103a4573d6000803e3d6000fd5b50506040517f8d3ef7ca00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f73696e676c655f63616c6c3200000000000000000000000000000000000000006044820152309250638d3ef7ca9150606401600060405180830381600087803b15801561042757600080fd5b505af115801561043b573d6000803e3d6000fd5b5050505061047d6040518060400160405280601281526020017f74657374696e672073746172742f73746f700000000000000000000000000000815250611178565b7f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff16637fb5297f6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156104e857600080fd5b505af11580156104fc573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3100000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b15801561057f57600080fd5b505af1158015610593573d6000803e3d6000fd5b50506040517f8d3ef7ca00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3200000000000000000000000000000000006044820152309250638d3ef7ca9150606401600060405180830381600087803b15801561061657600080fd5b505af115801561062a573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166376eadd366040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561069957600080fd5b505af11580156106ad573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3300000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b15801561073057600080fd5b505af1158015610744573d6000803e3d6000fd5b505050506107866040518060400160405280600e81526020017f74657374696e67206e6573746564000000000000000000000000000000000000815250611178565b7f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff16637fb5297f6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156107f157600080fd5b505af1158015610805573d6000803e3d6000fd5b50506040517fa76ccdfa00000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f6e65737465640000000000000000000000000000000000000000000000000000604482015230925063a76ccdfa9150606401600060405180830381600087803b15801561088857600080fd5b505af115801561089c573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166376eadd366040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561090b57600080fd5b505af115801561091f573d6000803e3d6000fd5b50505050565b604080517f4777f3cf0000000000000000000000000000000000000000000000000000000081526004810191909152600c60448201527f4558414d504c455f424f4f4c0000000000000000000000000000000000000000606482015260006024820181905290737109709ecfa91a80626ff3989d68f67f5b1dd12d90634777f3cf90608401602060405180830381865afa1580156109c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109eb919061158f565b9050610a2c6040518060400160405280601381526020017f626f6f6c2076616c75652066726f6d20656e76000000000000000000000000008152508261129b565b610a6b6040518060400160405280600d81526020017f636f6e74726163742061646472000000000000000000000000000000000000008152503061120a565b604080518082018252600e81527f636f6e7472616374206e6f6e6365000000000000000000000000000000000000602082015290517f2d0335ab000000000000000000000000000000000000000000000000000000008152306004820152610b3e9190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab906024015b602060405180830381865afa158015610b0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2f91906115b8565b67ffffffffffffffff1661132c565b610b7d6040518060400160405280600b81526020017f73656e64657220616464720000000000000000000000000000000000000000008152503361120a565b604080518082018252600c81527f73656e646572206e6f6e63650000000000000000000000000000000000000000602082015290517f2d0335ab000000000000000000000000000000000000000000000000000000008152336004820152610c049190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab90602401610aee565b60408051808201825260208082527f7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d9082015290517f213e4198000000000000000000000000000000000000000000000000000000008152600090737109709ecfa91a80626ff3989d68f67f5b1dd12d9063213e419890610c89908590600401611658565b600060405180830381865afa158015610ca6573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610cec9190810190611728565b9050610d626040518060400160405280600481526020017f6b6579730000000000000000000000000000000000000000000000000000000081525082600081518110610d3a57610d3a61185c565b602002602001015183600181518110610d5557610d5561185c565b60200260200101516113bd565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f66726f6d206f726967696e616c000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b158015610ddf57600080fd5b505afa158015610df3573d6000803e3d6000fd5b50506040517f06447d5600000000000000000000000000000000000000000000000000000000815260426004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d92506306447d569150602401600060405180830381600087803b158015610e5d57600080fd5b505af1158015610e71573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b20310000000000000000000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b158015610ef257600080fd5b505afa158015610f06573d6000803e3d6000fd5b50505050610f496040518060400160405280601781526020017f706172656e742073636f7065206d73672e73656e6465720000000000000000008152503361120a565b610f886040518060400160405280601a81526020017f706172656e742073636f706520636f6e74726163742e616464720000000000008152503061120a565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b203200000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b15801561100557600080fd5b505afa158015611019573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166390c5013b6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561108857600080fd5b505af115801561109c573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f66726f6d206f726967696e616c20616761696e00000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b15801561111d57600080fd5b505afa158015611131573d6000803e3d6000fd5b505050506111736040518060400160405280600581526020017f646f6e6521000000000000000000000000000000000000000000000000000000815250611178565b505050565b6112078160405160240161118c919061188b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f41304fac0000000000000000000000000000000000000000000000000000000017905261144c565b50565b610146828260405160240161122092919061189e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f319af3330000000000000000000000000000000000000000000000000000000017905261144c565b61014682826040516024016112b19291906118d6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fc3b556350000000000000000000000000000000000000000000000000000000017905261144c565b61014682826040516024016113429291906118fa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb60e72cc0000000000000000000000000000000000000000000000000000000017905261144c565b6111738383836040516024016113d59392919061191c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f2ced7cef000000000000000000000000000000000000000000000000000000001790525b6112078180516a636f6e736f6c652e6c6f67602083016000808483855afa5050505050565b6000806020838503121561148457600080fd5b823567ffffffffffffffff8082111561149c57600080fd5b818501915085601f8301126114b057600080fd5b8135818111156114bf57600080fd5b8660208285010111156114d157600080fd5b60209290920196919550909350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361153b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000602082840312156115a157600080fd5b815180151581146115b157600080fd5b9392505050565b6000602082840312156115ca57600080fd5b815167ffffffffffffffff811681146115b157600080fd5b60005b838110156115fd5781810151838201526020016115e5565b8381111561091f5750506000910152565b600081518084526116268160208601602086016115e2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60408152600061166b604083018461160e565b8281036020840152600c81527f2e726f6f745f6b65795b305d000000000000000000000000000000000000000060208201526040810191505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611720576117206116aa565b604052919050565b6000602080838503121561173b57600080fd5b825167ffffffffffffffff8082111561175357600080fd5b8185019150601f868184011261176857600080fd5b82518281111561177a5761177a6116aa565b8060051b6117898682016116d9565b918252848101860191868101908a8411156117a357600080fd5b87870192505b8383101561184e578251868111156117c15760008081fd5b8701603f81018c136117d35760008081fd5b888101516040888211156117e9576117e96116aa565b6118188b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08a850116016116d9565b8281528e8284860101111561182d5760008081fd5b61183c838d83018487016115e2565b855250505091870191908701906117a9565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020815260006115b1602083018461160e565b6040815260006118b1604083018561160e565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b6040815260006118e9604083018561160e565b905082151560208301529392505050565b60408152600061190d604083018561160e565b90508260208301529392505050565b60608152600061192f606083018661160e565b8281036020840152611941818661160e565b90508281036040840152611955818561160e565b969550505050505056fea164736f6c634300080f000a","sourceMap":"2432:2531:0:-:0;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063a777d0dc1161005b578063a777d0dc146100d0578063bef03abc146100e3578063c0406226146100eb578063dbf1282f146100a857600080fd5b806361bc221a1461008d5780637e79255d146100a85780638d3ef7ca146100a8578063a76ccdfa146100bd575b600080fd5b61009660005481565b60405190815260200160405180910390f35b6100bb6100b6366004611471565b6100f3565b005b6100bb6100cb366004611471565b61014a565b6100bb6100de366004611471565b6101d2565b6100bb610250565b6100bb610925565b600080549080610102836114e3565b919050555061014682828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061117892505050565b5050565b600080549080610159836114e3565b90915550506040517fdbf1282f000000000000000000000000000000000000000000000000000000008152309063dbf1282f9061019c9085908590600401611542565b600060405180830381600087803b1580156101b657600080fd5b505af11580156101ca573d6000803e3d6000fd5b505050505050565b61021182828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061117892505050565b6101466040518060400160405280601081526020017f68656c6c6f206d73672e73656e646572000000000000000000000000000000008152503361120a565b61028e6040518060400160405280600e81526020017f74657374696e672073696e676c65000000000000000000000000000000000000815250611178565b7f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff1663afc980406040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156102f957600080fd5b505af115801561030d573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f73696e676c655f63616c6c3100000000000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b15801561039057600080fd5b505af11580156103a4573d6000803e3d6000fd5b50506040517f8d3ef7ca00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f73696e676c655f63616c6c3200000000000000000000000000000000000000006044820152309250638d3ef7ca9150606401600060405180830381600087803b15801561042757600080fd5b505af115801561043b573d6000803e3d6000fd5b5050505061047d6040518060400160405280601281526020017f74657374696e672073746172742f73746f700000000000000000000000000000815250611178565b7f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff16637fb5297f6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156104e857600080fd5b505af11580156104fc573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3100000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b15801561057f57600080fd5b505af1158015610593573d6000803e3d6000fd5b50506040517f8d3ef7ca00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3200000000000000000000000000000000006044820152309250638d3ef7ca9150606401600060405180830381600087803b15801561061657600080fd5b505af115801561062a573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166376eadd366040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561069957600080fd5b505af11580156106ad573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3300000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b15801561073057600080fd5b505af1158015610744573d6000803e3d6000fd5b505050506107866040518060400160405280600e81526020017f74657374696e67206e6573746564000000000000000000000000000000000000815250611178565b7f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff16637fb5297f6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156107f157600080fd5b505af1158015610805573d6000803e3d6000fd5b50506040517fa76ccdfa00000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f6e65737465640000000000000000000000000000000000000000000000000000604482015230925063a76ccdfa9150606401600060405180830381600087803b15801561088857600080fd5b505af115801561089c573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166376eadd366040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561090b57600080fd5b505af115801561091f573d6000803e3d6000fd5b50505050565b604080517f4777f3cf0000000000000000000000000000000000000000000000000000000081526004810191909152600c60448201527f4558414d504c455f424f4f4c0000000000000000000000000000000000000000606482015260006024820181905290737109709ecfa91a80626ff3989d68f67f5b1dd12d90634777f3cf90608401602060405180830381865afa1580156109c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109eb919061158f565b9050610a2c6040518060400160405280601381526020017f626f6f6c2076616c75652066726f6d20656e76000000000000000000000000008152508261129b565b610a6b6040518060400160405280600d81526020017f636f6e74726163742061646472000000000000000000000000000000000000008152503061120a565b604080518082018252600e81527f636f6e7472616374206e6f6e6365000000000000000000000000000000000000602082015290517f2d0335ab000000000000000000000000000000000000000000000000000000008152306004820152610b3e9190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab906024015b602060405180830381865afa158015610b0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2f91906115b8565b67ffffffffffffffff1661132c565b610b7d6040518060400160405280600b81526020017f73656e64657220616464720000000000000000000000000000000000000000008152503361120a565b604080518082018252600c81527f73656e646572206e6f6e63650000000000000000000000000000000000000000602082015290517f2d0335ab000000000000000000000000000000000000000000000000000000008152336004820152610c049190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab90602401610aee565b60408051808201825260208082527f7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d9082015290517f213e4198000000000000000000000000000000000000000000000000000000008152600090737109709ecfa91a80626ff3989d68f67f5b1dd12d9063213e419890610c89908590600401611658565b600060405180830381865afa158015610ca6573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610cec9190810190611728565b9050610d626040518060400160405280600481526020017f6b6579730000000000000000000000000000000000000000000000000000000081525082600081518110610d3a57610d3a61185c565b602002602001015183600181518110610d5557610d5561185c565b60200260200101516113bd565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f66726f6d206f726967696e616c000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b158015610ddf57600080fd5b505afa158015610df3573d6000803e3d6000fd5b50506040517f06447d5600000000000000000000000000000000000000000000000000000000815260426004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d92506306447d569150602401600060405180830381600087803b158015610e5d57600080fd5b505af1158015610e71573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b20310000000000000000000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b158015610ef257600080fd5b505afa158015610f06573d6000803e3d6000fd5b50505050610f496040518060400160405280601781526020017f706172656e742073636f7065206d73672e73656e6465720000000000000000008152503361120a565b610f886040518060400160405280601a81526020017f706172656e742073636f706520636f6e74726163742e616464720000000000008152503061120a565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b203200000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b15801561100557600080fd5b505afa158015611019573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166390c5013b6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561108857600080fd5b505af115801561109c573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f66726f6d206f726967696e616c20616761696e00000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b15801561111d57600080fd5b505afa158015611131573d6000803e3d6000fd5b505050506111736040518060400160405280600581526020017f646f6e6521000000000000000000000000000000000000000000000000000000815250611178565b505050565b6112078160405160240161118c919061188b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f41304fac0000000000000000000000000000000000000000000000000000000017905261144c565b50565b610146828260405160240161122092919061189e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f319af3330000000000000000000000000000000000000000000000000000000017905261144c565b61014682826040516024016112b19291906118d6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fc3b556350000000000000000000000000000000000000000000000000000000017905261144c565b61014682826040516024016113429291906118fa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb60e72cc0000000000000000000000000000000000000000000000000000000017905261144c565b6111738383836040516024016113d59392919061191c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f2ced7cef000000000000000000000000000000000000000000000000000000001790525b6112078180516a636f6e736f6c652e6c6f67602083016000808483855afa5050505050565b6000806020838503121561148457600080fd5b823567ffffffffffffffff8082111561149c57600080fd5b818501915085601f8301126114b057600080fd5b8135818111156114bf57600080fd5b8660208285010111156114d157600080fd5b60209290920196919550909350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361153b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000602082840312156115a157600080fd5b815180151581146115b157600080fd5b9392505050565b6000602082840312156115ca57600080fd5b815167ffffffffffffffff811681146115b157600080fd5b60005b838110156115fd5781810151838201526020016115e5565b8381111561091f5750506000910152565b600081518084526116268160208601602086016115e2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60408152600061166b604083018461160e565b8281036020840152600c81527f2e726f6f745f6b65795b305d000000000000000000000000000000000000000060208201526040810191505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611720576117206116aa565b604052919050565b6000602080838503121561173b57600080fd5b825167ffffffffffffffff8082111561175357600080fd5b8185019150601f868184011261176857600080fd5b82518281111561177a5761177a6116aa565b8060051b6117898682016116d9565b918252848101860191868101908a8411156117a357600080fd5b87870192505b8383101561184e578251868111156117c15760008081fd5b8701603f81018c136117d35760008081fd5b888101516040888211156117e9576117e96116aa565b6118188b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08a850116016116d9565b8281528e8284860101111561182d5760008081fd5b61183c838d83018487016115e2565b855250505091870191908701906117a9565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020815260006115b1602083018461160e565b6040815260006118b1604083018561160e565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b6040815260006118e9604083018561160e565b905082151560208301529392505050565b60408152600061190d604083018561160e565b90508260208301529392505050565b60608152600061192f606083018661160e565b8281036020840152611941818661160e565b90508281036040840152611955818561160e565b969550505050505056fea164736f6c634300080f000a","sourceMap":"2432:2531:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2666:22;;;;;;;;;160:25:1;;;148:2;133:18;2666:22:0;;;;;;;4558:95;;;;;;:::i;:::-;;:::i;:::-;;4760:98;;;;;;:::i;:::-;;:::i;4409:143::-;;;;;;:::i;:::-;;:::i;3794:520::-;;;:::i;2778:949::-;;;:::i;4558:95::-;4612:7;:9;;;:7;:9;;;:::i;:::-;;;;;;4631:15;4643:2;;4631:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4631:11:0;;-1:-1:-1;;;4631:15:0:i;:::-;4558:95;;:::o;4760:98::-;4816:7;:9;;;:7;:9;;;:::i;:::-;;;;-1:-1:-1;;4835:16:0;;;;;:4;;:12;;:16;;4848:2;;;;4835:16;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4760:98;;:::o;4409:143::-;4468:15;4480:2;;4468:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4468:11:0;;-1:-1:-1;;;4468:15:0:i;:::-;4493:52;;;;;;;;;;;;;;;;;;4533:10;4493:11;:52::i;3794:520::-;3835:29;;;;;;;;;;;;;;;;;;:11;:29::i;:::-;2525:28;2517:37;;3874:12;;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3898:26:0;;;;;1803:2:1;3898:26:0;;;1785:21:1;1842:2;1822:18;;;1815:30;1881:14;1861:18;;;1854:42;3898:4:0;;-1:-1:-1;3898:10:0;;-1:-1:-1;1913:18:1;;3898:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3934:26:0;;;;;2144:2:1;3934:26:0;;;2126:21:1;2183:2;2163:18;;;2156:30;2222:14;2202:18;;;2195:42;3934:4:0;;-1:-1:-1;3934:10:0;;-1:-1:-1;2254:18:1;;3934:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3971:33;;;;;;;;;;;;;;;;;;:11;:33::i;:::-;2525:28;2517:37;;4014:17;;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4043:29:0;;;;;2485:2:1;4043:29:0;;;2467:21:1;2524:2;2504:18;;;2497:30;2563:17;2543:18;;;2536:45;4043:4:0;;-1:-1:-1;4043:10:0;;-1:-1:-1;2598:18:1;;4043:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4082:29:0;;;;;2829:2:1;4082:29:0;;;2811:21:1;2868:2;2848:18;;;2841:30;2907:17;2887:18;;;2880:45;4082:4:0;;-1:-1:-1;4082:10:0;;-1:-1:-1;2942:18:1;;4082:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2525:28;2517:37;;4121:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4149:29:0;;;;;3173:2:1;4149:29:0;;;3155:21:1;3212:2;3192:18;;;3185:30;3251:17;3231:18;;;3224:45;4149:4:0;;-1:-1:-1;4149:10:0;;-1:-1:-1;3286:18:1;;4149:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4189;;;;;;;;;;;;;;;;;;:11;:29::i;:::-;2525:28;2517:37;;4228:17;;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4257:22:0;;;;;3517:2:1;4257:22:0;;;3499:21:1;3556:1;3536:18;;;3529:29;3594:8;3574:18;;;3567:36;4257:4:0;;-1:-1:-1;4257:12:0;;-1:-1:-1;3620:18:1;;4257:22:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2525:28;2517:37;;4289:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3794:520::o;2778:949::-;2819:31;;;;;;;;;3855:21:1;;;;3912:2;3892:18;;;3885:30;3951:14;3931:18;;;3924:42;2810:6:0;4018:20:1;;;4011:52;;;2810:6:0;2819:8;;;;3983:19:1;;2819:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2810:40;;2860:37;;;;;;;;;;;;;;;;;;2895:1;2860:11;:37::i;:::-;2908:43;;;;;;;;;;;;;;;;;;2945:4;2908:11;:43::i;:::-;2961:57;;;;;;;;;;;;;;;;2991:26;;;;;3011:4;2991:26;;;4502:74:1;2961:57:0;;;2991:11;;;;4475:18:1;;2991:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2961:57;;:11;:57::i;:::-;3028:47;;;;;;;;;;;;;;;;;;3063:10;3028:11;:47::i;:::-;3085:61;;;;;;;;;;;;;;;;3113:32;;;;;3133:10;3113:32;;;4502:74:1;3085:61:0;;;3113:11;;;;4475:18:1;;3113:32:0;4356:226:1;3085:61:0;3157:55;;;;;;;;;;;;;;;;;3245:38;;;;;3157:18;;3245:16;;;;:38;;3157:55;;3245:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3222:61;;3293:37;;;;;;;;;;;;;;;;;;3313:4;3318:1;3313:7;;;;;;;;:::i;:::-;;;;;;;3322:4;3327:1;3322:7;;;;;;;;:::i;:::-;;;;;;;3293:11;:37::i;:::-;3341:27;;;;;8688:2:1;3341:27:0;;;8670:21:1;8727:2;8707:18;;;8700:30;8766:15;8746:18;;;8739:43;3341:4:0;;:10;;8799:18:1;;3341:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3378:37:0;;;;;3408:4;3378:37;;;4502:74:1;3378:13:0;;-1:-1:-1;3378:13:0;;-1:-1:-1;4475:18:1;;3378:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3425:26:0;;;;;9030:2:1;3425:26:0;;;9012:21:1;9069:2;9049:18;;;9042:30;9108:14;9088:18;;;9081:42;3425:4:0;;-1:-1:-1;3425:10:0;;-1:-1:-1;9140:18:1;;3425:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3461:59;;;;;;;;;;;;;;;;;;3508:10;3461:11;:59::i;:::-;3530:56;;;;;;;;;;;;;;;;;;3580:4;3530:11;:56::i;:::-;3596:26;;;;;9371:2:1;3596:26:0;;;9353:21:1;9410:2;9390:18;;;9383:30;9449:14;9429:18;;;9422:42;3596:4:0;;:10;;9481:18:1;;3596:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2525:28;2517:37;;3632:12;;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3656:33:0;;;;;9712:2:1;3656:33:0;;;9694:21:1;9751:2;9731:18;;;9724:30;9790:21;9770:18;;;9763:49;3656:4:0;;-1:-1:-1;3656:10:0;;-1:-1:-1;9829:18:1;;3656:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3700:20;;;;;;;;;;;;;;;;;;:11;:20::i;:::-;2800:927;;;2778:949::o;1549:121::-;1604:59;1659:2;1620:42;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1604:15;:59::i;:::-;1549:121;:::o;1972:145::-;2039:71;2102:2;2106;2055:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;2039:15;:71::i;1676:139::-;1740:68;1800:2;1804;1756:51;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1740:15;:68::i;1821:145::-;1888:71;1951:2;1955;1904:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1888:15;:71::i;2123:179::-;2214:81;2283:2;2287;2291;2230:64;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1024:133;1095:55;1142:7;1261:14;;747:42;1434:2;1421:16;;1237:21;;1261:14;1421:16;747:42;1470:5;1459:68;1450:77;;1387:150;;1163:380;:::o;196:592:1:-;267:6;275;328:2;316:9;307:7;303:23;299:32;296:52;;;344:1;341;334:12;296:52;384:9;371:23;413:18;454:2;446:6;443:14;440:34;;;470:1;467;460:12;440:34;508:6;497:9;493:22;483:32;;553:7;546:4;542:2;538:13;534:27;524:55;;575:1;572;565:12;524:55;615:2;602:16;641:2;633:6;630:14;627:34;;;657:1;654;647:12;627:34;702:7;697:2;688:6;684:2;680:15;676:24;673:37;670:57;;;723:1;720;713:12;670:57;754:2;746:11;;;;;776:6;;-1:-1:-1;196:592:1;;-1:-1:-1;;;;196:592:1:o;793:349::-;832:3;863:66;856:5;853:77;850:257;;963:77;960:1;953:88;1064:4;1061:1;1054:15;1092:4;1089:1;1082:15;850:257;-1:-1:-1;1134:1:1;1123:13;;793:349::o;1147:449::-;1306:2;1295:9;1288:21;1345:6;1340:2;1329:9;1325:18;1318:34;1402:6;1394;1389:2;1378:9;1374:18;1361:48;1458:1;1429:22;;;1453:2;1425:31;;;1418:42;;;;1512:2;1500:15;;;1517:66;1496:88;1481:104;1477:113;;1147:449;-1:-1:-1;1147:449:1:o;4074:277::-;4141:6;4194:2;4182:9;4173:7;4169:23;4165:32;4162:52;;;4210:1;4207;4200:12;4162:52;4242:9;4236:16;4295:5;4288:13;4281:21;4274:5;4271:32;4261:60;;4317:1;4314;4307:12;4261:60;4340:5;4074:277;-1:-1:-1;;;4074:277:1:o;4587:288::-;4656:6;4709:2;4697:9;4688:7;4684:23;4680:32;4677:52;;;4725:1;4722;4715:12;4677:52;4757:9;4751:16;4807:18;4800:5;4796:30;4789:5;4786:41;4776:69;;4841:1;4838;4831:12;4880:258;4952:1;4962:113;4976:6;4973:1;4970:13;4962:113;;;5052:11;;;5046:18;5033:11;;;5026:39;4998:2;4991:10;4962:113;;;5093:6;5090:1;5087:13;5084:48;;;-1:-1:-1;;5128:1:1;5110:16;;5103:27;4880:258::o;5143:317::-;5185:3;5223:5;5217:12;5250:6;5245:3;5238:19;5266:63;5322:6;5315:4;5310:3;5306:14;5299:4;5292:5;5288:16;5266:63;:::i;:::-;5374:2;5362:15;5379:66;5358:88;5349:98;;;;5449:4;5345:109;;5143:317;-1:-1:-1;;5143:317:1:o;5465:493::-;5715:2;5704:9;5697:21;5678:4;5741:45;5782:2;5771:9;5767:18;5759:6;5741:45;:::i;:::-;5834:9;5826:6;5822:22;5817:2;5806:9;5802:18;5795:50;5869:2;5861:6;5854:18;5905:14;5900:2;5892:6;5888:15;5881:39;5949:2;5941:6;5937:15;5929:23;;;5465:493;;;;:::o;5963:184::-;6015:77;6012:1;6005:88;6112:4;6109:1;6102:15;6136:4;6133:1;6126:15;6152:334;6223:2;6217:9;6279:2;6269:13;;6284:66;6265:86;6253:99;;6382:18;6367:34;;6403:22;;;6364:62;6361:88;;;6429:18;;:::i;:::-;6465:2;6458:22;6152:334;;-1:-1:-1;6152:334:1:o;6491:1801::-;6596:6;6627:2;6670;6658:9;6649:7;6645:23;6641:32;6638:52;;;6686:1;6683;6676:12;6638:52;6719:9;6713:16;6748:18;6789:2;6781:6;6778:14;6775:34;;;6805:1;6802;6795:12;6775:34;6843:6;6832:9;6828:22;6818:32;;6869:4;6909:7;6904:2;6900;6896:11;6892:25;6882:53;;6931:1;6928;6921:12;6882:53;6960:2;6954:9;6982:2;6978;6975:10;6972:36;;;6988:18;;:::i;:::-;7034:2;7031:1;7027:10;7057:28;7081:2;7077;7073:11;7057:28;:::i;:::-;7119:15;;;7189:11;;;7185:20;;;7150:12;;;;7217:19;;;7214:39;;;7249:1;7246;7239:12;7214:39;7281:2;7277;7273:11;7262:22;;7293:969;7309:6;7304:3;7301:15;7293:969;;;7388:3;7382:10;7424:2;7411:11;7408:19;7405:109;;;7468:1;7497:2;7493;7486:14;7405:109;7537:20;;7592:2;7584:11;;7580:25;-1:-1:-1;7570:123:1;;7647:1;7676:2;7672;7665:14;7570:123;7731:2;7727;7723:11;7717:18;7759:2;7785;7780:3;7777:11;7774:37;;;7791:18;;:::i;:::-;7837:111;7944:2;7875:66;7870:2;7865:3;7861:12;7857:85;7853:94;7837:111;:::i;:::-;7975:3;7968:5;7961:18;8022:7;8016:3;8010;8006:2;8002:12;7998:22;7995:35;7992:128;;;8072:1;8102:3;8097;8090:16;7992:128;8133:56;8185:3;8180:2;8173:5;8169:14;8163:3;8159:2;8155:12;8133:56;:::i;:::-;8202:18;;-1:-1:-1;;;7326:12:1;;;;8240;;;;7293:969;;;8281:5;6491:1801;-1:-1:-1;;;;;;;;;;6491:1801:1:o;8297:184::-;8349:77;8346:1;8339:88;8446:4;8443:1;8436:15;8470:4;8467:1;8460:15;9858:220;10007:2;9996:9;9989:21;9970:4;10027:45;10068:2;10057:9;10053:18;10045:6;10027:45;:::i;10083:340::-;10260:2;10249:9;10242:21;10223:4;10280:45;10321:2;10310:9;10306:18;10298:6;10280:45;:::i;:::-;10272:53;;10373:42;10365:6;10361:55;10356:2;10345:9;10341:18;10334:83;10083:340;;;;;:::o;10428:301::-;10599:2;10588:9;10581:21;10562:4;10619:45;10660:2;10649:9;10645:18;10637:6;10619:45;:::i;:::-;10611:53;;10714:6;10707:14;10700:22;10695:2;10684:9;10680:18;10673:50;10428:301;;;;;:::o;10734:291::-;10911:2;10900:9;10893:21;10874:4;10931:45;10972:2;10961:9;10957:18;10949:6;10931:45;:::i;:::-;10923:53;;11012:6;11007:2;10996:9;10992:18;10985:34;10734:291;;;;;:::o;11030:546::-;11275:2;11264:9;11257:21;11238:4;11301:45;11342:2;11331:9;11327:18;11319:6;11301:45;:::i;:::-;11394:9;11386:6;11382:22;11377:2;11366:9;11362:18;11355:50;11428:33;11454:6;11446;11428:33;:::i;:::-;11414:47;;11509:9;11501:6;11497:22;11492:2;11481:9;11477:18;11470:50;11537:33;11563:6;11555;11537:33;:::i;:::-;11529:41;11030:546;-1:-1:-1;;;;;;11030:546:1:o","linkReferences":{}},"methodIdentifiers":{"call1(string)":"7e79255d","call2(string)":"8d3ef7ca","counter()":"61bc221a","hello(string)":"a777d0dc","nested1(string)":"a76ccdfa","nested2(string)":"dbf1282f","run()":"c0406226","runBroadcast()":"bef03abc"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"call1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"call2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"counter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"hello\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"nested1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"nested2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"run\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"runBroadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"title\":\"ScriptExample\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"hello(string)\":{\"notice\":\"example external function, to force a CALL, and test vm.startPrank with.\"},\"run()\":{\"notice\":\"example function, runs through basic cheat-codes and console logs.\"},\"runBroadcast()\":{\"notice\":\"example function, to test vm.broadcast with.\"}},\"notice\":\"ScriptExample is an example script. The Go forge script code tests that it can run this.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"ScriptExample\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x7727e5a55f4b3d442729483d41848c957b04027e48d972a568ee6f50aa3daa7a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4de8bd2d73869b583c44f8996ef56f872ce47499e801aa95da90a8e695196b00\",\"dweb:/ipfs/QmZzQy8ZSWuMnLBsGWTxUxZRhWGTJ8cq8yHpM59irYA2dw\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"call1"},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"call2"},{"inputs":[],"stateMutability":"view","type":"function","name":"counter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"view","type":"function","name":"hello"},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"nested1"},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"nested2"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"run"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"runBroadcast"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{"hello(string)":{"notice":"example external function, to force a CALL, and test vm.startPrank with."},"run()":{"notice":"example function, runs through basic cheat-codes and console logs."},"runBroadcast()":{"notice":"example function, to test vm.broadcast with."}},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"ScriptExample"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x7727e5a55f4b3d442729483d41848c957b04027e48d972a568ee6f50aa3daa7a","urls":["bzz-raw://4de8bd2d73869b583c44f8996ef56f872ce47499e801aa95da90a8e695196b00","dweb:/ipfs/QmZzQy8ZSWuMnLBsGWTxUxZRhWGTJ8cq8yHpM59irYA2dw"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[{"astId":205,"contract":"scripts/ScriptExample.s.sol:ScriptExample","label":"counter","offset":0,"slot":"0","type":"t_uint256"}],"types":{"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"userdoc":{"version":1,"kind":"user","methods":{"hello(string)":{"notice":"example external function, to force a CALL, and test vm.startPrank with."},"run()":{"notice":"example function, runs through basic cheat-codes and console logs."},"runBroadcast()":{"notice":"example function, to test vm.broadcast with."}},"notice":"ScriptExample is an example script. The Go forge script code tests that it can run this."},"devdoc":{"version":1,"kind":"dev","title":"ScriptExample"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":538,"exportedSymbols":{"ScriptExample":[537],"Vm":[45],"console":[182]},"nodeType":"SourceUnit","src":"32:4932:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":45,"nodeType":"ContractDefinition","src":"120:507:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":45,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":45,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":45,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":38,"nodeType":"FunctionDefinition","src":"516:30:0","nodes":[],"functionSelector":"afc98040","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"525:9:0","parameters":{"id":36,"nodeType":"ParameterList","parameters":[],"src":"534:2:0"},"returnParameters":{"id":37,"nodeType":"ParameterList","parameters":[],"src":"545:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":41,"nodeType":"FunctionDefinition","src":"551:35:0","nodes":[],"functionSelector":"7fb5297f","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"560:14:0","parameters":{"id":39,"nodeType":"ParameterList","parameters":[],"src":"574:2:0"},"returnParameters":{"id":40,"nodeType":"ParameterList","parameters":[],"src":"585:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":44,"nodeType":"FunctionDefinition","src":"591:34:0","nodes":[],"functionSelector":"76eadd36","implemented":false,"kind":"function","modifiers":[],"name":"stopBroadcast","nameLocation":"600:13:0","parameters":{"id":42,"nodeType":"ParameterList","parameters":[],"src":"613:2:0"},"returnParameters":{"id":43,"nodeType":"ParameterList","parameters":[],"src":"624:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[45],"name":"Vm","nameLocation":"130:2:0","scope":538,"usedErrors":[]},{"id":182,"nodeType":"ContractDefinition","src":"682:1622:0","nodes":[{"id":51,"nodeType":"VariableDeclaration","src":"704:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"721:15:0","scope":182,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":46,"name":"address","nodeType":"ElementaryTypeName","src":"704:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":49,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"747:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":48,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"739:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":47,"name":"address","nodeType":"ElementaryTypeName","src":"739:7:0","typeDescriptions":{}}},"id":50,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"739:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":68,"nodeType":"FunctionDefinition","src":"797:221:0","nodes":[],"body":{"id":67,"nodeType":"Block","src":"956:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"975:37:0","statements":[{"nodeType":"YulAssignment","src":"989:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"998:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"989:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":57,"isOffset":false,"isSlot":false,"src":"998:4:0","valueSize":1},{"declaration":64,"isOffset":false,"isSlot":false,"src":"989:5:0","valueSize":1}],"id":66,"nodeType":"InlineAssembly","src":"966:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"806:25:0","parameters":{"id":58,"nodeType":"ParameterList","parameters":[{"constant":false,"id":57,"mutability":"mutable","name":"fnIn","nameLocation":"878:4:0","nodeType":"VariableDeclaration","scope":68,"src":"841:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":56,"nodeType":"FunctionTypeName","parameterTypes":{"id":54,"nodeType":"ParameterList","parameters":[{"constant":false,"id":53,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":56,"src":"850:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":52,"name":"bytes","nodeType":"ElementaryTypeName","src":"850:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"849:14:0"},"returnParameterTypes":{"id":55,"nodeType":"ParameterList","parameters":[],"src":"878:0:0"},"src":"841:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"831:57:0"},"returnParameters":{"id":65,"nodeType":"ParameterList","parameters":[{"constant":false,"id":64,"mutability":"mutable","name":"fnOut","nameLocation":"949:5:0","nodeType":"VariableDeclaration","scope":68,"src":"912:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":63,"nodeType":"FunctionTypeName","parameterTypes":{"id":61,"nodeType":"ParameterList","parameters":[{"constant":false,"id":60,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":63,"src":"921:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":59,"name":"bytes","nodeType":"ElementaryTypeName","src":"921:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"920:14:0"},"returnParameterTypes":{"id":62,"nodeType":"ParameterList","parameters":[],"src":"949:0:0"},"src":"912:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"911:44:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":80,"nodeType":"FunctionDefinition","src":"1024:133:0","nodes":[],"body":{"id":79,"nodeType":"Block","src":"1085:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":76,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":70,"src":"1142:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":74,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":96,"src":"1121:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":73,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":68,"src":"1095:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":75,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1095:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":77,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1095:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":78,"nodeType":"ExpressionStatement","src":"1095:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"1033:15:0","parameters":{"id":71,"nodeType":"ParameterList","parameters":[{"constant":false,"id":70,"mutability":"mutable","name":"payload","nameLocation":"1062:7:0","nodeType":"VariableDeclaration","scope":80,"src":"1049:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":69,"name":"bytes","nodeType":"ElementaryTypeName","src":"1049:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1048:22:0"},"returnParameters":{"id":72,"nodeType":"ParameterList","parameters":[],"src":"1085:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":96,"nodeType":"FunctionDefinition","src":"1163:380:0","nodes":[],"body":{"id":95,"nodeType":"Block","src":"1227:316:0","nodes":[],"statements":[{"assignments":[86],"declarations":[{"constant":false,"id":86,"mutability":"mutable","name":"payloadLength","nameLocation":"1245:13:0","nodeType":"VariableDeclaration","scope":95,"src":"1237:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":85,"name":"uint256","nodeType":"ElementaryTypeName","src":"1237:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":89,"initialValue":{"expression":{"id":87,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":82,"src":"1261:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":88,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1261:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1237:38:0"},{"assignments":[91],"declarations":[{"constant":false,"id":91,"mutability":"mutable","name":"consoleAddress","nameLocation":"1293:14:0","nodeType":"VariableDeclaration","scope":95,"src":"1285:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":90,"name":"address","nodeType":"ElementaryTypeName","src":"1285:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":93,"initialValue":{"id":92,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":51,"src":"1310:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1285:40:0"},{"AST":{"nodeType":"YulBlock","src":"1387:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1401:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1425:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1434:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1421:3:0"},"nodeType":"YulFunctionCall","src":"1421:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1405:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1450:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1470:3:0"},"nodeType":"YulFunctionCall","src":"1470:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1477:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1493:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1507:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1522:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1525:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1459:10:0"},"nodeType":"YulFunctionCall","src":"1459:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1454:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":91,"isOffset":false,"isSlot":false,"src":"1477:14:0","valueSize":1},{"declaration":82,"isOffset":false,"isSlot":false,"src":"1425:7:0","valueSize":1},{"declaration":86,"isOffset":false,"isSlot":false,"src":"1507:13:0","valueSize":1}],"id":94,"nodeType":"InlineAssembly","src":"1378:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1172:19:0","parameters":{"id":83,"nodeType":"ParameterList","parameters":[{"constant":false,"id":82,"mutability":"mutable","name":"payload","nameLocation":"1205:7:0","nodeType":"VariableDeclaration","scope":96,"src":"1192:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":81,"name":"bytes","nodeType":"ElementaryTypeName","src":"1192:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1191:22:0"},"returnParameters":{"id":84,"nodeType":"ParameterList","parameters":[],"src":"1227:0:0"},"scope":182,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":110,"nodeType":"FunctionDefinition","src":"1549:121:0","nodes":[],"body":{"id":109,"nodeType":"Block","src":"1594:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":104,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1644:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":105,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":98,"src":"1659:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":102,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1620:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":103,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1620:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":106,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1620:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":101,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1604:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":107,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1604:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":108,"nodeType":"ExpressionStatement","src":"1604:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1558:3:0","parameters":{"id":99,"nodeType":"ParameterList","parameters":[{"constant":false,"id":98,"mutability":"mutable","name":"p0","nameLocation":"1576:2:0","nodeType":"VariableDeclaration","scope":110,"src":"1562:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":97,"name":"string","nodeType":"ElementaryTypeName","src":"1562:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1561:18:0"},"returnParameters":{"id":100,"nodeType":"ParameterList","parameters":[],"src":"1594:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":127,"nodeType":"FunctionDefinition","src":"1676:139:0","nodes":[],"body":{"id":126,"nodeType":"Block","src":"1730:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":120,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1780:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":121,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":112,"src":"1800:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":122,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":114,"src":"1804:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":118,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1756:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":119,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1756:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":123,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1756:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":117,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1740:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":124,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1740:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":125,"nodeType":"ExpressionStatement","src":"1740:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1685:3:0","parameters":{"id":115,"nodeType":"ParameterList","parameters":[{"constant":false,"id":112,"mutability":"mutable","name":"p0","nameLocation":"1703:2:0","nodeType":"VariableDeclaration","scope":127,"src":"1689:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":111,"name":"string","nodeType":"ElementaryTypeName","src":"1689:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":114,"mutability":"mutable","name":"p1","nameLocation":"1712:2:0","nodeType":"VariableDeclaration","scope":127,"src":"1707:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":113,"name":"bool","nodeType":"ElementaryTypeName","src":"1707:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1688:27:0"},"returnParameters":{"id":116,"nodeType":"ParameterList","parameters":[],"src":"1730:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":144,"nodeType":"FunctionDefinition","src":"1821:145:0","nodes":[],"body":{"id":143,"nodeType":"Block","src":"1878:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":137,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1928:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":138,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":129,"src":"1951:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":139,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":131,"src":"1955:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":135,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1904:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":136,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1904:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":140,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1904:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":134,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1888:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":141,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1888:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":142,"nodeType":"ExpressionStatement","src":"1888:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1830:3:0","parameters":{"id":132,"nodeType":"ParameterList","parameters":[{"constant":false,"id":129,"mutability":"mutable","name":"p0","nameLocation":"1848:2:0","nodeType":"VariableDeclaration","scope":144,"src":"1834:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":128,"name":"string","nodeType":"ElementaryTypeName","src":"1834:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":131,"mutability":"mutable","name":"p1","nameLocation":"1860:2:0","nodeType":"VariableDeclaration","scope":144,"src":"1852:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":130,"name":"uint256","nodeType":"ElementaryTypeName","src":"1852:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1833:30:0"},"returnParameters":{"id":133,"nodeType":"ParameterList","parameters":[],"src":"1878:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":161,"nodeType":"FunctionDefinition","src":"1972:145:0","nodes":[],"body":{"id":160,"nodeType":"Block","src":"2029:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":154,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2079:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":155,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":146,"src":"2102:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":156,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":148,"src":"2106:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":152,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2055:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":153,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2055:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":157,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2055:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":151,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"2039:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":158,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2039:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":159,"nodeType":"ExpressionStatement","src":"2039:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1981:3:0","parameters":{"id":149,"nodeType":"ParameterList","parameters":[{"constant":false,"id":146,"mutability":"mutable","name":"p0","nameLocation":"1999:2:0","nodeType":"VariableDeclaration","scope":161,"src":"1985:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":145,"name":"string","nodeType":"ElementaryTypeName","src":"1985:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":148,"mutability":"mutable","name":"p1","nameLocation":"2011:2:0","nodeType":"VariableDeclaration","scope":161,"src":"2003:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":147,"name":"address","nodeType":"ElementaryTypeName","src":"2003:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1984:30:0"},"returnParameters":{"id":150,"nodeType":"ParameterList","parameters":[],"src":"2029:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":181,"nodeType":"FunctionDefinition","src":"2123:179:0","nodes":[],"body":{"id":180,"nodeType":"Block","src":"2204:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":173,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2254:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":174,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":163,"src":"2283:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":175,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":165,"src":"2287:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":176,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":167,"src":"2291:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":171,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2230:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":172,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2230:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":177,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2230:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":170,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"2214:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":178,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2214:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":179,"nodeType":"ExpressionStatement","src":"2214:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2132:3:0","parameters":{"id":168,"nodeType":"ParameterList","parameters":[{"constant":false,"id":163,"mutability":"mutable","name":"p0","nameLocation":"2150:2:0","nodeType":"VariableDeclaration","scope":181,"src":"2136:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":162,"name":"string","nodeType":"ElementaryTypeName","src":"2136:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":165,"mutability":"mutable","name":"p1","nameLocation":"2168:2:0","nodeType":"VariableDeclaration","scope":181,"src":"2154:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":164,"name":"string","nodeType":"ElementaryTypeName","src":"2154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":167,"mutability":"mutable","name":"p2","nameLocation":"2186:2:0","nodeType":"VariableDeclaration","scope":181,"src":"2172:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":166,"name":"string","nodeType":"ElementaryTypeName","src":"2172:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2135:54:0"},"returnParameters":{"id":169,"nodeType":"ParameterList","parameters":[],"src":"2204:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[182],"name":"console","nameLocation":"690:7:0","scope":538,"usedErrors":[]},{"id":537,"nodeType":"ContractDefinition","src":"2432:2531:0","nodes":[{"id":197,"nodeType":"VariableDeclaration","src":"2462:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2488:10:0","scope":537,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":184,"name":"address","nodeType":"ElementaryTypeName","src":"2462:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":192,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2535:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":191,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2525:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":193,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2525:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":190,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2517:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":189,"name":"uint256","nodeType":"ElementaryTypeName","src":"2517:7:0","typeDescriptions":{}}},"id":194,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2517:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":188,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2509:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":187,"name":"uint160","nodeType":"ElementaryTypeName","src":"2509:7:0","typeDescriptions":{}}},"id":195,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2509:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":186,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2501:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":185,"name":"address","nodeType":"ElementaryTypeName","src":"2501:7:0","typeDescriptions":{}}},"id":196,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2501:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":203,"nodeType":"VariableDeclaration","src":"2562:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2583:2:0","scope":537,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"},"typeName":{"id":199,"nodeType":"UserDefinedTypeName","pathNode":{"id":198,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":45,"src":"2562:2:0"},"referencedDeclaration":45,"src":"2562:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"value":{"arguments":[{"id":201,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":197,"src":"2591:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":200,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":45,"src":"2588:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$45_$","typeString":"type(contract Vm)"}},"id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2588:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"visibility":"internal"},{"id":205,"nodeType":"VariableDeclaration","src":"2666:22:0","nodes":[],"constant":false,"functionSelector":"61bc221a","mutability":"mutable","name":"counter","nameLocation":"2681:7:0","scope":537,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":204,"name":"uint256","nodeType":"ElementaryTypeName","src":"2666:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":368,"nodeType":"FunctionDefinition","src":"2778:949:0","nodes":[],"body":{"id":367,"nodeType":"Block","src":"2800:927:0","nodes":[],"statements":[{"assignments":[210],"declarations":[{"constant":false,"id":210,"mutability":"mutable","name":"x","nameLocation":"2815:1:0","nodeType":"VariableDeclaration","scope":367,"src":"2810:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":209,"name":"bool","nodeType":"ElementaryTypeName","src":"2810:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":216,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":213,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2828:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":214,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2844:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":211,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"2819:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":212,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2819:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":215,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2819:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2810:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":220,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2872:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":221,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":210,"src":"2895:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":217,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"2860:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":219,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":127,"src":"2860:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":222,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2860:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":223,"nodeType":"ExpressionStatement","src":"2860:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":227,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2920:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":230,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"2945:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}],"id":229,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2937:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":228,"name":"address","nodeType":"ElementaryTypeName","src":"2937:7:0","typeDescriptions":{}}},"id":231,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2937:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":224,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"2908:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":226,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"2908:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2908:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":233,"nodeType":"ExpressionStatement","src":"2908:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":237,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2973:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":242,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3011:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}],"id":241,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3003:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":240,"name":"address","nodeType":"ElementaryTypeName","src":"3003:7:0","typeDescriptions":{}}},"id":243,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3003:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":238,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"2991:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":239,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"2991:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":244,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2991:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":234,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"2961:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":236,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":144,"src":"2961:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":245,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2961:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":246,"nodeType":"ExpressionStatement","src":"2961:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":250,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3040:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":253,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3063:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":254,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3063:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":252,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3055:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":251,"name":"address","nodeType":"ElementaryTypeName","src":"3055:7:0","typeDescriptions":{}}},"id":255,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3055:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":247,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3028:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"3028:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":256,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3028:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":257,"nodeType":"ExpressionStatement","src":"3028:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":261,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3097:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":266,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3133:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":267,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3133:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":265,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3125:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":264,"name":"address","nodeType":"ElementaryTypeName","src":"3125:7:0","typeDescriptions":{}}},"id":268,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3125:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":262,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3113:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":263,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3113:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":269,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3113:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":258,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3085:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":260,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":144,"src":"3085:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":270,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3085:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":271,"nodeType":"ExpressionStatement","src":"3085:61:0"},{"assignments":[273],"declarations":[{"constant":false,"id":273,"mutability":"mutable","name":"json","nameLocation":"3171:4:0","nodeType":"VariableDeclaration","scope":367,"src":"3157:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":272,"name":"string","nodeType":"ElementaryTypeName","src":"3157:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":275,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":274,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3178:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"3157:55:0"},{"assignments":[280],"declarations":[{"constant":false,"id":280,"mutability":"mutable","name":"keys","nameLocation":"3238:4:0","nodeType":"VariableDeclaration","scope":367,"src":"3222:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":278,"name":"string","nodeType":"ElementaryTypeName","src":"3222:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":279,"nodeType":"ArrayTypeName","src":"3222:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":286,"initialValue":{"arguments":[{"id":283,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":273,"src":"3262:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3268:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":281,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3245:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":282,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3245:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":285,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3245:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3222:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":290,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3305:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":291,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":280,"src":"3313:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":293,"indexExpression":{"hexValue":"30","id":292,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3318:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3313:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":294,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":280,"src":"3322:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":296,"indexExpression":{"hexValue":"31","id":295,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3327:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3322:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":287,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3293:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":289,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":181,"src":"3293:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":297,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3293:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":298,"nodeType":"ExpressionStatement","src":"3293:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3352:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":299,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3341:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":301,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3341:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":303,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3341:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":304,"nodeType":"ExpressionStatement","src":"3341:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":312,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3408:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":311,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3400:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":310,"name":"uint160","nodeType":"ElementaryTypeName","src":"3400:7:0","typeDescriptions":{}}},"id":313,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3400:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":309,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3392:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":308,"name":"address","nodeType":"ElementaryTypeName","src":"3392:7:0","typeDescriptions":{}}},"id":314,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3392:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":305,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3378:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":307,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3378:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":315,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3378:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":316,"nodeType":"ExpressionStatement","src":"3378:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":320,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3436:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":317,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3425:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":319,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3425:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":321,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3425:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":322,"nodeType":"ExpressionStatement","src":"3425:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":326,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3473:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":329,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3508:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":330,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3508:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":328,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3500:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":327,"name":"address","nodeType":"ElementaryTypeName","src":"3500:7:0","typeDescriptions":{}}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3500:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":323,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3461:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"3461:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":332,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3461:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":333,"nodeType":"ExpressionStatement","src":"3461:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":337,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3542:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":340,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3580:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}],"id":339,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3572:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":338,"name":"address","nodeType":"ElementaryTypeName","src":"3572:7:0","typeDescriptions":{}}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3572:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":334,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3530:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":336,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"3530:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3530:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3530:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3607:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":344,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3596:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3596:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":348,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3596:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":349,"nodeType":"ExpressionStatement","src":"3596:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":350,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3632:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3632:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":353,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3632:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":354,"nodeType":"ExpressionStatement","src":"3632:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":358,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3667:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":355,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3656:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":357,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3656:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":359,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3656:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":360,"nodeType":"ExpressionStatement","src":"3656:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":364,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3712:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":361,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3700:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":363,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"3700:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":365,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3700:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":366,"nodeType":"ExpressionStatement","src":"3700:20:0"}]},"documentation":{"id":206,"nodeType":"StructuredDocumentation","src":"2695:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2787:3:0","parameters":{"id":207,"nodeType":"ParameterList","parameters":[],"src":"2790:2:0"},"returnParameters":{"id":208,"nodeType":"ParameterList","parameters":[],"src":"2800:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":452,"nodeType":"FunctionDefinition","src":"3794:520:0","nodes":[],"body":{"id":451,"nodeType":"Block","src":"3825:489:0","nodes":[],"statements":[{"expression":{"arguments":[{"hexValue":"74657374696e672073696e676c65","id":375,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3847:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""},"value":"testing single"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""}],"expression":{"id":372,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3835:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":374,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"3835:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":376,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3835:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":377,"nodeType":"ExpressionStatement","src":"3835:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":378,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3874:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":380,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"3874:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":381,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3874:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":382,"nodeType":"ExpressionStatement","src":"3874:14:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c31","id":386,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3909:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""},"value":"single_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""}],"expression":{"id":383,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3898:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":385,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":491,"src":"3898:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":387,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3898:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":388,"nodeType":"ExpressionStatement","src":"3898:26:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c32","id":392,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3945:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""},"value":"single_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""}],"expression":{"id":389,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3934:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":391,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":506,"src":"3934:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":393,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3934:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":394,"nodeType":"ExpressionStatement","src":"3934:26:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073746172742f73746f70","id":398,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3983:20:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""},"value":"testing start/stop"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""}],"expression":{"id":395,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3971:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":397,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"3971:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":399,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3971:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":400,"nodeType":"ExpressionStatement","src":"3971:33:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":401,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4014:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":403,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":41,"src":"4014:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":404,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4014:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":405,"nodeType":"ExpressionStatement","src":"4014:19:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c31","id":409,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4054:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""},"value":"startstop_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""}],"expression":{"id":406,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4043:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":408,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":491,"src":"4043:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":410,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4043:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":411,"nodeType":"ExpressionStatement","src":"4043:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c32","id":415,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4093:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""},"value":"startstop_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""}],"expression":{"id":412,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4082:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":414,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":506,"src":"4082:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":416,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4082:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":417,"nodeType":"ExpressionStatement","src":"4082:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":418,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4121:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":420,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":44,"src":"4121:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":421,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4121:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":422,"nodeType":"ExpressionStatement","src":"4121:18:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c33","id":426,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4160:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""},"value":"startstop_call3"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""}],"expression":{"id":423,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4149:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":425,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":491,"src":"4149:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":427,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4149:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":428,"nodeType":"ExpressionStatement","src":"4149:29:0"},{"expression":{"arguments":[{"hexValue":"74657374696e67206e6573746564","id":432,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4201:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""},"value":"testing nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""}],"expression":{"id":429,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4189:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":431,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4189:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":433,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4189:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":434,"nodeType":"ExpressionStatement","src":"4189:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":435,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4228:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":437,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":41,"src":"4228:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":438,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4228:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":439,"nodeType":"ExpressionStatement","src":"4228:19:0"},{"expression":{"arguments":[{"hexValue":"6e6573746564","id":443,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4270:8:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""},"value":"nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""}],"expression":{"id":440,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4257:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":442,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested1","nodeType":"MemberAccess","referencedDeclaration":521,"src":"4257:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":444,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4257:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":445,"nodeType":"ExpressionStatement","src":"4257:22:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":446,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4289:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":448,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":44,"src":"4289:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":449,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4289:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":450,"nodeType":"ExpressionStatement","src":"4289:18:0"}]},"documentation":{"id":369,"nodeType":"StructuredDocumentation","src":"3733:56:0","text":"@notice example function, to test vm.broadcast with."},"functionSelector":"bef03abc","implemented":true,"kind":"function","modifiers":[],"name":"runBroadcast","nameLocation":"3803:12:0","parameters":{"id":370,"nodeType":"ParameterList","parameters":[],"src":"3815:2:0"},"returnParameters":{"id":371,"nodeType":"ParameterList","parameters":[],"src":"3825:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":476,"nodeType":"FunctionDefinition","src":"4409:143:0","nodes":[],"body":{"id":475,"nodeType":"Block","src":"4458:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":461,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":455,"src":"4480:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":458,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4468:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":460,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4468:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":462,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4468:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":463,"nodeType":"ExpressionStatement","src":"4468:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":467,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4505:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":470,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"4533:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":471,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"4533:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":469,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4525:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":468,"name":"address","nodeType":"ElementaryTypeName","src":"4525:7:0","typeDescriptions":{}}},"id":472,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4525:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":464,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4493:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":466,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"4493:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":473,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4493:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":474,"nodeType":"ExpressionStatement","src":"4493:52:0"}]},"documentation":{"id":453,"nodeType":"StructuredDocumentation","src":"4320:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"4418:5:0","parameters":{"id":456,"nodeType":"ParameterList","parameters":[{"constant":false,"id":455,"mutability":"mutable","name":"_v","nameLocation":"4440:2:0","nodeType":"VariableDeclaration","scope":476,"src":"4424:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":454,"name":"string","nodeType":"ElementaryTypeName","src":"4424:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4423:20:0"},"returnParameters":{"id":457,"nodeType":"ParameterList","parameters":[],"src":"4458:0:0"},"scope":537,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":491,"nodeType":"FunctionDefinition","src":"4558:95:0","nodes":[],"body":{"id":490,"nodeType":"Block","src":"4602:51:0","nodes":[],"statements":[{"expression":{"id":482,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4612:9:0","subExpression":{"id":481,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4612:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":483,"nodeType":"ExpressionStatement","src":"4612:9:0"},{"expression":{"arguments":[{"id":487,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":478,"src":"4643:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":484,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4631:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":486,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4631:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":488,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4631:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":489,"nodeType":"ExpressionStatement","src":"4631:15:0"}]},"functionSelector":"7e79255d","implemented":true,"kind":"function","modifiers":[],"name":"call1","nameLocation":"4567:5:0","parameters":{"id":479,"nodeType":"ParameterList","parameters":[{"constant":false,"id":478,"mutability":"mutable","name":"_v","nameLocation":"4589:2:0","nodeType":"VariableDeclaration","scope":491,"src":"4573:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":477,"name":"string","nodeType":"ElementaryTypeName","src":"4573:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4572:20:0"},"returnParameters":{"id":480,"nodeType":"ParameterList","parameters":[],"src":"4602:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":506,"nodeType":"FunctionDefinition","src":"4659:95:0","nodes":[],"body":{"id":505,"nodeType":"Block","src":"4703:51:0","nodes":[],"statements":[{"expression":{"id":497,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4713:9:0","subExpression":{"id":496,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4713:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":498,"nodeType":"ExpressionStatement","src":"4713:9:0"},{"expression":{"arguments":[{"id":502,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":493,"src":"4744:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":499,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4732:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":501,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4732:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":503,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4732:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":504,"nodeType":"ExpressionStatement","src":"4732:15:0"}]},"functionSelector":"8d3ef7ca","implemented":true,"kind":"function","modifiers":[],"name":"call2","nameLocation":"4668:5:0","parameters":{"id":494,"nodeType":"ParameterList","parameters":[{"constant":false,"id":493,"mutability":"mutable","name":"_v","nameLocation":"4690:2:0","nodeType":"VariableDeclaration","scope":506,"src":"4674:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":492,"name":"string","nodeType":"ElementaryTypeName","src":"4674:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4673:20:0"},"returnParameters":{"id":495,"nodeType":"ParameterList","parameters":[],"src":"4703:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":521,"nodeType":"FunctionDefinition","src":"4760:98:0","nodes":[],"body":{"id":520,"nodeType":"Block","src":"4806:52:0","nodes":[],"statements":[{"expression":{"id":512,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4816:9:0","subExpression":{"id":511,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4816:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":513,"nodeType":"ExpressionStatement","src":"4816:9:0"},{"expression":{"arguments":[{"id":517,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":508,"src":"4848:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":514,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4835:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":516,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested2","nodeType":"MemberAccess","referencedDeclaration":536,"src":"4835:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":518,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4835:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":519,"nodeType":"ExpressionStatement","src":"4835:16:0"}]},"functionSelector":"a76ccdfa","implemented":true,"kind":"function","modifiers":[],"name":"nested1","nameLocation":"4769:7:0","parameters":{"id":509,"nodeType":"ParameterList","parameters":[{"constant":false,"id":508,"mutability":"mutable","name":"_v","nameLocation":"4793:2:0","nodeType":"VariableDeclaration","scope":521,"src":"4777:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":507,"name":"string","nodeType":"ElementaryTypeName","src":"4777:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4776:20:0"},"returnParameters":{"id":510,"nodeType":"ParameterList","parameters":[],"src":"4806:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":536,"nodeType":"FunctionDefinition","src":"4864:97:0","nodes":[],"body":{"id":535,"nodeType":"Block","src":"4910:51:0","nodes":[],"statements":[{"expression":{"id":527,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4920:9:0","subExpression":{"id":526,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4920:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":528,"nodeType":"ExpressionStatement","src":"4920:9:0"},{"expression":{"arguments":[{"id":532,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":523,"src":"4951:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":529,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4939:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":531,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4939:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":533,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4939:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":534,"nodeType":"ExpressionStatement","src":"4939:15:0"}]},"functionSelector":"dbf1282f","implemented":true,"kind":"function","modifiers":[],"name":"nested2","nameLocation":"4873:7:0","parameters":{"id":524,"nodeType":"ParameterList","parameters":[{"constant":false,"id":523,"mutability":"mutable","name":"_v","nameLocation":"4897:2:0","nodeType":"VariableDeclaration","scope":536,"src":"4881:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":522,"name":"string","nodeType":"ElementaryTypeName","src":"4881:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4880:20:0"},"returnParameters":{"id":525,"nodeType":"ParameterList","parameters":[],"src":"4910:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[],"contractKind":"contract","documentation":{"id":183,"nodeType":"StructuredDocumentation","src":"2306:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[537],"name":"ScriptExample","nameLocation":"2441:13:0","scope":538,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file diff --git a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/Vm.json b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/Vm.json index c60108b595af..de72d377618a 100644 --- a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/Vm.json +++ b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/Vm.json @@ -1 +1 @@ -{"abi":[{"type":"function","name":"envOr","inputs":[{"name":"name","type":"string","internalType":"string"},{"name":"defaultValue","type":"bool","internalType":"bool"}],"outputs":[{"name":"value","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"getNonce","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"nonce","type":"uint64","internalType":"uint64"}],"stateMutability":"view"},{"type":"function","name":"parseJsonKeys","inputs":[{"name":"json","type":"string","internalType":"string"},{"name":"key","type":"string","internalType":"string"}],"outputs":[{"name":"keys","type":"string[]","internalType":"string[]"}],"stateMutability":"pure"},{"type":"function","name":"startPrank","inputs":[{"name":"msgSender","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"stopPrank","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{"envOr(string,bool)":"4777f3cf","getNonce(address)":"2d0335ab","parseJsonKeys(string,string)":"213e4198","startPrank(address)":"06447d56","stopPrank()":"90c5013b"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"defaultValue\",\"type\":\"bool\"}],\"name\":\"envOr\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"json\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"}],\"name\":\"parseJsonKeys\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"keys\",\"type\":\"string[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"msgSender\",\"type\":\"address\"}],\"name\":\"startPrank\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stopPrank\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"Vm\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x531a2ad96c1a2c0bbfa9ab0e1195cd32551b0c10e16e7d256ce5e4c0289a8089\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://24dc6c71502c01f43fb5e113786e377c3b4cafabd5c506067d229fcdd7b037fa\",\"dweb:/ipfs/QmZ9AuxNx9Ygescfg5M4p6Abc2CCwCMZpX5xU32Fz1r4kY\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"bool","name":"defaultValue","type":"bool"}],"stateMutability":"view","type":"function","name":"envOr","outputs":[{"internalType":"bool","name":"value","type":"bool"}]},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"stateMutability":"view","type":"function","name":"getNonce","outputs":[{"internalType":"uint64","name":"nonce","type":"uint64"}]},{"inputs":[{"internalType":"string","name":"json","type":"string"},{"internalType":"string","name":"key","type":"string"}],"stateMutability":"pure","type":"function","name":"parseJsonKeys","outputs":[{"internalType":"string[]","name":"keys","type":"string[]"}]},{"inputs":[{"internalType":"address","name":"msgSender","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"startPrank"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"stopPrank"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"Vm"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x531a2ad96c1a2c0bbfa9ab0e1195cd32551b0c10e16e7d256ce5e4c0289a8089","urls":["bzz-raw://24dc6c71502c01f43fb5e113786e377c3b4cafabd5c506067d229fcdd7b037fa","dweb:/ipfs/QmZ9AuxNx9Ygescfg5M4p6Abc2CCwCMZpX5xU32Fz1r4kY"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[],"types":{}},"userdoc":{"version":1,"kind":"user"},"devdoc":{"version":1,"kind":"dev"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":383,"exportedSymbols":{"ScriptExample":[382],"Vm":[36],"console":[173]},"nodeType":"SourceUnit","src":"32:3736:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":36,"nodeType":"ContractDefinition","src":"120:393:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":36,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":36,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":36,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":36,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":36,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[36],"name":"Vm","nameLocation":"130:2:0","scope":383,"usedErrors":[]},{"id":173,"nodeType":"ContractDefinition","src":"568:1622:0","nodes":[{"id":42,"nodeType":"VariableDeclaration","src":"590:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"607:15:0","scope":173,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":37,"name":"address","nodeType":"ElementaryTypeName","src":"590:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":40,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"633:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":39,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"625:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":38,"name":"address","nodeType":"ElementaryTypeName","src":"625:7:0","typeDescriptions":{}}},"id":41,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"625:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":59,"nodeType":"FunctionDefinition","src":"683:221:0","nodes":[],"body":{"id":58,"nodeType":"Block","src":"842:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"861:37:0","statements":[{"nodeType":"YulAssignment","src":"875:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"884:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"875:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":48,"isOffset":false,"isSlot":false,"src":"884:4:0","valueSize":1},{"declaration":55,"isOffset":false,"isSlot":false,"src":"875:5:0","valueSize":1}],"id":57,"nodeType":"InlineAssembly","src":"852:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"692:25:0","parameters":{"id":49,"nodeType":"ParameterList","parameters":[{"constant":false,"id":48,"mutability":"mutable","name":"fnIn","nameLocation":"764:4:0","nodeType":"VariableDeclaration","scope":59,"src":"727:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":47,"nodeType":"FunctionTypeName","parameterTypes":{"id":45,"nodeType":"ParameterList","parameters":[{"constant":false,"id":44,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":47,"src":"736:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":43,"name":"bytes","nodeType":"ElementaryTypeName","src":"736:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"735:14:0"},"returnParameterTypes":{"id":46,"nodeType":"ParameterList","parameters":[],"src":"764:0:0"},"src":"727:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"717:57:0"},"returnParameters":{"id":56,"nodeType":"ParameterList","parameters":[{"constant":false,"id":55,"mutability":"mutable","name":"fnOut","nameLocation":"835:5:0","nodeType":"VariableDeclaration","scope":59,"src":"798:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":54,"nodeType":"FunctionTypeName","parameterTypes":{"id":52,"nodeType":"ParameterList","parameters":[{"constant":false,"id":51,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":54,"src":"807:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":50,"name":"bytes","nodeType":"ElementaryTypeName","src":"807:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"806:14:0"},"returnParameterTypes":{"id":53,"nodeType":"ParameterList","parameters":[],"src":"835:0:0"},"src":"798:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"797:44:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":71,"nodeType":"FunctionDefinition","src":"910:133:0","nodes":[],"body":{"id":70,"nodeType":"Block","src":"971:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":67,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":61,"src":"1028:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":65,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":87,"src":"1007:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":64,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":59,"src":"981:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":66,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"981:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":68,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"981:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":69,"nodeType":"ExpressionStatement","src":"981:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"919:15:0","parameters":{"id":62,"nodeType":"ParameterList","parameters":[{"constant":false,"id":61,"mutability":"mutable","name":"payload","nameLocation":"948:7:0","nodeType":"VariableDeclaration","scope":71,"src":"935:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":60,"name":"bytes","nodeType":"ElementaryTypeName","src":"935:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"934:22:0"},"returnParameters":{"id":63,"nodeType":"ParameterList","parameters":[],"src":"971:0:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":87,"nodeType":"FunctionDefinition","src":"1049:380:0","nodes":[],"body":{"id":86,"nodeType":"Block","src":"1113:316:0","nodes":[],"statements":[{"assignments":[77],"declarations":[{"constant":false,"id":77,"mutability":"mutable","name":"payloadLength","nameLocation":"1131:13:0","nodeType":"VariableDeclaration","scope":86,"src":"1123:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":76,"name":"uint256","nodeType":"ElementaryTypeName","src":"1123:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":80,"initialValue":{"expression":{"id":78,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":73,"src":"1147:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":79,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1147:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1123:38:0"},{"assignments":[82],"declarations":[{"constant":false,"id":82,"mutability":"mutable","name":"consoleAddress","nameLocation":"1179:14:0","nodeType":"VariableDeclaration","scope":86,"src":"1171:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":81,"name":"address","nodeType":"ElementaryTypeName","src":"1171:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":84,"initialValue":{"id":83,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":42,"src":"1196:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1171:40:0"},{"AST":{"nodeType":"YulBlock","src":"1273:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1287:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1311:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1320:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1307:3:0"},"nodeType":"YulFunctionCall","src":"1307:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1291:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1336:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1356:3:0"},"nodeType":"YulFunctionCall","src":"1356:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1363:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1379:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1393:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1408:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1411:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1345:10:0"},"nodeType":"YulFunctionCall","src":"1345:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1340:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":82,"isOffset":false,"isSlot":false,"src":"1363:14:0","valueSize":1},{"declaration":73,"isOffset":false,"isSlot":false,"src":"1311:7:0","valueSize":1},{"declaration":77,"isOffset":false,"isSlot":false,"src":"1393:13:0","valueSize":1}],"id":85,"nodeType":"InlineAssembly","src":"1264:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1058:19:0","parameters":{"id":74,"nodeType":"ParameterList","parameters":[{"constant":false,"id":73,"mutability":"mutable","name":"payload","nameLocation":"1091:7:0","nodeType":"VariableDeclaration","scope":87,"src":"1078:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":72,"name":"bytes","nodeType":"ElementaryTypeName","src":"1078:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1077:22:0"},"returnParameters":{"id":75,"nodeType":"ParameterList","parameters":[],"src":"1113:0:0"},"scope":173,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":101,"nodeType":"FunctionDefinition","src":"1435:121:0","nodes":[],"body":{"id":100,"nodeType":"Block","src":"1480:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":95,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1530:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":96,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":89,"src":"1545:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":93,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1506:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":94,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1506:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":97,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1506:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":92,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":71,"src":"1490:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":98,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1490:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":99,"nodeType":"ExpressionStatement","src":"1490:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1444:3:0","parameters":{"id":90,"nodeType":"ParameterList","parameters":[{"constant":false,"id":89,"mutability":"mutable","name":"p0","nameLocation":"1462:2:0","nodeType":"VariableDeclaration","scope":101,"src":"1448:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":88,"name":"string","nodeType":"ElementaryTypeName","src":"1448:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1447:18:0"},"returnParameters":{"id":91,"nodeType":"ParameterList","parameters":[],"src":"1480:0:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":118,"nodeType":"FunctionDefinition","src":"1562:139:0","nodes":[],"body":{"id":117,"nodeType":"Block","src":"1616:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":111,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1666:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":112,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":103,"src":"1686:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":113,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":105,"src":"1690:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":109,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1642:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":110,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1642:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":114,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1642:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":108,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":71,"src":"1626:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":115,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1626:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":116,"nodeType":"ExpressionStatement","src":"1626:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1571:3:0","parameters":{"id":106,"nodeType":"ParameterList","parameters":[{"constant":false,"id":103,"mutability":"mutable","name":"p0","nameLocation":"1589:2:0","nodeType":"VariableDeclaration","scope":118,"src":"1575:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":102,"name":"string","nodeType":"ElementaryTypeName","src":"1575:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":105,"mutability":"mutable","name":"p1","nameLocation":"1598:2:0","nodeType":"VariableDeclaration","scope":118,"src":"1593:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":104,"name":"bool","nodeType":"ElementaryTypeName","src":"1593:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1574:27:0"},"returnParameters":{"id":107,"nodeType":"ParameterList","parameters":[],"src":"1616:0:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":135,"nodeType":"FunctionDefinition","src":"1707:145:0","nodes":[],"body":{"id":134,"nodeType":"Block","src":"1764:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":128,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1814:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":129,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":120,"src":"1837:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":130,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":122,"src":"1841:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":126,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1790:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":127,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1790:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":131,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1790:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":125,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":71,"src":"1774:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":132,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1774:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":133,"nodeType":"ExpressionStatement","src":"1774:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1716:3:0","parameters":{"id":123,"nodeType":"ParameterList","parameters":[{"constant":false,"id":120,"mutability":"mutable","name":"p0","nameLocation":"1734:2:0","nodeType":"VariableDeclaration","scope":135,"src":"1720:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":119,"name":"string","nodeType":"ElementaryTypeName","src":"1720:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":122,"mutability":"mutable","name":"p1","nameLocation":"1746:2:0","nodeType":"VariableDeclaration","scope":135,"src":"1738:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":121,"name":"uint256","nodeType":"ElementaryTypeName","src":"1738:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1719:30:0"},"returnParameters":{"id":124,"nodeType":"ParameterList","parameters":[],"src":"1764:0:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":152,"nodeType":"FunctionDefinition","src":"1858:145:0","nodes":[],"body":{"id":151,"nodeType":"Block","src":"1915:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":145,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1965:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":146,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":137,"src":"1988:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":147,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":139,"src":"1992:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":143,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1941:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":144,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1941:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":148,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1941:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":142,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":71,"src":"1925:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":149,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1925:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":150,"nodeType":"ExpressionStatement","src":"1925:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1867:3:0","parameters":{"id":140,"nodeType":"ParameterList","parameters":[{"constant":false,"id":137,"mutability":"mutable","name":"p0","nameLocation":"1885:2:0","nodeType":"VariableDeclaration","scope":152,"src":"1871:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":136,"name":"string","nodeType":"ElementaryTypeName","src":"1871:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":139,"mutability":"mutable","name":"p1","nameLocation":"1897:2:0","nodeType":"VariableDeclaration","scope":152,"src":"1889:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":138,"name":"address","nodeType":"ElementaryTypeName","src":"1889:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1870:30:0"},"returnParameters":{"id":141,"nodeType":"ParameterList","parameters":[],"src":"1915:0:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":172,"nodeType":"FunctionDefinition","src":"2009:179:0","nodes":[],"body":{"id":171,"nodeType":"Block","src":"2090:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":164,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2140:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":165,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":154,"src":"2169:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":166,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":156,"src":"2173:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":167,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":158,"src":"2177:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":162,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2116:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":163,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2116:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":168,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2116:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":161,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":71,"src":"2100:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":169,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2100:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":170,"nodeType":"ExpressionStatement","src":"2100:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2018:3:0","parameters":{"id":159,"nodeType":"ParameterList","parameters":[{"constant":false,"id":154,"mutability":"mutable","name":"p0","nameLocation":"2036:2:0","nodeType":"VariableDeclaration","scope":172,"src":"2022:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":153,"name":"string","nodeType":"ElementaryTypeName","src":"2022:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":156,"mutability":"mutable","name":"p1","nameLocation":"2054:2:0","nodeType":"VariableDeclaration","scope":172,"src":"2040:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":155,"name":"string","nodeType":"ElementaryTypeName","src":"2040:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":158,"mutability":"mutable","name":"p2","nameLocation":"2072:2:0","nodeType":"VariableDeclaration","scope":172,"src":"2058:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":157,"name":"string","nodeType":"ElementaryTypeName","src":"2058:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2021:54:0"},"returnParameters":{"id":160,"nodeType":"ParameterList","parameters":[],"src":"2090:0:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[173],"name":"console","nameLocation":"576:7:0","scope":383,"usedErrors":[]},{"id":382,"nodeType":"ContractDefinition","src":"2318:1449:0","nodes":[{"id":188,"nodeType":"VariableDeclaration","src":"2348:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2374:10:0","scope":382,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":175,"name":"address","nodeType":"ElementaryTypeName","src":"2348:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":183,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2421:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":182,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2411:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":184,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2411:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":181,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2403:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":180,"name":"uint256","nodeType":"ElementaryTypeName","src":"2403:7:0","typeDescriptions":{}}},"id":185,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2403:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":179,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2395:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":178,"name":"uint160","nodeType":"ElementaryTypeName","src":"2395:7:0","typeDescriptions":{}}},"id":186,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2395:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":177,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2387:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":176,"name":"address","nodeType":"ElementaryTypeName","src":"2387:7:0","typeDescriptions":{}}},"id":187,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2387:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":194,"nodeType":"VariableDeclaration","src":"2448:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2469:2:0","scope":382,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"},"typeName":{"id":190,"nodeType":"UserDefinedTypeName","pathNode":{"id":189,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":36,"src":"2448:2:0"},"referencedDeclaration":36,"src":"2448:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"value":{"arguments":[{"id":192,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":188,"src":"2477:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":191,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":36,"src":"2474:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$36_$","typeString":"type(contract Vm)"}},"id":193,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2474:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"visibility":"internal"},{"id":357,"nodeType":"FunctionDefinition","src":"2578:949:0","nodes":[],"body":{"id":356,"nodeType":"Block","src":"2600:927:0","nodes":[],"statements":[{"assignments":[199],"declarations":[{"constant":false,"id":199,"mutability":"mutable","name":"x","nameLocation":"2615:1:0","nodeType":"VariableDeclaration","scope":356,"src":"2610:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":198,"name":"bool","nodeType":"ElementaryTypeName","src":"2610:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":205,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2628:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":203,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2644:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":200,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":194,"src":"2619:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"id":201,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2619:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":204,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2619:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2610:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":209,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2672:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":210,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":199,"src":"2695:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":206,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2660:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":208,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":118,"src":"2660:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":211,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2660:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":212,"nodeType":"ExpressionStatement","src":"2660:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":216,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2720:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":219,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"2745:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}],"id":218,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2737:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":217,"name":"address","nodeType":"ElementaryTypeName","src":"2737:7:0","typeDescriptions":{}}},"id":220,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2737:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":213,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2708:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":215,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":152,"src":"2708:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":221,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2708:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":222,"nodeType":"ExpressionStatement","src":"2708:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":226,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2773:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":231,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"2811:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}],"id":230,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2803:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":229,"name":"address","nodeType":"ElementaryTypeName","src":"2803:7:0","typeDescriptions":{}}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2803:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":227,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":194,"src":"2791:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"id":228,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"2791:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":233,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2791:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":223,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2761:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":225,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":135,"src":"2761:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":234,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2761:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":235,"nodeType":"ExpressionStatement","src":"2761:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":239,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2840:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":242,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"2863:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":243,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"2863:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":241,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2855:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":240,"name":"address","nodeType":"ElementaryTypeName","src":"2855:7:0","typeDescriptions":{}}},"id":244,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2855:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":236,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2828:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":238,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":152,"src":"2828:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":245,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2828:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":246,"nodeType":"ExpressionStatement","src":"2828:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":250,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2897:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":255,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"2933:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":256,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"2933:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":254,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2925:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":253,"name":"address","nodeType":"ElementaryTypeName","src":"2925:7:0","typeDescriptions":{}}},"id":257,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2925:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":251,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":194,"src":"2913:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"id":252,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"2913:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":258,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2913:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":247,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2885:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":135,"src":"2885:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":259,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2885:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":260,"nodeType":"ExpressionStatement","src":"2885:61:0"},{"assignments":[262],"declarations":[{"constant":false,"id":262,"mutability":"mutable","name":"json","nameLocation":"2971:4:0","nodeType":"VariableDeclaration","scope":356,"src":"2957:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":261,"name":"string","nodeType":"ElementaryTypeName","src":"2957:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":264,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":263,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2978:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"2957:55:0"},{"assignments":[269],"declarations":[{"constant":false,"id":269,"mutability":"mutable","name":"keys","nameLocation":"3038:4:0","nodeType":"VariableDeclaration","scope":356,"src":"3022:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":267,"name":"string","nodeType":"ElementaryTypeName","src":"3022:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":268,"nodeType":"ArrayTypeName","src":"3022:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":275,"initialValue":{"arguments":[{"id":272,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":262,"src":"3062:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":273,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3068:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":270,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":194,"src":"3045:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"id":271,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3045:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":274,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3045:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3022:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":279,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3105:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":280,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":269,"src":"3113:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":282,"indexExpression":{"hexValue":"30","id":281,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3118:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3113:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":283,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":269,"src":"3122:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":285,"indexExpression":{"hexValue":"31","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3127:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3122:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":276,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"3093:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":278,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":172,"src":"3093:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":286,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3093:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":287,"nodeType":"ExpressionStatement","src":"3093:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":291,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3152:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":288,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3141:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}},"id":290,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":381,"src":"3141:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":292,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3141:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":293,"nodeType":"ExpressionStatement","src":"3141:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":301,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3208:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":300,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3200:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":299,"name":"uint160","nodeType":"ElementaryTypeName","src":"3200:7:0","typeDescriptions":{}}},"id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3200:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":298,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3192:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":297,"name":"address","nodeType":"ElementaryTypeName","src":"3192:7:0","typeDescriptions":{}}},"id":303,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3192:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":294,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":194,"src":"3178:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"id":296,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3178:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":304,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3178:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":305,"nodeType":"ExpressionStatement","src":"3178:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":309,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3236:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":306,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3225:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}},"id":308,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":381,"src":"3225:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":310,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3225:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":311,"nodeType":"ExpressionStatement","src":"3225:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":315,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3273:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":318,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3308:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":319,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3308:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":317,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3300:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":316,"name":"address","nodeType":"ElementaryTypeName","src":"3300:7:0","typeDescriptions":{}}},"id":320,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3300:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":312,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"3261:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":314,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":152,"src":"3261:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":321,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3261:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":322,"nodeType":"ExpressionStatement","src":"3261:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":326,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3342:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":329,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3380:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}],"id":328,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3372:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":327,"name":"address","nodeType":"ElementaryTypeName","src":"3372:7:0","typeDescriptions":{}}},"id":330,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3372:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":323,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"3330:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":152,"src":"3330:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3330:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":332,"nodeType":"ExpressionStatement","src":"3330:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":336,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3407:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":333,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3396:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}},"id":335,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":381,"src":"3396:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":337,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3396:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":338,"nodeType":"ExpressionStatement","src":"3396:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":339,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":194,"src":"3432:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3432:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3432:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3432:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3467:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":344,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3456:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":381,"src":"3456:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":348,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3456:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":349,"nodeType":"ExpressionStatement","src":"3456:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":353,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3512:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":350,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"3500:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":101,"src":"3500:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":354,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3500:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":355,"nodeType":"ExpressionStatement","src":"3500:20:0"}]},"documentation":{"id":195,"nodeType":"StructuredDocumentation","src":"2495:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2587:3:0","parameters":{"id":196,"nodeType":"ParameterList","parameters":[],"src":"2590:2:0"},"returnParameters":{"id":197,"nodeType":"ParameterList","parameters":[],"src":"2600:0:0"},"scope":382,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":381,"nodeType":"FunctionDefinition","src":"3622:143:0","nodes":[],"body":{"id":380,"nodeType":"Block","src":"3671:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":366,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":360,"src":"3693:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":363,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"3681:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":365,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":101,"src":"3681:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":367,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3681:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":368,"nodeType":"ExpressionStatement","src":"3681:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":372,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3718:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":375,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3746:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":376,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3746:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":374,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3738:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":373,"name":"address","nodeType":"ElementaryTypeName","src":"3738:7:0","typeDescriptions":{}}},"id":377,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3738:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":369,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"3706:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":371,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":152,"src":"3706:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":378,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3706:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":379,"nodeType":"ExpressionStatement","src":"3706:52:0"}]},"documentation":{"id":358,"nodeType":"StructuredDocumentation","src":"3533:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"3631:5:0","parameters":{"id":361,"nodeType":"ParameterList","parameters":[{"constant":false,"id":360,"mutability":"mutable","name":"_v","nameLocation":"3653:2:0","nodeType":"VariableDeclaration","scope":381,"src":"3637:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":359,"name":"string","nodeType":"ElementaryTypeName","src":"3637:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"3636:20:0"},"returnParameters":{"id":362,"nodeType":"ParameterList","parameters":[],"src":"3671:0:0"},"scope":382,"stateMutability":"view","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[],"contractKind":"contract","documentation":{"id":174,"nodeType":"StructuredDocumentation","src":"2192:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[382],"name":"ScriptExample","nameLocation":"2327:13:0","scope":383,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file +{"abi":[{"type":"function","name":"broadcast","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"envOr","inputs":[{"name":"name","type":"string","internalType":"string"},{"name":"defaultValue","type":"bool","internalType":"bool"}],"outputs":[{"name":"value","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"getNonce","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"nonce","type":"uint64","internalType":"uint64"}],"stateMutability":"view"},{"type":"function","name":"parseJsonKeys","inputs":[{"name":"json","type":"string","internalType":"string"},{"name":"key","type":"string","internalType":"string"}],"outputs":[{"name":"keys","type":"string[]","internalType":"string[]"}],"stateMutability":"pure"},{"type":"function","name":"startBroadcast","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"startPrank","inputs":[{"name":"msgSender","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"stopBroadcast","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"stopPrank","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{"broadcast()":"afc98040","envOr(string,bool)":"4777f3cf","getNonce(address)":"2d0335ab","parseJsonKeys(string,string)":"213e4198","startBroadcast()":"7fb5297f","startPrank(address)":"06447d56","stopBroadcast()":"76eadd36","stopPrank()":"90c5013b"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"broadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"defaultValue\",\"type\":\"bool\"}],\"name\":\"envOr\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"json\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"}],\"name\":\"parseJsonKeys\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"keys\",\"type\":\"string[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startBroadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"msgSender\",\"type\":\"address\"}],\"name\":\"startPrank\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stopBroadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stopPrank\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"Vm\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x7727e5a55f4b3d442729483d41848c957b04027e48d972a568ee6f50aa3daa7a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4de8bd2d73869b583c44f8996ef56f872ce47499e801aa95da90a8e695196b00\",\"dweb:/ipfs/QmZzQy8ZSWuMnLBsGWTxUxZRhWGTJ8cq8yHpM59irYA2dw\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"broadcast"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"bool","name":"defaultValue","type":"bool"}],"stateMutability":"view","type":"function","name":"envOr","outputs":[{"internalType":"bool","name":"value","type":"bool"}]},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"stateMutability":"view","type":"function","name":"getNonce","outputs":[{"internalType":"uint64","name":"nonce","type":"uint64"}]},{"inputs":[{"internalType":"string","name":"json","type":"string"},{"internalType":"string","name":"key","type":"string"}],"stateMutability":"pure","type":"function","name":"parseJsonKeys","outputs":[{"internalType":"string[]","name":"keys","type":"string[]"}]},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"startBroadcast"},{"inputs":[{"internalType":"address","name":"msgSender","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"startPrank"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"stopBroadcast"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"stopPrank"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"Vm"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x7727e5a55f4b3d442729483d41848c957b04027e48d972a568ee6f50aa3daa7a","urls":["bzz-raw://4de8bd2d73869b583c44f8996ef56f872ce47499e801aa95da90a8e695196b00","dweb:/ipfs/QmZzQy8ZSWuMnLBsGWTxUxZRhWGTJ8cq8yHpM59irYA2dw"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[],"types":{}},"userdoc":{"version":1,"kind":"user"},"devdoc":{"version":1,"kind":"dev"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":538,"exportedSymbols":{"ScriptExample":[537],"Vm":[45],"console":[182]},"nodeType":"SourceUnit","src":"32:4932:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":45,"nodeType":"ContractDefinition","src":"120:507:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":45,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":45,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":45,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":38,"nodeType":"FunctionDefinition","src":"516:30:0","nodes":[],"functionSelector":"afc98040","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"525:9:0","parameters":{"id":36,"nodeType":"ParameterList","parameters":[],"src":"534:2:0"},"returnParameters":{"id":37,"nodeType":"ParameterList","parameters":[],"src":"545:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":41,"nodeType":"FunctionDefinition","src":"551:35:0","nodes":[],"functionSelector":"7fb5297f","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"560:14:0","parameters":{"id":39,"nodeType":"ParameterList","parameters":[],"src":"574:2:0"},"returnParameters":{"id":40,"nodeType":"ParameterList","parameters":[],"src":"585:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":44,"nodeType":"FunctionDefinition","src":"591:34:0","nodes":[],"functionSelector":"76eadd36","implemented":false,"kind":"function","modifiers":[],"name":"stopBroadcast","nameLocation":"600:13:0","parameters":{"id":42,"nodeType":"ParameterList","parameters":[],"src":"613:2:0"},"returnParameters":{"id":43,"nodeType":"ParameterList","parameters":[],"src":"624:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[45],"name":"Vm","nameLocation":"130:2:0","scope":538,"usedErrors":[]},{"id":182,"nodeType":"ContractDefinition","src":"682:1622:0","nodes":[{"id":51,"nodeType":"VariableDeclaration","src":"704:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"721:15:0","scope":182,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":46,"name":"address","nodeType":"ElementaryTypeName","src":"704:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":49,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"747:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":48,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"739:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":47,"name":"address","nodeType":"ElementaryTypeName","src":"739:7:0","typeDescriptions":{}}},"id":50,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"739:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":68,"nodeType":"FunctionDefinition","src":"797:221:0","nodes":[],"body":{"id":67,"nodeType":"Block","src":"956:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"975:37:0","statements":[{"nodeType":"YulAssignment","src":"989:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"998:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"989:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":57,"isOffset":false,"isSlot":false,"src":"998:4:0","valueSize":1},{"declaration":64,"isOffset":false,"isSlot":false,"src":"989:5:0","valueSize":1}],"id":66,"nodeType":"InlineAssembly","src":"966:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"806:25:0","parameters":{"id":58,"nodeType":"ParameterList","parameters":[{"constant":false,"id":57,"mutability":"mutable","name":"fnIn","nameLocation":"878:4:0","nodeType":"VariableDeclaration","scope":68,"src":"841:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":56,"nodeType":"FunctionTypeName","parameterTypes":{"id":54,"nodeType":"ParameterList","parameters":[{"constant":false,"id":53,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":56,"src":"850:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":52,"name":"bytes","nodeType":"ElementaryTypeName","src":"850:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"849:14:0"},"returnParameterTypes":{"id":55,"nodeType":"ParameterList","parameters":[],"src":"878:0:0"},"src":"841:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"831:57:0"},"returnParameters":{"id":65,"nodeType":"ParameterList","parameters":[{"constant":false,"id":64,"mutability":"mutable","name":"fnOut","nameLocation":"949:5:0","nodeType":"VariableDeclaration","scope":68,"src":"912:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":63,"nodeType":"FunctionTypeName","parameterTypes":{"id":61,"nodeType":"ParameterList","parameters":[{"constant":false,"id":60,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":63,"src":"921:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":59,"name":"bytes","nodeType":"ElementaryTypeName","src":"921:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"920:14:0"},"returnParameterTypes":{"id":62,"nodeType":"ParameterList","parameters":[],"src":"949:0:0"},"src":"912:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"911:44:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":80,"nodeType":"FunctionDefinition","src":"1024:133:0","nodes":[],"body":{"id":79,"nodeType":"Block","src":"1085:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":76,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":70,"src":"1142:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":74,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":96,"src":"1121:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":73,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":68,"src":"1095:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":75,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1095:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":77,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1095:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":78,"nodeType":"ExpressionStatement","src":"1095:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"1033:15:0","parameters":{"id":71,"nodeType":"ParameterList","parameters":[{"constant":false,"id":70,"mutability":"mutable","name":"payload","nameLocation":"1062:7:0","nodeType":"VariableDeclaration","scope":80,"src":"1049:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":69,"name":"bytes","nodeType":"ElementaryTypeName","src":"1049:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1048:22:0"},"returnParameters":{"id":72,"nodeType":"ParameterList","parameters":[],"src":"1085:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":96,"nodeType":"FunctionDefinition","src":"1163:380:0","nodes":[],"body":{"id":95,"nodeType":"Block","src":"1227:316:0","nodes":[],"statements":[{"assignments":[86],"declarations":[{"constant":false,"id":86,"mutability":"mutable","name":"payloadLength","nameLocation":"1245:13:0","nodeType":"VariableDeclaration","scope":95,"src":"1237:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":85,"name":"uint256","nodeType":"ElementaryTypeName","src":"1237:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":89,"initialValue":{"expression":{"id":87,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":82,"src":"1261:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":88,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1261:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1237:38:0"},{"assignments":[91],"declarations":[{"constant":false,"id":91,"mutability":"mutable","name":"consoleAddress","nameLocation":"1293:14:0","nodeType":"VariableDeclaration","scope":95,"src":"1285:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":90,"name":"address","nodeType":"ElementaryTypeName","src":"1285:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":93,"initialValue":{"id":92,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":51,"src":"1310:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1285:40:0"},{"AST":{"nodeType":"YulBlock","src":"1387:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1401:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1425:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1434:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1421:3:0"},"nodeType":"YulFunctionCall","src":"1421:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1405:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1450:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1470:3:0"},"nodeType":"YulFunctionCall","src":"1470:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1477:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1493:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1507:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1522:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1525:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1459:10:0"},"nodeType":"YulFunctionCall","src":"1459:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1454:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":91,"isOffset":false,"isSlot":false,"src":"1477:14:0","valueSize":1},{"declaration":82,"isOffset":false,"isSlot":false,"src":"1425:7:0","valueSize":1},{"declaration":86,"isOffset":false,"isSlot":false,"src":"1507:13:0","valueSize":1}],"id":94,"nodeType":"InlineAssembly","src":"1378:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1172:19:0","parameters":{"id":83,"nodeType":"ParameterList","parameters":[{"constant":false,"id":82,"mutability":"mutable","name":"payload","nameLocation":"1205:7:0","nodeType":"VariableDeclaration","scope":96,"src":"1192:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":81,"name":"bytes","nodeType":"ElementaryTypeName","src":"1192:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1191:22:0"},"returnParameters":{"id":84,"nodeType":"ParameterList","parameters":[],"src":"1227:0:0"},"scope":182,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":110,"nodeType":"FunctionDefinition","src":"1549:121:0","nodes":[],"body":{"id":109,"nodeType":"Block","src":"1594:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":104,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1644:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":105,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":98,"src":"1659:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":102,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1620:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":103,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1620:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":106,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1620:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":101,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1604:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":107,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1604:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":108,"nodeType":"ExpressionStatement","src":"1604:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1558:3:0","parameters":{"id":99,"nodeType":"ParameterList","parameters":[{"constant":false,"id":98,"mutability":"mutable","name":"p0","nameLocation":"1576:2:0","nodeType":"VariableDeclaration","scope":110,"src":"1562:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":97,"name":"string","nodeType":"ElementaryTypeName","src":"1562:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1561:18:0"},"returnParameters":{"id":100,"nodeType":"ParameterList","parameters":[],"src":"1594:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":127,"nodeType":"FunctionDefinition","src":"1676:139:0","nodes":[],"body":{"id":126,"nodeType":"Block","src":"1730:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":120,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1780:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":121,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":112,"src":"1800:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":122,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":114,"src":"1804:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":118,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1756:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":119,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1756:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":123,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1756:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":117,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1740:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":124,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1740:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":125,"nodeType":"ExpressionStatement","src":"1740:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1685:3:0","parameters":{"id":115,"nodeType":"ParameterList","parameters":[{"constant":false,"id":112,"mutability":"mutable","name":"p0","nameLocation":"1703:2:0","nodeType":"VariableDeclaration","scope":127,"src":"1689:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":111,"name":"string","nodeType":"ElementaryTypeName","src":"1689:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":114,"mutability":"mutable","name":"p1","nameLocation":"1712:2:0","nodeType":"VariableDeclaration","scope":127,"src":"1707:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":113,"name":"bool","nodeType":"ElementaryTypeName","src":"1707:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1688:27:0"},"returnParameters":{"id":116,"nodeType":"ParameterList","parameters":[],"src":"1730:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":144,"nodeType":"FunctionDefinition","src":"1821:145:0","nodes":[],"body":{"id":143,"nodeType":"Block","src":"1878:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":137,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1928:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":138,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":129,"src":"1951:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":139,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":131,"src":"1955:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":135,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1904:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":136,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1904:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":140,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1904:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":134,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1888:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":141,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1888:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":142,"nodeType":"ExpressionStatement","src":"1888:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1830:3:0","parameters":{"id":132,"nodeType":"ParameterList","parameters":[{"constant":false,"id":129,"mutability":"mutable","name":"p0","nameLocation":"1848:2:0","nodeType":"VariableDeclaration","scope":144,"src":"1834:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":128,"name":"string","nodeType":"ElementaryTypeName","src":"1834:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":131,"mutability":"mutable","name":"p1","nameLocation":"1860:2:0","nodeType":"VariableDeclaration","scope":144,"src":"1852:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":130,"name":"uint256","nodeType":"ElementaryTypeName","src":"1852:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1833:30:0"},"returnParameters":{"id":133,"nodeType":"ParameterList","parameters":[],"src":"1878:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":161,"nodeType":"FunctionDefinition","src":"1972:145:0","nodes":[],"body":{"id":160,"nodeType":"Block","src":"2029:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":154,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2079:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":155,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":146,"src":"2102:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":156,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":148,"src":"2106:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":152,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2055:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":153,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2055:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":157,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2055:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":151,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"2039:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":158,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2039:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":159,"nodeType":"ExpressionStatement","src":"2039:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1981:3:0","parameters":{"id":149,"nodeType":"ParameterList","parameters":[{"constant":false,"id":146,"mutability":"mutable","name":"p0","nameLocation":"1999:2:0","nodeType":"VariableDeclaration","scope":161,"src":"1985:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":145,"name":"string","nodeType":"ElementaryTypeName","src":"1985:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":148,"mutability":"mutable","name":"p1","nameLocation":"2011:2:0","nodeType":"VariableDeclaration","scope":161,"src":"2003:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":147,"name":"address","nodeType":"ElementaryTypeName","src":"2003:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1984:30:0"},"returnParameters":{"id":150,"nodeType":"ParameterList","parameters":[],"src":"2029:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":181,"nodeType":"FunctionDefinition","src":"2123:179:0","nodes":[],"body":{"id":180,"nodeType":"Block","src":"2204:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":173,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2254:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":174,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":163,"src":"2283:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":175,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":165,"src":"2287:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":176,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":167,"src":"2291:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":171,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2230:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":172,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2230:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":177,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2230:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":170,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"2214:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":178,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2214:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":179,"nodeType":"ExpressionStatement","src":"2214:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2132:3:0","parameters":{"id":168,"nodeType":"ParameterList","parameters":[{"constant":false,"id":163,"mutability":"mutable","name":"p0","nameLocation":"2150:2:0","nodeType":"VariableDeclaration","scope":181,"src":"2136:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":162,"name":"string","nodeType":"ElementaryTypeName","src":"2136:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":165,"mutability":"mutable","name":"p1","nameLocation":"2168:2:0","nodeType":"VariableDeclaration","scope":181,"src":"2154:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":164,"name":"string","nodeType":"ElementaryTypeName","src":"2154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":167,"mutability":"mutable","name":"p2","nameLocation":"2186:2:0","nodeType":"VariableDeclaration","scope":181,"src":"2172:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":166,"name":"string","nodeType":"ElementaryTypeName","src":"2172:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2135:54:0"},"returnParameters":{"id":169,"nodeType":"ParameterList","parameters":[],"src":"2204:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[182],"name":"console","nameLocation":"690:7:0","scope":538,"usedErrors":[]},{"id":537,"nodeType":"ContractDefinition","src":"2432:2531:0","nodes":[{"id":197,"nodeType":"VariableDeclaration","src":"2462:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2488:10:0","scope":537,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":184,"name":"address","nodeType":"ElementaryTypeName","src":"2462:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":192,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2535:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":191,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2525:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":193,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2525:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":190,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2517:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":189,"name":"uint256","nodeType":"ElementaryTypeName","src":"2517:7:0","typeDescriptions":{}}},"id":194,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2517:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":188,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2509:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":187,"name":"uint160","nodeType":"ElementaryTypeName","src":"2509:7:0","typeDescriptions":{}}},"id":195,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2509:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":186,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2501:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":185,"name":"address","nodeType":"ElementaryTypeName","src":"2501:7:0","typeDescriptions":{}}},"id":196,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2501:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":203,"nodeType":"VariableDeclaration","src":"2562:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2583:2:0","scope":537,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"},"typeName":{"id":199,"nodeType":"UserDefinedTypeName","pathNode":{"id":198,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":45,"src":"2562:2:0"},"referencedDeclaration":45,"src":"2562:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"value":{"arguments":[{"id":201,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":197,"src":"2591:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":200,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":45,"src":"2588:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$45_$","typeString":"type(contract Vm)"}},"id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2588:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"visibility":"internal"},{"id":205,"nodeType":"VariableDeclaration","src":"2666:22:0","nodes":[],"constant":false,"functionSelector":"61bc221a","mutability":"mutable","name":"counter","nameLocation":"2681:7:0","scope":537,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":204,"name":"uint256","nodeType":"ElementaryTypeName","src":"2666:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":368,"nodeType":"FunctionDefinition","src":"2778:949:0","nodes":[],"body":{"id":367,"nodeType":"Block","src":"2800:927:0","nodes":[],"statements":[{"assignments":[210],"declarations":[{"constant":false,"id":210,"mutability":"mutable","name":"x","nameLocation":"2815:1:0","nodeType":"VariableDeclaration","scope":367,"src":"2810:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":209,"name":"bool","nodeType":"ElementaryTypeName","src":"2810:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":216,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":213,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2828:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":214,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2844:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":211,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"2819:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":212,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2819:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":215,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2819:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2810:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":220,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2872:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":221,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":210,"src":"2895:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":217,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"2860:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":219,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":127,"src":"2860:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":222,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2860:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":223,"nodeType":"ExpressionStatement","src":"2860:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":227,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2920:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":230,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"2945:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}],"id":229,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2937:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":228,"name":"address","nodeType":"ElementaryTypeName","src":"2937:7:0","typeDescriptions":{}}},"id":231,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2937:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":224,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"2908:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":226,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"2908:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2908:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":233,"nodeType":"ExpressionStatement","src":"2908:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":237,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2973:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":242,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3011:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}],"id":241,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3003:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":240,"name":"address","nodeType":"ElementaryTypeName","src":"3003:7:0","typeDescriptions":{}}},"id":243,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3003:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":238,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"2991:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":239,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"2991:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":244,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2991:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":234,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"2961:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":236,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":144,"src":"2961:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":245,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2961:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":246,"nodeType":"ExpressionStatement","src":"2961:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":250,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3040:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":253,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3063:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":254,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3063:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":252,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3055:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":251,"name":"address","nodeType":"ElementaryTypeName","src":"3055:7:0","typeDescriptions":{}}},"id":255,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3055:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":247,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3028:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"3028:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":256,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3028:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":257,"nodeType":"ExpressionStatement","src":"3028:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":261,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3097:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":266,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3133:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":267,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3133:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":265,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3125:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":264,"name":"address","nodeType":"ElementaryTypeName","src":"3125:7:0","typeDescriptions":{}}},"id":268,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3125:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":262,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3113:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":263,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3113:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":269,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3113:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":258,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3085:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":260,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":144,"src":"3085:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":270,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3085:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":271,"nodeType":"ExpressionStatement","src":"3085:61:0"},{"assignments":[273],"declarations":[{"constant":false,"id":273,"mutability":"mutable","name":"json","nameLocation":"3171:4:0","nodeType":"VariableDeclaration","scope":367,"src":"3157:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":272,"name":"string","nodeType":"ElementaryTypeName","src":"3157:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":275,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":274,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3178:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"3157:55:0"},{"assignments":[280],"declarations":[{"constant":false,"id":280,"mutability":"mutable","name":"keys","nameLocation":"3238:4:0","nodeType":"VariableDeclaration","scope":367,"src":"3222:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":278,"name":"string","nodeType":"ElementaryTypeName","src":"3222:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":279,"nodeType":"ArrayTypeName","src":"3222:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":286,"initialValue":{"arguments":[{"id":283,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":273,"src":"3262:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3268:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":281,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3245:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":282,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3245:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":285,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3245:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3222:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":290,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3305:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":291,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":280,"src":"3313:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":293,"indexExpression":{"hexValue":"30","id":292,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3318:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3313:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":294,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":280,"src":"3322:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":296,"indexExpression":{"hexValue":"31","id":295,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3327:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3322:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":287,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3293:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":289,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":181,"src":"3293:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":297,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3293:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":298,"nodeType":"ExpressionStatement","src":"3293:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3352:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":299,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3341:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":301,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3341:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":303,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3341:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":304,"nodeType":"ExpressionStatement","src":"3341:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":312,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3408:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":311,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3400:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":310,"name":"uint160","nodeType":"ElementaryTypeName","src":"3400:7:0","typeDescriptions":{}}},"id":313,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3400:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":309,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3392:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":308,"name":"address","nodeType":"ElementaryTypeName","src":"3392:7:0","typeDescriptions":{}}},"id":314,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3392:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":305,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3378:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":307,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3378:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":315,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3378:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":316,"nodeType":"ExpressionStatement","src":"3378:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":320,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3436:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":317,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3425:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":319,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3425:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":321,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3425:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":322,"nodeType":"ExpressionStatement","src":"3425:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":326,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3473:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":329,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3508:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":330,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3508:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":328,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3500:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":327,"name":"address","nodeType":"ElementaryTypeName","src":"3500:7:0","typeDescriptions":{}}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3500:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":323,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3461:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"3461:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":332,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3461:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":333,"nodeType":"ExpressionStatement","src":"3461:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":337,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3542:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":340,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3580:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}],"id":339,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3572:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":338,"name":"address","nodeType":"ElementaryTypeName","src":"3572:7:0","typeDescriptions":{}}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3572:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":334,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3530:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":336,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"3530:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3530:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3530:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3607:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":344,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3596:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3596:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":348,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3596:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":349,"nodeType":"ExpressionStatement","src":"3596:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":350,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3632:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3632:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":353,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3632:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":354,"nodeType":"ExpressionStatement","src":"3632:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":358,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3667:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":355,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3656:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":357,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3656:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":359,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3656:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":360,"nodeType":"ExpressionStatement","src":"3656:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":364,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3712:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":361,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3700:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":363,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"3700:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":365,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3700:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":366,"nodeType":"ExpressionStatement","src":"3700:20:0"}]},"documentation":{"id":206,"nodeType":"StructuredDocumentation","src":"2695:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2787:3:0","parameters":{"id":207,"nodeType":"ParameterList","parameters":[],"src":"2790:2:0"},"returnParameters":{"id":208,"nodeType":"ParameterList","parameters":[],"src":"2800:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":452,"nodeType":"FunctionDefinition","src":"3794:520:0","nodes":[],"body":{"id":451,"nodeType":"Block","src":"3825:489:0","nodes":[],"statements":[{"expression":{"arguments":[{"hexValue":"74657374696e672073696e676c65","id":375,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3847:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""},"value":"testing single"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""}],"expression":{"id":372,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3835:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":374,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"3835:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":376,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3835:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":377,"nodeType":"ExpressionStatement","src":"3835:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":378,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3874:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":380,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"3874:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":381,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3874:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":382,"nodeType":"ExpressionStatement","src":"3874:14:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c31","id":386,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3909:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""},"value":"single_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""}],"expression":{"id":383,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3898:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":385,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":491,"src":"3898:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":387,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3898:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":388,"nodeType":"ExpressionStatement","src":"3898:26:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c32","id":392,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3945:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""},"value":"single_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""}],"expression":{"id":389,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3934:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":391,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":506,"src":"3934:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":393,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3934:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":394,"nodeType":"ExpressionStatement","src":"3934:26:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073746172742f73746f70","id":398,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3983:20:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""},"value":"testing start/stop"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""}],"expression":{"id":395,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3971:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":397,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"3971:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":399,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3971:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":400,"nodeType":"ExpressionStatement","src":"3971:33:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":401,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4014:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":403,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":41,"src":"4014:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":404,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4014:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":405,"nodeType":"ExpressionStatement","src":"4014:19:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c31","id":409,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4054:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""},"value":"startstop_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""}],"expression":{"id":406,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4043:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":408,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":491,"src":"4043:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":410,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4043:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":411,"nodeType":"ExpressionStatement","src":"4043:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c32","id":415,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4093:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""},"value":"startstop_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""}],"expression":{"id":412,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4082:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":414,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":506,"src":"4082:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":416,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4082:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":417,"nodeType":"ExpressionStatement","src":"4082:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":418,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4121:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":420,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":44,"src":"4121:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":421,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4121:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":422,"nodeType":"ExpressionStatement","src":"4121:18:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c33","id":426,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4160:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""},"value":"startstop_call3"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""}],"expression":{"id":423,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4149:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":425,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":491,"src":"4149:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":427,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4149:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":428,"nodeType":"ExpressionStatement","src":"4149:29:0"},{"expression":{"arguments":[{"hexValue":"74657374696e67206e6573746564","id":432,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4201:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""},"value":"testing nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""}],"expression":{"id":429,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4189:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":431,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4189:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":433,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4189:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":434,"nodeType":"ExpressionStatement","src":"4189:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":435,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4228:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":437,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":41,"src":"4228:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":438,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4228:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":439,"nodeType":"ExpressionStatement","src":"4228:19:0"},{"expression":{"arguments":[{"hexValue":"6e6573746564","id":443,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4270:8:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""},"value":"nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""}],"expression":{"id":440,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4257:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":442,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested1","nodeType":"MemberAccess","referencedDeclaration":521,"src":"4257:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":444,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4257:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":445,"nodeType":"ExpressionStatement","src":"4257:22:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":446,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4289:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":448,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":44,"src":"4289:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":449,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4289:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":450,"nodeType":"ExpressionStatement","src":"4289:18:0"}]},"documentation":{"id":369,"nodeType":"StructuredDocumentation","src":"3733:56:0","text":"@notice example function, to test vm.broadcast with."},"functionSelector":"bef03abc","implemented":true,"kind":"function","modifiers":[],"name":"runBroadcast","nameLocation":"3803:12:0","parameters":{"id":370,"nodeType":"ParameterList","parameters":[],"src":"3815:2:0"},"returnParameters":{"id":371,"nodeType":"ParameterList","parameters":[],"src":"3825:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":476,"nodeType":"FunctionDefinition","src":"4409:143:0","nodes":[],"body":{"id":475,"nodeType":"Block","src":"4458:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":461,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":455,"src":"4480:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":458,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4468:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":460,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4468:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":462,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4468:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":463,"nodeType":"ExpressionStatement","src":"4468:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":467,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4505:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":470,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"4533:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":471,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"4533:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":469,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4525:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":468,"name":"address","nodeType":"ElementaryTypeName","src":"4525:7:0","typeDescriptions":{}}},"id":472,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4525:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":464,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4493:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":466,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"4493:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":473,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4493:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":474,"nodeType":"ExpressionStatement","src":"4493:52:0"}]},"documentation":{"id":453,"nodeType":"StructuredDocumentation","src":"4320:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"4418:5:0","parameters":{"id":456,"nodeType":"ParameterList","parameters":[{"constant":false,"id":455,"mutability":"mutable","name":"_v","nameLocation":"4440:2:0","nodeType":"VariableDeclaration","scope":476,"src":"4424:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":454,"name":"string","nodeType":"ElementaryTypeName","src":"4424:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4423:20:0"},"returnParameters":{"id":457,"nodeType":"ParameterList","parameters":[],"src":"4458:0:0"},"scope":537,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":491,"nodeType":"FunctionDefinition","src":"4558:95:0","nodes":[],"body":{"id":490,"nodeType":"Block","src":"4602:51:0","nodes":[],"statements":[{"expression":{"id":482,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4612:9:0","subExpression":{"id":481,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4612:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":483,"nodeType":"ExpressionStatement","src":"4612:9:0"},{"expression":{"arguments":[{"id":487,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":478,"src":"4643:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":484,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4631:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":486,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4631:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":488,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4631:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":489,"nodeType":"ExpressionStatement","src":"4631:15:0"}]},"functionSelector":"7e79255d","implemented":true,"kind":"function","modifiers":[],"name":"call1","nameLocation":"4567:5:0","parameters":{"id":479,"nodeType":"ParameterList","parameters":[{"constant":false,"id":478,"mutability":"mutable","name":"_v","nameLocation":"4589:2:0","nodeType":"VariableDeclaration","scope":491,"src":"4573:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":477,"name":"string","nodeType":"ElementaryTypeName","src":"4573:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4572:20:0"},"returnParameters":{"id":480,"nodeType":"ParameterList","parameters":[],"src":"4602:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":506,"nodeType":"FunctionDefinition","src":"4659:95:0","nodes":[],"body":{"id":505,"nodeType":"Block","src":"4703:51:0","nodes":[],"statements":[{"expression":{"id":497,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4713:9:0","subExpression":{"id":496,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4713:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":498,"nodeType":"ExpressionStatement","src":"4713:9:0"},{"expression":{"arguments":[{"id":502,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":493,"src":"4744:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":499,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4732:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":501,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4732:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":503,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4732:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":504,"nodeType":"ExpressionStatement","src":"4732:15:0"}]},"functionSelector":"8d3ef7ca","implemented":true,"kind":"function","modifiers":[],"name":"call2","nameLocation":"4668:5:0","parameters":{"id":494,"nodeType":"ParameterList","parameters":[{"constant":false,"id":493,"mutability":"mutable","name":"_v","nameLocation":"4690:2:0","nodeType":"VariableDeclaration","scope":506,"src":"4674:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":492,"name":"string","nodeType":"ElementaryTypeName","src":"4674:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4673:20:0"},"returnParameters":{"id":495,"nodeType":"ParameterList","parameters":[],"src":"4703:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":521,"nodeType":"FunctionDefinition","src":"4760:98:0","nodes":[],"body":{"id":520,"nodeType":"Block","src":"4806:52:0","nodes":[],"statements":[{"expression":{"id":512,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4816:9:0","subExpression":{"id":511,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4816:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":513,"nodeType":"ExpressionStatement","src":"4816:9:0"},{"expression":{"arguments":[{"id":517,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":508,"src":"4848:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":514,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4835:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":516,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested2","nodeType":"MemberAccess","referencedDeclaration":536,"src":"4835:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":518,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4835:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":519,"nodeType":"ExpressionStatement","src":"4835:16:0"}]},"functionSelector":"a76ccdfa","implemented":true,"kind":"function","modifiers":[],"name":"nested1","nameLocation":"4769:7:0","parameters":{"id":509,"nodeType":"ParameterList","parameters":[{"constant":false,"id":508,"mutability":"mutable","name":"_v","nameLocation":"4793:2:0","nodeType":"VariableDeclaration","scope":521,"src":"4777:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":507,"name":"string","nodeType":"ElementaryTypeName","src":"4777:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4776:20:0"},"returnParameters":{"id":510,"nodeType":"ParameterList","parameters":[],"src":"4806:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":536,"nodeType":"FunctionDefinition","src":"4864:97:0","nodes":[],"body":{"id":535,"nodeType":"Block","src":"4910:51:0","nodes":[],"statements":[{"expression":{"id":527,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4920:9:0","subExpression":{"id":526,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4920:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":528,"nodeType":"ExpressionStatement","src":"4920:9:0"},{"expression":{"arguments":[{"id":532,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":523,"src":"4951:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":529,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4939:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":531,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4939:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":533,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4939:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":534,"nodeType":"ExpressionStatement","src":"4939:15:0"}]},"functionSelector":"dbf1282f","implemented":true,"kind":"function","modifiers":[],"name":"nested2","nameLocation":"4873:7:0","parameters":{"id":524,"nodeType":"ParameterList","parameters":[{"constant":false,"id":523,"mutability":"mutable","name":"_v","nameLocation":"4897:2:0","nodeType":"VariableDeclaration","scope":536,"src":"4881:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":522,"name":"string","nodeType":"ElementaryTypeName","src":"4881:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4880:20:0"},"returnParameters":{"id":525,"nodeType":"ParameterList","parameters":[],"src":"4910:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[],"contractKind":"contract","documentation":{"id":183,"nodeType":"StructuredDocumentation","src":"2306:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[537],"name":"ScriptExample","nameLocation":"2441:13:0","scope":538,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file diff --git a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/console.json b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/console.json index 23641034487b..25387bcbbdbf 100644 --- a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/console.json +++ b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/console.json @@ -1 +1 @@ -{"abi":[],"bytecode":{"object":"0x602d6037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300080f000a","sourceMap":"568:1622:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;568:1622:0;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300080f000a","sourceMap":"568:1622:0:-:0;;;;;;;;","linkReferences":{}},"methodIdentifiers":{},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"console\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x531a2ad96c1a2c0bbfa9ab0e1195cd32551b0c10e16e7d256ce5e4c0289a8089\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://24dc6c71502c01f43fb5e113786e377c3b4cafabd5c506067d229fcdd7b037fa\",\"dweb:/ipfs/QmZ9AuxNx9Ygescfg5M4p6Abc2CCwCMZpX5xU32Fz1r4kY\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"console"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x531a2ad96c1a2c0bbfa9ab0e1195cd32551b0c10e16e7d256ce5e4c0289a8089","urls":["bzz-raw://24dc6c71502c01f43fb5e113786e377c3b4cafabd5c506067d229fcdd7b037fa","dweb:/ipfs/QmZ9AuxNx9Ygescfg5M4p6Abc2CCwCMZpX5xU32Fz1r4kY"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[],"types":{}},"userdoc":{"version":1,"kind":"user"},"devdoc":{"version":1,"kind":"dev"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":383,"exportedSymbols":{"ScriptExample":[382],"Vm":[36],"console":[173]},"nodeType":"SourceUnit","src":"32:3736:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":36,"nodeType":"ContractDefinition","src":"120:393:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":36,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":36,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":36,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":36,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":36,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[36],"name":"Vm","nameLocation":"130:2:0","scope":383,"usedErrors":[]},{"id":173,"nodeType":"ContractDefinition","src":"568:1622:0","nodes":[{"id":42,"nodeType":"VariableDeclaration","src":"590:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"607:15:0","scope":173,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":37,"name":"address","nodeType":"ElementaryTypeName","src":"590:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":40,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"633:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":39,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"625:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":38,"name":"address","nodeType":"ElementaryTypeName","src":"625:7:0","typeDescriptions":{}}},"id":41,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"625:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":59,"nodeType":"FunctionDefinition","src":"683:221:0","nodes":[],"body":{"id":58,"nodeType":"Block","src":"842:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"861:37:0","statements":[{"nodeType":"YulAssignment","src":"875:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"884:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"875:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":48,"isOffset":false,"isSlot":false,"src":"884:4:0","valueSize":1},{"declaration":55,"isOffset":false,"isSlot":false,"src":"875:5:0","valueSize":1}],"id":57,"nodeType":"InlineAssembly","src":"852:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"692:25:0","parameters":{"id":49,"nodeType":"ParameterList","parameters":[{"constant":false,"id":48,"mutability":"mutable","name":"fnIn","nameLocation":"764:4:0","nodeType":"VariableDeclaration","scope":59,"src":"727:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":47,"nodeType":"FunctionTypeName","parameterTypes":{"id":45,"nodeType":"ParameterList","parameters":[{"constant":false,"id":44,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":47,"src":"736:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":43,"name":"bytes","nodeType":"ElementaryTypeName","src":"736:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"735:14:0"},"returnParameterTypes":{"id":46,"nodeType":"ParameterList","parameters":[],"src":"764:0:0"},"src":"727:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"717:57:0"},"returnParameters":{"id":56,"nodeType":"ParameterList","parameters":[{"constant":false,"id":55,"mutability":"mutable","name":"fnOut","nameLocation":"835:5:0","nodeType":"VariableDeclaration","scope":59,"src":"798:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":54,"nodeType":"FunctionTypeName","parameterTypes":{"id":52,"nodeType":"ParameterList","parameters":[{"constant":false,"id":51,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":54,"src":"807:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":50,"name":"bytes","nodeType":"ElementaryTypeName","src":"807:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"806:14:0"},"returnParameterTypes":{"id":53,"nodeType":"ParameterList","parameters":[],"src":"835:0:0"},"src":"798:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"797:44:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":71,"nodeType":"FunctionDefinition","src":"910:133:0","nodes":[],"body":{"id":70,"nodeType":"Block","src":"971:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":67,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":61,"src":"1028:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":65,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":87,"src":"1007:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":64,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":59,"src":"981:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":66,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"981:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":68,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"981:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":69,"nodeType":"ExpressionStatement","src":"981:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"919:15:0","parameters":{"id":62,"nodeType":"ParameterList","parameters":[{"constant":false,"id":61,"mutability":"mutable","name":"payload","nameLocation":"948:7:0","nodeType":"VariableDeclaration","scope":71,"src":"935:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":60,"name":"bytes","nodeType":"ElementaryTypeName","src":"935:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"934:22:0"},"returnParameters":{"id":63,"nodeType":"ParameterList","parameters":[],"src":"971:0:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":87,"nodeType":"FunctionDefinition","src":"1049:380:0","nodes":[],"body":{"id":86,"nodeType":"Block","src":"1113:316:0","nodes":[],"statements":[{"assignments":[77],"declarations":[{"constant":false,"id":77,"mutability":"mutable","name":"payloadLength","nameLocation":"1131:13:0","nodeType":"VariableDeclaration","scope":86,"src":"1123:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":76,"name":"uint256","nodeType":"ElementaryTypeName","src":"1123:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":80,"initialValue":{"expression":{"id":78,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":73,"src":"1147:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":79,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1147:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1123:38:0"},{"assignments":[82],"declarations":[{"constant":false,"id":82,"mutability":"mutable","name":"consoleAddress","nameLocation":"1179:14:0","nodeType":"VariableDeclaration","scope":86,"src":"1171:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":81,"name":"address","nodeType":"ElementaryTypeName","src":"1171:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":84,"initialValue":{"id":83,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":42,"src":"1196:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1171:40:0"},{"AST":{"nodeType":"YulBlock","src":"1273:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1287:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1311:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1320:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1307:3:0"},"nodeType":"YulFunctionCall","src":"1307:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1291:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1336:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1356:3:0"},"nodeType":"YulFunctionCall","src":"1356:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1363:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1379:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1393:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1408:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1411:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1345:10:0"},"nodeType":"YulFunctionCall","src":"1345:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1340:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":82,"isOffset":false,"isSlot":false,"src":"1363:14:0","valueSize":1},{"declaration":73,"isOffset":false,"isSlot":false,"src":"1311:7:0","valueSize":1},{"declaration":77,"isOffset":false,"isSlot":false,"src":"1393:13:0","valueSize":1}],"id":85,"nodeType":"InlineAssembly","src":"1264:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1058:19:0","parameters":{"id":74,"nodeType":"ParameterList","parameters":[{"constant":false,"id":73,"mutability":"mutable","name":"payload","nameLocation":"1091:7:0","nodeType":"VariableDeclaration","scope":87,"src":"1078:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":72,"name":"bytes","nodeType":"ElementaryTypeName","src":"1078:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1077:22:0"},"returnParameters":{"id":75,"nodeType":"ParameterList","parameters":[],"src":"1113:0:0"},"scope":173,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":101,"nodeType":"FunctionDefinition","src":"1435:121:0","nodes":[],"body":{"id":100,"nodeType":"Block","src":"1480:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":95,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1530:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":96,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":89,"src":"1545:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":93,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1506:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":94,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1506:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":97,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1506:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":92,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":71,"src":"1490:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":98,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1490:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":99,"nodeType":"ExpressionStatement","src":"1490:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1444:3:0","parameters":{"id":90,"nodeType":"ParameterList","parameters":[{"constant":false,"id":89,"mutability":"mutable","name":"p0","nameLocation":"1462:2:0","nodeType":"VariableDeclaration","scope":101,"src":"1448:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":88,"name":"string","nodeType":"ElementaryTypeName","src":"1448:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1447:18:0"},"returnParameters":{"id":91,"nodeType":"ParameterList","parameters":[],"src":"1480:0:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":118,"nodeType":"FunctionDefinition","src":"1562:139:0","nodes":[],"body":{"id":117,"nodeType":"Block","src":"1616:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":111,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1666:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":112,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":103,"src":"1686:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":113,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":105,"src":"1690:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":109,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1642:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":110,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1642:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":114,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1642:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":108,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":71,"src":"1626:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":115,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1626:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":116,"nodeType":"ExpressionStatement","src":"1626:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1571:3:0","parameters":{"id":106,"nodeType":"ParameterList","parameters":[{"constant":false,"id":103,"mutability":"mutable","name":"p0","nameLocation":"1589:2:0","nodeType":"VariableDeclaration","scope":118,"src":"1575:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":102,"name":"string","nodeType":"ElementaryTypeName","src":"1575:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":105,"mutability":"mutable","name":"p1","nameLocation":"1598:2:0","nodeType":"VariableDeclaration","scope":118,"src":"1593:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":104,"name":"bool","nodeType":"ElementaryTypeName","src":"1593:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1574:27:0"},"returnParameters":{"id":107,"nodeType":"ParameterList","parameters":[],"src":"1616:0:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":135,"nodeType":"FunctionDefinition","src":"1707:145:0","nodes":[],"body":{"id":134,"nodeType":"Block","src":"1764:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":128,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1814:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":129,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":120,"src":"1837:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":130,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":122,"src":"1841:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":126,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1790:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":127,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1790:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":131,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1790:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":125,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":71,"src":"1774:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":132,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1774:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":133,"nodeType":"ExpressionStatement","src":"1774:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1716:3:0","parameters":{"id":123,"nodeType":"ParameterList","parameters":[{"constant":false,"id":120,"mutability":"mutable","name":"p0","nameLocation":"1734:2:0","nodeType":"VariableDeclaration","scope":135,"src":"1720:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":119,"name":"string","nodeType":"ElementaryTypeName","src":"1720:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":122,"mutability":"mutable","name":"p1","nameLocation":"1746:2:0","nodeType":"VariableDeclaration","scope":135,"src":"1738:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":121,"name":"uint256","nodeType":"ElementaryTypeName","src":"1738:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1719:30:0"},"returnParameters":{"id":124,"nodeType":"ParameterList","parameters":[],"src":"1764:0:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":152,"nodeType":"FunctionDefinition","src":"1858:145:0","nodes":[],"body":{"id":151,"nodeType":"Block","src":"1915:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":145,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1965:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":146,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":137,"src":"1988:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":147,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":139,"src":"1992:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":143,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1941:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":144,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1941:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":148,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1941:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":142,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":71,"src":"1925:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":149,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1925:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":150,"nodeType":"ExpressionStatement","src":"1925:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1867:3:0","parameters":{"id":140,"nodeType":"ParameterList","parameters":[{"constant":false,"id":137,"mutability":"mutable","name":"p0","nameLocation":"1885:2:0","nodeType":"VariableDeclaration","scope":152,"src":"1871:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":136,"name":"string","nodeType":"ElementaryTypeName","src":"1871:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":139,"mutability":"mutable","name":"p1","nameLocation":"1897:2:0","nodeType":"VariableDeclaration","scope":152,"src":"1889:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":138,"name":"address","nodeType":"ElementaryTypeName","src":"1889:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1870:30:0"},"returnParameters":{"id":141,"nodeType":"ParameterList","parameters":[],"src":"1915:0:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":172,"nodeType":"FunctionDefinition","src":"2009:179:0","nodes":[],"body":{"id":171,"nodeType":"Block","src":"2090:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":164,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2140:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":165,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":154,"src":"2169:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":166,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":156,"src":"2173:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":167,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":158,"src":"2177:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":162,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2116:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":163,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2116:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":168,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2116:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":161,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":71,"src":"2100:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":169,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2100:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":170,"nodeType":"ExpressionStatement","src":"2100:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2018:3:0","parameters":{"id":159,"nodeType":"ParameterList","parameters":[{"constant":false,"id":154,"mutability":"mutable","name":"p0","nameLocation":"2036:2:0","nodeType":"VariableDeclaration","scope":172,"src":"2022:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":153,"name":"string","nodeType":"ElementaryTypeName","src":"2022:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":156,"mutability":"mutable","name":"p1","nameLocation":"2054:2:0","nodeType":"VariableDeclaration","scope":172,"src":"2040:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":155,"name":"string","nodeType":"ElementaryTypeName","src":"2040:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":158,"mutability":"mutable","name":"p2","nameLocation":"2072:2:0","nodeType":"VariableDeclaration","scope":172,"src":"2058:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":157,"name":"string","nodeType":"ElementaryTypeName","src":"2058:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2021:54:0"},"returnParameters":{"id":160,"nodeType":"ParameterList","parameters":[],"src":"2090:0:0"},"scope":173,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[173],"name":"console","nameLocation":"576:7:0","scope":383,"usedErrors":[]},{"id":382,"nodeType":"ContractDefinition","src":"2318:1449:0","nodes":[{"id":188,"nodeType":"VariableDeclaration","src":"2348:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2374:10:0","scope":382,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":175,"name":"address","nodeType":"ElementaryTypeName","src":"2348:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":183,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2421:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":182,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2411:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":184,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2411:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":181,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2403:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":180,"name":"uint256","nodeType":"ElementaryTypeName","src":"2403:7:0","typeDescriptions":{}}},"id":185,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2403:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":179,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2395:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":178,"name":"uint160","nodeType":"ElementaryTypeName","src":"2395:7:0","typeDescriptions":{}}},"id":186,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2395:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":177,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2387:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":176,"name":"address","nodeType":"ElementaryTypeName","src":"2387:7:0","typeDescriptions":{}}},"id":187,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2387:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":194,"nodeType":"VariableDeclaration","src":"2448:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2469:2:0","scope":382,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"},"typeName":{"id":190,"nodeType":"UserDefinedTypeName","pathNode":{"id":189,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":36,"src":"2448:2:0"},"referencedDeclaration":36,"src":"2448:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"value":{"arguments":[{"id":192,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":188,"src":"2477:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":191,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":36,"src":"2474:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$36_$","typeString":"type(contract Vm)"}},"id":193,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2474:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"visibility":"internal"},{"id":357,"nodeType":"FunctionDefinition","src":"2578:949:0","nodes":[],"body":{"id":356,"nodeType":"Block","src":"2600:927:0","nodes":[],"statements":[{"assignments":[199],"declarations":[{"constant":false,"id":199,"mutability":"mutable","name":"x","nameLocation":"2615:1:0","nodeType":"VariableDeclaration","scope":356,"src":"2610:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":198,"name":"bool","nodeType":"ElementaryTypeName","src":"2610:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":205,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2628:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":203,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2644:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":200,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":194,"src":"2619:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"id":201,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2619:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":204,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2619:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2610:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":209,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2672:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":210,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":199,"src":"2695:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":206,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2660:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":208,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":118,"src":"2660:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":211,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2660:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":212,"nodeType":"ExpressionStatement","src":"2660:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":216,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2720:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":219,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"2745:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}],"id":218,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2737:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":217,"name":"address","nodeType":"ElementaryTypeName","src":"2737:7:0","typeDescriptions":{}}},"id":220,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2737:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":213,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2708:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":215,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":152,"src":"2708:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":221,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2708:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":222,"nodeType":"ExpressionStatement","src":"2708:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":226,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2773:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":231,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"2811:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}],"id":230,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2803:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":229,"name":"address","nodeType":"ElementaryTypeName","src":"2803:7:0","typeDescriptions":{}}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2803:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":227,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":194,"src":"2791:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"id":228,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"2791:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":233,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2791:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":223,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2761:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":225,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":135,"src":"2761:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":234,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2761:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":235,"nodeType":"ExpressionStatement","src":"2761:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":239,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2840:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":242,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"2863:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":243,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"2863:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":241,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2855:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":240,"name":"address","nodeType":"ElementaryTypeName","src":"2855:7:0","typeDescriptions":{}}},"id":244,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2855:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":236,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2828:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":238,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":152,"src":"2828:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":245,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2828:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":246,"nodeType":"ExpressionStatement","src":"2828:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":250,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2897:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":255,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"2933:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":256,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"2933:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":254,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2925:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":253,"name":"address","nodeType":"ElementaryTypeName","src":"2925:7:0","typeDescriptions":{}}},"id":257,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2925:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":251,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":194,"src":"2913:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"id":252,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"2913:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":258,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2913:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":247,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2885:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":135,"src":"2885:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":259,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2885:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":260,"nodeType":"ExpressionStatement","src":"2885:61:0"},{"assignments":[262],"declarations":[{"constant":false,"id":262,"mutability":"mutable","name":"json","nameLocation":"2971:4:0","nodeType":"VariableDeclaration","scope":356,"src":"2957:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":261,"name":"string","nodeType":"ElementaryTypeName","src":"2957:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":264,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":263,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2978:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"2957:55:0"},{"assignments":[269],"declarations":[{"constant":false,"id":269,"mutability":"mutable","name":"keys","nameLocation":"3038:4:0","nodeType":"VariableDeclaration","scope":356,"src":"3022:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":267,"name":"string","nodeType":"ElementaryTypeName","src":"3022:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":268,"nodeType":"ArrayTypeName","src":"3022:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":275,"initialValue":{"arguments":[{"id":272,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":262,"src":"3062:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":273,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3068:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":270,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":194,"src":"3045:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"id":271,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3045:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":274,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3045:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3022:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":279,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3105:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":280,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":269,"src":"3113:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":282,"indexExpression":{"hexValue":"30","id":281,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3118:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3113:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":283,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":269,"src":"3122:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":285,"indexExpression":{"hexValue":"31","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3127:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3122:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":276,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"3093:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":278,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":172,"src":"3093:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":286,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3093:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":287,"nodeType":"ExpressionStatement","src":"3093:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":291,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3152:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":288,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3141:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}},"id":290,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":381,"src":"3141:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":292,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3141:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":293,"nodeType":"ExpressionStatement","src":"3141:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":301,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3208:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":300,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3200:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":299,"name":"uint160","nodeType":"ElementaryTypeName","src":"3200:7:0","typeDescriptions":{}}},"id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3200:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":298,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3192:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":297,"name":"address","nodeType":"ElementaryTypeName","src":"3192:7:0","typeDescriptions":{}}},"id":303,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3192:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":294,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":194,"src":"3178:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"id":296,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3178:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":304,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3178:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":305,"nodeType":"ExpressionStatement","src":"3178:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":309,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3236:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":306,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3225:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}},"id":308,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":381,"src":"3225:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":310,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3225:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":311,"nodeType":"ExpressionStatement","src":"3225:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":315,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3273:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":318,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3308:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":319,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3308:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":317,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3300:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":316,"name":"address","nodeType":"ElementaryTypeName","src":"3300:7:0","typeDescriptions":{}}},"id":320,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3300:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":312,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"3261:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":314,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":152,"src":"3261:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":321,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3261:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":322,"nodeType":"ExpressionStatement","src":"3261:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":326,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3342:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":329,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3380:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}],"id":328,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3372:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":327,"name":"address","nodeType":"ElementaryTypeName","src":"3372:7:0","typeDescriptions":{}}},"id":330,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3372:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":323,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"3330:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":152,"src":"3330:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3330:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":332,"nodeType":"ExpressionStatement","src":"3330:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":336,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3407:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":333,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3396:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}},"id":335,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":381,"src":"3396:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":337,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3396:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":338,"nodeType":"ExpressionStatement","src":"3396:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":339,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":194,"src":"3432:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$36","typeString":"contract Vm"}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3432:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3432:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3432:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3467:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":344,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3456:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$382","typeString":"contract ScriptExample"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":381,"src":"3456:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":348,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3456:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":349,"nodeType":"ExpressionStatement","src":"3456:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":353,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3512:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":350,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"3500:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":101,"src":"3500:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":354,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3500:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":355,"nodeType":"ExpressionStatement","src":"3500:20:0"}]},"documentation":{"id":195,"nodeType":"StructuredDocumentation","src":"2495:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2587:3:0","parameters":{"id":196,"nodeType":"ParameterList","parameters":[],"src":"2590:2:0"},"returnParameters":{"id":197,"nodeType":"ParameterList","parameters":[],"src":"2600:0:0"},"scope":382,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":381,"nodeType":"FunctionDefinition","src":"3622:143:0","nodes":[],"body":{"id":380,"nodeType":"Block","src":"3671:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":366,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":360,"src":"3693:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":363,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"3681:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":365,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":101,"src":"3681:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":367,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3681:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":368,"nodeType":"ExpressionStatement","src":"3681:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":372,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3718:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":375,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3746:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":376,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3746:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":374,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3738:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":373,"name":"address","nodeType":"ElementaryTypeName","src":"3738:7:0","typeDescriptions":{}}},"id":377,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3738:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":369,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"3706:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$173_$","typeString":"type(library console)"}},"id":371,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":152,"src":"3706:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":378,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3706:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":379,"nodeType":"ExpressionStatement","src":"3706:52:0"}]},"documentation":{"id":358,"nodeType":"StructuredDocumentation","src":"3533:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"3631:5:0","parameters":{"id":361,"nodeType":"ParameterList","parameters":[{"constant":false,"id":360,"mutability":"mutable","name":"_v","nameLocation":"3653:2:0","nodeType":"VariableDeclaration","scope":381,"src":"3637:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":359,"name":"string","nodeType":"ElementaryTypeName","src":"3637:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"3636:20:0"},"returnParameters":{"id":362,"nodeType":"ParameterList","parameters":[],"src":"3671:0:0"},"scope":382,"stateMutability":"view","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[],"contractKind":"contract","documentation":{"id":174,"nodeType":"StructuredDocumentation","src":"2192:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[382],"name":"ScriptExample","nameLocation":"2327:13:0","scope":383,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file +{"abi":[],"bytecode":{"object":"0x602d6037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300080f000a","sourceMap":"682:1622:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;682:1622:0;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300080f000a","sourceMap":"682:1622:0:-:0;;;;;;;;","linkReferences":{}},"methodIdentifiers":{},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"console\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x7727e5a55f4b3d442729483d41848c957b04027e48d972a568ee6f50aa3daa7a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4de8bd2d73869b583c44f8996ef56f872ce47499e801aa95da90a8e695196b00\",\"dweb:/ipfs/QmZzQy8ZSWuMnLBsGWTxUxZRhWGTJ8cq8yHpM59irYA2dw\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"console"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x7727e5a55f4b3d442729483d41848c957b04027e48d972a568ee6f50aa3daa7a","urls":["bzz-raw://4de8bd2d73869b583c44f8996ef56f872ce47499e801aa95da90a8e695196b00","dweb:/ipfs/QmZzQy8ZSWuMnLBsGWTxUxZRhWGTJ8cq8yHpM59irYA2dw"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[],"types":{}},"userdoc":{"version":1,"kind":"user"},"devdoc":{"version":1,"kind":"dev"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":538,"exportedSymbols":{"ScriptExample":[537],"Vm":[45],"console":[182]},"nodeType":"SourceUnit","src":"32:4932:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":45,"nodeType":"ContractDefinition","src":"120:507:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":45,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":45,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":45,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":38,"nodeType":"FunctionDefinition","src":"516:30:0","nodes":[],"functionSelector":"afc98040","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"525:9:0","parameters":{"id":36,"nodeType":"ParameterList","parameters":[],"src":"534:2:0"},"returnParameters":{"id":37,"nodeType":"ParameterList","parameters":[],"src":"545:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":41,"nodeType":"FunctionDefinition","src":"551:35:0","nodes":[],"functionSelector":"7fb5297f","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"560:14:0","parameters":{"id":39,"nodeType":"ParameterList","parameters":[],"src":"574:2:0"},"returnParameters":{"id":40,"nodeType":"ParameterList","parameters":[],"src":"585:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":44,"nodeType":"FunctionDefinition","src":"591:34:0","nodes":[],"functionSelector":"76eadd36","implemented":false,"kind":"function","modifiers":[],"name":"stopBroadcast","nameLocation":"600:13:0","parameters":{"id":42,"nodeType":"ParameterList","parameters":[],"src":"613:2:0"},"returnParameters":{"id":43,"nodeType":"ParameterList","parameters":[],"src":"624:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[45],"name":"Vm","nameLocation":"130:2:0","scope":538,"usedErrors":[]},{"id":182,"nodeType":"ContractDefinition","src":"682:1622:0","nodes":[{"id":51,"nodeType":"VariableDeclaration","src":"704:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"721:15:0","scope":182,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":46,"name":"address","nodeType":"ElementaryTypeName","src":"704:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":49,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"747:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":48,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"739:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":47,"name":"address","nodeType":"ElementaryTypeName","src":"739:7:0","typeDescriptions":{}}},"id":50,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"739:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":68,"nodeType":"FunctionDefinition","src":"797:221:0","nodes":[],"body":{"id":67,"nodeType":"Block","src":"956:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"975:37:0","statements":[{"nodeType":"YulAssignment","src":"989:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"998:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"989:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":57,"isOffset":false,"isSlot":false,"src":"998:4:0","valueSize":1},{"declaration":64,"isOffset":false,"isSlot":false,"src":"989:5:0","valueSize":1}],"id":66,"nodeType":"InlineAssembly","src":"966:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"806:25:0","parameters":{"id":58,"nodeType":"ParameterList","parameters":[{"constant":false,"id":57,"mutability":"mutable","name":"fnIn","nameLocation":"878:4:0","nodeType":"VariableDeclaration","scope":68,"src":"841:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":56,"nodeType":"FunctionTypeName","parameterTypes":{"id":54,"nodeType":"ParameterList","parameters":[{"constant":false,"id":53,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":56,"src":"850:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":52,"name":"bytes","nodeType":"ElementaryTypeName","src":"850:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"849:14:0"},"returnParameterTypes":{"id":55,"nodeType":"ParameterList","parameters":[],"src":"878:0:0"},"src":"841:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"831:57:0"},"returnParameters":{"id":65,"nodeType":"ParameterList","parameters":[{"constant":false,"id":64,"mutability":"mutable","name":"fnOut","nameLocation":"949:5:0","nodeType":"VariableDeclaration","scope":68,"src":"912:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":63,"nodeType":"FunctionTypeName","parameterTypes":{"id":61,"nodeType":"ParameterList","parameters":[{"constant":false,"id":60,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":63,"src":"921:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":59,"name":"bytes","nodeType":"ElementaryTypeName","src":"921:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"920:14:0"},"returnParameterTypes":{"id":62,"nodeType":"ParameterList","parameters":[],"src":"949:0:0"},"src":"912:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"911:44:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":80,"nodeType":"FunctionDefinition","src":"1024:133:0","nodes":[],"body":{"id":79,"nodeType":"Block","src":"1085:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":76,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":70,"src":"1142:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":74,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":96,"src":"1121:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":73,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":68,"src":"1095:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":75,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1095:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":77,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1095:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":78,"nodeType":"ExpressionStatement","src":"1095:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"1033:15:0","parameters":{"id":71,"nodeType":"ParameterList","parameters":[{"constant":false,"id":70,"mutability":"mutable","name":"payload","nameLocation":"1062:7:0","nodeType":"VariableDeclaration","scope":80,"src":"1049:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":69,"name":"bytes","nodeType":"ElementaryTypeName","src":"1049:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1048:22:0"},"returnParameters":{"id":72,"nodeType":"ParameterList","parameters":[],"src":"1085:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":96,"nodeType":"FunctionDefinition","src":"1163:380:0","nodes":[],"body":{"id":95,"nodeType":"Block","src":"1227:316:0","nodes":[],"statements":[{"assignments":[86],"declarations":[{"constant":false,"id":86,"mutability":"mutable","name":"payloadLength","nameLocation":"1245:13:0","nodeType":"VariableDeclaration","scope":95,"src":"1237:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":85,"name":"uint256","nodeType":"ElementaryTypeName","src":"1237:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":89,"initialValue":{"expression":{"id":87,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":82,"src":"1261:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":88,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1261:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1237:38:0"},{"assignments":[91],"declarations":[{"constant":false,"id":91,"mutability":"mutable","name":"consoleAddress","nameLocation":"1293:14:0","nodeType":"VariableDeclaration","scope":95,"src":"1285:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":90,"name":"address","nodeType":"ElementaryTypeName","src":"1285:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":93,"initialValue":{"id":92,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":51,"src":"1310:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1285:40:0"},{"AST":{"nodeType":"YulBlock","src":"1387:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1401:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1425:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1434:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1421:3:0"},"nodeType":"YulFunctionCall","src":"1421:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1405:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1450:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1470:3:0"},"nodeType":"YulFunctionCall","src":"1470:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1477:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1493:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1507:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1522:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1525:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1459:10:0"},"nodeType":"YulFunctionCall","src":"1459:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1454:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":91,"isOffset":false,"isSlot":false,"src":"1477:14:0","valueSize":1},{"declaration":82,"isOffset":false,"isSlot":false,"src":"1425:7:0","valueSize":1},{"declaration":86,"isOffset":false,"isSlot":false,"src":"1507:13:0","valueSize":1}],"id":94,"nodeType":"InlineAssembly","src":"1378:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1172:19:0","parameters":{"id":83,"nodeType":"ParameterList","parameters":[{"constant":false,"id":82,"mutability":"mutable","name":"payload","nameLocation":"1205:7:0","nodeType":"VariableDeclaration","scope":96,"src":"1192:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":81,"name":"bytes","nodeType":"ElementaryTypeName","src":"1192:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1191:22:0"},"returnParameters":{"id":84,"nodeType":"ParameterList","parameters":[],"src":"1227:0:0"},"scope":182,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":110,"nodeType":"FunctionDefinition","src":"1549:121:0","nodes":[],"body":{"id":109,"nodeType":"Block","src":"1594:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":104,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1644:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":105,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":98,"src":"1659:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":102,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1620:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":103,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1620:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":106,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1620:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":101,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1604:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":107,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1604:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":108,"nodeType":"ExpressionStatement","src":"1604:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1558:3:0","parameters":{"id":99,"nodeType":"ParameterList","parameters":[{"constant":false,"id":98,"mutability":"mutable","name":"p0","nameLocation":"1576:2:0","nodeType":"VariableDeclaration","scope":110,"src":"1562:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":97,"name":"string","nodeType":"ElementaryTypeName","src":"1562:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1561:18:0"},"returnParameters":{"id":100,"nodeType":"ParameterList","parameters":[],"src":"1594:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":127,"nodeType":"FunctionDefinition","src":"1676:139:0","nodes":[],"body":{"id":126,"nodeType":"Block","src":"1730:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":120,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1780:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":121,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":112,"src":"1800:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":122,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":114,"src":"1804:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":118,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1756:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":119,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1756:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":123,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1756:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":117,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1740:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":124,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1740:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":125,"nodeType":"ExpressionStatement","src":"1740:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1685:3:0","parameters":{"id":115,"nodeType":"ParameterList","parameters":[{"constant":false,"id":112,"mutability":"mutable","name":"p0","nameLocation":"1703:2:0","nodeType":"VariableDeclaration","scope":127,"src":"1689:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":111,"name":"string","nodeType":"ElementaryTypeName","src":"1689:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":114,"mutability":"mutable","name":"p1","nameLocation":"1712:2:0","nodeType":"VariableDeclaration","scope":127,"src":"1707:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":113,"name":"bool","nodeType":"ElementaryTypeName","src":"1707:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1688:27:0"},"returnParameters":{"id":116,"nodeType":"ParameterList","parameters":[],"src":"1730:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":144,"nodeType":"FunctionDefinition","src":"1821:145:0","nodes":[],"body":{"id":143,"nodeType":"Block","src":"1878:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":137,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1928:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":138,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":129,"src":"1951:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":139,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":131,"src":"1955:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":135,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1904:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":136,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1904:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":140,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1904:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":134,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1888:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":141,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1888:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":142,"nodeType":"ExpressionStatement","src":"1888:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1830:3:0","parameters":{"id":132,"nodeType":"ParameterList","parameters":[{"constant":false,"id":129,"mutability":"mutable","name":"p0","nameLocation":"1848:2:0","nodeType":"VariableDeclaration","scope":144,"src":"1834:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":128,"name":"string","nodeType":"ElementaryTypeName","src":"1834:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":131,"mutability":"mutable","name":"p1","nameLocation":"1860:2:0","nodeType":"VariableDeclaration","scope":144,"src":"1852:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":130,"name":"uint256","nodeType":"ElementaryTypeName","src":"1852:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1833:30:0"},"returnParameters":{"id":133,"nodeType":"ParameterList","parameters":[],"src":"1878:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":161,"nodeType":"FunctionDefinition","src":"1972:145:0","nodes":[],"body":{"id":160,"nodeType":"Block","src":"2029:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":154,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2079:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":155,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":146,"src":"2102:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":156,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":148,"src":"2106:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":152,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2055:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":153,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2055:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":157,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2055:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":151,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"2039:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":158,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2039:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":159,"nodeType":"ExpressionStatement","src":"2039:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1981:3:0","parameters":{"id":149,"nodeType":"ParameterList","parameters":[{"constant":false,"id":146,"mutability":"mutable","name":"p0","nameLocation":"1999:2:0","nodeType":"VariableDeclaration","scope":161,"src":"1985:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":145,"name":"string","nodeType":"ElementaryTypeName","src":"1985:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":148,"mutability":"mutable","name":"p1","nameLocation":"2011:2:0","nodeType":"VariableDeclaration","scope":161,"src":"2003:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":147,"name":"address","nodeType":"ElementaryTypeName","src":"2003:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1984:30:0"},"returnParameters":{"id":150,"nodeType":"ParameterList","parameters":[],"src":"2029:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":181,"nodeType":"FunctionDefinition","src":"2123:179:0","nodes":[],"body":{"id":180,"nodeType":"Block","src":"2204:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":173,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2254:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":174,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":163,"src":"2283:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":175,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":165,"src":"2287:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":176,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":167,"src":"2291:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":171,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2230:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":172,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2230:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":177,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2230:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":170,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"2214:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":178,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2214:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":179,"nodeType":"ExpressionStatement","src":"2214:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2132:3:0","parameters":{"id":168,"nodeType":"ParameterList","parameters":[{"constant":false,"id":163,"mutability":"mutable","name":"p0","nameLocation":"2150:2:0","nodeType":"VariableDeclaration","scope":181,"src":"2136:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":162,"name":"string","nodeType":"ElementaryTypeName","src":"2136:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":165,"mutability":"mutable","name":"p1","nameLocation":"2168:2:0","nodeType":"VariableDeclaration","scope":181,"src":"2154:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":164,"name":"string","nodeType":"ElementaryTypeName","src":"2154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":167,"mutability":"mutable","name":"p2","nameLocation":"2186:2:0","nodeType":"VariableDeclaration","scope":181,"src":"2172:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":166,"name":"string","nodeType":"ElementaryTypeName","src":"2172:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2135:54:0"},"returnParameters":{"id":169,"nodeType":"ParameterList","parameters":[],"src":"2204:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[182],"name":"console","nameLocation":"690:7:0","scope":538,"usedErrors":[]},{"id":537,"nodeType":"ContractDefinition","src":"2432:2531:0","nodes":[{"id":197,"nodeType":"VariableDeclaration","src":"2462:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2488:10:0","scope":537,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":184,"name":"address","nodeType":"ElementaryTypeName","src":"2462:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":192,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2535:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":191,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2525:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":193,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2525:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":190,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2517:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":189,"name":"uint256","nodeType":"ElementaryTypeName","src":"2517:7:0","typeDescriptions":{}}},"id":194,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2517:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":188,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2509:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":187,"name":"uint160","nodeType":"ElementaryTypeName","src":"2509:7:0","typeDescriptions":{}}},"id":195,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2509:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":186,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2501:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":185,"name":"address","nodeType":"ElementaryTypeName","src":"2501:7:0","typeDescriptions":{}}},"id":196,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2501:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":203,"nodeType":"VariableDeclaration","src":"2562:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2583:2:0","scope":537,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"},"typeName":{"id":199,"nodeType":"UserDefinedTypeName","pathNode":{"id":198,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":45,"src":"2562:2:0"},"referencedDeclaration":45,"src":"2562:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"value":{"arguments":[{"id":201,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":197,"src":"2591:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":200,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":45,"src":"2588:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$45_$","typeString":"type(contract Vm)"}},"id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2588:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"visibility":"internal"},{"id":205,"nodeType":"VariableDeclaration","src":"2666:22:0","nodes":[],"constant":false,"functionSelector":"61bc221a","mutability":"mutable","name":"counter","nameLocation":"2681:7:0","scope":537,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":204,"name":"uint256","nodeType":"ElementaryTypeName","src":"2666:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":368,"nodeType":"FunctionDefinition","src":"2778:949:0","nodes":[],"body":{"id":367,"nodeType":"Block","src":"2800:927:0","nodes":[],"statements":[{"assignments":[210],"declarations":[{"constant":false,"id":210,"mutability":"mutable","name":"x","nameLocation":"2815:1:0","nodeType":"VariableDeclaration","scope":367,"src":"2810:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":209,"name":"bool","nodeType":"ElementaryTypeName","src":"2810:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":216,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":213,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2828:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":214,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2844:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":211,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"2819:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":212,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2819:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":215,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2819:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2810:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":220,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2872:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":221,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":210,"src":"2895:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":217,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"2860:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":219,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":127,"src":"2860:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":222,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2860:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":223,"nodeType":"ExpressionStatement","src":"2860:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":227,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2920:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":230,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"2945:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}],"id":229,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2937:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":228,"name":"address","nodeType":"ElementaryTypeName","src":"2937:7:0","typeDescriptions":{}}},"id":231,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2937:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":224,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"2908:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":226,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"2908:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2908:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":233,"nodeType":"ExpressionStatement","src":"2908:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":237,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2973:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":242,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3011:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}],"id":241,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3003:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":240,"name":"address","nodeType":"ElementaryTypeName","src":"3003:7:0","typeDescriptions":{}}},"id":243,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3003:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":238,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"2991:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":239,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"2991:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":244,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2991:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":234,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"2961:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":236,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":144,"src":"2961:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":245,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2961:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":246,"nodeType":"ExpressionStatement","src":"2961:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":250,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3040:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":253,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3063:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":254,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3063:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":252,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3055:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":251,"name":"address","nodeType":"ElementaryTypeName","src":"3055:7:0","typeDescriptions":{}}},"id":255,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3055:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":247,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3028:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"3028:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":256,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3028:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":257,"nodeType":"ExpressionStatement","src":"3028:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":261,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3097:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":266,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3133:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":267,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3133:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":265,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3125:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":264,"name":"address","nodeType":"ElementaryTypeName","src":"3125:7:0","typeDescriptions":{}}},"id":268,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3125:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":262,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3113:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":263,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3113:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":269,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3113:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":258,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3085:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":260,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":144,"src":"3085:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":270,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3085:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":271,"nodeType":"ExpressionStatement","src":"3085:61:0"},{"assignments":[273],"declarations":[{"constant":false,"id":273,"mutability":"mutable","name":"json","nameLocation":"3171:4:0","nodeType":"VariableDeclaration","scope":367,"src":"3157:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":272,"name":"string","nodeType":"ElementaryTypeName","src":"3157:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":275,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":274,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3178:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"3157:55:0"},{"assignments":[280],"declarations":[{"constant":false,"id":280,"mutability":"mutable","name":"keys","nameLocation":"3238:4:0","nodeType":"VariableDeclaration","scope":367,"src":"3222:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":278,"name":"string","nodeType":"ElementaryTypeName","src":"3222:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":279,"nodeType":"ArrayTypeName","src":"3222:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":286,"initialValue":{"arguments":[{"id":283,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":273,"src":"3262:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3268:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":281,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3245:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":282,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3245:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":285,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3245:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3222:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":290,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3305:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":291,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":280,"src":"3313:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":293,"indexExpression":{"hexValue":"30","id":292,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3318:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3313:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":294,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":280,"src":"3322:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":296,"indexExpression":{"hexValue":"31","id":295,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3327:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3322:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":287,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3293:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":289,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":181,"src":"3293:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":297,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3293:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":298,"nodeType":"ExpressionStatement","src":"3293:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3352:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":299,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3341:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":301,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3341:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":303,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3341:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":304,"nodeType":"ExpressionStatement","src":"3341:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":312,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3408:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":311,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3400:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":310,"name":"uint160","nodeType":"ElementaryTypeName","src":"3400:7:0","typeDescriptions":{}}},"id":313,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3400:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":309,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3392:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":308,"name":"address","nodeType":"ElementaryTypeName","src":"3392:7:0","typeDescriptions":{}}},"id":314,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3392:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":305,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3378:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":307,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3378:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":315,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3378:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":316,"nodeType":"ExpressionStatement","src":"3378:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":320,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3436:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":317,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3425:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":319,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3425:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":321,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3425:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":322,"nodeType":"ExpressionStatement","src":"3425:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":326,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3473:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":329,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3508:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":330,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3508:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":328,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3500:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":327,"name":"address","nodeType":"ElementaryTypeName","src":"3500:7:0","typeDescriptions":{}}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3500:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":323,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3461:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"3461:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":332,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3461:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":333,"nodeType":"ExpressionStatement","src":"3461:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":337,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3542:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":340,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3580:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}],"id":339,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3572:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":338,"name":"address","nodeType":"ElementaryTypeName","src":"3572:7:0","typeDescriptions":{}}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3572:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":334,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3530:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":336,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"3530:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3530:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3530:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3607:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":344,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3596:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3596:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":348,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3596:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":349,"nodeType":"ExpressionStatement","src":"3596:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":350,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3632:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3632:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":353,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3632:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":354,"nodeType":"ExpressionStatement","src":"3632:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":358,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3667:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":355,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3656:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":357,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3656:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":359,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3656:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":360,"nodeType":"ExpressionStatement","src":"3656:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":364,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3712:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":361,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3700:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":363,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"3700:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":365,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3700:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":366,"nodeType":"ExpressionStatement","src":"3700:20:0"}]},"documentation":{"id":206,"nodeType":"StructuredDocumentation","src":"2695:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2787:3:0","parameters":{"id":207,"nodeType":"ParameterList","parameters":[],"src":"2790:2:0"},"returnParameters":{"id":208,"nodeType":"ParameterList","parameters":[],"src":"2800:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":452,"nodeType":"FunctionDefinition","src":"3794:520:0","nodes":[],"body":{"id":451,"nodeType":"Block","src":"3825:489:0","nodes":[],"statements":[{"expression":{"arguments":[{"hexValue":"74657374696e672073696e676c65","id":375,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3847:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""},"value":"testing single"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""}],"expression":{"id":372,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3835:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":374,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"3835:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":376,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3835:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":377,"nodeType":"ExpressionStatement","src":"3835:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":378,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3874:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":380,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"3874:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":381,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3874:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":382,"nodeType":"ExpressionStatement","src":"3874:14:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c31","id":386,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3909:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""},"value":"single_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""}],"expression":{"id":383,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3898:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":385,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":491,"src":"3898:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":387,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3898:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":388,"nodeType":"ExpressionStatement","src":"3898:26:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c32","id":392,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3945:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""},"value":"single_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""}],"expression":{"id":389,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3934:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":391,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":506,"src":"3934:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":393,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3934:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":394,"nodeType":"ExpressionStatement","src":"3934:26:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073746172742f73746f70","id":398,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3983:20:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""},"value":"testing start/stop"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""}],"expression":{"id":395,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3971:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":397,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"3971:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":399,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3971:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":400,"nodeType":"ExpressionStatement","src":"3971:33:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":401,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4014:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":403,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":41,"src":"4014:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":404,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4014:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":405,"nodeType":"ExpressionStatement","src":"4014:19:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c31","id":409,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4054:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""},"value":"startstop_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""}],"expression":{"id":406,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4043:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":408,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":491,"src":"4043:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":410,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4043:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":411,"nodeType":"ExpressionStatement","src":"4043:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c32","id":415,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4093:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""},"value":"startstop_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""}],"expression":{"id":412,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4082:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":414,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":506,"src":"4082:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":416,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4082:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":417,"nodeType":"ExpressionStatement","src":"4082:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":418,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4121:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":420,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":44,"src":"4121:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":421,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4121:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":422,"nodeType":"ExpressionStatement","src":"4121:18:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c33","id":426,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4160:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""},"value":"startstop_call3"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""}],"expression":{"id":423,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4149:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":425,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":491,"src":"4149:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":427,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4149:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":428,"nodeType":"ExpressionStatement","src":"4149:29:0"},{"expression":{"arguments":[{"hexValue":"74657374696e67206e6573746564","id":432,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4201:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""},"value":"testing nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""}],"expression":{"id":429,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4189:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":431,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4189:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":433,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4189:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":434,"nodeType":"ExpressionStatement","src":"4189:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":435,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4228:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":437,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":41,"src":"4228:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":438,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4228:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":439,"nodeType":"ExpressionStatement","src":"4228:19:0"},{"expression":{"arguments":[{"hexValue":"6e6573746564","id":443,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4270:8:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""},"value":"nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""}],"expression":{"id":440,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4257:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":442,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested1","nodeType":"MemberAccess","referencedDeclaration":521,"src":"4257:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":444,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4257:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":445,"nodeType":"ExpressionStatement","src":"4257:22:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":446,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4289:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":448,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":44,"src":"4289:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":449,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4289:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":450,"nodeType":"ExpressionStatement","src":"4289:18:0"}]},"documentation":{"id":369,"nodeType":"StructuredDocumentation","src":"3733:56:0","text":"@notice example function, to test vm.broadcast with."},"functionSelector":"bef03abc","implemented":true,"kind":"function","modifiers":[],"name":"runBroadcast","nameLocation":"3803:12:0","parameters":{"id":370,"nodeType":"ParameterList","parameters":[],"src":"3815:2:0"},"returnParameters":{"id":371,"nodeType":"ParameterList","parameters":[],"src":"3825:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":476,"nodeType":"FunctionDefinition","src":"4409:143:0","nodes":[],"body":{"id":475,"nodeType":"Block","src":"4458:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":461,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":455,"src":"4480:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":458,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4468:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":460,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4468:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":462,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4468:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":463,"nodeType":"ExpressionStatement","src":"4468:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":467,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4505:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":470,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"4533:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":471,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"4533:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":469,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4525:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":468,"name":"address","nodeType":"ElementaryTypeName","src":"4525:7:0","typeDescriptions":{}}},"id":472,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4525:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":464,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4493:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":466,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"4493:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":473,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4493:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":474,"nodeType":"ExpressionStatement","src":"4493:52:0"}]},"documentation":{"id":453,"nodeType":"StructuredDocumentation","src":"4320:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"4418:5:0","parameters":{"id":456,"nodeType":"ParameterList","parameters":[{"constant":false,"id":455,"mutability":"mutable","name":"_v","nameLocation":"4440:2:0","nodeType":"VariableDeclaration","scope":476,"src":"4424:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":454,"name":"string","nodeType":"ElementaryTypeName","src":"4424:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4423:20:0"},"returnParameters":{"id":457,"nodeType":"ParameterList","parameters":[],"src":"4458:0:0"},"scope":537,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":491,"nodeType":"FunctionDefinition","src":"4558:95:0","nodes":[],"body":{"id":490,"nodeType":"Block","src":"4602:51:0","nodes":[],"statements":[{"expression":{"id":482,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4612:9:0","subExpression":{"id":481,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4612:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":483,"nodeType":"ExpressionStatement","src":"4612:9:0"},{"expression":{"arguments":[{"id":487,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":478,"src":"4643:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":484,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4631:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":486,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4631:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":488,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4631:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":489,"nodeType":"ExpressionStatement","src":"4631:15:0"}]},"functionSelector":"7e79255d","implemented":true,"kind":"function","modifiers":[],"name":"call1","nameLocation":"4567:5:0","parameters":{"id":479,"nodeType":"ParameterList","parameters":[{"constant":false,"id":478,"mutability":"mutable","name":"_v","nameLocation":"4589:2:0","nodeType":"VariableDeclaration","scope":491,"src":"4573:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":477,"name":"string","nodeType":"ElementaryTypeName","src":"4573:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4572:20:0"},"returnParameters":{"id":480,"nodeType":"ParameterList","parameters":[],"src":"4602:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":506,"nodeType":"FunctionDefinition","src":"4659:95:0","nodes":[],"body":{"id":505,"nodeType":"Block","src":"4703:51:0","nodes":[],"statements":[{"expression":{"id":497,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4713:9:0","subExpression":{"id":496,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4713:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":498,"nodeType":"ExpressionStatement","src":"4713:9:0"},{"expression":{"arguments":[{"id":502,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":493,"src":"4744:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":499,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4732:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":501,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4732:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":503,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4732:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":504,"nodeType":"ExpressionStatement","src":"4732:15:0"}]},"functionSelector":"8d3ef7ca","implemented":true,"kind":"function","modifiers":[],"name":"call2","nameLocation":"4668:5:0","parameters":{"id":494,"nodeType":"ParameterList","parameters":[{"constant":false,"id":493,"mutability":"mutable","name":"_v","nameLocation":"4690:2:0","nodeType":"VariableDeclaration","scope":506,"src":"4674:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":492,"name":"string","nodeType":"ElementaryTypeName","src":"4674:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4673:20:0"},"returnParameters":{"id":495,"nodeType":"ParameterList","parameters":[],"src":"4703:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":521,"nodeType":"FunctionDefinition","src":"4760:98:0","nodes":[],"body":{"id":520,"nodeType":"Block","src":"4806:52:0","nodes":[],"statements":[{"expression":{"id":512,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4816:9:0","subExpression":{"id":511,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4816:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":513,"nodeType":"ExpressionStatement","src":"4816:9:0"},{"expression":{"arguments":[{"id":517,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":508,"src":"4848:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":514,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4835:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":516,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested2","nodeType":"MemberAccess","referencedDeclaration":536,"src":"4835:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":518,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4835:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":519,"nodeType":"ExpressionStatement","src":"4835:16:0"}]},"functionSelector":"a76ccdfa","implemented":true,"kind":"function","modifiers":[],"name":"nested1","nameLocation":"4769:7:0","parameters":{"id":509,"nodeType":"ParameterList","parameters":[{"constant":false,"id":508,"mutability":"mutable","name":"_v","nameLocation":"4793:2:0","nodeType":"VariableDeclaration","scope":521,"src":"4777:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":507,"name":"string","nodeType":"ElementaryTypeName","src":"4777:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4776:20:0"},"returnParameters":{"id":510,"nodeType":"ParameterList","parameters":[],"src":"4806:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":536,"nodeType":"FunctionDefinition","src":"4864:97:0","nodes":[],"body":{"id":535,"nodeType":"Block","src":"4910:51:0","nodes":[],"statements":[{"expression":{"id":527,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4920:9:0","subExpression":{"id":526,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4920:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":528,"nodeType":"ExpressionStatement","src":"4920:9:0"},{"expression":{"arguments":[{"id":532,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":523,"src":"4951:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":529,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4939:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":531,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4939:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":533,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4939:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":534,"nodeType":"ExpressionStatement","src":"4939:15:0"}]},"functionSelector":"dbf1282f","implemented":true,"kind":"function","modifiers":[],"name":"nested2","nameLocation":"4873:7:0","parameters":{"id":524,"nodeType":"ParameterList","parameters":[{"constant":false,"id":523,"mutability":"mutable","name":"_v","nameLocation":"4897:2:0","nodeType":"VariableDeclaration","scope":536,"src":"4881:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":522,"name":"string","nodeType":"ElementaryTypeName","src":"4881:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4880:20:0"},"returnParameters":{"id":525,"nodeType":"ParameterList","parameters":[],"src":"4910:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[],"contractKind":"contract","documentation":{"id":183,"nodeType":"StructuredDocumentation","src":"2306:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[537],"name":"ScriptExample","nameLocation":"2441:13:0","scope":538,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file From 91e306b0f5716389911e5478c1aff5aff6f2ba92 Mon Sep 17 00:00:00 2001 From: Emiliano Bonassi Date: Tue, 10 Sep 2024 15:21:50 +0200 Subject: [PATCH 082/264] fix(op-batcher): initAltDA before initChannelConfig (#11816) * fix(op-batcher): initAltDA before initChannelConfig * chore(op-bastcher): fix comment --- op-batcher/batcher/service.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/op-batcher/batcher/service.go b/op-batcher/batcher/service.go index 00d3d32071f7..9b896817f145 100644 --- a/op-batcher/batcher/service.go +++ b/op-batcher/batcher/service.go @@ -105,6 +105,10 @@ func (bs *BatcherService) initFromCLIConfig(ctx context.Context, version string, if err := bs.initTxManager(cfg); err != nil { return fmt.Errorf("failed to init Tx manager: %w", err) } + // must be init before driver and channel config + if err := bs.initAltDA(cfg); err != nil { + return fmt.Errorf("failed to init AltDA: %w", err) + } if err := bs.initChannelConfig(cfg); err != nil { return fmt.Errorf("failed to init channel config: %w", err) } @@ -115,10 +119,6 @@ func (bs *BatcherService) initFromCLIConfig(ctx context.Context, version string, if err := bs.initPProf(cfg); err != nil { return fmt.Errorf("failed to init profiling: %w", err) } - // init before driver - if err := bs.initAltDA(cfg); err != nil { - return fmt.Errorf("failed to init AltDA: %w", err) - } bs.initDriver() if err := bs.initRPCServer(cfg); err != nil { return fmt.Errorf("failed to start RPC server: %w", err) From 53fa7b9e94a7f5b474dea02ccb125257d7bdec5a Mon Sep 17 00:00:00 2001 From: Sam Stokes <35908605+bitwiseguy@users.noreply.github.com> Date: Tue, 10 Sep 2024 12:38:31 -0400 Subject: [PATCH 083/264] op-node: read DACommitmentType from scr in LoadOPStackRollupConfig (#11830) * op-node: read DACommitmentType from scr in LoadOPStackRollupConfig * op-node: check for altda nil pointers before dereferencing * op-node: leave altDA config nil if not existent in scr config --- go.mod | 2 +- go.sum | 4 ++-- op-node/rollup/superchain.go | 16 ++++++++++++---- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index c600dbac5db8..5ab245ccf283 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/crate-crypto/go-kzg-4844 v1.0.0 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 - github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20240821192748-42bd03ba8313 + github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20240910145426-b3905c89e8ac github.com/ethereum/go-ethereum v1.14.8 github.com/fsnotify/fsnotify v1.7.0 github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb diff --git a/go.sum b/go.sum index bf4985669419..22368b8d57d1 100644 --- a/go.sum +++ b/go.sum @@ -178,8 +178,8 @@ github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 h1:RWHKLhCrQThMfch+QJ1Z github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3/go.mod h1:QziizLAiF0KqyLdNJYD7O5cpDlaFMNZzlxYNcWsJUxs= github.com/ethereum-optimism/op-geth v1.101408.0-rc.4.0.20240827042333-110c433a2469 h1:sGqlBjx0+z/ExU6VNo5OHSXS/5nc6BfkEQJvSdVbWp0= github.com/ethereum-optimism/op-geth v1.101408.0-rc.4.0.20240827042333-110c433a2469/go.mod h1:Mk8AhvlqFbjI9oW2ymThSSoqc6kiEH0/tCmHGMEu6ac= -github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20240821192748-42bd03ba8313 h1:SVSFg8ccdRBJxOdRS1pK8oIHvMufiPAQz1gkQsEPnZc= -github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20240821192748-42bd03ba8313/go.mod h1:XaVXL9jg8BcyOeugECgIUGa9Y3DjYJj71RHmb5qon6M= +github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20240910145426-b3905c89e8ac h1:hCIrLuOPV3FJfMDvXeOhCC3uQNvFoMIIlkT2mN2cfeg= +github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20240910145426-b3905c89e8ac/go.mod h1:XaVXL9jg8BcyOeugECgIUGa9Y3DjYJj71RHmb5qon6M= github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-verkle v0.1.1-0.20240306133620-7d920df305f0 h1:KrE8I4reeVvf7C1tm8elRjj4BdscTYzz/WAbYyf/JI4= diff --git a/op-node/rollup/superchain.go b/op-node/rollup/superchain.go index b0aa47635f81..21a74323c05f 100644 --- a/op-node/rollup/superchain.go +++ b/op-node/rollup/superchain.go @@ -46,10 +46,18 @@ func LoadOPStackRollupConfig(chainID uint64) (*Config, error) { var altDA *AltDAConfig if chConfig.AltDA != nil { - altDA = &AltDAConfig{ - DAChallengeAddress: common.Address(*chConfig.AltDA.DAChallengeAddress), - DAChallengeWindow: *chConfig.AltDA.DAChallengeWindow, - DAResolveWindow: *chConfig.AltDA.DAResolveWindow, + altDA = &AltDAConfig{} + if chConfig.AltDA.DAChallengeAddress != nil { + altDA.DAChallengeAddress = common.Address(*chConfig.AltDA.DAChallengeAddress) + } + if chConfig.AltDA.DAChallengeWindow != nil { + altDA.DAChallengeWindow = *chConfig.AltDA.DAChallengeWindow + } + if chConfig.AltDA.DAResolveWindow != nil { + altDA.DAResolveWindow = *chConfig.AltDA.DAResolveWindow + } + if chConfig.AltDA.DACommitmentType != nil { + altDA.CommitmentType = *chConfig.AltDA.DACommitmentType } } From de31478bdfcd6ec39bf86e9b0ba200e092d0c2f1 Mon Sep 17 00:00:00 2001 From: Matt Solomon Date: Tue, 10 Sep 2024 10:19:58 -0700 Subject: [PATCH 084/264] OPSM: Begin implementing OP Stack Manager code and it's deployment (#11623) * begin supporting specifying versions in OPSM * add deploy logic * deploy OPSM along with implementations * scaffold opsm interface between scripts * fixes * mvp of DeployOPChain * start working on an e2e opsm test, currently reverts * fix tests * test cleanup * rename opsmSingleton to opsm * chore: remove unused imports * refactor: switch from 'new' to blueprints, 50% code size reduction * fix semgrep * feat: add OPSM interop tests * test: add missing specs * add DisputeGameFactory deployment * chore: update snapshots * fix opsm interop support * chore: update snapshots * Update packages/contracts-bedrock/test/DeployOPChain.t.sol * fix: add L1StandardBridge setter and initialization * chore: small clarification of deploy flow * Update packages/contracts-bedrock/scripts/DeployImplementations.s.sol Co-authored-by: Blaine Malone * chore: add todos * fix: change bytes32 to string * rename addrs to opChainAddrs for clarity * test: fix assertion string numbering * chore: update semver lock: --------- Co-authored-by: Blaine Malone --- .../scripts/DeployImplementations.s.sol | 325 ++++++++++- .../scripts/DeployOPChain.s.sol | 69 ++- .../scripts/libraries/Solarray.sol | 34 +- packages/contracts-bedrock/semver-lock.json | 4 +- .../snapshots/abi/OPStackManager.json | 435 ++++++++++++++- .../snapshots/abi/OPStackManagerInterop.json | 512 ++++++++++++++++++ .../storageLayout/OPStackManager.json | 31 +- .../storageLayout/OPStackManagerInterop.json | 30 + .../src/L1/OPStackManager.sol | 508 ++++++++++++++++- .../src/L1/OPStackManagerInterop.sol | 58 ++ .../test/DeployImplementations.t.sol | 65 ++- .../test/DeployOPChain.t.sol | 164 +++++- .../test/L1/OPStackManager.t.sol | 81 ++- packages/contracts-bedrock/test/Specs.t.sol | 19 +- 14 files changed, 2225 insertions(+), 110 deletions(-) create mode 100644 packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json create mode 100644 packages/contracts-bedrock/snapshots/storageLayout/OPStackManagerInterop.json create mode 100644 packages/contracts-bedrock/src/L1/OPStackManagerInterop.sol diff --git a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol index 1cf246622837..3de9f3285ccc 100644 --- a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol +++ b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol @@ -3,11 +3,21 @@ pragma solidity 0.8.15; import { Script } from "forge-std/Script.sol"; +import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; +import { Proxy } from "src/universal/Proxy.sol"; +import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol"; +import { ResolvedDelegateProxy } from "src/legacy/ResolvedDelegateProxy.sol"; +import { AddressManager } from "src/legacy/AddressManager.sol"; + import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol"; import { MIPS } from "src/cannon/MIPS.sol"; +import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; +import { OPStackManager } from "src/L1/OPStackManager.sol"; import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; @@ -15,6 +25,12 @@ import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; +import { OPStackManagerInterop } from "src/L1/OPStackManagerInterop.sol"; +import { OptimismPortalInterop } from "src/L1/OptimismPortalInterop.sol"; +import { SystemConfigInterop } from "src/L1/SystemConfigInterop.sol"; + +import { Blueprint } from "src/libraries/Blueprint.sol"; + import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; import { Solarray } from "scripts/libraries/Solarray.sol"; @@ -26,6 +42,11 @@ contract DeployImplementationsInput { uint256 challengePeriodSeconds; uint256 proofMaturityDelaySeconds; uint256 disputeGameFinalityDelaySeconds; + // We also deploy OP Stack Manager here, which has a dependency on the prior step of deploying + // the superchain contracts. + string release; // The release version to set OPSM implementations for, of the format `op-contracts/vX.Y.Z`. + SuperchainConfig superchainConfigProxy; + ProtocolVersions protocolVersionsProxy; } bool public inputSet = false; @@ -81,12 +102,28 @@ contract DeployImplementationsInput { assertInputSet(); return inputs.disputeGameFinalityDelaySeconds; } + + function release() public view returns (string memory) { + assertInputSet(); + return inputs.release; + } + + function superchainConfigProxy() public view returns (SuperchainConfig) { + assertInputSet(); + return inputs.superchainConfigProxy; + } + + function protocolVersionsProxy() public view returns (ProtocolVersions) { + assertInputSet(); + return inputs.protocolVersionsProxy; + } } contract DeployImplementationsOutput { struct Output { + OPStackManager opsm; DelayedWETH delayedWETHImpl; - OptimismPortal2 optimismPortal2Impl; + OptimismPortal2 optimismPortalImpl; PreimageOracle preimageOracleSingleton; MIPS mipsSingleton; SystemConfig systemConfigImpl; @@ -94,13 +131,15 @@ contract DeployImplementationsOutput { L1ERC721Bridge l1ERC721BridgeImpl; L1StandardBridge l1StandardBridgeImpl; OptimismMintableERC20Factory optimismMintableERC20FactoryImpl; + DisputeGameFactory disputeGameFactoryImpl; } Output internal outputs; function set(bytes4 sel, address _addr) public { // forgefmt: disable-start - if (sel == this.optimismPortal2Impl.selector) outputs.optimismPortal2Impl = OptimismPortal2(payable(_addr)); + if (sel == this.opsm.selector) outputs.opsm = OPStackManager(payable(_addr)); + else if (sel == this.optimismPortalImpl.selector) outputs.optimismPortalImpl = OptimismPortal2(payable(_addr)); else if (sel == this.delayedWETHImpl.selector) outputs.delayedWETHImpl = DelayedWETH(payable(_addr)); else if (sel == this.preimageOracleSingleton.selector) outputs.preimageOracleSingleton = PreimageOracle(_addr); else if (sel == this.mipsSingleton.selector) outputs.mipsSingleton = MIPS(_addr); @@ -109,6 +148,7 @@ contract DeployImplementationsOutput { else if (sel == this.l1ERC721BridgeImpl.selector) outputs.l1ERC721BridgeImpl = L1ERC721Bridge(_addr); else if (sel == this.l1StandardBridgeImpl.selector) outputs.l1StandardBridgeImpl = L1StandardBridge(payable(_addr)); else if (sel == this.optimismMintableERC20FactoryImpl.selector) outputs.optimismMintableERC20FactoryImpl = OptimismMintableERC20Factory(_addr); + else if (sel == this.disputeGameFactoryImpl.selector) outputs.disputeGameFactoryImpl = DisputeGameFactory(_addr); else revert("DeployImplementationsOutput: unknown selector"); // forgefmt: disable-end } @@ -124,7 +164,8 @@ contract DeployImplementationsOutput { function checkOutput() public view { address[] memory addrs = Solarray.addresses( - address(outputs.optimismPortal2Impl), + address(outputs.opsm), + address(outputs.optimismPortalImpl), address(outputs.delayedWETHImpl), address(outputs.preimageOracleSingleton), address(outputs.mipsSingleton), @@ -132,14 +173,20 @@ contract DeployImplementationsOutput { address(outputs.l1CrossDomainMessengerImpl), address(outputs.l1ERC721BridgeImpl), address(outputs.l1StandardBridgeImpl), - address(outputs.optimismMintableERC20FactoryImpl) + address(outputs.optimismMintableERC20FactoryImpl), + address(outputs.disputeGameFactoryImpl) ); DeployUtils.assertValidContractAddresses(addrs); } - function optimismPortal2Impl() public view returns (OptimismPortal2) { - DeployUtils.assertValidContractAddress(address(outputs.optimismPortal2Impl)); - return outputs.optimismPortal2Impl; + function opsm() public view returns (OPStackManager) { + DeployUtils.assertValidContractAddress(address(outputs.opsm)); + return outputs.opsm; + } + + function optimismPortalImpl() public view returns (OptimismPortal2) { + DeployUtils.assertValidContractAddress(address(outputs.optimismPortalImpl)); + return outputs.optimismPortalImpl; } function delayedWETHImpl() public view returns (DelayedWETH) { @@ -181,6 +228,11 @@ contract DeployImplementationsOutput { DeployUtils.assertValidContractAddress(address(outputs.optimismMintableERC20FactoryImpl)); return outputs.optimismMintableERC20FactoryImpl; } + + function disputeGameFactoryImpl() public view returns (DisputeGameFactory) { + DeployUtils.assertValidContractAddress(address(outputs.disputeGameFactoryImpl)); + return outputs.disputeGameFactoryImpl; + } } contract DeployImplementations is Script { @@ -208,6 +260,7 @@ contract DeployImplementations is Script { function run(DeployImplementationsInput _dsi, DeployImplementationsOutput _dso) public { require(_dsi.inputSet(), "DeployImplementations: input not set"); + // Deploy the implementations. deploySystemConfigImpl(_dsi, _dso); deployL1CrossDomainMessengerImpl(_dsi, _dso); deployL1ERC721BridgeImpl(_dsi, _dso); @@ -217,13 +270,110 @@ contract DeployImplementations is Script { deployDelayedWETHImpl(_dsi, _dso); deployPreimageOracleSingleton(_dsi, _dso); deployMipsSingleton(_dsi, _dso); + deployDisputeGameFactoryImpl(_dsi, _dso); + + // Deploy the OP Stack Manager with the new implementations set. + deployOPStackManager(_dsi, _dso); _dso.checkOutput(); } // -------- Deployment Steps -------- - function deploySystemConfigImpl(DeployImplementationsInput, DeployImplementationsOutput _dso) public { + // --- OP Stack Manager --- + + function opsmSystemConfigSetter( + DeployImplementationsInput, + DeployImplementationsOutput _dso + ) + internal + view + virtual + returns (OPStackManager.ImplementationSetter memory) + { + return OPStackManager.ImplementationSetter({ + name: "SystemConfig", + info: OPStackManager.Implementation(address(_dso.systemConfigImpl()), SystemConfig.initialize.selector) + }); + } + + function createOPSMContract( + DeployImplementationsInput _dsi, + DeployImplementationsOutput, + OPStackManager.Blueprints memory blueprints + ) + internal + virtual + returns (OPStackManager opsm_) + { + SuperchainConfig superchainConfigProxy = _dsi.superchainConfigProxy(); + ProtocolVersions protocolVersionsProxy = _dsi.protocolVersionsProxy(); + + vm.broadcast(msg.sender); + opsm_ = new OPStackManager({ + _superchainConfig: superchainConfigProxy, + _protocolVersions: protocolVersionsProxy, + _blueprints: blueprints + }); + } + + function deployOPStackManager(DeployImplementationsInput _dsi, DeployImplementationsOutput _dso) public virtual { + string memory release = _dsi.release(); + + // First we deploy the blueprints for the singletons deployed by OPSM. + // forgefmt: disable-start + bytes32 salt = bytes32(0); + OPStackManager.Blueprints memory blueprints; + + vm.startBroadcast(msg.sender); + blueprints.addressManager = deployBytecode(Blueprint.blueprintDeployerBytecode(type(AddressManager).creationCode), salt); + blueprints.proxy = deployBytecode(Blueprint.blueprintDeployerBytecode(type(Proxy).creationCode), salt); + blueprints.proxyAdmin = deployBytecode(Blueprint.blueprintDeployerBytecode(type(ProxyAdmin).creationCode), salt); + blueprints.l1ChugSplashProxy = deployBytecode(Blueprint.blueprintDeployerBytecode(type(L1ChugSplashProxy).creationCode), salt); + blueprints.resolvedDelegateProxy = deployBytecode(Blueprint.blueprintDeployerBytecode(type(ResolvedDelegateProxy).creationCode), salt); + vm.stopBroadcast(); + // forgefmt: disable-end + + // This call contains a broadcast to deploy OPSM. + OPStackManager opsm = createOPSMContract(_dsi, _dso, blueprints); + + OPStackManager.ImplementationSetter[] memory setters = new OPStackManager.ImplementationSetter[](6); + setters[0] = OPStackManager.ImplementationSetter({ + name: "L1ERC721Bridge", + info: OPStackManager.Implementation(address(_dso.l1ERC721BridgeImpl()), L1ERC721Bridge.initialize.selector) + }); + setters[1] = OPStackManager.ImplementationSetter({ + name: "OptimismPortal", + info: OPStackManager.Implementation(address(_dso.optimismPortalImpl()), OptimismPortal2.initialize.selector) + }); + setters[2] = opsmSystemConfigSetter(_dsi, _dso); + setters[3] = OPStackManager.ImplementationSetter({ + name: "OptimismMintableERC20Factory", + info: OPStackManager.Implementation( + address(_dso.optimismMintableERC20FactoryImpl()), OptimismMintableERC20Factory.initialize.selector + ) + }); + setters[4] = OPStackManager.ImplementationSetter({ + name: "L1CrossDomainMessenger", + info: OPStackManager.Implementation( + address(_dso.l1CrossDomainMessengerImpl()), L1CrossDomainMessenger.initialize.selector + ) + }); + setters[5] = OPStackManager.ImplementationSetter({ + name: "L1StandardBridge", + info: OPStackManager.Implementation(address(_dso.l1StandardBridgeImpl()), L1StandardBridge.initialize.selector) + }); + + vm.broadcast(msg.sender); + opsm.setRelease({ _release: release, _isLatest: true, _setters: setters }); + + vm.label(address(opsm), "OPStackManager"); + _dso.set(_dso.opsm.selector, address(opsm)); + } + + // --- Core Contracts --- + + function deploySystemConfigImpl(DeployImplementationsInput, DeployImplementationsOutput _dso) public virtual { vm.broadcast(msg.sender); SystemConfig systemConfigImpl = new SystemConfig(); @@ -231,7 +381,13 @@ contract DeployImplementations is Script { _dso.set(_dso.systemConfigImpl.selector, address(systemConfigImpl)); } - function deployL1CrossDomainMessengerImpl(DeployImplementationsInput, DeployImplementationsOutput _dso) public { + function deployL1CrossDomainMessengerImpl( + DeployImplementationsInput, + DeployImplementationsOutput _dso + ) + public + virtual + { vm.broadcast(msg.sender); L1CrossDomainMessenger l1CrossDomainMessengerImpl = new L1CrossDomainMessenger(); @@ -239,7 +395,7 @@ contract DeployImplementations is Script { _dso.set(_dso.l1CrossDomainMessengerImpl.selector, address(l1CrossDomainMessengerImpl)); } - function deployL1ERC721BridgeImpl(DeployImplementationsInput, DeployImplementationsOutput _dso) public { + function deployL1ERC721BridgeImpl(DeployImplementationsInput, DeployImplementationsOutput _dso) public virtual { vm.broadcast(msg.sender); L1ERC721Bridge l1ERC721BridgeImpl = new L1ERC721Bridge(); @@ -247,7 +403,7 @@ contract DeployImplementations is Script { _dso.set(_dso.l1ERC721BridgeImpl.selector, address(l1ERC721BridgeImpl)); } - function deployL1StandardBridgeImpl(DeployImplementationsInput, DeployImplementationsOutput _dso) public { + function deployL1StandardBridgeImpl(DeployImplementationsInput, DeployImplementationsOutput _dso) public virtual { vm.broadcast(msg.sender); L1StandardBridge l1StandardBridgeImpl = new L1StandardBridge(); @@ -260,6 +416,7 @@ contract DeployImplementations is Script { DeployImplementationsOutput _dso ) public + virtual { vm.broadcast(msg.sender); OptimismMintableERC20Factory optimismMintableERC20FactoryImpl = new OptimismMintableERC20Factory(); @@ -268,6 +425,8 @@ contract DeployImplementations is Script { _dso.set(_dso.optimismMintableERC20FactoryImpl.selector, address(optimismMintableERC20FactoryImpl)); } + // --- Fault Proofs Contracts --- + // The fault proofs contracts are configured as follows: // - DisputeGameFactory: Proxied, bespoke per chain. // - AnchorStateRegistry: Proxied, bespoke per chain. @@ -288,21 +447,27 @@ contract DeployImplementations is Script { // - PreimageOracle (singleton) // - MIPS (singleton) - function deployOptimismPortalImpl(DeployImplementationsInput _dsi, DeployImplementationsOutput _dso) public { + function deployOptimismPortalImpl( + DeployImplementationsInput _dsi, + DeployImplementationsOutput _dso + ) + public + virtual + { uint256 proofMaturityDelaySeconds = _dsi.proofMaturityDelaySeconds(); uint256 disputeGameFinalityDelaySeconds = _dsi.disputeGameFinalityDelaySeconds(); vm.broadcast(msg.sender); - OptimismPortal2 optimismPortal2Impl = new OptimismPortal2({ + OptimismPortal2 optimismPortalImpl = new OptimismPortal2({ _proofMaturityDelaySeconds: proofMaturityDelaySeconds, _disputeGameFinalityDelaySeconds: disputeGameFinalityDelaySeconds }); - vm.label(address(optimismPortal2Impl), "OptimismPortal2Impl"); - _dso.set(_dso.optimismPortal2Impl.selector, address(optimismPortal2Impl)); + vm.label(address(optimismPortalImpl), "OptimismPortalImpl"); + _dso.set(_dso.optimismPortalImpl.selector, address(optimismPortalImpl)); } - function deployDelayedWETHImpl(DeployImplementationsInput _dsi, DeployImplementationsOutput _dso) public { + function deployDelayedWETHImpl(DeployImplementationsInput _dsi, DeployImplementationsOutput _dso) public virtual { uint256 withdrawalDelaySeconds = _dsi.withdrawalDelaySeconds(); vm.broadcast(msg.sender); @@ -312,7 +477,13 @@ contract DeployImplementations is Script { _dso.set(_dso.delayedWETHImpl.selector, address(delayedWETHImpl)); } - function deployPreimageOracleSingleton(DeployImplementationsInput _dsi, DeployImplementationsOutput _dso) public { + function deployPreimageOracleSingleton( + DeployImplementationsInput _dsi, + DeployImplementationsOutput _dso + ) + public + virtual + { uint256 minProposalSizeBytes = _dsi.minProposalSizeBytes(); uint256 challengePeriodSeconds = _dsi.challengePeriodSeconds(); @@ -324,7 +495,7 @@ contract DeployImplementations is Script { _dso.set(_dso.preimageOracleSingleton.selector, address(preimageOracleSingleton)); } - function deployMipsSingleton(DeployImplementationsInput, DeployImplementationsOutput _dso) public { + function deployMipsSingleton(DeployImplementationsInput, DeployImplementationsOutput _dso) public virtual { IPreimageOracle preimageOracle = IPreimageOracle(_dso.preimageOracleSingleton()); vm.broadcast(msg.sender); @@ -334,6 +505,20 @@ contract DeployImplementations is Script { _dso.set(_dso.mipsSingleton.selector, address(mipsSingleton)); } + function deployDisputeGameFactoryImpl( + DeployImplementationsInput, + DeployImplementationsOutput _dso + ) + public + virtual + { + vm.broadcast(msg.sender); + DisputeGameFactory disputeGameFactoryImpl = new DisputeGameFactory(); + + vm.label(address(disputeGameFactoryImpl), "DisputeGameFactoryImpl"); + _dso.set(_dso.disputeGameFactoryImpl.selector, address(disputeGameFactoryImpl)); + } + // -------- Utilities -------- function etchIOContracts() internal returns (DeployImplementationsInput dsi_, DeployImplementationsOutput dso_) { @@ -346,4 +531,108 @@ contract DeployImplementations is Script { dsi_ = DeployImplementationsInput(DeployUtils.toIOAddress(msg.sender, "optimism.DeployImplementationsInput")); dso_ = DeployImplementationsOutput(DeployUtils.toIOAddress(msg.sender, "optimism.DeployImplementationsOutput")); } + + function deployBytecode(bytes memory _bytecode, bytes32 _salt) public returns (address newContract_) { + assembly ("memory-safe") { + newContract_ := create2(0, add(_bytecode, 0x20), mload(_bytecode), _salt) + } + require(newContract_ != address(0), "DeployImplementations: create2 failed"); + } +} + +// Similar to how DeploySuperchain.s.sol contains a lot of comments to thoroughly document the script +// architecture, this comment block documents how to update the deploy scripts to support new features. +// +// Using the base scripts and contracts (DeploySuperchain, DeployImplementations, DeployOPChain, and +// the corresponding OPStackManager) deploys a standard chain. For nonstandard and in-development +// features we need to modify some or all of those contracts, and we do that via inheritance. Using +// interop as an example, they've made the following changes to L1 contracts: +// - `OptimismPortalInterop is OptimismPortal`: A different portal implementation is used, and +// it's ABI is the same. +// - `SystemConfigInterop is SystemConfig`: A different system config implementation is used, and +// it's initializer has a different signature. This signature is different because there is a +// new input parameter, the `dependencyManager`. +// - Because of the different system config initializer, there is a new input parameter (dependencyManager). +// +// Similar to how inheritance was used to develop the new portal and system config contracts, we use +// inheritance to modify up to all of the deployer contracts. For this interop example, what this +// means is we need: +// - An `OPStackManagerInterop is OPStackManager` that knows how to encode the calldata for the +// new system config initializer. +// - A `DeployImplementationsInterop is DeployImplementations` that: +// - Deploys OptimismPortalInterop instead of OptimismPortal. +// - Deploys SystemConfigInterop instead of SystemConfig. +// - Deploys OPStackManagerInterop instead of OPStackManager, which contains the updated logic +// for encoding the SystemConfig initializer. +// - Updates the OPSM release setter logic to use the updated initializer. +// - A `DeployOPChainInterop is DeployOPChain` that allows the updated input parameter to be passed. +// +// Most of the complexity in the above flow comes from the the new input for the updated SystemConfig +// initializer. If all function signatures were the same, all we'd have to change is the contract +// implementations that are deployed then set in the OPSM. For now, to simplify things until we +// resolve https://github.com/ethereum-optimism/optimism/issues/11783, we just assume this new role +// is the same as the proxy admin owner. +contract DeployImplementationsInterop is DeployImplementations { + function createOPSMContract( + DeployImplementationsInput _dsi, + DeployImplementationsOutput, + OPStackManager.Blueprints memory blueprints + ) + internal + override + returns (OPStackManager opsm_) + { + SuperchainConfig superchainConfigProxy = _dsi.superchainConfigProxy(); + ProtocolVersions protocolVersionsProxy = _dsi.protocolVersionsProxy(); + + vm.broadcast(msg.sender); + opsm_ = new OPStackManagerInterop({ + _superchainConfig: superchainConfigProxy, + _protocolVersions: protocolVersionsProxy, + _blueprints: blueprints + }); + } + + function deployOptimismPortalImpl( + DeployImplementationsInput _dsi, + DeployImplementationsOutput _dso + ) + public + override + { + uint256 proofMaturityDelaySeconds = _dsi.proofMaturityDelaySeconds(); + uint256 disputeGameFinalityDelaySeconds = _dsi.disputeGameFinalityDelaySeconds(); + + vm.broadcast(msg.sender); + OptimismPortalInterop optimismPortalImpl = new OptimismPortalInterop({ + _proofMaturityDelaySeconds: proofMaturityDelaySeconds, + _disputeGameFinalityDelaySeconds: disputeGameFinalityDelaySeconds + }); + + vm.label(address(optimismPortalImpl), "OptimismPortalImpl"); + _dso.set(_dso.optimismPortalImpl.selector, address(optimismPortalImpl)); + } + + function deploySystemConfigImpl(DeployImplementationsInput, DeployImplementationsOutput _dso) public override { + vm.broadcast(msg.sender); + SystemConfigInterop systemConfigImpl = new SystemConfigInterop(); + + vm.label(address(systemConfigImpl), "systemConfigImpl"); + _dso.set(_dso.systemConfigImpl.selector, address(systemConfigImpl)); + } + + function opsmSystemConfigSetter( + DeployImplementationsInput, + DeployImplementationsOutput _dso + ) + internal + view + override + returns (OPStackManager.ImplementationSetter memory) + { + return OPStackManager.ImplementationSetter({ + name: "SystemConfig", + info: OPStackManager.Implementation(address(_dso.systemConfigImpl()), SystemConfigInterop.initialize.selector) + }); + } } diff --git a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol index e42bd5df324d..17693f010a38 100644 --- a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol @@ -15,6 +15,7 @@ import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; +import { OPStackManager } from "src/L1/OPStackManager.sol"; import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; @@ -38,6 +39,7 @@ contract DeployOPChainInput { uint32 basefeeScalar; uint32 blobBaseFeeScalar; uint256 l2ChainId; + OPStackManager opsm; } bool public inputSet = false; @@ -59,6 +61,8 @@ contract DeployOPChainInput { require(_input.roles.unsafeBlockSigner != address(0), "DeployOPChainInput: null unsafeBlockSigner"); require(_input.roles.proposer != address(0), "DeployOPChainInput: null proposer"); require(_input.roles.challenger != address(0), "DeployOPChainInput: null challenger"); + require(_input.l2ChainId != 0 && _input.l2ChainId != block.chainid, "DeployOPChainInput: invalid l2ChainId"); + require(address(_input.opsm) != address(0), "DeployOPChainInput: null opsm"); inputSet = true; inputs = _input; @@ -117,6 +121,11 @@ contract DeployOPChainInput { assertInputSet(); return inputs.l2ChainId; } + + function opsm() public view returns (OPStackManager) { + assertInputSet(); + return inputs.opsm; + } } contract DeployOPChainOutput { @@ -298,10 +307,66 @@ contract DeployOPChain is Script { return dso.output(); } - function run(DeployOPChainInput _dsi, DeployOPChainOutput _dso) public view { + function run(DeployOPChainInput _dsi, DeployOPChainOutput _dso) public { require(_dsi.inputSet(), "DeployOPChain: input not set"); - // TODO call OP Stack Manager deploy method + OPStackManager opsm = _dsi.opsm(); + + OPStackManager.Roles memory roles = OPStackManager.Roles({ + opChainProxyAdminOwner: _dsi.opChainProxyAdminOwner(), + systemConfigOwner: _dsi.systemConfigOwner(), + batcher: _dsi.batcher(), + unsafeBlockSigner: _dsi.unsafeBlockSigner(), + proposer: _dsi.proposer(), + challenger: _dsi.challenger() + }); + OPStackManager.DeployInput memory deployInput = OPStackManager.DeployInput({ + roles: roles, + basefeeScalar: _dsi.basefeeScalar(), + blobBasefeeScalar: _dsi.blobBaseFeeScalar(), + l2ChainId: _dsi.l2ChainId() + }); + + vm.broadcast(msg.sender); + OPStackManager.DeployOutput memory deployOutput = opsm.deploy(deployInput); + + vm.label(address(deployOutput.opChainProxyAdmin), "opChainProxyAdmin"); + vm.label(address(deployOutput.addressManager), "addressManager"); + vm.label(address(deployOutput.l1ERC721BridgeProxy), "l1ERC721BridgeProxy"); + vm.label(address(deployOutput.systemConfigProxy), "systemConfigProxy"); + vm.label(address(deployOutput.optimismMintableERC20FactoryProxy), "optimismMintableERC20FactoryProxy"); + vm.label(address(deployOutput.l1StandardBridgeProxy), "l1StandardBridgeProxy"); + vm.label(address(deployOutput.l1CrossDomainMessengerProxy), "l1CrossDomainMessengerProxy"); + vm.label(address(deployOutput.optimismPortalProxy), "optimismPortalProxy"); + vm.label(address(deployOutput.disputeGameFactoryProxy), "disputeGameFactoryProxy"); + vm.label(address(deployOutput.disputeGameFactoryImpl), "disputeGameFactoryImpl"); + vm.label(address(deployOutput.anchorStateRegistryProxy), "anchorStateRegistryProxy"); + vm.label(address(deployOutput.anchorStateRegistryImpl), "anchorStateRegistryImpl"); + vm.label(address(deployOutput.faultDisputeGame), "faultDisputeGame"); + vm.label(address(deployOutput.permissionedDisputeGame), "permissionedDisputeGame"); + vm.label(address(deployOutput.delayedWETHPermissionedGameProxy), "delayedWETHPermissionedGameProxy"); + vm.label(address(deployOutput.delayedWETHPermissionlessGameProxy), "delayedWETHPermissionlessGameProxy"); + + _dso.set(_dso.opChainProxyAdmin.selector, address(deployOutput.opChainProxyAdmin)); + _dso.set(_dso.addressManager.selector, address(deployOutput.addressManager)); + _dso.set(_dso.l1ERC721BridgeProxy.selector, address(deployOutput.l1ERC721BridgeProxy)); + _dso.set(_dso.systemConfigProxy.selector, address(deployOutput.systemConfigProxy)); + _dso.set( + _dso.optimismMintableERC20FactoryProxy.selector, address(deployOutput.optimismMintableERC20FactoryProxy) + ); + _dso.set(_dso.l1StandardBridgeProxy.selector, address(deployOutput.l1StandardBridgeProxy)); + _dso.set(_dso.l1CrossDomainMessengerProxy.selector, address(deployOutput.l1CrossDomainMessengerProxy)); + _dso.set(_dso.optimismPortalProxy.selector, address(deployOutput.optimismPortalProxy)); + _dso.set(_dso.disputeGameFactoryProxy.selector, address(deployOutput.disputeGameFactoryProxy)); + _dso.set(_dso.disputeGameFactoryImpl.selector, address(deployOutput.disputeGameFactoryImpl)); + _dso.set(_dso.anchorStateRegistryProxy.selector, address(deployOutput.anchorStateRegistryProxy)); + _dso.set(_dso.anchorStateRegistryImpl.selector, address(deployOutput.anchorStateRegistryImpl)); + _dso.set(_dso.faultDisputeGame.selector, address(deployOutput.faultDisputeGame)); + _dso.set(_dso.permissionedDisputeGame.selector, address(deployOutput.permissionedDisputeGame)); + _dso.set(_dso.delayedWETHPermissionedGameProxy.selector, address(deployOutput.delayedWETHPermissionedGameProxy)); + _dso.set( + _dso.delayedWETHPermissionlessGameProxy.selector, address(deployOutput.delayedWETHPermissionlessGameProxy) + ); _dso.checkOutput(); } diff --git a/packages/contracts-bedrock/scripts/libraries/Solarray.sol b/packages/contracts-bedrock/scripts/libraries/Solarray.sol index d6049c5654f3..57ef9b320bb0 100644 --- a/packages/contracts-bedrock/scripts/libraries/Solarray.sol +++ b/packages/contracts-bedrock/scripts/libraries/Solarray.sol @@ -7,7 +7,7 @@ pragma solidity ^0.8.13; // since Solidity does not have great array UX. // // This library was generated using the `generator.py` script from the linked repo with the length -// set to 10, and then everything except the `addresses` functions was removed. +// set accordingly, and then everything except the `addresses` functions was removed. library Solarray { function addresses(address a) internal pure returns (address[] memory) { address[] memory arr = new address[](1); @@ -189,6 +189,38 @@ library Solarray { return arr; } + function addresses( + address a, + address b, + address c, + address d, + address e, + address f, + address g, + address h, + address i, + address j, + address k + ) + internal + pure + returns (address[] memory) + { + address[] memory arr = new address[](11); + arr[0] = a; + arr[1] = b; + arr[2] = c; + arr[3] = d; + arr[4] = e; + arr[5] = f; + arr[6] = g; + arr[7] = h; + arr[8] = i; + arr[9] = j; + arr[10] = k; + return arr; + } + function extend(address[] memory arr1, address[] memory arr2) internal pure returns (address[] memory newArr) { uint256 length1 = arr1.length; uint256 length2 = arr2.length; diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 96db34d38ed1..8ee179e7bd7c 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -32,8 +32,8 @@ "sourceCodeHash": "0xde4df0f9633dc0cdb1c9f634003ea5b0f7c5c1aebc407bc1b2f44c0ecf938649" }, "src/L1/OPStackManager.sol": { - "initCodeHash": "0x67bf02405bf1ca7d78c4215c350ad9c5c7b4cece35d9fab837f279d65f995c5d", - "sourceCodeHash": "0x8e272e707e383d516b8f1cce0ea29ff46a0eb448c8386fa146e6a43f3100042a" + "initCodeHash": "0xe1eab75651e3d81ad20ca01b1e7d373b25d716ee5f8841a56e56b4531a6e0e70", + "sourceCodeHash": "0x5182a2678dadb200dd255ecdfa395e5f7b1e1e27288e78ddf8802ab51ed2dd81" }, "src/L1/OptimismPortal.sol": { "initCodeHash": "0x6bf59539298b20221de6c51db21016be8d3278bdbe0be1cdd49638dc828e003e", diff --git a/packages/contracts-bedrock/snapshots/abi/OPStackManager.json b/packages/contracts-bedrock/snapshots/abi/OPStackManager.json index 3f3a48ded1ff..8180e2799c96 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPStackManager.json +++ b/packages/contracts-bedrock/snapshots/abi/OPStackManager.json @@ -2,63 +2,374 @@ { "inputs": [ { - "internalType": "uint256", - "name": "_l2ChainId", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_basefeeScalar", - "type": "uint32" + "internalType": "contract SuperchainConfig", + "name": "_superchainConfig", + "type": "address" }, { - "internalType": "uint32", - "name": "_blobBasefeeScalar", - "type": "uint32" + "internalType": "contract ProtocolVersions", + "name": "_protocolVersions", + "type": "address" }, { "components": [ { "internalType": "address", - "name": "proxyAdminOwner", + "name": "addressManager", + "type": "address" + }, + { + "internalType": "address", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "proxyAdmin", + "type": "address" + }, + { + "internalType": "address", + "name": "l1ChugSplashProxy", "type": "address" }, { "internalType": "address", - "name": "systemConfigOwner", + "name": "resolvedDelegateProxy", + "type": "address" + } + ], + "internalType": "struct OPStackManager.Blueprints", + "name": "_blueprints", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "blueprints", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "addressManager", "type": "address" }, { "internalType": "address", - "name": "batcher", + "name": "proxy", "type": "address" }, { "internalType": "address", - "name": "unsafeBlockSigner", + "name": "proxyAdmin", "type": "address" }, { "internalType": "address", - "name": "proposer", + "name": "l1ChugSplashProxy", "type": "address" }, { "internalType": "address", - "name": "challenger", + "name": "resolvedDelegateProxy", "type": "address" } ], - "internalType": "struct OPStackManager.Roles", - "name": "_roles", + "internalType": "struct OPStackManager.Blueprints", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "opChainProxyAdminOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "systemConfigOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "batcher", + "type": "address" + }, + { + "internalType": "address", + "name": "unsafeBlockSigner", + "type": "address" + }, + { + "internalType": "address", + "name": "proposer", + "type": "address" + }, + { + "internalType": "address", + "name": "challenger", + "type": "address" + } + ], + "internalType": "struct OPStackManager.Roles", + "name": "roles", + "type": "tuple" + }, + { + "internalType": "uint32", + "name": "basefeeScalar", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "blobBasefeeScalar", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "l2ChainId", + "type": "uint256" + } + ], + "internalType": "struct OPStackManager.DeployInput", + "name": "_input", "type": "tuple" } ], "name": "deploy", + "outputs": [ + { + "components": [ + { + "internalType": "contract ProxyAdmin", + "name": "opChainProxyAdmin", + "type": "address" + }, + { + "internalType": "contract AddressManager", + "name": "addressManager", + "type": "address" + }, + { + "internalType": "contract L1ERC721Bridge", + "name": "l1ERC721BridgeProxy", + "type": "address" + }, + { + "internalType": "contract SystemConfig", + "name": "systemConfigProxy", + "type": "address" + }, + { + "internalType": "contract OptimismMintableERC20Factory", + "name": "optimismMintableERC20FactoryProxy", + "type": "address" + }, + { + "internalType": "contract L1StandardBridge", + "name": "l1StandardBridgeProxy", + "type": "address" + }, + { + "internalType": "contract L1CrossDomainMessenger", + "name": "l1CrossDomainMessengerProxy", + "type": "address" + }, + { + "internalType": "contract OptimismPortal2", + "name": "optimismPortalProxy", + "type": "address" + }, + { + "internalType": "contract DisputeGameFactory", + "name": "disputeGameFactoryProxy", + "type": "address" + }, + { + "internalType": "contract DisputeGameFactory", + "name": "disputeGameFactoryImpl", + "type": "address" + }, + { + "internalType": "contract AnchorStateRegistry", + "name": "anchorStateRegistryProxy", + "type": "address" + }, + { + "internalType": "contract AnchorStateRegistry", + "name": "anchorStateRegistryImpl", + "type": "address" + }, + { + "internalType": "contract FaultDisputeGame", + "name": "faultDisputeGame", + "type": "address" + }, + { + "internalType": "contract PermissionedDisputeGame", + "name": "permissionedDisputeGame", + "type": "address" + }, + { + "internalType": "contract DelayedWETH", + "name": "delayedWETHPermissionedGameProxy", + "type": "address" + }, + { + "internalType": "contract DelayedWETH", + "name": "delayedWETHPermissionlessGameProxy", + "type": "address" + } + ], + "internalType": "struct OPStackManager.DeployOutput", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "name": "implementations", + "outputs": [ + { + "internalType": "address", + "name": "logic", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "initializer", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestRelease", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolVersions", + "outputs": [ + { + "internalType": "contract ProtocolVersions", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_release", + "type": "string" + }, + { + "internalType": "bool", + "name": "_isLatest", + "type": "bool" + }, + { + "components": [ + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "components": [ + { + "internalType": "address", + "name": "logic", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "initializer", + "type": "bytes4" + } + ], + "internalType": "struct OPStackManager.Implementation", + "name": "info", + "type": "tuple" + } + ], + "internalType": "struct OPStackManager.ImplementationSetter[]", + "name": "_setters", + "type": "tuple[]" + } + ], + "name": "setRelease", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "superchainConfig", + "outputs": [ + { + "internalType": "contract SuperchainConfig", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "systemConfigs", "outputs": [ { "internalType": "contract SystemConfig", - "name": "systemConfig_", + "name": "", "type": "address" } ], @@ -97,25 +408,105 @@ "name": "Deployed", "type": "event" }, + { + "inputs": [ + { + "internalType": "address", + "name": "who", + "type": "address" + } + ], + "name": "AddressHasNoCode", + "type": "error" + }, { "inputs": [ { "internalType": "string", - "name": "reason", + "name": "addressName", "type": "string" } ], + "name": "AddressMismatch", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "who", + "type": "address" + } + ], + "name": "AddressNotFound", + "type": "error" + }, + { + "inputs": [], + "name": "AlreadyReleased", + "type": "error" + }, + { + "inputs": [], + "name": "BytesArrayTooLong", + "type": "error" + }, + { + "inputs": [], "name": "DeploymentFailed", "type": "error" }, + { + "inputs": [], + "name": "EmptyInitcode", + "type": "error" + }, { "inputs": [], "name": "InvalidChainId", "type": "error" }, + { + "inputs": [ + { + "internalType": "string", + "name": "role", + "type": "string" + } + ], + "name": "InvalidRoleAddress", + "type": "error" + }, { "inputs": [], - "name": "NotImplemented", + "name": "NotABlueprint", + "type": "error" + }, + { + "inputs": [], + "name": "ReservedBitsSet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "UnexpectedPreambleData", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "UnsupportedERCVersion", "type": "error" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json b/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json new file mode 100644 index 000000000000..8180e2799c96 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json @@ -0,0 +1,512 @@ +[ + { + "inputs": [ + { + "internalType": "contract SuperchainConfig", + "name": "_superchainConfig", + "type": "address" + }, + { + "internalType": "contract ProtocolVersions", + "name": "_protocolVersions", + "type": "address" + }, + { + "components": [ + { + "internalType": "address", + "name": "addressManager", + "type": "address" + }, + { + "internalType": "address", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "proxyAdmin", + "type": "address" + }, + { + "internalType": "address", + "name": "l1ChugSplashProxy", + "type": "address" + }, + { + "internalType": "address", + "name": "resolvedDelegateProxy", + "type": "address" + } + ], + "internalType": "struct OPStackManager.Blueprints", + "name": "_blueprints", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "blueprints", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "addressManager", + "type": "address" + }, + { + "internalType": "address", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "proxyAdmin", + "type": "address" + }, + { + "internalType": "address", + "name": "l1ChugSplashProxy", + "type": "address" + }, + { + "internalType": "address", + "name": "resolvedDelegateProxy", + "type": "address" + } + ], + "internalType": "struct OPStackManager.Blueprints", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "opChainProxyAdminOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "systemConfigOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "batcher", + "type": "address" + }, + { + "internalType": "address", + "name": "unsafeBlockSigner", + "type": "address" + }, + { + "internalType": "address", + "name": "proposer", + "type": "address" + }, + { + "internalType": "address", + "name": "challenger", + "type": "address" + } + ], + "internalType": "struct OPStackManager.Roles", + "name": "roles", + "type": "tuple" + }, + { + "internalType": "uint32", + "name": "basefeeScalar", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "blobBasefeeScalar", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "l2ChainId", + "type": "uint256" + } + ], + "internalType": "struct OPStackManager.DeployInput", + "name": "_input", + "type": "tuple" + } + ], + "name": "deploy", + "outputs": [ + { + "components": [ + { + "internalType": "contract ProxyAdmin", + "name": "opChainProxyAdmin", + "type": "address" + }, + { + "internalType": "contract AddressManager", + "name": "addressManager", + "type": "address" + }, + { + "internalType": "contract L1ERC721Bridge", + "name": "l1ERC721BridgeProxy", + "type": "address" + }, + { + "internalType": "contract SystemConfig", + "name": "systemConfigProxy", + "type": "address" + }, + { + "internalType": "contract OptimismMintableERC20Factory", + "name": "optimismMintableERC20FactoryProxy", + "type": "address" + }, + { + "internalType": "contract L1StandardBridge", + "name": "l1StandardBridgeProxy", + "type": "address" + }, + { + "internalType": "contract L1CrossDomainMessenger", + "name": "l1CrossDomainMessengerProxy", + "type": "address" + }, + { + "internalType": "contract OptimismPortal2", + "name": "optimismPortalProxy", + "type": "address" + }, + { + "internalType": "contract DisputeGameFactory", + "name": "disputeGameFactoryProxy", + "type": "address" + }, + { + "internalType": "contract DisputeGameFactory", + "name": "disputeGameFactoryImpl", + "type": "address" + }, + { + "internalType": "contract AnchorStateRegistry", + "name": "anchorStateRegistryProxy", + "type": "address" + }, + { + "internalType": "contract AnchorStateRegistry", + "name": "anchorStateRegistryImpl", + "type": "address" + }, + { + "internalType": "contract FaultDisputeGame", + "name": "faultDisputeGame", + "type": "address" + }, + { + "internalType": "contract PermissionedDisputeGame", + "name": "permissionedDisputeGame", + "type": "address" + }, + { + "internalType": "contract DelayedWETH", + "name": "delayedWETHPermissionedGameProxy", + "type": "address" + }, + { + "internalType": "contract DelayedWETH", + "name": "delayedWETHPermissionlessGameProxy", + "type": "address" + } + ], + "internalType": "struct OPStackManager.DeployOutput", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "name": "implementations", + "outputs": [ + { + "internalType": "address", + "name": "logic", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "initializer", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestRelease", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolVersions", + "outputs": [ + { + "internalType": "contract ProtocolVersions", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_release", + "type": "string" + }, + { + "internalType": "bool", + "name": "_isLatest", + "type": "bool" + }, + { + "components": [ + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "components": [ + { + "internalType": "address", + "name": "logic", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "initializer", + "type": "bytes4" + } + ], + "internalType": "struct OPStackManager.Implementation", + "name": "info", + "type": "tuple" + } + ], + "internalType": "struct OPStackManager.ImplementationSetter[]", + "name": "_setters", + "type": "tuple[]" + } + ], + "name": "setRelease", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "superchainConfig", + "outputs": [ + { + "internalType": "contract SuperchainConfig", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "systemConfigs", + "outputs": [ + { + "internalType": "contract SystemConfig", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "l2ChainId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract SystemConfig", + "name": "systemConfig", + "type": "address" + } + ], + "name": "Deployed", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "who", + "type": "address" + } + ], + "name": "AddressHasNoCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "addressName", + "type": "string" + } + ], + "name": "AddressMismatch", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "who", + "type": "address" + } + ], + "name": "AddressNotFound", + "type": "error" + }, + { + "inputs": [], + "name": "AlreadyReleased", + "type": "error" + }, + { + "inputs": [], + "name": "BytesArrayTooLong", + "type": "error" + }, + { + "inputs": [], + "name": "DeploymentFailed", + "type": "error" + }, + { + "inputs": [], + "name": "EmptyInitcode", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidChainId", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "role", + "type": "string" + } + ], + "name": "InvalidRoleAddress", + "type": "error" + }, + { + "inputs": [], + "name": "NotABlueprint", + "type": "error" + }, + { + "inputs": [], + "name": "ReservedBitsSet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "UnexpectedPreambleData", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "UnsupportedERCVersion", + "type": "error" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OPStackManager.json b/packages/contracts-bedrock/snapshots/storageLayout/OPStackManager.json index 0637a088a01e..3ef385443c3d 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/OPStackManager.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/OPStackManager.json @@ -1 +1,30 @@ -[] \ No newline at end of file +[ + { + "bytes": "160", + "label": "blueprint", + "offset": 0, + "slot": "0", + "type": "struct OPStackManager.Blueprints" + }, + { + "bytes": "32", + "label": "latestRelease", + "offset": 0, + "slot": "5", + "type": "string" + }, + { + "bytes": "32", + "label": "implementations", + "offset": 0, + "slot": "6", + "type": "mapping(string => mapping(string => struct OPStackManager.Implementation))" + }, + { + "bytes": "32", + "label": "systemConfigs", + "offset": 0, + "slot": "7", + "type": "mapping(uint256 => contract SystemConfig)" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OPStackManagerInterop.json b/packages/contracts-bedrock/snapshots/storageLayout/OPStackManagerInterop.json new file mode 100644 index 000000000000..3ef385443c3d --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/OPStackManagerInterop.json @@ -0,0 +1,30 @@ +[ + { + "bytes": "160", + "label": "blueprint", + "offset": 0, + "slot": "0", + "type": "struct OPStackManager.Blueprints" + }, + { + "bytes": "32", + "label": "latestRelease", + "offset": 0, + "slot": "5", + "type": "string" + }, + { + "bytes": "32", + "label": "implementations", + "offset": 0, + "slot": "6", + "type": "mapping(string => mapping(string => struct OPStackManager.Implementation))" + }, + { + "bytes": "32", + "label": "systemConfigs", + "offset": 0, + "slot": "7", + "type": "mapping(uint256 => contract SystemConfig)" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/src/L1/OPStackManager.sol b/packages/contracts-bedrock/src/L1/OPStackManager.sol index bd798aa530b9..5c96cd6aeb8b 100644 --- a/packages/contracts-bedrock/src/L1/OPStackManager.sol +++ b/packages/contracts-bedrock/src/L1/OPStackManager.sol @@ -1,17 +1,40 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +import { Blueprint } from "src/libraries/Blueprint.sol"; + import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { Proxy } from "src/universal/Proxy.sol"; +import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; + +import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol"; +import { ResolvedDelegateProxy } from "src/legacy/ResolvedDelegateProxy.sol"; +import { AddressManager } from "src/legacy/AddressManager.sol"; + +import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; +import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; +import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; +import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; +import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; +import { GameTypes } from "src/dispute/lib/Types.sol"; + +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; +import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; +import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; +import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; +import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; /// @custom:proxied true contract OPStackManager is ISemver { - /// @custom:semver 1.0.0-beta.2 - string public constant version = "1.0.0-beta.2"; + // -------- Structs -------- /// @notice Represents the roles that can be set when deploying a standard OP Stack chain. struct Roles { - address proxyAdminOwner; + address opChainProxyAdminOwner; address systemConfigOwner; address batcher; address unsafeBlockSigner; @@ -19,39 +42,292 @@ contract OPStackManager is ISemver { address challenger; } + /// @notice The full set of inputs to deploy a new OP Stack chain. + struct DeployInput { + Roles roles; + uint32 basefeeScalar; + uint32 blobBasefeeScalar; + uint256 l2ChainId; + } + + /// @notice The full set of outputs from deploying a new OP Stack chain. + struct DeployOutput { + ProxyAdmin opChainProxyAdmin; + AddressManager addressManager; + L1ERC721Bridge l1ERC721BridgeProxy; + SystemConfig systemConfigProxy; + OptimismMintableERC20Factory optimismMintableERC20FactoryProxy; + L1StandardBridge l1StandardBridgeProxy; + L1CrossDomainMessenger l1CrossDomainMessengerProxy; + // Fault proof contracts below. + OptimismPortal2 optimismPortalProxy; + DisputeGameFactory disputeGameFactoryProxy; + DisputeGameFactory disputeGameFactoryImpl; + AnchorStateRegistry anchorStateRegistryProxy; + AnchorStateRegistry anchorStateRegistryImpl; + FaultDisputeGame faultDisputeGame; + PermissionedDisputeGame permissionedDisputeGame; + DelayedWETH delayedWETHPermissionedGameProxy; + DelayedWETH delayedWETHPermissionlessGameProxy; + } + + /// @notice The logic address and initializer selector for an implementation contract. + struct Implementation { + address logic; // Address containing the deployed logic contract. + bytes4 initializer; // Function selector for the initializer. + } + + /// @notice Used to set the implementation for a contract by mapping a contract + /// name to the implementation data. + struct ImplementationSetter { + string name; // Contract name. + Implementation info; // Implementation to set. + } + + /// @notice Addresses of ERC-5202 Blueprint contracts. There are used for deploying full size + /// contracts, to reduce the code size of this factory contract. If it deployed full contracts + /// using the `new Proxy()` syntax, the code size would get large fast, since this contract would + /// contain the bytecode of every contract it deploys. Therefore we instead use Blueprints to + /// reduce the code size of this contract. + struct Blueprints { + address addressManager; + address proxy; + address proxyAdmin; + address l1ChugSplashProxy; + address resolvedDelegateProxy; + } + + // -------- Constants and Variables -------- + + /// @custom:semver 1.0.0-beta.3 + string public constant version = "1.0.0-beta.3"; + + /// @notice Address of the SuperchainConfig contract shared by all chains. + SuperchainConfig public immutable superchainConfig; + + /// @notice Address of the ProtocolVersions contract shared by all chains. + ProtocolVersions public immutable protocolVersions; + + /// @notice Addresses of the Blueprint contracts. + /// This is internal because if public the autogenerated getter method would return a tuple of + /// addresses, but we want it to return a struct. + Blueprints internal blueprint; + + /// @notice The latest release of the OP Stack Manager, as a string of the format `op-contracts/vX.Y.Z`. + string public latestRelease; + + /// @notice Maps a release version to a contract name to it's implementation data. + mapping(string => mapping(string => Implementation)) public implementations; + + /// @notice Maps an L2 Chain ID to the SystemConfig for that chain. + mapping(uint256 => SystemConfig) public systemConfigs; + + // -------- Events -------- + /// @notice Emitted when a new OP Stack chain is deployed. /// @param l2ChainId The chain ID of the new chain. /// @param systemConfig The address of the new chain's SystemConfig contract. event Deployed(uint256 indexed l2ChainId, SystemConfig indexed systemConfig); + // -------- Errors -------- + + /// @notice Throw when two addresses do not match but are expected to. + error AddressMismatch(string addressName); + + /// @notice Thrown when an address is the zero address. + error AddressNotFound(address who); + + /// @notice Throw when a contract address has no code. + error AddressHasNoCode(address who); + + /// @notice Thrown when a release version is already set. + error AlreadyReleased(); + /// @notice Thrown when an invalid `l2ChainId` is provided to `deploy`. error InvalidChainId(); - /// @notice Thrown when a deployment fails. - error DeploymentFailed(string reason); + /// @notice Thrown when a role's address is not valid. + error InvalidRoleAddress(string role); - /// @notice Temporary error since the deploy method is not yet implemented. - error NotImplemented(); + // -------- Methods -------- - function deploy( - uint256 _l2ChainId, - uint32 _basefeeScalar, - uint32 _blobBasefeeScalar, - Roles calldata _roles - ) - external - view // This is only here to silence the compiler warning until the function is fully implemented. - returns (SystemConfig systemConfig_) - { - if (_l2ChainId == 0 || _l2ChainId == block.chainid) revert InvalidChainId(); + /// @notice OPSM is intended to be proxied when used in production. Since we are initially + /// focused on an OPSM version that unblocks interop, we are not proxying OPSM for simplicity. + /// Later, we will `_disableInitializers` in the constructor and replace any constructor logic + /// with an `initialize` function, which will be a breaking change to the OPSM interface. + constructor(SuperchainConfig _superchainConfig, ProtocolVersions _protocolVersions, Blueprints memory _blueprints) { + // TODO uncomment these as we add more validations to this contract, currently this will break a few tests. + // assertValidContractAddress(address(_superchainConfig)); + // assertValidContractAddress(address(_protocolVersions)); + // assertValidContractAddress(_blueprints.addressManager); + // assertValidContractAddress(_blueprints.proxy); + // assertValidContractAddress(_blueprints.proxyAdmin); + // assertValidContractAddress(_blueprints.l1ChugSplashProxy); + // assertValidContractAddress(_blueprints.resolvedDelegateProxy); + + superchainConfig = _superchainConfig; + protocolVersions = _protocolVersions; + blueprint = _blueprints; + } + + /// @notice Callable by the OPSM owner to release a set of implementation contracts for a given + /// release version. This must be called with `_isLatest` set to true before any chains can be deployed. + /// @param _release The release version to set implementations for, of the format `op-contracts/vX.Y.Z`. + /// @param _isLatest Whether the release version is the latest released version. This is + /// significant because the latest version is used to deploy chains in the `deploy` function. + /// @param _setters The set of implementations to set for the release version. + function setRelease(string memory _release, bool _isLatest, ImplementationSetter[] calldata _setters) external { + // TODO Add auth to this method. + + if (_isLatest) latestRelease = _release; + + for (uint256 i = 0; i < _setters.length; i++) { + ImplementationSetter calldata setter = _setters[i]; + Implementation storage impl = implementations[_release][setter.name]; + if (impl.logic != address(0)) revert AlreadyReleased(); + + impl.initializer = setter.info.initializer; + impl.logic = setter.info.logic; + } + } + + function deploy(DeployInput calldata _input) external returns (DeployOutput memory) { + assertValidInputs(_input); + + // TODO Determine how we want to choose salt, e.g. are we concerned about chain ID squatting + // since this approach means a chain ID can only be used once. + uint256 l2ChainId = _input.l2ChainId; + bytes32 salt = bytes32(_input.l2ChainId); + DeployOutput memory output; + + // -------- Deploy Chain Singletons -------- + + // The ProxyAdmin is the owner of all proxies for the chain. We temporarily set the owner to + // this contract, and then transfer ownership to the specified owner at the end of deployment. + // The AddressManager is used to store the implementation for the L1CrossDomainMessenger + // due to it's usage of the legacy ResolvedDelegateProxy. + output.addressManager = AddressManager(Blueprint.deployFrom(blueprint.addressManager, salt)); + output.opChainProxyAdmin = + ProxyAdmin(Blueprint.deployFrom(blueprint.proxyAdmin, salt, abi.encode(address(this)))); + output.opChainProxyAdmin.setAddressManager(output.addressManager); + + // -------- Deploy Proxy Contracts -------- + + // Deploy ERC-1967 proxied contracts. + output.l1ERC721BridgeProxy = L1ERC721Bridge(deployProxy(l2ChainId, output.opChainProxyAdmin, "L1ERC721Bridge")); + output.optimismPortalProxy = + OptimismPortal2(payable(deployProxy(l2ChainId, output.opChainProxyAdmin, "OptimismPortal"))); + output.systemConfigProxy = SystemConfig(deployProxy(l2ChainId, output.opChainProxyAdmin, "SystemConfig")); + output.optimismMintableERC20FactoryProxy = OptimismMintableERC20Factory( + deployProxy(l2ChainId, output.opChainProxyAdmin, "OptimismMintableERC20Factory") + ); + + // Deploy legacy proxied contracts. + output.l1StandardBridgeProxy = L1StandardBridge( + payable(Blueprint.deployFrom(blueprint.l1ChugSplashProxy, salt, abi.encode(output.opChainProxyAdmin))) + ); + output.opChainProxyAdmin.setProxyType(address(output.l1StandardBridgeProxy), ProxyAdmin.ProxyType.CHUGSPLASH); + + string memory contractName = "OVM_L1CrossDomainMessenger"; + output.l1CrossDomainMessengerProxy = L1CrossDomainMessenger( + Blueprint.deployFrom(blueprint.resolvedDelegateProxy, salt, abi.encode(output.addressManager, contractName)) + ); + output.opChainProxyAdmin.setProxyType( + address(output.l1CrossDomainMessengerProxy), ProxyAdmin.ProxyType.RESOLVED + ); + output.opChainProxyAdmin.setImplementationName(address(output.l1CrossDomainMessengerProxy), contractName); + + // Now that all proxies are deployed, we can transfer ownership of the AddressManager to the ProxyAdmin. + output.addressManager.transferOwnership(address(output.opChainProxyAdmin)); + + // -------- Set and Initialize Proxy Implementations -------- + Implementation storage impl; + bytes memory data; + + impl = getLatestImplementation("L1ERC721Bridge"); + data = encodeL1ERC721BridgeInitializer(impl.initializer, output); + upgradeAndCall(output.opChainProxyAdmin, address(output.l1ERC721BridgeProxy), impl.logic, data); + + impl = getLatestImplementation("OptimismPortal"); + data = encodeOptimismPortalInitializer(impl.initializer, output); + upgradeAndCall(output.opChainProxyAdmin, address(output.optimismPortalProxy), impl.logic, data); + + impl = getLatestImplementation("SystemConfig"); + data = encodeSystemConfigInitializer(impl.initializer, _input, output); + upgradeAndCall(output.opChainProxyAdmin, address(output.systemConfigProxy), impl.logic, data); + + impl = getLatestImplementation("OptimismMintableERC20Factory"); + data = encodeOptimismMintableERC20FactoryInitializer(impl.initializer, output); + upgradeAndCall(output.opChainProxyAdmin, address(output.optimismMintableERC20FactoryProxy), impl.logic, data); + + impl = getLatestImplementation("L1CrossDomainMessenger"); + // TODO add this check back in + // require( + // impl.logic == referenceAddressManager.getAddress("OVM_L1CrossDomainMessenger"), + // "OpStackManager: L1CrossDomainMessenger implementation mismatch" + // ); + data = encodeL1CrossDomainMessengerInitializer(impl.initializer, output); + upgradeAndCall(output.opChainProxyAdmin, address(output.l1CrossDomainMessengerProxy), impl.logic, data); + + impl = getLatestImplementation("L1StandardBridge"); + data = encodeL1StandardBridgeInitializer(impl.initializer, output); + upgradeAndCall(output.opChainProxyAdmin, address(output.l1StandardBridgeProxy), impl.logic, data); - // Silence compiler warnings. - _roles; - _basefeeScalar; - _blobBasefeeScalar; - systemConfig_; + // -------- TODO: Placeholders -------- + // For contracts we don't yet deploy, we set the outputs to dummy proxies so they have code to pass assertions. + output.disputeGameFactoryProxy = DisputeGameFactory(deployProxy(l2ChainId, output.opChainProxyAdmin, "1")); + output.disputeGameFactoryImpl = DisputeGameFactory(deployProxy(l2ChainId, output.opChainProxyAdmin, "2")); + output.anchorStateRegistryProxy = AnchorStateRegistry(deployProxy(l2ChainId, output.opChainProxyAdmin, "3")); + output.anchorStateRegistryImpl = AnchorStateRegistry(deployProxy(l2ChainId, output.opChainProxyAdmin, "4")); + output.faultDisputeGame = FaultDisputeGame(deployProxy(l2ChainId, output.opChainProxyAdmin, "5")); + output.permissionedDisputeGame = PermissionedDisputeGame(deployProxy(l2ChainId, output.opChainProxyAdmin, "6")); + output.delayedWETHPermissionedGameProxy = + DelayedWETH(payable(deployProxy(l2ChainId, output.opChainProxyAdmin, "7"))); + output.delayedWETHPermissionlessGameProxy = + DelayedWETH(payable(deployProxy(l2ChainId, output.opChainProxyAdmin, "8"))); - revert NotImplemented(); + // -------- Finalize Deployment -------- + // Transfer ownership of the ProxyAdmin from this contract to the specified owner. + output.opChainProxyAdmin.transferOwnership(_input.roles.opChainProxyAdminOwner); + + // Correctness checks. + // TODO these currently fail in tests because the tests use dummy implementation addresses that have no code. + // if (output.systemConfigProxy.owner() != _input.roles.systemConfigOwner) { + // revert AddressMismatch("systemConfigOwner"); + // } + // if (output.systemConfigProxy.l1CrossDomainMessenger() != address(output.l1CrossDomainMessengerProxy)) { + // revert AddressMismatch("l1CrossDomainMessengerProxy"); + // } + // if (output.systemConfigProxy.l1ERC721Bridge() != address(output.l1ERC721BridgeProxy)) { + // revert AddressMismatch("l1ERC721BridgeProxy"); + // } + // if (output.systemConfigProxy.l1StandardBridge() != address(output.l1StandardBridgeProxy)) { + // revert AddressMismatch("l1StandardBridgeProxy"); + // } + // if (output.systemConfigProxy.optimismPortal() != address(output.optimismPortalProxy)) { + // revert AddressMismatch("optimismPortalProxy"); + // } + // if ( + // output.systemConfigProxy.optimismMintableERC20Factory() != + // address(output.optimismMintableERC20FactoryProxy) + // ) revert AddressMismatch("optimismMintableERC20FactoryProxy"); + + return output; + } + + // -------- Utilities -------- + + /// @notice Verifies that all inputs are valid and reverts if any are invalid. + /// Typically the proxy admin owner is expected to have code, but this is not enforced here. + function assertValidInputs(DeployInput calldata _input) internal view { + if (_input.l2ChainId == 0 || _input.l2ChainId == block.chainid) revert InvalidChainId(); + + if (_input.roles.opChainProxyAdminOwner == address(0)) revert InvalidRoleAddress("opChainProxyAdminOwner"); + if (_input.roles.systemConfigOwner == address(0)) revert InvalidRoleAddress("systemConfigOwner"); + if (_input.roles.batcher == address(0)) revert InvalidRoleAddress("batcher"); + if (_input.roles.unsafeBlockSigner == address(0)) revert InvalidRoleAddress("unsafeBlockSigner"); + if (_input.roles.proposer == address(0)) revert InvalidRoleAddress("proposer"); + if (_input.roles.challenger == address(0)) revert InvalidRoleAddress("challenger"); } /// @notice Maps an L2 chain ID to an L1 batch inbox address as defined by the standard @@ -64,4 +340,188 @@ contract OPStackManager is ISemver { bytes19 first19Bytes = bytes19(hashedChainId); return address(uint160(bytes20(bytes.concat(versionByte, first19Bytes)))); } + + /// @notice Deterministically deploys a new proxy contract owned by the provided ProxyAdmin. + /// The salt is computed as a function of the L2 chain ID and the contract name. This is required + /// because we deploy many identical proxies, so they each require a unique salt for determinism. + function deployProxy( + uint256 _l2ChainId, + ProxyAdmin _proxyAdmin, + string memory _contractName + ) + internal + returns (address) + { + bytes32 salt = keccak256(abi.encode(_l2ChainId, _contractName)); + return Blueprint.deployFrom(blueprint.proxy, salt, abi.encode(_proxyAdmin)); + } + + /// @notice Returns the implementation data for a contract name. + function getLatestImplementation(string memory _name) internal view returns (Implementation storage) { + return implementations[latestRelease][_name]; + } + + // -------- Initializer Encoding -------- + + /// @notice Helper method for encoding the L1ERC721Bridge initializer data. + function encodeL1ERC721BridgeInitializer( + bytes4 _selector, + DeployOutput memory _output + ) + internal + view + virtual + returns (bytes memory) + { + return abi.encodeWithSelector(_selector, _output.l1CrossDomainMessengerProxy, superchainConfig); + } + + /// @notice Helper method for encoding the OptimismPortal initializer data. + function encodeOptimismPortalInitializer( + bytes4 _selector, + DeployOutput memory _output + ) + internal + view + virtual + returns (bytes memory) + { + _output; + // TODO make GameTypes.CANNON an input once FPs are supported + return abi.encodeWithSelector( + _selector, _output.disputeGameFactoryProxy, _output.systemConfigProxy, superchainConfig, GameTypes.CANNON + ); + } + + /// @notice Helper method for encoding the SystemConfig initializer data. + function encodeSystemConfigInitializer( + bytes4 selector, + DeployInput memory _input, + DeployOutput memory _output + ) + internal + pure + virtual + returns (bytes memory) + { + (ResourceMetering.ResourceConfig memory referenceResourceConfig, SystemConfig.Addresses memory opChainAddrs) = + defaultSystemConfigParams(selector, _input, _output); + + return abi.encodeWithSelector( + selector, + _input.roles.systemConfigOwner, + _input.basefeeScalar, + _input.blobBasefeeScalar, + bytes32(uint256(uint160(_input.roles.batcher))), // batcherHash + 30_000_000, // gasLimit, TODO should this be an input? + _input.roles.unsafeBlockSigner, + referenceResourceConfig, + chainIdToBatchInboxAddress(_input.l2ChainId), + opChainAddrs + ); + } + + /// @notice Helper method for encoding the OptimismMintableERC20Factory initializer data. + function encodeOptimismMintableERC20FactoryInitializer( + bytes4 _selector, + DeployOutput memory _output + ) + internal + pure + virtual + returns (bytes memory) + { + return abi.encodeWithSelector(_selector, _output.l1StandardBridgeProxy); + } + + /// @notice Helper method for encoding the L1CrossDomainMessenger initializer data. + function encodeL1CrossDomainMessengerInitializer( + bytes4 _selector, + DeployOutput memory _output + ) + internal + view + virtual + returns (bytes memory) + { + return + abi.encodeWithSelector(_selector, superchainConfig, _output.optimismPortalProxy, _output.systemConfigProxy); + } + + /// @notice Helper method for encoding the L1StandardBridge initializer data. + function encodeL1StandardBridgeInitializer( + bytes4 _selector, + DeployOutput memory _output + ) + internal + view + virtual + returns (bytes memory) + { + return abi.encodeWithSelector( + _selector, _output.l1CrossDomainMessengerProxy, superchainConfig, _output.systemConfigProxy + ); + } + + /// @notice Returns default, standard config arguments for the SystemConfig initializer. + /// This is used by subclasses to reduce code duplication. + function defaultSystemConfigParams( + bytes4, /* selector */ + DeployInput memory, /* _input */ + DeployOutput memory _output + ) + internal + pure + virtual + returns (ResourceMetering.ResourceConfig memory, SystemConfig.Addresses memory) + { + // TODO do any of these need to be configurable? are these values correct? + ResourceMetering.ResourceConfig memory referenceResourceConfig = ResourceMetering.ResourceConfig({ + maxResourceLimit: 2e7, + elasticityMultiplier: 10, + baseFeeMaxChangeDenominator: 8, + minimumBaseFee: 1e9, + systemTxMaxGas: 1e6, + maximumBaseFee: 340282366920938463463374607431768211455 + }); + + SystemConfig.Addresses memory opChainAddrs = SystemConfig.Addresses({ + l1CrossDomainMessenger: address(_output.l1CrossDomainMessengerProxy), + l1ERC721Bridge: address(_output.l1ERC721BridgeProxy), + l1StandardBridge: address(_output.l1StandardBridgeProxy), + disputeGameFactory: address(_output.disputeGameFactoryProxy), + optimismPortal: address(_output.optimismPortalProxy), + optimismMintableERC20Factory: address(_output.optimismMintableERC20FactoryProxy), + gasPayingToken: address(0) + }); + + return (referenceResourceConfig, opChainAddrs); + } + + /// @notice Makes an external call to the target to initialize the proxy with the specified data. + /// First performs safety checks to ensure the target, implementation, and proxy admin are valid. + function upgradeAndCall( + ProxyAdmin _proxyAdmin, + address _target, + address _implementation, + bytes memory _data + ) + internal + { + assertValidContractAddress(address(_proxyAdmin)); + assertValidContractAddress(_target); + assertValidContractAddress(_implementation); + + _proxyAdmin.upgradeAndCall(payable(address(_target)), _implementation, _data); + } + + function assertValidContractAddress(address _who) internal view { + if (_who == address(0)) revert AddressNotFound(_who); + if (_who.code.length == 0) revert AddressHasNoCode(_who); + } + + /// @notice Returns the blueprint contract addresses. + function blueprints() public view returns (Blueprints memory) { + return blueprint; + } } diff --git a/packages/contracts-bedrock/src/L1/OPStackManagerInterop.sol b/packages/contracts-bedrock/src/L1/OPStackManagerInterop.sol new file mode 100644 index 000000000000..e9fa44c90f9b --- /dev/null +++ b/packages/contracts-bedrock/src/L1/OPStackManagerInterop.sol @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { OPStackManager } from "src/L1/OPStackManager.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; +import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { SystemConfigInterop } from "src/L1/SystemConfigInterop.sol"; + +/// @custom:proxied TODO this is not proxied yet. +contract OPStackManagerInterop is OPStackManager { + constructor( + SuperchainConfig _superchainConfig, + ProtocolVersions _protocolVersions, + Blueprints memory _blueprints + ) + OPStackManager(_superchainConfig, _protocolVersions, _blueprints) + { } + + // The `SystemConfigInterop` contract has an extra `address _dependencyManager` argument + // that we must account for. + function encodeSystemConfigInitializer( + bytes4 selector, + DeployInput memory _input, + DeployOutput memory _output + ) + internal + pure + virtual + override + returns (bytes memory) + { + (ResourceMetering.ResourceConfig memory referenceResourceConfig, SystemConfig.Addresses memory opChainAddrs) = + defaultSystemConfigParams(selector, _input, _output); + + // TODO For now we assume that the dependency manager is the same as the proxy admin owner. + // This is currently undefined since it's not part of the standard config, so we may need + // to update where this value is pulled from in the future. To support a different dependency + // manager in this contract without an invasive change of redefining the `Roles` struct, + // we will make the change described in https://github.com/ethereum-optimism/optimism/issues/11783. + address dependencyManager = address(_input.roles.opChainProxyAdminOwner); + + return abi.encodeWithSelector( + selector, + _input.roles.systemConfigOwner, + _input.basefeeScalar, + _input.blobBasefeeScalar, + bytes32(uint256(uint160(_input.roles.batcher))), // batcherHash + 30_000_000, // gasLimit TODO make this configurable? + _input.roles.unsafeBlockSigner, + referenceResourceConfig, + chainIdToBatchInboxAddress(_input.l2ChainId), + opChainAddrs, + dependencyManager + ); + } +} diff --git a/packages/contracts-bedrock/test/DeployImplementations.t.sol b/packages/contracts-bedrock/test/DeployImplementations.t.sol index 4a6adfa6edc9..dc51da5982f1 100644 --- a/packages/contracts-bedrock/test/DeployImplementations.t.sol +++ b/packages/contracts-bedrock/test/DeployImplementations.t.sol @@ -6,7 +6,11 @@ import { Test } from "forge-std/Test.sol"; import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { MIPS } from "src/cannon/MIPS.sol"; +import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; +import { OPStackManager } from "src/L1/OPStackManager.sol"; import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; @@ -17,6 +21,7 @@ import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC2 import { DeployImplementationsInput, DeployImplementations, + DeployImplementationsInterop, DeployImplementationsOutput } from "scripts/DeployImplementations.s.sol"; @@ -28,7 +33,10 @@ contract DeployImplementationsInput_Test is Test { minProposalSizeBytes: 200, challengePeriodSeconds: 300, proofMaturityDelaySeconds: 400, - disputeGameFinalityDelaySeconds: 500 + disputeGameFinalityDelaySeconds: 500, + release: "op-contracts/latest", + superchainConfigProxy: SuperchainConfig(makeAddr("superchainConfigProxy")), + protocolVersionsProxy: ProtocolVersions(makeAddr("protocolVersionsProxy")) }); function setUp() public { @@ -80,7 +88,8 @@ contract DeployImplementationsOutput_Test is Test { function test_set_succeeds() public { DeployImplementationsOutput.Output memory output = DeployImplementationsOutput.Output({ - optimismPortal2Impl: OptimismPortal2(payable(makeAddr("optimismPortal2Impl"))), + opsm: OPStackManager(makeAddr("opsm")), + optimismPortalImpl: OptimismPortal2(payable(makeAddr("optimismPortalImpl"))), delayedWETHImpl: DelayedWETH(payable(makeAddr("delayedWETHImpl"))), preimageOracleSingleton: PreimageOracle(makeAddr("preimageOracleSingleton")), mipsSingleton: MIPS(makeAddr("mipsSingleton")), @@ -88,10 +97,12 @@ contract DeployImplementationsOutput_Test is Test { l1CrossDomainMessengerImpl: L1CrossDomainMessenger(makeAddr("l1CrossDomainMessengerImpl")), l1ERC721BridgeImpl: L1ERC721Bridge(makeAddr("l1ERC721BridgeImpl")), l1StandardBridgeImpl: L1StandardBridge(payable(makeAddr("l1StandardBridgeImpl"))), - optimismMintableERC20FactoryImpl: OptimismMintableERC20Factory(makeAddr("optimismMintableERC20FactoryImpl")) + optimismMintableERC20FactoryImpl: OptimismMintableERC20Factory(makeAddr("optimismMintableERC20FactoryImpl")), + disputeGameFactoryImpl: DisputeGameFactory(makeAddr("disputeGameFactoryImpl")) }); - vm.etch(address(output.optimismPortal2Impl), hex"01"); + vm.etch(address(output.opsm), hex"01"); + vm.etch(address(output.optimismPortalImpl), hex"01"); vm.etch(address(output.delayedWETHImpl), hex"01"); vm.etch(address(output.preimageOracleSingleton), hex"01"); vm.etch(address(output.mipsSingleton), hex"01"); @@ -100,8 +111,9 @@ contract DeployImplementationsOutput_Test is Test { vm.etch(address(output.l1ERC721BridgeImpl), hex"01"); vm.etch(address(output.l1StandardBridgeImpl), hex"01"); vm.etch(address(output.optimismMintableERC20FactoryImpl), hex"01"); - - dso.set(dso.optimismPortal2Impl.selector, address(output.optimismPortal2Impl)); + vm.etch(address(output.disputeGameFactoryImpl), hex"01"); + dso.set(dso.opsm.selector, address(output.opsm)); + dso.set(dso.optimismPortalImpl.selector, address(output.optimismPortalImpl)); dso.set(dso.delayedWETHImpl.selector, address(output.delayedWETHImpl)); dso.set(dso.preimageOracleSingleton.selector, address(output.preimageOracleSingleton)); dso.set(dso.mipsSingleton.selector, address(output.mipsSingleton)); @@ -110,8 +122,10 @@ contract DeployImplementationsOutput_Test is Test { dso.set(dso.l1ERC721BridgeImpl.selector, address(output.l1ERC721BridgeImpl)); dso.set(dso.l1StandardBridgeImpl.selector, address(output.l1StandardBridgeImpl)); dso.set(dso.optimismMintableERC20FactoryImpl.selector, address(output.optimismMintableERC20FactoryImpl)); + dso.set(dso.disputeGameFactoryImpl.selector, address(output.disputeGameFactoryImpl)); - assertEq(address(output.optimismPortal2Impl), address(dso.optimismPortal2Impl()), "100"); + assertEq(address(output.opsm), address(dso.opsm()), "50"); + assertEq(address(output.optimismPortalImpl), address(dso.optimismPortalImpl()), "100"); assertEq(address(output.delayedWETHImpl), address(dso.delayedWETHImpl()), "200"); assertEq(address(output.preimageOracleSingleton), address(dso.preimageOracleSingleton()), "300"); assertEq(address(output.mipsSingleton), address(dso.mipsSingleton()), "400"); @@ -122,6 +136,7 @@ contract DeployImplementationsOutput_Test is Test { assertEq( address(output.optimismMintableERC20FactoryImpl), address(dso.optimismMintableERC20FactoryImpl()), "900" ); + assertEq(address(output.disputeGameFactoryImpl), address(dso.disputeGameFactoryImpl()), "950"); assertEq(keccak256(abi.encode(output)), keccak256(abi.encode(dso.output())), "1000"); } @@ -130,7 +145,7 @@ contract DeployImplementationsOutput_Test is Test { bytes memory expectedErr = "DeployUtils: zero address"; vm.expectRevert(expectedErr); - dso.optimismPortal2Impl(); + dso.optimismPortalImpl(); vm.expectRevert(expectedErr); dso.delayedWETHImpl(); @@ -155,15 +170,18 @@ contract DeployImplementationsOutput_Test is Test { vm.expectRevert(expectedErr); dso.optimismMintableERC20FactoryImpl(); + + vm.expectRevert(expectedErr); + dso.disputeGameFactoryImpl(); } function test_getters_whenAddrHasNoCode_reverts() public { address emptyAddr = makeAddr("emptyAddr"); bytes memory expectedErr = bytes(string.concat("DeployUtils: no code at ", vm.toString(emptyAddr))); - dso.set(dso.optimismPortal2Impl.selector, emptyAddr); + dso.set(dso.optimismPortalImpl.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.optimismPortal2Impl(); + dso.optimismPortalImpl(); dso.set(dso.delayedWETHImpl.selector, emptyAddr); vm.expectRevert(expectedErr); @@ -210,14 +228,24 @@ contract DeployImplementations_Test is Test { minProposalSizeBytes: 200, challengePeriodSeconds: 300, proofMaturityDelaySeconds: 400, - disputeGameFinalityDelaySeconds: 500 + disputeGameFinalityDelaySeconds: 500, + release: "op-contracts/latest", + superchainConfigProxy: SuperchainConfig(makeAddr("superchainConfigProxy")), + protocolVersionsProxy: ProtocolVersions(makeAddr("protocolVersionsProxy")) }); - function setUp() public { + function setUp() public virtual { deployImplementations = new DeployImplementations(); (dsi, dso) = deployImplementations.getIOContracts(); } + // By deploying the `DeployImplementations` contract with this virtual function, we provide a + // hook that child contracts can override to return a different implementation of the contract. + // This lets us test e.g. the `DeployImplementationsInterop` contract without duplicating test code. + function createDeployImplementationsContract() internal virtual returns (DeployImplementations) { + return new DeployImplementations(); + } + function test_run_succeeds(DeployImplementationsInput.Input memory _input) public { // This is a requirement in the PreimageOracle contract. _input.challengePeriodSeconds = bound(_input.challengePeriodSeconds, 0, type(uint64).max); @@ -232,7 +260,7 @@ contract DeployImplementations_Test is Test { assertEq(_input.disputeGameFinalityDelaySeconds, dsi.disputeGameFinalityDelaySeconds(), "500"); // Assert that individual output fields were properly set based on the output struct. - assertEq(address(output.optimismPortal2Impl), address(dso.optimismPortal2Impl()), "600"); + assertEq(address(output.optimismPortalImpl), address(dso.optimismPortalImpl()), "600"); assertEq(address(output.delayedWETHImpl), address(dso.delayedWETHImpl()), "700"); assertEq(address(output.preimageOracleSingleton), address(dso.preimageOracleSingleton()), "800"); assertEq(address(output.mipsSingleton), address(dso.mipsSingleton()), "900"); @@ -243,6 +271,7 @@ contract DeployImplementations_Test is Test { assertEq( address(output.optimismMintableERC20FactoryImpl), address(dso.optimismMintableERC20FactoryImpl()), "1400" ); + assertEq(address(output.disputeGameFactoryImpl), address(dso.disputeGameFactoryImpl()), "1450"); // Assert that the full input and output structs were properly set. assertEq(keccak256(abi.encode(_input)), keccak256(abi.encode(DeployImplementationsInput(dsi).input())), "1500"); @@ -254,9 +283,9 @@ contract DeployImplementations_Test is Test { assertEq(output.delayedWETHImpl.delay(), _input.withdrawalDelaySeconds, "1700"); assertEq(output.preimageOracleSingleton.challengePeriod(), _input.challengePeriodSeconds, "1800"); assertEq(output.preimageOracleSingleton.minProposalSize(), _input.minProposalSizeBytes, "1900"); - assertEq(output.optimismPortal2Impl.proofMaturityDelaySeconds(), _input.proofMaturityDelaySeconds, "2000"); + assertEq(output.optimismPortalImpl.proofMaturityDelaySeconds(), _input.proofMaturityDelaySeconds, "2000"); assertEq( - output.optimismPortal2Impl.disputeGameFinalityDelaySeconds(), _input.disputeGameFinalityDelaySeconds, "2100" + output.optimismPortalImpl.disputeGameFinalityDelaySeconds(), _input.disputeGameFinalityDelaySeconds, "2100" ); // Architecture assertions. @@ -273,3 +302,9 @@ contract DeployImplementations_Test is Test { deployImplementations.run(input); } } + +contract DeployImplementationsInterop_Test is DeployImplementations_Test { + function createDeployImplementationsContract() internal override returns (DeployImplementations) { + return new DeployImplementationsInterop(); + } +} diff --git a/packages/contracts-bedrock/test/DeployOPChain.t.sol b/packages/contracts-bedrock/test/DeployOPChain.t.sol index 5b4b60d175c4..a9fde919d3d7 100644 --- a/packages/contracts-bedrock/test/DeployOPChain.t.sol +++ b/packages/contracts-bedrock/test/DeployOPChain.t.sol @@ -3,6 +3,15 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; +import { DeploySuperchainInput, DeploySuperchain, DeploySuperchainOutput } from "scripts/DeploySuperchain.s.sol"; +import { + DeployImplementationsInput, + DeployImplementations, + DeployImplementationsInterop, + DeployImplementationsOutput +} from "scripts/DeployImplementations.s.sol"; +import { DeployOPChainInput, DeployOPChain, DeployOPChainOutput } from "scripts/DeployOPChain.s.sol"; + import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { AddressManager } from "src/legacy/AddressManager.sol"; @@ -12,6 +21,9 @@ import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { ProtocolVersions, ProtocolVersion } from "src/L1/ProtocolVersions.sol"; +import { OPStackManager } from "src/L1/OPStackManager.sol"; import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; @@ -19,8 +31,6 @@ import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; -import { DeployOPChainInput, DeployOPChain, DeployOPChainOutput } from "scripts/DeployOPChain.s.sol"; - contract DeployOPChainInput_Test is Test { DeployOPChainInput dsi; @@ -35,7 +45,8 @@ contract DeployOPChainInput_Test is Test { }), basefeeScalar: 100, blobBaseFeeScalar: 200, - l2ChainId: 300 + l2ChainId: 300, + opsm: OPStackManager(makeAddr("opsm")) }); function setUp() public { @@ -57,9 +68,10 @@ contract DeployOPChainInput_Test is Test { assertEq(input.basefeeScalar, dsi.basefeeScalar(), "800"); assertEq(input.blobBaseFeeScalar, dsi.blobBaseFeeScalar(), "900"); assertEq(input.l2ChainId, dsi.l2ChainId(), "1000"); + assertEq(address(input.opsm), address(dsi.opsm()), "1100"); // Compare the test input struct to the `input` getter method. - assertEq(keccak256(abi.encode(input)), keccak256(abi.encode(dsi.input())), "1100"); + assertEq(keccak256(abi.encode(input)), keccak256(abi.encode(dsi.input())), "1200"); } function test_getters_whenNotSet_revert() public { @@ -304,3 +316,147 @@ contract DeployOPChainOutput_Test is Test { dso.delayedWETHPermissionlessGameProxy(); } } + +// To mimic a production environment, we default to integration tests here that actually run the +// DeploySuperchain and DeployImplementations scripts. +contract DeployOPChain_TestBase is Test { + DeployOPChain deployOPChain; + DeployOPChainInput dsi; + DeployOPChainOutput dso; + + // We define a default initial input struct for DeploySuperchain. The other input structs are + // dependent on the outputs of the previous scripts, so we initialize them here and populate + // the null values in the `setUp` method.assert + DeploySuperchainInput.Input deploySuperchainInput = DeploySuperchainInput.Input({ + roles: DeploySuperchainInput.Roles({ + proxyAdminOwner: makeAddr("defaultProxyAdminOwner"), + protocolVersionsOwner: makeAddr("defaultProtocolVersionsOwner"), + guardian: makeAddr("defaultGuardian") + }), + paused: false, + requiredProtocolVersion: ProtocolVersion.wrap(1), + recommendedProtocolVersion: ProtocolVersion.wrap(2) + }); + + DeployImplementationsInput.Input deployImplementationsInput = DeployImplementationsInput.Input({ + withdrawalDelaySeconds: 100, + minProposalSizeBytes: 200, + challengePeriodSeconds: 300, + proofMaturityDelaySeconds: 400, + disputeGameFinalityDelaySeconds: 500, + release: "op-contracts/latest", + // These are set during `setUp` since they are outputs of the previous step. + superchainConfigProxy: SuperchainConfig(address(0)), + protocolVersionsProxy: ProtocolVersions(address(0)) + }); + + DeployOPChainInput.Input deployOPChainInput = DeployOPChainInput.Input({ + roles: DeployOPChainInput.Roles({ + opChainProxyAdminOwner: makeAddr("defaultOPChainProxyAdminOwner"), + systemConfigOwner: makeAddr("defaultSystemConfigOwner"), + batcher: makeAddr("defaultBatcher"), + unsafeBlockSigner: makeAddr("defaultUnsafeBlockSigner"), + proposer: makeAddr("defaultProposer"), + challenger: makeAddr("defaultChallenger") + }), + basefeeScalar: 100, + blobBaseFeeScalar: 200, + l2ChainId: 300, + // This is set during `setUp` since it is an output of the previous step. + opsm: OPStackManager(address(0)) + }); + + // Set during `setUp`. + DeployImplementationsOutput.Output deployImplementationsOutput; + + function setUp() public { + // Initialize deploy scripts. + DeploySuperchain deploySuperchain = new DeploySuperchain(); + DeployImplementations deployImplementations = new DeployImplementations(); + deployOPChain = new DeployOPChain(); + (dsi, dso) = deployOPChain.getIOContracts(); + + // Deploy the superchain contracts. + DeploySuperchainOutput.Output memory superchainOutput = deploySuperchain.run(deploySuperchainInput); + + // Populate the input struct for DeployImplementations based on the output of DeploySuperchain. + deployImplementationsInput.superchainConfigProxy = superchainOutput.superchainConfigProxy; + deployImplementationsInput.protocolVersionsProxy = superchainOutput.protocolVersionsProxy; + + // Deploy the implementations using the updated DeployImplementations input struct. + deployImplementationsOutput = deployImplementations.run(deployImplementationsInput); + + // Set the OPStackManager on the input struct for DeployOPChain. + deployOPChainInput.opsm = deployImplementationsOutput.opsm; + } + + // See the function of the same name in the `DeployImplementations_Test` contract of + // `DeployImplementations.t.sol` for more details on why we use this method. + function createDeployImplementationsContract() internal virtual returns (DeployImplementations) { + return new DeployImplementations(); + } +} + +contract DeployOPChain_Test is DeployOPChain_TestBase { + function test_run_succeeds(DeployOPChainInput.Input memory _input) public { + vm.assume(_input.roles.opChainProxyAdminOwner != address(0)); + vm.assume(_input.roles.systemConfigOwner != address(0)); + vm.assume(_input.roles.batcher != address(0)); + vm.assume(_input.roles.unsafeBlockSigner != address(0)); + vm.assume(_input.roles.proposer != address(0)); + vm.assume(_input.roles.challenger != address(0)); + vm.assume(_input.l2ChainId != 0 && _input.l2ChainId != block.chainid); + + _input.opsm = deployOPChainInput.opsm; + + DeployOPChainOutput.Output memory output = deployOPChain.run(_input); + + // TODO Add fault proof contract assertions below once OPSM fully supports them. + + // Assert that individual input fields were properly set based on the input struct. + assertEq(_input.roles.opChainProxyAdminOwner, dsi.opChainProxyAdminOwner(), "100"); + assertEq(_input.roles.systemConfigOwner, dsi.systemConfigOwner(), "200"); + assertEq(_input.roles.batcher, dsi.batcher(), "300"); + assertEq(_input.roles.unsafeBlockSigner, dsi.unsafeBlockSigner(), "400"); + assertEq(_input.roles.proposer, dsi.proposer(), "500"); + assertEq(_input.roles.challenger, dsi.challenger(), "600"); + assertEq(_input.basefeeScalar, dsi.basefeeScalar(), "700"); + assertEq(_input.blobBaseFeeScalar, dsi.blobBaseFeeScalar(), "800"); + assertEq(_input.l2ChainId, dsi.l2ChainId(), "900"); + + // Assert that individual output fields were properly set based on the output struct. + assertEq(address(output.opChainProxyAdmin), address(dso.opChainProxyAdmin()), "1100"); + assertEq(address(output.addressManager), address(dso.addressManager()), "1200"); + assertEq(address(output.l1ERC721BridgeProxy), address(dso.l1ERC721BridgeProxy()), "1300"); + assertEq(address(output.systemConfigProxy), address(dso.systemConfigProxy()), "1400"); + assertEq( + address(output.optimismMintableERC20FactoryProxy), address(dso.optimismMintableERC20FactoryProxy()), "1500" + ); + assertEq(address(output.l1StandardBridgeProxy), address(dso.l1StandardBridgeProxy()), "1600"); + assertEq(address(output.l1CrossDomainMessengerProxy), address(dso.l1CrossDomainMessengerProxy()), "1700"); + assertEq(address(output.optimismPortalProxy), address(dso.optimismPortalProxy()), "1800"); + + // Assert that the full input and output structs were properly set. + assertEq(keccak256(abi.encode(_input)), keccak256(abi.encode(DeployOPChainInput(dsi).input())), "1900"); + assertEq(keccak256(abi.encode(output)), keccak256(abi.encode(DeployOPChainOutput(dso).output())), "2000"); + + // Assert inputs were properly passed through to the contract initializers. + assertEq(address(output.opChainProxyAdmin.owner()), _input.roles.opChainProxyAdminOwner, "2100"); + assertEq(address(output.systemConfigProxy.owner()), _input.roles.systemConfigOwner, "2200"); + address batcher = address(uint160(uint256(output.systemConfigProxy.batcherHash()))); + assertEq(batcher, _input.roles.batcher, "2300"); + assertEq(address(output.systemConfigProxy.unsafeBlockSigner()), _input.roles.unsafeBlockSigner, "2400"); + // assertEq(address(...proposer()), _input.roles.proposer, "2500"); // TODO once we deploy dispute games. + // assertEq(address(...challenger()), _input.roles.challenger, "2600"); // TODO once we deploy dispute games. + + // Most architecture assertions are handled within the OP Stack Manager itself and therefore + // we only assert on the things that are not visible onchain. + // TODO add these assertions: AddressManager, Proxy, ProxyAdmin, etc. + } +} + +contract DeployOPChain_Test_Interop is DeployOPChain_Test { + function createDeployImplementationsContract() internal override returns (DeployImplementations) { + return new DeployImplementationsInterop(); + } +} diff --git a/packages/contracts-bedrock/test/L1/OPStackManager.t.sol b/packages/contracts-bedrock/test/L1/OPStackManager.t.sol index c97e9632faac..b1af4fc1409f 100644 --- a/packages/contracts-bedrock/test/L1/OPStackManager.t.sol +++ b/packages/contracts-bedrock/test/L1/OPStackManager.t.sol @@ -1,14 +1,25 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Testing utilities import { Test } from "forge-std/Test.sol"; -// Target contract +import { DeployOPChainInput } from "scripts/DeployOPChain.s.sol"; +import { DeployOPChain_TestBase } from "test/DeployOPChain.t.sol"; + import { OPStackManager } from "src/L1/OPStackManager.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; // Exposes internal functions for testing. contract OPStackManager_Harness is OPStackManager { + constructor( + SuperchainConfig _superchainConfig, + ProtocolVersions _protocolVersions, + Blueprints memory _blueprints + ) + OPStackManager(_superchainConfig, _protocolVersions, _blueprints) + { } + function chainIdToBatchInboxAddress_exposed(uint256 l2ChainId) public pure returns (address) { return super.chainIdToBatchInboxAddress(l2ChainId); } @@ -17,38 +28,68 @@ contract OPStackManager_Harness is OPStackManager { // Unlike other test suites, we intentionally do not inherit from CommonTest or Setup. This is // because OPStackManager acts as a deploy script, so we start from a clean slate here and // work OPStackManager's deployment into the existing test setup, instead of using the existing -// test setup to deploy OPStackManager. -contract OPStackManager_Init is Test { - OPStackManager opsm; - - // Default dummy parameters for the deploy function. - OPStackManager.Roles roles; - uint256 l2ChainId = 1234; - uint32 basefeeScalar = 1; - uint32 blobBasefeeScalar = 1; - - function setUp() public { - opsm = new OPStackManager(); +// test setup to deploy OPStackManager. We do however inherit from DeployOPChain_TestBase so +// we can use its setup to deploy the implementations similarly to how a real deployment would +// happen. +contract OPStackManager_Deploy_Test is DeployOPChain_TestBase { + // This helper function is used to convert the input struct type defined in DeployOPChain.s.sol + // to the input struct type defined in OPStackManager.sol. + function toOPSMDeployInput(DeployOPChainInput.Input memory input) + internal + pure + returns (OPStackManager.DeployInput memory) + { + return OPStackManager.DeployInput({ + roles: OPStackManager.Roles({ + opChainProxyAdminOwner: input.roles.opChainProxyAdminOwner, + systemConfigOwner: input.roles.systemConfigOwner, + batcher: input.roles.batcher, + unsafeBlockSigner: input.roles.unsafeBlockSigner, + proposer: input.roles.proposer, + challenger: input.roles.challenger + }), + basefeeScalar: input.basefeeScalar, + blobBasefeeScalar: input.blobBaseFeeScalar, + l2ChainId: input.l2ChainId + }); } -} -contract OPStackManager_Deploy_Test is OPStackManager_Init { function test_deploy_l2ChainIdEqualsZero_reverts() public { + deployOPChainInput.l2ChainId = 0; vm.expectRevert(OPStackManager.InvalidChainId.selector); - opsm.deploy(0, basefeeScalar, blobBasefeeScalar, roles); + deployImplementationsOutput.opsm.deploy(toOPSMDeployInput(deployOPChainInput)); } function test_deploy_l2ChainIdEqualsCurrentChainId_reverts() public { + deployOPChainInput.l2ChainId = block.chainid; vm.expectRevert(OPStackManager.InvalidChainId.selector); - opsm.deploy(block.chainid, basefeeScalar, blobBasefeeScalar, roles); + deployImplementationsOutput.opsm.deploy(toOPSMDeployInput(deployOPChainInput)); + } + + function test_deploy_succeeds() public { + deployImplementationsOutput.opsm.deploy(toOPSMDeployInput(deployOPChainInput)); } } // These tests use the harness which exposes internal functions for testing. contract OPStackManager_InternalMethods_Test is Test { - function test_calculatesBatchInboxAddress_succeeds() public { - OPStackManager_Harness opsmHarness = new OPStackManager_Harness(); + OPStackManager_Harness opsmHarness; + + function setUp() public { + opsmHarness = new OPStackManager_Harness({ + _superchainConfig: SuperchainConfig(makeAddr("superchainConfig")), + _protocolVersions: ProtocolVersions(makeAddr("protocolVersions")), + _blueprints: OPStackManager.Blueprints({ + addressManager: makeAddr("addressManager"), + proxy: makeAddr("proxy"), + proxyAdmin: makeAddr("proxyAdmin"), + l1ChugSplashProxy: makeAddr("l1ChugSplashProxy"), + resolvedDelegateProxy: makeAddr("resolvedDelegateProxy") + }) + }); + } + function test_calculatesBatchInboxAddress_succeeds() public view { // These test vectors were calculated manually: // 1. Compute the bytes32 encoding of the chainId: bytes32(uint256(chainId)); // 2. Hash it and manually take the first 19 bytes, and prefixed it with 0x00. diff --git a/packages/contracts-bedrock/test/Specs.t.sol b/packages/contracts-bedrock/test/Specs.t.sol index 6fac763938fb..f9d6a0145bb3 100644 --- a/packages/contracts-bedrock/test/Specs.t.sol +++ b/packages/contracts-bedrock/test/Specs.t.sol @@ -2,7 +2,6 @@ pragma solidity ^0.8.15; import { CommonTest } from "test/setup/CommonTest.sol"; -import { Executables } from "scripts/libraries/Executables.sol"; import { console2 as console } from "forge-std/console2.sol"; import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol"; @@ -823,7 +822,25 @@ contract Specification_Test is CommonTest { // OPStackManager _addSpec({ _name: "OPStackManager", _sel: _getSel("version()") }); + _addSpec({ _name: "OPStackManager", _sel: _getSel("superchainConfig()") }); + _addSpec({ _name: "OPStackManager", _sel: _getSel("protocolVersions()") }); + _addSpec({ _name: "OPStackManager", _sel: _getSel("latestRelease()") }); + _addSpec({ _name: "OPStackManager", _sel: _getSel("implementations(string,string)") }); + _addSpec({ _name: "OPStackManager", _sel: _getSel("systemConfigs(uint256)") }); + _addSpec({ _name: "OPStackManager", _sel: OPStackManager.setRelease.selector }); _addSpec({ _name: "OPStackManager", _sel: OPStackManager.deploy.selector }); + _addSpec({ _name: "OPStackManager", _sel: OPStackManager.blueprints.selector }); + + // OPStackManagerInterop + _addSpec({ _name: "OPStackManagerInterop", _sel: _getSel("version()") }); + _addSpec({ _name: "OPStackManagerInterop", _sel: _getSel("superchainConfig()") }); + _addSpec({ _name: "OPStackManagerInterop", _sel: _getSel("protocolVersions()") }); + _addSpec({ _name: "OPStackManagerInterop", _sel: _getSel("latestRelease()") }); + _addSpec({ _name: "OPStackManagerInterop", _sel: _getSel("implementations(string,string)") }); + _addSpec({ _name: "OPStackManagerInterop", _sel: _getSel("systemConfigs(uint256)") }); + _addSpec({ _name: "OPStackManagerInterop", _sel: OPStackManager.setRelease.selector }); + _addSpec({ _name: "OPStackManagerInterop", _sel: OPStackManager.deploy.selector }); + _addSpec({ _name: "OPStackManagerInterop", _sel: OPStackManager.blueprints.selector }); // DeputyGuardianModule _addSpec({ From 9d73864857117abfdbcd77eddf2b4d3d369886ef Mon Sep 17 00:00:00 2001 From: protolambda Date: Tue, 10 Sep 2024 11:50:07 -0600 Subject: [PATCH 085/264] op-chain-ops: fix Go forge script broadcast handling (#11832) --- op-chain-ops/script/prank.go | 110 ++++++++++++++---- op-chain-ops/script/script.go | 36 ++++-- op-chain-ops/script/script_test.go | 72 +++++++++--- .../testdata/scripts/ScriptExample.s.sol | 25 +++- .../ScriptExample.s.sol/FooBar.json | 1 + .../ScriptExample.s.sol/ScriptExample.json | 2 +- .../ScriptExample.s.sol/Vm.json | 2 +- .../ScriptExample.s.sol/console.json | 2 +- 8 files changed, 192 insertions(+), 58 deletions(-) create mode 100644 op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/FooBar.json diff --git a/op-chain-ops/script/prank.go b/op-chain-ops/script/prank.go index 49214fdb7888..5cecbdf29cb4 100644 --- a/op-chain-ops/script/prank.go +++ b/op-chain-ops/script/prank.go @@ -3,12 +3,15 @@ package script import ( "bytes" "errors" + "fmt" "math/big" "github.com/holiman/uint256" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" ) // Prank represents an active prank task for the next sub-call. @@ -159,35 +162,92 @@ const ( CallerModeRecurrentPrank ) -// Broadcast captures a transaction that was selected to be broadcasted +type BroadcastType string + +const ( + BroadcastCall BroadcastType = "call" + BroadcastCreate BroadcastType = "create" + // BroadcastCreate2 is to be broadcast via the Create2Deployer, + // and not really documented much anywhere. + BroadcastCreate2 BroadcastType = "create2" +) + +func (bt BroadcastType) String() string { + return string(bt) +} + +func (bt BroadcastType) MarshalText() ([]byte, error) { + return []byte(bt.String()), nil +} + +func (bt *BroadcastType) UnmarshalText(data []byte) error { + v := BroadcastType(data) + switch v { + case BroadcastCall, BroadcastCreate, BroadcastCreate2: + *bt = v + return nil + default: + return fmt.Errorf("unrecognized broadcast type bytes: %x", data) + } +} + +// Broadcast captures a transaction that was selected to be broadcast // via vm.broadcast(). Actually submitting the transaction is left up // to other tools. type Broadcast struct { - From common.Address - To common.Address - Calldata []byte - Value *big.Int + From common.Address `json:"from"` + To common.Address `json:"to"` // set to expected contract address, if this is a deployment + Input hexutil.Bytes `json:"input"` // set to contract-creation code, if this is a deployment + Value *hexutil.U256 `json:"value"` + Salt common.Hash `json:"salt"` // set if this is a Create2 broadcast + Type BroadcastType `json:"type"` } -// NewBroadcastFromCtx creates a Broadcast from a VM context. This method -// is preferred to manually creating the struct since it correctly handles -// data that must be copied prior to being returned to prevent accidental -// mutation. -func NewBroadcastFromCtx(ctx *vm.ScopeContext) Broadcast { - // Consistently return nil for zero values in order - // for tests to have a deterministic value to compare - // against. - value := ctx.CallValue().ToBig() - if value.Cmp(common.Big0) == 0 { - value = nil - } - - // Need to clone CallInput() below since it's used within - // the VM itself elsewhere. - return Broadcast{ - From: ctx.Caller(), - To: ctx.Address(), - Calldata: bytes.Clone(ctx.CallInput()), - Value: value, +// NewBroadcast creates a Broadcast from a parent callframe, and the completed child callframe. +// This method is preferred to manually creating the struct since it correctly handles +// data that must be copied prior to being returned to prevent accidental mutation. +func NewBroadcast(parent, current *CallFrame) Broadcast { + ctx := current.Ctx + + value := ctx.CallValue() + if value == nil { + value = uint256.NewInt(0) + } + + // Code is tracked separate from calldata input, + // even though they are the same thing for a regular contract creation + input := ctx.CallInput() + if ctx.Contract.IsDeployment { + input = ctx.Contract.Code + } + + bcast := Broadcast{ + From: ctx.Caller(), + To: ctx.Address(), + // Need to clone the input below since memory is reused in the VM + Input: bytes.Clone(input), + Value: (*hexutil.U256)(value.Clone()), } + + switch parent.LastOp { + case vm.CREATE: + bcast.Type = BroadcastCreate + case vm.CREATE2: + bcast.Salt = parent.LastCreate2Salt + initHash := crypto.Keccak256Hash(bcast.Input) + expectedAddr := crypto.CreateAddress2(bcast.From, bcast.Salt, initHash[:]) + // Sanity-check the create2 salt is correct by checking the address computation. + if expectedAddr != bcast.To { + panic(fmt.Errorf("script bug: create2 broadcast has "+ + "unexpected address: %s, expected %s. Sender: %s, Salt: %s, Inithash: %s", + bcast.To, expectedAddr, bcast.From, bcast.Salt, initHash)) + } + bcast.Type = BroadcastCreate2 + case vm.CALL: + bcast.Type = BroadcastCall + default: + panic(fmt.Errorf("unexpected broadcast operation %s", parent.LastOp)) + } + + return bcast } diff --git a/op-chain-ops/script/script.go b/op-chain-ops/script/script.go index a9c98679ab3d..0512f4258e39 100644 --- a/op-chain-ops/script/script.go +++ b/op-chain-ops/script/script.go @@ -3,7 +3,6 @@ package script import ( "bytes" "encoding/binary" - "encoding/hex" "encoding/json" "fmt" "math/big" @@ -40,6 +39,9 @@ type CallFrame struct { LastOp vm.OpCode LastPC uint64 + // To reconstruct a create2 later, e.g. on broadcast + LastCreate2Salt [32]byte + // Reverts often happen in generated code. // We want to fallback to logging the source-map position of // the non-generated code, i.e. the origin of the last successful jump. @@ -391,17 +393,24 @@ func (h *Host) unwindCallstack(depth int) { if len(h.callStack) > 1 { parentCallFrame := h.callStack[len(h.callStack)-2] if parentCallFrame.Prank != nil { - if parentCallFrame.Prank.Broadcast && parentCallFrame.LastOp != vm.STATICCALL { - currentFrame := h.callStack[len(h.callStack)-1] - bcast := NewBroadcastFromCtx(currentFrame.Ctx) - h.hooks.OnBroadcast(bcast) - h.log.Debug( - "called broadcast hook", - "from", bcast.From, - "to", bcast.To, - "calldata", hex.EncodeToString(bcast.Calldata), - "value", bcast.Value, - ) + if parentCallFrame.Prank.Broadcast { + if parentCallFrame.LastOp == vm.DELEGATECALL { + h.log.Warn("Cannot broadcast a delegate-call. Ignoring broadcast hook.") + } else if parentCallFrame.LastOp == vm.STATICCALL { + h.log.Trace("Broadcast is active, ignoring static-call.") + } else { + currentCallFrame := h.callStack[len(h.callStack)-1] + bcast := NewBroadcast(parentCallFrame, currentCallFrame) + h.log.Debug( + "calling broadcast hook", + "from", bcast.From, + "to", bcast.To, + "input", bcast.Input, + "value", bcast.Value, + "type", bcast.Type, + ) + h.hooks.OnBroadcast(bcast) + } } // While going back to the parent, restore the tx.origin. @@ -448,6 +457,9 @@ func (h *Host) onOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpCo } cf.LastOp = vm.OpCode(op) cf.LastPC = pc + if cf.LastOp == vm.CREATE2 { + cf.LastCreate2Salt = scopeCtx.Stack.Back(3).Bytes32() + } } // onStorageChange is a trace-hook to capture state changes diff --git a/op-chain-ops/script/script_test.go b/op-chain-ops/script/script_test.go index 075761756081..cf1f58751fa8 100644 --- a/op-chain-ops/script/script_test.go +++ b/op-chain-ops/script/script_test.go @@ -1,16 +1,20 @@ package script import ( + "bytes" + "encoding/json" "fmt" + "math/big" "strings" "testing" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/holiman/uint256" "github.com/stretchr/testify/require" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" @@ -54,27 +58,58 @@ func TestScriptBroadcast(t *testing.T) { return data } + fooBar, err := af.ReadArtifact("ScriptExample.s.sol", "FooBar") + require.NoError(t, err) + + expectedInitCode := bytes.Clone(fooBar.Bytecode.Object) + // Add the contract init argument we use in the script + expectedInitCode = append(expectedInitCode, leftPad32(big.NewInt(1234).Bytes())...) + salt := uint256.NewInt(42).Bytes32() + senderAddr := common.HexToAddress("0x5b73C5498c1E3b4dbA84de0F1833c4a029d90519") expBroadcasts := []Broadcast{ { - From: senderAddr, - To: senderAddr, - Calldata: mustEncodeCalldata("call1", "single_call1"), + From: senderAddr, + To: senderAddr, + Input: mustEncodeCalldata("call1", "single_call1"), + Value: (*hexutil.U256)(uint256.NewInt(0)), + Type: BroadcastCall, }, { - From: senderAddr, - To: senderAddr, - Calldata: mustEncodeCalldata("call1", "startstop_call1"), + From: common.HexToAddress("0x0000000000000000000000000000000000C0FFEE"), + To: senderAddr, + Input: mustEncodeCalldata("call1", "startstop_call1"), + Value: (*hexutil.U256)(uint256.NewInt(0)), + Type: BroadcastCall, }, { - From: senderAddr, - To: senderAddr, - Calldata: mustEncodeCalldata("call2", "startstop_call2"), + From: common.HexToAddress("0x0000000000000000000000000000000000C0FFEE"), + To: senderAddr, + Input: mustEncodeCalldata("call2", "startstop_call2"), + Value: (*hexutil.U256)(uint256.NewInt(0)), + Type: BroadcastCall, }, { - From: senderAddr, - To: senderAddr, - Calldata: mustEncodeCalldata("nested1", "nested"), + From: common.HexToAddress("0x1234"), + To: senderAddr, + Input: mustEncodeCalldata("nested1", "nested"), + Value: (*hexutil.U256)(uint256.NewInt(0)), + Type: BroadcastCall, + }, + { + From: common.HexToAddress("0x123456"), + To: crypto.CreateAddress(common.HexToAddress("0x123456"), 0), + Input: expectedInitCode, + Value: (*hexutil.U256)(uint256.NewInt(0)), + Type: BroadcastCreate, + }, + { + From: common.HexToAddress("0xcafe"), + To: crypto.CreateAddress2(common.HexToAddress("0xcafe"), salt, crypto.Keccak256(expectedInitCode)), + Input: expectedInitCode, + Value: (*hexutil.U256)(uint256.NewInt(0)), + Type: BroadcastCreate2, + Salt: salt, }, } @@ -92,5 +127,10 @@ func TestScriptBroadcast(t *testing.T) { input := bytes4("runBroadcast()") returnData, _, err := h.Call(scriptContext.Sender, addr, input[:], DefaultFoundryGasLimit, uint256.NewInt(0)) require.NoError(t, err, "call failed: %x", string(returnData)) - require.EqualValues(t, expBroadcasts, broadcasts) + + expected, err := json.MarshalIndent(expBroadcasts, " ", " ") + require.NoError(t, err) + got, err := json.MarshalIndent(broadcasts, " ", " ") + require.NoError(t, err) + require.Equal(t, string(expected), string(got)) } diff --git a/op-chain-ops/script/testdata/scripts/ScriptExample.s.sol b/op-chain-ops/script/testdata/scripts/ScriptExample.s.sol index 954cab960a88..637c900a46cc 100644 --- a/op-chain-ops/script/testdata/scripts/ScriptExample.s.sol +++ b/op-chain-ops/script/testdata/scripts/ScriptExample.s.sol @@ -9,6 +9,8 @@ interface Vm { function startPrank(address msgSender) external; function stopPrank() external; function broadcast() external; + function broadcast(address msgSender) external; + function startBroadcast(address msgSender) external; function startBroadcast() external; function stopBroadcast() external; } @@ -104,7 +106,7 @@ contract ScriptExample { this.call2("single_call2"); console.log("testing start/stop"); - vm.startBroadcast(); + vm.startBroadcast(address(uint160(0xc0ffee))); this.call1("startstop_call1"); this.call2("startstop_call2"); this.callPure("startstop_pure"); @@ -112,9 +114,20 @@ contract ScriptExample { this.call1("startstop_call3"); console.log("testing nested"); - vm.startBroadcast(); + vm.startBroadcast(address(uint160(0x1234))); this.nested1("nested"); vm.stopBroadcast(); + + console.log("contract deployment"); + vm.broadcast(address(uint160(0x123456))); + FooBar x = new FooBar(1234); + require(x.foo() == 1234); + + console.log("create 2"); + vm.broadcast(address(uint160(0xcafe))); + FooBar y = new FooBar{salt: bytes32(uint256(42))}(1234); + require(y.foo() == 1234); + console.log("done!"); } /// @notice example external function, to force a CALL, and test vm.startPrank with. @@ -147,3 +160,11 @@ contract ScriptExample { console.log(_v); } } + +contract FooBar { + uint256 public foo; + + constructor(uint256 v) { + foo = v; + } +} diff --git a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/FooBar.json b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/FooBar.json new file mode 100644 index 000000000000..f64c50b29b2d --- /dev/null +++ b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/FooBar.json @@ -0,0 +1 @@ +{"abi":[{"type":"constructor","inputs":[{"name":"v","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"type":"function","name":"foo","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"}],"bytecode":{"object":"0x608060405234801561001057600080fd5b506040516100b23803806100b283398101604081905261002f91610037565b600055610050565b60006020828403121561004957600080fd5b5051919050565b60548061005e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b603560005481565b60405190815260200160405180910390f3fea164736f6c634300080f000a","sourceMap":"5632:96:0:-:0;;;5679:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5712:3;:7;5632:96;;14:184:1;84:6;137:2;125:9;116:7;112:23;108:32;105:52;;;153:1;150;143:12;105:52;-1:-1:-1;176:16:1;;14:184;-1:-1:-1;14:184:1:o;:::-;5632:96:0;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b603560005481565b60405190815260200160405180910390f3fea164736f6c634300080f000a","sourceMap":"5632:96:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5654:18;;;;;;;;;160:25:1;;;148:2;133:18;5654::0;;;;;;","linkReferences":{}},"methodIdentifiers":{"foo()":"c2985578"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"v\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"foo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"FooBar\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x4fc2ffeba31e146fc3a2edef7cc8b7e82fb2344454d32d6371a62c6d76dfcb4e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a517c69eba90ee5f3efb198a2247d5744bed8e17d332ce2dda4d3cf3a2c334f9\",\"dweb:/ipfs/QmciXeDt5EEhmjH5xECVk2VX6EbnER5UFv58dvGgemwkKK\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"uint256","name":"v","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"stateMutability":"view","type":"function","name":"foo","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"FooBar"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x4fc2ffeba31e146fc3a2edef7cc8b7e82fb2344454d32d6371a62c6d76dfcb4e","urls":["bzz-raw://a517c69eba90ee5f3efb198a2247d5744bed8e17d332ce2dda4d3cf3a2c334f9","dweb:/ipfs/QmciXeDt5EEhmjH5xECVk2VX6EbnER5UFv58dvGgemwkKK"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[{"astId":665,"contract":"scripts/ScriptExample.s.sol:FooBar","label":"foo","offset":0,"slot":"0","type":"t_uint256"}],"types":{"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"userdoc":{"version":1,"kind":"user"},"devdoc":{"version":1,"kind":"dev"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":677,"exportedSymbols":{"FooBar":[676],"ScriptExample":[663],"Vm":[55],"console":[192]},"nodeType":"SourceUnit","src":"32:5697:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":55,"nodeType":"ContractDefinition","src":"120:616:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":55,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":38,"nodeType":"FunctionDefinition","src":"516:30:0","nodes":[],"functionSelector":"afc98040","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"525:9:0","parameters":{"id":36,"nodeType":"ParameterList","parameters":[],"src":"534:2:0"},"returnParameters":{"id":37,"nodeType":"ParameterList","parameters":[],"src":"545:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":43,"nodeType":"FunctionDefinition","src":"551:47:0","nodes":[],"functionSelector":"e6962cdb","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"560:9:0","parameters":{"id":41,"nodeType":"ParameterList","parameters":[{"constant":false,"id":40,"mutability":"mutable","name":"msgSender","nameLocation":"578:9:0","nodeType":"VariableDeclaration","scope":43,"src":"570:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":39,"name":"address","nodeType":"ElementaryTypeName","src":"570:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"569:19:0"},"returnParameters":{"id":42,"nodeType":"ParameterList","parameters":[],"src":"597:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":48,"nodeType":"FunctionDefinition","src":"603:52:0","nodes":[],"functionSelector":"7fec2a8d","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"612:14:0","parameters":{"id":46,"nodeType":"ParameterList","parameters":[{"constant":false,"id":45,"mutability":"mutable","name":"msgSender","nameLocation":"635:9:0","nodeType":"VariableDeclaration","scope":48,"src":"627:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":44,"name":"address","nodeType":"ElementaryTypeName","src":"627:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"626:19:0"},"returnParameters":{"id":47,"nodeType":"ParameterList","parameters":[],"src":"654:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":51,"nodeType":"FunctionDefinition","src":"660:35:0","nodes":[],"functionSelector":"7fb5297f","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"669:14:0","parameters":{"id":49,"nodeType":"ParameterList","parameters":[],"src":"683:2:0"},"returnParameters":{"id":50,"nodeType":"ParameterList","parameters":[],"src":"694:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":54,"nodeType":"FunctionDefinition","src":"700:34:0","nodes":[],"functionSelector":"76eadd36","implemented":false,"kind":"function","modifiers":[],"name":"stopBroadcast","nameLocation":"709:13:0","parameters":{"id":52,"nodeType":"ParameterList","parameters":[],"src":"722:2:0"},"returnParameters":{"id":53,"nodeType":"ParameterList","parameters":[],"src":"733:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[55],"name":"Vm","nameLocation":"130:2:0","scope":677,"usedErrors":[]},{"id":192,"nodeType":"ContractDefinition","src":"791:1622:0","nodes":[{"id":61,"nodeType":"VariableDeclaration","src":"813:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"830:15:0","scope":192,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":56,"name":"address","nodeType":"ElementaryTypeName","src":"813:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":59,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"856:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":58,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"848:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":57,"name":"address","nodeType":"ElementaryTypeName","src":"848:7:0","typeDescriptions":{}}},"id":60,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"848:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":78,"nodeType":"FunctionDefinition","src":"906:221:0","nodes":[],"body":{"id":77,"nodeType":"Block","src":"1065:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"1084:37:0","statements":[{"nodeType":"YulAssignment","src":"1098:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"1107:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"1098:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":67,"isOffset":false,"isSlot":false,"src":"1107:4:0","valueSize":1},{"declaration":74,"isOffset":false,"isSlot":false,"src":"1098:5:0","valueSize":1}],"id":76,"nodeType":"InlineAssembly","src":"1075:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"915:25:0","parameters":{"id":68,"nodeType":"ParameterList","parameters":[{"constant":false,"id":67,"mutability":"mutable","name":"fnIn","nameLocation":"987:4:0","nodeType":"VariableDeclaration","scope":78,"src":"950:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":66,"nodeType":"FunctionTypeName","parameterTypes":{"id":64,"nodeType":"ParameterList","parameters":[{"constant":false,"id":63,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":66,"src":"959:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":62,"name":"bytes","nodeType":"ElementaryTypeName","src":"959:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"958:14:0"},"returnParameterTypes":{"id":65,"nodeType":"ParameterList","parameters":[],"src":"987:0:0"},"src":"950:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"940:57:0"},"returnParameters":{"id":75,"nodeType":"ParameterList","parameters":[{"constant":false,"id":74,"mutability":"mutable","name":"fnOut","nameLocation":"1058:5:0","nodeType":"VariableDeclaration","scope":78,"src":"1021:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":73,"nodeType":"FunctionTypeName","parameterTypes":{"id":71,"nodeType":"ParameterList","parameters":[{"constant":false,"id":70,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":73,"src":"1030:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":69,"name":"bytes","nodeType":"ElementaryTypeName","src":"1030:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1029:14:0"},"returnParameterTypes":{"id":72,"nodeType":"ParameterList","parameters":[],"src":"1058:0:0"},"src":"1021:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"1020:44:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":90,"nodeType":"FunctionDefinition","src":"1133:133:0","nodes":[],"body":{"id":89,"nodeType":"Block","src":"1194:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":86,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1251:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":84,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":106,"src":"1230:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":83,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":78,"src":"1204:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":85,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":87,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":88,"nodeType":"ExpressionStatement","src":"1204:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"1142:15:0","parameters":{"id":81,"nodeType":"ParameterList","parameters":[{"constant":false,"id":80,"mutability":"mutable","name":"payload","nameLocation":"1171:7:0","nodeType":"VariableDeclaration","scope":90,"src":"1158:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":79,"name":"bytes","nodeType":"ElementaryTypeName","src":"1158:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1157:22:0"},"returnParameters":{"id":82,"nodeType":"ParameterList","parameters":[],"src":"1194:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":106,"nodeType":"FunctionDefinition","src":"1272:380:0","nodes":[],"body":{"id":105,"nodeType":"Block","src":"1336:316:0","nodes":[],"statements":[{"assignments":[96],"declarations":[{"constant":false,"id":96,"mutability":"mutable","name":"payloadLength","nameLocation":"1354:13:0","nodeType":"VariableDeclaration","scope":105,"src":"1346:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":95,"name":"uint256","nodeType":"ElementaryTypeName","src":"1346:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":99,"initialValue":{"expression":{"id":97,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":92,"src":"1370:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":98,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1370:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1346:38:0"},{"assignments":[101],"declarations":[{"constant":false,"id":101,"mutability":"mutable","name":"consoleAddress","nameLocation":"1402:14:0","nodeType":"VariableDeclaration","scope":105,"src":"1394:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":100,"name":"address","nodeType":"ElementaryTypeName","src":"1394:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":103,"initialValue":{"id":102,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":61,"src":"1419:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1394:40:0"},{"AST":{"nodeType":"YulBlock","src":"1496:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1510:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1534:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1543:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1530:3:0"},"nodeType":"YulFunctionCall","src":"1530:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1514:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1559:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1579:3:0"},"nodeType":"YulFunctionCall","src":"1579:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1586:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1602:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1616:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1631:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1634:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1568:10:0"},"nodeType":"YulFunctionCall","src":"1568:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1563:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":101,"isOffset":false,"isSlot":false,"src":"1586:14:0","valueSize":1},{"declaration":92,"isOffset":false,"isSlot":false,"src":"1534:7:0","valueSize":1},{"declaration":96,"isOffset":false,"isSlot":false,"src":"1616:13:0","valueSize":1}],"id":104,"nodeType":"InlineAssembly","src":"1487:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1281:19:0","parameters":{"id":93,"nodeType":"ParameterList","parameters":[{"constant":false,"id":92,"mutability":"mutable","name":"payload","nameLocation":"1314:7:0","nodeType":"VariableDeclaration","scope":106,"src":"1301:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":91,"name":"bytes","nodeType":"ElementaryTypeName","src":"1301:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1300:22:0"},"returnParameters":{"id":94,"nodeType":"ParameterList","parameters":[],"src":"1336:0:0"},"scope":192,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":120,"nodeType":"FunctionDefinition","src":"1658:121:0","nodes":[],"body":{"id":119,"nodeType":"Block","src":"1703:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":114,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1753:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":115,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":108,"src":"1768:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":112,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1729:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":113,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1729:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":116,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1729:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":111,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1713:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":117,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1713:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":118,"nodeType":"ExpressionStatement","src":"1713:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1667:3:0","parameters":{"id":109,"nodeType":"ParameterList","parameters":[{"constant":false,"id":108,"mutability":"mutable","name":"p0","nameLocation":"1685:2:0","nodeType":"VariableDeclaration","scope":120,"src":"1671:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":107,"name":"string","nodeType":"ElementaryTypeName","src":"1671:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1670:18:0"},"returnParameters":{"id":110,"nodeType":"ParameterList","parameters":[],"src":"1703:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":137,"nodeType":"FunctionDefinition","src":"1785:139:0","nodes":[],"body":{"id":136,"nodeType":"Block","src":"1839:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":130,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1889:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":131,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":122,"src":"1909:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":132,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":124,"src":"1913:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":128,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1865:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":129,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1865:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":133,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1865:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":127,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1849:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":134,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1849:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":135,"nodeType":"ExpressionStatement","src":"1849:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1794:3:0","parameters":{"id":125,"nodeType":"ParameterList","parameters":[{"constant":false,"id":122,"mutability":"mutable","name":"p0","nameLocation":"1812:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1798:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":121,"name":"string","nodeType":"ElementaryTypeName","src":"1798:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":124,"mutability":"mutable","name":"p1","nameLocation":"1821:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1816:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":123,"name":"bool","nodeType":"ElementaryTypeName","src":"1816:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1797:27:0"},"returnParameters":{"id":126,"nodeType":"ParameterList","parameters":[],"src":"1839:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":154,"nodeType":"FunctionDefinition","src":"1930:145:0","nodes":[],"body":{"id":153,"nodeType":"Block","src":"1987:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":147,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2037:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":148,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":139,"src":"2060:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":149,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":141,"src":"2064:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":145,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2013:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":146,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2013:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":150,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2013:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":144,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1997:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":151,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1997:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":152,"nodeType":"ExpressionStatement","src":"1997:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1939:3:0","parameters":{"id":142,"nodeType":"ParameterList","parameters":[{"constant":false,"id":139,"mutability":"mutable","name":"p0","nameLocation":"1957:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1943:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":138,"name":"string","nodeType":"ElementaryTypeName","src":"1943:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":141,"mutability":"mutable","name":"p1","nameLocation":"1969:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1961:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":140,"name":"uint256","nodeType":"ElementaryTypeName","src":"1961:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1942:30:0"},"returnParameters":{"id":143,"nodeType":"ParameterList","parameters":[],"src":"1987:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":171,"nodeType":"FunctionDefinition","src":"2081:145:0","nodes":[],"body":{"id":170,"nodeType":"Block","src":"2138:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":164,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2188:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":165,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":156,"src":"2211:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":166,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":158,"src":"2215:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":162,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2164:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":163,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2164:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":167,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2164:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":161,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2148:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":168,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2148:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":169,"nodeType":"ExpressionStatement","src":"2148:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2090:3:0","parameters":{"id":159,"nodeType":"ParameterList","parameters":[{"constant":false,"id":156,"mutability":"mutable","name":"p0","nameLocation":"2108:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2094:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":155,"name":"string","nodeType":"ElementaryTypeName","src":"2094:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":158,"mutability":"mutable","name":"p1","nameLocation":"2120:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2112:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":157,"name":"address","nodeType":"ElementaryTypeName","src":"2112:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"2093:30:0"},"returnParameters":{"id":160,"nodeType":"ParameterList","parameters":[],"src":"2138:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":191,"nodeType":"FunctionDefinition","src":"2232:179:0","nodes":[],"body":{"id":190,"nodeType":"Block","src":"2313:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":183,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2363:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":184,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2392:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":185,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":175,"src":"2396:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":186,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":177,"src":"2400:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":181,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2339:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":182,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2339:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":187,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2339:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":180,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2323:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":188,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2323:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":189,"nodeType":"ExpressionStatement","src":"2323:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2241:3:0","parameters":{"id":178,"nodeType":"ParameterList","parameters":[{"constant":false,"id":173,"mutability":"mutable","name":"p0","nameLocation":"2259:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2245:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":172,"name":"string","nodeType":"ElementaryTypeName","src":"2245:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":175,"mutability":"mutable","name":"p1","nameLocation":"2277:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2263:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":174,"name":"string","nodeType":"ElementaryTypeName","src":"2263:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":177,"mutability":"mutable","name":"p2","nameLocation":"2295:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2281:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":176,"name":"string","nodeType":"ElementaryTypeName","src":"2281:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2244:54:0"},"returnParameters":{"id":179,"nodeType":"ParameterList","parameters":[],"src":"2313:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[192],"name":"console","nameLocation":"799:7:0","scope":677,"usedErrors":[]},{"id":663,"nodeType":"ContractDefinition","src":"2541:3089:0","nodes":[{"id":207,"nodeType":"VariableDeclaration","src":"2571:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2597:10:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":194,"name":"address","nodeType":"ElementaryTypeName","src":"2571:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2644:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":201,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2634:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":203,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2634:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":200,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2626:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":199,"name":"uint256","nodeType":"ElementaryTypeName","src":"2626:7:0","typeDescriptions":{}}},"id":204,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2626:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":198,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2618:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":197,"name":"uint160","nodeType":"ElementaryTypeName","src":"2618:7:0","typeDescriptions":{}}},"id":205,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2618:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":196,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2610:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":195,"name":"address","nodeType":"ElementaryTypeName","src":"2610:7:0","typeDescriptions":{}}},"id":206,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2610:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":213,"nodeType":"VariableDeclaration","src":"2671:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2692:2:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"},"typeName":{"id":209,"nodeType":"UserDefinedTypeName","pathNode":{"id":208,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":55,"src":"2671:2:0"},"referencedDeclaration":55,"src":"2671:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"value":{"arguments":[{"id":211,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":207,"src":"2700:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":210,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":55,"src":"2697:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$55_$","typeString":"type(contract Vm)"}},"id":212,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2697:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"visibility":"internal"},{"id":215,"nodeType":"VariableDeclaration","src":"2775:22:0","nodes":[],"constant":false,"functionSelector":"61bc221a","mutability":"mutable","name":"counter","nameLocation":"2790:7:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":214,"name":"uint256","nodeType":"ElementaryTypeName","src":"2775:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":378,"nodeType":"FunctionDefinition","src":"2887:949:0","nodes":[],"body":{"id":377,"nodeType":"Block","src":"2909:927:0","nodes":[],"statements":[{"assignments":[220],"declarations":[{"constant":false,"id":220,"mutability":"mutable","name":"x","nameLocation":"2924:1:0","nodeType":"VariableDeclaration","scope":377,"src":"2919:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":219,"name":"bool","nodeType":"ElementaryTypeName","src":"2919:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":226,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":223,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2937:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":224,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2953:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":221,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"2928:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":222,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2928:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":225,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2928:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2919:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":230,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2981:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":231,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":220,"src":"3004:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":227,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"2969:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":229,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":137,"src":"2969:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2969:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":233,"nodeType":"ExpressionStatement","src":"2969:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":237,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3029:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":240,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3054:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":239,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3046:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":238,"name":"address","nodeType":"ElementaryTypeName","src":"3046:7:0","typeDescriptions":{}}},"id":241,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3046:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":234,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3017:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":236,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3017:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":242,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3017:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":243,"nodeType":"ExpressionStatement","src":"3017:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":247,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3082:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":252,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3120:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":251,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3112:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":250,"name":"address","nodeType":"ElementaryTypeName","src":"3112:7:0","typeDescriptions":{}}},"id":253,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3112:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":248,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3100:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3100:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":254,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3100:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":244,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3070:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":246,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3070:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":255,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3070:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":256,"nodeType":"ExpressionStatement","src":"3070:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":260,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3149:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":263,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3172:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":264,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3172:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":262,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3164:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":261,"name":"address","nodeType":"ElementaryTypeName","src":"3164:7:0","typeDescriptions":{}}},"id":265,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3164:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":257,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3137:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":259,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3137:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":266,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3137:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":267,"nodeType":"ExpressionStatement","src":"3137:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":271,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3206:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":276,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3242:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":277,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3242:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":275,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3234:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":274,"name":"address","nodeType":"ElementaryTypeName","src":"3234:7:0","typeDescriptions":{}}},"id":278,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3234:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":272,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3222:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":273,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3222:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":279,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3222:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":268,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3194:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":270,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3194:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":280,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3194:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":281,"nodeType":"ExpressionStatement","src":"3194:61:0"},{"assignments":[283],"declarations":[{"constant":false,"id":283,"mutability":"mutable","name":"json","nameLocation":"3280:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3266:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":282,"name":"string","nodeType":"ElementaryTypeName","src":"3266:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":285,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3287:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"3266:55:0"},{"assignments":[290],"declarations":[{"constant":false,"id":290,"mutability":"mutable","name":"keys","nameLocation":"3347:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3331:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":288,"name":"string","nodeType":"ElementaryTypeName","src":"3331:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":289,"nodeType":"ArrayTypeName","src":"3331:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":296,"initialValue":{"arguments":[{"id":293,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":283,"src":"3371:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":294,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3377:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":291,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3354:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":292,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3354:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":295,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3354:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3331:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":300,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3414:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":301,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3422:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":303,"indexExpression":{"hexValue":"30","id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3427:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3422:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":304,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3431:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":306,"indexExpression":{"hexValue":"31","id":305,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3436:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3431:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":297,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3402:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":299,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":191,"src":"3402:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":307,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3402:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":308,"nodeType":"ExpressionStatement","src":"3402:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":312,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3461:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":309,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3450:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":311,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3450:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":313,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3450:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":314,"nodeType":"ExpressionStatement","src":"3450:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":322,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3517:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":321,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3509:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":320,"name":"uint160","nodeType":"ElementaryTypeName","src":"3509:7:0","typeDescriptions":{}}},"id":323,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3509:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":319,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3501:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":318,"name":"address","nodeType":"ElementaryTypeName","src":"3501:7:0","typeDescriptions":{}}},"id":324,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3501:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":315,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3487:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":317,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3487:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3487:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":326,"nodeType":"ExpressionStatement","src":"3487:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":330,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3545:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":327,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3534:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":329,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3534:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3534:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":332,"nodeType":"ExpressionStatement","src":"3534:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":336,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3582:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":339,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3617:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":340,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3617:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":338,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3609:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":337,"name":"address","nodeType":"ElementaryTypeName","src":"3609:7:0","typeDescriptions":{}}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3609:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":333,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3570:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":335,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3570:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3570:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3570:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3651:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":350,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3689:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":349,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3681:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":348,"name":"address","nodeType":"ElementaryTypeName","src":"3681:7:0","typeDescriptions":{}}},"id":351,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3681:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":344,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3639:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3639:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3639:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":353,"nodeType":"ExpressionStatement","src":"3639:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":357,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3716:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":354,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3705:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":356,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3705:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":358,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3705:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":359,"nodeType":"ExpressionStatement","src":"3705:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":360,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3741:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":362,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3741:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":363,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3741:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":364,"nodeType":"ExpressionStatement","src":"3741:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":368,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3776:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":365,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3765:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":367,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3765:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":369,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3765:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":370,"nodeType":"ExpressionStatement","src":"3765:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":374,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3821:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":371,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3809:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":373,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"3809:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":375,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3809:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":376,"nodeType":"ExpressionStatement","src":"3809:20:0"}]},"documentation":{"id":216,"nodeType":"StructuredDocumentation","src":"2804:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2896:3:0","parameters":{"id":217,"nodeType":"ParameterList","parameters":[],"src":"2899:2:0"},"returnParameters":{"id":218,"nodeType":"ParameterList","parameters":[],"src":"2909:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":566,"nodeType":"FunctionDefinition","src":"3903:988:0","nodes":[],"body":{"id":565,"nodeType":"Block","src":"3934:957:0","nodes":[],"statements":[{"expression":{"arguments":[{"hexValue":"74657374696e672073696e676c65","id":385,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3956:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""},"value":"testing single"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""}],"expression":{"id":382,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3944:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":384,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"3944:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":386,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3944:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":387,"nodeType":"ExpressionStatement","src":"3944:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":388,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3983:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":390,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"3983:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":391,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3983:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":392,"nodeType":"ExpressionStatement","src":"3983:14:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c31","id":396,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4018:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""},"value":"single_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""}],"expression":{"id":393,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4007:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":395,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4007:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":397,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4007:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":398,"nodeType":"ExpressionStatement","src":"4007:26:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c32","id":402,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4054:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""},"value":"single_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""}],"expression":{"id":399,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4043:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":401,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":620,"src":"4043:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":403,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4043:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":404,"nodeType":"ExpressionStatement","src":"4043:26:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073746172742f73746f70","id":408,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4092:20:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""},"value":"testing start/stop"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""}],"expression":{"id":405,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4080:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":407,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4080:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":409,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4080:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":410,"nodeType":"ExpressionStatement","src":"4080:33:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078633066666565","id":418,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4157:8:0","typeDescriptions":{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"},"value":"0xc0ffee"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"}],"id":417,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4149:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":416,"name":"uint160","nodeType":"ElementaryTypeName","src":"4149:7:0","typeDescriptions":{}}},"id":419,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4149:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":415,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4141:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":414,"name":"address","nodeType":"ElementaryTypeName","src":"4141:7:0","typeDescriptions":{}}},"id":420,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4141:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":411,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4123:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":413,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4123:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":421,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4123:45:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":422,"nodeType":"ExpressionStatement","src":"4123:45:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c31","id":426,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4189:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""},"value":"startstop_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""}],"expression":{"id":423,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4178:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":425,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4178:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":427,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4178:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":428,"nodeType":"ExpressionStatement","src":"4178:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c32","id":432,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4228:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""},"value":"startstop_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""}],"expression":{"id":429,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4217:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":431,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":620,"src":"4217:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":433,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4217:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":434,"nodeType":"ExpressionStatement","src":"4217:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f70757265","id":438,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4270:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""},"value":"startstop_pure"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""}],"expression":{"id":435,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4256:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":437,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"callPure","nodeType":"MemberAccess","referencedDeclaration":662,"src":"4256:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure external"}},"id":439,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4256:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":440,"nodeType":"ExpressionStatement","src":"4256:31:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":441,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4297:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":443,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4297:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":444,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4297:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":445,"nodeType":"ExpressionStatement","src":"4297:18:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c33","id":449,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4336:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""},"value":"startstop_call3"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""}],"expression":{"id":446,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4325:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":448,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4325:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":450,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4325:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":451,"nodeType":"ExpressionStatement","src":"4325:29:0"},{"expression":{"arguments":[{"hexValue":"74657374696e67206e6573746564","id":455,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4377:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""},"value":"testing nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""}],"expression":{"id":452,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4365:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":454,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4365:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":456,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4365:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":457,"nodeType":"ExpressionStatement","src":"4365:29:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307831323334","id":465,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4438:6:0","typeDescriptions":{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"},"value":"0x1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"}],"id":464,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4430:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":463,"name":"uint160","nodeType":"ElementaryTypeName","src":"4430:7:0","typeDescriptions":{}}},"id":466,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4430:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":462,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4422:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":461,"name":"address","nodeType":"ElementaryTypeName","src":"4422:7:0","typeDescriptions":{}}},"id":467,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4422:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":458,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4404:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":460,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4404:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":468,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4404:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":469,"nodeType":"ExpressionStatement","src":"4404:43:0"},{"expression":{"arguments":[{"hexValue":"6e6573746564","id":473,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4470:8:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""},"value":"nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""}],"expression":{"id":470,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4457:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":472,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested1","nodeType":"MemberAccess","referencedDeclaration":635,"src":"4457:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":474,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4457:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":475,"nodeType":"ExpressionStatement","src":"4457:22:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":476,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4489:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":478,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4489:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":479,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4489:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":480,"nodeType":"ExpressionStatement","src":"4489:18:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206465706c6f796d656e74","id":484,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4530:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""},"value":"contract deployment"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""}],"expression":{"id":481,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4518:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":483,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4518:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":485,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4518:34:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":486,"nodeType":"ExpressionStatement","src":"4518:34:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078313233343536","id":494,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4591:8:0","typeDescriptions":{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"},"value":"0x123456"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"}],"id":493,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4583:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":492,"name":"uint160","nodeType":"ElementaryTypeName","src":"4583:7:0","typeDescriptions":{}}},"id":495,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4583:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":491,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4575:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":490,"name":"address","nodeType":"ElementaryTypeName","src":"4575:7:0","typeDescriptions":{}}},"id":496,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4575:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":487,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4562:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":489,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4562:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":497,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4562:40:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":498,"nodeType":"ExpressionStatement","src":"4562:40:0"},{"assignments":[501],"declarations":[{"constant":false,"id":501,"mutability":"mutable","name":"x","nameLocation":"4619:1:0","nodeType":"VariableDeclaration","scope":565,"src":"4612:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"},"typeName":{"id":500,"nodeType":"UserDefinedTypeName","pathNode":{"id":499,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4612:6:0"},"referencedDeclaration":676,"src":"4612:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"visibility":"internal"}],"id":507,"initialValue":{"arguments":[{"hexValue":"31323334","id":505,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4634:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":504,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4623:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":503,"nodeType":"UserDefinedTypeName","pathNode":{"id":502,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4627:6:0"},"referencedDeclaration":676,"src":"4627:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}}},"id":506,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4623:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4612:27:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":513,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":509,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":501,"src":"4657:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"id":510,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":665,"src":"4657:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":511,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4657:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":512,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4668:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4657:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":508,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4649:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":514,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4649:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":515,"nodeType":"ExpressionStatement","src":"4649:24:0"},{"expression":{"arguments":[{"hexValue":"6372656174652032","id":519,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4696:10:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""},"value":"create 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""}],"expression":{"id":516,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4684:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":518,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4684:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":520,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4684:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":521,"nodeType":"ExpressionStatement","src":"4684:23:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307863616665","id":529,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4746:6:0","typeDescriptions":{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"},"value":"0xcafe"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"}],"id":528,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4738:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":527,"name":"uint160","nodeType":"ElementaryTypeName","src":"4738:7:0","typeDescriptions":{}}},"id":530,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4738:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":526,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4730:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":525,"name":"address","nodeType":"ElementaryTypeName","src":"4730:7:0","typeDescriptions":{}}},"id":531,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4730:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":522,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4717:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":524,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4717:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":532,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4717:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":533,"nodeType":"ExpressionStatement","src":"4717:38:0"},{"assignments":[536],"declarations":[{"constant":false,"id":536,"mutability":"mutable","name":"y","nameLocation":"4772:1:0","nodeType":"VariableDeclaration","scope":565,"src":"4765:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"},"typeName":{"id":535,"nodeType":"UserDefinedTypeName","pathNode":{"id":534,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4765:6:0"},"referencedDeclaration":676,"src":"4765:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"visibility":"internal"}],"id":550,"initialValue":{"arguments":[{"hexValue":"31323334","id":548,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4815:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":539,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4776:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":538,"nodeType":"UserDefinedTypeName","pathNode":{"id":537,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4780:6:0"},"referencedDeclaration":676,"src":"4780:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}}},"id":547,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"names":["salt"],"nodeType":"FunctionCallOptions","options":[{"arguments":[{"arguments":[{"hexValue":"3432","id":544,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4809:2:0","typeDescriptions":{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"},"value":"42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"}],"id":543,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4801:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":542,"name":"uint256","nodeType":"ElementaryTypeName","src":"4801:7:0","typeDescriptions":{}}},"id":545,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4801:11:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":541,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4793:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_bytes32_$","typeString":"type(bytes32)"},"typeName":{"id":540,"name":"bytes32","nodeType":"ElementaryTypeName","src":"4793:7:0","typeDescriptions":{}}},"id":546,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4793:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"src":"4776:38:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$salt","typeString":"function (uint256) returns (contract FooBar)"}},"id":549,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4776:44:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4765:55:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":556,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":552,"name":"y","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":536,"src":"4838:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"id":553,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":665,"src":"4838:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":554,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4838:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":555,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4849:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4838:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":551,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4830:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":557,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4830:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":558,"nodeType":"ExpressionStatement","src":"4830:24:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":562,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4876:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":559,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4864:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":561,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4864:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":563,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4864:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":564,"nodeType":"ExpressionStatement","src":"4864:20:0"}]},"documentation":{"id":379,"nodeType":"StructuredDocumentation","src":"3842:56:0","text":"@notice example function, to test vm.broadcast with."},"functionSelector":"bef03abc","implemented":true,"kind":"function","modifiers":[],"name":"runBroadcast","nameLocation":"3912:12:0","parameters":{"id":380,"nodeType":"ParameterList","parameters":[],"src":"3924:2:0"},"returnParameters":{"id":381,"nodeType":"ParameterList","parameters":[],"src":"3934:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":590,"nodeType":"FunctionDefinition","src":"4986:143:0","nodes":[],"body":{"id":589,"nodeType":"Block","src":"5035:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":575,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":569,"src":"5057:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":572,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5045:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":574,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5045:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":576,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5045:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":577,"nodeType":"ExpressionStatement","src":"5045:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":581,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"5082:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":584,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"5110:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":585,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"5110:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":583,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5102:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":582,"name":"address","nodeType":"ElementaryTypeName","src":"5102:7:0","typeDescriptions":{}}},"id":586,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5102:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":578,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5070:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":580,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"5070:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":587,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5070:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":588,"nodeType":"ExpressionStatement","src":"5070:52:0"}]},"documentation":{"id":567,"nodeType":"StructuredDocumentation","src":"4897:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"4995:5:0","parameters":{"id":570,"nodeType":"ParameterList","parameters":[{"constant":false,"id":569,"mutability":"mutable","name":"_v","nameLocation":"5017:2:0","nodeType":"VariableDeclaration","scope":590,"src":"5001:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":568,"name":"string","nodeType":"ElementaryTypeName","src":"5001:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5000:20:0"},"returnParameters":{"id":571,"nodeType":"ParameterList","parameters":[],"src":"5035:0:0"},"scope":663,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":605,"nodeType":"FunctionDefinition","src":"5135:95:0","nodes":[],"body":{"id":604,"nodeType":"Block","src":"5179:51:0","nodes":[],"statements":[{"expression":{"id":596,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5189:9:0","subExpression":{"id":595,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5189:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":597,"nodeType":"ExpressionStatement","src":"5189:9:0"},{"expression":{"arguments":[{"id":601,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":592,"src":"5220:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":598,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5208:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":600,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5208:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":602,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5208:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":603,"nodeType":"ExpressionStatement","src":"5208:15:0"}]},"functionSelector":"7e79255d","implemented":true,"kind":"function","modifiers":[],"name":"call1","nameLocation":"5144:5:0","parameters":{"id":593,"nodeType":"ParameterList","parameters":[{"constant":false,"id":592,"mutability":"mutable","name":"_v","nameLocation":"5166:2:0","nodeType":"VariableDeclaration","scope":605,"src":"5150:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":591,"name":"string","nodeType":"ElementaryTypeName","src":"5150:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5149:20:0"},"returnParameters":{"id":594,"nodeType":"ParameterList","parameters":[],"src":"5179:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":620,"nodeType":"FunctionDefinition","src":"5236:95:0","nodes":[],"body":{"id":619,"nodeType":"Block","src":"5280:51:0","nodes":[],"statements":[{"expression":{"id":611,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5290:9:0","subExpression":{"id":610,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5290:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":612,"nodeType":"ExpressionStatement","src":"5290:9:0"},{"expression":{"arguments":[{"id":616,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":607,"src":"5321:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":613,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5309:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":615,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5309:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":617,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5309:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":618,"nodeType":"ExpressionStatement","src":"5309:15:0"}]},"functionSelector":"8d3ef7ca","implemented":true,"kind":"function","modifiers":[],"name":"call2","nameLocation":"5245:5:0","parameters":{"id":608,"nodeType":"ParameterList","parameters":[{"constant":false,"id":607,"mutability":"mutable","name":"_v","nameLocation":"5267:2:0","nodeType":"VariableDeclaration","scope":620,"src":"5251:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":606,"name":"string","nodeType":"ElementaryTypeName","src":"5251:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5250:20:0"},"returnParameters":{"id":609,"nodeType":"ParameterList","parameters":[],"src":"5280:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":635,"nodeType":"FunctionDefinition","src":"5337:98:0","nodes":[],"body":{"id":634,"nodeType":"Block","src":"5383:52:0","nodes":[],"statements":[{"expression":{"id":626,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5393:9:0","subExpression":{"id":625,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5393:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":627,"nodeType":"ExpressionStatement","src":"5393:9:0"},{"expression":{"arguments":[{"id":631,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":622,"src":"5425:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":628,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"5412:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":630,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested2","nodeType":"MemberAccess","referencedDeclaration":650,"src":"5412:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":632,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5412:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":633,"nodeType":"ExpressionStatement","src":"5412:16:0"}]},"functionSelector":"a76ccdfa","implemented":true,"kind":"function","modifiers":[],"name":"nested1","nameLocation":"5346:7:0","parameters":{"id":623,"nodeType":"ParameterList","parameters":[{"constant":false,"id":622,"mutability":"mutable","name":"_v","nameLocation":"5370:2:0","nodeType":"VariableDeclaration","scope":635,"src":"5354:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":621,"name":"string","nodeType":"ElementaryTypeName","src":"5354:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5353:20:0"},"returnParameters":{"id":624,"nodeType":"ParameterList","parameters":[],"src":"5383:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":650,"nodeType":"FunctionDefinition","src":"5441:97:0","nodes":[],"body":{"id":649,"nodeType":"Block","src":"5487:51:0","nodes":[],"statements":[{"expression":{"id":641,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5497:9:0","subExpression":{"id":640,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5497:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":642,"nodeType":"ExpressionStatement","src":"5497:9:0"},{"expression":{"arguments":[{"id":646,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":637,"src":"5528:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":643,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5516:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":645,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5516:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":647,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5516:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":648,"nodeType":"ExpressionStatement","src":"5516:15:0"}]},"functionSelector":"dbf1282f","implemented":true,"kind":"function","modifiers":[],"name":"nested2","nameLocation":"5450:7:0","parameters":{"id":638,"nodeType":"ParameterList","parameters":[{"constant":false,"id":637,"mutability":"mutable","name":"_v","nameLocation":"5474:2:0","nodeType":"VariableDeclaration","scope":650,"src":"5458:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":636,"name":"string","nodeType":"ElementaryTypeName","src":"5458:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5457:20:0"},"returnParameters":{"id":639,"nodeType":"ParameterList","parameters":[],"src":"5487:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":662,"nodeType":"FunctionDefinition","src":"5544:84:0","nodes":[],"body":{"id":661,"nodeType":"Block","src":"5596:32:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":658,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":652,"src":"5618:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":655,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5606:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":657,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5606:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":659,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5606:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":660,"nodeType":"ExpressionStatement","src":"5606:15:0"}]},"functionSelector":"7f8b915c","implemented":true,"kind":"function","modifiers":[],"name":"callPure","nameLocation":"5553:8:0","parameters":{"id":653,"nodeType":"ParameterList","parameters":[{"constant":false,"id":652,"mutability":"mutable","name":"_v","nameLocation":"5578:2:0","nodeType":"VariableDeclaration","scope":662,"src":"5562:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":651,"name":"string","nodeType":"ElementaryTypeName","src":"5562:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5561:20:0"},"returnParameters":{"id":654,"nodeType":"ParameterList","parameters":[],"src":"5596:0:0"},"scope":663,"stateMutability":"pure","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[676],"contractKind":"contract","documentation":{"id":193,"nodeType":"StructuredDocumentation","src":"2415:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[663],"name":"ScriptExample","nameLocation":"2550:13:0","scope":677,"usedErrors":[]},{"id":676,"nodeType":"ContractDefinition","src":"5632:96:0","nodes":[{"id":665,"nodeType":"VariableDeclaration","src":"5654:18:0","nodes":[],"constant":false,"functionSelector":"c2985578","mutability":"mutable","name":"foo","nameLocation":"5669:3:0","scope":676,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":664,"name":"uint256","nodeType":"ElementaryTypeName","src":"5654:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":675,"nodeType":"FunctionDefinition","src":"5679:47:0","nodes":[],"body":{"id":674,"nodeType":"Block","src":"5702:24:0","nodes":[],"statements":[{"expression":{"id":672,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":670,"name":"foo","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":665,"src":"5712:3:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":671,"name":"v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":667,"src":"5718:1:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5712:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":673,"nodeType":"ExpressionStatement","src":"5712:7:0"}]},"implemented":true,"kind":"constructor","modifiers":[],"name":"","nameLocation":"-1:-1:-1","parameters":{"id":668,"nodeType":"ParameterList","parameters":[{"constant":false,"id":667,"mutability":"mutable","name":"v","nameLocation":"5699:1:0","nodeType":"VariableDeclaration","scope":675,"src":"5691:9:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":666,"name":"uint256","nodeType":"ElementaryTypeName","src":"5691:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"5690:11:0"},"returnParameters":{"id":669,"nodeType":"ParameterList","parameters":[],"src":"5702:0:0"},"scope":676,"stateMutability":"nonpayable","virtual":false,"visibility":"public"}],"abstract":false,"baseContracts":[],"canonicalName":"FooBar","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[676],"name":"FooBar","nameLocation":"5641:6:0","scope":677,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file diff --git a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/ScriptExample.json b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/ScriptExample.json index fb6f32b277af..474fa84e4127 100644 --- a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/ScriptExample.json +++ b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/ScriptExample.json @@ -1 +1 @@ -{"abi":[{"type":"function","name":"call1","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"call2","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"counter","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"hello","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"view"},{"type":"function","name":"nested1","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"nested2","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"run","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"runBroadcast","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"bytecode":{"object":"0x608060405234801561001057600080fd5b5061196c806100206000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063a777d0dc1161005b578063a777d0dc146100d0578063bef03abc146100e3578063c0406226146100eb578063dbf1282f146100a857600080fd5b806361bc221a1461008d5780637e79255d146100a85780638d3ef7ca146100a8578063a76ccdfa146100bd575b600080fd5b61009660005481565b60405190815260200160405180910390f35b6100bb6100b6366004611471565b6100f3565b005b6100bb6100cb366004611471565b61014a565b6100bb6100de366004611471565b6101d2565b6100bb610250565b6100bb610925565b600080549080610102836114e3565b919050555061014682828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061117892505050565b5050565b600080549080610159836114e3565b90915550506040517fdbf1282f000000000000000000000000000000000000000000000000000000008152309063dbf1282f9061019c9085908590600401611542565b600060405180830381600087803b1580156101b657600080fd5b505af11580156101ca573d6000803e3d6000fd5b505050505050565b61021182828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061117892505050565b6101466040518060400160405280601081526020017f68656c6c6f206d73672e73656e646572000000000000000000000000000000008152503361120a565b61028e6040518060400160405280600e81526020017f74657374696e672073696e676c65000000000000000000000000000000000000815250611178565b7f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff1663afc980406040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156102f957600080fd5b505af115801561030d573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f73696e676c655f63616c6c3100000000000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b15801561039057600080fd5b505af11580156103a4573d6000803e3d6000fd5b50506040517f8d3ef7ca00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f73696e676c655f63616c6c3200000000000000000000000000000000000000006044820152309250638d3ef7ca9150606401600060405180830381600087803b15801561042757600080fd5b505af115801561043b573d6000803e3d6000fd5b5050505061047d6040518060400160405280601281526020017f74657374696e672073746172742f73746f700000000000000000000000000000815250611178565b7f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff16637fb5297f6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156104e857600080fd5b505af11580156104fc573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3100000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b15801561057f57600080fd5b505af1158015610593573d6000803e3d6000fd5b50506040517f8d3ef7ca00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3200000000000000000000000000000000006044820152309250638d3ef7ca9150606401600060405180830381600087803b15801561061657600080fd5b505af115801561062a573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166376eadd366040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561069957600080fd5b505af11580156106ad573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3300000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b15801561073057600080fd5b505af1158015610744573d6000803e3d6000fd5b505050506107866040518060400160405280600e81526020017f74657374696e67206e6573746564000000000000000000000000000000000000815250611178565b7f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff16637fb5297f6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156107f157600080fd5b505af1158015610805573d6000803e3d6000fd5b50506040517fa76ccdfa00000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f6e65737465640000000000000000000000000000000000000000000000000000604482015230925063a76ccdfa9150606401600060405180830381600087803b15801561088857600080fd5b505af115801561089c573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166376eadd366040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561090b57600080fd5b505af115801561091f573d6000803e3d6000fd5b50505050565b604080517f4777f3cf0000000000000000000000000000000000000000000000000000000081526004810191909152600c60448201527f4558414d504c455f424f4f4c0000000000000000000000000000000000000000606482015260006024820181905290737109709ecfa91a80626ff3989d68f67f5b1dd12d90634777f3cf90608401602060405180830381865afa1580156109c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109eb919061158f565b9050610a2c6040518060400160405280601381526020017f626f6f6c2076616c75652066726f6d20656e76000000000000000000000000008152508261129b565b610a6b6040518060400160405280600d81526020017f636f6e74726163742061646472000000000000000000000000000000000000008152503061120a565b604080518082018252600e81527f636f6e7472616374206e6f6e6365000000000000000000000000000000000000602082015290517f2d0335ab000000000000000000000000000000000000000000000000000000008152306004820152610b3e9190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab906024015b602060405180830381865afa158015610b0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2f91906115b8565b67ffffffffffffffff1661132c565b610b7d6040518060400160405280600b81526020017f73656e64657220616464720000000000000000000000000000000000000000008152503361120a565b604080518082018252600c81527f73656e646572206e6f6e63650000000000000000000000000000000000000000602082015290517f2d0335ab000000000000000000000000000000000000000000000000000000008152336004820152610c049190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab90602401610aee565b60408051808201825260208082527f7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d9082015290517f213e4198000000000000000000000000000000000000000000000000000000008152600090737109709ecfa91a80626ff3989d68f67f5b1dd12d9063213e419890610c89908590600401611658565b600060405180830381865afa158015610ca6573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610cec9190810190611728565b9050610d626040518060400160405280600481526020017f6b6579730000000000000000000000000000000000000000000000000000000081525082600081518110610d3a57610d3a61185c565b602002602001015183600181518110610d5557610d5561185c565b60200260200101516113bd565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f66726f6d206f726967696e616c000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b158015610ddf57600080fd5b505afa158015610df3573d6000803e3d6000fd5b50506040517f06447d5600000000000000000000000000000000000000000000000000000000815260426004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d92506306447d569150602401600060405180830381600087803b158015610e5d57600080fd5b505af1158015610e71573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b20310000000000000000000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b158015610ef257600080fd5b505afa158015610f06573d6000803e3d6000fd5b50505050610f496040518060400160405280601781526020017f706172656e742073636f7065206d73672e73656e6465720000000000000000008152503361120a565b610f886040518060400160405280601a81526020017f706172656e742073636f706520636f6e74726163742e616464720000000000008152503061120a565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b203200000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b15801561100557600080fd5b505afa158015611019573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166390c5013b6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561108857600080fd5b505af115801561109c573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f66726f6d206f726967696e616c20616761696e00000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b15801561111d57600080fd5b505afa158015611131573d6000803e3d6000fd5b505050506111736040518060400160405280600581526020017f646f6e6521000000000000000000000000000000000000000000000000000000815250611178565b505050565b6112078160405160240161118c919061188b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f41304fac0000000000000000000000000000000000000000000000000000000017905261144c565b50565b610146828260405160240161122092919061189e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f319af3330000000000000000000000000000000000000000000000000000000017905261144c565b61014682826040516024016112b19291906118d6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fc3b556350000000000000000000000000000000000000000000000000000000017905261144c565b61014682826040516024016113429291906118fa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb60e72cc0000000000000000000000000000000000000000000000000000000017905261144c565b6111738383836040516024016113d59392919061191c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f2ced7cef000000000000000000000000000000000000000000000000000000001790525b6112078180516a636f6e736f6c652e6c6f67602083016000808483855afa5050505050565b6000806020838503121561148457600080fd5b823567ffffffffffffffff8082111561149c57600080fd5b818501915085601f8301126114b057600080fd5b8135818111156114bf57600080fd5b8660208285010111156114d157600080fd5b60209290920196919550909350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361153b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000602082840312156115a157600080fd5b815180151581146115b157600080fd5b9392505050565b6000602082840312156115ca57600080fd5b815167ffffffffffffffff811681146115b157600080fd5b60005b838110156115fd5781810151838201526020016115e5565b8381111561091f5750506000910152565b600081518084526116268160208601602086016115e2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60408152600061166b604083018461160e565b8281036020840152600c81527f2e726f6f745f6b65795b305d000000000000000000000000000000000000000060208201526040810191505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611720576117206116aa565b604052919050565b6000602080838503121561173b57600080fd5b825167ffffffffffffffff8082111561175357600080fd5b8185019150601f868184011261176857600080fd5b82518281111561177a5761177a6116aa565b8060051b6117898682016116d9565b918252848101860191868101908a8411156117a357600080fd5b87870192505b8383101561184e578251868111156117c15760008081fd5b8701603f81018c136117d35760008081fd5b888101516040888211156117e9576117e96116aa565b6118188b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08a850116016116d9565b8281528e8284860101111561182d5760008081fd5b61183c838d83018487016115e2565b855250505091870191908701906117a9565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020815260006115b1602083018461160e565b6040815260006118b1604083018561160e565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b6040815260006118e9604083018561160e565b905082151560208301529392505050565b60408152600061190d604083018561160e565b90508260208301529392505050565b60608152600061192f606083018661160e565b8281036020840152611941818661160e565b90508281036040840152611955818561160e565b969550505050505056fea164736f6c634300080f000a","sourceMap":"2432:2531:0:-:0;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063a777d0dc1161005b578063a777d0dc146100d0578063bef03abc146100e3578063c0406226146100eb578063dbf1282f146100a857600080fd5b806361bc221a1461008d5780637e79255d146100a85780638d3ef7ca146100a8578063a76ccdfa146100bd575b600080fd5b61009660005481565b60405190815260200160405180910390f35b6100bb6100b6366004611471565b6100f3565b005b6100bb6100cb366004611471565b61014a565b6100bb6100de366004611471565b6101d2565b6100bb610250565b6100bb610925565b600080549080610102836114e3565b919050555061014682828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061117892505050565b5050565b600080549080610159836114e3565b90915550506040517fdbf1282f000000000000000000000000000000000000000000000000000000008152309063dbf1282f9061019c9085908590600401611542565b600060405180830381600087803b1580156101b657600080fd5b505af11580156101ca573d6000803e3d6000fd5b505050505050565b61021182828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061117892505050565b6101466040518060400160405280601081526020017f68656c6c6f206d73672e73656e646572000000000000000000000000000000008152503361120a565b61028e6040518060400160405280600e81526020017f74657374696e672073696e676c65000000000000000000000000000000000000815250611178565b7f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff1663afc980406040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156102f957600080fd5b505af115801561030d573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f73696e676c655f63616c6c3100000000000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b15801561039057600080fd5b505af11580156103a4573d6000803e3d6000fd5b50506040517f8d3ef7ca00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f73696e676c655f63616c6c3200000000000000000000000000000000000000006044820152309250638d3ef7ca9150606401600060405180830381600087803b15801561042757600080fd5b505af115801561043b573d6000803e3d6000fd5b5050505061047d6040518060400160405280601281526020017f74657374696e672073746172742f73746f700000000000000000000000000000815250611178565b7f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff16637fb5297f6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156104e857600080fd5b505af11580156104fc573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3100000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b15801561057f57600080fd5b505af1158015610593573d6000803e3d6000fd5b50506040517f8d3ef7ca00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3200000000000000000000000000000000006044820152309250638d3ef7ca9150606401600060405180830381600087803b15801561061657600080fd5b505af115801561062a573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166376eadd366040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561069957600080fd5b505af11580156106ad573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3300000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b15801561073057600080fd5b505af1158015610744573d6000803e3d6000fd5b505050506107866040518060400160405280600e81526020017f74657374696e67206e6573746564000000000000000000000000000000000000815250611178565b7f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff16637fb5297f6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156107f157600080fd5b505af1158015610805573d6000803e3d6000fd5b50506040517fa76ccdfa00000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f6e65737465640000000000000000000000000000000000000000000000000000604482015230925063a76ccdfa9150606401600060405180830381600087803b15801561088857600080fd5b505af115801561089c573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166376eadd366040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561090b57600080fd5b505af115801561091f573d6000803e3d6000fd5b50505050565b604080517f4777f3cf0000000000000000000000000000000000000000000000000000000081526004810191909152600c60448201527f4558414d504c455f424f4f4c0000000000000000000000000000000000000000606482015260006024820181905290737109709ecfa91a80626ff3989d68f67f5b1dd12d90634777f3cf90608401602060405180830381865afa1580156109c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109eb919061158f565b9050610a2c6040518060400160405280601381526020017f626f6f6c2076616c75652066726f6d20656e76000000000000000000000000008152508261129b565b610a6b6040518060400160405280600d81526020017f636f6e74726163742061646472000000000000000000000000000000000000008152503061120a565b604080518082018252600e81527f636f6e7472616374206e6f6e6365000000000000000000000000000000000000602082015290517f2d0335ab000000000000000000000000000000000000000000000000000000008152306004820152610b3e9190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab906024015b602060405180830381865afa158015610b0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2f91906115b8565b67ffffffffffffffff1661132c565b610b7d6040518060400160405280600b81526020017f73656e64657220616464720000000000000000000000000000000000000000008152503361120a565b604080518082018252600c81527f73656e646572206e6f6e63650000000000000000000000000000000000000000602082015290517f2d0335ab000000000000000000000000000000000000000000000000000000008152336004820152610c049190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab90602401610aee565b60408051808201825260208082527f7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d9082015290517f213e4198000000000000000000000000000000000000000000000000000000008152600090737109709ecfa91a80626ff3989d68f67f5b1dd12d9063213e419890610c89908590600401611658565b600060405180830381865afa158015610ca6573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610cec9190810190611728565b9050610d626040518060400160405280600481526020017f6b6579730000000000000000000000000000000000000000000000000000000081525082600081518110610d3a57610d3a61185c565b602002602001015183600181518110610d5557610d5561185c565b60200260200101516113bd565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f66726f6d206f726967696e616c000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b158015610ddf57600080fd5b505afa158015610df3573d6000803e3d6000fd5b50506040517f06447d5600000000000000000000000000000000000000000000000000000000815260426004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d92506306447d569150602401600060405180830381600087803b158015610e5d57600080fd5b505af1158015610e71573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b20310000000000000000000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b158015610ef257600080fd5b505afa158015610f06573d6000803e3d6000fd5b50505050610f496040518060400160405280601781526020017f706172656e742073636f7065206d73672e73656e6465720000000000000000008152503361120a565b610f886040518060400160405280601a81526020017f706172656e742073636f706520636f6e74726163742e616464720000000000008152503061120a565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b203200000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b15801561100557600080fd5b505afa158015611019573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166390c5013b6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561108857600080fd5b505af115801561109c573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f66726f6d206f726967696e616c20616761696e00000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b15801561111d57600080fd5b505afa158015611131573d6000803e3d6000fd5b505050506111736040518060400160405280600581526020017f646f6e6521000000000000000000000000000000000000000000000000000000815250611178565b505050565b6112078160405160240161118c919061188b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f41304fac0000000000000000000000000000000000000000000000000000000017905261144c565b50565b610146828260405160240161122092919061189e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f319af3330000000000000000000000000000000000000000000000000000000017905261144c565b61014682826040516024016112b19291906118d6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fc3b556350000000000000000000000000000000000000000000000000000000017905261144c565b61014682826040516024016113429291906118fa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb60e72cc0000000000000000000000000000000000000000000000000000000017905261144c565b6111738383836040516024016113d59392919061191c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f2ced7cef000000000000000000000000000000000000000000000000000000001790525b6112078180516a636f6e736f6c652e6c6f67602083016000808483855afa5050505050565b6000806020838503121561148457600080fd5b823567ffffffffffffffff8082111561149c57600080fd5b818501915085601f8301126114b057600080fd5b8135818111156114bf57600080fd5b8660208285010111156114d157600080fd5b60209290920196919550909350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361153b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000602082840312156115a157600080fd5b815180151581146115b157600080fd5b9392505050565b6000602082840312156115ca57600080fd5b815167ffffffffffffffff811681146115b157600080fd5b60005b838110156115fd5781810151838201526020016115e5565b8381111561091f5750506000910152565b600081518084526116268160208601602086016115e2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60408152600061166b604083018461160e565b8281036020840152600c81527f2e726f6f745f6b65795b305d000000000000000000000000000000000000000060208201526040810191505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611720576117206116aa565b604052919050565b6000602080838503121561173b57600080fd5b825167ffffffffffffffff8082111561175357600080fd5b8185019150601f868184011261176857600080fd5b82518281111561177a5761177a6116aa565b8060051b6117898682016116d9565b918252848101860191868101908a8411156117a357600080fd5b87870192505b8383101561184e578251868111156117c15760008081fd5b8701603f81018c136117d35760008081fd5b888101516040888211156117e9576117e96116aa565b6118188b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08a850116016116d9565b8281528e8284860101111561182d5760008081fd5b61183c838d83018487016115e2565b855250505091870191908701906117a9565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020815260006115b1602083018461160e565b6040815260006118b1604083018561160e565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b6040815260006118e9604083018561160e565b905082151560208301529392505050565b60408152600061190d604083018561160e565b90508260208301529392505050565b60608152600061192f606083018661160e565b8281036020840152611941818661160e565b90508281036040840152611955818561160e565b969550505050505056fea164736f6c634300080f000a","sourceMap":"2432:2531:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2666:22;;;;;;;;;160:25:1;;;148:2;133:18;2666:22:0;;;;;;;4558:95;;;;;;:::i;:::-;;:::i;:::-;;4760:98;;;;;;:::i;:::-;;:::i;4409:143::-;;;;;;:::i;:::-;;:::i;3794:520::-;;;:::i;2778:949::-;;;:::i;4558:95::-;4612:7;:9;;;:7;:9;;;:::i;:::-;;;;;;4631:15;4643:2;;4631:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4631:11:0;;-1:-1:-1;;;4631:15:0:i;:::-;4558:95;;:::o;4760:98::-;4816:7;:9;;;:7;:9;;;:::i;:::-;;;;-1:-1:-1;;4835:16:0;;;;;:4;;:12;;:16;;4848:2;;;;4835:16;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4760:98;;:::o;4409:143::-;4468:15;4480:2;;4468:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4468:11:0;;-1:-1:-1;;;4468:15:0:i;:::-;4493:52;;;;;;;;;;;;;;;;;;4533:10;4493:11;:52::i;3794:520::-;3835:29;;;;;;;;;;;;;;;;;;:11;:29::i;:::-;2525:28;2517:37;;3874:12;;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3898:26:0;;;;;1803:2:1;3898:26:0;;;1785:21:1;1842:2;1822:18;;;1815:30;1881:14;1861:18;;;1854:42;3898:4:0;;-1:-1:-1;3898:10:0;;-1:-1:-1;1913:18:1;;3898:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3934:26:0;;;;;2144:2:1;3934:26:0;;;2126:21:1;2183:2;2163:18;;;2156:30;2222:14;2202:18;;;2195:42;3934:4:0;;-1:-1:-1;3934:10:0;;-1:-1:-1;2254:18:1;;3934:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3971:33;;;;;;;;;;;;;;;;;;:11;:33::i;:::-;2525:28;2517:37;;4014:17;;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4043:29:0;;;;;2485:2:1;4043:29:0;;;2467:21:1;2524:2;2504:18;;;2497:30;2563:17;2543:18;;;2536:45;4043:4:0;;-1:-1:-1;4043:10:0;;-1:-1:-1;2598:18:1;;4043:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4082:29:0;;;;;2829:2:1;4082:29:0;;;2811:21:1;2868:2;2848:18;;;2841:30;2907:17;2887:18;;;2880:45;4082:4:0;;-1:-1:-1;4082:10:0;;-1:-1:-1;2942:18:1;;4082:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2525:28;2517:37;;4121:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4149:29:0;;;;;3173:2:1;4149:29:0;;;3155:21:1;3212:2;3192:18;;;3185:30;3251:17;3231:18;;;3224:45;4149:4:0;;-1:-1:-1;4149:10:0;;-1:-1:-1;3286:18:1;;4149:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4189;;;;;;;;;;;;;;;;;;:11;:29::i;:::-;2525:28;2517:37;;4228:17;;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4257:22:0;;;;;3517:2:1;4257:22:0;;;3499:21:1;3556:1;3536:18;;;3529:29;3594:8;3574:18;;;3567:36;4257:4:0;;-1:-1:-1;4257:12:0;;-1:-1:-1;3620:18:1;;4257:22:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2525:28;2517:37;;4289:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3794:520::o;2778:949::-;2819:31;;;;;;;;;3855:21:1;;;;3912:2;3892:18;;;3885:30;3951:14;3931:18;;;3924:42;2810:6:0;4018:20:1;;;4011:52;;;2810:6:0;2819:8;;;;3983:19:1;;2819:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2810:40;;2860:37;;;;;;;;;;;;;;;;;;2895:1;2860:11;:37::i;:::-;2908:43;;;;;;;;;;;;;;;;;;2945:4;2908:11;:43::i;:::-;2961:57;;;;;;;;;;;;;;;;2991:26;;;;;3011:4;2991:26;;;4502:74:1;2961:57:0;;;2991:11;;;;4475:18:1;;2991:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2961:57;;:11;:57::i;:::-;3028:47;;;;;;;;;;;;;;;;;;3063:10;3028:11;:47::i;:::-;3085:61;;;;;;;;;;;;;;;;3113:32;;;;;3133:10;3113:32;;;4502:74:1;3085:61:0;;;3113:11;;;;4475:18:1;;3113:32:0;4356:226:1;3085:61:0;3157:55;;;;;;;;;;;;;;;;;3245:38;;;;;3157:18;;3245:16;;;;:38;;3157:55;;3245:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3222:61;;3293:37;;;;;;;;;;;;;;;;;;3313:4;3318:1;3313:7;;;;;;;;:::i;:::-;;;;;;;3322:4;3327:1;3322:7;;;;;;;;:::i;:::-;;;;;;;3293:11;:37::i;:::-;3341:27;;;;;8688:2:1;3341:27:0;;;8670:21:1;8727:2;8707:18;;;8700:30;8766:15;8746:18;;;8739:43;3341:4:0;;:10;;8799:18:1;;3341:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3378:37:0;;;;;3408:4;3378:37;;;4502:74:1;3378:13:0;;-1:-1:-1;3378:13:0;;-1:-1:-1;4475:18:1;;3378:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3425:26:0;;;;;9030:2:1;3425:26:0;;;9012:21:1;9069:2;9049:18;;;9042:30;9108:14;9088:18;;;9081:42;3425:4:0;;-1:-1:-1;3425:10:0;;-1:-1:-1;9140:18:1;;3425:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3461:59;;;;;;;;;;;;;;;;;;3508:10;3461:11;:59::i;:::-;3530:56;;;;;;;;;;;;;;;;;;3580:4;3530:11;:56::i;:::-;3596:26;;;;;9371:2:1;3596:26:0;;;9353:21:1;9410:2;9390:18;;;9383:30;9449:14;9429:18;;;9422:42;3596:4:0;;:10;;9481:18:1;;3596:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2525:28;2517:37;;3632:12;;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3656:33:0;;;;;9712:2:1;3656:33:0;;;9694:21:1;9751:2;9731:18;;;9724:30;9790:21;9770:18;;;9763:49;3656:4:0;;-1:-1:-1;3656:10:0;;-1:-1:-1;9829:18:1;;3656:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3700:20;;;;;;;;;;;;;;;;;;:11;:20::i;:::-;2800:927;;;2778:949::o;1549:121::-;1604:59;1659:2;1620:42;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1604:15;:59::i;:::-;1549:121;:::o;1972:145::-;2039:71;2102:2;2106;2055:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;2039:15;:71::i;1676:139::-;1740:68;1800:2;1804;1756:51;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1740:15;:68::i;1821:145::-;1888:71;1951:2;1955;1904:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1888:15;:71::i;2123:179::-;2214:81;2283:2;2287;2291;2230:64;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1024:133;1095:55;1142:7;1261:14;;747:42;1434:2;1421:16;;1237:21;;1261:14;1421:16;747:42;1470:5;1459:68;1450:77;;1387:150;;1163:380;:::o;196:592:1:-;267:6;275;328:2;316:9;307:7;303:23;299:32;296:52;;;344:1;341;334:12;296:52;384:9;371:23;413:18;454:2;446:6;443:14;440:34;;;470:1;467;460:12;440:34;508:6;497:9;493:22;483:32;;553:7;546:4;542:2;538:13;534:27;524:55;;575:1;572;565:12;524:55;615:2;602:16;641:2;633:6;630:14;627:34;;;657:1;654;647:12;627:34;702:7;697:2;688:6;684:2;680:15;676:24;673:37;670:57;;;723:1;720;713:12;670:57;754:2;746:11;;;;;776:6;;-1:-1:-1;196:592:1;;-1:-1:-1;;;;196:592:1:o;793:349::-;832:3;863:66;856:5;853:77;850:257;;963:77;960:1;953:88;1064:4;1061:1;1054:15;1092:4;1089:1;1082:15;850:257;-1:-1:-1;1134:1:1;1123:13;;793:349::o;1147:449::-;1306:2;1295:9;1288:21;1345:6;1340:2;1329:9;1325:18;1318:34;1402:6;1394;1389:2;1378:9;1374:18;1361:48;1458:1;1429:22;;;1453:2;1425:31;;;1418:42;;;;1512:2;1500:15;;;1517:66;1496:88;1481:104;1477:113;;1147:449;-1:-1:-1;1147:449:1:o;4074:277::-;4141:6;4194:2;4182:9;4173:7;4169:23;4165:32;4162:52;;;4210:1;4207;4200:12;4162:52;4242:9;4236:16;4295:5;4288:13;4281:21;4274:5;4271:32;4261:60;;4317:1;4314;4307:12;4261:60;4340:5;4074:277;-1:-1:-1;;;4074:277:1:o;4587:288::-;4656:6;4709:2;4697:9;4688:7;4684:23;4680:32;4677:52;;;4725:1;4722;4715:12;4677:52;4757:9;4751:16;4807:18;4800:5;4796:30;4789:5;4786:41;4776:69;;4841:1;4838;4831:12;4880:258;4952:1;4962:113;4976:6;4973:1;4970:13;4962:113;;;5052:11;;;5046:18;5033:11;;;5026:39;4998:2;4991:10;4962:113;;;5093:6;5090:1;5087:13;5084:48;;;-1:-1:-1;;5128:1:1;5110:16;;5103:27;4880:258::o;5143:317::-;5185:3;5223:5;5217:12;5250:6;5245:3;5238:19;5266:63;5322:6;5315:4;5310:3;5306:14;5299:4;5292:5;5288:16;5266:63;:::i;:::-;5374:2;5362:15;5379:66;5358:88;5349:98;;;;5449:4;5345:109;;5143:317;-1:-1:-1;;5143:317:1:o;5465:493::-;5715:2;5704:9;5697:21;5678:4;5741:45;5782:2;5771:9;5767:18;5759:6;5741:45;:::i;:::-;5834:9;5826:6;5822:22;5817:2;5806:9;5802:18;5795:50;5869:2;5861:6;5854:18;5905:14;5900:2;5892:6;5888:15;5881:39;5949:2;5941:6;5937:15;5929:23;;;5465:493;;;;:::o;5963:184::-;6015:77;6012:1;6005:88;6112:4;6109:1;6102:15;6136:4;6133:1;6126:15;6152:334;6223:2;6217:9;6279:2;6269:13;;6284:66;6265:86;6253:99;;6382:18;6367:34;;6403:22;;;6364:62;6361:88;;;6429:18;;:::i;:::-;6465:2;6458:22;6152:334;;-1:-1:-1;6152:334:1:o;6491:1801::-;6596:6;6627:2;6670;6658:9;6649:7;6645:23;6641:32;6638:52;;;6686:1;6683;6676:12;6638:52;6719:9;6713:16;6748:18;6789:2;6781:6;6778:14;6775:34;;;6805:1;6802;6795:12;6775:34;6843:6;6832:9;6828:22;6818:32;;6869:4;6909:7;6904:2;6900;6896:11;6892:25;6882:53;;6931:1;6928;6921:12;6882:53;6960:2;6954:9;6982:2;6978;6975:10;6972:36;;;6988:18;;:::i;:::-;7034:2;7031:1;7027:10;7057:28;7081:2;7077;7073:11;7057:28;:::i;:::-;7119:15;;;7189:11;;;7185:20;;;7150:12;;;;7217:19;;;7214:39;;;7249:1;7246;7239:12;7214:39;7281:2;7277;7273:11;7262:22;;7293:969;7309:6;7304:3;7301:15;7293:969;;;7388:3;7382:10;7424:2;7411:11;7408:19;7405:109;;;7468:1;7497:2;7493;7486:14;7405:109;7537:20;;7592:2;7584:11;;7580:25;-1:-1:-1;7570:123:1;;7647:1;7676:2;7672;7665:14;7570:123;7731:2;7727;7723:11;7717:18;7759:2;7785;7780:3;7777:11;7774:37;;;7791:18;;:::i;:::-;7837:111;7944:2;7875:66;7870:2;7865:3;7861:12;7857:85;7853:94;7837:111;:::i;:::-;7975:3;7968:5;7961:18;8022:7;8016:3;8010;8006:2;8002:12;7998:22;7995:35;7992:128;;;8072:1;8102:3;8097;8090:16;7992:128;8133:56;8185:3;8180:2;8173:5;8169:14;8163:3;8159:2;8155:12;8133:56;:::i;:::-;8202:18;;-1:-1:-1;;;7326:12:1;;;;8240;;;;7293:969;;;8281:5;6491:1801;-1:-1:-1;;;;;;;;;;6491:1801:1:o;8297:184::-;8349:77;8346:1;8339:88;8446:4;8443:1;8436:15;8470:4;8467:1;8460:15;9858:220;10007:2;9996:9;9989:21;9970:4;10027:45;10068:2;10057:9;10053:18;10045:6;10027:45;:::i;10083:340::-;10260:2;10249:9;10242:21;10223:4;10280:45;10321:2;10310:9;10306:18;10298:6;10280:45;:::i;:::-;10272:53;;10373:42;10365:6;10361:55;10356:2;10345:9;10341:18;10334:83;10083:340;;;;;:::o;10428:301::-;10599:2;10588:9;10581:21;10562:4;10619:45;10660:2;10649:9;10645:18;10637:6;10619:45;:::i;:::-;10611:53;;10714:6;10707:14;10700:22;10695:2;10684:9;10680:18;10673:50;10428:301;;;;;:::o;10734:291::-;10911:2;10900:9;10893:21;10874:4;10931:45;10972:2;10961:9;10957:18;10949:6;10931:45;:::i;:::-;10923:53;;11012:6;11007:2;10996:9;10992:18;10985:34;10734:291;;;;;:::o;11030:546::-;11275:2;11264:9;11257:21;11238:4;11301:45;11342:2;11331:9;11327:18;11319:6;11301:45;:::i;:::-;11394:9;11386:6;11382:22;11377:2;11366:9;11362:18;11355:50;11428:33;11454:6;11446;11428:33;:::i;:::-;11414:47;;11509:9;11501:6;11497:22;11492:2;11481:9;11477:18;11470:50;11537:33;11563:6;11555;11537:33;:::i;:::-;11529:41;11030:546;-1:-1:-1;;;;;;11030:546:1:o","linkReferences":{}},"methodIdentifiers":{"call1(string)":"7e79255d","call2(string)":"8d3ef7ca","counter()":"61bc221a","hello(string)":"a777d0dc","nested1(string)":"a76ccdfa","nested2(string)":"dbf1282f","run()":"c0406226","runBroadcast()":"bef03abc"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"call1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"call2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"counter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"hello\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"nested1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"nested2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"run\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"runBroadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"title\":\"ScriptExample\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"hello(string)\":{\"notice\":\"example external function, to force a CALL, and test vm.startPrank with.\"},\"run()\":{\"notice\":\"example function, runs through basic cheat-codes and console logs.\"},\"runBroadcast()\":{\"notice\":\"example function, to test vm.broadcast with.\"}},\"notice\":\"ScriptExample is an example script. The Go forge script code tests that it can run this.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"ScriptExample\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x7727e5a55f4b3d442729483d41848c957b04027e48d972a568ee6f50aa3daa7a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4de8bd2d73869b583c44f8996ef56f872ce47499e801aa95da90a8e695196b00\",\"dweb:/ipfs/QmZzQy8ZSWuMnLBsGWTxUxZRhWGTJ8cq8yHpM59irYA2dw\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"call1"},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"call2"},{"inputs":[],"stateMutability":"view","type":"function","name":"counter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"view","type":"function","name":"hello"},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"nested1"},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"nested2"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"run"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"runBroadcast"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{"hello(string)":{"notice":"example external function, to force a CALL, and test vm.startPrank with."},"run()":{"notice":"example function, runs through basic cheat-codes and console logs."},"runBroadcast()":{"notice":"example function, to test vm.broadcast with."}},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"ScriptExample"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x7727e5a55f4b3d442729483d41848c957b04027e48d972a568ee6f50aa3daa7a","urls":["bzz-raw://4de8bd2d73869b583c44f8996ef56f872ce47499e801aa95da90a8e695196b00","dweb:/ipfs/QmZzQy8ZSWuMnLBsGWTxUxZRhWGTJ8cq8yHpM59irYA2dw"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[{"astId":205,"contract":"scripts/ScriptExample.s.sol:ScriptExample","label":"counter","offset":0,"slot":"0","type":"t_uint256"}],"types":{"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"userdoc":{"version":1,"kind":"user","methods":{"hello(string)":{"notice":"example external function, to force a CALL, and test vm.startPrank with."},"run()":{"notice":"example function, runs through basic cheat-codes and console logs."},"runBroadcast()":{"notice":"example function, to test vm.broadcast with."}},"notice":"ScriptExample is an example script. The Go forge script code tests that it can run this."},"devdoc":{"version":1,"kind":"dev","title":"ScriptExample"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":538,"exportedSymbols":{"ScriptExample":[537],"Vm":[45],"console":[182]},"nodeType":"SourceUnit","src":"32:4932:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":45,"nodeType":"ContractDefinition","src":"120:507:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":45,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":45,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":45,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":38,"nodeType":"FunctionDefinition","src":"516:30:0","nodes":[],"functionSelector":"afc98040","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"525:9:0","parameters":{"id":36,"nodeType":"ParameterList","parameters":[],"src":"534:2:0"},"returnParameters":{"id":37,"nodeType":"ParameterList","parameters":[],"src":"545:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":41,"nodeType":"FunctionDefinition","src":"551:35:0","nodes":[],"functionSelector":"7fb5297f","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"560:14:0","parameters":{"id":39,"nodeType":"ParameterList","parameters":[],"src":"574:2:0"},"returnParameters":{"id":40,"nodeType":"ParameterList","parameters":[],"src":"585:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":44,"nodeType":"FunctionDefinition","src":"591:34:0","nodes":[],"functionSelector":"76eadd36","implemented":false,"kind":"function","modifiers":[],"name":"stopBroadcast","nameLocation":"600:13:0","parameters":{"id":42,"nodeType":"ParameterList","parameters":[],"src":"613:2:0"},"returnParameters":{"id":43,"nodeType":"ParameterList","parameters":[],"src":"624:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[45],"name":"Vm","nameLocation":"130:2:0","scope":538,"usedErrors":[]},{"id":182,"nodeType":"ContractDefinition","src":"682:1622:0","nodes":[{"id":51,"nodeType":"VariableDeclaration","src":"704:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"721:15:0","scope":182,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":46,"name":"address","nodeType":"ElementaryTypeName","src":"704:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":49,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"747:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":48,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"739:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":47,"name":"address","nodeType":"ElementaryTypeName","src":"739:7:0","typeDescriptions":{}}},"id":50,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"739:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":68,"nodeType":"FunctionDefinition","src":"797:221:0","nodes":[],"body":{"id":67,"nodeType":"Block","src":"956:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"975:37:0","statements":[{"nodeType":"YulAssignment","src":"989:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"998:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"989:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":57,"isOffset":false,"isSlot":false,"src":"998:4:0","valueSize":1},{"declaration":64,"isOffset":false,"isSlot":false,"src":"989:5:0","valueSize":1}],"id":66,"nodeType":"InlineAssembly","src":"966:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"806:25:0","parameters":{"id":58,"nodeType":"ParameterList","parameters":[{"constant":false,"id":57,"mutability":"mutable","name":"fnIn","nameLocation":"878:4:0","nodeType":"VariableDeclaration","scope":68,"src":"841:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":56,"nodeType":"FunctionTypeName","parameterTypes":{"id":54,"nodeType":"ParameterList","parameters":[{"constant":false,"id":53,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":56,"src":"850:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":52,"name":"bytes","nodeType":"ElementaryTypeName","src":"850:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"849:14:0"},"returnParameterTypes":{"id":55,"nodeType":"ParameterList","parameters":[],"src":"878:0:0"},"src":"841:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"831:57:0"},"returnParameters":{"id":65,"nodeType":"ParameterList","parameters":[{"constant":false,"id":64,"mutability":"mutable","name":"fnOut","nameLocation":"949:5:0","nodeType":"VariableDeclaration","scope":68,"src":"912:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":63,"nodeType":"FunctionTypeName","parameterTypes":{"id":61,"nodeType":"ParameterList","parameters":[{"constant":false,"id":60,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":63,"src":"921:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":59,"name":"bytes","nodeType":"ElementaryTypeName","src":"921:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"920:14:0"},"returnParameterTypes":{"id":62,"nodeType":"ParameterList","parameters":[],"src":"949:0:0"},"src":"912:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"911:44:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":80,"nodeType":"FunctionDefinition","src":"1024:133:0","nodes":[],"body":{"id":79,"nodeType":"Block","src":"1085:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":76,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":70,"src":"1142:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":74,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":96,"src":"1121:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":73,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":68,"src":"1095:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":75,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1095:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":77,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1095:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":78,"nodeType":"ExpressionStatement","src":"1095:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"1033:15:0","parameters":{"id":71,"nodeType":"ParameterList","parameters":[{"constant":false,"id":70,"mutability":"mutable","name":"payload","nameLocation":"1062:7:0","nodeType":"VariableDeclaration","scope":80,"src":"1049:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":69,"name":"bytes","nodeType":"ElementaryTypeName","src":"1049:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1048:22:0"},"returnParameters":{"id":72,"nodeType":"ParameterList","parameters":[],"src":"1085:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":96,"nodeType":"FunctionDefinition","src":"1163:380:0","nodes":[],"body":{"id":95,"nodeType":"Block","src":"1227:316:0","nodes":[],"statements":[{"assignments":[86],"declarations":[{"constant":false,"id":86,"mutability":"mutable","name":"payloadLength","nameLocation":"1245:13:0","nodeType":"VariableDeclaration","scope":95,"src":"1237:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":85,"name":"uint256","nodeType":"ElementaryTypeName","src":"1237:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":89,"initialValue":{"expression":{"id":87,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":82,"src":"1261:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":88,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1261:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1237:38:0"},{"assignments":[91],"declarations":[{"constant":false,"id":91,"mutability":"mutable","name":"consoleAddress","nameLocation":"1293:14:0","nodeType":"VariableDeclaration","scope":95,"src":"1285:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":90,"name":"address","nodeType":"ElementaryTypeName","src":"1285:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":93,"initialValue":{"id":92,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":51,"src":"1310:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1285:40:0"},{"AST":{"nodeType":"YulBlock","src":"1387:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1401:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1425:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1434:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1421:3:0"},"nodeType":"YulFunctionCall","src":"1421:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1405:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1450:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1470:3:0"},"nodeType":"YulFunctionCall","src":"1470:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1477:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1493:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1507:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1522:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1525:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1459:10:0"},"nodeType":"YulFunctionCall","src":"1459:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1454:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":91,"isOffset":false,"isSlot":false,"src":"1477:14:0","valueSize":1},{"declaration":82,"isOffset":false,"isSlot":false,"src":"1425:7:0","valueSize":1},{"declaration":86,"isOffset":false,"isSlot":false,"src":"1507:13:0","valueSize":1}],"id":94,"nodeType":"InlineAssembly","src":"1378:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1172:19:0","parameters":{"id":83,"nodeType":"ParameterList","parameters":[{"constant":false,"id":82,"mutability":"mutable","name":"payload","nameLocation":"1205:7:0","nodeType":"VariableDeclaration","scope":96,"src":"1192:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":81,"name":"bytes","nodeType":"ElementaryTypeName","src":"1192:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1191:22:0"},"returnParameters":{"id":84,"nodeType":"ParameterList","parameters":[],"src":"1227:0:0"},"scope":182,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":110,"nodeType":"FunctionDefinition","src":"1549:121:0","nodes":[],"body":{"id":109,"nodeType":"Block","src":"1594:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":104,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1644:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":105,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":98,"src":"1659:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":102,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1620:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":103,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1620:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":106,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1620:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":101,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1604:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":107,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1604:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":108,"nodeType":"ExpressionStatement","src":"1604:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1558:3:0","parameters":{"id":99,"nodeType":"ParameterList","parameters":[{"constant":false,"id":98,"mutability":"mutable","name":"p0","nameLocation":"1576:2:0","nodeType":"VariableDeclaration","scope":110,"src":"1562:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":97,"name":"string","nodeType":"ElementaryTypeName","src":"1562:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1561:18:0"},"returnParameters":{"id":100,"nodeType":"ParameterList","parameters":[],"src":"1594:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":127,"nodeType":"FunctionDefinition","src":"1676:139:0","nodes":[],"body":{"id":126,"nodeType":"Block","src":"1730:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":120,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1780:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":121,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":112,"src":"1800:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":122,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":114,"src":"1804:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":118,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1756:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":119,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1756:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":123,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1756:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":117,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1740:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":124,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1740:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":125,"nodeType":"ExpressionStatement","src":"1740:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1685:3:0","parameters":{"id":115,"nodeType":"ParameterList","parameters":[{"constant":false,"id":112,"mutability":"mutable","name":"p0","nameLocation":"1703:2:0","nodeType":"VariableDeclaration","scope":127,"src":"1689:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":111,"name":"string","nodeType":"ElementaryTypeName","src":"1689:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":114,"mutability":"mutable","name":"p1","nameLocation":"1712:2:0","nodeType":"VariableDeclaration","scope":127,"src":"1707:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":113,"name":"bool","nodeType":"ElementaryTypeName","src":"1707:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1688:27:0"},"returnParameters":{"id":116,"nodeType":"ParameterList","parameters":[],"src":"1730:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":144,"nodeType":"FunctionDefinition","src":"1821:145:0","nodes":[],"body":{"id":143,"nodeType":"Block","src":"1878:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":137,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1928:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":138,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":129,"src":"1951:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":139,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":131,"src":"1955:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":135,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1904:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":136,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1904:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":140,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1904:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":134,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1888:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":141,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1888:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":142,"nodeType":"ExpressionStatement","src":"1888:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1830:3:0","parameters":{"id":132,"nodeType":"ParameterList","parameters":[{"constant":false,"id":129,"mutability":"mutable","name":"p0","nameLocation":"1848:2:0","nodeType":"VariableDeclaration","scope":144,"src":"1834:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":128,"name":"string","nodeType":"ElementaryTypeName","src":"1834:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":131,"mutability":"mutable","name":"p1","nameLocation":"1860:2:0","nodeType":"VariableDeclaration","scope":144,"src":"1852:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":130,"name":"uint256","nodeType":"ElementaryTypeName","src":"1852:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1833:30:0"},"returnParameters":{"id":133,"nodeType":"ParameterList","parameters":[],"src":"1878:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":161,"nodeType":"FunctionDefinition","src":"1972:145:0","nodes":[],"body":{"id":160,"nodeType":"Block","src":"2029:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":154,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2079:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":155,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":146,"src":"2102:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":156,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":148,"src":"2106:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":152,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2055:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":153,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2055:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":157,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2055:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":151,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"2039:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":158,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2039:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":159,"nodeType":"ExpressionStatement","src":"2039:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1981:3:0","parameters":{"id":149,"nodeType":"ParameterList","parameters":[{"constant":false,"id":146,"mutability":"mutable","name":"p0","nameLocation":"1999:2:0","nodeType":"VariableDeclaration","scope":161,"src":"1985:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":145,"name":"string","nodeType":"ElementaryTypeName","src":"1985:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":148,"mutability":"mutable","name":"p1","nameLocation":"2011:2:0","nodeType":"VariableDeclaration","scope":161,"src":"2003:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":147,"name":"address","nodeType":"ElementaryTypeName","src":"2003:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1984:30:0"},"returnParameters":{"id":150,"nodeType":"ParameterList","parameters":[],"src":"2029:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":181,"nodeType":"FunctionDefinition","src":"2123:179:0","nodes":[],"body":{"id":180,"nodeType":"Block","src":"2204:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":173,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2254:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":174,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":163,"src":"2283:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":175,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":165,"src":"2287:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":176,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":167,"src":"2291:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":171,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2230:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":172,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2230:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":177,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2230:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":170,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"2214:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":178,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2214:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":179,"nodeType":"ExpressionStatement","src":"2214:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2132:3:0","parameters":{"id":168,"nodeType":"ParameterList","parameters":[{"constant":false,"id":163,"mutability":"mutable","name":"p0","nameLocation":"2150:2:0","nodeType":"VariableDeclaration","scope":181,"src":"2136:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":162,"name":"string","nodeType":"ElementaryTypeName","src":"2136:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":165,"mutability":"mutable","name":"p1","nameLocation":"2168:2:0","nodeType":"VariableDeclaration","scope":181,"src":"2154:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":164,"name":"string","nodeType":"ElementaryTypeName","src":"2154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":167,"mutability":"mutable","name":"p2","nameLocation":"2186:2:0","nodeType":"VariableDeclaration","scope":181,"src":"2172:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":166,"name":"string","nodeType":"ElementaryTypeName","src":"2172:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2135:54:0"},"returnParameters":{"id":169,"nodeType":"ParameterList","parameters":[],"src":"2204:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[182],"name":"console","nameLocation":"690:7:0","scope":538,"usedErrors":[]},{"id":537,"nodeType":"ContractDefinition","src":"2432:2531:0","nodes":[{"id":197,"nodeType":"VariableDeclaration","src":"2462:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2488:10:0","scope":537,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":184,"name":"address","nodeType":"ElementaryTypeName","src":"2462:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":192,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2535:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":191,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2525:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":193,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2525:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":190,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2517:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":189,"name":"uint256","nodeType":"ElementaryTypeName","src":"2517:7:0","typeDescriptions":{}}},"id":194,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2517:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":188,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2509:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":187,"name":"uint160","nodeType":"ElementaryTypeName","src":"2509:7:0","typeDescriptions":{}}},"id":195,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2509:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":186,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2501:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":185,"name":"address","nodeType":"ElementaryTypeName","src":"2501:7:0","typeDescriptions":{}}},"id":196,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2501:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":203,"nodeType":"VariableDeclaration","src":"2562:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2583:2:0","scope":537,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"},"typeName":{"id":199,"nodeType":"UserDefinedTypeName","pathNode":{"id":198,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":45,"src":"2562:2:0"},"referencedDeclaration":45,"src":"2562:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"value":{"arguments":[{"id":201,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":197,"src":"2591:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":200,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":45,"src":"2588:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$45_$","typeString":"type(contract Vm)"}},"id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2588:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"visibility":"internal"},{"id":205,"nodeType":"VariableDeclaration","src":"2666:22:0","nodes":[],"constant":false,"functionSelector":"61bc221a","mutability":"mutable","name":"counter","nameLocation":"2681:7:0","scope":537,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":204,"name":"uint256","nodeType":"ElementaryTypeName","src":"2666:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":368,"nodeType":"FunctionDefinition","src":"2778:949:0","nodes":[],"body":{"id":367,"nodeType":"Block","src":"2800:927:0","nodes":[],"statements":[{"assignments":[210],"declarations":[{"constant":false,"id":210,"mutability":"mutable","name":"x","nameLocation":"2815:1:0","nodeType":"VariableDeclaration","scope":367,"src":"2810:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":209,"name":"bool","nodeType":"ElementaryTypeName","src":"2810:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":216,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":213,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2828:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":214,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2844:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":211,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"2819:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":212,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2819:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":215,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2819:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2810:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":220,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2872:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":221,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":210,"src":"2895:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":217,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"2860:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":219,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":127,"src":"2860:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":222,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2860:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":223,"nodeType":"ExpressionStatement","src":"2860:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":227,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2920:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":230,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"2945:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}],"id":229,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2937:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":228,"name":"address","nodeType":"ElementaryTypeName","src":"2937:7:0","typeDescriptions":{}}},"id":231,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2937:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":224,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"2908:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":226,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"2908:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2908:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":233,"nodeType":"ExpressionStatement","src":"2908:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":237,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2973:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":242,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3011:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}],"id":241,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3003:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":240,"name":"address","nodeType":"ElementaryTypeName","src":"3003:7:0","typeDescriptions":{}}},"id":243,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3003:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":238,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"2991:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":239,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"2991:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":244,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2991:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":234,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"2961:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":236,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":144,"src":"2961:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":245,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2961:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":246,"nodeType":"ExpressionStatement","src":"2961:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":250,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3040:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":253,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3063:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":254,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3063:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":252,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3055:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":251,"name":"address","nodeType":"ElementaryTypeName","src":"3055:7:0","typeDescriptions":{}}},"id":255,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3055:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":247,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3028:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"3028:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":256,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3028:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":257,"nodeType":"ExpressionStatement","src":"3028:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":261,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3097:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":266,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3133:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":267,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3133:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":265,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3125:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":264,"name":"address","nodeType":"ElementaryTypeName","src":"3125:7:0","typeDescriptions":{}}},"id":268,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3125:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":262,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3113:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":263,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3113:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":269,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3113:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":258,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3085:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":260,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":144,"src":"3085:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":270,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3085:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":271,"nodeType":"ExpressionStatement","src":"3085:61:0"},{"assignments":[273],"declarations":[{"constant":false,"id":273,"mutability":"mutable","name":"json","nameLocation":"3171:4:0","nodeType":"VariableDeclaration","scope":367,"src":"3157:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":272,"name":"string","nodeType":"ElementaryTypeName","src":"3157:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":275,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":274,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3178:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"3157:55:0"},{"assignments":[280],"declarations":[{"constant":false,"id":280,"mutability":"mutable","name":"keys","nameLocation":"3238:4:0","nodeType":"VariableDeclaration","scope":367,"src":"3222:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":278,"name":"string","nodeType":"ElementaryTypeName","src":"3222:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":279,"nodeType":"ArrayTypeName","src":"3222:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":286,"initialValue":{"arguments":[{"id":283,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":273,"src":"3262:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3268:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":281,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3245:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":282,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3245:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":285,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3245:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3222:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":290,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3305:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":291,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":280,"src":"3313:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":293,"indexExpression":{"hexValue":"30","id":292,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3318:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3313:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":294,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":280,"src":"3322:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":296,"indexExpression":{"hexValue":"31","id":295,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3327:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3322:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":287,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3293:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":289,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":181,"src":"3293:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":297,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3293:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":298,"nodeType":"ExpressionStatement","src":"3293:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3352:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":299,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3341:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":301,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3341:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":303,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3341:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":304,"nodeType":"ExpressionStatement","src":"3341:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":312,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3408:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":311,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3400:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":310,"name":"uint160","nodeType":"ElementaryTypeName","src":"3400:7:0","typeDescriptions":{}}},"id":313,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3400:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":309,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3392:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":308,"name":"address","nodeType":"ElementaryTypeName","src":"3392:7:0","typeDescriptions":{}}},"id":314,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3392:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":305,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3378:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":307,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3378:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":315,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3378:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":316,"nodeType":"ExpressionStatement","src":"3378:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":320,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3436:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":317,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3425:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":319,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3425:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":321,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3425:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":322,"nodeType":"ExpressionStatement","src":"3425:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":326,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3473:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":329,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3508:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":330,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3508:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":328,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3500:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":327,"name":"address","nodeType":"ElementaryTypeName","src":"3500:7:0","typeDescriptions":{}}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3500:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":323,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3461:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"3461:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":332,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3461:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":333,"nodeType":"ExpressionStatement","src":"3461:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":337,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3542:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":340,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3580:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}],"id":339,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3572:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":338,"name":"address","nodeType":"ElementaryTypeName","src":"3572:7:0","typeDescriptions":{}}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3572:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":334,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3530:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":336,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"3530:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3530:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3530:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3607:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":344,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3596:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3596:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":348,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3596:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":349,"nodeType":"ExpressionStatement","src":"3596:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":350,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3632:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3632:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":353,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3632:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":354,"nodeType":"ExpressionStatement","src":"3632:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":358,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3667:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":355,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3656:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":357,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3656:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":359,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3656:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":360,"nodeType":"ExpressionStatement","src":"3656:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":364,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3712:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":361,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3700:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":363,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"3700:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":365,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3700:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":366,"nodeType":"ExpressionStatement","src":"3700:20:0"}]},"documentation":{"id":206,"nodeType":"StructuredDocumentation","src":"2695:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2787:3:0","parameters":{"id":207,"nodeType":"ParameterList","parameters":[],"src":"2790:2:0"},"returnParameters":{"id":208,"nodeType":"ParameterList","parameters":[],"src":"2800:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":452,"nodeType":"FunctionDefinition","src":"3794:520:0","nodes":[],"body":{"id":451,"nodeType":"Block","src":"3825:489:0","nodes":[],"statements":[{"expression":{"arguments":[{"hexValue":"74657374696e672073696e676c65","id":375,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3847:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""},"value":"testing single"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""}],"expression":{"id":372,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3835:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":374,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"3835:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":376,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3835:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":377,"nodeType":"ExpressionStatement","src":"3835:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":378,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3874:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":380,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"3874:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":381,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3874:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":382,"nodeType":"ExpressionStatement","src":"3874:14:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c31","id":386,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3909:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""},"value":"single_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""}],"expression":{"id":383,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3898:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":385,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":491,"src":"3898:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":387,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3898:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":388,"nodeType":"ExpressionStatement","src":"3898:26:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c32","id":392,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3945:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""},"value":"single_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""}],"expression":{"id":389,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3934:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":391,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":506,"src":"3934:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":393,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3934:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":394,"nodeType":"ExpressionStatement","src":"3934:26:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073746172742f73746f70","id":398,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3983:20:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""},"value":"testing start/stop"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""}],"expression":{"id":395,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3971:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":397,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"3971:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":399,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3971:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":400,"nodeType":"ExpressionStatement","src":"3971:33:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":401,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4014:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":403,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":41,"src":"4014:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":404,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4014:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":405,"nodeType":"ExpressionStatement","src":"4014:19:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c31","id":409,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4054:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""},"value":"startstop_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""}],"expression":{"id":406,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4043:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":408,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":491,"src":"4043:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":410,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4043:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":411,"nodeType":"ExpressionStatement","src":"4043:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c32","id":415,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4093:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""},"value":"startstop_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""}],"expression":{"id":412,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4082:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":414,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":506,"src":"4082:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":416,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4082:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":417,"nodeType":"ExpressionStatement","src":"4082:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":418,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4121:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":420,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":44,"src":"4121:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":421,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4121:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":422,"nodeType":"ExpressionStatement","src":"4121:18:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c33","id":426,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4160:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""},"value":"startstop_call3"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""}],"expression":{"id":423,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4149:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":425,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":491,"src":"4149:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":427,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4149:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":428,"nodeType":"ExpressionStatement","src":"4149:29:0"},{"expression":{"arguments":[{"hexValue":"74657374696e67206e6573746564","id":432,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4201:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""},"value":"testing nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""}],"expression":{"id":429,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4189:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":431,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4189:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":433,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4189:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":434,"nodeType":"ExpressionStatement","src":"4189:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":435,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4228:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":437,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":41,"src":"4228:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":438,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4228:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":439,"nodeType":"ExpressionStatement","src":"4228:19:0"},{"expression":{"arguments":[{"hexValue":"6e6573746564","id":443,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4270:8:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""},"value":"nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""}],"expression":{"id":440,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4257:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":442,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested1","nodeType":"MemberAccess","referencedDeclaration":521,"src":"4257:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":444,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4257:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":445,"nodeType":"ExpressionStatement","src":"4257:22:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":446,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4289:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":448,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":44,"src":"4289:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":449,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4289:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":450,"nodeType":"ExpressionStatement","src":"4289:18:0"}]},"documentation":{"id":369,"nodeType":"StructuredDocumentation","src":"3733:56:0","text":"@notice example function, to test vm.broadcast with."},"functionSelector":"bef03abc","implemented":true,"kind":"function","modifiers":[],"name":"runBroadcast","nameLocation":"3803:12:0","parameters":{"id":370,"nodeType":"ParameterList","parameters":[],"src":"3815:2:0"},"returnParameters":{"id":371,"nodeType":"ParameterList","parameters":[],"src":"3825:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":476,"nodeType":"FunctionDefinition","src":"4409:143:0","nodes":[],"body":{"id":475,"nodeType":"Block","src":"4458:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":461,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":455,"src":"4480:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":458,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4468:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":460,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4468:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":462,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4468:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":463,"nodeType":"ExpressionStatement","src":"4468:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":467,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4505:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":470,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"4533:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":471,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"4533:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":469,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4525:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":468,"name":"address","nodeType":"ElementaryTypeName","src":"4525:7:0","typeDescriptions":{}}},"id":472,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4525:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":464,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4493:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":466,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"4493:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":473,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4493:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":474,"nodeType":"ExpressionStatement","src":"4493:52:0"}]},"documentation":{"id":453,"nodeType":"StructuredDocumentation","src":"4320:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"4418:5:0","parameters":{"id":456,"nodeType":"ParameterList","parameters":[{"constant":false,"id":455,"mutability":"mutable","name":"_v","nameLocation":"4440:2:0","nodeType":"VariableDeclaration","scope":476,"src":"4424:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":454,"name":"string","nodeType":"ElementaryTypeName","src":"4424:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4423:20:0"},"returnParameters":{"id":457,"nodeType":"ParameterList","parameters":[],"src":"4458:0:0"},"scope":537,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":491,"nodeType":"FunctionDefinition","src":"4558:95:0","nodes":[],"body":{"id":490,"nodeType":"Block","src":"4602:51:0","nodes":[],"statements":[{"expression":{"id":482,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4612:9:0","subExpression":{"id":481,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4612:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":483,"nodeType":"ExpressionStatement","src":"4612:9:0"},{"expression":{"arguments":[{"id":487,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":478,"src":"4643:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":484,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4631:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":486,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4631:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":488,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4631:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":489,"nodeType":"ExpressionStatement","src":"4631:15:0"}]},"functionSelector":"7e79255d","implemented":true,"kind":"function","modifiers":[],"name":"call1","nameLocation":"4567:5:0","parameters":{"id":479,"nodeType":"ParameterList","parameters":[{"constant":false,"id":478,"mutability":"mutable","name":"_v","nameLocation":"4589:2:0","nodeType":"VariableDeclaration","scope":491,"src":"4573:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":477,"name":"string","nodeType":"ElementaryTypeName","src":"4573:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4572:20:0"},"returnParameters":{"id":480,"nodeType":"ParameterList","parameters":[],"src":"4602:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":506,"nodeType":"FunctionDefinition","src":"4659:95:0","nodes":[],"body":{"id":505,"nodeType":"Block","src":"4703:51:0","nodes":[],"statements":[{"expression":{"id":497,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4713:9:0","subExpression":{"id":496,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4713:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":498,"nodeType":"ExpressionStatement","src":"4713:9:0"},{"expression":{"arguments":[{"id":502,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":493,"src":"4744:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":499,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4732:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":501,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4732:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":503,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4732:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":504,"nodeType":"ExpressionStatement","src":"4732:15:0"}]},"functionSelector":"8d3ef7ca","implemented":true,"kind":"function","modifiers":[],"name":"call2","nameLocation":"4668:5:0","parameters":{"id":494,"nodeType":"ParameterList","parameters":[{"constant":false,"id":493,"mutability":"mutable","name":"_v","nameLocation":"4690:2:0","nodeType":"VariableDeclaration","scope":506,"src":"4674:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":492,"name":"string","nodeType":"ElementaryTypeName","src":"4674:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4673:20:0"},"returnParameters":{"id":495,"nodeType":"ParameterList","parameters":[],"src":"4703:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":521,"nodeType":"FunctionDefinition","src":"4760:98:0","nodes":[],"body":{"id":520,"nodeType":"Block","src":"4806:52:0","nodes":[],"statements":[{"expression":{"id":512,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4816:9:0","subExpression":{"id":511,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4816:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":513,"nodeType":"ExpressionStatement","src":"4816:9:0"},{"expression":{"arguments":[{"id":517,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":508,"src":"4848:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":514,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4835:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":516,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested2","nodeType":"MemberAccess","referencedDeclaration":536,"src":"4835:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":518,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4835:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":519,"nodeType":"ExpressionStatement","src":"4835:16:0"}]},"functionSelector":"a76ccdfa","implemented":true,"kind":"function","modifiers":[],"name":"nested1","nameLocation":"4769:7:0","parameters":{"id":509,"nodeType":"ParameterList","parameters":[{"constant":false,"id":508,"mutability":"mutable","name":"_v","nameLocation":"4793:2:0","nodeType":"VariableDeclaration","scope":521,"src":"4777:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":507,"name":"string","nodeType":"ElementaryTypeName","src":"4777:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4776:20:0"},"returnParameters":{"id":510,"nodeType":"ParameterList","parameters":[],"src":"4806:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":536,"nodeType":"FunctionDefinition","src":"4864:97:0","nodes":[],"body":{"id":535,"nodeType":"Block","src":"4910:51:0","nodes":[],"statements":[{"expression":{"id":527,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4920:9:0","subExpression":{"id":526,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4920:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":528,"nodeType":"ExpressionStatement","src":"4920:9:0"},{"expression":{"arguments":[{"id":532,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":523,"src":"4951:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":529,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4939:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":531,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4939:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":533,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4939:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":534,"nodeType":"ExpressionStatement","src":"4939:15:0"}]},"functionSelector":"dbf1282f","implemented":true,"kind":"function","modifiers":[],"name":"nested2","nameLocation":"4873:7:0","parameters":{"id":524,"nodeType":"ParameterList","parameters":[{"constant":false,"id":523,"mutability":"mutable","name":"_v","nameLocation":"4897:2:0","nodeType":"VariableDeclaration","scope":536,"src":"4881:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":522,"name":"string","nodeType":"ElementaryTypeName","src":"4881:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4880:20:0"},"returnParameters":{"id":525,"nodeType":"ParameterList","parameters":[],"src":"4910:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[],"contractKind":"contract","documentation":{"id":183,"nodeType":"StructuredDocumentation","src":"2306:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[537],"name":"ScriptExample","nameLocation":"2441:13:0","scope":538,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file +{"abi":[{"type":"function","name":"call1","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"call2","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"callPure","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"pure"},{"type":"function","name":"counter","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"hello","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"view"},{"type":"function","name":"nested1","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"nested2","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"run","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"runBroadcast","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"bytecode":{"object":"0x608060405234801561001057600080fd5b50611e66806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063a76ccdfa11610076578063bef03abc1161005b578063bef03abc14610111578063c040622614610119578063dbf1282f146100c357600080fd5b8063a76ccdfa146100eb578063a777d0dc146100fe57600080fd5b806361bc221a146100a85780637e79255d146100c35780637f8b915c146100d85780638d3ef7ca146100c3575b600080fd5b6100b160005481565b60405190815260200160405180910390f35b6100d66100d136600461189c565b610121565b005b6100d66100e636600461189c565b610178565b6100d66100f936600461189c565b6101b7565b6100d661010c36600461189c565b61023f565b6100d66102bd565b6100d6610d44565b6000805490806101308361190e565b919050555061017482828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061159792505050565b5050565b61017482828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061159792505050565b6000805490806101c68361190e565b90915550506040517fdbf1282f000000000000000000000000000000000000000000000000000000008152309063dbf1282f90610209908590859060040161196d565b600060405180830381600087803b15801561022357600080fd5b505af1158015610237573d6000803e3d6000fd5b505050505050565b61027e82828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061159792505050565b6101746040518060400160405280601081526020017f68656c6c6f206d73672e73656e6465720000000000000000000000000000000081525033611629565b6102fb6040518060400160405280600e81526020017f74657374696e672073696e676c65000000000000000000000000000000000000815250611597565b7f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff1663afc980406040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561036657600080fd5b505af115801561037a573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f73696e676c655f63616c6c3100000000000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b1580156103fd57600080fd5b505af1158015610411573d6000803e3d6000fd5b50506040517f8d3ef7ca00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f73696e676c655f63616c6c3200000000000000000000000000000000000000006044820152309250638d3ef7ca9150606401600060405180830381600087803b15801561049457600080fd5b505af11580156104a8573d6000803e3d6000fd5b505050506104ea6040518060400160405280601281526020017f74657374696e672073746172742f73746f700000000000000000000000000000815250611597565b6040517f7fec2a8d00000000000000000000000000000000000000000000000000000000815262c0ffee6004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d90637fec2a8d90602401600060405180830381600087803b15801561055257600080fd5b505af1158015610566573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3100000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b1580156105e957600080fd5b505af11580156105fd573d6000803e3d6000fd5b50506040517f8d3ef7ca00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3200000000000000000000000000000000006044820152309250638d3ef7ca9150606401600060405180830381600087803b15801561068057600080fd5b505af1158015610694573d6000803e3d6000fd5b50506040517f7f8b915c00000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f737461727473746f705f707572650000000000000000000000000000000000006044820152309250637f8b915c915060640160006040518083038186803b15801561071557600080fd5b505afa158015610729573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166376eadd366040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561079857600080fd5b505af11580156107ac573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3300000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b15801561082f57600080fd5b505af1158015610843573d6000803e3d6000fd5b505050506108856040518060400160405280600e81526020017f74657374696e67206e6573746564000000000000000000000000000000000000815250611597565b6040517f7fec2a8d0000000000000000000000000000000000000000000000000000000081526112346004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d90637fec2a8d90602401600060405180830381600087803b1580156108ec57600080fd5b505af1158015610900573d6000803e3d6000fd5b50506040517fa76ccdfa00000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f6e65737465640000000000000000000000000000000000000000000000000000604482015230925063a76ccdfa9150606401600060405180830381600087803b15801561098357600080fd5b505af1158015610997573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166376eadd366040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610a0657600080fd5b505af1158015610a1a573d6000803e3d6000fd5b50505050610a5c6040518060400160405280601381526020017f636f6e7472616374206465706c6f796d656e7400000000000000000000000000815250611597565b6040517fe6962cdb000000000000000000000000000000000000000000000000000000008152621234566004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d9063e6962cdb90602401600060405180830381600087803b158015610ac457600080fd5b505af1158015610ad8573d6000803e3d6000fd5b5050505060006104d2604051610aed90611890565b908152602001604051809103906000f080158015610b0f573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff1663c29855786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8191906119ba565b6104d214610b8e57600080fd5b610bcc6040518060400160405280600881526020017f6372656174652032000000000000000000000000000000000000000000000000815250611597565b6040517fe6962cdb00000000000000000000000000000000000000000000000000000000815261cafe6004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d9063e6962cdb90602401600060405180830381600087803b158015610c3357600080fd5b505af1158015610c47573d6000803e3d6000fd5b505050506000602a60001b6104d2604051610c6190611890565b9081526020018190604051809103906000f5905080158015610c87573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff1663c29855786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf991906119ba565b6104d214610d0657600080fd5b6101746040518060400160405280600581526020017f646f6e6521000000000000000000000000000000000000000000000000000000815250611597565b604080517f4777f3cf0000000000000000000000000000000000000000000000000000000081526004810191909152600c60448201527f4558414d504c455f424f4f4c0000000000000000000000000000000000000000606482015260006024820181905290737109709ecfa91a80626ff3989d68f67f5b1dd12d90634777f3cf90608401602060405180830381865afa158015610de6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0a91906119d3565b9050610e4b6040518060400160405280601381526020017f626f6f6c2076616c75652066726f6d20656e7600000000000000000000000000815250826116ba565b610e8a6040518060400160405280600d81526020017f636f6e747261637420616464720000000000000000000000000000000000000081525030611629565b604080518082018252600e81527f636f6e7472616374206e6f6e6365000000000000000000000000000000000000602082015290517f2d0335ab000000000000000000000000000000000000000000000000000000008152306004820152610f5d9190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab906024015b602060405180830381865afa158015610f2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4e91906119fc565b67ffffffffffffffff1661174b565b610f9c6040518060400160405280600b81526020017f73656e646572206164647200000000000000000000000000000000000000000081525033611629565b604080518082018252600c81527f73656e646572206e6f6e63650000000000000000000000000000000000000000602082015290517f2d0335ab0000000000000000000000000000000000000000000000000000000081523360048201526110239190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab90602401610f0d565b60408051808201825260208082527f7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d9082015290517f213e4198000000000000000000000000000000000000000000000000000000008152600090737109709ecfa91a80626ff3989d68f67f5b1dd12d9063213e4198906110a8908590600401611aa0565b600060405180830381865afa1580156110c5573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261110b9190810190611b70565b90506111816040518060400160405280600481526020017f6b657973000000000000000000000000000000000000000000000000000000008152508260008151811061115957611159611ca4565b60200260200101518360018151811061117457611174611ca4565b60200260200101516117dc565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f66726f6d206f726967696e616c000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b1580156111fe57600080fd5b505afa158015611212573d6000803e3d6000fd5b50506040517f06447d5600000000000000000000000000000000000000000000000000000000815260426004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d92506306447d569150602401600060405180830381600087803b15801561127c57600080fd5b505af1158015611290573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b20310000000000000000000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b15801561131157600080fd5b505afa158015611325573d6000803e3d6000fd5b505050506113686040518060400160405280601781526020017f706172656e742073636f7065206d73672e73656e64657200000000000000000081525033611629565b6113a76040518060400160405280601a81526020017f706172656e742073636f706520636f6e74726163742e6164647200000000000081525030611629565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b203200000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b15801561142457600080fd5b505afa158015611438573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166390c5013b6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156114a757600080fd5b505af11580156114bb573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f66726f6d206f726967696e616c20616761696e00000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b15801561153c57600080fd5b505afa158015611550573d6000803e3d6000fd5b505050506115926040518060400160405280600581526020017f646f6e6521000000000000000000000000000000000000000000000000000000815250611597565b505050565b611626816040516024016115ab9190611cd3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f41304fac0000000000000000000000000000000000000000000000000000000017905261186b565b50565b610174828260405160240161163f929190611ce6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f319af3330000000000000000000000000000000000000000000000000000000017905261186b565b61017482826040516024016116d0929190611d1e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fc3b556350000000000000000000000000000000000000000000000000000000017905261186b565b6101748282604051602401611761929190611d42565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb60e72cc0000000000000000000000000000000000000000000000000000000017905261186b565b6115928383836040516024016117f493929190611d64565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f2ced7cef000000000000000000000000000000000000000000000000000000001790525b6116268180516a636f6e736f6c652e6c6f67602083016000808483855afa5050505050565b60b280611da883390190565b600080602083850312156118af57600080fd5b823567ffffffffffffffff808211156118c757600080fd5b818501915085601f8301126118db57600080fd5b8135818111156118ea57600080fd5b8660208285010111156118fc57600080fd5b60209290920196919550909350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611966577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000602082840312156119cc57600080fd5b5051919050565b6000602082840312156119e557600080fd5b815180151581146119f557600080fd5b9392505050565b600060208284031215611a0e57600080fd5b815167ffffffffffffffff811681146119f557600080fd5b60005b83811015611a41578181015183820152602001611a29565b83811115611a50576000848401525b50505050565b60008151808452611a6e816020860160208601611a26565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b604081526000611ab36040830184611a56565b8281036020840152600c81527f2e726f6f745f6b65795b305d000000000000000000000000000000000000000060208201526040810191505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611b6857611b68611af2565b604052919050565b60006020808385031215611b8357600080fd5b825167ffffffffffffffff80821115611b9b57600080fd5b8185019150601f8681840112611bb057600080fd5b825182811115611bc257611bc2611af2565b8060051b611bd1868201611b21565b918252848101860191868101908a841115611beb57600080fd5b87870192505b83831015611c9657825186811115611c095760008081fd5b8701603f81018c13611c1b5760008081fd5b88810151604088821115611c3157611c31611af2565b611c608b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08a85011601611b21565b8281528e82848601011115611c755760008081fd5b611c84838d8301848701611a26565b85525050509187019190870190611bf1565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020815260006119f56020830184611a56565b604081526000611cf96040830185611a56565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b604081526000611d316040830185611a56565b905082151560208301529392505050565b604081526000611d556040830185611a56565b90508260208301529392505050565b606081526000611d776060830186611a56565b8281036020840152611d898186611a56565b90508281036040840152611d9d8185611a56565b969550505050505056fe608060405234801561001057600080fd5b506040516100b23803806100b283398101604081905261002f91610037565b600055610050565b60006020828403121561004957600080fd5b5051919050565b60548061005e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b603560005481565b60405190815260200160405180910390f3fea164736f6c634300080f000aa164736f6c634300080f000a","sourceMap":"2541:3089:0:-:0;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405234801561001057600080fd5b50600436106100a35760003560e01c8063a76ccdfa11610076578063bef03abc1161005b578063bef03abc14610111578063c040622614610119578063dbf1282f146100c357600080fd5b8063a76ccdfa146100eb578063a777d0dc146100fe57600080fd5b806361bc221a146100a85780637e79255d146100c35780637f8b915c146100d85780638d3ef7ca146100c3575b600080fd5b6100b160005481565b60405190815260200160405180910390f35b6100d66100d136600461189c565b610121565b005b6100d66100e636600461189c565b610178565b6100d66100f936600461189c565b6101b7565b6100d661010c36600461189c565b61023f565b6100d66102bd565b6100d6610d44565b6000805490806101308361190e565b919050555061017482828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061159792505050565b5050565b61017482828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061159792505050565b6000805490806101c68361190e565b90915550506040517fdbf1282f000000000000000000000000000000000000000000000000000000008152309063dbf1282f90610209908590859060040161196d565b600060405180830381600087803b15801561022357600080fd5b505af1158015610237573d6000803e3d6000fd5b505050505050565b61027e82828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061159792505050565b6101746040518060400160405280601081526020017f68656c6c6f206d73672e73656e6465720000000000000000000000000000000081525033611629565b6102fb6040518060400160405280600e81526020017f74657374696e672073696e676c65000000000000000000000000000000000000815250611597565b7f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff1663afc980406040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561036657600080fd5b505af115801561037a573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f73696e676c655f63616c6c3100000000000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b1580156103fd57600080fd5b505af1158015610411573d6000803e3d6000fd5b50506040517f8d3ef7ca00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f73696e676c655f63616c6c3200000000000000000000000000000000000000006044820152309250638d3ef7ca9150606401600060405180830381600087803b15801561049457600080fd5b505af11580156104a8573d6000803e3d6000fd5b505050506104ea6040518060400160405280601281526020017f74657374696e672073746172742f73746f700000000000000000000000000000815250611597565b6040517f7fec2a8d00000000000000000000000000000000000000000000000000000000815262c0ffee6004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d90637fec2a8d90602401600060405180830381600087803b15801561055257600080fd5b505af1158015610566573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3100000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b1580156105e957600080fd5b505af11580156105fd573d6000803e3d6000fd5b50506040517f8d3ef7ca00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3200000000000000000000000000000000006044820152309250638d3ef7ca9150606401600060405180830381600087803b15801561068057600080fd5b505af1158015610694573d6000803e3d6000fd5b50506040517f7f8b915c00000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f737461727473746f705f707572650000000000000000000000000000000000006044820152309250637f8b915c915060640160006040518083038186803b15801561071557600080fd5b505afa158015610729573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166376eadd366040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561079857600080fd5b505af11580156107ac573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3300000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b15801561082f57600080fd5b505af1158015610843573d6000803e3d6000fd5b505050506108856040518060400160405280600e81526020017f74657374696e67206e6573746564000000000000000000000000000000000000815250611597565b6040517f7fec2a8d0000000000000000000000000000000000000000000000000000000081526112346004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d90637fec2a8d90602401600060405180830381600087803b1580156108ec57600080fd5b505af1158015610900573d6000803e3d6000fd5b50506040517fa76ccdfa00000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f6e65737465640000000000000000000000000000000000000000000000000000604482015230925063a76ccdfa9150606401600060405180830381600087803b15801561098357600080fd5b505af1158015610997573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166376eadd366040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610a0657600080fd5b505af1158015610a1a573d6000803e3d6000fd5b50505050610a5c6040518060400160405280601381526020017f636f6e7472616374206465706c6f796d656e7400000000000000000000000000815250611597565b6040517fe6962cdb000000000000000000000000000000000000000000000000000000008152621234566004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d9063e6962cdb90602401600060405180830381600087803b158015610ac457600080fd5b505af1158015610ad8573d6000803e3d6000fd5b5050505060006104d2604051610aed90611890565b908152602001604051809103906000f080158015610b0f573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff1663c29855786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8191906119ba565b6104d214610b8e57600080fd5b610bcc6040518060400160405280600881526020017f6372656174652032000000000000000000000000000000000000000000000000815250611597565b6040517fe6962cdb00000000000000000000000000000000000000000000000000000000815261cafe6004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d9063e6962cdb90602401600060405180830381600087803b158015610c3357600080fd5b505af1158015610c47573d6000803e3d6000fd5b505050506000602a60001b6104d2604051610c6190611890565b9081526020018190604051809103906000f5905080158015610c87573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff1663c29855786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf991906119ba565b6104d214610d0657600080fd5b6101746040518060400160405280600581526020017f646f6e6521000000000000000000000000000000000000000000000000000000815250611597565b604080517f4777f3cf0000000000000000000000000000000000000000000000000000000081526004810191909152600c60448201527f4558414d504c455f424f4f4c0000000000000000000000000000000000000000606482015260006024820181905290737109709ecfa91a80626ff3989d68f67f5b1dd12d90634777f3cf90608401602060405180830381865afa158015610de6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0a91906119d3565b9050610e4b6040518060400160405280601381526020017f626f6f6c2076616c75652066726f6d20656e7600000000000000000000000000815250826116ba565b610e8a6040518060400160405280600d81526020017f636f6e747261637420616464720000000000000000000000000000000000000081525030611629565b604080518082018252600e81527f636f6e7472616374206e6f6e6365000000000000000000000000000000000000602082015290517f2d0335ab000000000000000000000000000000000000000000000000000000008152306004820152610f5d9190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab906024015b602060405180830381865afa158015610f2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4e91906119fc565b67ffffffffffffffff1661174b565b610f9c6040518060400160405280600b81526020017f73656e646572206164647200000000000000000000000000000000000000000081525033611629565b604080518082018252600c81527f73656e646572206e6f6e63650000000000000000000000000000000000000000602082015290517f2d0335ab0000000000000000000000000000000000000000000000000000000081523360048201526110239190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab90602401610f0d565b60408051808201825260208082527f7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d9082015290517f213e4198000000000000000000000000000000000000000000000000000000008152600090737109709ecfa91a80626ff3989d68f67f5b1dd12d9063213e4198906110a8908590600401611aa0565b600060405180830381865afa1580156110c5573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261110b9190810190611b70565b90506111816040518060400160405280600481526020017f6b657973000000000000000000000000000000000000000000000000000000008152508260008151811061115957611159611ca4565b60200260200101518360018151811061117457611174611ca4565b60200260200101516117dc565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f66726f6d206f726967696e616c000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b1580156111fe57600080fd5b505afa158015611212573d6000803e3d6000fd5b50506040517f06447d5600000000000000000000000000000000000000000000000000000000815260426004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d92506306447d569150602401600060405180830381600087803b15801561127c57600080fd5b505af1158015611290573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b20310000000000000000000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b15801561131157600080fd5b505afa158015611325573d6000803e3d6000fd5b505050506113686040518060400160405280601781526020017f706172656e742073636f7065206d73672e73656e64657200000000000000000081525033611629565b6113a76040518060400160405280601a81526020017f706172656e742073636f706520636f6e74726163742e6164647200000000000081525030611629565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b203200000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b15801561142457600080fd5b505afa158015611438573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166390c5013b6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156114a757600080fd5b505af11580156114bb573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f66726f6d206f726967696e616c20616761696e00000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b15801561153c57600080fd5b505afa158015611550573d6000803e3d6000fd5b505050506115926040518060400160405280600581526020017f646f6e6521000000000000000000000000000000000000000000000000000000815250611597565b505050565b611626816040516024016115ab9190611cd3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f41304fac0000000000000000000000000000000000000000000000000000000017905261186b565b50565b610174828260405160240161163f929190611ce6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f319af3330000000000000000000000000000000000000000000000000000000017905261186b565b61017482826040516024016116d0929190611d1e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fc3b556350000000000000000000000000000000000000000000000000000000017905261186b565b6101748282604051602401611761929190611d42565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb60e72cc0000000000000000000000000000000000000000000000000000000017905261186b565b6115928383836040516024016117f493929190611d64565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f2ced7cef000000000000000000000000000000000000000000000000000000001790525b6116268180516a636f6e736f6c652e6c6f67602083016000808483855afa5050505050565b60b280611da883390190565b600080602083850312156118af57600080fd5b823567ffffffffffffffff808211156118c757600080fd5b818501915085601f8301126118db57600080fd5b8135818111156118ea57600080fd5b8660208285010111156118fc57600080fd5b60209290920196919550909350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611966577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000602082840312156119cc57600080fd5b5051919050565b6000602082840312156119e557600080fd5b815180151581146119f557600080fd5b9392505050565b600060208284031215611a0e57600080fd5b815167ffffffffffffffff811681146119f557600080fd5b60005b83811015611a41578181015183820152602001611a29565b83811115611a50576000848401525b50505050565b60008151808452611a6e816020860160208601611a26565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b604081526000611ab36040830184611a56565b8281036020840152600c81527f2e726f6f745f6b65795b305d000000000000000000000000000000000000000060208201526040810191505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611b6857611b68611af2565b604052919050565b60006020808385031215611b8357600080fd5b825167ffffffffffffffff80821115611b9b57600080fd5b8185019150601f8681840112611bb057600080fd5b825182811115611bc257611bc2611af2565b8060051b611bd1868201611b21565b918252848101860191868101908a841115611beb57600080fd5b87870192505b83831015611c9657825186811115611c095760008081fd5b8701603f81018c13611c1b5760008081fd5b88810151604088821115611c3157611c31611af2565b611c608b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08a85011601611b21565b8281528e82848601011115611c755760008081fd5b611c84838d8301848701611a26565b85525050509187019190870190611bf1565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020815260006119f56020830184611a56565b604081526000611cf96040830185611a56565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b604081526000611d316040830185611a56565b905082151560208301529392505050565b604081526000611d556040830185611a56565b90508260208301529392505050565b606081526000611d776060830186611a56565b8281036020840152611d898186611a56565b90508281036040840152611d9d8185611a56565b969550505050505056fe608060405234801561001057600080fd5b506040516100b23803806100b283398101604081905261002f91610037565b600055610050565b60006020828403121561004957600080fd5b5051919050565b60548061005e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b603560005481565b60405190815260200160405180910390f3fea164736f6c634300080f000aa164736f6c634300080f000a","sourceMap":"2541:3089:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2775:22;;;;;;;;;160:25:1;;;148:2;133:18;2775:22:0;;;;;;;5135:95;;;;;;:::i;:::-;;:::i;:::-;;5544:84;;;;;;:::i;:::-;;:::i;5337:98::-;;;;;;:::i;:::-;;:::i;4986:143::-;;;;;;:::i;:::-;;:::i;3903:988::-;;;:::i;2887:949::-;;;:::i;5135:95::-;5189:7;:9;;;:7;:9;;;:::i;:::-;;;;;;5208:15;5220:2;;5208:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5208:11:0;;-1:-1:-1;;;5208:15:0:i;:::-;5135:95;;:::o;5544:84::-;5606:15;5618:2;;5606:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5606:11:0;;-1:-1:-1;;;5606:15:0:i;5337:98::-;5393:7;:9;;;:7;:9;;;:::i;:::-;;;;-1:-1:-1;;5412:16:0;;;;;:4;;:12;;:16;;5425:2;;;;5412:16;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5337:98;;:::o;4986:143::-;5045:15;5057:2;;5045:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5045:11:0;;-1:-1:-1;;;5045:15:0:i;:::-;5070:52;;;;;;;;;;;;;;;;;;5110:10;5070:11;:52::i;3903:988::-;3944:29;;;;;;;;;;;;;;;;;;:11;:29::i;:::-;2634:28;2626:37;;3983:12;;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4007:26:0;;;;;1803:2:1;4007:26:0;;;1785:21:1;1842:2;1822:18;;;1815:30;1881:14;1861:18;;;1854:42;4007:4:0;;-1:-1:-1;4007:10:0;;-1:-1:-1;1913:18:1;;4007:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4043:26:0;;;;;2144:2:1;4043:26:0;;;2126:21:1;2183:2;2163:18;;;2156:30;2222:14;2202:18;;;2195:42;4043:4:0;;-1:-1:-1;4043:10:0;;-1:-1:-1;2254:18:1;;4043:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4080:33;;;;;;;;;;;;;;;;;;:11;:33::i;:::-;4123:45;;;;;4157:8;4123:45;;;2429:74:1;4123:17:0;;;;2402:18:1;;4123:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4178:29:0;;;;;2716:2:1;4178:29:0;;;2698:21:1;2755:2;2735:18;;;2728:30;2794:17;2774:18;;;2767:45;4178:4:0;;-1:-1:-1;4178:10:0;;-1:-1:-1;2829:18:1;;4178:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4217:29:0;;;;;3060:2:1;4217:29:0;;;3042:21:1;3099:2;3079:18;;;3072:30;3138:17;3118:18;;;3111:45;4217:4:0;;-1:-1:-1;4217:10:0;;-1:-1:-1;3173:18:1;;4217:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4256:31:0;;;;;3404:2:1;4256:31:0;;;3386:21:1;3443:2;3423:18;;;3416:30;3482:16;3462:18;;;3455:44;4256:4:0;;-1:-1:-1;4256:13:0;;-1:-1:-1;3516:18:1;;4256:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2634:28;2626:37;;4297:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4325:29:0;;;;;3747:2:1;4325:29:0;;;3729:21:1;3786:2;3766:18;;;3759:30;3825:17;3805:18;;;3798:45;4325:4:0;;-1:-1:-1;4325:10:0;;-1:-1:-1;3860:18:1;;4325:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4365;;;;;;;;;;;;;;;;;;:11;:29::i;:::-;4404:43;;;;;4438:6;4404:43;;;2429:74:1;4404:17:0;;;;2402:18:1;;4404:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4457:22:0;;;;;4091:2:1;4457:22:0;;;4073:21:1;4130:1;4110:18;;;4103:29;4168:8;4148:18;;;4141:36;4457:4:0;;-1:-1:-1;4457:12:0;;-1:-1:-1;4194:18:1;;4457:22:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2634:28;2626:37;;4489:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4518:34;;;;;;;;;;;;;;;;;;:11;:34::i;:::-;4562:40;;;;;4591:8;4562:40;;;2429:74:1;4562:12:0;;;;2402:18:1;;4562:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4612:8;4634:4;4623:16;;;;;:::i;:::-;160:25:1;;;148:2;133:18;4623:16:0;;;;;;;;;;;;;;;;;;;;;;;4612:27;;4657:1;:5;;;:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4668:4;4657:15;4649:24;;;;;;4684:23;;;;;;;;;;;;;;;;;;:11;:23::i;:::-;4717:38;;;;;4746:6;4717:38;;;2429:74:1;4717:12:0;;;;2402:18:1;;4717:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4765:8;4809:2;4793:20;;4815:4;4776:44;;;;;:::i;:::-;160:25:1;;;148:2;133:18;4776:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;4765:55;;4838:1;:5;;;:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4849:4;4838:15;4830:24;;;;;;4864:20;;;;;;;;;;;;;;;;;;:11;:20::i;2887:949::-;2928:31;;;;;;;;;4811:21:1;;;;4868:2;4848:18;;;4841:30;4907:14;4887:18;;;4880:42;2919:6:0;4974:20:1;;;4967:52;;;2919:6:0;2928:8;;;;4939:19:1;;2928:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2919:40;;2969:37;;;;;;;;;;;;;;;;;;3004:1;2969:11;:37::i;:::-;3017:43;;;;;;;;;;;;;;;;;;3054:4;3017:11;:43::i;:::-;3070:57;;;;;;;;;;;;;;;;3100:26;;;;;3120:4;3100:26;;;2429:74:1;3070:57:0;;;3100:11;;;;2402:18:1;;3100:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3070:57;;:11;:57::i;:::-;3137:47;;;;;;;;;;;;;;;;;;3172:10;3137:11;:47::i;:::-;3194:61;;;;;;;;;;;;;;;;3222:32;;;;;3242:10;3222:32;;;2429:74:1;3194:61:0;;;3222:11;;;;2402:18:1;;3222:32:0;2283:226:1;3194:61:0;3266:55;;;;;;;;;;;;;;;;;3354:38;;;;;3266:18;;3354:16;;;;:38;;3266:55;;3354:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3331:61;;3402:37;;;;;;;;;;;;;;;;;;3422:4;3427:1;3422:7;;;;;;;;:::i;:::-;;;;;;;3431:4;3436:1;3431:7;;;;;;;;:::i;:::-;;;;;;;3402:11;:37::i;:::-;3450:27;;;;;9413:2:1;3450:27:0;;;9395:21:1;9452:2;9432:18;;;9425:30;9491:15;9471:18;;;9464:43;3450:4:0;;:10;;9524:18:1;;3450:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3487:37:0;;;;;3517:4;3487:37;;;2429:74:1;3487:13:0;;-1:-1:-1;3487:13:0;;-1:-1:-1;2402:18:1;;3487:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3534:26:0;;;;;9755:2:1;3534:26:0;;;9737:21:1;9794:2;9774:18;;;9767:30;9833:14;9813:18;;;9806:42;3534:4:0;;-1:-1:-1;3534:10:0;;-1:-1:-1;9865:18:1;;3534:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3570:59;;;;;;;;;;;;;;;;;;3617:10;3570:11;:59::i;:::-;3639:56;;;;;;;;;;;;;;;;;;3689:4;3639:11;:56::i;:::-;3705:26;;;;;10096:2:1;3705:26:0;;;10078:21:1;10135:2;10115:18;;;10108:30;10174:14;10154:18;;;10147:42;3705:4:0;;:10;;10206:18:1;;3705:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2634:28;2626:37;;3741:12;;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3765:33:0;;;;;10437:2:1;3765:33:0;;;10419:21:1;10476:2;10456:18;;;10449:30;10515:21;10495:18;;;10488:49;3765:4:0;;-1:-1:-1;3765:10:0;;-1:-1:-1;10554:18:1;;3765:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3809:20;;;;;;;;;;;;;;;;;;:11;:20::i;:::-;2909:927;;;2887:949::o;1658:121::-;1713:59;1768:2;1729:42;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1713:15;:59::i;:::-;1658:121;:::o;2081:145::-;2148:71;2211:2;2215;2164:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;2148:15;:71::i;1785:139::-;1849:68;1909:2;1913;1865:51;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1849:15;:68::i;1930:145::-;1997:71;2060:2;2064;2013:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1997:15;:71::i;2232:179::-;2323:81;2392:2;2396;2400;2339:64;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1133:133;1204:55;1251:7;1370:14;;856:42;1543:2;1530:16;;1346:21;;1370:14;1530:16;856:42;1579:5;1568:68;1559:77;;1496:150;;1272:380;:::o;-1:-1:-1:-;;;;;;;;:::o;196:592:1:-;267:6;275;328:2;316:9;307:7;303:23;299:32;296:52;;;344:1;341;334:12;296:52;384:9;371:23;413:18;454:2;446:6;443:14;440:34;;;470:1;467;460:12;440:34;508:6;497:9;493:22;483:32;;553:7;546:4;542:2;538:13;534:27;524:55;;575:1;572;565:12;524:55;615:2;602:16;641:2;633:6;630:14;627:34;;;657:1;654;647:12;627:34;702:7;697:2;688:6;684:2;680:15;676:24;673:37;670:57;;;723:1;720;713:12;670:57;754:2;746:11;;;;;776:6;;-1:-1:-1;196:592:1;;-1:-1:-1;;;;196:592:1:o;793:349::-;832:3;863:66;856:5;853:77;850:257;;963:77;960:1;953:88;1064:4;1061:1;1054:15;1092:4;1089:1;1082:15;850:257;-1:-1:-1;1134:1:1;1123:13;;793:349::o;1147:449::-;1306:2;1295:9;1288:21;1345:6;1340:2;1329:9;1325:18;1318:34;1402:6;1394;1389:2;1378:9;1374:18;1361:48;1458:1;1429:22;;;1453:2;1425:31;;;1418:42;;;;1512:2;1500:15;;;1517:66;1496:88;1481:104;1477:113;;1147:449;-1:-1:-1;1147:449:1:o;4416:184::-;4486:6;4539:2;4527:9;4518:7;4514:23;4510:32;4507:52;;;4555:1;4552;4545:12;4507:52;-1:-1:-1;4578:16:1;;4416:184;-1:-1:-1;4416:184:1:o;5030:277::-;5097:6;5150:2;5138:9;5129:7;5125:23;5121:32;5118:52;;;5166:1;5163;5156:12;5118:52;5198:9;5192:16;5251:5;5244:13;5237:21;5230:5;5227:32;5217:60;;5273:1;5270;5263:12;5217:60;5296:5;5030:277;-1:-1:-1;;;5030:277:1:o;5312:288::-;5381:6;5434:2;5422:9;5413:7;5409:23;5405:32;5402:52;;;5450:1;5447;5440:12;5402:52;5482:9;5476:16;5532:18;5525:5;5521:30;5514:5;5511:41;5501:69;;5566:1;5563;5556:12;5605:258;5677:1;5687:113;5701:6;5698:1;5695:13;5687:113;;;5777:11;;;5771:18;5758:11;;;5751:39;5723:2;5716:10;5687:113;;;5818:6;5815:1;5812:13;5809:48;;;5853:1;5844:6;5839:3;5835:16;5828:27;5809:48;;5605:258;;;:::o;5868:317::-;5910:3;5948:5;5942:12;5975:6;5970:3;5963:19;5991:63;6047:6;6040:4;6035:3;6031:14;6024:4;6017:5;6013:16;5991:63;:::i;:::-;6099:2;6087:15;6104:66;6083:88;6074:98;;;;6174:4;6070:109;;5868:317;-1:-1:-1;;5868:317:1:o;6190:493::-;6440:2;6429:9;6422:21;6403:4;6466:45;6507:2;6496:9;6492:18;6484:6;6466:45;:::i;:::-;6559:9;6551:6;6547:22;6542:2;6531:9;6527:18;6520:50;6594:2;6586:6;6579:18;6630:14;6625:2;6617:6;6613:15;6606:39;6674:2;6666:6;6662:15;6654:23;;;6190:493;;;;:::o;6688:184::-;6740:77;6737:1;6730:88;6837:4;6834:1;6827:15;6861:4;6858:1;6851:15;6877:334;6948:2;6942:9;7004:2;6994:13;;7009:66;6990:86;6978:99;;7107:18;7092:34;;7128:22;;;7089:62;7086:88;;;7154:18;;:::i;:::-;7190:2;7183:22;6877:334;;-1:-1:-1;6877:334:1:o;7216:1801::-;7321:6;7352:2;7395;7383:9;7374:7;7370:23;7366:32;7363:52;;;7411:1;7408;7401:12;7363:52;7444:9;7438:16;7473:18;7514:2;7506:6;7503:14;7500:34;;;7530:1;7527;7520:12;7500:34;7568:6;7557:9;7553:22;7543:32;;7594:4;7634:7;7629:2;7625;7621:11;7617:25;7607:53;;7656:1;7653;7646:12;7607:53;7685:2;7679:9;7707:2;7703;7700:10;7697:36;;;7713:18;;:::i;:::-;7759:2;7756:1;7752:10;7782:28;7806:2;7802;7798:11;7782:28;:::i;:::-;7844:15;;;7914:11;;;7910:20;;;7875:12;;;;7942:19;;;7939:39;;;7974:1;7971;7964:12;7939:39;8006:2;8002;7998:11;7987:22;;8018:969;8034:6;8029:3;8026:15;8018:969;;;8113:3;8107:10;8149:2;8136:11;8133:19;8130:109;;;8193:1;8222:2;8218;8211:14;8130:109;8262:20;;8317:2;8309:11;;8305:25;-1:-1:-1;8295:123:1;;8372:1;8401:2;8397;8390:14;8295:123;8456:2;8452;8448:11;8442:18;8484:2;8510;8505:3;8502:11;8499:37;;;8516:18;;:::i;:::-;8562:111;8669:2;8600:66;8595:2;8590:3;8586:12;8582:85;8578:94;8562:111;:::i;:::-;8700:3;8693:5;8686:18;8747:7;8741:3;8735;8731:2;8727:12;8723:22;8720:35;8717:128;;;8797:1;8827:3;8822;8815:16;8717:128;8858:56;8910:3;8905:2;8898:5;8894:14;8888:3;8884:2;8880:12;8858:56;:::i;:::-;8927:18;;-1:-1:-1;;;8051:12:1;;;;8965;;;;8018:969;;;9006:5;7216:1801;-1:-1:-1;;;;;;;;;;7216:1801:1:o;9022:184::-;9074:77;9071:1;9064:88;9171:4;9168:1;9161:15;9195:4;9192:1;9185:15;10583:220;10732:2;10721:9;10714:21;10695:4;10752:45;10793:2;10782:9;10778:18;10770:6;10752:45;:::i;10808:340::-;10985:2;10974:9;10967:21;10948:4;11005:45;11046:2;11035:9;11031:18;11023:6;11005:45;:::i;:::-;10997:53;;11098:42;11090:6;11086:55;11081:2;11070:9;11066:18;11059:83;10808:340;;;;;:::o;11153:301::-;11324:2;11313:9;11306:21;11287:4;11344:45;11385:2;11374:9;11370:18;11362:6;11344:45;:::i;:::-;11336:53;;11439:6;11432:14;11425:22;11420:2;11409:9;11405:18;11398:50;11153:301;;;;;:::o;11459:291::-;11636:2;11625:9;11618:21;11599:4;11656:45;11697:2;11686:9;11682:18;11674:6;11656:45;:::i;:::-;11648:53;;11737:6;11732:2;11721:9;11717:18;11710:34;11459:291;;;;;:::o;11755:546::-;12000:2;11989:9;11982:21;11963:4;12026:45;12067:2;12056:9;12052:18;12044:6;12026:45;:::i;:::-;12119:9;12111:6;12107:22;12102:2;12091:9;12087:18;12080:50;12153:33;12179:6;12171;12153:33;:::i;:::-;12139:47;;12234:9;12226:6;12222:22;12217:2;12206:9;12202:18;12195:50;12262:33;12288:6;12280;12262:33;:::i;:::-;12254:41;11755:546;-1:-1:-1;;;;;;11755:546:1:o","linkReferences":{}},"methodIdentifiers":{"call1(string)":"7e79255d","call2(string)":"8d3ef7ca","callPure(string)":"7f8b915c","counter()":"61bc221a","hello(string)":"a777d0dc","nested1(string)":"a76ccdfa","nested2(string)":"dbf1282f","run()":"c0406226","runBroadcast()":"bef03abc"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"call1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"call2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"callPure\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"counter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"hello\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"nested1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"nested2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"run\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"runBroadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"title\":\"ScriptExample\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"hello(string)\":{\"notice\":\"example external function, to force a CALL, and test vm.startPrank with.\"},\"run()\":{\"notice\":\"example function, runs through basic cheat-codes and console logs.\"},\"runBroadcast()\":{\"notice\":\"example function, to test vm.broadcast with.\"}},\"notice\":\"ScriptExample is an example script. The Go forge script code tests that it can run this.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"ScriptExample\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x4fc2ffeba31e146fc3a2edef7cc8b7e82fb2344454d32d6371a62c6d76dfcb4e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a517c69eba90ee5f3efb198a2247d5744bed8e17d332ce2dda4d3cf3a2c334f9\",\"dweb:/ipfs/QmciXeDt5EEhmjH5xECVk2VX6EbnER5UFv58dvGgemwkKK\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"call1"},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"call2"},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"pure","type":"function","name":"callPure"},{"inputs":[],"stateMutability":"view","type":"function","name":"counter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"view","type":"function","name":"hello"},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"nested1"},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"nested2"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"run"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"runBroadcast"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{"hello(string)":{"notice":"example external function, to force a CALL, and test vm.startPrank with."},"run()":{"notice":"example function, runs through basic cheat-codes and console logs."},"runBroadcast()":{"notice":"example function, to test vm.broadcast with."}},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"ScriptExample"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x4fc2ffeba31e146fc3a2edef7cc8b7e82fb2344454d32d6371a62c6d76dfcb4e","urls":["bzz-raw://a517c69eba90ee5f3efb198a2247d5744bed8e17d332ce2dda4d3cf3a2c334f9","dweb:/ipfs/QmciXeDt5EEhmjH5xECVk2VX6EbnER5UFv58dvGgemwkKK"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[{"astId":215,"contract":"scripts/ScriptExample.s.sol:ScriptExample","label":"counter","offset":0,"slot":"0","type":"t_uint256"}],"types":{"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"userdoc":{"version":1,"kind":"user","methods":{"hello(string)":{"notice":"example external function, to force a CALL, and test vm.startPrank with."},"run()":{"notice":"example function, runs through basic cheat-codes and console logs."},"runBroadcast()":{"notice":"example function, to test vm.broadcast with."}},"notice":"ScriptExample is an example script. The Go forge script code tests that it can run this."},"devdoc":{"version":1,"kind":"dev","title":"ScriptExample"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":677,"exportedSymbols":{"FooBar":[676],"ScriptExample":[663],"Vm":[55],"console":[192]},"nodeType":"SourceUnit","src":"32:5697:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":55,"nodeType":"ContractDefinition","src":"120:616:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":55,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":38,"nodeType":"FunctionDefinition","src":"516:30:0","nodes":[],"functionSelector":"afc98040","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"525:9:0","parameters":{"id":36,"nodeType":"ParameterList","parameters":[],"src":"534:2:0"},"returnParameters":{"id":37,"nodeType":"ParameterList","parameters":[],"src":"545:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":43,"nodeType":"FunctionDefinition","src":"551:47:0","nodes":[],"functionSelector":"e6962cdb","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"560:9:0","parameters":{"id":41,"nodeType":"ParameterList","parameters":[{"constant":false,"id":40,"mutability":"mutable","name":"msgSender","nameLocation":"578:9:0","nodeType":"VariableDeclaration","scope":43,"src":"570:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":39,"name":"address","nodeType":"ElementaryTypeName","src":"570:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"569:19:0"},"returnParameters":{"id":42,"nodeType":"ParameterList","parameters":[],"src":"597:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":48,"nodeType":"FunctionDefinition","src":"603:52:0","nodes":[],"functionSelector":"7fec2a8d","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"612:14:0","parameters":{"id":46,"nodeType":"ParameterList","parameters":[{"constant":false,"id":45,"mutability":"mutable","name":"msgSender","nameLocation":"635:9:0","nodeType":"VariableDeclaration","scope":48,"src":"627:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":44,"name":"address","nodeType":"ElementaryTypeName","src":"627:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"626:19:0"},"returnParameters":{"id":47,"nodeType":"ParameterList","parameters":[],"src":"654:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":51,"nodeType":"FunctionDefinition","src":"660:35:0","nodes":[],"functionSelector":"7fb5297f","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"669:14:0","parameters":{"id":49,"nodeType":"ParameterList","parameters":[],"src":"683:2:0"},"returnParameters":{"id":50,"nodeType":"ParameterList","parameters":[],"src":"694:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":54,"nodeType":"FunctionDefinition","src":"700:34:0","nodes":[],"functionSelector":"76eadd36","implemented":false,"kind":"function","modifiers":[],"name":"stopBroadcast","nameLocation":"709:13:0","parameters":{"id":52,"nodeType":"ParameterList","parameters":[],"src":"722:2:0"},"returnParameters":{"id":53,"nodeType":"ParameterList","parameters":[],"src":"733:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[55],"name":"Vm","nameLocation":"130:2:0","scope":677,"usedErrors":[]},{"id":192,"nodeType":"ContractDefinition","src":"791:1622:0","nodes":[{"id":61,"nodeType":"VariableDeclaration","src":"813:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"830:15:0","scope":192,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":56,"name":"address","nodeType":"ElementaryTypeName","src":"813:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":59,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"856:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":58,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"848:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":57,"name":"address","nodeType":"ElementaryTypeName","src":"848:7:0","typeDescriptions":{}}},"id":60,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"848:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":78,"nodeType":"FunctionDefinition","src":"906:221:0","nodes":[],"body":{"id":77,"nodeType":"Block","src":"1065:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"1084:37:0","statements":[{"nodeType":"YulAssignment","src":"1098:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"1107:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"1098:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":67,"isOffset":false,"isSlot":false,"src":"1107:4:0","valueSize":1},{"declaration":74,"isOffset":false,"isSlot":false,"src":"1098:5:0","valueSize":1}],"id":76,"nodeType":"InlineAssembly","src":"1075:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"915:25:0","parameters":{"id":68,"nodeType":"ParameterList","parameters":[{"constant":false,"id":67,"mutability":"mutable","name":"fnIn","nameLocation":"987:4:0","nodeType":"VariableDeclaration","scope":78,"src":"950:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":66,"nodeType":"FunctionTypeName","parameterTypes":{"id":64,"nodeType":"ParameterList","parameters":[{"constant":false,"id":63,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":66,"src":"959:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":62,"name":"bytes","nodeType":"ElementaryTypeName","src":"959:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"958:14:0"},"returnParameterTypes":{"id":65,"nodeType":"ParameterList","parameters":[],"src":"987:0:0"},"src":"950:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"940:57:0"},"returnParameters":{"id":75,"nodeType":"ParameterList","parameters":[{"constant":false,"id":74,"mutability":"mutable","name":"fnOut","nameLocation":"1058:5:0","nodeType":"VariableDeclaration","scope":78,"src":"1021:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":73,"nodeType":"FunctionTypeName","parameterTypes":{"id":71,"nodeType":"ParameterList","parameters":[{"constant":false,"id":70,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":73,"src":"1030:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":69,"name":"bytes","nodeType":"ElementaryTypeName","src":"1030:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1029:14:0"},"returnParameterTypes":{"id":72,"nodeType":"ParameterList","parameters":[],"src":"1058:0:0"},"src":"1021:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"1020:44:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":90,"nodeType":"FunctionDefinition","src":"1133:133:0","nodes":[],"body":{"id":89,"nodeType":"Block","src":"1194:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":86,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1251:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":84,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":106,"src":"1230:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":83,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":78,"src":"1204:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":85,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":87,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":88,"nodeType":"ExpressionStatement","src":"1204:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"1142:15:0","parameters":{"id":81,"nodeType":"ParameterList","parameters":[{"constant":false,"id":80,"mutability":"mutable","name":"payload","nameLocation":"1171:7:0","nodeType":"VariableDeclaration","scope":90,"src":"1158:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":79,"name":"bytes","nodeType":"ElementaryTypeName","src":"1158:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1157:22:0"},"returnParameters":{"id":82,"nodeType":"ParameterList","parameters":[],"src":"1194:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":106,"nodeType":"FunctionDefinition","src":"1272:380:0","nodes":[],"body":{"id":105,"nodeType":"Block","src":"1336:316:0","nodes":[],"statements":[{"assignments":[96],"declarations":[{"constant":false,"id":96,"mutability":"mutable","name":"payloadLength","nameLocation":"1354:13:0","nodeType":"VariableDeclaration","scope":105,"src":"1346:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":95,"name":"uint256","nodeType":"ElementaryTypeName","src":"1346:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":99,"initialValue":{"expression":{"id":97,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":92,"src":"1370:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":98,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1370:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1346:38:0"},{"assignments":[101],"declarations":[{"constant":false,"id":101,"mutability":"mutable","name":"consoleAddress","nameLocation":"1402:14:0","nodeType":"VariableDeclaration","scope":105,"src":"1394:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":100,"name":"address","nodeType":"ElementaryTypeName","src":"1394:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":103,"initialValue":{"id":102,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":61,"src":"1419:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1394:40:0"},{"AST":{"nodeType":"YulBlock","src":"1496:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1510:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1534:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1543:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1530:3:0"},"nodeType":"YulFunctionCall","src":"1530:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1514:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1559:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1579:3:0"},"nodeType":"YulFunctionCall","src":"1579:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1586:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1602:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1616:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1631:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1634:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1568:10:0"},"nodeType":"YulFunctionCall","src":"1568:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1563:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":101,"isOffset":false,"isSlot":false,"src":"1586:14:0","valueSize":1},{"declaration":92,"isOffset":false,"isSlot":false,"src":"1534:7:0","valueSize":1},{"declaration":96,"isOffset":false,"isSlot":false,"src":"1616:13:0","valueSize":1}],"id":104,"nodeType":"InlineAssembly","src":"1487:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1281:19:0","parameters":{"id":93,"nodeType":"ParameterList","parameters":[{"constant":false,"id":92,"mutability":"mutable","name":"payload","nameLocation":"1314:7:0","nodeType":"VariableDeclaration","scope":106,"src":"1301:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":91,"name":"bytes","nodeType":"ElementaryTypeName","src":"1301:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1300:22:0"},"returnParameters":{"id":94,"nodeType":"ParameterList","parameters":[],"src":"1336:0:0"},"scope":192,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":120,"nodeType":"FunctionDefinition","src":"1658:121:0","nodes":[],"body":{"id":119,"nodeType":"Block","src":"1703:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":114,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1753:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":115,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":108,"src":"1768:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":112,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1729:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":113,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1729:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":116,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1729:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":111,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1713:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":117,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1713:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":118,"nodeType":"ExpressionStatement","src":"1713:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1667:3:0","parameters":{"id":109,"nodeType":"ParameterList","parameters":[{"constant":false,"id":108,"mutability":"mutable","name":"p0","nameLocation":"1685:2:0","nodeType":"VariableDeclaration","scope":120,"src":"1671:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":107,"name":"string","nodeType":"ElementaryTypeName","src":"1671:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1670:18:0"},"returnParameters":{"id":110,"nodeType":"ParameterList","parameters":[],"src":"1703:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":137,"nodeType":"FunctionDefinition","src":"1785:139:0","nodes":[],"body":{"id":136,"nodeType":"Block","src":"1839:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":130,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1889:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":131,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":122,"src":"1909:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":132,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":124,"src":"1913:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":128,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1865:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":129,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1865:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":133,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1865:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":127,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1849:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":134,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1849:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":135,"nodeType":"ExpressionStatement","src":"1849:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1794:3:0","parameters":{"id":125,"nodeType":"ParameterList","parameters":[{"constant":false,"id":122,"mutability":"mutable","name":"p0","nameLocation":"1812:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1798:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":121,"name":"string","nodeType":"ElementaryTypeName","src":"1798:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":124,"mutability":"mutable","name":"p1","nameLocation":"1821:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1816:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":123,"name":"bool","nodeType":"ElementaryTypeName","src":"1816:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1797:27:0"},"returnParameters":{"id":126,"nodeType":"ParameterList","parameters":[],"src":"1839:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":154,"nodeType":"FunctionDefinition","src":"1930:145:0","nodes":[],"body":{"id":153,"nodeType":"Block","src":"1987:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":147,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2037:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":148,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":139,"src":"2060:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":149,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":141,"src":"2064:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":145,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2013:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":146,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2013:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":150,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2013:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":144,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1997:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":151,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1997:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":152,"nodeType":"ExpressionStatement","src":"1997:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1939:3:0","parameters":{"id":142,"nodeType":"ParameterList","parameters":[{"constant":false,"id":139,"mutability":"mutable","name":"p0","nameLocation":"1957:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1943:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":138,"name":"string","nodeType":"ElementaryTypeName","src":"1943:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":141,"mutability":"mutable","name":"p1","nameLocation":"1969:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1961:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":140,"name":"uint256","nodeType":"ElementaryTypeName","src":"1961:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1942:30:0"},"returnParameters":{"id":143,"nodeType":"ParameterList","parameters":[],"src":"1987:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":171,"nodeType":"FunctionDefinition","src":"2081:145:0","nodes":[],"body":{"id":170,"nodeType":"Block","src":"2138:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":164,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2188:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":165,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":156,"src":"2211:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":166,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":158,"src":"2215:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":162,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2164:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":163,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2164:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":167,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2164:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":161,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2148:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":168,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2148:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":169,"nodeType":"ExpressionStatement","src":"2148:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2090:3:0","parameters":{"id":159,"nodeType":"ParameterList","parameters":[{"constant":false,"id":156,"mutability":"mutable","name":"p0","nameLocation":"2108:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2094:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":155,"name":"string","nodeType":"ElementaryTypeName","src":"2094:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":158,"mutability":"mutable","name":"p1","nameLocation":"2120:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2112:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":157,"name":"address","nodeType":"ElementaryTypeName","src":"2112:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"2093:30:0"},"returnParameters":{"id":160,"nodeType":"ParameterList","parameters":[],"src":"2138:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":191,"nodeType":"FunctionDefinition","src":"2232:179:0","nodes":[],"body":{"id":190,"nodeType":"Block","src":"2313:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":183,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2363:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":184,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2392:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":185,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":175,"src":"2396:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":186,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":177,"src":"2400:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":181,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2339:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":182,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2339:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":187,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2339:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":180,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2323:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":188,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2323:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":189,"nodeType":"ExpressionStatement","src":"2323:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2241:3:0","parameters":{"id":178,"nodeType":"ParameterList","parameters":[{"constant":false,"id":173,"mutability":"mutable","name":"p0","nameLocation":"2259:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2245:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":172,"name":"string","nodeType":"ElementaryTypeName","src":"2245:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":175,"mutability":"mutable","name":"p1","nameLocation":"2277:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2263:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":174,"name":"string","nodeType":"ElementaryTypeName","src":"2263:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":177,"mutability":"mutable","name":"p2","nameLocation":"2295:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2281:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":176,"name":"string","nodeType":"ElementaryTypeName","src":"2281:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2244:54:0"},"returnParameters":{"id":179,"nodeType":"ParameterList","parameters":[],"src":"2313:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[192],"name":"console","nameLocation":"799:7:0","scope":677,"usedErrors":[]},{"id":663,"nodeType":"ContractDefinition","src":"2541:3089:0","nodes":[{"id":207,"nodeType":"VariableDeclaration","src":"2571:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2597:10:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":194,"name":"address","nodeType":"ElementaryTypeName","src":"2571:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2644:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":201,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2634:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":203,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2634:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":200,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2626:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":199,"name":"uint256","nodeType":"ElementaryTypeName","src":"2626:7:0","typeDescriptions":{}}},"id":204,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2626:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":198,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2618:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":197,"name":"uint160","nodeType":"ElementaryTypeName","src":"2618:7:0","typeDescriptions":{}}},"id":205,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2618:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":196,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2610:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":195,"name":"address","nodeType":"ElementaryTypeName","src":"2610:7:0","typeDescriptions":{}}},"id":206,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2610:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":213,"nodeType":"VariableDeclaration","src":"2671:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2692:2:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"},"typeName":{"id":209,"nodeType":"UserDefinedTypeName","pathNode":{"id":208,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":55,"src":"2671:2:0"},"referencedDeclaration":55,"src":"2671:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"value":{"arguments":[{"id":211,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":207,"src":"2700:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":210,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":55,"src":"2697:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$55_$","typeString":"type(contract Vm)"}},"id":212,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2697:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"visibility":"internal"},{"id":215,"nodeType":"VariableDeclaration","src":"2775:22:0","nodes":[],"constant":false,"functionSelector":"61bc221a","mutability":"mutable","name":"counter","nameLocation":"2790:7:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":214,"name":"uint256","nodeType":"ElementaryTypeName","src":"2775:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":378,"nodeType":"FunctionDefinition","src":"2887:949:0","nodes":[],"body":{"id":377,"nodeType":"Block","src":"2909:927:0","nodes":[],"statements":[{"assignments":[220],"declarations":[{"constant":false,"id":220,"mutability":"mutable","name":"x","nameLocation":"2924:1:0","nodeType":"VariableDeclaration","scope":377,"src":"2919:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":219,"name":"bool","nodeType":"ElementaryTypeName","src":"2919:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":226,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":223,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2937:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":224,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2953:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":221,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"2928:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":222,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2928:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":225,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2928:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2919:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":230,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2981:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":231,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":220,"src":"3004:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":227,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"2969:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":229,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":137,"src":"2969:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2969:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":233,"nodeType":"ExpressionStatement","src":"2969:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":237,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3029:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":240,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3054:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":239,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3046:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":238,"name":"address","nodeType":"ElementaryTypeName","src":"3046:7:0","typeDescriptions":{}}},"id":241,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3046:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":234,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3017:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":236,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3017:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":242,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3017:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":243,"nodeType":"ExpressionStatement","src":"3017:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":247,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3082:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":252,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3120:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":251,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3112:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":250,"name":"address","nodeType":"ElementaryTypeName","src":"3112:7:0","typeDescriptions":{}}},"id":253,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3112:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":248,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3100:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3100:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":254,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3100:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":244,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3070:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":246,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3070:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":255,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3070:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":256,"nodeType":"ExpressionStatement","src":"3070:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":260,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3149:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":263,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3172:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":264,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3172:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":262,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3164:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":261,"name":"address","nodeType":"ElementaryTypeName","src":"3164:7:0","typeDescriptions":{}}},"id":265,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3164:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":257,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3137:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":259,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3137:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":266,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3137:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":267,"nodeType":"ExpressionStatement","src":"3137:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":271,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3206:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":276,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3242:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":277,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3242:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":275,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3234:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":274,"name":"address","nodeType":"ElementaryTypeName","src":"3234:7:0","typeDescriptions":{}}},"id":278,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3234:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":272,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3222:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":273,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3222:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":279,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3222:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":268,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3194:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":270,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3194:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":280,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3194:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":281,"nodeType":"ExpressionStatement","src":"3194:61:0"},{"assignments":[283],"declarations":[{"constant":false,"id":283,"mutability":"mutable","name":"json","nameLocation":"3280:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3266:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":282,"name":"string","nodeType":"ElementaryTypeName","src":"3266:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":285,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3287:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"3266:55:0"},{"assignments":[290],"declarations":[{"constant":false,"id":290,"mutability":"mutable","name":"keys","nameLocation":"3347:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3331:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":288,"name":"string","nodeType":"ElementaryTypeName","src":"3331:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":289,"nodeType":"ArrayTypeName","src":"3331:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":296,"initialValue":{"arguments":[{"id":293,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":283,"src":"3371:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":294,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3377:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":291,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3354:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":292,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3354:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":295,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3354:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3331:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":300,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3414:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":301,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3422:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":303,"indexExpression":{"hexValue":"30","id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3427:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3422:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":304,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3431:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":306,"indexExpression":{"hexValue":"31","id":305,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3436:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3431:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":297,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3402:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":299,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":191,"src":"3402:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":307,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3402:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":308,"nodeType":"ExpressionStatement","src":"3402:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":312,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3461:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":309,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3450:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":311,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3450:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":313,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3450:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":314,"nodeType":"ExpressionStatement","src":"3450:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":322,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3517:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":321,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3509:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":320,"name":"uint160","nodeType":"ElementaryTypeName","src":"3509:7:0","typeDescriptions":{}}},"id":323,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3509:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":319,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3501:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":318,"name":"address","nodeType":"ElementaryTypeName","src":"3501:7:0","typeDescriptions":{}}},"id":324,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3501:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":315,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3487:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":317,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3487:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3487:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":326,"nodeType":"ExpressionStatement","src":"3487:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":330,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3545:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":327,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3534:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":329,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3534:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3534:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":332,"nodeType":"ExpressionStatement","src":"3534:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":336,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3582:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":339,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3617:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":340,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3617:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":338,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3609:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":337,"name":"address","nodeType":"ElementaryTypeName","src":"3609:7:0","typeDescriptions":{}}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3609:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":333,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3570:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":335,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3570:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3570:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3570:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3651:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":350,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3689:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":349,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3681:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":348,"name":"address","nodeType":"ElementaryTypeName","src":"3681:7:0","typeDescriptions":{}}},"id":351,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3681:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":344,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3639:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3639:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3639:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":353,"nodeType":"ExpressionStatement","src":"3639:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":357,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3716:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":354,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3705:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":356,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3705:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":358,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3705:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":359,"nodeType":"ExpressionStatement","src":"3705:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":360,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3741:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":362,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3741:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":363,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3741:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":364,"nodeType":"ExpressionStatement","src":"3741:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":368,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3776:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":365,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3765:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":367,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3765:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":369,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3765:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":370,"nodeType":"ExpressionStatement","src":"3765:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":374,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3821:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":371,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3809:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":373,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"3809:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":375,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3809:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":376,"nodeType":"ExpressionStatement","src":"3809:20:0"}]},"documentation":{"id":216,"nodeType":"StructuredDocumentation","src":"2804:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2896:3:0","parameters":{"id":217,"nodeType":"ParameterList","parameters":[],"src":"2899:2:0"},"returnParameters":{"id":218,"nodeType":"ParameterList","parameters":[],"src":"2909:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":566,"nodeType":"FunctionDefinition","src":"3903:988:0","nodes":[],"body":{"id":565,"nodeType":"Block","src":"3934:957:0","nodes":[],"statements":[{"expression":{"arguments":[{"hexValue":"74657374696e672073696e676c65","id":385,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3956:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""},"value":"testing single"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""}],"expression":{"id":382,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3944:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":384,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"3944:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":386,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3944:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":387,"nodeType":"ExpressionStatement","src":"3944:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":388,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3983:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":390,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"3983:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":391,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3983:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":392,"nodeType":"ExpressionStatement","src":"3983:14:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c31","id":396,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4018:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""},"value":"single_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""}],"expression":{"id":393,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4007:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":395,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4007:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":397,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4007:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":398,"nodeType":"ExpressionStatement","src":"4007:26:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c32","id":402,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4054:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""},"value":"single_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""}],"expression":{"id":399,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4043:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":401,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":620,"src":"4043:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":403,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4043:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":404,"nodeType":"ExpressionStatement","src":"4043:26:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073746172742f73746f70","id":408,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4092:20:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""},"value":"testing start/stop"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""}],"expression":{"id":405,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4080:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":407,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4080:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":409,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4080:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":410,"nodeType":"ExpressionStatement","src":"4080:33:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078633066666565","id":418,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4157:8:0","typeDescriptions":{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"},"value":"0xc0ffee"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"}],"id":417,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4149:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":416,"name":"uint160","nodeType":"ElementaryTypeName","src":"4149:7:0","typeDescriptions":{}}},"id":419,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4149:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":415,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4141:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":414,"name":"address","nodeType":"ElementaryTypeName","src":"4141:7:0","typeDescriptions":{}}},"id":420,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4141:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":411,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4123:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":413,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4123:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":421,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4123:45:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":422,"nodeType":"ExpressionStatement","src":"4123:45:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c31","id":426,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4189:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""},"value":"startstop_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""}],"expression":{"id":423,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4178:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":425,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4178:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":427,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4178:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":428,"nodeType":"ExpressionStatement","src":"4178:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c32","id":432,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4228:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""},"value":"startstop_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""}],"expression":{"id":429,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4217:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":431,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":620,"src":"4217:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":433,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4217:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":434,"nodeType":"ExpressionStatement","src":"4217:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f70757265","id":438,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4270:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""},"value":"startstop_pure"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""}],"expression":{"id":435,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4256:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":437,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"callPure","nodeType":"MemberAccess","referencedDeclaration":662,"src":"4256:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure external"}},"id":439,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4256:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":440,"nodeType":"ExpressionStatement","src":"4256:31:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":441,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4297:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":443,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4297:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":444,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4297:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":445,"nodeType":"ExpressionStatement","src":"4297:18:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c33","id":449,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4336:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""},"value":"startstop_call3"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""}],"expression":{"id":446,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4325:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":448,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4325:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":450,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4325:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":451,"nodeType":"ExpressionStatement","src":"4325:29:0"},{"expression":{"arguments":[{"hexValue":"74657374696e67206e6573746564","id":455,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4377:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""},"value":"testing nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""}],"expression":{"id":452,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4365:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":454,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4365:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":456,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4365:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":457,"nodeType":"ExpressionStatement","src":"4365:29:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307831323334","id":465,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4438:6:0","typeDescriptions":{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"},"value":"0x1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"}],"id":464,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4430:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":463,"name":"uint160","nodeType":"ElementaryTypeName","src":"4430:7:0","typeDescriptions":{}}},"id":466,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4430:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":462,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4422:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":461,"name":"address","nodeType":"ElementaryTypeName","src":"4422:7:0","typeDescriptions":{}}},"id":467,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4422:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":458,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4404:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":460,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4404:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":468,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4404:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":469,"nodeType":"ExpressionStatement","src":"4404:43:0"},{"expression":{"arguments":[{"hexValue":"6e6573746564","id":473,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4470:8:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""},"value":"nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""}],"expression":{"id":470,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4457:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":472,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested1","nodeType":"MemberAccess","referencedDeclaration":635,"src":"4457:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":474,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4457:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":475,"nodeType":"ExpressionStatement","src":"4457:22:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":476,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4489:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":478,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4489:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":479,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4489:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":480,"nodeType":"ExpressionStatement","src":"4489:18:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206465706c6f796d656e74","id":484,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4530:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""},"value":"contract deployment"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""}],"expression":{"id":481,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4518:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":483,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4518:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":485,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4518:34:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":486,"nodeType":"ExpressionStatement","src":"4518:34:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078313233343536","id":494,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4591:8:0","typeDescriptions":{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"},"value":"0x123456"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"}],"id":493,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4583:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":492,"name":"uint160","nodeType":"ElementaryTypeName","src":"4583:7:0","typeDescriptions":{}}},"id":495,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4583:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":491,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4575:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":490,"name":"address","nodeType":"ElementaryTypeName","src":"4575:7:0","typeDescriptions":{}}},"id":496,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4575:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":487,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4562:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":489,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4562:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":497,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4562:40:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":498,"nodeType":"ExpressionStatement","src":"4562:40:0"},{"assignments":[501],"declarations":[{"constant":false,"id":501,"mutability":"mutable","name":"x","nameLocation":"4619:1:0","nodeType":"VariableDeclaration","scope":565,"src":"4612:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"},"typeName":{"id":500,"nodeType":"UserDefinedTypeName","pathNode":{"id":499,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4612:6:0"},"referencedDeclaration":676,"src":"4612:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"visibility":"internal"}],"id":507,"initialValue":{"arguments":[{"hexValue":"31323334","id":505,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4634:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":504,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4623:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":503,"nodeType":"UserDefinedTypeName","pathNode":{"id":502,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4627:6:0"},"referencedDeclaration":676,"src":"4627:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}}},"id":506,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4623:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4612:27:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":513,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":509,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":501,"src":"4657:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"id":510,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":665,"src":"4657:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":511,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4657:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":512,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4668:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4657:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":508,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4649:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":514,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4649:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":515,"nodeType":"ExpressionStatement","src":"4649:24:0"},{"expression":{"arguments":[{"hexValue":"6372656174652032","id":519,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4696:10:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""},"value":"create 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""}],"expression":{"id":516,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4684:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":518,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4684:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":520,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4684:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":521,"nodeType":"ExpressionStatement","src":"4684:23:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307863616665","id":529,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4746:6:0","typeDescriptions":{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"},"value":"0xcafe"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"}],"id":528,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4738:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":527,"name":"uint160","nodeType":"ElementaryTypeName","src":"4738:7:0","typeDescriptions":{}}},"id":530,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4738:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":526,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4730:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":525,"name":"address","nodeType":"ElementaryTypeName","src":"4730:7:0","typeDescriptions":{}}},"id":531,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4730:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":522,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4717:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":524,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4717:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":532,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4717:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":533,"nodeType":"ExpressionStatement","src":"4717:38:0"},{"assignments":[536],"declarations":[{"constant":false,"id":536,"mutability":"mutable","name":"y","nameLocation":"4772:1:0","nodeType":"VariableDeclaration","scope":565,"src":"4765:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"},"typeName":{"id":535,"nodeType":"UserDefinedTypeName","pathNode":{"id":534,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4765:6:0"},"referencedDeclaration":676,"src":"4765:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"visibility":"internal"}],"id":550,"initialValue":{"arguments":[{"hexValue":"31323334","id":548,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4815:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":539,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4776:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":538,"nodeType":"UserDefinedTypeName","pathNode":{"id":537,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4780:6:0"},"referencedDeclaration":676,"src":"4780:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}}},"id":547,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"names":["salt"],"nodeType":"FunctionCallOptions","options":[{"arguments":[{"arguments":[{"hexValue":"3432","id":544,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4809:2:0","typeDescriptions":{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"},"value":"42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"}],"id":543,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4801:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":542,"name":"uint256","nodeType":"ElementaryTypeName","src":"4801:7:0","typeDescriptions":{}}},"id":545,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4801:11:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":541,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4793:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_bytes32_$","typeString":"type(bytes32)"},"typeName":{"id":540,"name":"bytes32","nodeType":"ElementaryTypeName","src":"4793:7:0","typeDescriptions":{}}},"id":546,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4793:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"src":"4776:38:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$salt","typeString":"function (uint256) returns (contract FooBar)"}},"id":549,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4776:44:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4765:55:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":556,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":552,"name":"y","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":536,"src":"4838:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"id":553,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":665,"src":"4838:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":554,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4838:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":555,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4849:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4838:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":551,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4830:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":557,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4830:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":558,"nodeType":"ExpressionStatement","src":"4830:24:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":562,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4876:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":559,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4864:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":561,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4864:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":563,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4864:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":564,"nodeType":"ExpressionStatement","src":"4864:20:0"}]},"documentation":{"id":379,"nodeType":"StructuredDocumentation","src":"3842:56:0","text":"@notice example function, to test vm.broadcast with."},"functionSelector":"bef03abc","implemented":true,"kind":"function","modifiers":[],"name":"runBroadcast","nameLocation":"3912:12:0","parameters":{"id":380,"nodeType":"ParameterList","parameters":[],"src":"3924:2:0"},"returnParameters":{"id":381,"nodeType":"ParameterList","parameters":[],"src":"3934:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":590,"nodeType":"FunctionDefinition","src":"4986:143:0","nodes":[],"body":{"id":589,"nodeType":"Block","src":"5035:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":575,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":569,"src":"5057:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":572,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5045:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":574,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5045:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":576,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5045:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":577,"nodeType":"ExpressionStatement","src":"5045:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":581,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"5082:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":584,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"5110:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":585,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"5110:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":583,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5102:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":582,"name":"address","nodeType":"ElementaryTypeName","src":"5102:7:0","typeDescriptions":{}}},"id":586,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5102:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":578,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5070:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":580,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"5070:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":587,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5070:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":588,"nodeType":"ExpressionStatement","src":"5070:52:0"}]},"documentation":{"id":567,"nodeType":"StructuredDocumentation","src":"4897:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"4995:5:0","parameters":{"id":570,"nodeType":"ParameterList","parameters":[{"constant":false,"id":569,"mutability":"mutable","name":"_v","nameLocation":"5017:2:0","nodeType":"VariableDeclaration","scope":590,"src":"5001:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":568,"name":"string","nodeType":"ElementaryTypeName","src":"5001:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5000:20:0"},"returnParameters":{"id":571,"nodeType":"ParameterList","parameters":[],"src":"5035:0:0"},"scope":663,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":605,"nodeType":"FunctionDefinition","src":"5135:95:0","nodes":[],"body":{"id":604,"nodeType":"Block","src":"5179:51:0","nodes":[],"statements":[{"expression":{"id":596,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5189:9:0","subExpression":{"id":595,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5189:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":597,"nodeType":"ExpressionStatement","src":"5189:9:0"},{"expression":{"arguments":[{"id":601,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":592,"src":"5220:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":598,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5208:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":600,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5208:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":602,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5208:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":603,"nodeType":"ExpressionStatement","src":"5208:15:0"}]},"functionSelector":"7e79255d","implemented":true,"kind":"function","modifiers":[],"name":"call1","nameLocation":"5144:5:0","parameters":{"id":593,"nodeType":"ParameterList","parameters":[{"constant":false,"id":592,"mutability":"mutable","name":"_v","nameLocation":"5166:2:0","nodeType":"VariableDeclaration","scope":605,"src":"5150:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":591,"name":"string","nodeType":"ElementaryTypeName","src":"5150:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5149:20:0"},"returnParameters":{"id":594,"nodeType":"ParameterList","parameters":[],"src":"5179:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":620,"nodeType":"FunctionDefinition","src":"5236:95:0","nodes":[],"body":{"id":619,"nodeType":"Block","src":"5280:51:0","nodes":[],"statements":[{"expression":{"id":611,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5290:9:0","subExpression":{"id":610,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5290:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":612,"nodeType":"ExpressionStatement","src":"5290:9:0"},{"expression":{"arguments":[{"id":616,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":607,"src":"5321:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":613,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5309:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":615,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5309:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":617,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5309:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":618,"nodeType":"ExpressionStatement","src":"5309:15:0"}]},"functionSelector":"8d3ef7ca","implemented":true,"kind":"function","modifiers":[],"name":"call2","nameLocation":"5245:5:0","parameters":{"id":608,"nodeType":"ParameterList","parameters":[{"constant":false,"id":607,"mutability":"mutable","name":"_v","nameLocation":"5267:2:0","nodeType":"VariableDeclaration","scope":620,"src":"5251:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":606,"name":"string","nodeType":"ElementaryTypeName","src":"5251:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5250:20:0"},"returnParameters":{"id":609,"nodeType":"ParameterList","parameters":[],"src":"5280:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":635,"nodeType":"FunctionDefinition","src":"5337:98:0","nodes":[],"body":{"id":634,"nodeType":"Block","src":"5383:52:0","nodes":[],"statements":[{"expression":{"id":626,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5393:9:0","subExpression":{"id":625,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5393:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":627,"nodeType":"ExpressionStatement","src":"5393:9:0"},{"expression":{"arguments":[{"id":631,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":622,"src":"5425:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":628,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"5412:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":630,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested2","nodeType":"MemberAccess","referencedDeclaration":650,"src":"5412:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":632,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5412:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":633,"nodeType":"ExpressionStatement","src":"5412:16:0"}]},"functionSelector":"a76ccdfa","implemented":true,"kind":"function","modifiers":[],"name":"nested1","nameLocation":"5346:7:0","parameters":{"id":623,"nodeType":"ParameterList","parameters":[{"constant":false,"id":622,"mutability":"mutable","name":"_v","nameLocation":"5370:2:0","nodeType":"VariableDeclaration","scope":635,"src":"5354:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":621,"name":"string","nodeType":"ElementaryTypeName","src":"5354:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5353:20:0"},"returnParameters":{"id":624,"nodeType":"ParameterList","parameters":[],"src":"5383:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":650,"nodeType":"FunctionDefinition","src":"5441:97:0","nodes":[],"body":{"id":649,"nodeType":"Block","src":"5487:51:0","nodes":[],"statements":[{"expression":{"id":641,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5497:9:0","subExpression":{"id":640,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5497:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":642,"nodeType":"ExpressionStatement","src":"5497:9:0"},{"expression":{"arguments":[{"id":646,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":637,"src":"5528:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":643,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5516:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":645,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5516:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":647,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5516:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":648,"nodeType":"ExpressionStatement","src":"5516:15:0"}]},"functionSelector":"dbf1282f","implemented":true,"kind":"function","modifiers":[],"name":"nested2","nameLocation":"5450:7:0","parameters":{"id":638,"nodeType":"ParameterList","parameters":[{"constant":false,"id":637,"mutability":"mutable","name":"_v","nameLocation":"5474:2:0","nodeType":"VariableDeclaration","scope":650,"src":"5458:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":636,"name":"string","nodeType":"ElementaryTypeName","src":"5458:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5457:20:0"},"returnParameters":{"id":639,"nodeType":"ParameterList","parameters":[],"src":"5487:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":662,"nodeType":"FunctionDefinition","src":"5544:84:0","nodes":[],"body":{"id":661,"nodeType":"Block","src":"5596:32:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":658,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":652,"src":"5618:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":655,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5606:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":657,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5606:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":659,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5606:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":660,"nodeType":"ExpressionStatement","src":"5606:15:0"}]},"functionSelector":"7f8b915c","implemented":true,"kind":"function","modifiers":[],"name":"callPure","nameLocation":"5553:8:0","parameters":{"id":653,"nodeType":"ParameterList","parameters":[{"constant":false,"id":652,"mutability":"mutable","name":"_v","nameLocation":"5578:2:0","nodeType":"VariableDeclaration","scope":662,"src":"5562:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":651,"name":"string","nodeType":"ElementaryTypeName","src":"5562:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5561:20:0"},"returnParameters":{"id":654,"nodeType":"ParameterList","parameters":[],"src":"5596:0:0"},"scope":663,"stateMutability":"pure","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[676],"contractKind":"contract","documentation":{"id":193,"nodeType":"StructuredDocumentation","src":"2415:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[663],"name":"ScriptExample","nameLocation":"2550:13:0","scope":677,"usedErrors":[]},{"id":676,"nodeType":"ContractDefinition","src":"5632:96:0","nodes":[{"id":665,"nodeType":"VariableDeclaration","src":"5654:18:0","nodes":[],"constant":false,"functionSelector":"c2985578","mutability":"mutable","name":"foo","nameLocation":"5669:3:0","scope":676,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":664,"name":"uint256","nodeType":"ElementaryTypeName","src":"5654:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":675,"nodeType":"FunctionDefinition","src":"5679:47:0","nodes":[],"body":{"id":674,"nodeType":"Block","src":"5702:24:0","nodes":[],"statements":[{"expression":{"id":672,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":670,"name":"foo","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":665,"src":"5712:3:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":671,"name":"v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":667,"src":"5718:1:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5712:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":673,"nodeType":"ExpressionStatement","src":"5712:7:0"}]},"implemented":true,"kind":"constructor","modifiers":[],"name":"","nameLocation":"-1:-1:-1","parameters":{"id":668,"nodeType":"ParameterList","parameters":[{"constant":false,"id":667,"mutability":"mutable","name":"v","nameLocation":"5699:1:0","nodeType":"VariableDeclaration","scope":675,"src":"5691:9:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":666,"name":"uint256","nodeType":"ElementaryTypeName","src":"5691:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"5690:11:0"},"returnParameters":{"id":669,"nodeType":"ParameterList","parameters":[],"src":"5702:0:0"},"scope":676,"stateMutability":"nonpayable","virtual":false,"visibility":"public"}],"abstract":false,"baseContracts":[],"canonicalName":"FooBar","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[676],"name":"FooBar","nameLocation":"5641:6:0","scope":677,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file diff --git a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/Vm.json b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/Vm.json index de72d377618a..dd1f6760babb 100644 --- a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/Vm.json +++ b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/Vm.json @@ -1 +1 @@ -{"abi":[{"type":"function","name":"broadcast","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"envOr","inputs":[{"name":"name","type":"string","internalType":"string"},{"name":"defaultValue","type":"bool","internalType":"bool"}],"outputs":[{"name":"value","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"getNonce","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"nonce","type":"uint64","internalType":"uint64"}],"stateMutability":"view"},{"type":"function","name":"parseJsonKeys","inputs":[{"name":"json","type":"string","internalType":"string"},{"name":"key","type":"string","internalType":"string"}],"outputs":[{"name":"keys","type":"string[]","internalType":"string[]"}],"stateMutability":"pure"},{"type":"function","name":"startBroadcast","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"startPrank","inputs":[{"name":"msgSender","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"stopBroadcast","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"stopPrank","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{"broadcast()":"afc98040","envOr(string,bool)":"4777f3cf","getNonce(address)":"2d0335ab","parseJsonKeys(string,string)":"213e4198","startBroadcast()":"7fb5297f","startPrank(address)":"06447d56","stopBroadcast()":"76eadd36","stopPrank()":"90c5013b"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"broadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"defaultValue\",\"type\":\"bool\"}],\"name\":\"envOr\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"json\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"}],\"name\":\"parseJsonKeys\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"keys\",\"type\":\"string[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startBroadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"msgSender\",\"type\":\"address\"}],\"name\":\"startPrank\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stopBroadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stopPrank\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"Vm\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x7727e5a55f4b3d442729483d41848c957b04027e48d972a568ee6f50aa3daa7a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4de8bd2d73869b583c44f8996ef56f872ce47499e801aa95da90a8e695196b00\",\"dweb:/ipfs/QmZzQy8ZSWuMnLBsGWTxUxZRhWGTJ8cq8yHpM59irYA2dw\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"broadcast"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"bool","name":"defaultValue","type":"bool"}],"stateMutability":"view","type":"function","name":"envOr","outputs":[{"internalType":"bool","name":"value","type":"bool"}]},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"stateMutability":"view","type":"function","name":"getNonce","outputs":[{"internalType":"uint64","name":"nonce","type":"uint64"}]},{"inputs":[{"internalType":"string","name":"json","type":"string"},{"internalType":"string","name":"key","type":"string"}],"stateMutability":"pure","type":"function","name":"parseJsonKeys","outputs":[{"internalType":"string[]","name":"keys","type":"string[]"}]},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"startBroadcast"},{"inputs":[{"internalType":"address","name":"msgSender","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"startPrank"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"stopBroadcast"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"stopPrank"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"Vm"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x7727e5a55f4b3d442729483d41848c957b04027e48d972a568ee6f50aa3daa7a","urls":["bzz-raw://4de8bd2d73869b583c44f8996ef56f872ce47499e801aa95da90a8e695196b00","dweb:/ipfs/QmZzQy8ZSWuMnLBsGWTxUxZRhWGTJ8cq8yHpM59irYA2dw"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[],"types":{}},"userdoc":{"version":1,"kind":"user"},"devdoc":{"version":1,"kind":"dev"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":538,"exportedSymbols":{"ScriptExample":[537],"Vm":[45],"console":[182]},"nodeType":"SourceUnit","src":"32:4932:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":45,"nodeType":"ContractDefinition","src":"120:507:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":45,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":45,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":45,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":38,"nodeType":"FunctionDefinition","src":"516:30:0","nodes":[],"functionSelector":"afc98040","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"525:9:0","parameters":{"id":36,"nodeType":"ParameterList","parameters":[],"src":"534:2:0"},"returnParameters":{"id":37,"nodeType":"ParameterList","parameters":[],"src":"545:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":41,"nodeType":"FunctionDefinition","src":"551:35:0","nodes":[],"functionSelector":"7fb5297f","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"560:14:0","parameters":{"id":39,"nodeType":"ParameterList","parameters":[],"src":"574:2:0"},"returnParameters":{"id":40,"nodeType":"ParameterList","parameters":[],"src":"585:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":44,"nodeType":"FunctionDefinition","src":"591:34:0","nodes":[],"functionSelector":"76eadd36","implemented":false,"kind":"function","modifiers":[],"name":"stopBroadcast","nameLocation":"600:13:0","parameters":{"id":42,"nodeType":"ParameterList","parameters":[],"src":"613:2:0"},"returnParameters":{"id":43,"nodeType":"ParameterList","parameters":[],"src":"624:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[45],"name":"Vm","nameLocation":"130:2:0","scope":538,"usedErrors":[]},{"id":182,"nodeType":"ContractDefinition","src":"682:1622:0","nodes":[{"id":51,"nodeType":"VariableDeclaration","src":"704:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"721:15:0","scope":182,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":46,"name":"address","nodeType":"ElementaryTypeName","src":"704:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":49,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"747:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":48,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"739:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":47,"name":"address","nodeType":"ElementaryTypeName","src":"739:7:0","typeDescriptions":{}}},"id":50,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"739:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":68,"nodeType":"FunctionDefinition","src":"797:221:0","nodes":[],"body":{"id":67,"nodeType":"Block","src":"956:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"975:37:0","statements":[{"nodeType":"YulAssignment","src":"989:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"998:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"989:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":57,"isOffset":false,"isSlot":false,"src":"998:4:0","valueSize":1},{"declaration":64,"isOffset":false,"isSlot":false,"src":"989:5:0","valueSize":1}],"id":66,"nodeType":"InlineAssembly","src":"966:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"806:25:0","parameters":{"id":58,"nodeType":"ParameterList","parameters":[{"constant":false,"id":57,"mutability":"mutable","name":"fnIn","nameLocation":"878:4:0","nodeType":"VariableDeclaration","scope":68,"src":"841:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":56,"nodeType":"FunctionTypeName","parameterTypes":{"id":54,"nodeType":"ParameterList","parameters":[{"constant":false,"id":53,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":56,"src":"850:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":52,"name":"bytes","nodeType":"ElementaryTypeName","src":"850:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"849:14:0"},"returnParameterTypes":{"id":55,"nodeType":"ParameterList","parameters":[],"src":"878:0:0"},"src":"841:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"831:57:0"},"returnParameters":{"id":65,"nodeType":"ParameterList","parameters":[{"constant":false,"id":64,"mutability":"mutable","name":"fnOut","nameLocation":"949:5:0","nodeType":"VariableDeclaration","scope":68,"src":"912:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":63,"nodeType":"FunctionTypeName","parameterTypes":{"id":61,"nodeType":"ParameterList","parameters":[{"constant":false,"id":60,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":63,"src":"921:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":59,"name":"bytes","nodeType":"ElementaryTypeName","src":"921:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"920:14:0"},"returnParameterTypes":{"id":62,"nodeType":"ParameterList","parameters":[],"src":"949:0:0"},"src":"912:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"911:44:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":80,"nodeType":"FunctionDefinition","src":"1024:133:0","nodes":[],"body":{"id":79,"nodeType":"Block","src":"1085:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":76,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":70,"src":"1142:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":74,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":96,"src":"1121:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":73,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":68,"src":"1095:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":75,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1095:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":77,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1095:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":78,"nodeType":"ExpressionStatement","src":"1095:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"1033:15:0","parameters":{"id":71,"nodeType":"ParameterList","parameters":[{"constant":false,"id":70,"mutability":"mutable","name":"payload","nameLocation":"1062:7:0","nodeType":"VariableDeclaration","scope":80,"src":"1049:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":69,"name":"bytes","nodeType":"ElementaryTypeName","src":"1049:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1048:22:0"},"returnParameters":{"id":72,"nodeType":"ParameterList","parameters":[],"src":"1085:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":96,"nodeType":"FunctionDefinition","src":"1163:380:0","nodes":[],"body":{"id":95,"nodeType":"Block","src":"1227:316:0","nodes":[],"statements":[{"assignments":[86],"declarations":[{"constant":false,"id":86,"mutability":"mutable","name":"payloadLength","nameLocation":"1245:13:0","nodeType":"VariableDeclaration","scope":95,"src":"1237:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":85,"name":"uint256","nodeType":"ElementaryTypeName","src":"1237:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":89,"initialValue":{"expression":{"id":87,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":82,"src":"1261:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":88,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1261:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1237:38:0"},{"assignments":[91],"declarations":[{"constant":false,"id":91,"mutability":"mutable","name":"consoleAddress","nameLocation":"1293:14:0","nodeType":"VariableDeclaration","scope":95,"src":"1285:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":90,"name":"address","nodeType":"ElementaryTypeName","src":"1285:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":93,"initialValue":{"id":92,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":51,"src":"1310:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1285:40:0"},{"AST":{"nodeType":"YulBlock","src":"1387:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1401:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1425:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1434:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1421:3:0"},"nodeType":"YulFunctionCall","src":"1421:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1405:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1450:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1470:3:0"},"nodeType":"YulFunctionCall","src":"1470:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1477:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1493:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1507:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1522:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1525:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1459:10:0"},"nodeType":"YulFunctionCall","src":"1459:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1454:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":91,"isOffset":false,"isSlot":false,"src":"1477:14:0","valueSize":1},{"declaration":82,"isOffset":false,"isSlot":false,"src":"1425:7:0","valueSize":1},{"declaration":86,"isOffset":false,"isSlot":false,"src":"1507:13:0","valueSize":1}],"id":94,"nodeType":"InlineAssembly","src":"1378:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1172:19:0","parameters":{"id":83,"nodeType":"ParameterList","parameters":[{"constant":false,"id":82,"mutability":"mutable","name":"payload","nameLocation":"1205:7:0","nodeType":"VariableDeclaration","scope":96,"src":"1192:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":81,"name":"bytes","nodeType":"ElementaryTypeName","src":"1192:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1191:22:0"},"returnParameters":{"id":84,"nodeType":"ParameterList","parameters":[],"src":"1227:0:0"},"scope":182,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":110,"nodeType":"FunctionDefinition","src":"1549:121:0","nodes":[],"body":{"id":109,"nodeType":"Block","src":"1594:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":104,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1644:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":105,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":98,"src":"1659:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":102,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1620:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":103,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1620:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":106,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1620:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":101,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1604:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":107,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1604:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":108,"nodeType":"ExpressionStatement","src":"1604:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1558:3:0","parameters":{"id":99,"nodeType":"ParameterList","parameters":[{"constant":false,"id":98,"mutability":"mutable","name":"p0","nameLocation":"1576:2:0","nodeType":"VariableDeclaration","scope":110,"src":"1562:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":97,"name":"string","nodeType":"ElementaryTypeName","src":"1562:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1561:18:0"},"returnParameters":{"id":100,"nodeType":"ParameterList","parameters":[],"src":"1594:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":127,"nodeType":"FunctionDefinition","src":"1676:139:0","nodes":[],"body":{"id":126,"nodeType":"Block","src":"1730:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":120,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1780:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":121,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":112,"src":"1800:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":122,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":114,"src":"1804:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":118,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1756:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":119,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1756:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":123,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1756:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":117,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1740:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":124,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1740:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":125,"nodeType":"ExpressionStatement","src":"1740:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1685:3:0","parameters":{"id":115,"nodeType":"ParameterList","parameters":[{"constant":false,"id":112,"mutability":"mutable","name":"p0","nameLocation":"1703:2:0","nodeType":"VariableDeclaration","scope":127,"src":"1689:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":111,"name":"string","nodeType":"ElementaryTypeName","src":"1689:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":114,"mutability":"mutable","name":"p1","nameLocation":"1712:2:0","nodeType":"VariableDeclaration","scope":127,"src":"1707:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":113,"name":"bool","nodeType":"ElementaryTypeName","src":"1707:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1688:27:0"},"returnParameters":{"id":116,"nodeType":"ParameterList","parameters":[],"src":"1730:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":144,"nodeType":"FunctionDefinition","src":"1821:145:0","nodes":[],"body":{"id":143,"nodeType":"Block","src":"1878:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":137,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1928:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":138,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":129,"src":"1951:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":139,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":131,"src":"1955:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":135,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1904:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":136,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1904:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":140,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1904:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":134,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1888:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":141,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1888:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":142,"nodeType":"ExpressionStatement","src":"1888:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1830:3:0","parameters":{"id":132,"nodeType":"ParameterList","parameters":[{"constant":false,"id":129,"mutability":"mutable","name":"p0","nameLocation":"1848:2:0","nodeType":"VariableDeclaration","scope":144,"src":"1834:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":128,"name":"string","nodeType":"ElementaryTypeName","src":"1834:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":131,"mutability":"mutable","name":"p1","nameLocation":"1860:2:0","nodeType":"VariableDeclaration","scope":144,"src":"1852:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":130,"name":"uint256","nodeType":"ElementaryTypeName","src":"1852:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1833:30:0"},"returnParameters":{"id":133,"nodeType":"ParameterList","parameters":[],"src":"1878:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":161,"nodeType":"FunctionDefinition","src":"1972:145:0","nodes":[],"body":{"id":160,"nodeType":"Block","src":"2029:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":154,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2079:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":155,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":146,"src":"2102:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":156,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":148,"src":"2106:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":152,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2055:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":153,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2055:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":157,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2055:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":151,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"2039:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":158,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2039:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":159,"nodeType":"ExpressionStatement","src":"2039:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1981:3:0","parameters":{"id":149,"nodeType":"ParameterList","parameters":[{"constant":false,"id":146,"mutability":"mutable","name":"p0","nameLocation":"1999:2:0","nodeType":"VariableDeclaration","scope":161,"src":"1985:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":145,"name":"string","nodeType":"ElementaryTypeName","src":"1985:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":148,"mutability":"mutable","name":"p1","nameLocation":"2011:2:0","nodeType":"VariableDeclaration","scope":161,"src":"2003:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":147,"name":"address","nodeType":"ElementaryTypeName","src":"2003:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1984:30:0"},"returnParameters":{"id":150,"nodeType":"ParameterList","parameters":[],"src":"2029:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":181,"nodeType":"FunctionDefinition","src":"2123:179:0","nodes":[],"body":{"id":180,"nodeType":"Block","src":"2204:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":173,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2254:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":174,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":163,"src":"2283:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":175,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":165,"src":"2287:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":176,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":167,"src":"2291:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":171,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2230:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":172,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2230:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":177,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2230:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":170,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"2214:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":178,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2214:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":179,"nodeType":"ExpressionStatement","src":"2214:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2132:3:0","parameters":{"id":168,"nodeType":"ParameterList","parameters":[{"constant":false,"id":163,"mutability":"mutable","name":"p0","nameLocation":"2150:2:0","nodeType":"VariableDeclaration","scope":181,"src":"2136:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":162,"name":"string","nodeType":"ElementaryTypeName","src":"2136:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":165,"mutability":"mutable","name":"p1","nameLocation":"2168:2:0","nodeType":"VariableDeclaration","scope":181,"src":"2154:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":164,"name":"string","nodeType":"ElementaryTypeName","src":"2154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":167,"mutability":"mutable","name":"p2","nameLocation":"2186:2:0","nodeType":"VariableDeclaration","scope":181,"src":"2172:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":166,"name":"string","nodeType":"ElementaryTypeName","src":"2172:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2135:54:0"},"returnParameters":{"id":169,"nodeType":"ParameterList","parameters":[],"src":"2204:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[182],"name":"console","nameLocation":"690:7:0","scope":538,"usedErrors":[]},{"id":537,"nodeType":"ContractDefinition","src":"2432:2531:0","nodes":[{"id":197,"nodeType":"VariableDeclaration","src":"2462:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2488:10:0","scope":537,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":184,"name":"address","nodeType":"ElementaryTypeName","src":"2462:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":192,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2535:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":191,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2525:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":193,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2525:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":190,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2517:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":189,"name":"uint256","nodeType":"ElementaryTypeName","src":"2517:7:0","typeDescriptions":{}}},"id":194,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2517:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":188,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2509:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":187,"name":"uint160","nodeType":"ElementaryTypeName","src":"2509:7:0","typeDescriptions":{}}},"id":195,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2509:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":186,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2501:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":185,"name":"address","nodeType":"ElementaryTypeName","src":"2501:7:0","typeDescriptions":{}}},"id":196,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2501:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":203,"nodeType":"VariableDeclaration","src":"2562:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2583:2:0","scope":537,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"},"typeName":{"id":199,"nodeType":"UserDefinedTypeName","pathNode":{"id":198,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":45,"src":"2562:2:0"},"referencedDeclaration":45,"src":"2562:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"value":{"arguments":[{"id":201,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":197,"src":"2591:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":200,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":45,"src":"2588:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$45_$","typeString":"type(contract Vm)"}},"id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2588:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"visibility":"internal"},{"id":205,"nodeType":"VariableDeclaration","src":"2666:22:0","nodes":[],"constant":false,"functionSelector":"61bc221a","mutability":"mutable","name":"counter","nameLocation":"2681:7:0","scope":537,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":204,"name":"uint256","nodeType":"ElementaryTypeName","src":"2666:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":368,"nodeType":"FunctionDefinition","src":"2778:949:0","nodes":[],"body":{"id":367,"nodeType":"Block","src":"2800:927:0","nodes":[],"statements":[{"assignments":[210],"declarations":[{"constant":false,"id":210,"mutability":"mutable","name":"x","nameLocation":"2815:1:0","nodeType":"VariableDeclaration","scope":367,"src":"2810:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":209,"name":"bool","nodeType":"ElementaryTypeName","src":"2810:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":216,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":213,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2828:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":214,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2844:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":211,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"2819:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":212,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2819:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":215,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2819:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2810:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":220,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2872:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":221,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":210,"src":"2895:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":217,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"2860:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":219,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":127,"src":"2860:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":222,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2860:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":223,"nodeType":"ExpressionStatement","src":"2860:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":227,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2920:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":230,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"2945:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}],"id":229,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2937:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":228,"name":"address","nodeType":"ElementaryTypeName","src":"2937:7:0","typeDescriptions":{}}},"id":231,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2937:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":224,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"2908:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":226,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"2908:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2908:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":233,"nodeType":"ExpressionStatement","src":"2908:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":237,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2973:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":242,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3011:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}],"id":241,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3003:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":240,"name":"address","nodeType":"ElementaryTypeName","src":"3003:7:0","typeDescriptions":{}}},"id":243,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3003:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":238,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"2991:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":239,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"2991:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":244,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2991:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":234,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"2961:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":236,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":144,"src":"2961:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":245,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2961:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":246,"nodeType":"ExpressionStatement","src":"2961:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":250,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3040:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":253,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3063:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":254,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3063:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":252,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3055:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":251,"name":"address","nodeType":"ElementaryTypeName","src":"3055:7:0","typeDescriptions":{}}},"id":255,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3055:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":247,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3028:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"3028:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":256,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3028:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":257,"nodeType":"ExpressionStatement","src":"3028:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":261,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3097:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":266,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3133:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":267,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3133:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":265,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3125:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":264,"name":"address","nodeType":"ElementaryTypeName","src":"3125:7:0","typeDescriptions":{}}},"id":268,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3125:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":262,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3113:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":263,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3113:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":269,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3113:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":258,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3085:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":260,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":144,"src":"3085:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":270,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3085:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":271,"nodeType":"ExpressionStatement","src":"3085:61:0"},{"assignments":[273],"declarations":[{"constant":false,"id":273,"mutability":"mutable","name":"json","nameLocation":"3171:4:0","nodeType":"VariableDeclaration","scope":367,"src":"3157:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":272,"name":"string","nodeType":"ElementaryTypeName","src":"3157:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":275,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":274,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3178:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"3157:55:0"},{"assignments":[280],"declarations":[{"constant":false,"id":280,"mutability":"mutable","name":"keys","nameLocation":"3238:4:0","nodeType":"VariableDeclaration","scope":367,"src":"3222:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":278,"name":"string","nodeType":"ElementaryTypeName","src":"3222:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":279,"nodeType":"ArrayTypeName","src":"3222:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":286,"initialValue":{"arguments":[{"id":283,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":273,"src":"3262:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3268:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":281,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3245:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":282,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3245:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":285,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3245:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3222:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":290,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3305:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":291,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":280,"src":"3313:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":293,"indexExpression":{"hexValue":"30","id":292,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3318:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3313:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":294,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":280,"src":"3322:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":296,"indexExpression":{"hexValue":"31","id":295,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3327:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3322:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":287,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3293:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":289,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":181,"src":"3293:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":297,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3293:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":298,"nodeType":"ExpressionStatement","src":"3293:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3352:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":299,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3341:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":301,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3341:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":303,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3341:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":304,"nodeType":"ExpressionStatement","src":"3341:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":312,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3408:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":311,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3400:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":310,"name":"uint160","nodeType":"ElementaryTypeName","src":"3400:7:0","typeDescriptions":{}}},"id":313,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3400:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":309,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3392:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":308,"name":"address","nodeType":"ElementaryTypeName","src":"3392:7:0","typeDescriptions":{}}},"id":314,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3392:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":305,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3378:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":307,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3378:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":315,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3378:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":316,"nodeType":"ExpressionStatement","src":"3378:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":320,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3436:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":317,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3425:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":319,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3425:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":321,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3425:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":322,"nodeType":"ExpressionStatement","src":"3425:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":326,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3473:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":329,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3508:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":330,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3508:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":328,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3500:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":327,"name":"address","nodeType":"ElementaryTypeName","src":"3500:7:0","typeDescriptions":{}}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3500:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":323,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3461:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"3461:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":332,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3461:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":333,"nodeType":"ExpressionStatement","src":"3461:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":337,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3542:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":340,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3580:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}],"id":339,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3572:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":338,"name":"address","nodeType":"ElementaryTypeName","src":"3572:7:0","typeDescriptions":{}}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3572:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":334,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3530:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":336,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"3530:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3530:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3530:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3607:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":344,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3596:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3596:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":348,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3596:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":349,"nodeType":"ExpressionStatement","src":"3596:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":350,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3632:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3632:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":353,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3632:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":354,"nodeType":"ExpressionStatement","src":"3632:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":358,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3667:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":355,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3656:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":357,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3656:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":359,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3656:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":360,"nodeType":"ExpressionStatement","src":"3656:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":364,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3712:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":361,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3700:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":363,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"3700:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":365,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3700:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":366,"nodeType":"ExpressionStatement","src":"3700:20:0"}]},"documentation":{"id":206,"nodeType":"StructuredDocumentation","src":"2695:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2787:3:0","parameters":{"id":207,"nodeType":"ParameterList","parameters":[],"src":"2790:2:0"},"returnParameters":{"id":208,"nodeType":"ParameterList","parameters":[],"src":"2800:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":452,"nodeType":"FunctionDefinition","src":"3794:520:0","nodes":[],"body":{"id":451,"nodeType":"Block","src":"3825:489:0","nodes":[],"statements":[{"expression":{"arguments":[{"hexValue":"74657374696e672073696e676c65","id":375,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3847:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""},"value":"testing single"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""}],"expression":{"id":372,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3835:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":374,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"3835:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":376,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3835:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":377,"nodeType":"ExpressionStatement","src":"3835:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":378,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3874:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":380,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"3874:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":381,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3874:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":382,"nodeType":"ExpressionStatement","src":"3874:14:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c31","id":386,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3909:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""},"value":"single_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""}],"expression":{"id":383,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3898:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":385,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":491,"src":"3898:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":387,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3898:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":388,"nodeType":"ExpressionStatement","src":"3898:26:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c32","id":392,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3945:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""},"value":"single_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""}],"expression":{"id":389,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3934:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":391,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":506,"src":"3934:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":393,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3934:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":394,"nodeType":"ExpressionStatement","src":"3934:26:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073746172742f73746f70","id":398,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3983:20:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""},"value":"testing start/stop"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""}],"expression":{"id":395,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3971:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":397,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"3971:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":399,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3971:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":400,"nodeType":"ExpressionStatement","src":"3971:33:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":401,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4014:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":403,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":41,"src":"4014:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":404,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4014:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":405,"nodeType":"ExpressionStatement","src":"4014:19:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c31","id":409,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4054:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""},"value":"startstop_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""}],"expression":{"id":406,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4043:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":408,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":491,"src":"4043:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":410,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4043:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":411,"nodeType":"ExpressionStatement","src":"4043:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c32","id":415,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4093:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""},"value":"startstop_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""}],"expression":{"id":412,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4082:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":414,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":506,"src":"4082:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":416,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4082:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":417,"nodeType":"ExpressionStatement","src":"4082:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":418,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4121:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":420,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":44,"src":"4121:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":421,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4121:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":422,"nodeType":"ExpressionStatement","src":"4121:18:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c33","id":426,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4160:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""},"value":"startstop_call3"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""}],"expression":{"id":423,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4149:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":425,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":491,"src":"4149:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":427,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4149:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":428,"nodeType":"ExpressionStatement","src":"4149:29:0"},{"expression":{"arguments":[{"hexValue":"74657374696e67206e6573746564","id":432,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4201:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""},"value":"testing nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""}],"expression":{"id":429,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4189:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":431,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4189:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":433,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4189:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":434,"nodeType":"ExpressionStatement","src":"4189:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":435,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4228:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":437,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":41,"src":"4228:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":438,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4228:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":439,"nodeType":"ExpressionStatement","src":"4228:19:0"},{"expression":{"arguments":[{"hexValue":"6e6573746564","id":443,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4270:8:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""},"value":"nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""}],"expression":{"id":440,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4257:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":442,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested1","nodeType":"MemberAccess","referencedDeclaration":521,"src":"4257:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":444,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4257:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":445,"nodeType":"ExpressionStatement","src":"4257:22:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":446,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4289:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":448,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":44,"src":"4289:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":449,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4289:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":450,"nodeType":"ExpressionStatement","src":"4289:18:0"}]},"documentation":{"id":369,"nodeType":"StructuredDocumentation","src":"3733:56:0","text":"@notice example function, to test vm.broadcast with."},"functionSelector":"bef03abc","implemented":true,"kind":"function","modifiers":[],"name":"runBroadcast","nameLocation":"3803:12:0","parameters":{"id":370,"nodeType":"ParameterList","parameters":[],"src":"3815:2:0"},"returnParameters":{"id":371,"nodeType":"ParameterList","parameters":[],"src":"3825:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":476,"nodeType":"FunctionDefinition","src":"4409:143:0","nodes":[],"body":{"id":475,"nodeType":"Block","src":"4458:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":461,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":455,"src":"4480:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":458,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4468:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":460,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4468:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":462,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4468:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":463,"nodeType":"ExpressionStatement","src":"4468:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":467,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4505:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":470,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"4533:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":471,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"4533:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":469,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4525:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":468,"name":"address","nodeType":"ElementaryTypeName","src":"4525:7:0","typeDescriptions":{}}},"id":472,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4525:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":464,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4493:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":466,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"4493:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":473,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4493:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":474,"nodeType":"ExpressionStatement","src":"4493:52:0"}]},"documentation":{"id":453,"nodeType":"StructuredDocumentation","src":"4320:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"4418:5:0","parameters":{"id":456,"nodeType":"ParameterList","parameters":[{"constant":false,"id":455,"mutability":"mutable","name":"_v","nameLocation":"4440:2:0","nodeType":"VariableDeclaration","scope":476,"src":"4424:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":454,"name":"string","nodeType":"ElementaryTypeName","src":"4424:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4423:20:0"},"returnParameters":{"id":457,"nodeType":"ParameterList","parameters":[],"src":"4458:0:0"},"scope":537,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":491,"nodeType":"FunctionDefinition","src":"4558:95:0","nodes":[],"body":{"id":490,"nodeType":"Block","src":"4602:51:0","nodes":[],"statements":[{"expression":{"id":482,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4612:9:0","subExpression":{"id":481,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4612:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":483,"nodeType":"ExpressionStatement","src":"4612:9:0"},{"expression":{"arguments":[{"id":487,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":478,"src":"4643:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":484,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4631:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":486,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4631:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":488,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4631:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":489,"nodeType":"ExpressionStatement","src":"4631:15:0"}]},"functionSelector":"7e79255d","implemented":true,"kind":"function","modifiers":[],"name":"call1","nameLocation":"4567:5:0","parameters":{"id":479,"nodeType":"ParameterList","parameters":[{"constant":false,"id":478,"mutability":"mutable","name":"_v","nameLocation":"4589:2:0","nodeType":"VariableDeclaration","scope":491,"src":"4573:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":477,"name":"string","nodeType":"ElementaryTypeName","src":"4573:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4572:20:0"},"returnParameters":{"id":480,"nodeType":"ParameterList","parameters":[],"src":"4602:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":506,"nodeType":"FunctionDefinition","src":"4659:95:0","nodes":[],"body":{"id":505,"nodeType":"Block","src":"4703:51:0","nodes":[],"statements":[{"expression":{"id":497,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4713:9:0","subExpression":{"id":496,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4713:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":498,"nodeType":"ExpressionStatement","src":"4713:9:0"},{"expression":{"arguments":[{"id":502,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":493,"src":"4744:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":499,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4732:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":501,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4732:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":503,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4732:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":504,"nodeType":"ExpressionStatement","src":"4732:15:0"}]},"functionSelector":"8d3ef7ca","implemented":true,"kind":"function","modifiers":[],"name":"call2","nameLocation":"4668:5:0","parameters":{"id":494,"nodeType":"ParameterList","parameters":[{"constant":false,"id":493,"mutability":"mutable","name":"_v","nameLocation":"4690:2:0","nodeType":"VariableDeclaration","scope":506,"src":"4674:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":492,"name":"string","nodeType":"ElementaryTypeName","src":"4674:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4673:20:0"},"returnParameters":{"id":495,"nodeType":"ParameterList","parameters":[],"src":"4703:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":521,"nodeType":"FunctionDefinition","src":"4760:98:0","nodes":[],"body":{"id":520,"nodeType":"Block","src":"4806:52:0","nodes":[],"statements":[{"expression":{"id":512,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4816:9:0","subExpression":{"id":511,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4816:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":513,"nodeType":"ExpressionStatement","src":"4816:9:0"},{"expression":{"arguments":[{"id":517,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":508,"src":"4848:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":514,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4835:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":516,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested2","nodeType":"MemberAccess","referencedDeclaration":536,"src":"4835:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":518,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4835:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":519,"nodeType":"ExpressionStatement","src":"4835:16:0"}]},"functionSelector":"a76ccdfa","implemented":true,"kind":"function","modifiers":[],"name":"nested1","nameLocation":"4769:7:0","parameters":{"id":509,"nodeType":"ParameterList","parameters":[{"constant":false,"id":508,"mutability":"mutable","name":"_v","nameLocation":"4793:2:0","nodeType":"VariableDeclaration","scope":521,"src":"4777:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":507,"name":"string","nodeType":"ElementaryTypeName","src":"4777:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4776:20:0"},"returnParameters":{"id":510,"nodeType":"ParameterList","parameters":[],"src":"4806:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":536,"nodeType":"FunctionDefinition","src":"4864:97:0","nodes":[],"body":{"id":535,"nodeType":"Block","src":"4910:51:0","nodes":[],"statements":[{"expression":{"id":527,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4920:9:0","subExpression":{"id":526,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4920:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":528,"nodeType":"ExpressionStatement","src":"4920:9:0"},{"expression":{"arguments":[{"id":532,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":523,"src":"4951:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":529,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4939:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":531,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4939:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":533,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4939:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":534,"nodeType":"ExpressionStatement","src":"4939:15:0"}]},"functionSelector":"dbf1282f","implemented":true,"kind":"function","modifiers":[],"name":"nested2","nameLocation":"4873:7:0","parameters":{"id":524,"nodeType":"ParameterList","parameters":[{"constant":false,"id":523,"mutability":"mutable","name":"_v","nameLocation":"4897:2:0","nodeType":"VariableDeclaration","scope":536,"src":"4881:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":522,"name":"string","nodeType":"ElementaryTypeName","src":"4881:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4880:20:0"},"returnParameters":{"id":525,"nodeType":"ParameterList","parameters":[],"src":"4910:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[],"contractKind":"contract","documentation":{"id":183,"nodeType":"StructuredDocumentation","src":"2306:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[537],"name":"ScriptExample","nameLocation":"2441:13:0","scope":538,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file +{"abi":[{"type":"function","name":"broadcast","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"broadcast","inputs":[{"name":"msgSender","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"envOr","inputs":[{"name":"name","type":"string","internalType":"string"},{"name":"defaultValue","type":"bool","internalType":"bool"}],"outputs":[{"name":"value","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"getNonce","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"nonce","type":"uint64","internalType":"uint64"}],"stateMutability":"view"},{"type":"function","name":"parseJsonKeys","inputs":[{"name":"json","type":"string","internalType":"string"},{"name":"key","type":"string","internalType":"string"}],"outputs":[{"name":"keys","type":"string[]","internalType":"string[]"}],"stateMutability":"pure"},{"type":"function","name":"startBroadcast","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"startBroadcast","inputs":[{"name":"msgSender","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"startPrank","inputs":[{"name":"msgSender","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"stopBroadcast","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"stopPrank","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{"broadcast()":"afc98040","broadcast(address)":"e6962cdb","envOr(string,bool)":"4777f3cf","getNonce(address)":"2d0335ab","parseJsonKeys(string,string)":"213e4198","startBroadcast()":"7fb5297f","startBroadcast(address)":"7fec2a8d","startPrank(address)":"06447d56","stopBroadcast()":"76eadd36","stopPrank()":"90c5013b"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"broadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"msgSender\",\"type\":\"address\"}],\"name\":\"broadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"defaultValue\",\"type\":\"bool\"}],\"name\":\"envOr\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"json\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"}],\"name\":\"parseJsonKeys\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"keys\",\"type\":\"string[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startBroadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"msgSender\",\"type\":\"address\"}],\"name\":\"startBroadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"msgSender\",\"type\":\"address\"}],\"name\":\"startPrank\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stopBroadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stopPrank\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"Vm\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x4fc2ffeba31e146fc3a2edef7cc8b7e82fb2344454d32d6371a62c6d76dfcb4e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a517c69eba90ee5f3efb198a2247d5744bed8e17d332ce2dda4d3cf3a2c334f9\",\"dweb:/ipfs/QmciXeDt5EEhmjH5xECVk2VX6EbnER5UFv58dvGgemwkKK\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"broadcast"},{"inputs":[{"internalType":"address","name":"msgSender","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"broadcast"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"bool","name":"defaultValue","type":"bool"}],"stateMutability":"view","type":"function","name":"envOr","outputs":[{"internalType":"bool","name":"value","type":"bool"}]},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"stateMutability":"view","type":"function","name":"getNonce","outputs":[{"internalType":"uint64","name":"nonce","type":"uint64"}]},{"inputs":[{"internalType":"string","name":"json","type":"string"},{"internalType":"string","name":"key","type":"string"}],"stateMutability":"pure","type":"function","name":"parseJsonKeys","outputs":[{"internalType":"string[]","name":"keys","type":"string[]"}]},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"startBroadcast"},{"inputs":[{"internalType":"address","name":"msgSender","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"startBroadcast"},{"inputs":[{"internalType":"address","name":"msgSender","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"startPrank"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"stopBroadcast"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"stopPrank"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"Vm"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x4fc2ffeba31e146fc3a2edef7cc8b7e82fb2344454d32d6371a62c6d76dfcb4e","urls":["bzz-raw://a517c69eba90ee5f3efb198a2247d5744bed8e17d332ce2dda4d3cf3a2c334f9","dweb:/ipfs/QmciXeDt5EEhmjH5xECVk2VX6EbnER5UFv58dvGgemwkKK"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[],"types":{}},"userdoc":{"version":1,"kind":"user"},"devdoc":{"version":1,"kind":"dev"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":677,"exportedSymbols":{"FooBar":[676],"ScriptExample":[663],"Vm":[55],"console":[192]},"nodeType":"SourceUnit","src":"32:5697:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":55,"nodeType":"ContractDefinition","src":"120:616:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":55,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":38,"nodeType":"FunctionDefinition","src":"516:30:0","nodes":[],"functionSelector":"afc98040","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"525:9:0","parameters":{"id":36,"nodeType":"ParameterList","parameters":[],"src":"534:2:0"},"returnParameters":{"id":37,"nodeType":"ParameterList","parameters":[],"src":"545:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":43,"nodeType":"FunctionDefinition","src":"551:47:0","nodes":[],"functionSelector":"e6962cdb","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"560:9:0","parameters":{"id":41,"nodeType":"ParameterList","parameters":[{"constant":false,"id":40,"mutability":"mutable","name":"msgSender","nameLocation":"578:9:0","nodeType":"VariableDeclaration","scope":43,"src":"570:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":39,"name":"address","nodeType":"ElementaryTypeName","src":"570:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"569:19:0"},"returnParameters":{"id":42,"nodeType":"ParameterList","parameters":[],"src":"597:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":48,"nodeType":"FunctionDefinition","src":"603:52:0","nodes":[],"functionSelector":"7fec2a8d","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"612:14:0","parameters":{"id":46,"nodeType":"ParameterList","parameters":[{"constant":false,"id":45,"mutability":"mutable","name":"msgSender","nameLocation":"635:9:0","nodeType":"VariableDeclaration","scope":48,"src":"627:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":44,"name":"address","nodeType":"ElementaryTypeName","src":"627:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"626:19:0"},"returnParameters":{"id":47,"nodeType":"ParameterList","parameters":[],"src":"654:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":51,"nodeType":"FunctionDefinition","src":"660:35:0","nodes":[],"functionSelector":"7fb5297f","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"669:14:0","parameters":{"id":49,"nodeType":"ParameterList","parameters":[],"src":"683:2:0"},"returnParameters":{"id":50,"nodeType":"ParameterList","parameters":[],"src":"694:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":54,"nodeType":"FunctionDefinition","src":"700:34:0","nodes":[],"functionSelector":"76eadd36","implemented":false,"kind":"function","modifiers":[],"name":"stopBroadcast","nameLocation":"709:13:0","parameters":{"id":52,"nodeType":"ParameterList","parameters":[],"src":"722:2:0"},"returnParameters":{"id":53,"nodeType":"ParameterList","parameters":[],"src":"733:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[55],"name":"Vm","nameLocation":"130:2:0","scope":677,"usedErrors":[]},{"id":192,"nodeType":"ContractDefinition","src":"791:1622:0","nodes":[{"id":61,"nodeType":"VariableDeclaration","src":"813:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"830:15:0","scope":192,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":56,"name":"address","nodeType":"ElementaryTypeName","src":"813:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":59,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"856:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":58,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"848:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":57,"name":"address","nodeType":"ElementaryTypeName","src":"848:7:0","typeDescriptions":{}}},"id":60,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"848:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":78,"nodeType":"FunctionDefinition","src":"906:221:0","nodes":[],"body":{"id":77,"nodeType":"Block","src":"1065:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"1084:37:0","statements":[{"nodeType":"YulAssignment","src":"1098:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"1107:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"1098:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":67,"isOffset":false,"isSlot":false,"src":"1107:4:0","valueSize":1},{"declaration":74,"isOffset":false,"isSlot":false,"src":"1098:5:0","valueSize":1}],"id":76,"nodeType":"InlineAssembly","src":"1075:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"915:25:0","parameters":{"id":68,"nodeType":"ParameterList","parameters":[{"constant":false,"id":67,"mutability":"mutable","name":"fnIn","nameLocation":"987:4:0","nodeType":"VariableDeclaration","scope":78,"src":"950:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":66,"nodeType":"FunctionTypeName","parameterTypes":{"id":64,"nodeType":"ParameterList","parameters":[{"constant":false,"id":63,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":66,"src":"959:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":62,"name":"bytes","nodeType":"ElementaryTypeName","src":"959:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"958:14:0"},"returnParameterTypes":{"id":65,"nodeType":"ParameterList","parameters":[],"src":"987:0:0"},"src":"950:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"940:57:0"},"returnParameters":{"id":75,"nodeType":"ParameterList","parameters":[{"constant":false,"id":74,"mutability":"mutable","name":"fnOut","nameLocation":"1058:5:0","nodeType":"VariableDeclaration","scope":78,"src":"1021:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":73,"nodeType":"FunctionTypeName","parameterTypes":{"id":71,"nodeType":"ParameterList","parameters":[{"constant":false,"id":70,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":73,"src":"1030:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":69,"name":"bytes","nodeType":"ElementaryTypeName","src":"1030:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1029:14:0"},"returnParameterTypes":{"id":72,"nodeType":"ParameterList","parameters":[],"src":"1058:0:0"},"src":"1021:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"1020:44:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":90,"nodeType":"FunctionDefinition","src":"1133:133:0","nodes":[],"body":{"id":89,"nodeType":"Block","src":"1194:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":86,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1251:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":84,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":106,"src":"1230:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":83,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":78,"src":"1204:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":85,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":87,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":88,"nodeType":"ExpressionStatement","src":"1204:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"1142:15:0","parameters":{"id":81,"nodeType":"ParameterList","parameters":[{"constant":false,"id":80,"mutability":"mutable","name":"payload","nameLocation":"1171:7:0","nodeType":"VariableDeclaration","scope":90,"src":"1158:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":79,"name":"bytes","nodeType":"ElementaryTypeName","src":"1158:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1157:22:0"},"returnParameters":{"id":82,"nodeType":"ParameterList","parameters":[],"src":"1194:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":106,"nodeType":"FunctionDefinition","src":"1272:380:0","nodes":[],"body":{"id":105,"nodeType":"Block","src":"1336:316:0","nodes":[],"statements":[{"assignments":[96],"declarations":[{"constant":false,"id":96,"mutability":"mutable","name":"payloadLength","nameLocation":"1354:13:0","nodeType":"VariableDeclaration","scope":105,"src":"1346:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":95,"name":"uint256","nodeType":"ElementaryTypeName","src":"1346:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":99,"initialValue":{"expression":{"id":97,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":92,"src":"1370:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":98,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1370:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1346:38:0"},{"assignments":[101],"declarations":[{"constant":false,"id":101,"mutability":"mutable","name":"consoleAddress","nameLocation":"1402:14:0","nodeType":"VariableDeclaration","scope":105,"src":"1394:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":100,"name":"address","nodeType":"ElementaryTypeName","src":"1394:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":103,"initialValue":{"id":102,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":61,"src":"1419:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1394:40:0"},{"AST":{"nodeType":"YulBlock","src":"1496:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1510:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1534:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1543:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1530:3:0"},"nodeType":"YulFunctionCall","src":"1530:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1514:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1559:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1579:3:0"},"nodeType":"YulFunctionCall","src":"1579:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1586:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1602:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1616:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1631:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1634:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1568:10:0"},"nodeType":"YulFunctionCall","src":"1568:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1563:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":101,"isOffset":false,"isSlot":false,"src":"1586:14:0","valueSize":1},{"declaration":92,"isOffset":false,"isSlot":false,"src":"1534:7:0","valueSize":1},{"declaration":96,"isOffset":false,"isSlot":false,"src":"1616:13:0","valueSize":1}],"id":104,"nodeType":"InlineAssembly","src":"1487:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1281:19:0","parameters":{"id":93,"nodeType":"ParameterList","parameters":[{"constant":false,"id":92,"mutability":"mutable","name":"payload","nameLocation":"1314:7:0","nodeType":"VariableDeclaration","scope":106,"src":"1301:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":91,"name":"bytes","nodeType":"ElementaryTypeName","src":"1301:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1300:22:0"},"returnParameters":{"id":94,"nodeType":"ParameterList","parameters":[],"src":"1336:0:0"},"scope":192,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":120,"nodeType":"FunctionDefinition","src":"1658:121:0","nodes":[],"body":{"id":119,"nodeType":"Block","src":"1703:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":114,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1753:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":115,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":108,"src":"1768:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":112,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1729:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":113,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1729:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":116,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1729:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":111,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1713:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":117,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1713:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":118,"nodeType":"ExpressionStatement","src":"1713:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1667:3:0","parameters":{"id":109,"nodeType":"ParameterList","parameters":[{"constant":false,"id":108,"mutability":"mutable","name":"p0","nameLocation":"1685:2:0","nodeType":"VariableDeclaration","scope":120,"src":"1671:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":107,"name":"string","nodeType":"ElementaryTypeName","src":"1671:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1670:18:0"},"returnParameters":{"id":110,"nodeType":"ParameterList","parameters":[],"src":"1703:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":137,"nodeType":"FunctionDefinition","src":"1785:139:0","nodes":[],"body":{"id":136,"nodeType":"Block","src":"1839:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":130,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1889:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":131,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":122,"src":"1909:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":132,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":124,"src":"1913:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":128,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1865:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":129,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1865:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":133,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1865:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":127,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1849:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":134,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1849:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":135,"nodeType":"ExpressionStatement","src":"1849:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1794:3:0","parameters":{"id":125,"nodeType":"ParameterList","parameters":[{"constant":false,"id":122,"mutability":"mutable","name":"p0","nameLocation":"1812:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1798:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":121,"name":"string","nodeType":"ElementaryTypeName","src":"1798:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":124,"mutability":"mutable","name":"p1","nameLocation":"1821:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1816:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":123,"name":"bool","nodeType":"ElementaryTypeName","src":"1816:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1797:27:0"},"returnParameters":{"id":126,"nodeType":"ParameterList","parameters":[],"src":"1839:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":154,"nodeType":"FunctionDefinition","src":"1930:145:0","nodes":[],"body":{"id":153,"nodeType":"Block","src":"1987:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":147,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2037:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":148,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":139,"src":"2060:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":149,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":141,"src":"2064:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":145,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2013:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":146,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2013:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":150,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2013:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":144,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1997:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":151,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1997:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":152,"nodeType":"ExpressionStatement","src":"1997:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1939:3:0","parameters":{"id":142,"nodeType":"ParameterList","parameters":[{"constant":false,"id":139,"mutability":"mutable","name":"p0","nameLocation":"1957:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1943:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":138,"name":"string","nodeType":"ElementaryTypeName","src":"1943:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":141,"mutability":"mutable","name":"p1","nameLocation":"1969:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1961:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":140,"name":"uint256","nodeType":"ElementaryTypeName","src":"1961:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1942:30:0"},"returnParameters":{"id":143,"nodeType":"ParameterList","parameters":[],"src":"1987:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":171,"nodeType":"FunctionDefinition","src":"2081:145:0","nodes":[],"body":{"id":170,"nodeType":"Block","src":"2138:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":164,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2188:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":165,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":156,"src":"2211:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":166,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":158,"src":"2215:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":162,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2164:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":163,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2164:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":167,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2164:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":161,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2148:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":168,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2148:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":169,"nodeType":"ExpressionStatement","src":"2148:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2090:3:0","parameters":{"id":159,"nodeType":"ParameterList","parameters":[{"constant":false,"id":156,"mutability":"mutable","name":"p0","nameLocation":"2108:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2094:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":155,"name":"string","nodeType":"ElementaryTypeName","src":"2094:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":158,"mutability":"mutable","name":"p1","nameLocation":"2120:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2112:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":157,"name":"address","nodeType":"ElementaryTypeName","src":"2112:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"2093:30:0"},"returnParameters":{"id":160,"nodeType":"ParameterList","parameters":[],"src":"2138:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":191,"nodeType":"FunctionDefinition","src":"2232:179:0","nodes":[],"body":{"id":190,"nodeType":"Block","src":"2313:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":183,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2363:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":184,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2392:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":185,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":175,"src":"2396:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":186,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":177,"src":"2400:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":181,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2339:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":182,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2339:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":187,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2339:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":180,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2323:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":188,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2323:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":189,"nodeType":"ExpressionStatement","src":"2323:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2241:3:0","parameters":{"id":178,"nodeType":"ParameterList","parameters":[{"constant":false,"id":173,"mutability":"mutable","name":"p0","nameLocation":"2259:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2245:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":172,"name":"string","nodeType":"ElementaryTypeName","src":"2245:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":175,"mutability":"mutable","name":"p1","nameLocation":"2277:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2263:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":174,"name":"string","nodeType":"ElementaryTypeName","src":"2263:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":177,"mutability":"mutable","name":"p2","nameLocation":"2295:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2281:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":176,"name":"string","nodeType":"ElementaryTypeName","src":"2281:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2244:54:0"},"returnParameters":{"id":179,"nodeType":"ParameterList","parameters":[],"src":"2313:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[192],"name":"console","nameLocation":"799:7:0","scope":677,"usedErrors":[]},{"id":663,"nodeType":"ContractDefinition","src":"2541:3089:0","nodes":[{"id":207,"nodeType":"VariableDeclaration","src":"2571:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2597:10:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":194,"name":"address","nodeType":"ElementaryTypeName","src":"2571:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2644:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":201,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2634:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":203,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2634:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":200,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2626:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":199,"name":"uint256","nodeType":"ElementaryTypeName","src":"2626:7:0","typeDescriptions":{}}},"id":204,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2626:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":198,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2618:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":197,"name":"uint160","nodeType":"ElementaryTypeName","src":"2618:7:0","typeDescriptions":{}}},"id":205,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2618:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":196,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2610:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":195,"name":"address","nodeType":"ElementaryTypeName","src":"2610:7:0","typeDescriptions":{}}},"id":206,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2610:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":213,"nodeType":"VariableDeclaration","src":"2671:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2692:2:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"},"typeName":{"id":209,"nodeType":"UserDefinedTypeName","pathNode":{"id":208,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":55,"src":"2671:2:0"},"referencedDeclaration":55,"src":"2671:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"value":{"arguments":[{"id":211,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":207,"src":"2700:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":210,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":55,"src":"2697:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$55_$","typeString":"type(contract Vm)"}},"id":212,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2697:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"visibility":"internal"},{"id":215,"nodeType":"VariableDeclaration","src":"2775:22:0","nodes":[],"constant":false,"functionSelector":"61bc221a","mutability":"mutable","name":"counter","nameLocation":"2790:7:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":214,"name":"uint256","nodeType":"ElementaryTypeName","src":"2775:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":378,"nodeType":"FunctionDefinition","src":"2887:949:0","nodes":[],"body":{"id":377,"nodeType":"Block","src":"2909:927:0","nodes":[],"statements":[{"assignments":[220],"declarations":[{"constant":false,"id":220,"mutability":"mutable","name":"x","nameLocation":"2924:1:0","nodeType":"VariableDeclaration","scope":377,"src":"2919:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":219,"name":"bool","nodeType":"ElementaryTypeName","src":"2919:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":226,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":223,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2937:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":224,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2953:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":221,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"2928:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":222,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2928:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":225,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2928:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2919:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":230,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2981:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":231,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":220,"src":"3004:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":227,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"2969:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":229,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":137,"src":"2969:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2969:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":233,"nodeType":"ExpressionStatement","src":"2969:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":237,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3029:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":240,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3054:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":239,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3046:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":238,"name":"address","nodeType":"ElementaryTypeName","src":"3046:7:0","typeDescriptions":{}}},"id":241,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3046:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":234,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3017:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":236,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3017:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":242,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3017:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":243,"nodeType":"ExpressionStatement","src":"3017:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":247,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3082:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":252,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3120:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":251,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3112:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":250,"name":"address","nodeType":"ElementaryTypeName","src":"3112:7:0","typeDescriptions":{}}},"id":253,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3112:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":248,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3100:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3100:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":254,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3100:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":244,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3070:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":246,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3070:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":255,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3070:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":256,"nodeType":"ExpressionStatement","src":"3070:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":260,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3149:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":263,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3172:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":264,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3172:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":262,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3164:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":261,"name":"address","nodeType":"ElementaryTypeName","src":"3164:7:0","typeDescriptions":{}}},"id":265,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3164:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":257,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3137:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":259,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3137:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":266,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3137:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":267,"nodeType":"ExpressionStatement","src":"3137:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":271,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3206:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":276,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3242:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":277,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3242:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":275,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3234:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":274,"name":"address","nodeType":"ElementaryTypeName","src":"3234:7:0","typeDescriptions":{}}},"id":278,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3234:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":272,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3222:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":273,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3222:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":279,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3222:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":268,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3194:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":270,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3194:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":280,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3194:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":281,"nodeType":"ExpressionStatement","src":"3194:61:0"},{"assignments":[283],"declarations":[{"constant":false,"id":283,"mutability":"mutable","name":"json","nameLocation":"3280:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3266:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":282,"name":"string","nodeType":"ElementaryTypeName","src":"3266:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":285,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3287:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"3266:55:0"},{"assignments":[290],"declarations":[{"constant":false,"id":290,"mutability":"mutable","name":"keys","nameLocation":"3347:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3331:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":288,"name":"string","nodeType":"ElementaryTypeName","src":"3331:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":289,"nodeType":"ArrayTypeName","src":"3331:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":296,"initialValue":{"arguments":[{"id":293,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":283,"src":"3371:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":294,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3377:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":291,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3354:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":292,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3354:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":295,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3354:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3331:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":300,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3414:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":301,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3422:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":303,"indexExpression":{"hexValue":"30","id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3427:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3422:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":304,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3431:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":306,"indexExpression":{"hexValue":"31","id":305,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3436:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3431:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":297,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3402:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":299,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":191,"src":"3402:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":307,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3402:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":308,"nodeType":"ExpressionStatement","src":"3402:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":312,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3461:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":309,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3450:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":311,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3450:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":313,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3450:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":314,"nodeType":"ExpressionStatement","src":"3450:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":322,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3517:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":321,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3509:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":320,"name":"uint160","nodeType":"ElementaryTypeName","src":"3509:7:0","typeDescriptions":{}}},"id":323,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3509:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":319,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3501:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":318,"name":"address","nodeType":"ElementaryTypeName","src":"3501:7:0","typeDescriptions":{}}},"id":324,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3501:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":315,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3487:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":317,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3487:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3487:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":326,"nodeType":"ExpressionStatement","src":"3487:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":330,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3545:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":327,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3534:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":329,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3534:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3534:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":332,"nodeType":"ExpressionStatement","src":"3534:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":336,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3582:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":339,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3617:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":340,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3617:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":338,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3609:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":337,"name":"address","nodeType":"ElementaryTypeName","src":"3609:7:0","typeDescriptions":{}}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3609:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":333,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3570:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":335,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3570:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3570:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3570:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3651:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":350,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3689:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":349,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3681:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":348,"name":"address","nodeType":"ElementaryTypeName","src":"3681:7:0","typeDescriptions":{}}},"id":351,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3681:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":344,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3639:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3639:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3639:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":353,"nodeType":"ExpressionStatement","src":"3639:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":357,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3716:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":354,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3705:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":356,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3705:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":358,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3705:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":359,"nodeType":"ExpressionStatement","src":"3705:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":360,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3741:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":362,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3741:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":363,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3741:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":364,"nodeType":"ExpressionStatement","src":"3741:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":368,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3776:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":365,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3765:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":367,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3765:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":369,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3765:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":370,"nodeType":"ExpressionStatement","src":"3765:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":374,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3821:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":371,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3809:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":373,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"3809:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":375,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3809:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":376,"nodeType":"ExpressionStatement","src":"3809:20:0"}]},"documentation":{"id":216,"nodeType":"StructuredDocumentation","src":"2804:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2896:3:0","parameters":{"id":217,"nodeType":"ParameterList","parameters":[],"src":"2899:2:0"},"returnParameters":{"id":218,"nodeType":"ParameterList","parameters":[],"src":"2909:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":566,"nodeType":"FunctionDefinition","src":"3903:988:0","nodes":[],"body":{"id":565,"nodeType":"Block","src":"3934:957:0","nodes":[],"statements":[{"expression":{"arguments":[{"hexValue":"74657374696e672073696e676c65","id":385,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3956:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""},"value":"testing single"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""}],"expression":{"id":382,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3944:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":384,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"3944:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":386,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3944:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":387,"nodeType":"ExpressionStatement","src":"3944:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":388,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3983:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":390,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"3983:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":391,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3983:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":392,"nodeType":"ExpressionStatement","src":"3983:14:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c31","id":396,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4018:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""},"value":"single_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""}],"expression":{"id":393,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4007:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":395,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4007:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":397,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4007:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":398,"nodeType":"ExpressionStatement","src":"4007:26:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c32","id":402,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4054:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""},"value":"single_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""}],"expression":{"id":399,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4043:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":401,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":620,"src":"4043:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":403,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4043:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":404,"nodeType":"ExpressionStatement","src":"4043:26:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073746172742f73746f70","id":408,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4092:20:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""},"value":"testing start/stop"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""}],"expression":{"id":405,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4080:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":407,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4080:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":409,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4080:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":410,"nodeType":"ExpressionStatement","src":"4080:33:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078633066666565","id":418,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4157:8:0","typeDescriptions":{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"},"value":"0xc0ffee"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"}],"id":417,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4149:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":416,"name":"uint160","nodeType":"ElementaryTypeName","src":"4149:7:0","typeDescriptions":{}}},"id":419,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4149:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":415,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4141:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":414,"name":"address","nodeType":"ElementaryTypeName","src":"4141:7:0","typeDescriptions":{}}},"id":420,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4141:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":411,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4123:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":413,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4123:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":421,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4123:45:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":422,"nodeType":"ExpressionStatement","src":"4123:45:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c31","id":426,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4189:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""},"value":"startstop_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""}],"expression":{"id":423,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4178:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":425,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4178:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":427,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4178:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":428,"nodeType":"ExpressionStatement","src":"4178:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c32","id":432,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4228:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""},"value":"startstop_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""}],"expression":{"id":429,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4217:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":431,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":620,"src":"4217:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":433,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4217:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":434,"nodeType":"ExpressionStatement","src":"4217:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f70757265","id":438,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4270:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""},"value":"startstop_pure"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""}],"expression":{"id":435,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4256:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":437,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"callPure","nodeType":"MemberAccess","referencedDeclaration":662,"src":"4256:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure external"}},"id":439,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4256:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":440,"nodeType":"ExpressionStatement","src":"4256:31:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":441,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4297:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":443,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4297:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":444,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4297:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":445,"nodeType":"ExpressionStatement","src":"4297:18:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c33","id":449,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4336:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""},"value":"startstop_call3"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""}],"expression":{"id":446,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4325:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":448,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4325:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":450,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4325:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":451,"nodeType":"ExpressionStatement","src":"4325:29:0"},{"expression":{"arguments":[{"hexValue":"74657374696e67206e6573746564","id":455,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4377:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""},"value":"testing nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""}],"expression":{"id":452,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4365:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":454,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4365:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":456,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4365:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":457,"nodeType":"ExpressionStatement","src":"4365:29:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307831323334","id":465,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4438:6:0","typeDescriptions":{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"},"value":"0x1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"}],"id":464,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4430:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":463,"name":"uint160","nodeType":"ElementaryTypeName","src":"4430:7:0","typeDescriptions":{}}},"id":466,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4430:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":462,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4422:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":461,"name":"address","nodeType":"ElementaryTypeName","src":"4422:7:0","typeDescriptions":{}}},"id":467,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4422:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":458,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4404:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":460,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4404:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":468,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4404:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":469,"nodeType":"ExpressionStatement","src":"4404:43:0"},{"expression":{"arguments":[{"hexValue":"6e6573746564","id":473,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4470:8:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""},"value":"nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""}],"expression":{"id":470,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4457:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":472,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested1","nodeType":"MemberAccess","referencedDeclaration":635,"src":"4457:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":474,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4457:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":475,"nodeType":"ExpressionStatement","src":"4457:22:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":476,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4489:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":478,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4489:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":479,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4489:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":480,"nodeType":"ExpressionStatement","src":"4489:18:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206465706c6f796d656e74","id":484,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4530:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""},"value":"contract deployment"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""}],"expression":{"id":481,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4518:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":483,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4518:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":485,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4518:34:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":486,"nodeType":"ExpressionStatement","src":"4518:34:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078313233343536","id":494,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4591:8:0","typeDescriptions":{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"},"value":"0x123456"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"}],"id":493,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4583:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":492,"name":"uint160","nodeType":"ElementaryTypeName","src":"4583:7:0","typeDescriptions":{}}},"id":495,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4583:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":491,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4575:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":490,"name":"address","nodeType":"ElementaryTypeName","src":"4575:7:0","typeDescriptions":{}}},"id":496,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4575:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":487,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4562:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":489,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4562:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":497,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4562:40:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":498,"nodeType":"ExpressionStatement","src":"4562:40:0"},{"assignments":[501],"declarations":[{"constant":false,"id":501,"mutability":"mutable","name":"x","nameLocation":"4619:1:0","nodeType":"VariableDeclaration","scope":565,"src":"4612:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"},"typeName":{"id":500,"nodeType":"UserDefinedTypeName","pathNode":{"id":499,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4612:6:0"},"referencedDeclaration":676,"src":"4612:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"visibility":"internal"}],"id":507,"initialValue":{"arguments":[{"hexValue":"31323334","id":505,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4634:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":504,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4623:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":503,"nodeType":"UserDefinedTypeName","pathNode":{"id":502,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4627:6:0"},"referencedDeclaration":676,"src":"4627:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}}},"id":506,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4623:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4612:27:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":513,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":509,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":501,"src":"4657:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"id":510,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":665,"src":"4657:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":511,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4657:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":512,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4668:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4657:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":508,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4649:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":514,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4649:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":515,"nodeType":"ExpressionStatement","src":"4649:24:0"},{"expression":{"arguments":[{"hexValue":"6372656174652032","id":519,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4696:10:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""},"value":"create 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""}],"expression":{"id":516,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4684:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":518,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4684:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":520,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4684:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":521,"nodeType":"ExpressionStatement","src":"4684:23:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307863616665","id":529,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4746:6:0","typeDescriptions":{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"},"value":"0xcafe"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"}],"id":528,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4738:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":527,"name":"uint160","nodeType":"ElementaryTypeName","src":"4738:7:0","typeDescriptions":{}}},"id":530,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4738:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":526,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4730:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":525,"name":"address","nodeType":"ElementaryTypeName","src":"4730:7:0","typeDescriptions":{}}},"id":531,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4730:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":522,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4717:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":524,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4717:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":532,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4717:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":533,"nodeType":"ExpressionStatement","src":"4717:38:0"},{"assignments":[536],"declarations":[{"constant":false,"id":536,"mutability":"mutable","name":"y","nameLocation":"4772:1:0","nodeType":"VariableDeclaration","scope":565,"src":"4765:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"},"typeName":{"id":535,"nodeType":"UserDefinedTypeName","pathNode":{"id":534,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4765:6:0"},"referencedDeclaration":676,"src":"4765:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"visibility":"internal"}],"id":550,"initialValue":{"arguments":[{"hexValue":"31323334","id":548,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4815:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":539,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4776:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":538,"nodeType":"UserDefinedTypeName","pathNode":{"id":537,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4780:6:0"},"referencedDeclaration":676,"src":"4780:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}}},"id":547,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"names":["salt"],"nodeType":"FunctionCallOptions","options":[{"arguments":[{"arguments":[{"hexValue":"3432","id":544,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4809:2:0","typeDescriptions":{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"},"value":"42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"}],"id":543,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4801:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":542,"name":"uint256","nodeType":"ElementaryTypeName","src":"4801:7:0","typeDescriptions":{}}},"id":545,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4801:11:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":541,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4793:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_bytes32_$","typeString":"type(bytes32)"},"typeName":{"id":540,"name":"bytes32","nodeType":"ElementaryTypeName","src":"4793:7:0","typeDescriptions":{}}},"id":546,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4793:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"src":"4776:38:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$salt","typeString":"function (uint256) returns (contract FooBar)"}},"id":549,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4776:44:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4765:55:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":556,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":552,"name":"y","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":536,"src":"4838:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"id":553,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":665,"src":"4838:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":554,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4838:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":555,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4849:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4838:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":551,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4830:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":557,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4830:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":558,"nodeType":"ExpressionStatement","src":"4830:24:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":562,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4876:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":559,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4864:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":561,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4864:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":563,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4864:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":564,"nodeType":"ExpressionStatement","src":"4864:20:0"}]},"documentation":{"id":379,"nodeType":"StructuredDocumentation","src":"3842:56:0","text":"@notice example function, to test vm.broadcast with."},"functionSelector":"bef03abc","implemented":true,"kind":"function","modifiers":[],"name":"runBroadcast","nameLocation":"3912:12:0","parameters":{"id":380,"nodeType":"ParameterList","parameters":[],"src":"3924:2:0"},"returnParameters":{"id":381,"nodeType":"ParameterList","parameters":[],"src":"3934:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":590,"nodeType":"FunctionDefinition","src":"4986:143:0","nodes":[],"body":{"id":589,"nodeType":"Block","src":"5035:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":575,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":569,"src":"5057:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":572,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5045:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":574,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5045:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":576,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5045:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":577,"nodeType":"ExpressionStatement","src":"5045:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":581,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"5082:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":584,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"5110:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":585,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"5110:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":583,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5102:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":582,"name":"address","nodeType":"ElementaryTypeName","src":"5102:7:0","typeDescriptions":{}}},"id":586,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5102:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":578,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5070:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":580,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"5070:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":587,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5070:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":588,"nodeType":"ExpressionStatement","src":"5070:52:0"}]},"documentation":{"id":567,"nodeType":"StructuredDocumentation","src":"4897:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"4995:5:0","parameters":{"id":570,"nodeType":"ParameterList","parameters":[{"constant":false,"id":569,"mutability":"mutable","name":"_v","nameLocation":"5017:2:0","nodeType":"VariableDeclaration","scope":590,"src":"5001:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":568,"name":"string","nodeType":"ElementaryTypeName","src":"5001:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5000:20:0"},"returnParameters":{"id":571,"nodeType":"ParameterList","parameters":[],"src":"5035:0:0"},"scope":663,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":605,"nodeType":"FunctionDefinition","src":"5135:95:0","nodes":[],"body":{"id":604,"nodeType":"Block","src":"5179:51:0","nodes":[],"statements":[{"expression":{"id":596,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5189:9:0","subExpression":{"id":595,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5189:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":597,"nodeType":"ExpressionStatement","src":"5189:9:0"},{"expression":{"arguments":[{"id":601,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":592,"src":"5220:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":598,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5208:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":600,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5208:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":602,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5208:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":603,"nodeType":"ExpressionStatement","src":"5208:15:0"}]},"functionSelector":"7e79255d","implemented":true,"kind":"function","modifiers":[],"name":"call1","nameLocation":"5144:5:0","parameters":{"id":593,"nodeType":"ParameterList","parameters":[{"constant":false,"id":592,"mutability":"mutable","name":"_v","nameLocation":"5166:2:0","nodeType":"VariableDeclaration","scope":605,"src":"5150:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":591,"name":"string","nodeType":"ElementaryTypeName","src":"5150:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5149:20:0"},"returnParameters":{"id":594,"nodeType":"ParameterList","parameters":[],"src":"5179:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":620,"nodeType":"FunctionDefinition","src":"5236:95:0","nodes":[],"body":{"id":619,"nodeType":"Block","src":"5280:51:0","nodes":[],"statements":[{"expression":{"id":611,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5290:9:0","subExpression":{"id":610,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5290:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":612,"nodeType":"ExpressionStatement","src":"5290:9:0"},{"expression":{"arguments":[{"id":616,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":607,"src":"5321:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":613,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5309:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":615,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5309:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":617,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5309:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":618,"nodeType":"ExpressionStatement","src":"5309:15:0"}]},"functionSelector":"8d3ef7ca","implemented":true,"kind":"function","modifiers":[],"name":"call2","nameLocation":"5245:5:0","parameters":{"id":608,"nodeType":"ParameterList","parameters":[{"constant":false,"id":607,"mutability":"mutable","name":"_v","nameLocation":"5267:2:0","nodeType":"VariableDeclaration","scope":620,"src":"5251:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":606,"name":"string","nodeType":"ElementaryTypeName","src":"5251:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5250:20:0"},"returnParameters":{"id":609,"nodeType":"ParameterList","parameters":[],"src":"5280:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":635,"nodeType":"FunctionDefinition","src":"5337:98:0","nodes":[],"body":{"id":634,"nodeType":"Block","src":"5383:52:0","nodes":[],"statements":[{"expression":{"id":626,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5393:9:0","subExpression":{"id":625,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5393:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":627,"nodeType":"ExpressionStatement","src":"5393:9:0"},{"expression":{"arguments":[{"id":631,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":622,"src":"5425:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":628,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"5412:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":630,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested2","nodeType":"MemberAccess","referencedDeclaration":650,"src":"5412:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":632,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5412:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":633,"nodeType":"ExpressionStatement","src":"5412:16:0"}]},"functionSelector":"a76ccdfa","implemented":true,"kind":"function","modifiers":[],"name":"nested1","nameLocation":"5346:7:0","parameters":{"id":623,"nodeType":"ParameterList","parameters":[{"constant":false,"id":622,"mutability":"mutable","name":"_v","nameLocation":"5370:2:0","nodeType":"VariableDeclaration","scope":635,"src":"5354:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":621,"name":"string","nodeType":"ElementaryTypeName","src":"5354:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5353:20:0"},"returnParameters":{"id":624,"nodeType":"ParameterList","parameters":[],"src":"5383:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":650,"nodeType":"FunctionDefinition","src":"5441:97:0","nodes":[],"body":{"id":649,"nodeType":"Block","src":"5487:51:0","nodes":[],"statements":[{"expression":{"id":641,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5497:9:0","subExpression":{"id":640,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5497:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":642,"nodeType":"ExpressionStatement","src":"5497:9:0"},{"expression":{"arguments":[{"id":646,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":637,"src":"5528:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":643,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5516:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":645,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5516:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":647,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5516:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":648,"nodeType":"ExpressionStatement","src":"5516:15:0"}]},"functionSelector":"dbf1282f","implemented":true,"kind":"function","modifiers":[],"name":"nested2","nameLocation":"5450:7:0","parameters":{"id":638,"nodeType":"ParameterList","parameters":[{"constant":false,"id":637,"mutability":"mutable","name":"_v","nameLocation":"5474:2:0","nodeType":"VariableDeclaration","scope":650,"src":"5458:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":636,"name":"string","nodeType":"ElementaryTypeName","src":"5458:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5457:20:0"},"returnParameters":{"id":639,"nodeType":"ParameterList","parameters":[],"src":"5487:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":662,"nodeType":"FunctionDefinition","src":"5544:84:0","nodes":[],"body":{"id":661,"nodeType":"Block","src":"5596:32:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":658,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":652,"src":"5618:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":655,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5606:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":657,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5606:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":659,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5606:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":660,"nodeType":"ExpressionStatement","src":"5606:15:0"}]},"functionSelector":"7f8b915c","implemented":true,"kind":"function","modifiers":[],"name":"callPure","nameLocation":"5553:8:0","parameters":{"id":653,"nodeType":"ParameterList","parameters":[{"constant":false,"id":652,"mutability":"mutable","name":"_v","nameLocation":"5578:2:0","nodeType":"VariableDeclaration","scope":662,"src":"5562:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":651,"name":"string","nodeType":"ElementaryTypeName","src":"5562:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5561:20:0"},"returnParameters":{"id":654,"nodeType":"ParameterList","parameters":[],"src":"5596:0:0"},"scope":663,"stateMutability":"pure","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[676],"contractKind":"contract","documentation":{"id":193,"nodeType":"StructuredDocumentation","src":"2415:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[663],"name":"ScriptExample","nameLocation":"2550:13:0","scope":677,"usedErrors":[]},{"id":676,"nodeType":"ContractDefinition","src":"5632:96:0","nodes":[{"id":665,"nodeType":"VariableDeclaration","src":"5654:18:0","nodes":[],"constant":false,"functionSelector":"c2985578","mutability":"mutable","name":"foo","nameLocation":"5669:3:0","scope":676,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":664,"name":"uint256","nodeType":"ElementaryTypeName","src":"5654:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":675,"nodeType":"FunctionDefinition","src":"5679:47:0","nodes":[],"body":{"id":674,"nodeType":"Block","src":"5702:24:0","nodes":[],"statements":[{"expression":{"id":672,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":670,"name":"foo","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":665,"src":"5712:3:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":671,"name":"v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":667,"src":"5718:1:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5712:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":673,"nodeType":"ExpressionStatement","src":"5712:7:0"}]},"implemented":true,"kind":"constructor","modifiers":[],"name":"","nameLocation":"-1:-1:-1","parameters":{"id":668,"nodeType":"ParameterList","parameters":[{"constant":false,"id":667,"mutability":"mutable","name":"v","nameLocation":"5699:1:0","nodeType":"VariableDeclaration","scope":675,"src":"5691:9:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":666,"name":"uint256","nodeType":"ElementaryTypeName","src":"5691:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"5690:11:0"},"returnParameters":{"id":669,"nodeType":"ParameterList","parameters":[],"src":"5702:0:0"},"scope":676,"stateMutability":"nonpayable","virtual":false,"visibility":"public"}],"abstract":false,"baseContracts":[],"canonicalName":"FooBar","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[676],"name":"FooBar","nameLocation":"5641:6:0","scope":677,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file diff --git a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/console.json b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/console.json index 25387bcbbdbf..d051823361a1 100644 --- a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/console.json +++ b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/console.json @@ -1 +1 @@ -{"abi":[],"bytecode":{"object":"0x602d6037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300080f000a","sourceMap":"682:1622:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;682:1622:0;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300080f000a","sourceMap":"682:1622:0:-:0;;;;;;;;","linkReferences":{}},"methodIdentifiers":{},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"console\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x7727e5a55f4b3d442729483d41848c957b04027e48d972a568ee6f50aa3daa7a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4de8bd2d73869b583c44f8996ef56f872ce47499e801aa95da90a8e695196b00\",\"dweb:/ipfs/QmZzQy8ZSWuMnLBsGWTxUxZRhWGTJ8cq8yHpM59irYA2dw\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"console"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x7727e5a55f4b3d442729483d41848c957b04027e48d972a568ee6f50aa3daa7a","urls":["bzz-raw://4de8bd2d73869b583c44f8996ef56f872ce47499e801aa95da90a8e695196b00","dweb:/ipfs/QmZzQy8ZSWuMnLBsGWTxUxZRhWGTJ8cq8yHpM59irYA2dw"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[],"types":{}},"userdoc":{"version":1,"kind":"user"},"devdoc":{"version":1,"kind":"dev"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":538,"exportedSymbols":{"ScriptExample":[537],"Vm":[45],"console":[182]},"nodeType":"SourceUnit","src":"32:4932:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":45,"nodeType":"ContractDefinition","src":"120:507:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":45,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":45,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":45,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":38,"nodeType":"FunctionDefinition","src":"516:30:0","nodes":[],"functionSelector":"afc98040","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"525:9:0","parameters":{"id":36,"nodeType":"ParameterList","parameters":[],"src":"534:2:0"},"returnParameters":{"id":37,"nodeType":"ParameterList","parameters":[],"src":"545:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":41,"nodeType":"FunctionDefinition","src":"551:35:0","nodes":[],"functionSelector":"7fb5297f","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"560:14:0","parameters":{"id":39,"nodeType":"ParameterList","parameters":[],"src":"574:2:0"},"returnParameters":{"id":40,"nodeType":"ParameterList","parameters":[],"src":"585:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":44,"nodeType":"FunctionDefinition","src":"591:34:0","nodes":[],"functionSelector":"76eadd36","implemented":false,"kind":"function","modifiers":[],"name":"stopBroadcast","nameLocation":"600:13:0","parameters":{"id":42,"nodeType":"ParameterList","parameters":[],"src":"613:2:0"},"returnParameters":{"id":43,"nodeType":"ParameterList","parameters":[],"src":"624:0:0"},"scope":45,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[45],"name":"Vm","nameLocation":"130:2:0","scope":538,"usedErrors":[]},{"id":182,"nodeType":"ContractDefinition","src":"682:1622:0","nodes":[{"id":51,"nodeType":"VariableDeclaration","src":"704:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"721:15:0","scope":182,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":46,"name":"address","nodeType":"ElementaryTypeName","src":"704:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":49,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"747:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":48,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"739:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":47,"name":"address","nodeType":"ElementaryTypeName","src":"739:7:0","typeDescriptions":{}}},"id":50,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"739:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":68,"nodeType":"FunctionDefinition","src":"797:221:0","nodes":[],"body":{"id":67,"nodeType":"Block","src":"956:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"975:37:0","statements":[{"nodeType":"YulAssignment","src":"989:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"998:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"989:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":57,"isOffset":false,"isSlot":false,"src":"998:4:0","valueSize":1},{"declaration":64,"isOffset":false,"isSlot":false,"src":"989:5:0","valueSize":1}],"id":66,"nodeType":"InlineAssembly","src":"966:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"806:25:0","parameters":{"id":58,"nodeType":"ParameterList","parameters":[{"constant":false,"id":57,"mutability":"mutable","name":"fnIn","nameLocation":"878:4:0","nodeType":"VariableDeclaration","scope":68,"src":"841:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":56,"nodeType":"FunctionTypeName","parameterTypes":{"id":54,"nodeType":"ParameterList","parameters":[{"constant":false,"id":53,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":56,"src":"850:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":52,"name":"bytes","nodeType":"ElementaryTypeName","src":"850:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"849:14:0"},"returnParameterTypes":{"id":55,"nodeType":"ParameterList","parameters":[],"src":"878:0:0"},"src":"841:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"831:57:0"},"returnParameters":{"id":65,"nodeType":"ParameterList","parameters":[{"constant":false,"id":64,"mutability":"mutable","name":"fnOut","nameLocation":"949:5:0","nodeType":"VariableDeclaration","scope":68,"src":"912:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":63,"nodeType":"FunctionTypeName","parameterTypes":{"id":61,"nodeType":"ParameterList","parameters":[{"constant":false,"id":60,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":63,"src":"921:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":59,"name":"bytes","nodeType":"ElementaryTypeName","src":"921:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"920:14:0"},"returnParameterTypes":{"id":62,"nodeType":"ParameterList","parameters":[],"src":"949:0:0"},"src":"912:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"911:44:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":80,"nodeType":"FunctionDefinition","src":"1024:133:0","nodes":[],"body":{"id":79,"nodeType":"Block","src":"1085:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":76,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":70,"src":"1142:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":74,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":96,"src":"1121:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":73,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":68,"src":"1095:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":75,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1095:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":77,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1095:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":78,"nodeType":"ExpressionStatement","src":"1095:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"1033:15:0","parameters":{"id":71,"nodeType":"ParameterList","parameters":[{"constant":false,"id":70,"mutability":"mutable","name":"payload","nameLocation":"1062:7:0","nodeType":"VariableDeclaration","scope":80,"src":"1049:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":69,"name":"bytes","nodeType":"ElementaryTypeName","src":"1049:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1048:22:0"},"returnParameters":{"id":72,"nodeType":"ParameterList","parameters":[],"src":"1085:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":96,"nodeType":"FunctionDefinition","src":"1163:380:0","nodes":[],"body":{"id":95,"nodeType":"Block","src":"1227:316:0","nodes":[],"statements":[{"assignments":[86],"declarations":[{"constant":false,"id":86,"mutability":"mutable","name":"payloadLength","nameLocation":"1245:13:0","nodeType":"VariableDeclaration","scope":95,"src":"1237:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":85,"name":"uint256","nodeType":"ElementaryTypeName","src":"1237:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":89,"initialValue":{"expression":{"id":87,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":82,"src":"1261:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":88,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1261:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1237:38:0"},{"assignments":[91],"declarations":[{"constant":false,"id":91,"mutability":"mutable","name":"consoleAddress","nameLocation":"1293:14:0","nodeType":"VariableDeclaration","scope":95,"src":"1285:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":90,"name":"address","nodeType":"ElementaryTypeName","src":"1285:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":93,"initialValue":{"id":92,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":51,"src":"1310:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1285:40:0"},{"AST":{"nodeType":"YulBlock","src":"1387:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1401:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1425:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1434:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1421:3:0"},"nodeType":"YulFunctionCall","src":"1421:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1405:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1450:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1470:3:0"},"nodeType":"YulFunctionCall","src":"1470:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1477:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1493:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1507:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1522:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1525:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1459:10:0"},"nodeType":"YulFunctionCall","src":"1459:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1454:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":91,"isOffset":false,"isSlot":false,"src":"1477:14:0","valueSize":1},{"declaration":82,"isOffset":false,"isSlot":false,"src":"1425:7:0","valueSize":1},{"declaration":86,"isOffset":false,"isSlot":false,"src":"1507:13:0","valueSize":1}],"id":94,"nodeType":"InlineAssembly","src":"1378:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1172:19:0","parameters":{"id":83,"nodeType":"ParameterList","parameters":[{"constant":false,"id":82,"mutability":"mutable","name":"payload","nameLocation":"1205:7:0","nodeType":"VariableDeclaration","scope":96,"src":"1192:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":81,"name":"bytes","nodeType":"ElementaryTypeName","src":"1192:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1191:22:0"},"returnParameters":{"id":84,"nodeType":"ParameterList","parameters":[],"src":"1227:0:0"},"scope":182,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":110,"nodeType":"FunctionDefinition","src":"1549:121:0","nodes":[],"body":{"id":109,"nodeType":"Block","src":"1594:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":104,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1644:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":105,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":98,"src":"1659:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":102,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1620:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":103,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1620:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":106,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1620:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":101,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1604:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":107,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1604:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":108,"nodeType":"ExpressionStatement","src":"1604:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1558:3:0","parameters":{"id":99,"nodeType":"ParameterList","parameters":[{"constant":false,"id":98,"mutability":"mutable","name":"p0","nameLocation":"1576:2:0","nodeType":"VariableDeclaration","scope":110,"src":"1562:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":97,"name":"string","nodeType":"ElementaryTypeName","src":"1562:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1561:18:0"},"returnParameters":{"id":100,"nodeType":"ParameterList","parameters":[],"src":"1594:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":127,"nodeType":"FunctionDefinition","src":"1676:139:0","nodes":[],"body":{"id":126,"nodeType":"Block","src":"1730:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":120,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1780:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":121,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":112,"src":"1800:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":122,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":114,"src":"1804:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":118,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1756:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":119,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1756:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":123,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1756:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":117,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1740:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":124,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1740:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":125,"nodeType":"ExpressionStatement","src":"1740:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1685:3:0","parameters":{"id":115,"nodeType":"ParameterList","parameters":[{"constant":false,"id":112,"mutability":"mutable","name":"p0","nameLocation":"1703:2:0","nodeType":"VariableDeclaration","scope":127,"src":"1689:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":111,"name":"string","nodeType":"ElementaryTypeName","src":"1689:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":114,"mutability":"mutable","name":"p1","nameLocation":"1712:2:0","nodeType":"VariableDeclaration","scope":127,"src":"1707:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":113,"name":"bool","nodeType":"ElementaryTypeName","src":"1707:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1688:27:0"},"returnParameters":{"id":116,"nodeType":"ParameterList","parameters":[],"src":"1730:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":144,"nodeType":"FunctionDefinition","src":"1821:145:0","nodes":[],"body":{"id":143,"nodeType":"Block","src":"1878:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":137,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1928:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":138,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":129,"src":"1951:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":139,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":131,"src":"1955:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":135,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1904:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":136,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1904:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":140,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1904:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":134,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1888:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":141,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1888:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":142,"nodeType":"ExpressionStatement","src":"1888:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1830:3:0","parameters":{"id":132,"nodeType":"ParameterList","parameters":[{"constant":false,"id":129,"mutability":"mutable","name":"p0","nameLocation":"1848:2:0","nodeType":"VariableDeclaration","scope":144,"src":"1834:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":128,"name":"string","nodeType":"ElementaryTypeName","src":"1834:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":131,"mutability":"mutable","name":"p1","nameLocation":"1860:2:0","nodeType":"VariableDeclaration","scope":144,"src":"1852:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":130,"name":"uint256","nodeType":"ElementaryTypeName","src":"1852:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1833:30:0"},"returnParameters":{"id":133,"nodeType":"ParameterList","parameters":[],"src":"1878:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":161,"nodeType":"FunctionDefinition","src":"1972:145:0","nodes":[],"body":{"id":160,"nodeType":"Block","src":"2029:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":154,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2079:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":155,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":146,"src":"2102:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":156,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":148,"src":"2106:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":152,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2055:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":153,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2055:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":157,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2055:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":151,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"2039:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":158,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2039:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":159,"nodeType":"ExpressionStatement","src":"2039:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1981:3:0","parameters":{"id":149,"nodeType":"ParameterList","parameters":[{"constant":false,"id":146,"mutability":"mutable","name":"p0","nameLocation":"1999:2:0","nodeType":"VariableDeclaration","scope":161,"src":"1985:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":145,"name":"string","nodeType":"ElementaryTypeName","src":"1985:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":148,"mutability":"mutable","name":"p1","nameLocation":"2011:2:0","nodeType":"VariableDeclaration","scope":161,"src":"2003:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":147,"name":"address","nodeType":"ElementaryTypeName","src":"2003:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1984:30:0"},"returnParameters":{"id":150,"nodeType":"ParameterList","parameters":[],"src":"2029:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":181,"nodeType":"FunctionDefinition","src":"2123:179:0","nodes":[],"body":{"id":180,"nodeType":"Block","src":"2204:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":173,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2254:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":174,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":163,"src":"2283:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":175,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":165,"src":"2287:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":176,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":167,"src":"2291:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":171,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2230:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":172,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2230:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":177,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2230:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":170,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"2214:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":178,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2214:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":179,"nodeType":"ExpressionStatement","src":"2214:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2132:3:0","parameters":{"id":168,"nodeType":"ParameterList","parameters":[{"constant":false,"id":163,"mutability":"mutable","name":"p0","nameLocation":"2150:2:0","nodeType":"VariableDeclaration","scope":181,"src":"2136:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":162,"name":"string","nodeType":"ElementaryTypeName","src":"2136:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":165,"mutability":"mutable","name":"p1","nameLocation":"2168:2:0","nodeType":"VariableDeclaration","scope":181,"src":"2154:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":164,"name":"string","nodeType":"ElementaryTypeName","src":"2154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":167,"mutability":"mutable","name":"p2","nameLocation":"2186:2:0","nodeType":"VariableDeclaration","scope":181,"src":"2172:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":166,"name":"string","nodeType":"ElementaryTypeName","src":"2172:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2135:54:0"},"returnParameters":{"id":169,"nodeType":"ParameterList","parameters":[],"src":"2204:0:0"},"scope":182,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[182],"name":"console","nameLocation":"690:7:0","scope":538,"usedErrors":[]},{"id":537,"nodeType":"ContractDefinition","src":"2432:2531:0","nodes":[{"id":197,"nodeType":"VariableDeclaration","src":"2462:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2488:10:0","scope":537,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":184,"name":"address","nodeType":"ElementaryTypeName","src":"2462:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":192,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2535:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":191,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2525:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":193,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2525:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":190,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2517:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":189,"name":"uint256","nodeType":"ElementaryTypeName","src":"2517:7:0","typeDescriptions":{}}},"id":194,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2517:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":188,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2509:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":187,"name":"uint160","nodeType":"ElementaryTypeName","src":"2509:7:0","typeDescriptions":{}}},"id":195,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2509:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":186,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2501:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":185,"name":"address","nodeType":"ElementaryTypeName","src":"2501:7:0","typeDescriptions":{}}},"id":196,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2501:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":203,"nodeType":"VariableDeclaration","src":"2562:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2583:2:0","scope":537,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"},"typeName":{"id":199,"nodeType":"UserDefinedTypeName","pathNode":{"id":198,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":45,"src":"2562:2:0"},"referencedDeclaration":45,"src":"2562:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"value":{"arguments":[{"id":201,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":197,"src":"2591:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":200,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":45,"src":"2588:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$45_$","typeString":"type(contract Vm)"}},"id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2588:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"visibility":"internal"},{"id":205,"nodeType":"VariableDeclaration","src":"2666:22:0","nodes":[],"constant":false,"functionSelector":"61bc221a","mutability":"mutable","name":"counter","nameLocation":"2681:7:0","scope":537,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":204,"name":"uint256","nodeType":"ElementaryTypeName","src":"2666:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":368,"nodeType":"FunctionDefinition","src":"2778:949:0","nodes":[],"body":{"id":367,"nodeType":"Block","src":"2800:927:0","nodes":[],"statements":[{"assignments":[210],"declarations":[{"constant":false,"id":210,"mutability":"mutable","name":"x","nameLocation":"2815:1:0","nodeType":"VariableDeclaration","scope":367,"src":"2810:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":209,"name":"bool","nodeType":"ElementaryTypeName","src":"2810:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":216,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":213,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2828:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":214,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2844:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":211,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"2819:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":212,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2819:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":215,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2819:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2810:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":220,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2872:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":221,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":210,"src":"2895:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":217,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"2860:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":219,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":127,"src":"2860:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":222,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2860:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":223,"nodeType":"ExpressionStatement","src":"2860:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":227,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2920:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":230,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"2945:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}],"id":229,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2937:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":228,"name":"address","nodeType":"ElementaryTypeName","src":"2937:7:0","typeDescriptions":{}}},"id":231,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2937:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":224,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"2908:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":226,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"2908:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2908:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":233,"nodeType":"ExpressionStatement","src":"2908:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":237,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2973:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":242,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3011:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}],"id":241,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3003:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":240,"name":"address","nodeType":"ElementaryTypeName","src":"3003:7:0","typeDescriptions":{}}},"id":243,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3003:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":238,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"2991:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":239,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"2991:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":244,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2991:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":234,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"2961:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":236,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":144,"src":"2961:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":245,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2961:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":246,"nodeType":"ExpressionStatement","src":"2961:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":250,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3040:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":253,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3063:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":254,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3063:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":252,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3055:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":251,"name":"address","nodeType":"ElementaryTypeName","src":"3055:7:0","typeDescriptions":{}}},"id":255,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3055:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":247,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3028:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"3028:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":256,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3028:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":257,"nodeType":"ExpressionStatement","src":"3028:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":261,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3097:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":266,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3133:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":267,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3133:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":265,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3125:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":264,"name":"address","nodeType":"ElementaryTypeName","src":"3125:7:0","typeDescriptions":{}}},"id":268,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3125:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":262,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3113:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":263,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3113:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":269,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3113:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":258,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3085:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":260,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":144,"src":"3085:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":270,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3085:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":271,"nodeType":"ExpressionStatement","src":"3085:61:0"},{"assignments":[273],"declarations":[{"constant":false,"id":273,"mutability":"mutable","name":"json","nameLocation":"3171:4:0","nodeType":"VariableDeclaration","scope":367,"src":"3157:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":272,"name":"string","nodeType":"ElementaryTypeName","src":"3157:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":275,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":274,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3178:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"3157:55:0"},{"assignments":[280],"declarations":[{"constant":false,"id":280,"mutability":"mutable","name":"keys","nameLocation":"3238:4:0","nodeType":"VariableDeclaration","scope":367,"src":"3222:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":278,"name":"string","nodeType":"ElementaryTypeName","src":"3222:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":279,"nodeType":"ArrayTypeName","src":"3222:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":286,"initialValue":{"arguments":[{"id":283,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":273,"src":"3262:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3268:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":281,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3245:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":282,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3245:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":285,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3245:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3222:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":290,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3305:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":291,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":280,"src":"3313:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":293,"indexExpression":{"hexValue":"30","id":292,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3318:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3313:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":294,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":280,"src":"3322:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":296,"indexExpression":{"hexValue":"31","id":295,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3327:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3322:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":287,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3293:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":289,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":181,"src":"3293:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":297,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3293:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":298,"nodeType":"ExpressionStatement","src":"3293:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3352:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":299,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3341:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":301,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3341:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":303,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3341:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":304,"nodeType":"ExpressionStatement","src":"3341:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":312,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3408:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":311,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3400:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":310,"name":"uint160","nodeType":"ElementaryTypeName","src":"3400:7:0","typeDescriptions":{}}},"id":313,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3400:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":309,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3392:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":308,"name":"address","nodeType":"ElementaryTypeName","src":"3392:7:0","typeDescriptions":{}}},"id":314,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3392:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":305,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3378:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":307,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3378:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":315,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3378:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":316,"nodeType":"ExpressionStatement","src":"3378:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":320,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3436:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":317,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3425:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":319,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3425:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":321,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3425:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":322,"nodeType":"ExpressionStatement","src":"3425:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":326,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3473:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":329,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3508:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":330,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3508:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":328,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3500:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":327,"name":"address","nodeType":"ElementaryTypeName","src":"3500:7:0","typeDescriptions":{}}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3500:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":323,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3461:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"3461:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":332,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3461:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":333,"nodeType":"ExpressionStatement","src":"3461:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":337,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3542:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":340,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3580:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}],"id":339,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3572:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":338,"name":"address","nodeType":"ElementaryTypeName","src":"3572:7:0","typeDescriptions":{}}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3572:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":334,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3530:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":336,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"3530:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3530:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3530:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3607:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":344,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3596:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3596:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":348,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3596:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":349,"nodeType":"ExpressionStatement","src":"3596:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":350,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3632:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3632:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":353,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3632:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":354,"nodeType":"ExpressionStatement","src":"3632:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":358,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3667:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":355,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3656:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":357,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":476,"src":"3656:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":359,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3656:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":360,"nodeType":"ExpressionStatement","src":"3656:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":364,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3712:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":361,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3700:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":363,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"3700:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":365,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3700:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":366,"nodeType":"ExpressionStatement","src":"3700:20:0"}]},"documentation":{"id":206,"nodeType":"StructuredDocumentation","src":"2695:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2787:3:0","parameters":{"id":207,"nodeType":"ParameterList","parameters":[],"src":"2790:2:0"},"returnParameters":{"id":208,"nodeType":"ParameterList","parameters":[],"src":"2800:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":452,"nodeType":"FunctionDefinition","src":"3794:520:0","nodes":[],"body":{"id":451,"nodeType":"Block","src":"3825:489:0","nodes":[],"statements":[{"expression":{"arguments":[{"hexValue":"74657374696e672073696e676c65","id":375,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3847:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""},"value":"testing single"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""}],"expression":{"id":372,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3835:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":374,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"3835:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":376,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3835:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":377,"nodeType":"ExpressionStatement","src":"3835:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":378,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"3874:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":380,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"3874:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":381,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3874:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":382,"nodeType":"ExpressionStatement","src":"3874:14:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c31","id":386,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3909:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""},"value":"single_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""}],"expression":{"id":383,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3898:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":385,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":491,"src":"3898:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":387,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3898:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":388,"nodeType":"ExpressionStatement","src":"3898:26:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c32","id":392,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3945:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""},"value":"single_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""}],"expression":{"id":389,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3934:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":391,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":506,"src":"3934:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":393,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3934:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":394,"nodeType":"ExpressionStatement","src":"3934:26:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073746172742f73746f70","id":398,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3983:20:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""},"value":"testing start/stop"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""}],"expression":{"id":395,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"3971:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":397,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"3971:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":399,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3971:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":400,"nodeType":"ExpressionStatement","src":"3971:33:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":401,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4014:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":403,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":41,"src":"4014:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":404,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4014:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":405,"nodeType":"ExpressionStatement","src":"4014:19:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c31","id":409,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4054:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""},"value":"startstop_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""}],"expression":{"id":406,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4043:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":408,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":491,"src":"4043:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":410,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4043:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":411,"nodeType":"ExpressionStatement","src":"4043:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c32","id":415,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4093:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""},"value":"startstop_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""}],"expression":{"id":412,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4082:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":414,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":506,"src":"4082:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":416,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4082:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":417,"nodeType":"ExpressionStatement","src":"4082:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":418,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4121:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":420,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":44,"src":"4121:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":421,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4121:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":422,"nodeType":"ExpressionStatement","src":"4121:18:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c33","id":426,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4160:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""},"value":"startstop_call3"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""}],"expression":{"id":423,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4149:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":425,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":491,"src":"4149:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":427,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4149:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":428,"nodeType":"ExpressionStatement","src":"4149:29:0"},{"expression":{"arguments":[{"hexValue":"74657374696e67206e6573746564","id":432,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4201:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""},"value":"testing nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""}],"expression":{"id":429,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4189:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":431,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4189:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":433,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4189:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":434,"nodeType":"ExpressionStatement","src":"4189:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":435,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4228:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":437,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":41,"src":"4228:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":438,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4228:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":439,"nodeType":"ExpressionStatement","src":"4228:19:0"},{"expression":{"arguments":[{"hexValue":"6e6573746564","id":443,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4270:8:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""},"value":"nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""}],"expression":{"id":440,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4257:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":442,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested1","nodeType":"MemberAccess","referencedDeclaration":521,"src":"4257:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":444,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4257:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":445,"nodeType":"ExpressionStatement","src":"4257:22:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":446,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":203,"src":"4289:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$45","typeString":"contract Vm"}},"id":448,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":44,"src":"4289:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":449,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4289:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":450,"nodeType":"ExpressionStatement","src":"4289:18:0"}]},"documentation":{"id":369,"nodeType":"StructuredDocumentation","src":"3733:56:0","text":"@notice example function, to test vm.broadcast with."},"functionSelector":"bef03abc","implemented":true,"kind":"function","modifiers":[],"name":"runBroadcast","nameLocation":"3803:12:0","parameters":{"id":370,"nodeType":"ParameterList","parameters":[],"src":"3815:2:0"},"returnParameters":{"id":371,"nodeType":"ParameterList","parameters":[],"src":"3825:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":476,"nodeType":"FunctionDefinition","src":"4409:143:0","nodes":[],"body":{"id":475,"nodeType":"Block","src":"4458:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":461,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":455,"src":"4480:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":458,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4468:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":460,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4468:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":462,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4468:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":463,"nodeType":"ExpressionStatement","src":"4468:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":467,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4505:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":470,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"4533:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":471,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"4533:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":469,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4525:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":468,"name":"address","nodeType":"ElementaryTypeName","src":"4525:7:0","typeDescriptions":{}}},"id":472,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4525:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":464,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4493:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":466,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":161,"src":"4493:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":473,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4493:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":474,"nodeType":"ExpressionStatement","src":"4493:52:0"}]},"documentation":{"id":453,"nodeType":"StructuredDocumentation","src":"4320:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"4418:5:0","parameters":{"id":456,"nodeType":"ParameterList","parameters":[{"constant":false,"id":455,"mutability":"mutable","name":"_v","nameLocation":"4440:2:0","nodeType":"VariableDeclaration","scope":476,"src":"4424:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":454,"name":"string","nodeType":"ElementaryTypeName","src":"4424:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4423:20:0"},"returnParameters":{"id":457,"nodeType":"ParameterList","parameters":[],"src":"4458:0:0"},"scope":537,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":491,"nodeType":"FunctionDefinition","src":"4558:95:0","nodes":[],"body":{"id":490,"nodeType":"Block","src":"4602:51:0","nodes":[],"statements":[{"expression":{"id":482,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4612:9:0","subExpression":{"id":481,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4612:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":483,"nodeType":"ExpressionStatement","src":"4612:9:0"},{"expression":{"arguments":[{"id":487,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":478,"src":"4643:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":484,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4631:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":486,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4631:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":488,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4631:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":489,"nodeType":"ExpressionStatement","src":"4631:15:0"}]},"functionSelector":"7e79255d","implemented":true,"kind":"function","modifiers":[],"name":"call1","nameLocation":"4567:5:0","parameters":{"id":479,"nodeType":"ParameterList","parameters":[{"constant":false,"id":478,"mutability":"mutable","name":"_v","nameLocation":"4589:2:0","nodeType":"VariableDeclaration","scope":491,"src":"4573:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":477,"name":"string","nodeType":"ElementaryTypeName","src":"4573:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4572:20:0"},"returnParameters":{"id":480,"nodeType":"ParameterList","parameters":[],"src":"4602:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":506,"nodeType":"FunctionDefinition","src":"4659:95:0","nodes":[],"body":{"id":505,"nodeType":"Block","src":"4703:51:0","nodes":[],"statements":[{"expression":{"id":497,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4713:9:0","subExpression":{"id":496,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4713:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":498,"nodeType":"ExpressionStatement","src":"4713:9:0"},{"expression":{"arguments":[{"id":502,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":493,"src":"4744:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":499,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4732:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":501,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4732:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":503,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4732:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":504,"nodeType":"ExpressionStatement","src":"4732:15:0"}]},"functionSelector":"8d3ef7ca","implemented":true,"kind":"function","modifiers":[],"name":"call2","nameLocation":"4668:5:0","parameters":{"id":494,"nodeType":"ParameterList","parameters":[{"constant":false,"id":493,"mutability":"mutable","name":"_v","nameLocation":"4690:2:0","nodeType":"VariableDeclaration","scope":506,"src":"4674:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":492,"name":"string","nodeType":"ElementaryTypeName","src":"4674:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4673:20:0"},"returnParameters":{"id":495,"nodeType":"ParameterList","parameters":[],"src":"4703:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":521,"nodeType":"FunctionDefinition","src":"4760:98:0","nodes":[],"body":{"id":520,"nodeType":"Block","src":"4806:52:0","nodes":[],"statements":[{"expression":{"id":512,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4816:9:0","subExpression":{"id":511,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4816:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":513,"nodeType":"ExpressionStatement","src":"4816:9:0"},{"expression":{"arguments":[{"id":517,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":508,"src":"4848:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":514,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4835:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$537","typeString":"contract ScriptExample"}},"id":516,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested2","nodeType":"MemberAccess","referencedDeclaration":536,"src":"4835:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":518,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4835:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":519,"nodeType":"ExpressionStatement","src":"4835:16:0"}]},"functionSelector":"a76ccdfa","implemented":true,"kind":"function","modifiers":[],"name":"nested1","nameLocation":"4769:7:0","parameters":{"id":509,"nodeType":"ParameterList","parameters":[{"constant":false,"id":508,"mutability":"mutable","name":"_v","nameLocation":"4793:2:0","nodeType":"VariableDeclaration","scope":521,"src":"4777:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":507,"name":"string","nodeType":"ElementaryTypeName","src":"4777:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4776:20:0"},"returnParameters":{"id":510,"nodeType":"ParameterList","parameters":[],"src":"4806:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":536,"nodeType":"FunctionDefinition","src":"4864:97:0","nodes":[],"body":{"id":535,"nodeType":"Block","src":"4910:51:0","nodes":[],"statements":[{"expression":{"id":527,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"4920:9:0","subExpression":{"id":526,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":205,"src":"4920:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":528,"nodeType":"ExpressionStatement","src":"4920:9:0"},{"expression":{"arguments":[{"id":532,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":523,"src":"4951:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":529,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":182,"src":"4939:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$182_$","typeString":"type(library console)"}},"id":531,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":110,"src":"4939:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":533,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4939:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":534,"nodeType":"ExpressionStatement","src":"4939:15:0"}]},"functionSelector":"dbf1282f","implemented":true,"kind":"function","modifiers":[],"name":"nested2","nameLocation":"4873:7:0","parameters":{"id":524,"nodeType":"ParameterList","parameters":[{"constant":false,"id":523,"mutability":"mutable","name":"_v","nameLocation":"4897:2:0","nodeType":"VariableDeclaration","scope":536,"src":"4881:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":522,"name":"string","nodeType":"ElementaryTypeName","src":"4881:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4880:20:0"},"returnParameters":{"id":525,"nodeType":"ParameterList","parameters":[],"src":"4910:0:0"},"scope":537,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[],"contractKind":"contract","documentation":{"id":183,"nodeType":"StructuredDocumentation","src":"2306:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[537],"name":"ScriptExample","nameLocation":"2441:13:0","scope":538,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file +{"abi":[],"bytecode":{"object":"0x602d6037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300080f000a","sourceMap":"791:1622:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;791:1622:0;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300080f000a","sourceMap":"791:1622:0:-:0;;;;;;;;","linkReferences":{}},"methodIdentifiers":{},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"console\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x4fc2ffeba31e146fc3a2edef7cc8b7e82fb2344454d32d6371a62c6d76dfcb4e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a517c69eba90ee5f3efb198a2247d5744bed8e17d332ce2dda4d3cf3a2c334f9\",\"dweb:/ipfs/QmciXeDt5EEhmjH5xECVk2VX6EbnER5UFv58dvGgemwkKK\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"console"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x4fc2ffeba31e146fc3a2edef7cc8b7e82fb2344454d32d6371a62c6d76dfcb4e","urls":["bzz-raw://a517c69eba90ee5f3efb198a2247d5744bed8e17d332ce2dda4d3cf3a2c334f9","dweb:/ipfs/QmciXeDt5EEhmjH5xECVk2VX6EbnER5UFv58dvGgemwkKK"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[],"types":{}},"userdoc":{"version":1,"kind":"user"},"devdoc":{"version":1,"kind":"dev"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":677,"exportedSymbols":{"FooBar":[676],"ScriptExample":[663],"Vm":[55],"console":[192]},"nodeType":"SourceUnit","src":"32:5697:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":55,"nodeType":"ContractDefinition","src":"120:616:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":55,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":38,"nodeType":"FunctionDefinition","src":"516:30:0","nodes":[],"functionSelector":"afc98040","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"525:9:0","parameters":{"id":36,"nodeType":"ParameterList","parameters":[],"src":"534:2:0"},"returnParameters":{"id":37,"nodeType":"ParameterList","parameters":[],"src":"545:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":43,"nodeType":"FunctionDefinition","src":"551:47:0","nodes":[],"functionSelector":"e6962cdb","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"560:9:0","parameters":{"id":41,"nodeType":"ParameterList","parameters":[{"constant":false,"id":40,"mutability":"mutable","name":"msgSender","nameLocation":"578:9:0","nodeType":"VariableDeclaration","scope":43,"src":"570:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":39,"name":"address","nodeType":"ElementaryTypeName","src":"570:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"569:19:0"},"returnParameters":{"id":42,"nodeType":"ParameterList","parameters":[],"src":"597:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":48,"nodeType":"FunctionDefinition","src":"603:52:0","nodes":[],"functionSelector":"7fec2a8d","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"612:14:0","parameters":{"id":46,"nodeType":"ParameterList","parameters":[{"constant":false,"id":45,"mutability":"mutable","name":"msgSender","nameLocation":"635:9:0","nodeType":"VariableDeclaration","scope":48,"src":"627:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":44,"name":"address","nodeType":"ElementaryTypeName","src":"627:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"626:19:0"},"returnParameters":{"id":47,"nodeType":"ParameterList","parameters":[],"src":"654:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":51,"nodeType":"FunctionDefinition","src":"660:35:0","nodes":[],"functionSelector":"7fb5297f","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"669:14:0","parameters":{"id":49,"nodeType":"ParameterList","parameters":[],"src":"683:2:0"},"returnParameters":{"id":50,"nodeType":"ParameterList","parameters":[],"src":"694:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":54,"nodeType":"FunctionDefinition","src":"700:34:0","nodes":[],"functionSelector":"76eadd36","implemented":false,"kind":"function","modifiers":[],"name":"stopBroadcast","nameLocation":"709:13:0","parameters":{"id":52,"nodeType":"ParameterList","parameters":[],"src":"722:2:0"},"returnParameters":{"id":53,"nodeType":"ParameterList","parameters":[],"src":"733:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[55],"name":"Vm","nameLocation":"130:2:0","scope":677,"usedErrors":[]},{"id":192,"nodeType":"ContractDefinition","src":"791:1622:0","nodes":[{"id":61,"nodeType":"VariableDeclaration","src":"813:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"830:15:0","scope":192,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":56,"name":"address","nodeType":"ElementaryTypeName","src":"813:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":59,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"856:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":58,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"848:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":57,"name":"address","nodeType":"ElementaryTypeName","src":"848:7:0","typeDescriptions":{}}},"id":60,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"848:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":78,"nodeType":"FunctionDefinition","src":"906:221:0","nodes":[],"body":{"id":77,"nodeType":"Block","src":"1065:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"1084:37:0","statements":[{"nodeType":"YulAssignment","src":"1098:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"1107:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"1098:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":67,"isOffset":false,"isSlot":false,"src":"1107:4:0","valueSize":1},{"declaration":74,"isOffset":false,"isSlot":false,"src":"1098:5:0","valueSize":1}],"id":76,"nodeType":"InlineAssembly","src":"1075:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"915:25:0","parameters":{"id":68,"nodeType":"ParameterList","parameters":[{"constant":false,"id":67,"mutability":"mutable","name":"fnIn","nameLocation":"987:4:0","nodeType":"VariableDeclaration","scope":78,"src":"950:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":66,"nodeType":"FunctionTypeName","parameterTypes":{"id":64,"nodeType":"ParameterList","parameters":[{"constant":false,"id":63,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":66,"src":"959:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":62,"name":"bytes","nodeType":"ElementaryTypeName","src":"959:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"958:14:0"},"returnParameterTypes":{"id":65,"nodeType":"ParameterList","parameters":[],"src":"987:0:0"},"src":"950:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"940:57:0"},"returnParameters":{"id":75,"nodeType":"ParameterList","parameters":[{"constant":false,"id":74,"mutability":"mutable","name":"fnOut","nameLocation":"1058:5:0","nodeType":"VariableDeclaration","scope":78,"src":"1021:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":73,"nodeType":"FunctionTypeName","parameterTypes":{"id":71,"nodeType":"ParameterList","parameters":[{"constant":false,"id":70,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":73,"src":"1030:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":69,"name":"bytes","nodeType":"ElementaryTypeName","src":"1030:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1029:14:0"},"returnParameterTypes":{"id":72,"nodeType":"ParameterList","parameters":[],"src":"1058:0:0"},"src":"1021:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"1020:44:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":90,"nodeType":"FunctionDefinition","src":"1133:133:0","nodes":[],"body":{"id":89,"nodeType":"Block","src":"1194:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":86,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1251:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":84,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":106,"src":"1230:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":83,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":78,"src":"1204:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":85,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":87,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":88,"nodeType":"ExpressionStatement","src":"1204:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"1142:15:0","parameters":{"id":81,"nodeType":"ParameterList","parameters":[{"constant":false,"id":80,"mutability":"mutable","name":"payload","nameLocation":"1171:7:0","nodeType":"VariableDeclaration","scope":90,"src":"1158:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":79,"name":"bytes","nodeType":"ElementaryTypeName","src":"1158:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1157:22:0"},"returnParameters":{"id":82,"nodeType":"ParameterList","parameters":[],"src":"1194:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":106,"nodeType":"FunctionDefinition","src":"1272:380:0","nodes":[],"body":{"id":105,"nodeType":"Block","src":"1336:316:0","nodes":[],"statements":[{"assignments":[96],"declarations":[{"constant":false,"id":96,"mutability":"mutable","name":"payloadLength","nameLocation":"1354:13:0","nodeType":"VariableDeclaration","scope":105,"src":"1346:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":95,"name":"uint256","nodeType":"ElementaryTypeName","src":"1346:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":99,"initialValue":{"expression":{"id":97,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":92,"src":"1370:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":98,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1370:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1346:38:0"},{"assignments":[101],"declarations":[{"constant":false,"id":101,"mutability":"mutable","name":"consoleAddress","nameLocation":"1402:14:0","nodeType":"VariableDeclaration","scope":105,"src":"1394:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":100,"name":"address","nodeType":"ElementaryTypeName","src":"1394:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":103,"initialValue":{"id":102,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":61,"src":"1419:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1394:40:0"},{"AST":{"nodeType":"YulBlock","src":"1496:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1510:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1534:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1543:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1530:3:0"},"nodeType":"YulFunctionCall","src":"1530:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1514:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1559:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1579:3:0"},"nodeType":"YulFunctionCall","src":"1579:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1586:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1602:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1616:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1631:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1634:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1568:10:0"},"nodeType":"YulFunctionCall","src":"1568:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1563:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":101,"isOffset":false,"isSlot":false,"src":"1586:14:0","valueSize":1},{"declaration":92,"isOffset":false,"isSlot":false,"src":"1534:7:0","valueSize":1},{"declaration":96,"isOffset":false,"isSlot":false,"src":"1616:13:0","valueSize":1}],"id":104,"nodeType":"InlineAssembly","src":"1487:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1281:19:0","parameters":{"id":93,"nodeType":"ParameterList","parameters":[{"constant":false,"id":92,"mutability":"mutable","name":"payload","nameLocation":"1314:7:0","nodeType":"VariableDeclaration","scope":106,"src":"1301:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":91,"name":"bytes","nodeType":"ElementaryTypeName","src":"1301:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1300:22:0"},"returnParameters":{"id":94,"nodeType":"ParameterList","parameters":[],"src":"1336:0:0"},"scope":192,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":120,"nodeType":"FunctionDefinition","src":"1658:121:0","nodes":[],"body":{"id":119,"nodeType":"Block","src":"1703:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":114,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1753:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":115,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":108,"src":"1768:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":112,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1729:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":113,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1729:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":116,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1729:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":111,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1713:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":117,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1713:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":118,"nodeType":"ExpressionStatement","src":"1713:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1667:3:0","parameters":{"id":109,"nodeType":"ParameterList","parameters":[{"constant":false,"id":108,"mutability":"mutable","name":"p0","nameLocation":"1685:2:0","nodeType":"VariableDeclaration","scope":120,"src":"1671:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":107,"name":"string","nodeType":"ElementaryTypeName","src":"1671:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1670:18:0"},"returnParameters":{"id":110,"nodeType":"ParameterList","parameters":[],"src":"1703:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":137,"nodeType":"FunctionDefinition","src":"1785:139:0","nodes":[],"body":{"id":136,"nodeType":"Block","src":"1839:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":130,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1889:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":131,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":122,"src":"1909:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":132,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":124,"src":"1913:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":128,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1865:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":129,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1865:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":133,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1865:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":127,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1849:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":134,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1849:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":135,"nodeType":"ExpressionStatement","src":"1849:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1794:3:0","parameters":{"id":125,"nodeType":"ParameterList","parameters":[{"constant":false,"id":122,"mutability":"mutable","name":"p0","nameLocation":"1812:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1798:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":121,"name":"string","nodeType":"ElementaryTypeName","src":"1798:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":124,"mutability":"mutable","name":"p1","nameLocation":"1821:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1816:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":123,"name":"bool","nodeType":"ElementaryTypeName","src":"1816:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1797:27:0"},"returnParameters":{"id":126,"nodeType":"ParameterList","parameters":[],"src":"1839:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":154,"nodeType":"FunctionDefinition","src":"1930:145:0","nodes":[],"body":{"id":153,"nodeType":"Block","src":"1987:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":147,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2037:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":148,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":139,"src":"2060:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":149,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":141,"src":"2064:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":145,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2013:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":146,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2013:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":150,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2013:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":144,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1997:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":151,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1997:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":152,"nodeType":"ExpressionStatement","src":"1997:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1939:3:0","parameters":{"id":142,"nodeType":"ParameterList","parameters":[{"constant":false,"id":139,"mutability":"mutable","name":"p0","nameLocation":"1957:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1943:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":138,"name":"string","nodeType":"ElementaryTypeName","src":"1943:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":141,"mutability":"mutable","name":"p1","nameLocation":"1969:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1961:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":140,"name":"uint256","nodeType":"ElementaryTypeName","src":"1961:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1942:30:0"},"returnParameters":{"id":143,"nodeType":"ParameterList","parameters":[],"src":"1987:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":171,"nodeType":"FunctionDefinition","src":"2081:145:0","nodes":[],"body":{"id":170,"nodeType":"Block","src":"2138:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":164,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2188:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":165,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":156,"src":"2211:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":166,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":158,"src":"2215:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":162,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2164:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":163,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2164:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":167,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2164:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":161,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2148:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":168,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2148:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":169,"nodeType":"ExpressionStatement","src":"2148:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2090:3:0","parameters":{"id":159,"nodeType":"ParameterList","parameters":[{"constant":false,"id":156,"mutability":"mutable","name":"p0","nameLocation":"2108:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2094:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":155,"name":"string","nodeType":"ElementaryTypeName","src":"2094:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":158,"mutability":"mutable","name":"p1","nameLocation":"2120:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2112:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":157,"name":"address","nodeType":"ElementaryTypeName","src":"2112:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"2093:30:0"},"returnParameters":{"id":160,"nodeType":"ParameterList","parameters":[],"src":"2138:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":191,"nodeType":"FunctionDefinition","src":"2232:179:0","nodes":[],"body":{"id":190,"nodeType":"Block","src":"2313:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":183,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2363:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":184,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2392:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":185,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":175,"src":"2396:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":186,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":177,"src":"2400:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":181,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2339:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":182,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2339:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":187,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2339:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":180,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2323:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":188,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2323:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":189,"nodeType":"ExpressionStatement","src":"2323:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2241:3:0","parameters":{"id":178,"nodeType":"ParameterList","parameters":[{"constant":false,"id":173,"mutability":"mutable","name":"p0","nameLocation":"2259:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2245:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":172,"name":"string","nodeType":"ElementaryTypeName","src":"2245:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":175,"mutability":"mutable","name":"p1","nameLocation":"2277:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2263:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":174,"name":"string","nodeType":"ElementaryTypeName","src":"2263:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":177,"mutability":"mutable","name":"p2","nameLocation":"2295:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2281:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":176,"name":"string","nodeType":"ElementaryTypeName","src":"2281:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2244:54:0"},"returnParameters":{"id":179,"nodeType":"ParameterList","parameters":[],"src":"2313:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[192],"name":"console","nameLocation":"799:7:0","scope":677,"usedErrors":[]},{"id":663,"nodeType":"ContractDefinition","src":"2541:3089:0","nodes":[{"id":207,"nodeType":"VariableDeclaration","src":"2571:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2597:10:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":194,"name":"address","nodeType":"ElementaryTypeName","src":"2571:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2644:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":201,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2634:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":203,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2634:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":200,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2626:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":199,"name":"uint256","nodeType":"ElementaryTypeName","src":"2626:7:0","typeDescriptions":{}}},"id":204,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2626:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":198,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2618:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":197,"name":"uint160","nodeType":"ElementaryTypeName","src":"2618:7:0","typeDescriptions":{}}},"id":205,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2618:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":196,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2610:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":195,"name":"address","nodeType":"ElementaryTypeName","src":"2610:7:0","typeDescriptions":{}}},"id":206,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2610:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":213,"nodeType":"VariableDeclaration","src":"2671:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2692:2:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"},"typeName":{"id":209,"nodeType":"UserDefinedTypeName","pathNode":{"id":208,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":55,"src":"2671:2:0"},"referencedDeclaration":55,"src":"2671:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"value":{"arguments":[{"id":211,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":207,"src":"2700:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":210,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":55,"src":"2697:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$55_$","typeString":"type(contract Vm)"}},"id":212,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2697:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"visibility":"internal"},{"id":215,"nodeType":"VariableDeclaration","src":"2775:22:0","nodes":[],"constant":false,"functionSelector":"61bc221a","mutability":"mutable","name":"counter","nameLocation":"2790:7:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":214,"name":"uint256","nodeType":"ElementaryTypeName","src":"2775:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":378,"nodeType":"FunctionDefinition","src":"2887:949:0","nodes":[],"body":{"id":377,"nodeType":"Block","src":"2909:927:0","nodes":[],"statements":[{"assignments":[220],"declarations":[{"constant":false,"id":220,"mutability":"mutable","name":"x","nameLocation":"2924:1:0","nodeType":"VariableDeclaration","scope":377,"src":"2919:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":219,"name":"bool","nodeType":"ElementaryTypeName","src":"2919:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":226,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":223,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2937:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":224,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2953:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":221,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"2928:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":222,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2928:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":225,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2928:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2919:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":230,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2981:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":231,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":220,"src":"3004:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":227,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"2969:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":229,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":137,"src":"2969:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2969:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":233,"nodeType":"ExpressionStatement","src":"2969:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":237,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3029:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":240,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3054:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":239,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3046:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":238,"name":"address","nodeType":"ElementaryTypeName","src":"3046:7:0","typeDescriptions":{}}},"id":241,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3046:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":234,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3017:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":236,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3017:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":242,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3017:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":243,"nodeType":"ExpressionStatement","src":"3017:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":247,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3082:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":252,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3120:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":251,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3112:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":250,"name":"address","nodeType":"ElementaryTypeName","src":"3112:7:0","typeDescriptions":{}}},"id":253,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3112:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":248,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3100:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3100:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":254,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3100:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":244,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3070:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":246,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3070:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":255,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3070:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":256,"nodeType":"ExpressionStatement","src":"3070:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":260,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3149:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":263,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3172:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":264,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3172:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":262,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3164:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":261,"name":"address","nodeType":"ElementaryTypeName","src":"3164:7:0","typeDescriptions":{}}},"id":265,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3164:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":257,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3137:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":259,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3137:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":266,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3137:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":267,"nodeType":"ExpressionStatement","src":"3137:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":271,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3206:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":276,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3242:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":277,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3242:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":275,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3234:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":274,"name":"address","nodeType":"ElementaryTypeName","src":"3234:7:0","typeDescriptions":{}}},"id":278,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3234:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":272,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3222:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":273,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3222:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":279,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3222:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":268,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3194:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":270,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3194:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":280,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3194:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":281,"nodeType":"ExpressionStatement","src":"3194:61:0"},{"assignments":[283],"declarations":[{"constant":false,"id":283,"mutability":"mutable","name":"json","nameLocation":"3280:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3266:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":282,"name":"string","nodeType":"ElementaryTypeName","src":"3266:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":285,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3287:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"3266:55:0"},{"assignments":[290],"declarations":[{"constant":false,"id":290,"mutability":"mutable","name":"keys","nameLocation":"3347:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3331:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":288,"name":"string","nodeType":"ElementaryTypeName","src":"3331:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":289,"nodeType":"ArrayTypeName","src":"3331:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":296,"initialValue":{"arguments":[{"id":293,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":283,"src":"3371:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":294,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3377:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":291,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3354:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":292,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3354:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":295,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3354:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3331:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":300,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3414:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":301,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3422:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":303,"indexExpression":{"hexValue":"30","id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3427:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3422:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":304,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3431:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":306,"indexExpression":{"hexValue":"31","id":305,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3436:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3431:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":297,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3402:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":299,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":191,"src":"3402:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":307,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3402:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":308,"nodeType":"ExpressionStatement","src":"3402:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":312,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3461:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":309,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3450:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":311,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3450:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":313,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3450:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":314,"nodeType":"ExpressionStatement","src":"3450:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":322,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3517:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":321,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3509:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":320,"name":"uint160","nodeType":"ElementaryTypeName","src":"3509:7:0","typeDescriptions":{}}},"id":323,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3509:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":319,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3501:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":318,"name":"address","nodeType":"ElementaryTypeName","src":"3501:7:0","typeDescriptions":{}}},"id":324,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3501:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":315,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3487:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":317,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3487:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3487:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":326,"nodeType":"ExpressionStatement","src":"3487:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":330,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3545:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":327,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3534:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":329,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3534:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3534:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":332,"nodeType":"ExpressionStatement","src":"3534:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":336,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3582:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":339,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3617:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":340,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3617:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":338,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3609:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":337,"name":"address","nodeType":"ElementaryTypeName","src":"3609:7:0","typeDescriptions":{}}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3609:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":333,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3570:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":335,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3570:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3570:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3570:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3651:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":350,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3689:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":349,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3681:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":348,"name":"address","nodeType":"ElementaryTypeName","src":"3681:7:0","typeDescriptions":{}}},"id":351,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3681:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":344,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3639:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3639:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3639:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":353,"nodeType":"ExpressionStatement","src":"3639:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":357,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3716:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":354,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3705:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":356,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3705:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":358,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3705:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":359,"nodeType":"ExpressionStatement","src":"3705:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":360,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3741:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":362,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3741:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":363,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3741:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":364,"nodeType":"ExpressionStatement","src":"3741:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":368,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3776:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":365,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3765:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":367,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3765:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":369,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3765:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":370,"nodeType":"ExpressionStatement","src":"3765:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":374,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3821:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":371,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3809:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":373,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"3809:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":375,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3809:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":376,"nodeType":"ExpressionStatement","src":"3809:20:0"}]},"documentation":{"id":216,"nodeType":"StructuredDocumentation","src":"2804:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2896:3:0","parameters":{"id":217,"nodeType":"ParameterList","parameters":[],"src":"2899:2:0"},"returnParameters":{"id":218,"nodeType":"ParameterList","parameters":[],"src":"2909:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":566,"nodeType":"FunctionDefinition","src":"3903:988:0","nodes":[],"body":{"id":565,"nodeType":"Block","src":"3934:957:0","nodes":[],"statements":[{"expression":{"arguments":[{"hexValue":"74657374696e672073696e676c65","id":385,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3956:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""},"value":"testing single"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""}],"expression":{"id":382,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3944:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":384,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"3944:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":386,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3944:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":387,"nodeType":"ExpressionStatement","src":"3944:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":388,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3983:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":390,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"3983:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":391,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3983:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":392,"nodeType":"ExpressionStatement","src":"3983:14:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c31","id":396,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4018:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""},"value":"single_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""}],"expression":{"id":393,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4007:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":395,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4007:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":397,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4007:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":398,"nodeType":"ExpressionStatement","src":"4007:26:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c32","id":402,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4054:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""},"value":"single_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""}],"expression":{"id":399,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4043:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":401,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":620,"src":"4043:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":403,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4043:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":404,"nodeType":"ExpressionStatement","src":"4043:26:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073746172742f73746f70","id":408,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4092:20:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""},"value":"testing start/stop"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""}],"expression":{"id":405,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4080:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":407,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4080:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":409,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4080:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":410,"nodeType":"ExpressionStatement","src":"4080:33:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078633066666565","id":418,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4157:8:0","typeDescriptions":{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"},"value":"0xc0ffee"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"}],"id":417,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4149:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":416,"name":"uint160","nodeType":"ElementaryTypeName","src":"4149:7:0","typeDescriptions":{}}},"id":419,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4149:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":415,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4141:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":414,"name":"address","nodeType":"ElementaryTypeName","src":"4141:7:0","typeDescriptions":{}}},"id":420,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4141:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":411,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4123:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":413,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4123:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":421,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4123:45:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":422,"nodeType":"ExpressionStatement","src":"4123:45:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c31","id":426,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4189:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""},"value":"startstop_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""}],"expression":{"id":423,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4178:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":425,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4178:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":427,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4178:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":428,"nodeType":"ExpressionStatement","src":"4178:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c32","id":432,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4228:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""},"value":"startstop_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""}],"expression":{"id":429,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4217:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":431,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":620,"src":"4217:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":433,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4217:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":434,"nodeType":"ExpressionStatement","src":"4217:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f70757265","id":438,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4270:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""},"value":"startstop_pure"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""}],"expression":{"id":435,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4256:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":437,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"callPure","nodeType":"MemberAccess","referencedDeclaration":662,"src":"4256:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure external"}},"id":439,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4256:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":440,"nodeType":"ExpressionStatement","src":"4256:31:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":441,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4297:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":443,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4297:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":444,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4297:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":445,"nodeType":"ExpressionStatement","src":"4297:18:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c33","id":449,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4336:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""},"value":"startstop_call3"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""}],"expression":{"id":446,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4325:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":448,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4325:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":450,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4325:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":451,"nodeType":"ExpressionStatement","src":"4325:29:0"},{"expression":{"arguments":[{"hexValue":"74657374696e67206e6573746564","id":455,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4377:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""},"value":"testing nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""}],"expression":{"id":452,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4365:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":454,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4365:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":456,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4365:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":457,"nodeType":"ExpressionStatement","src":"4365:29:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307831323334","id":465,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4438:6:0","typeDescriptions":{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"},"value":"0x1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"}],"id":464,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4430:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":463,"name":"uint160","nodeType":"ElementaryTypeName","src":"4430:7:0","typeDescriptions":{}}},"id":466,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4430:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":462,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4422:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":461,"name":"address","nodeType":"ElementaryTypeName","src":"4422:7:0","typeDescriptions":{}}},"id":467,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4422:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":458,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4404:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":460,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4404:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":468,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4404:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":469,"nodeType":"ExpressionStatement","src":"4404:43:0"},{"expression":{"arguments":[{"hexValue":"6e6573746564","id":473,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4470:8:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""},"value":"nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""}],"expression":{"id":470,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4457:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":472,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested1","nodeType":"MemberAccess","referencedDeclaration":635,"src":"4457:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":474,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4457:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":475,"nodeType":"ExpressionStatement","src":"4457:22:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":476,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4489:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":478,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4489:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":479,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4489:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":480,"nodeType":"ExpressionStatement","src":"4489:18:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206465706c6f796d656e74","id":484,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4530:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""},"value":"contract deployment"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""}],"expression":{"id":481,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4518:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":483,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4518:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":485,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4518:34:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":486,"nodeType":"ExpressionStatement","src":"4518:34:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078313233343536","id":494,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4591:8:0","typeDescriptions":{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"},"value":"0x123456"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"}],"id":493,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4583:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":492,"name":"uint160","nodeType":"ElementaryTypeName","src":"4583:7:0","typeDescriptions":{}}},"id":495,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4583:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":491,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4575:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":490,"name":"address","nodeType":"ElementaryTypeName","src":"4575:7:0","typeDescriptions":{}}},"id":496,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4575:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":487,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4562:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":489,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4562:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":497,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4562:40:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":498,"nodeType":"ExpressionStatement","src":"4562:40:0"},{"assignments":[501],"declarations":[{"constant":false,"id":501,"mutability":"mutable","name":"x","nameLocation":"4619:1:0","nodeType":"VariableDeclaration","scope":565,"src":"4612:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"},"typeName":{"id":500,"nodeType":"UserDefinedTypeName","pathNode":{"id":499,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4612:6:0"},"referencedDeclaration":676,"src":"4612:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"visibility":"internal"}],"id":507,"initialValue":{"arguments":[{"hexValue":"31323334","id":505,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4634:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":504,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4623:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":503,"nodeType":"UserDefinedTypeName","pathNode":{"id":502,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4627:6:0"},"referencedDeclaration":676,"src":"4627:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}}},"id":506,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4623:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4612:27:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":513,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":509,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":501,"src":"4657:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"id":510,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":665,"src":"4657:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":511,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4657:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":512,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4668:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4657:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":508,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4649:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":514,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4649:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":515,"nodeType":"ExpressionStatement","src":"4649:24:0"},{"expression":{"arguments":[{"hexValue":"6372656174652032","id":519,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4696:10:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""},"value":"create 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""}],"expression":{"id":516,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4684:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":518,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4684:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":520,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4684:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":521,"nodeType":"ExpressionStatement","src":"4684:23:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307863616665","id":529,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4746:6:0","typeDescriptions":{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"},"value":"0xcafe"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"}],"id":528,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4738:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":527,"name":"uint160","nodeType":"ElementaryTypeName","src":"4738:7:0","typeDescriptions":{}}},"id":530,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4738:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":526,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4730:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":525,"name":"address","nodeType":"ElementaryTypeName","src":"4730:7:0","typeDescriptions":{}}},"id":531,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4730:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":522,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4717:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":524,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4717:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":532,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4717:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":533,"nodeType":"ExpressionStatement","src":"4717:38:0"},{"assignments":[536],"declarations":[{"constant":false,"id":536,"mutability":"mutable","name":"y","nameLocation":"4772:1:0","nodeType":"VariableDeclaration","scope":565,"src":"4765:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"},"typeName":{"id":535,"nodeType":"UserDefinedTypeName","pathNode":{"id":534,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4765:6:0"},"referencedDeclaration":676,"src":"4765:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"visibility":"internal"}],"id":550,"initialValue":{"arguments":[{"hexValue":"31323334","id":548,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4815:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":539,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4776:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":538,"nodeType":"UserDefinedTypeName","pathNode":{"id":537,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4780:6:0"},"referencedDeclaration":676,"src":"4780:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}}},"id":547,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"names":["salt"],"nodeType":"FunctionCallOptions","options":[{"arguments":[{"arguments":[{"hexValue":"3432","id":544,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4809:2:0","typeDescriptions":{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"},"value":"42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"}],"id":543,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4801:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":542,"name":"uint256","nodeType":"ElementaryTypeName","src":"4801:7:0","typeDescriptions":{}}},"id":545,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4801:11:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":541,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4793:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_bytes32_$","typeString":"type(bytes32)"},"typeName":{"id":540,"name":"bytes32","nodeType":"ElementaryTypeName","src":"4793:7:0","typeDescriptions":{}}},"id":546,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4793:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"src":"4776:38:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$salt","typeString":"function (uint256) returns (contract FooBar)"}},"id":549,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4776:44:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4765:55:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":556,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":552,"name":"y","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":536,"src":"4838:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"id":553,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":665,"src":"4838:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":554,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4838:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":555,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4849:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4838:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":551,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4830:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":557,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4830:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":558,"nodeType":"ExpressionStatement","src":"4830:24:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":562,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4876:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":559,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4864:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":561,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4864:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":563,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4864:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":564,"nodeType":"ExpressionStatement","src":"4864:20:0"}]},"documentation":{"id":379,"nodeType":"StructuredDocumentation","src":"3842:56:0","text":"@notice example function, to test vm.broadcast with."},"functionSelector":"bef03abc","implemented":true,"kind":"function","modifiers":[],"name":"runBroadcast","nameLocation":"3912:12:0","parameters":{"id":380,"nodeType":"ParameterList","parameters":[],"src":"3924:2:0"},"returnParameters":{"id":381,"nodeType":"ParameterList","parameters":[],"src":"3934:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":590,"nodeType":"FunctionDefinition","src":"4986:143:0","nodes":[],"body":{"id":589,"nodeType":"Block","src":"5035:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":575,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":569,"src":"5057:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":572,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5045:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":574,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5045:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":576,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5045:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":577,"nodeType":"ExpressionStatement","src":"5045:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":581,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"5082:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":584,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"5110:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":585,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"5110:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":583,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5102:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":582,"name":"address","nodeType":"ElementaryTypeName","src":"5102:7:0","typeDescriptions":{}}},"id":586,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5102:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":578,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5070:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":580,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"5070:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":587,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5070:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":588,"nodeType":"ExpressionStatement","src":"5070:52:0"}]},"documentation":{"id":567,"nodeType":"StructuredDocumentation","src":"4897:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"4995:5:0","parameters":{"id":570,"nodeType":"ParameterList","parameters":[{"constant":false,"id":569,"mutability":"mutable","name":"_v","nameLocation":"5017:2:0","nodeType":"VariableDeclaration","scope":590,"src":"5001:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":568,"name":"string","nodeType":"ElementaryTypeName","src":"5001:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5000:20:0"},"returnParameters":{"id":571,"nodeType":"ParameterList","parameters":[],"src":"5035:0:0"},"scope":663,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":605,"nodeType":"FunctionDefinition","src":"5135:95:0","nodes":[],"body":{"id":604,"nodeType":"Block","src":"5179:51:0","nodes":[],"statements":[{"expression":{"id":596,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5189:9:0","subExpression":{"id":595,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5189:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":597,"nodeType":"ExpressionStatement","src":"5189:9:0"},{"expression":{"arguments":[{"id":601,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":592,"src":"5220:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":598,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5208:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":600,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5208:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":602,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5208:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":603,"nodeType":"ExpressionStatement","src":"5208:15:0"}]},"functionSelector":"7e79255d","implemented":true,"kind":"function","modifiers":[],"name":"call1","nameLocation":"5144:5:0","parameters":{"id":593,"nodeType":"ParameterList","parameters":[{"constant":false,"id":592,"mutability":"mutable","name":"_v","nameLocation":"5166:2:0","nodeType":"VariableDeclaration","scope":605,"src":"5150:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":591,"name":"string","nodeType":"ElementaryTypeName","src":"5150:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5149:20:0"},"returnParameters":{"id":594,"nodeType":"ParameterList","parameters":[],"src":"5179:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":620,"nodeType":"FunctionDefinition","src":"5236:95:0","nodes":[],"body":{"id":619,"nodeType":"Block","src":"5280:51:0","nodes":[],"statements":[{"expression":{"id":611,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5290:9:0","subExpression":{"id":610,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5290:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":612,"nodeType":"ExpressionStatement","src":"5290:9:0"},{"expression":{"arguments":[{"id":616,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":607,"src":"5321:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":613,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5309:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":615,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5309:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":617,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5309:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":618,"nodeType":"ExpressionStatement","src":"5309:15:0"}]},"functionSelector":"8d3ef7ca","implemented":true,"kind":"function","modifiers":[],"name":"call2","nameLocation":"5245:5:0","parameters":{"id":608,"nodeType":"ParameterList","parameters":[{"constant":false,"id":607,"mutability":"mutable","name":"_v","nameLocation":"5267:2:0","nodeType":"VariableDeclaration","scope":620,"src":"5251:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":606,"name":"string","nodeType":"ElementaryTypeName","src":"5251:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5250:20:0"},"returnParameters":{"id":609,"nodeType":"ParameterList","parameters":[],"src":"5280:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":635,"nodeType":"FunctionDefinition","src":"5337:98:0","nodes":[],"body":{"id":634,"nodeType":"Block","src":"5383:52:0","nodes":[],"statements":[{"expression":{"id":626,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5393:9:0","subExpression":{"id":625,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5393:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":627,"nodeType":"ExpressionStatement","src":"5393:9:0"},{"expression":{"arguments":[{"id":631,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":622,"src":"5425:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":628,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"5412:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":630,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested2","nodeType":"MemberAccess","referencedDeclaration":650,"src":"5412:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":632,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5412:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":633,"nodeType":"ExpressionStatement","src":"5412:16:0"}]},"functionSelector":"a76ccdfa","implemented":true,"kind":"function","modifiers":[],"name":"nested1","nameLocation":"5346:7:0","parameters":{"id":623,"nodeType":"ParameterList","parameters":[{"constant":false,"id":622,"mutability":"mutable","name":"_v","nameLocation":"5370:2:0","nodeType":"VariableDeclaration","scope":635,"src":"5354:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":621,"name":"string","nodeType":"ElementaryTypeName","src":"5354:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5353:20:0"},"returnParameters":{"id":624,"nodeType":"ParameterList","parameters":[],"src":"5383:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":650,"nodeType":"FunctionDefinition","src":"5441:97:0","nodes":[],"body":{"id":649,"nodeType":"Block","src":"5487:51:0","nodes":[],"statements":[{"expression":{"id":641,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5497:9:0","subExpression":{"id":640,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5497:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":642,"nodeType":"ExpressionStatement","src":"5497:9:0"},{"expression":{"arguments":[{"id":646,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":637,"src":"5528:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":643,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5516:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":645,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5516:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":647,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5516:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":648,"nodeType":"ExpressionStatement","src":"5516:15:0"}]},"functionSelector":"dbf1282f","implemented":true,"kind":"function","modifiers":[],"name":"nested2","nameLocation":"5450:7:0","parameters":{"id":638,"nodeType":"ParameterList","parameters":[{"constant":false,"id":637,"mutability":"mutable","name":"_v","nameLocation":"5474:2:0","nodeType":"VariableDeclaration","scope":650,"src":"5458:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":636,"name":"string","nodeType":"ElementaryTypeName","src":"5458:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5457:20:0"},"returnParameters":{"id":639,"nodeType":"ParameterList","parameters":[],"src":"5487:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":662,"nodeType":"FunctionDefinition","src":"5544:84:0","nodes":[],"body":{"id":661,"nodeType":"Block","src":"5596:32:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":658,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":652,"src":"5618:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":655,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5606:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":657,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5606:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":659,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5606:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":660,"nodeType":"ExpressionStatement","src":"5606:15:0"}]},"functionSelector":"7f8b915c","implemented":true,"kind":"function","modifiers":[],"name":"callPure","nameLocation":"5553:8:0","parameters":{"id":653,"nodeType":"ParameterList","parameters":[{"constant":false,"id":652,"mutability":"mutable","name":"_v","nameLocation":"5578:2:0","nodeType":"VariableDeclaration","scope":662,"src":"5562:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":651,"name":"string","nodeType":"ElementaryTypeName","src":"5562:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5561:20:0"},"returnParameters":{"id":654,"nodeType":"ParameterList","parameters":[],"src":"5596:0:0"},"scope":663,"stateMutability":"pure","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[676],"contractKind":"contract","documentation":{"id":193,"nodeType":"StructuredDocumentation","src":"2415:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[663],"name":"ScriptExample","nameLocation":"2550:13:0","scope":677,"usedErrors":[]},{"id":676,"nodeType":"ContractDefinition","src":"5632:96:0","nodes":[{"id":665,"nodeType":"VariableDeclaration","src":"5654:18:0","nodes":[],"constant":false,"functionSelector":"c2985578","mutability":"mutable","name":"foo","nameLocation":"5669:3:0","scope":676,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":664,"name":"uint256","nodeType":"ElementaryTypeName","src":"5654:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":675,"nodeType":"FunctionDefinition","src":"5679:47:0","nodes":[],"body":{"id":674,"nodeType":"Block","src":"5702:24:0","nodes":[],"statements":[{"expression":{"id":672,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":670,"name":"foo","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":665,"src":"5712:3:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":671,"name":"v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":667,"src":"5718:1:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5712:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":673,"nodeType":"ExpressionStatement","src":"5712:7:0"}]},"implemented":true,"kind":"constructor","modifiers":[],"name":"","nameLocation":"-1:-1:-1","parameters":{"id":668,"nodeType":"ParameterList","parameters":[{"constant":false,"id":667,"mutability":"mutable","name":"v","nameLocation":"5699:1:0","nodeType":"VariableDeclaration","scope":675,"src":"5691:9:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":666,"name":"uint256","nodeType":"ElementaryTypeName","src":"5691:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"5690:11:0"},"returnParameters":{"id":669,"nodeType":"ParameterList","parameters":[],"src":"5702:0:0"},"scope":676,"stateMutability":"nonpayable","virtual":false,"visibility":"public"}],"abstract":false,"baseContracts":[],"canonicalName":"FooBar","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[676],"name":"FooBar","nameLocation":"5641:6:0","scope":677,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file From f93f9f40adcd448168c6ea27820aeee5da65fcbd Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Tue, 10 Sep 2024 14:12:29 -0400 Subject: [PATCH 086/264] fix: OptimismPortal fuzz flakes (#11818) OptimismPortal fuzz tests were flaking because the base fee would increase so much that there wouldn't be enough gas to burn for the user to be able to buy the gas that they want. Introduces an additional assumption that will prevent the elasticity multiplier and max change denominator from being such that the maximum change to the base fee won't cause us to run out of gas. --- .../test/L1/OptimismPortal.t.sol | 20 +++++++++++++++---- .../test/L1/OptimismPortal2.t.sol | 19 +++++++++++++++--- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/packages/contracts-bedrock/test/L1/OptimismPortal.t.sol b/packages/contracts-bedrock/test/L1/OptimismPortal.t.sol index 49991aee21f5..b47bad8e4173 100644 --- a/packages/contracts-bedrock/test/L1/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/L1/OptimismPortal.t.sol @@ -1211,19 +1211,31 @@ contract OptimismPortalResourceFuzz_Test is CommonTest { { // Get the set system gas limit uint64 gasLimit = systemConfig.gasLimit(); + // Bound resource config _maxResourceLimit = uint32(bound(_maxResourceLimit, 21000, MAX_GAS_LIMIT / 8)); _gasLimit = uint64(bound(_gasLimit, 21000, _maxResourceLimit)); _prevBaseFee = uint128(bound(_prevBaseFee, 0, 3 gwei)); + _prevBoughtGas = uint64(bound(_prevBoughtGas, 0, _maxResourceLimit - _gasLimit)); + _blockDiff = uint8(bound(_blockDiff, 0, 3)); + _baseFeeMaxChangeDenominator = uint8(bound(_baseFeeMaxChangeDenominator, 2, type(uint8).max)); + _elasticityMultiplier = uint8(bound(_elasticityMultiplier, 1, type(uint8).max)); + // Prevent values that would cause reverts vm.assume(gasLimit >= _gasLimit); vm.assume(_minimumBaseFee < _maximumBaseFee); - vm.assume(_baseFeeMaxChangeDenominator > 1); vm.assume(uint256(_maxResourceLimit) + uint256(_systemTxMaxGas) <= gasLimit); - vm.assume(_elasticityMultiplier > 0); vm.assume(((_maxResourceLimit / _elasticityMultiplier) * _elasticityMultiplier) == _maxResourceLimit); - _prevBoughtGas = uint64(bound(_prevBoughtGas, 0, _maxResourceLimit - _gasLimit)); - _blockDiff = uint8(bound(_blockDiff, 0, 3)); + + // Base fee can increase quickly and mean that we can't buy the amount of gas we want. + // Here we add a VM assumption to bound the potential increase. + // Compute the maximum possible increase in base fee. + uint256 maxPercentIncrease = uint256(_elasticityMultiplier - 1) * 100 / uint256(_baseFeeMaxChangeDenominator); + // Assume that we have enough gas to burn. + // Compute the maximum amount of gas we'd need to burn. + // Assume we need 1/5 of our gas to do other stuff. + vm.assume(_prevBaseFee * maxPercentIncrease * _gasLimit / 100 < MAX_GAS_LIMIT * 4 / 5); + // Pick a pseudorandom block number vm.roll(uint256(keccak256(abi.encode(_blockDiff))) % uint256(type(uint16).max) + uint256(_blockDiff)); diff --git a/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol b/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol index 5c8ba27f6335..91ea566dfce0 100644 --- a/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol +++ b/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol @@ -1464,19 +1464,32 @@ contract OptimismPortal2_ResourceFuzz_Test is CommonTest { { // Get the set system gas limit uint64 gasLimit = systemConfig.gasLimit(); + // Bound resource config _maxResourceLimit = uint32(bound(_maxResourceLimit, 21000, MAX_GAS_LIMIT / 8)); _gasLimit = uint64(bound(_gasLimit, 21000, _maxResourceLimit)); _prevBaseFee = uint128(bound(_prevBaseFee, 0, 3 gwei)); + _prevBoughtGas = uint64(bound(_prevBoughtGas, 0, _maxResourceLimit - _gasLimit)); + _blockDiff = uint8(bound(_blockDiff, 0, 3)); + _baseFeeMaxChangeDenominator = uint8(bound(_baseFeeMaxChangeDenominator, 2, type(uint8).max)); + _elasticityMultiplier = uint8(bound(_elasticityMultiplier, 1, type(uint8).max)); + // Prevent values that would cause reverts vm.assume(gasLimit >= _gasLimit); vm.assume(_minimumBaseFee < _maximumBaseFee); vm.assume(_baseFeeMaxChangeDenominator > 1); vm.assume(uint256(_maxResourceLimit) + uint256(_systemTxMaxGas) <= gasLimit); - vm.assume(_elasticityMultiplier > 0); vm.assume(((_maxResourceLimit / _elasticityMultiplier) * _elasticityMultiplier) == _maxResourceLimit); - _prevBoughtGas = uint64(bound(_prevBoughtGas, 0, _maxResourceLimit - _gasLimit)); - _blockDiff = uint8(bound(_blockDiff, 0, 3)); + + // Base fee can increase quickly and mean that we can't buy the amount of gas we want. + // Here we add a VM assumption to bound the potential increase. + // Compute the maximum possible increase in base fee. + uint256 maxPercentIncrease = uint256(_elasticityMultiplier - 1) * 100 / uint256(_baseFeeMaxChangeDenominator); + // Assume that we have enough gas to burn. + // Compute the maximum amount of gas we'd need to burn. + // Assume we need 1/5 of our gas to do other stuff. + vm.assume(_prevBaseFee * maxPercentIncrease * _gasLimit / 100 < MAX_GAS_LIMIT * 4 / 5); + // Pick a pseudorandom block number vm.roll(uint256(keccak256(abi.encode(_blockDiff))) % uint256(type(uint16).max) + uint256(_blockDiff)); From 89c3d35d6deb3881d5d4864daacd14d52596699b Mon Sep 17 00:00:00 2001 From: Inphi Date: Tue, 10 Sep 2024 16:12:07 -0400 Subject: [PATCH 087/264] cannon: Fix jalr stack tracking (#11831) --- cannon/mipsevm/exec/mips_instructions.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cannon/mipsevm/exec/mips_instructions.go b/cannon/mipsevm/exec/mips_instructions.go index 0c4eb919e99f..d016dd2c07e0 100644 --- a/cannon/mipsevm/exec/mips_instructions.go +++ b/cannon/mipsevm/exec/mips_instructions.go @@ -86,8 +86,10 @@ func ExecMipsCoreStepLogic(cpu *mipsevm.CpuScalars, registers *[32]uint32, memor linkReg := uint32(0) if fun == 9 { linkReg = rdReg + stackTracker.PushStack(cpu.PC, rs) + } else { + stackTracker.PopStack() } - stackTracker.PopStack() return HandleJump(cpu, registers, linkReg, rs) } From 3ac725a2e6bae018e81c729146e3d0bbdcb5d241 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Tue, 10 Sep 2024 16:45:22 -0400 Subject: [PATCH 088/264] ci: make semgrep-scan use a large docker image (#11834) semgrep-scan kept failing with a medium docker image with 4g RAM. Updating this image to large seems to fix the issue. --- .circleci/config.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5a79a26081f4..08f79a7662ae 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1342,7 +1342,7 @@ jobs: SEMGREP_COMMIT: << pipeline.git.revision >> docker: - image: returntocorp/semgrep - resource_class: medium + resource_class: large steps: - checkout - unless: @@ -1364,12 +1364,10 @@ jobs: - run: name: "Semgrep scan" # --time shows which rules take the most time - # --max-memory (in MiB) limits memory usage - # (defaults to 5GB, but medium runner only has 4GB, so we conservatively limit it to 3GB) # --timeout (in seconds) limits the time per rule and file. # SEMGREP_TIMEOUT is the same, but docs have conflicting defaults (5s in CLI flag, 1800 in some places) # https://semgrep.dev/docs/troubleshooting/semgrep-app#if-the-job-is-aborted-due-to-taking-too-long - command: semgrep ci --time --timeout=100 --max-memory=3000 + command: semgrep ci --time --timeout=100 # If semgrep hangs, stop the scan after 20m, to prevent a useless 5h job no_output_timeout: 20m - notify-failures-on-develop From 4ffc7cf3ca054a951b9ed8a2dcca474579f8a725 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Tue, 10 Sep 2024 18:04:55 -0400 Subject: [PATCH 089/264] maint: clarify interface fixes are manual (#11835) --- packages/contracts-bedrock/scripts/checks/check-interfaces.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh index d7dd7007cb57..0bcf73a3d2ad 100755 --- a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh +++ b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh @@ -210,6 +210,9 @@ if [ "$issues_detected" = true ]; then echo "If the interface is an external dependency or should otherwise be excluded from this" echo "check, add the interface name to the EXCLUDE_CONTRACTS list in the script. This will prevent" echo "the script from comparing it against a corresponding contract." + echo "IMPORTANT: Interface files are NOT yet generated automatically. You must fix any" + echo "listed discrepancies manually by updating the specified interface file. Automated" + echo "interface generation is dependent on a few Forge bug fixes." exit 1 else exit 0 From 627f7afefcec74af0daf01e106555fa466b5d093 Mon Sep 17 00:00:00 2001 From: Skeletor Spaceman <92943766+skeletor-spaceman@users.noreply.github.com> Date: Wed, 11 Sep 2024 00:08:19 -0300 Subject: [PATCH 090/264] feat: ban deposits interop (#11712) * interop: disable interop messages in force-deposits Co-authored-by: Disco <131301107+0xDiscotech@users.noreply.github.com> * interop: clean up config helpers * op-node: fix/improve L1 info tx tests * op-node: fix attributes test * op-node: fix sequence-number usage in post-interop system deposit, fix tests * op-contracts: L1Block interop: fix diff, remove duplicate test from renaming * contracts: update metadata * contracts: fix build warnings * contracts: fix interface build * script: ignore * lint: fix * test: .testdata directory * tests: fix revert --------- Co-authored-by: Disco <131301107+0xDiscotech@users.noreply.github.com> Co-authored-by: protolambda Co-authored-by: Mark Tyneway --- op-node/rollup/derive/attributes.go | 12 +- op-node/rollup/derive/attributes_test.go | 92 ++++++++++ op-node/rollup/derive/deposit_source.go | 25 ++- op-node/rollup/derive/deposit_source_test.go | 31 ++++ op-node/rollup/derive/fuzz_parsers_test.go | 17 +- op-node/rollup/derive/l1_block_info.go | 120 +++++++++++-- op-node/rollup/derive/l1_block_info_test.go | 118 +++++++++--- op-node/rollup/types.go | 34 ++++ packages/contracts-bedrock/.gas-snapshot | 6 + .../contracts-bedrock/scripts/L2Genesis.s.sol | 2 +- .../scripts/checks/check-interfaces.sh | 1 + packages/contracts-bedrock/semver-lock.json | 18 +- .../snapshots/abi/CrossL2Inbox.json | 5 + ...1BlockInterop.json => L1BlockIsthmus.json} | 32 ++++ ...1BlockInterop.json => L1BlockIsthmus.json} | 0 .../src/L1/OptimismPortalInterop.sol | 4 +- .../src/L1/SystemConfigInterop.sol | 2 +- .../contracts-bedrock/src/L2/CrossL2Inbox.sol | 7 + packages/contracts-bedrock/src/L2/L1Block.sol | 22 ++- ...{L1BlockInterop.sol => L1BlockIsthmus.sol} | 50 +++++- .../src/L2/interfaces/IL1BlockIsthmus.sol | 54 ++++++ .../src/libraries/Encoding.sol | 16 +- .../src/libraries/L1BlockErrors.sol | 3 + .../src/libraries/SafeCall.sol | 7 + .../test/BenchmarkTest.t.sol | 101 +++++++++++ .../test/L1/OptimismPortalInterop.t.sol | 8 +- .../test/L1/SystemConfigInterop.t.sol | 2 +- .../test/L2/CrossL2Inbox.t.sol | 70 ++++++++ ...lockInterop.t.sol => L1BlockIsthmus.t.sol} | 168 ++++++++++++++---- 29 files changed, 910 insertions(+), 117 deletions(-) rename packages/contracts-bedrock/snapshots/abi/{L1BlockInterop.json => L1BlockIsthmus.json} (93%) rename packages/contracts-bedrock/snapshots/storageLayout/{L1BlockInterop.json => L1BlockIsthmus.json} (100%) rename packages/contracts-bedrock/src/L2/{L1BlockInterop.sol => L1BlockIsthmus.sol} (69%) create mode 100644 packages/contracts-bedrock/src/L2/interfaces/IL1BlockIsthmus.sol rename packages/contracts-bedrock/test/L2/{L1BlockInterop.t.sol => L1BlockIsthmus.t.sol} (50%) diff --git a/op-node/rollup/derive/attributes.go b/op-node/rollup/derive/attributes.go index c65198bcec73..cc38a31b9c54 100644 --- a/op-node/rollup/derive/attributes.go +++ b/op-node/rollup/derive/attributes.go @@ -121,9 +121,19 @@ func (ba *FetchingAttributesBuilder) PreparePayloadAttributes(ctx context.Contex return nil, NewCriticalError(fmt.Errorf("failed to create l1InfoTx: %w", err)) } - txs := make([]hexutil.Bytes, 0, 1+len(depositTxs)+len(upgradeTxs)) + var afterForceIncludeTxs []hexutil.Bytes + if ba.rollupCfg.IsInterop(nextL2Time) { + depositsCompleteTx, err := DepositsCompleteBytes(seqNumber, l1Info) + if err != nil { + return nil, NewCriticalError(fmt.Errorf("failed to create depositsCompleteTx: %w", err)) + } + afterForceIncludeTxs = append(afterForceIncludeTxs, depositsCompleteTx) + } + + txs := make([]hexutil.Bytes, 0, 1+len(depositTxs)+len(afterForceIncludeTxs)+len(upgradeTxs)) txs = append(txs, l1InfoTx) txs = append(txs, depositTxs...) + txs = append(txs, afterForceIncludeTxs...) txs = append(txs, upgradeTxs...) var withdrawals *types.Withdrawals diff --git a/op-node/rollup/derive/attributes_test.go b/op-node/rollup/derive/attributes_test.go index 68c7c71aa1e1..64fcec556343 100644 --- a/op-node/rollup/derive/attributes_test.go +++ b/op-node/rollup/derive/attributes_test.go @@ -195,6 +195,98 @@ func TestPreparePayloadAttributes(t *testing.T) { require.Equal(t, l1InfoTx, []byte(attrs.Transactions[0])) require.True(t, attrs.NoTxPool) }) + t.Run("new origin with deposits on post-Isthmus", func(t *testing.T) { + rng := rand.New(rand.NewSource(1234)) + l1Fetcher := &testutils.MockL1Source{} + defer l1Fetcher.AssertExpectations(t) + l2Parent := testutils.RandomL2BlockRef(rng) + l1CfgFetcher := &testutils.MockL2Client{} + l1CfgFetcher.ExpectSystemConfigByL2Hash(l2Parent.Hash, testSysCfg, nil) + defer l1CfgFetcher.AssertExpectations(t) + + l1Info := testutils.RandomBlockInfo(rng) + l1Info.InfoParentHash = l2Parent.L1Origin.Hash + l1Info.InfoNum = l2Parent.L1Origin.Number + 1 // next origin, where deposits may be + + receipts, depositTxs, err := makeReceipts(rng, l1Info.InfoHash, cfg.DepositContractAddress, []receiptData{ + {goodReceipt: true, DepositLogs: []bool{true, false}}, + {goodReceipt: true, DepositLogs: []bool{true}}, + {goodReceipt: false, DepositLogs: []bool{true}}, + {goodReceipt: false, DepositLogs: []bool{false}}, + }) + require.NoError(t, err) + userDepositTxs, err := encodeDeposits(depositTxs) + require.NoError(t, err) + + // sets config to post-interop + cfg.ActivateAtGenesis(rollup.Interop) + + seqNumber := uint64(0) + epoch := l1Info.ID() + l1InfoTx, err := L1InfoDepositBytes(cfg, testSysCfg, seqNumber, l1Info, 0) + require.NoError(t, err) + depositsComplete, err := DepositsCompleteBytes(seqNumber, l1Info) + require.NoError(t, err) + + var l2Txs []eth.Data + l2Txs = append(l2Txs, l1InfoTx) + l2Txs = append(l2Txs, userDepositTxs...) + l2Txs = append(l2Txs, depositsComplete) + + l1Fetcher.ExpectFetchReceipts(epoch.Hash, l1Info, receipts, nil) + attrBuilder := NewFetchingAttributesBuilder(cfg, l1Fetcher, l1CfgFetcher) + attrs, err := attrBuilder.PreparePayloadAttributes(context.Background(), l2Parent, epoch) + require.NoError(t, err) + require.NotNil(t, attrs) + require.Equal(t, l2Parent.Time+cfg.BlockTime, uint64(attrs.Timestamp)) + require.Equal(t, eth.Bytes32(l1Info.InfoMixDigest), attrs.PrevRandao) + require.Equal(t, predeploys.SequencerFeeVaultAddr, attrs.SuggestedFeeRecipient) + require.Equal(t, len(l2Txs), len(attrs.Transactions), "Expected txs to equal l1 info tx + user deposit txs + DepositsComplete") + require.Equal(t, eth.Data(depositsComplete).String(), attrs.Transactions[len(l2Txs)-1].String()) + require.Equal(t, l2Txs, attrs.Transactions) + require.True(t, attrs.NoTxPool) + }) + + t.Run("same origin without deposits on post-Isthmus", func(t *testing.T) { + rng := rand.New(rand.NewSource(1234)) + l1Fetcher := &testutils.MockL1Source{} + defer l1Fetcher.AssertExpectations(t) + l2Parent := testutils.RandomL2BlockRef(rng) + l1CfgFetcher := &testutils.MockL2Client{} + l1CfgFetcher.ExpectSystemConfigByL2Hash(l2Parent.Hash, testSysCfg, nil) + defer l1CfgFetcher.AssertExpectations(t) + l1Info := testutils.RandomBlockInfo(rng) + l1Info.InfoHash = l2Parent.L1Origin.Hash + l1Info.InfoNum = l2Parent.L1Origin.Number // same origin again, so the sequence number is not reset + + // sets config to post-interop + cfg.ActivateAtGenesis(rollup.Interop) + + seqNumber := l2Parent.SequenceNumber + 1 + epoch := l1Info.ID() + l1InfoTx, err := L1InfoDepositBytes(cfg, testSysCfg, seqNumber, l1Info, 0) + require.NoError(t, err) + depositsComplete, err := DepositsCompleteBytes(seqNumber, l1Info) + require.NoError(t, err) + + var l2Txs []eth.Data + l2Txs = append(l2Txs, l1InfoTx) + l2Txs = append(l2Txs, depositsComplete) + + l1Fetcher.ExpectInfoByHash(epoch.Hash, l1Info, nil) + attrBuilder := NewFetchingAttributesBuilder(cfg, l1Fetcher, l1CfgFetcher) + attrs, err := attrBuilder.PreparePayloadAttributes(context.Background(), l2Parent, epoch) + require.NoError(t, err) + require.NotNil(t, attrs) + require.Equal(t, l2Parent.Time+cfg.BlockTime, uint64(attrs.Timestamp)) + require.Equal(t, eth.Bytes32(l1Info.InfoMixDigest), attrs.PrevRandao) + require.Equal(t, predeploys.SequencerFeeVaultAddr, attrs.SuggestedFeeRecipient) + require.Equal(t, len(l2Txs), len(attrs.Transactions), "Expected txs to equal l1 info tx + user deposit txs + DepositsComplete") + require.Equal(t, eth.Data(depositsComplete).String(), attrs.Transactions[len(l2Txs)-1].String()) + require.Equal(t, l2Txs, attrs.Transactions) + require.True(t, attrs.NoTxPool) + }) + // Test that the payload attributes builder changes the deposit format based on L2-time-based regolith activation t.Run("regolith", func(t *testing.T) { testCases := []struct { diff --git a/op-node/rollup/derive/deposit_source.go b/op-node/rollup/derive/deposit_source.go index f7a9730ad026..8b4e49590e3c 100644 --- a/op-node/rollup/derive/deposit_source.go +++ b/op-node/rollup/derive/deposit_source.go @@ -13,9 +13,10 @@ type UserDepositSource struct { } const ( - UserDepositSourceDomain = 0 - L1InfoDepositSourceDomain = 1 - UpgradeDepositSourceDomain = 2 + UserDepositSourceDomain = 0 + L1InfoDepositSourceDomain = 1 + UpgradeDepositSourceDomain = 2 + AfterForceIncludeSourceDomain = 3 ) func (dep *UserDepositSource) SourceHash() common.Hash { @@ -63,3 +64,21 @@ func (dep *UpgradeDepositSource) SourceHash() common.Hash { copy(domainInput[32:], intentHash[:]) return crypto.Keccak256Hash(domainInput[:]) } + +// AfterForceIncludeSource identifies the DepositsComplete post-user-deposits deposit-transaction. +type AfterForceIncludeSource struct { + L1BlockHash common.Hash + SeqNumber uint64 // without this the Deposit tx would have the same tx hash for every time the L1 info repeats. +} + +func (dep *AfterForceIncludeSource) SourceHash() common.Hash { + var input [32 * 2]byte + copy(input[:32], dep.L1BlockHash[:]) + binary.BigEndian.PutUint64(input[32*2-8:], dep.SeqNumber) + depositIDHash := crypto.Keccak256Hash(input[:]) + + var domainInput [32 * 2]byte + binary.BigEndian.PutUint64(domainInput[32-8:32], AfterForceIncludeSourceDomain) + copy(domainInput[32:], depositIDHash[:]) + return crypto.Keccak256Hash(domainInput[:]) +} diff --git a/op-node/rollup/derive/deposit_source_test.go b/op-node/rollup/derive/deposit_source_test.go index 10fb7048a2a2..fb30e8918829 100644 --- a/op-node/rollup/derive/deposit_source_test.go +++ b/op-node/rollup/derive/deposit_source_test.go @@ -3,6 +3,7 @@ package derive import ( "testing" + "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/assert" ) @@ -34,3 +35,33 @@ func TestEcotone4788ContractSourceHash(t *testing.T) { assert.Equal(t, expected, actual.Hex()) } + +// TestL1InfoDepositSource +// cast keccak $(cast concat-hex 0x0000000000000000000000000000000000000000000000000000000000000001 $(cast keccak $(cast concat-hex 0xc00e5d67c2755389aded7d8b151cbd5bcdf7ed275ad5e028b664880fc7581c77 0x0000000000000000000000000000000000000000000000000000000000000004))) +// # 0x0586c503340591999b8b38bc9834bb16aec7d5bc00eb5587ab139c9ddab81977 +func TestL1InfoDepositSource(t *testing.T) { + source := L1InfoDepositSource{ + L1BlockHash: common.HexToHash("0xc00e5d67c2755389aded7d8b151cbd5bcdf7ed275ad5e028b664880fc7581c77"), + SeqNumber: 4, + } + + actual := source.SourceHash() + expected := "0x0586c503340591999b8b38bc9834bb16aec7d5bc00eb5587ab139c9ddab81977" + + assert.Equal(t, expected, actual.Hex()) +} + +// TestAfterForceIncludeSourceHash +// cast keccak $(cast concat-hex 0x0000000000000000000000000000000000000000000000000000000000000003 $(cast keccak $(cast concat-hex 0xc00e5d67c2755389aded7d8b151cbd5bcdf7ed275ad5e028b664880fc7581c77 0x0000000000000000000000000000000000000000000000000000000000000004))) +// # 0x0d165c391384b29c29f655e3f32315755b8c1e4c1147d1824d1243420dda5ec3 +func TestAfterForceIncludeSource(t *testing.T) { + source := AfterForceIncludeSource{ + L1BlockHash: common.HexToHash("0xc00e5d67c2755389aded7d8b151cbd5bcdf7ed275ad5e028b664880fc7581c77"), + SeqNumber: 4, + } + + actual := source.SourceHash() + expected := "0x0d165c391384b29c29f655e3f32315755b8c1e4c1147d1824d1243420dda5ec3" + + assert.Equal(t, expected, actual.Hex()) +} diff --git a/op-node/rollup/derive/fuzz_parsers_test.go b/op-node/rollup/derive/fuzz_parsers_test.go index 95ce94bc7cc8..4f76c4ac7420 100644 --- a/op-node/rollup/derive/fuzz_parsers_test.go +++ b/op-node/rollup/derive/fuzz_parsers_test.go @@ -83,15 +83,26 @@ func FuzzL1InfoEcotoneRoundTrip(f *testing.F) { } enc, err := in.marshalBinaryEcotone() if err != nil { - t.Fatalf("Failed to marshal binary: %v", err) + t.Fatalf("Failed to marshal Ecotone binary: %v", err) } var out L1BlockInfo err = out.unmarshalBinaryEcotone(enc) if err != nil { - t.Fatalf("Failed to unmarshal binary: %v", err) + t.Fatalf("Failed to unmarshal Ecotone binary: %v", err) } if !cmp.Equal(in, out, cmp.Comparer(testutils.BigEqual)) { - t.Fatalf("The data did not round trip correctly. in: %v. out: %v", in, out) + t.Fatalf("The Ecotone data did not round trip correctly. in: %v. out: %v", in, out) + } + enc, err = in.marshalBinaryIsthmus() + if err != nil { + t.Fatalf("Failed to marshal Isthmus binary: %v", err) + } + err = out.unmarshalBinaryIsthmus(enc) + if err != nil { + t.Fatalf("Failed to unmarshal Isthmus binary: %v", err) + } + if !cmp.Equal(in, out, cmp.Comparer(testutils.BigEqual)) { + t.Fatalf("The Isthmus data did not round trip correctly. in: %v. out: %v", in, out) } }) diff --git a/op-node/rollup/derive/l1_block_info.go b/op-node/rollup/derive/l1_block_info.go index 26f3f6711f55..43ea9b29bedc 100644 --- a/op-node/rollup/derive/l1_block_info.go +++ b/op-node/rollup/derive/l1_block_info.go @@ -20,14 +20,25 @@ import ( const ( L1InfoFuncBedrockSignature = "setL1BlockValues(uint64,uint64,uint256,bytes32,uint64,bytes32,uint256,uint256)" L1InfoFuncEcotoneSignature = "setL1BlockValuesEcotone()" + L1InfoFuncIsthmusSignature = "setL1BlockValuesIsthmus()" + DepositsCompleteSignature = "depositsComplete()" L1InfoArguments = 8 L1InfoBedrockLen = 4 + 32*L1InfoArguments L1InfoEcotoneLen = 4 + 32*5 // after Ecotone upgrade, args are packed into 5 32-byte slots + DepositsCompleteLen = 4 // only the selector + // DepositsCompleteGas allocates 21k gas for intrinsic tx costs, and + // an additional 15k to ensure that the DepositsComplete call does not run out of gas. + // GasBenchMark_L1BlockIsthmus_DepositsComplete:test_depositsComplete_benchmark() (gas: 7768) + // GasBenchMark_L1BlockIsthmus_DepositsComplete_Warm:test_depositsComplete_benchmark() (gas: 5768) + // see `test_depositsComplete_benchmark` at: `/packages/contracts-bedrock/test/BenchmarkTest.t.sol` + DepositsCompleteGas = uint64(21_000 + 15_000) ) var ( L1InfoFuncBedrockBytes4 = crypto.Keccak256([]byte(L1InfoFuncBedrockSignature))[:4] L1InfoFuncEcotoneBytes4 = crypto.Keccak256([]byte(L1InfoFuncEcotoneSignature))[:4] + L1InfoFuncIsthmusBytes4 = crypto.Keccak256([]byte(L1InfoFuncIsthmusSignature))[:4] + DepositsCompleteBytes4 = crypto.Keccak256([]byte(DepositsCompleteSignature))[:4] L1InfoDepositerAddress = common.HexToAddress("0xdeaddeaddeaddeaddeaddeaddeaddeaddead0001") L1BlockAddress = predeploys.L1BlockAddr ErrInvalidFormat = errors.New("invalid ecotone l1 block info format") @@ -144,7 +155,7 @@ func (info *L1BlockInfo) unmarshalBinaryBedrock(data []byte) error { return nil } -// Ecotone Binary Format +// Isthmus & Ecotone Binary Format // +---------+--------------------------+ // | Bytes | Field | // +---------+--------------------------+ @@ -161,8 +172,24 @@ func (info *L1BlockInfo) unmarshalBinaryBedrock(data []byte) error { // +---------+--------------------------+ func (info *L1BlockInfo) marshalBinaryEcotone() ([]byte, error) { - w := bytes.NewBuffer(make([]byte, 0, L1InfoEcotoneLen)) - if err := solabi.WriteSignature(w, L1InfoFuncEcotoneBytes4); err != nil { + out, err := marshalBinaryWithSignature(info, L1InfoFuncEcotoneBytes4) + if err != nil { + return nil, fmt.Errorf("failed to marshal Ecotone l1 block info: %w", err) + } + return out, nil +} + +func (info *L1BlockInfo) marshalBinaryIsthmus() ([]byte, error) { + out, err := marshalBinaryWithSignature(info, L1InfoFuncIsthmusBytes4) + if err != nil { + return nil, fmt.Errorf("failed to marshal Isthmus l1 block info: %w", err) + } + return out, nil +} + +func marshalBinaryWithSignature(info *L1BlockInfo, signature []byte) ([]byte, error) { + w := bytes.NewBuffer(make([]byte, 0, L1InfoEcotoneLen)) // Ecotone and Isthmus have the same length + if err := solabi.WriteSignature(w, signature); err != nil { return nil, err } if err := binary.Write(w, binary.BigEndian, info.BaseFeeScalar); err != nil { @@ -201,13 +228,21 @@ func (info *L1BlockInfo) marshalBinaryEcotone() ([]byte, error) { } func (info *L1BlockInfo) unmarshalBinaryEcotone(data []byte) error { + return unmarshalBinaryWithSignatureAndData(info, L1InfoFuncEcotoneBytes4, data) +} + +func (info *L1BlockInfo) unmarshalBinaryIsthmus(data []byte) error { + return unmarshalBinaryWithSignatureAndData(info, L1InfoFuncIsthmusBytes4, data) +} + +func unmarshalBinaryWithSignatureAndData(info *L1BlockInfo, signature []byte, data []byte) error { if len(data) != L1InfoEcotoneLen { return fmt.Errorf("data is unexpected length: %d", len(data)) } r := bytes.NewReader(data) var err error - if _, err := solabi.ReadAndValidateSignature(r, L1InfoFuncEcotoneBytes4); err != nil { + if _, err := solabi.ReadAndValidateSignature(r, signature); err != nil { return err } if err := binary.Read(r, binary.BigEndian, &info.BaseFeeScalar); err != nil { @@ -245,14 +280,28 @@ func (info *L1BlockInfo) unmarshalBinaryEcotone(data []byte) error { } // isEcotoneButNotFirstBlock returns whether the specified block is subject to the Ecotone upgrade, -// but is not the actiation block itself. -func isEcotoneButNotFirstBlock(rollupCfg *rollup.Config, l2BlockTime uint64) bool { - return rollupCfg.IsEcotone(l2BlockTime) && !rollupCfg.IsEcotoneActivationBlock(l2BlockTime) +// but is not the activation block itself. +func isEcotoneButNotFirstBlock(rollupCfg *rollup.Config, l2Timestamp uint64) bool { + return rollupCfg.IsEcotone(l2Timestamp) && !rollupCfg.IsEcotoneActivationBlock(l2Timestamp) +} + +// isInteropButNotFirstBlock returns whether the specified block is subject to the Isthmus upgrade, +// but is not the activation block itself. +func isInteropButNotFirstBlock(rollupCfg *rollup.Config, l2Timestamp uint64) bool { + // Since we use the pre-interop L1 tx one last time during the upgrade block, + // we must disallow the deposit-txs from using the CrossL2Inbox during this block. + // If the CrossL2Inbox does not exist yet, then it is safe, + // but we have to ensure that the spec and code puts any Interop upgrade-txs after the user deposits. + return rollupCfg.IsInterop(l2Timestamp) && !rollupCfg.IsInteropActivationBlock(l2Timestamp) } // L1BlockInfoFromBytes is the inverse of L1InfoDeposit, to see where the L2 chain is derived from func L1BlockInfoFromBytes(rollupCfg *rollup.Config, l2BlockTime uint64, data []byte) (*L1BlockInfo, error) { var info L1BlockInfo + // Important, this should be ordered from most recent to oldest + if isInteropButNotFirstBlock(rollupCfg, l2BlockTime) { + return &info, info.unmarshalBinaryIsthmus(data) + } if isEcotoneButNotFirstBlock(rollupCfg, l2BlockTime) { return &info, info.unmarshalBinaryEcotone(data) } @@ -261,7 +310,7 @@ func L1BlockInfoFromBytes(rollupCfg *rollup.Config, l2BlockTime uint64, data []b // L1InfoDeposit creates a L1 Info deposit transaction based on the L1 block, // and the L2 block-height difference with the start of the epoch. -func L1InfoDeposit(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber uint64, block eth.BlockInfo, l2BlockTime uint64) (*types.DepositTx, error) { +func L1InfoDeposit(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber uint64, block eth.BlockInfo, l2Timestamp uint64) (*types.DepositTx, error) { l1BlockInfo := L1BlockInfo{ Number: block.NumberU64(), Time: block.Time(), @@ -271,7 +320,7 @@ func L1InfoDeposit(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber BatcherAddr: sysCfg.BatcherAddr, } var data []byte - if isEcotoneButNotFirstBlock(rollupCfg, l2BlockTime) { + if isEcotoneButNotFirstBlock(rollupCfg, l2Timestamp) { l1BlockInfo.BlobBaseFee = block.BlobBaseFee() if l1BlockInfo.BlobBaseFee == nil { // The L2 spec states to use the MIN_BLOB_GASPRICE from EIP-4844 if not yet active on L1. @@ -283,11 +332,19 @@ func L1InfoDeposit(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber } l1BlockInfo.BlobBaseFeeScalar = scalars.BlobBaseFeeScalar l1BlockInfo.BaseFeeScalar = scalars.BaseFeeScalar - out, err := l1BlockInfo.marshalBinaryEcotone() - if err != nil { - return nil, fmt.Errorf("failed to marshal Ecotone l1 block info: %w", err) + if isInteropButNotFirstBlock(rollupCfg, l2Timestamp) { + out, err := l1BlockInfo.marshalBinaryIsthmus() + if err != nil { + return nil, fmt.Errorf("failed to marshal Isthmus l1 block info: %w", err) + } + data = out + } else { + out, err := l1BlockInfo.marshalBinaryEcotone() + if err != nil { + return nil, fmt.Errorf("failed to marshal Ecotone l1 block info: %w", err) + } + data = out } - data = out } else { l1BlockInfo.L1FeeOverhead = sysCfg.Overhead l1BlockInfo.L1FeeScalar = sysCfg.Scalar @@ -315,7 +372,7 @@ func L1InfoDeposit(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber Data: data, } // With the regolith fork we disable the IsSystemTx functionality, and allocate real gas - if rollupCfg.IsRegolith(l2BlockTime) { + if rollupCfg.IsRegolith(l2Timestamp) { out.IsSystemTransaction = false out.Gas = RegolithSystemTxGas } @@ -323,8 +380,8 @@ func L1InfoDeposit(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber } // L1InfoDepositBytes returns a serialized L1-info attributes transaction. -func L1InfoDepositBytes(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber uint64, l1Info eth.BlockInfo, l2BlockTime uint64) ([]byte, error) { - dep, err := L1InfoDeposit(rollupCfg, sysCfg, seqNumber, l1Info, l2BlockTime) +func L1InfoDepositBytes(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber uint64, l1Info eth.BlockInfo, l2Timestamp uint64) ([]byte, error) { + dep, err := L1InfoDeposit(rollupCfg, sysCfg, seqNumber, l1Info, l2Timestamp) if err != nil { return nil, fmt.Errorf("failed to create L1 info tx: %w", err) } @@ -335,3 +392,34 @@ func L1InfoDepositBytes(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNu } return opaqueL1Tx, nil } + +func DepositsCompleteDeposit(seqNumber uint64, block eth.BlockInfo) (*types.DepositTx, error) { + source := AfterForceIncludeSource{ + L1BlockHash: block.Hash(), + SeqNumber: seqNumber, + } + out := &types.DepositTx{ + SourceHash: source.SourceHash(), + From: L1InfoDepositerAddress, + To: &L1BlockAddress, + Mint: nil, + Value: big.NewInt(0), + Gas: DepositsCompleteGas, + IsSystemTransaction: false, + Data: DepositsCompleteBytes4, + } + return out, nil +} + +func DepositsCompleteBytes(seqNumber uint64, l1Info eth.BlockInfo) ([]byte, error) { + dep, err := DepositsCompleteDeposit(seqNumber, l1Info) + if err != nil { + return nil, fmt.Errorf("failed to create DepositsComplete tx: %w", err) + } + depositsCompleteTx := types.NewTx(dep) + opaqueDepositsCompleteTx, err := depositsCompleteTx.MarshalBinary() + if err != nil { + return nil, fmt.Errorf("failed to encode DepositsComplete tx: %w", err) + } + return opaqueDepositsCompleteTx, nil +} diff --git a/op-node/rollup/derive/l1_block_info_test.go b/op-node/rollup/derive/l1_block_info_test.go index e5c9253ce1c6..b98e8a7d4c63 100644 --- a/op-node/rollup/derive/l1_block_info_test.go +++ b/op-node/rollup/derive/l1_block_info_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-service/eth" @@ -109,10 +110,8 @@ func TestParseL1InfoDepositTxData(t *testing.T) { t.Run("regolith", func(t *testing.T) { rng := rand.New(rand.NewSource(1234)) info := testutils.MakeBlockInfo(nil)(rng) - zero := uint64(0) - rollupCfg := rollup.Config{ - RegolithTime: &zero, - } + rollupCfg := rollup.Config{} + rollupCfg.ActivateAtGenesis(rollup.Regolith) depTx, err := L1InfoDeposit(&rollupCfg, randomL1Cfg(rng, info), randomSeqNr(rng), info, 0) require.NoError(t, err) require.False(t, depTx.IsSystemTransaction) @@ -121,27 +120,24 @@ func TestParseL1InfoDepositTxData(t *testing.T) { t.Run("ecotone", func(t *testing.T) { rng := rand.New(rand.NewSource(1234)) info := testutils.MakeBlockInfo(nil)(rng) - zero := uint64(0) - rollupCfg := rollup.Config{ - RegolithTime: &zero, - EcotoneTime: &zero, - } - depTx, err := L1InfoDeposit(&rollupCfg, randomL1Cfg(rng, info), randomSeqNr(rng), info, 1) + rollupCfg := rollup.Config{BlockTime: 2, Genesis: rollup.Genesis{L2Time: 1000}} + rollupCfg.ActivateAtGenesis(rollup.Ecotone) + // run 1 block after ecotone transition + timestamp := rollupCfg.Genesis.L2Time + rollupCfg.BlockTime + depTx, err := L1InfoDeposit(&rollupCfg, randomL1Cfg(rng, info), randomSeqNr(rng), info, timestamp) require.NoError(t, err) require.False(t, depTx.IsSystemTransaction) require.Equal(t, depTx.Gas, uint64(RegolithSystemTxGas)) require.Equal(t, L1InfoEcotoneLen, len(depTx.Data)) }) - t.Run("first-block ecotone", func(t *testing.T) { + t.Run("activation-block ecotone", func(t *testing.T) { rng := rand.New(rand.NewSource(1234)) info := testutils.MakeBlockInfo(nil)(rng) - zero := uint64(2) - rollupCfg := rollup.Config{ - RegolithTime: &zero, - EcotoneTime: &zero, - BlockTime: 2, - } - depTx, err := L1InfoDeposit(&rollupCfg, randomL1Cfg(rng, info), randomSeqNr(rng), info, 2) + rollupCfg := rollup.Config{BlockTime: 2, Genesis: rollup.Genesis{L2Time: 1000}} + rollupCfg.ActivateAtGenesis(rollup.Delta) + ecotoneTime := rollupCfg.Genesis.L2Time + rollupCfg.BlockTime // activate ecotone just after genesis + rollupCfg.EcotoneTime = &ecotoneTime + depTx, err := L1InfoDeposit(&rollupCfg, randomL1Cfg(rng, info), randomSeqNr(rng), info, ecotoneTime) require.NoError(t, err) require.False(t, depTx.IsSystemTransaction) require.Equal(t, depTx.Gas, uint64(RegolithSystemTxGas)) @@ -150,16 +146,88 @@ func TestParseL1InfoDepositTxData(t *testing.T) { t.Run("genesis-block ecotone", func(t *testing.T) { rng := rand.New(rand.NewSource(1234)) info := testutils.MakeBlockInfo(nil)(rng) - zero := uint64(0) - rollupCfg := rollup.Config{ - RegolithTime: &zero, - EcotoneTime: &zero, - BlockTime: 2, - } - depTx, err := L1InfoDeposit(&rollupCfg, randomL1Cfg(rng, info), randomSeqNr(rng), info, 0) + rollupCfg := rollup.Config{BlockTime: 2, Genesis: rollup.Genesis{L2Time: 1000}} + rollupCfg.ActivateAtGenesis(rollup.Ecotone) + depTx, err := L1InfoDeposit(&rollupCfg, randomL1Cfg(rng, info), randomSeqNr(rng), info, rollupCfg.Genesis.L2Time) + require.NoError(t, err) + require.False(t, depTx.IsSystemTransaction) + require.Equal(t, depTx.Gas, uint64(RegolithSystemTxGas)) + require.Equal(t, L1InfoEcotoneLen, len(depTx.Data)) + }) + t.Run("isthmus", func(t *testing.T) { + rng := rand.New(rand.NewSource(1234)) + info := testutils.MakeBlockInfo(nil)(rng) + rollupCfg := rollup.Config{BlockTime: 2, Genesis: rollup.Genesis{L2Time: 1000}} + rollupCfg.ActivateAtGenesis(rollup.Interop) + // run 1 block after interop transition + timestamp := rollupCfg.Genesis.L2Time + rollupCfg.BlockTime + depTx, err := L1InfoDeposit(&rollupCfg, randomL1Cfg(rng, info), randomSeqNr(rng), info, timestamp) + require.NoError(t, err) + require.False(t, depTx.IsSystemTransaction) + require.Equal(t, depTx.Gas, uint64(RegolithSystemTxGas)) + require.Equal(t, L1InfoEcotoneLen, len(depTx.Data), "the length is same in isthmus") + require.Equal(t, L1InfoFuncIsthmusBytes4, depTx.Data[:4], "upgrade is active, need isthmus signature") + }) + t.Run("activation-block isthmus", func(t *testing.T) { + rng := rand.New(rand.NewSource(1234)) + info := testutils.MakeBlockInfo(nil)(rng) + rollupCfg := rollup.Config{BlockTime: 2, Genesis: rollup.Genesis{L2Time: 1000}} + rollupCfg.ActivateAtGenesis(rollup.Fjord) + isthmusTime := rollupCfg.Genesis.L2Time + rollupCfg.BlockTime // activate isthmus just after genesis + rollupCfg.InteropTime = &isthmusTime + depTx, err := L1InfoDeposit(&rollupCfg, randomL1Cfg(rng, info), randomSeqNr(rng), info, isthmusTime) + require.NoError(t, err) + require.False(t, depTx.IsSystemTransaction) + require.Equal(t, depTx.Gas, uint64(RegolithSystemTxGas)) + // Isthmus activates, but ecotone L1 info is still used at this upgrade block + require.Equal(t, L1InfoEcotoneLen, len(depTx.Data)) + require.Equal(t, L1InfoFuncEcotoneBytes4, depTx.Data[:4]) + }) + t.Run("genesis-block isthmus", func(t *testing.T) { + rng := rand.New(rand.NewSource(1234)) + info := testutils.MakeBlockInfo(nil)(rng) + rollupCfg := rollup.Config{BlockTime: 2, Genesis: rollup.Genesis{L2Time: 1000}} + rollupCfg.ActivateAtGenesis(rollup.Interop) + depTx, err := L1InfoDeposit(&rollupCfg, randomL1Cfg(rng, info), randomSeqNr(rng), info, rollupCfg.Genesis.L2Time) require.NoError(t, err) require.False(t, depTx.IsSystemTransaction) require.Equal(t, depTx.Gas, uint64(RegolithSystemTxGas)) require.Equal(t, L1InfoEcotoneLen, len(depTx.Data)) }) } + +func TestDepositsCompleteBytes(t *testing.T) { + randomSeqNr := func(rng *rand.Rand) uint64 { + return rng.Uint64() + } + t.Run("valid return bytes", func(t *testing.T) { + rng := rand.New(rand.NewSource(1234)) + info := testutils.MakeBlockInfo(nil)(rng) + depTxByes, err := DepositsCompleteBytes(randomSeqNr(rng), info) + require.NoError(t, err) + var depTx types.Transaction + require.NoError(t, depTx.UnmarshalBinary(depTxByes)) + require.Equal(t, uint8(types.DepositTxType), depTx.Type()) + require.Equal(t, depTx.Data(), DepositsCompleteBytes4) + require.Equal(t, DepositsCompleteLen, len(depTx.Data())) + require.Equal(t, DepositsCompleteGas, depTx.Gas()) + require.False(t, depTx.IsSystemTx()) + require.Equal(t, depTx.Value(), big.NewInt(0)) + signer := types.LatestSignerForChainID(depTx.ChainId()) + sender, err := signer.Sender(&depTx) + require.NoError(t, err) + require.Equal(t, L1InfoDepositerAddress, sender) + }) + t.Run("valid return Transaction", func(t *testing.T) { + rng := rand.New(rand.NewSource(1234)) + info := testutils.MakeBlockInfo(nil)(rng) + depTx, err := DepositsCompleteDeposit(randomSeqNr(rng), info) + require.NoError(t, err) + require.Equal(t, depTx.Data, DepositsCompleteBytes4) + require.Equal(t, DepositsCompleteLen, len(depTx.Data)) + require.Equal(t, DepositsCompleteGas, depTx.Gas) + require.False(t, depTx.IsSystemTransaction) + require.Equal(t, depTx.Value, big.NewInt(0)) + require.Equal(t, L1InfoDepositerAddress, depTx.From) + }) +} diff --git a/op-node/rollup/types.go b/op-node/rollup/types.go index fec118567c56..0c611a5d8d35 100644 --- a/op-node/rollup/types.go +++ b/op-node/rollup/types.go @@ -463,6 +463,40 @@ func (c *Config) IsInteropActivationBlock(l2BlockTime uint64) bool { !c.IsInterop(l2BlockTime-c.BlockTime) } +func (c *Config) ActivateAtGenesis(hardfork ForkName) { + // IMPORTANT! ordered from newest to oldest + switch hardfork { + case Interop: + c.InteropTime = new(uint64) + fallthrough + case Holocene: + c.HoloceneTime = new(uint64) + fallthrough + case Granite: + c.GraniteTime = new(uint64) + fallthrough + case Fjord: + c.FjordTime = new(uint64) + fallthrough + case Ecotone: + c.EcotoneTime = new(uint64) + fallthrough + case Delta: + c.DeltaTime = new(uint64) + fallthrough + case Canyon: + c.CanyonTime = new(uint64) + fallthrough + case Regolith: + c.RegolithTime = new(uint64) + fallthrough + case Bedrock: + // default + case None: + break + } +} + // ForkchoiceUpdatedVersion returns the EngineAPIMethod suitable for the chain hard fork version. func (c *Config) ForkchoiceUpdatedVersion(attr *eth.PayloadAttributes) eth.EngineAPIMethod { if attr == nil { diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index b3ea3b88545e..b28d6b6c9cad 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -1,3 +1,9 @@ +GasBenchMark_L1BlockIsthmus_DepositsComplete:test_depositsComplete_benchmark() (gas: 7567) +GasBenchMark_L1BlockIsthmus_DepositsComplete_Warm:test_depositsComplete_benchmark() (gas: 5567) +GasBenchMark_L1BlockIsthmus_SetValuesIsthmus:test_setL1BlockValuesIsthmus_benchmark() (gas: 175657) +GasBenchMark_L1BlockIsthmus_SetValuesIsthmus_Warm:test_setL1BlockValuesIsthmus_benchmark() (gas: 5121) +GasBenchMark_L1Block_SetValuesEcotone:test_setL1BlockValuesEcotone_benchmark() (gas: 158531) +GasBenchMark_L1Block_SetValuesEcotone_Warm:test_setL1BlockValuesEcotone_benchmark() (gas: 7597) GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 369356) GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2967496) GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 564483) diff --git a/packages/contracts-bedrock/scripts/L2Genesis.s.sol b/packages/contracts-bedrock/scripts/L2Genesis.s.sol index ba2c5e4bf4f4..eb2f8d396365 100644 --- a/packages/contracts-bedrock/scripts/L2Genesis.s.sol +++ b/packages/contracts-bedrock/scripts/L2Genesis.s.sol @@ -357,7 +357,7 @@ contract L2Genesis is Deployer { /// @notice This predeploy is following the safety invariant #1. function setL1Block() public { if (cfg.useInterop()) { - string memory cname = "L1BlockInterop"; + string memory cname = "L1BlockIsthmus"; address impl = Predeploys.predeployToCodeNamespace(Predeploys.L1_BLOCK_ATTRIBUTES); console.log("Setting %s implementation at: %s", cname, impl); vm.etch(impl, vm.getDeployedCode(string.concat(cname, ".sol:", cname))); diff --git a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh index 0bcf73a3d2ad..827ae5ee4452 100755 --- a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh +++ b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh @@ -67,6 +67,7 @@ EXCLUDE_CONTRACTS=( "IL1StandardBridge" "ISuperchainConfig" "IOptimismPortal" + "IL1BlockIsthmus" ) # Find all JSON files in the forge-artifacts folder diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 8ee179e7bd7c..5f885b995732 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -45,7 +45,7 @@ }, "src/L1/OptimismPortalInterop.sol": { "initCodeHash": "0x9222fba222d1ab66898eef09ecea3ea757e64c8ae98def4da7808cd7cc8f39a8", - "sourceCodeHash": "0x3fc9d9fc1143bec92801f8a18ad3527533923dc26c4820d03d6905f519d735b4" + "sourceCodeHash": "0x57353b84bbcb05634f135ad8090d96f07467dd3dbf159650714449d0667efc62" }, "src/L1/ProtocolVersions.sol": { "initCodeHash": "0x8f033874dd8b36615b2209d553660dcff1ff91ca2bad3ca1de7b441dbfba4842", @@ -61,15 +61,15 @@ }, "src/L1/SystemConfigInterop.sol": { "initCodeHash": "0xc5a3ffc59dd7bf1ef238087414cfa04b37f0d83fc9a4f5e6d62a1059a23359f3", - "sourceCodeHash": "0x71606c81ff4e69bac78d04731287c34dfb20a648ad384646926a62c16344e0d7" + "sourceCodeHash": "0x272bcfafab62516609250c85cd73815bf0a243fdb9d34fc603f71e801299b57c" }, "src/L2/BaseFeeVault.sol": { "initCodeHash": "0x3bfcd57e25ad54b66c374f63e24e33a6cf107044aa8f5f69ef21202c380b5c5b", "sourceCodeHash": "0x2dc2284cf7c68e743da50e4113e96ffeab435de2390aeba2eab2f1e8ca411ce9" }, "src/L2/CrossL2Inbox.sol": { - "initCodeHash": "0x926ec5b92a5ff032c00ae13f1156332cb43b98b89573467e9ddfab6fce9f3e95", - "sourceCodeHash": "0xd5d3f9f1ff7d15367e200832d3257514c6e8cf3cf64703111111982c0ea4840b" + "initCodeHash": "0x79c5deb404605b42ef917b5e7308a9015dacfb71225d957a634e6d0a3a5bc621", + "sourceCodeHash": "0xd219408d99f627770dfcdb3243a183dec7429372787f0aec3bdbff5b3c294f2a" }, "src/L2/ETHLiquidity.sol": { "initCodeHash": "0x1d9958d75fd502f018408ed5585d541b156435ac9c163009135b866d66f8f6ee", @@ -80,12 +80,12 @@ "sourceCodeHash": "0xaef30eab756a3804a241f57c8bb787179376477f6344a6ae49771d532153c9d3" }, "src/L2/L1Block.sol": { - "initCodeHash": "0xb12c0560e4e0aed12df5f65a1bc2b302afd183601c149285a26eafe5e4c20c0e", - "sourceCodeHash": "0x30aef5ac102e3655651ff821ce560ecf0da0914456379b784f5652fe09c37aa3" + "initCodeHash": "0x21a09e366c69cae22f8fa3f3e1ddbbfed19408dee19f482a3d60ae699bebf462", + "sourceCodeHash": "0x254a5709e04e5a3b0a3e73253525457d956fde5299b22da4033012a44070ea09" }, - "src/L2/L1BlockInterop.sol": { - "initCodeHash": "0xd2afdf64b0232264e4996e0557523c108c2f12a9b6d2de45dfd961f7a1c927e3", - "sourceCodeHash": "0xfd2283b341239be76b0b8fa067e8ccdf71ef5b29eb75df6783d9f004a9203530" + "src/L2/L1BlockIsthmus.sol": { + "initCodeHash": "0x93b0a4bc7a0990e5c4e7081fce10f729f4d1c8e9128a7931a610152b786dc461", + "sourceCodeHash": "0x6e4927fb8c26273694257696ff286ed0382d8bd1ecaf02abec51aa4b53922c68" }, "src/L2/L1FeeVault.sol": { "initCodeHash": "0x3bfcd57e25ad54b66c374f63e24e33a6cf107044aa8f5f69ef21202c380b5c5b", diff --git a/packages/contracts-bedrock/snapshots/abi/CrossL2Inbox.json b/packages/contracts-bedrock/snapshots/abi/CrossL2Inbox.json index 7253ac21bdcb..6f8c10e82eed 100644 --- a/packages/contracts-bedrock/snapshots/abi/CrossL2Inbox.json +++ b/packages/contracts-bedrock/snapshots/abi/CrossL2Inbox.json @@ -253,6 +253,11 @@ "name": "InvalidTimestamp", "type": "error" }, + { + "inputs": [], + "name": "NoExecutingDeposits", + "type": "error" + }, { "inputs": [], "name": "NotDepositor", diff --git a/packages/contracts-bedrock/snapshots/abi/L1BlockInterop.json b/packages/contracts-bedrock/snapshots/abi/L1BlockIsthmus.json similarity index 93% rename from packages/contracts-bedrock/snapshots/abi/L1BlockInterop.json rename to packages/contracts-bedrock/snapshots/abi/L1BlockIsthmus.json index 146691aff1a1..d827b32a9cab 100644 --- a/packages/contracts-bedrock/snapshots/abi/L1BlockInterop.json +++ b/packages/contracts-bedrock/snapshots/abi/L1BlockIsthmus.json @@ -90,6 +90,13 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "depositsComplete", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "gasPayingToken", @@ -160,6 +167,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "isDeposit", + "outputs": [ + { + "internalType": "bool", + "name": "isDeposit_", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -332,6 +352,13 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "setL1BlockValuesIsthmus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "timestamp", @@ -430,6 +457,11 @@ "name": "DependencySetSizeTooLarge", "type": "error" }, + { + "inputs": [], + "name": "NotCrossL2Inbox", + "type": "error" + }, { "inputs": [], "name": "NotDependency", diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L1BlockInterop.json b/packages/contracts-bedrock/snapshots/storageLayout/L1BlockIsthmus.json similarity index 100% rename from packages/contracts-bedrock/snapshots/storageLayout/L1BlockInterop.json rename to packages/contracts-bedrock/snapshots/storageLayout/L1BlockIsthmus.json diff --git a/packages/contracts-bedrock/src/L1/OptimismPortalInterop.sol b/packages/contracts-bedrock/src/L1/OptimismPortalInterop.sol index b22b7092a73f..ffbb1afefa5a 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortalInterop.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortalInterop.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; -import { L1BlockInterop, ConfigType } from "src/L2/L1BlockInterop.sol"; +import { L1BlockIsthmus, ConfigType } from "src/L2/L1BlockIsthmus.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { Constants } from "src/libraries/Constants.sol"; @@ -47,7 +47,7 @@ contract OptimismPortalInterop is OptimismPortal2 { uint256(0), // value uint64(SYSTEM_DEPOSIT_GAS_LIMIT), // gasLimit false, // isCreation, - abi.encodeCall(L1BlockInterop.setConfig, (_type, _value)) + abi.encodeCall(L1BlockIsthmus.setConfig, (_type, _value)) ) ); } diff --git a/packages/contracts-bedrock/src/L1/SystemConfigInterop.sol b/packages/contracts-bedrock/src/L1/SystemConfigInterop.sol index 39f1f35ca6e8..0033bfa54fae 100644 --- a/packages/contracts-bedrock/src/L1/SystemConfigInterop.sol +++ b/packages/contracts-bedrock/src/L1/SystemConfigInterop.sol @@ -6,7 +6,7 @@ import { OptimismPortalInterop as OptimismPortal } from "src/L1/OptimismPortalIn import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; -import { ConfigType } from "src/L2/L1BlockInterop.sol"; +import { ConfigType } from "src/L2/L1BlockIsthmus.sol"; import { StaticConfig } from "src/libraries/StaticConfig.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { Storage } from "src/libraries/Storage.sol"; diff --git a/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol b/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol index d662fec3f28c..6f86717c4e4d 100644 --- a/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol +++ b/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol @@ -7,6 +7,7 @@ import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ICrossL2Inbox } from "src/L2/interfaces/ICrossL2Inbox.sol"; import { SafeCall } from "src/libraries/SafeCall.sol"; import { IDependencySet } from "src/L2/interfaces/IDependencySet.sol"; +import { IL1BlockIsthmus } from "src/L2/interfaces/IL1BlockIsthmus.sol"; /// @notice Thrown when the caller is not DEPOSITOR_ACCOUNT when calling `setInteropStart()` error NotDepositor(); @@ -26,6 +27,9 @@ error InvalidChainId(); /// @notice Thrown when trying to execute a cross chain message and the target call fails. error TargetCallFailed(); +/// @notice Thrown when trying to execute a cross chain message on a deposit transaction. +error NoExecutingDeposits(); + /// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000022 /// @title CrossL2Inbox @@ -135,6 +139,9 @@ contract CrossL2Inbox is ICrossL2Inbox, ISemver, TransientReentrancyAware { payable reentrantAware { + // We need to know if this is being called on a depositTx + if (IL1BlockIsthmus(Predeploys.L1_BLOCK_ATTRIBUTES).isDeposit()) revert NoExecutingDeposits(); + // Check the Identifier. _checkIdentifier(_id); diff --git a/packages/contracts-bedrock/src/L2/L1Block.sol b/packages/contracts-bedrock/src/L2/L1Block.sol index f3c86e248c2c..ffcca0bf7ceb 100644 --- a/packages/contracts-bedrock/src/L2/L1Block.sol +++ b/packages/contracts-bedrock/src/L2/L1Block.sol @@ -57,9 +57,9 @@ contract L1Block is ISemver, IGasToken { /// @notice The latest L1 blob base fee. uint256 public blobBaseFee; - /// @custom:semver 1.4.1-beta.2 + /// @custom:semver 1.5.1-beta.1 function version() public pure virtual returns (string memory) { - return "1.4.1-beta.2"; + return "1.5.1-beta.1"; } /// @notice Returns the gas paying token, its decimals, name and symbol. @@ -133,7 +133,23 @@ contract L1Block is ISemver, IGasToken { /// 7. _blobBaseFee L1 blob base fee. /// 8. _hash L1 blockhash. /// 9. _batcherHash Versioned hash to authenticate batcher by. - function setL1BlockValuesEcotone() external { + function setL1BlockValuesEcotone() public { + _setL1BlockValuesEcotone(); + } + + /// @notice Updates the L1 block values for an Ecotone upgraded chain. + /// Params are packed and passed in as raw msg.data instead of ABI to reduce calldata size. + /// Params are expected to be in the following order: + /// 1. _baseFeeScalar L1 base fee scalar + /// 2. _blobBaseFeeScalar L1 blob base fee scalar + /// 3. _sequenceNumber Number of L2 blocks since epoch start. + /// 4. _timestamp L1 timestamp. + /// 5. _number L1 blocknumber. + /// 6. _basefee L1 base fee. + /// 7. _blobBaseFee L1 blob base fee. + /// 8. _hash L1 blockhash. + /// 9. _batcherHash Versioned hash to authenticate batcher by. + function _setL1BlockValuesEcotone() internal { address depositor = DEPOSITOR_ACCOUNT(); assembly { // Revert if the caller is not the depositor account. diff --git a/packages/contracts-bedrock/src/L2/L1BlockInterop.sol b/packages/contracts-bedrock/src/L2/L1BlockIsthmus.sol similarity index 69% rename from packages/contracts-bedrock/src/L2/L1BlockInterop.sol rename to packages/contracts-bedrock/src/L2/L1BlockIsthmus.sol index 4b445e6d566c..bd848aba3e81 100644 --- a/packages/contracts-bedrock/src/L2/L1BlockInterop.sol +++ b/packages/contracts-bedrock/src/L2/L1BlockIsthmus.sol @@ -5,9 +5,10 @@ import { L1Block } from "src/L2/L1Block.sol"; import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; import { StaticConfig } from "src/libraries/StaticConfig.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; import "src/libraries/L1BlockErrors.sol"; -/// @notice Enum representing different types of configurations that can be set on L1BlockInterop. +/// @notice Enum representing different types of configurations that can be set on L1BlockIsthmus. /// @custom:value SET_GAS_PAYING_TOKEN Represents the config type for setting the gas paying token. /// @custom:value ADD_DEPENDENCY Represents the config type for adding a chain to the interop dependency set. /// @custom:value REMOVE_DEPENDENCY Represents the config type for removing a chain from the interop dependency set. @@ -19,9 +20,9 @@ enum ConfigType { /// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000015 -/// @title L1BlockInterop -/// @notice Interop extenstions of L1Block. -contract L1BlockInterop is L1Block { +/// @title L1BlockIsthmus +/// @notice Isthmus extenstions of L1Block. +contract L1BlockIsthmus is L1Block { using EnumerableSet for EnumerableSet.UintSet; /// @notice Event emitted when a new dependency is added to the interop dependency set. @@ -33,9 +34,23 @@ contract L1BlockInterop is L1Block { /// @notice The interop dependency set, containing the chain IDs in it. EnumerableSet.UintSet dependencySet; - /// @custom:semver +interop + /// @notice Storage slot that the isDeposit is stored at. + /// This is a custom slot that is not part of the standard storage layout. + /// keccak256(abi.encode(uint256(keccak256("l1Block.identifier.isDeposit")) - 1)) & ~bytes32(uint256(0xff)) + uint256 internal constant IS_DEPOSIT_SLOT = 0x921bd3a089295c6e5540e8fba8195448d253efd6f2e3e495b499b627dc36a300; + + /// @custom:semver +isthmus function version() public pure override returns (string memory) { - return string.concat(super.version(), "+interop"); + return string.concat(super.version(), "+isthmus"); + } + + /// @notice Returns whether the call was triggered from a a deposit or not. + /// @notice This function is only callable by the CrossL2Inbox contract. + function isDeposit() external view returns (bool isDeposit_) { + if (msg.sender != Predeploys.CROSS_L2_INBOX) revert NotCrossL2Inbox(); + assembly { + isDeposit_ := sload(IS_DEPOSIT_SLOT) + } } /// @notice Returns true if a chain ID is in the interop dependency set and false otherwise. @@ -52,6 +67,29 @@ contract L1BlockInterop is L1Block { return uint8(dependencySet.length()); } + /// @notice Updates the `isDeposit` flag and sets the L1 block values for an Isthmus upgraded chain. + /// It updates the L1 block values through the `setL1BlockValuesEcotone` function. + /// It forwards the calldata to the internally-used `setL1BlockValuesEcotone` function. + function setL1BlockValuesIsthmus() external { + // Set the isDeposit flag to true. + assembly { + sstore(IS_DEPOSIT_SLOT, 1) + } + + _setL1BlockValuesEcotone(); + } + + /// @notice Resets the isDeposit flag. + /// Should only be called by the depositor account after the deposits are complete. + function depositsComplete() external { + if (msg.sender != DEPOSITOR_ACCOUNT()) revert NotDepositor(); + + // Set the isDeposit flag to false. + assembly { + sstore(IS_DEPOSIT_SLOT, 0) + } + } + /// @notice Sets static configuration options for the L2 system. Can only be called by the special /// depositor account. /// @param _type The type of configuration to set. diff --git a/packages/contracts-bedrock/src/L2/interfaces/IL1BlockIsthmus.sol b/packages/contracts-bedrock/src/L2/interfaces/IL1BlockIsthmus.sol new file mode 100644 index 000000000000..a622a1fa3fee --- /dev/null +++ b/packages/contracts-bedrock/src/L2/interfaces/IL1BlockIsthmus.sol @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IL1BlockIsthmus { + type ConfigType is uint8; + + error AlreadyDependency(); + error CantRemovedDependency(); + error DependencySetSizeTooLarge(); + error NotCrossL2Inbox(); + error NotDependency(); + error NotDepositor(); + + event DependencyAdded(uint256 indexed chainId); + event DependencyRemoved(uint256 indexed chainId); + event GasPayingTokenSet(address indexed token, uint8 indexed decimals, bytes32 name, bytes32 symbol); + + function DEPOSITOR_ACCOUNT() external pure returns (address addr_); + function baseFeeScalar() external view returns (uint32); + function basefee() external view returns (uint256); + function batcherHash() external view returns (bytes32); + function blobBaseFee() external view returns (uint256); + function blobBaseFeeScalar() external view returns (uint32); + function dependencySetSize() external view returns (uint8); + function depositsComplete() external; + function gasPayingToken() external view returns (address addr_, uint8 decimals_); + function gasPayingTokenName() external view returns (string memory name_); + function gasPayingTokenSymbol() external view returns (string memory symbol_); + function hash() external view returns (bytes32); + function isCustomGasToken() external view returns (bool); + function isDeposit() external view returns (bool isDeposit_); + function isInDependencySet(uint256 _chainId) external view returns (bool); + function l1FeeOverhead() external view returns (uint256); + function l1FeeScalar() external view returns (uint256); + function number() external view returns (uint64); + function sequenceNumber() external view returns (uint64); + function setConfig(ConfigType _type, bytes memory _value) external; + function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external; + function setL1BlockValues( + uint64 _number, + uint64 _timestamp, + uint256 _basefee, + bytes32 _hash, + uint64 _sequenceNumber, + bytes32 _batcherHash, + uint256 _l1FeeOverhead, + uint256 _l1FeeScalar + ) + external; + function setL1BlockValuesEcotone() external; + function setL1BlockValuesIsthmus() external; + function timestamp() external view returns (uint64); + function version() external pure returns (string memory); +} diff --git a/packages/contracts-bedrock/src/libraries/Encoding.sol b/packages/contracts-bedrock/src/libraries/Encoding.sol index dae9486c7c63..7ab1a285841f 100644 --- a/packages/contracts-bedrock/src/libraries/Encoding.sol +++ b/packages/contracts-bedrock/src/libraries/Encoding.sol @@ -184,8 +184,7 @@ library Encoding { /// @param _blobBaseFee L1 blob base fee. /// @param _hash L1 blockhash. /// @param _batcherHash Versioned hash to authenticate batcher by. - /// @param _dependencySet Array of the chain IDs in the interop dependency set. - function encodeSetL1BlockValuesInterop( + function encodeSetL1BlockValuesIsthmus( uint32 _baseFeeScalar, uint32 _blobBaseFeeScalar, uint64 _sequenceNumber, @@ -194,18 +193,13 @@ library Encoding { uint256 _baseFee, uint256 _blobBaseFee, bytes32 _hash, - bytes32 _batcherHash, - uint256[] memory _dependencySet + bytes32 _batcherHash ) internal pure returns (bytes memory) { - require(_dependencySet.length <= type(uint8).max, "Encoding: dependency set length is too large"); - // Check that the batcher hash is just the address with 0 padding to the left for version 0. - require(uint160(uint256(_batcherHash)) == uint256(_batcherHash), "Encoding: invalid batcher hash"); - - bytes4 functionSignature = bytes4(keccak256("setL1BlockValuesInterop()")); + bytes4 functionSignature = bytes4(keccak256("setL1BlockValuesIsthmus()")); return abi.encodePacked( functionSignature, _baseFeeScalar, @@ -216,9 +210,7 @@ library Encoding { _baseFee, _blobBaseFee, _hash, - _batcherHash, - uint8(_dependencySet.length), - _dependencySet + _batcherHash ); } } diff --git a/packages/contracts-bedrock/src/libraries/L1BlockErrors.sol b/packages/contracts-bedrock/src/libraries/L1BlockErrors.sol index c9ef3903aebe..44e156e158c0 100644 --- a/packages/contracts-bedrock/src/libraries/L1BlockErrors.sol +++ b/packages/contracts-bedrock/src/libraries/L1BlockErrors.sol @@ -4,6 +4,9 @@ pragma solidity ^0.8.0; /// @notice Error returns when a non-depositor account tries to set L1 block values. error NotDepositor(); +/// @notice Error when a non-cross L2 Inbox sender tries to call the `isDeposit()` method. +error NotCrossL2Inbox(); + /// @notice Error when a chain ID is not in the interop dependency set. error NotDependency(); diff --git a/packages/contracts-bedrock/src/libraries/SafeCall.sol b/packages/contracts-bedrock/src/libraries/SafeCall.sol index c2c4e635f0fb..a8ae9ec8be32 100644 --- a/packages/contracts-bedrock/src/libraries/SafeCall.sol +++ b/packages/contracts-bedrock/src/libraries/SafeCall.sol @@ -67,6 +67,13 @@ library SafeCall { success_ = call({ _target: _target, _gas: gasleft(), _value: _value, _calldata: _calldata }); } + /// @notice Perform a low level call without copying any returndata + /// @param _target Address to call + /// @param _calldata Calldata to pass to the call + function call(address _target, bytes memory _calldata) internal returns (bool success_) { + success_ = call({ _target: _target, _gas: gasleft(), _value: 0, _calldata: _calldata }); + } + /// @notice Helper function to determine if there is sufficient gas remaining within the context /// to guarantee that the minimum gas requirement for a call will be met as well as /// optionally reserving a specified amount of gas for after the call has concluded. diff --git a/packages/contracts-bedrock/test/BenchmarkTest.t.sol b/packages/contracts-bedrock/test/BenchmarkTest.t.sol index 4722107a314f..060ceddcc136 100644 --- a/packages/contracts-bedrock/test/BenchmarkTest.t.sol +++ b/packages/contracts-bedrock/test/BenchmarkTest.t.sol @@ -9,6 +9,9 @@ import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { Types } from "src/libraries/Types.sol"; +import { SafeCall } from "src/libraries/SafeCall.sol"; +import { L1BlockIsthmus } from "src/L2/L1BlockIsthmus.sol"; +import { Encoding } from "src/libraries/Encoding.sol"; // Free function for setting the prevBaseFee param in the OptimismPortal. function setPrevBaseFee(Vm _vm, address _op, uint128 _prevBaseFee) { @@ -209,3 +212,101 @@ contract GasBenchMark_L2OutputOracle is CommonTest { l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0); } } + +contract GasBenchMark_L1Block is CommonTest { + address depositor; + bytes setValuesCalldata; + + function setUp() public virtual override { + super.setUp(); + depositor = l1Block.DEPOSITOR_ACCOUNT(); + setValuesCalldata = Encoding.encodeSetL1BlockValuesEcotone( + type(uint32).max, + type(uint32).max, + type(uint64).max, + type(uint64).max, + type(uint64).max, + type(uint256).max, + type(uint256).max, + keccak256(abi.encode(1)), + bytes32(type(uint256).max) + ); + vm.startPrank(depositor); + } +} + +contract GasBenchMark_L1Block_SetValuesEcotone is GasBenchMark_L1Block { + function test_setL1BlockValuesEcotone_benchmark() external { + SafeCall.call({ _target: address(l1Block), _calldata: setValuesCalldata }); + } +} + +contract GasBenchMark_L1Block_SetValuesEcotone_Warm is GasBenchMark_L1Block { + function setUp() public virtual override { + SafeCall.call({ _target: address(l1Block), _calldata: setValuesCalldata }); + } + + function test_setL1BlockValuesEcotone_benchmark() external { + SafeCall.call({ _target: address(l1Block), _calldata: setValuesCalldata }); + } +} + +contract GasBenchMark_L1BlockIsthmus is GasBenchMark_L1Block { + L1BlockIsthmus l1BlockIsthmus; + + function setUp() public virtual override { + super.setUp(); + l1BlockIsthmus = new L1BlockIsthmus(); + setValuesCalldata = Encoding.encodeSetL1BlockValuesIsthmus( + type(uint32).max, + type(uint32).max, + type(uint64).max, + type(uint64).max, + type(uint64).max, + type(uint256).max, + type(uint256).max, + keccak256(abi.encode(1)), + bytes32(type(uint256).max) + ); + } +} + +contract GasBenchMark_L1BlockIsthmus_SetValuesIsthmus is GasBenchMark_L1BlockIsthmus { + function test_setL1BlockValuesIsthmus_benchmark() external { + SafeCall.call({ _target: address(l1BlockIsthmus), _calldata: setValuesCalldata }); + } +} + +contract GasBenchMark_L1BlockIsthmus_SetValuesIsthmus_Warm is GasBenchMark_L1BlockIsthmus { + function setUp() public virtual override { + SafeCall.call({ _target: address(l1BlockIsthmus), _calldata: setValuesCalldata }); + } + + function test_setL1BlockValuesIsthmus_benchmark() external { + SafeCall.call({ _target: address(l1BlockIsthmus), _calldata: setValuesCalldata }); + } +} + +contract GasBenchMark_L1BlockIsthmus_DepositsComplete is GasBenchMark_L1BlockIsthmus { + function test_depositsComplete_benchmark() external { + SafeCall.call({ + _target: address(l1BlockIsthmus), + _calldata: abi.encodeWithSelector(l1BlockIsthmus.depositsComplete.selector) + }); + } +} + +contract GasBenchMark_L1BlockIsthmus_DepositsComplete_Warm is GasBenchMark_L1BlockIsthmus { + function setUp() public virtual override { + super.setUp(); + // Set the isDeposit flag to true so then we can benchmark when it is reset. + SafeCall.call({ _target: address(l1BlockIsthmus), _calldata: setValuesCalldata }); + } + + function test_depositsComplete_benchmark() external { + SafeCall.call({ + _target: address(l1BlockIsthmus), + _calldata: abi.encodeWithSelector(l1BlockIsthmus.depositsComplete.selector) + }); + } +} diff --git a/packages/contracts-bedrock/test/L1/OptimismPortalInterop.t.sol b/packages/contracts-bedrock/test/L1/OptimismPortalInterop.t.sol index 1d9c2b01a248..6fb9a1aab6ed 100644 --- a/packages/contracts-bedrock/test/L1/OptimismPortalInterop.t.sol +++ b/packages/contracts-bedrock/test/L1/OptimismPortalInterop.t.sol @@ -11,7 +11,7 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; // Target contract dependencies import "src/libraries/PortalErrors.sol"; import { OptimismPortalInterop } from "src/L1/OptimismPortalInterop.sol"; -import { L1BlockInterop, ConfigType } from "src/L2/L1BlockInterop.sol"; +import { L1BlockIsthmus, ConfigType } from "src/L2/L1BlockIsthmus.sol"; contract OptimismPortalInterop_Test is CommonTest { /// @notice Marked virtual to be overridden in @@ -31,7 +31,7 @@ contract OptimismPortalInterop_Test is CommonTest { _mint: 0, _gasLimit: 200_000, _isCreation: false, - _data: abi.encodeCall(L1BlockInterop.setConfig, (ConfigType.SET_GAS_PAYING_TOKEN, _value)) + _data: abi.encodeCall(L1BlockIsthmus.setConfig, (ConfigType.SET_GAS_PAYING_TOKEN, _value)) }); vm.prank(address(_optimismPortalInterop().systemConfig())); @@ -54,7 +54,7 @@ contract OptimismPortalInterop_Test is CommonTest { _mint: 0, _gasLimit: 200_000, _isCreation: false, - _data: abi.encodeCall(L1BlockInterop.setConfig, (ConfigType.ADD_DEPENDENCY, _value)) + _data: abi.encodeCall(L1BlockIsthmus.setConfig, (ConfigType.ADD_DEPENDENCY, _value)) }); vm.prank(address(_optimismPortalInterop().systemConfig())); @@ -77,7 +77,7 @@ contract OptimismPortalInterop_Test is CommonTest { _mint: 0, _gasLimit: 200_000, _isCreation: false, - _data: abi.encodeCall(L1BlockInterop.setConfig, (ConfigType.REMOVE_DEPENDENCY, _value)) + _data: abi.encodeCall(L1BlockIsthmus.setConfig, (ConfigType.REMOVE_DEPENDENCY, _value)) }); vm.prank(address(_optimismPortalInterop().systemConfig())); diff --git a/packages/contracts-bedrock/test/L1/SystemConfigInterop.t.sol b/packages/contracts-bedrock/test/L1/SystemConfigInterop.t.sol index 36887fa33684..c861331b1387 100644 --- a/packages/contracts-bedrock/test/L1/SystemConfigInterop.t.sol +++ b/packages/contracts-bedrock/test/L1/SystemConfigInterop.t.sol @@ -14,7 +14,7 @@ import { SystemConfig } from "src/L1/SystemConfig.sol"; import { SystemConfigInterop } from "src/L1/SystemConfigInterop.sol"; import { OptimismPortalInterop } from "src/L1/OptimismPortalInterop.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import { ConfigType } from "src/L2/L1BlockInterop.sol"; +import { ConfigType } from "src/L2/L1BlockIsthmus.sol"; contract SystemConfigInterop_Test is CommonTest { /// @notice Marked virtual to be overridden in diff --git a/packages/contracts-bedrock/test/L2/CrossL2Inbox.t.sol b/packages/contracts-bedrock/test/L2/CrossL2Inbox.t.sol index 51759c7ce9b8..99704860c00d 100644 --- a/packages/contracts-bedrock/test/L2/CrossL2Inbox.t.sol +++ b/packages/contracts-bedrock/test/L2/CrossL2Inbox.t.sol @@ -12,12 +12,14 @@ import { TransientContext } from "src/libraries/TransientContext.sol"; import { CrossL2Inbox, NotEntered, + NoExecutingDeposits, InvalidTimestamp, InvalidChainId, TargetCallFailed, NotDepositor, InteropStartAlreadySet } from "src/L2/CrossL2Inbox.sol"; +import { IL1BlockIsthmus } from "src/L2/interfaces/IL1BlockIsthmus.sol"; import { ICrossL2Inbox } from "src/L2/interfaces/ICrossL2Inbox.sol"; /// @title CrossL2InboxWithModifiableTransientStorage @@ -155,6 +157,13 @@ contract CrossL2InboxTest is Test { // Ensure that the target call is payable if value is sent if (_value > 0) assumePayable(_target); + // Ensure is not a deposit transaction + vm.mockCall({ + callee: Predeploys.L1_BLOCK_ATTRIBUTES, + data: abi.encodeWithSelector(IL1BlockIsthmus.isDeposit.selector), + returnData: abi.encode(false) + }); + // Ensure that the target call does not revert vm.mockCall({ callee: _target, msgValue: _value, data: _message, returnData: abi.encode(true) }); @@ -210,6 +219,13 @@ contract CrossL2InboxTest is Test { _id1.timestamp = bound(_id1.timestamp, interopStartTime + 1, block.timestamp); _id2.timestamp = bound(_id2.timestamp, interopStartTime + 1, block.timestamp); + // Ensure is not a deposit transaction + vm.mockCall({ + callee: Predeploys.L1_BLOCK_ATTRIBUTES, + data: abi.encodeWithSelector(IL1BlockIsthmus.isDeposit.selector), + returnData: abi.encode(false) + }); + // Ensure that id1's chain ID is in the dependency set vm.mockCall({ callee: Predeploys.L1_BLOCK_ATTRIBUTES, @@ -254,6 +270,32 @@ contract CrossL2InboxTest is Test { assertEq(crossL2Inbox.chainId(), _id2.chainId); } + /// @dev Tests that the `executeMessage` function reverts if the transaction comes from a deposit. + function testFuzz_executeMessage_isDeposit_reverts( + ICrossL2Inbox.Identifier calldata _id, + address _target, + bytes calldata _message, + uint256 _value + ) + external + { + // Ensure it is a deposit transaction + vm.mockCall({ + callee: Predeploys.L1_BLOCK_ATTRIBUTES, + data: abi.encodeWithSelector(IL1BlockIsthmus.isDeposit.selector), + returnData: abi.encode(true) + }); + + // Ensure that the contract has enough balance to send with value + vm.deal(address(this), _value); + + // Expect a revert with the NoExecutingDeposits selector + vm.expectRevert(NoExecutingDeposits.selector); + + // Call the executeMessage function + crossL2Inbox.executeMessage{ value: _value }({ _id: _id, _target: _target, _message: _message }); + } + /// @dev Tests that the `executeMessage` function reverts when called with an identifier with an invalid timestamp. function testFuzz_executeMessage_invalidTimestamp_reverts( ICrossL2Inbox.Identifier calldata _id, @@ -267,6 +309,13 @@ contract CrossL2InboxTest is Test { // Ensure that the id's timestamp is invalid (greater than the current block timestamp) vm.assume(_id.timestamp > block.timestamp); + // Ensure is not a deposit transaction + vm.mockCall({ + callee: Predeploys.L1_BLOCK_ATTRIBUTES, + data: abi.encodeWithSelector(IL1BlockIsthmus.isDeposit.selector), + returnData: abi.encode(false) + }); + // Ensure that the contract has enough balance to send with value vm.deal(address(this), _value); @@ -294,6 +343,13 @@ contract CrossL2InboxTest is Test { // Ensure that the contract has enough balance to send with value vm.deal(address(this), _value); + // Ensure is not a deposit transaction + vm.mockCall({ + callee: Predeploys.L1_BLOCK_ATTRIBUTES, + data: abi.encodeWithSelector(IL1BlockIsthmus.isDeposit.selector), + returnData: abi.encode(false) + }); + // Expect a revert with the InvalidTimestamp selector vm.expectRevert(InvalidTimestamp.selector); @@ -316,6 +372,13 @@ contract CrossL2InboxTest is Test { // interop start time) _id.timestamp = bound(_id.timestamp, interopStartTime + 1, block.timestamp); + // Ensure is not a deposit transaction + vm.mockCall({ + callee: Predeploys.L1_BLOCK_ATTRIBUTES, + data: abi.encodeWithSelector(IL1BlockIsthmus.isDeposit.selector), + returnData: abi.encode(false) + }); + // Ensure that the chain ID is NOT in the dependency set vm.mockCall({ callee: Predeploys.L1_BLOCK_ATTRIBUTES, @@ -353,6 +416,13 @@ contract CrossL2InboxTest is Test { // Ensure that the target call reverts vm.mockCallRevert({ callee: _target, msgValue: _value, data: _message, revertData: abi.encode(false) }); + // Ensure is not a deposit transaction + vm.mockCall({ + callee: Predeploys.L1_BLOCK_ATTRIBUTES, + data: abi.encodeWithSelector(IL1BlockIsthmus.isDeposit.selector), + returnData: abi.encode(false) + }); + // Ensure that the chain ID is in the dependency set vm.mockCall({ callee: Predeploys.L1_BLOCK_ATTRIBUTES, diff --git a/packages/contracts-bedrock/test/L2/L1BlockInterop.t.sol b/packages/contracts-bedrock/test/L2/L1BlockIsthmus.t.sol similarity index 50% rename from packages/contracts-bedrock/test/L2/L1BlockInterop.t.sol rename to packages/contracts-bedrock/test/L2/L1BlockIsthmus.t.sol index 159021e77dcc..1c2407dd73ab 100644 --- a/packages/contracts-bedrock/test/L2/L1BlockInterop.t.sol +++ b/packages/contracts-bedrock/test/L2/L1BlockIsthmus.t.sol @@ -8,16 +8,17 @@ import { CommonTest } from "test/setup/CommonTest.sol"; import { StaticConfig } from "src/libraries/StaticConfig.sol"; // Target contract dependencies -import { L1BlockInterop, ConfigType } from "src/L2/L1BlockInterop.sol"; +import { L1BlockIsthmus, ConfigType } from "src/L2/L1BlockIsthmus.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; import "src/libraries/L1BlockErrors.sol"; -contract L1BlockInteropTest is CommonTest { +contract L1BlockIsthmusTest is CommonTest { event GasPayingTokenSet(address indexed token, uint8 indexed decimals, bytes32 name, bytes32 symbol); event DependencyAdded(uint256 indexed chainId); event DependencyRemoved(uint256 indexed chainId); modifier prankDepositor() { - vm.startPrank(l1Block.DEPOSITOR_ACCOUNT()); + vm.startPrank(_l1BlockIsthmus().DEPOSITOR_ACCOUNT()); _; vm.stopPrank(); } @@ -33,14 +34,14 @@ contract L1BlockInteropTest is CommonTest { function testFuzz_isInDependencySet_succeeds(uint256 _chainId) public prankDepositor { vm.assume(_chainId != block.chainid); - _l1BlockInterop().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)); + _l1BlockIsthmus().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)); - assertTrue(_l1BlockInterop().isInDependencySet(_chainId)); + assertTrue(_l1BlockIsthmus().isInDependencySet(_chainId)); } /// @dev Tests that `isInDependencySet` returns true when the chain's chain ID is passed as the input. function test_isInDependencySet_chainChainId_succeeds() public view { - assertTrue(_l1BlockInterop().isInDependencySet(block.chainid)); + assertTrue(_l1BlockIsthmus().isInDependencySet(block.chainid)); } /// @dev Tests that `isInDependencySet` reverts when the input chain ID is not in the dependency set @@ -49,16 +50,16 @@ contract L1BlockInteropTest is CommonTest { vm.assume(_chainId != block.chainid); // Check that the chain ID is not in the dependency set - assertFalse(_l1BlockInterop().isInDependencySet(_chainId)); + assertFalse(_l1BlockIsthmus().isInDependencySet(_chainId)); } /// @dev Tests that `isInDependencySet` returns false when the dependency set is empty. function testFuzz_isInDependencySet_dependencySetEmpty_succeeds(uint256 _chainId) public view { vm.assume(_chainId != block.chainid); - assertEq(_l1BlockInterop().dependencySetSize(), 0); + assertEq(_l1BlockIsthmus().dependencySetSize(), 0); - assertFalse(_l1BlockInterop().isInDependencySet(_chainId)); + assertFalse(_l1BlockIsthmus().isInDependencySet(_chainId)); } /// @dev Tests that the dependency set size is correct when adding an arbitrary number of chain IDs. @@ -69,16 +70,16 @@ contract L1BlockInteropTest is CommonTest { for (uint256 i = 0; i < _dependencySetSize; i++) { if (i == block.chainid) continue; - _l1BlockInterop().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(i)); + _l1BlockIsthmus().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(i)); uniqueCount++; } - assertEq(_l1BlockInterop().dependencySetSize(), uniqueCount); + assertEq(_l1BlockIsthmus().dependencySetSize(), uniqueCount); } /// @dev Tests that the dependency set size is correct when the dependency set is empty. function test_dependencySetSize_dependencySetEmpty_succeeds() public view { - assertEq(_l1BlockInterop().dependencySetSize(), 0); + assertEq(_l1BlockIsthmus().dependencySetSize(), 0); } /// @dev Tests that the config for setting the gas paying token succeeds. @@ -96,7 +97,7 @@ contract L1BlockInteropTest is CommonTest { vm.expectEmit(address(l1Block)); emit GasPayingTokenSet({ token: _token, decimals: _decimals, name: _name, symbol: _symbol }); - _l1BlockInterop().setConfig( + _l1BlockIsthmus().setConfig( ConfigType.SET_GAS_PAYING_TOKEN, StaticConfig.encodeSetGasPayingToken({ _token: _token, _decimals: _decimals, _name: _name, _symbol: _symbol }) ); @@ -114,7 +115,7 @@ contract L1BlockInteropTest is CommonTest { vm.assume(_token != address(vm)); vm.expectRevert(NotDepositor.selector); - _l1BlockInterop().setConfig( + _l1BlockIsthmus().setConfig( ConfigType.SET_GAS_PAYING_TOKEN, StaticConfig.encodeSetGasPayingToken({ _token: _token, _decimals: _decimals, _name: _name, _symbol: _symbol }) ); @@ -127,41 +128,41 @@ contract L1BlockInteropTest is CommonTest { vm.expectEmit(address(l1Block)); emit DependencyAdded(_chainId); - _l1BlockInterop().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)); + _l1BlockIsthmus().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)); } /// @dev Tests that adding a dependency reverts if it's the chain's chain id function test_setConfig_addDependency_chainChainId_reverts() public prankDepositor { vm.expectRevert(AlreadyDependency.selector); - _l1BlockInterop().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(block.chainid)); + _l1BlockIsthmus().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(block.chainid)); } /// @dev Tests that adding a dependency already in the set reverts function test_setConfig_addDependency_alreadyDependency_reverts(uint256 _chainId) public prankDepositor { vm.assume(_chainId != block.chainid); - _l1BlockInterop().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)); + _l1BlockIsthmus().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)); vm.expectRevert(AlreadyDependency.selector); - _l1BlockInterop().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)); + _l1BlockIsthmus().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)); } /// @dev Tests that setting the add dependency config as not the depositor reverts. function testFuzz_setConfig_addDependency_notDepositor_reverts(uint256 _chainId) public { vm.expectRevert(NotDepositor.selector); - _l1BlockInterop().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)); + _l1BlockIsthmus().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)); } /// @dev Tests that setting the add dependency config when the dependency set size is too large reverts. function test_setConfig_addDependency_dependencySetSizeTooLarge_reverts() public prankDepositor { for (uint256 i = 0; i < type(uint8).max; i++) { - _l1BlockInterop().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(i)); + _l1BlockIsthmus().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(i)); } - assertEq(_l1BlockInterop().dependencySetSize(), type(uint8).max); + assertEq(_l1BlockIsthmus().dependencySetSize(), type(uint8).max); vm.expectRevert(DependencySetSizeTooLarge.selector); - _l1BlockInterop().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(1)); + _l1BlockIsthmus().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(1)); } /// @dev Tests that the config for removing a dependency can be set. @@ -169,24 +170,24 @@ contract L1BlockInteropTest is CommonTest { vm.assume(_chainId != block.chainid); // Add the chain ID to the dependency set before removing it - _l1BlockInterop().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)); + _l1BlockIsthmus().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)); vm.expectEmit(address(l1Block)); emit DependencyRemoved(_chainId); - _l1BlockInterop().setConfig(ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(_chainId)); + _l1BlockIsthmus().setConfig(ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(_chainId)); } /// @dev Tests that setting the remove dependency config as not the depositor reverts. function testFuzz_setConfig_removeDependency_notDepositor_reverts(uint256 _chainId) public { vm.expectRevert(NotDepositor.selector); - _l1BlockInterop().setConfig(ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(_chainId)); + _l1BlockIsthmus().setConfig(ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(_chainId)); } /// @dev Tests that setting the remove dependency config for the chain's chain ID reverts. function test_setConfig_removeDependency_chainChainId_reverts() public prankDepositor { vm.expectRevert(CantRemovedDependency.selector); - _l1BlockInterop().setConfig(ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(block.chainid)); + _l1BlockIsthmus().setConfig(ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(block.chainid)); } /// @dev Tests that setting the remove dependency config for a chain ID that is not in the dependency set reverts. @@ -194,11 +195,118 @@ contract L1BlockInteropTest is CommonTest { vm.assume(_chainId != block.chainid); vm.expectRevert(NotDependency.selector); - _l1BlockInterop().setConfig(ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(_chainId)); + _l1BlockIsthmus().setConfig(ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(_chainId)); } - /// @dev Returns the L1BlockInterop instance. - function _l1BlockInterop() internal view returns (L1BlockInterop) { - return L1BlockInterop(address(l1Block)); + /// @dev Returns the L1BlockIsthmus instance. + function _l1BlockIsthmus() internal view returns (L1BlockIsthmus) { + return L1BlockIsthmus(address(l1Block)); + } +} + +contract L1BlockIsthmusIsDeposit_Test is L1BlockIsthmusTest { + /// @dev Tests that `isDeposit` reverts if the caller is not the cross L2 inbox. + function test_isDeposit_notCrossL2Inbox_reverts(address _caller) external { + vm.assume(_caller != Predeploys.CROSS_L2_INBOX); + vm.expectRevert(NotCrossL2Inbox.selector); + _l1BlockIsthmus().isDeposit(); + } + + /// @dev Tests that `isDeposit` always returns the correct value. + function test_isDeposit_succeeds() external { + // Assert is false if the value is not updated + vm.prank(Predeploys.CROSS_L2_INBOX); + assertEq(_l1BlockIsthmus().isDeposit(), false); + + /// @dev Assuming that `setL1BlockValuesIsthmus` will set the proper value. That function is tested as well + vm.prank(_l1BlockIsthmus().DEPOSITOR_ACCOUNT()); + _l1BlockIsthmus().setL1BlockValuesIsthmus(); + + // Assert is true if the value is updated + vm.prank(Predeploys.CROSS_L2_INBOX); + assertEq(_l1BlockIsthmus().isDeposit(), true); + } +} + +contract L1BlockIsthmusSetL1BlockValuesIsthmus_Test is L1BlockIsthmusTest { + /// @dev Tests that `setL1BlockValuesIsthmus` reverts if sender address is not the depositor + function test_setL1BlockValuesIsthmus_notDepositor_reverts(address _caller) external { + vm.assume(_caller != _l1BlockIsthmus().DEPOSITOR_ACCOUNT()); + vm.prank(_caller); + vm.expectRevert(NotDepositor.selector); + _l1BlockIsthmus().setL1BlockValuesIsthmus(); + } + + /// @dev Tests that `setL1BlockValuesIsthmus` succeeds if sender address is the depositor + function test_setL1BlockValuesIsthmus_succeeds( + uint32 baseFeeScalar, + uint32 blobBaseFeeScalar, + uint64 sequenceNumber, + uint64 timestamp, + uint64 number, + uint256 baseFee, + uint256 blobBaseFee, + bytes32 hash, + bytes32 batcherHash + ) + external + { + // Ensure the `isDepositTransaction` flag is false before calling `setL1BlockValuesIsthmus` + vm.prank(Predeploys.CROSS_L2_INBOX); + assertEq(_l1BlockIsthmus().isDeposit(), false); + + bytes memory setValuesEcotoneCalldata = abi.encodePacked( + baseFeeScalar, blobBaseFeeScalar, sequenceNumber, timestamp, number, baseFee, blobBaseFee, hash, batcherHash + ); + + vm.prank(_l1BlockIsthmus().DEPOSITOR_ACCOUNT()); + (bool success,) = address(l1Block).call( + abi.encodePacked(L1BlockIsthmus.setL1BlockValuesIsthmus.selector, setValuesEcotoneCalldata) + ); + assertTrue(success, "function call failed"); + + // Assert that the `isDepositTransaction` flag was properly set to true + vm.prank(Predeploys.CROSS_L2_INBOX); + assertEq(_l1BlockIsthmus().isDeposit(), true); + + // Assert `setL1BlockValuesEcotone` was properly called, forwarding the calldata to it + assertEq(_l1BlockIsthmus().baseFeeScalar(), baseFeeScalar, "base fee scalar not properly set"); + assertEq(_l1BlockIsthmus().blobBaseFeeScalar(), blobBaseFeeScalar, "blob base fee scalar not properly set"); + assertEq(_l1BlockIsthmus().sequenceNumber(), sequenceNumber, "sequence number not properly set"); + assertEq(_l1BlockIsthmus().timestamp(), timestamp, "timestamp not properly set"); + assertEq(_l1BlockIsthmus().number(), number, "number not properly set"); + assertEq(_l1BlockIsthmus().basefee(), baseFee, "base fee not properly set"); + assertEq(_l1BlockIsthmus().blobBaseFee(), blobBaseFee, "blob base fee not properly set"); + assertEq(_l1BlockIsthmus().hash(), hash, "hash not properly set"); + assertEq(_l1BlockIsthmus().batcherHash(), batcherHash, "batcher hash not properly set"); + } +} + +contract L1BlockDepositsComplete_Test is L1BlockIsthmusTest { + // @dev Tests that `depositsComplete` reverts if the caller is not the depositor. + function test_deposits_is_depositor_reverts(address _caller) external { + vm.assume(_caller != _l1BlockIsthmus().DEPOSITOR_ACCOUNT()); + vm.expectRevert(NotDepositor.selector); + _l1BlockIsthmus().depositsComplete(); + } + + // @dev Tests that `depositsComplete` succeeds if the caller is the depositor. + function test_depositsComplete_succeeds() external { + // Set the `isDeposit` flag to true + vm.prank(_l1BlockIsthmus().DEPOSITOR_ACCOUNT()); + _l1BlockIsthmus().setL1BlockValuesIsthmus(); + + // Assert that the `isDeposit` flag was properly set to true + vm.prank(Predeploys.CROSS_L2_INBOX); + assertTrue(_l1BlockIsthmus().isDeposit()); + + // Call `depositsComplete` + vm.prank(_l1BlockIsthmus().DEPOSITOR_ACCOUNT()); + _l1BlockIsthmus().depositsComplete(); + + // Assert that the `isDeposit` flag was properly set to false + /// @dev Assuming that `isDeposit()` wil return the proper value. That function is tested as well + vm.prank(Predeploys.CROSS_L2_INBOX); + assertEq(_l1BlockIsthmus().isDeposit(), false); } } From f84c92ccbeeb248ce401e96907928d7c3dc7aae1 Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Wed, 11 Sep 2024 10:57:41 -0600 Subject: [PATCH 091/264] Improvements/bugfixes to Go forge scripts (#11838) * Improvements/bugfixes to Go forge scripts Adds some improvements to the Go forge scripts: - Adds a `GasUsed` field to the `Broadcast` struct so that transaction broadcast utilities can use it for gas estimation. Gas estimation using the RPC will fail when sending transactions in parallel since the state can change significantly between calls. - Fixes a bug in the `vm.broadcast` cheatcode where sender nonce were not increased for `vm.CALL`s. This led to a mismatch between the contract addresses generated by the Forge tooling, and what was actually being generated onchain. * op-chain-ops: isolate broadcast functionality * review updates * wrap in broadcast check * Add nonce tests * Update op-chain-ops/script/script.go Co-authored-by: protolambda * Fix test * op-chain-ops: track broadcast nonce, add sanity checks --------- Co-authored-by: protolambda --- op-chain-ops/script/prank.go | 30 ++++-- op-chain-ops/script/script.go | 93 +++++++++++++++- op-chain-ops/script/script_test.go | 102 ++++++++++++------ .../testdata/scripts/ScriptExample.s.sol | 8 ++ .../ScriptExample.s.sol/FooBar.json | 2 +- .../ScriptExample.s.sol/ScriptExample.json | 2 +- .../ScriptExample.s.sol/Vm.json | 2 +- .../ScriptExample.s.sol/console.json | 2 +- 8 files changed, 190 insertions(+), 51 deletions(-) diff --git a/op-chain-ops/script/prank.go b/op-chain-ops/script/prank.go index 5cecbdf29cb4..d7cca3068e63 100644 --- a/op-chain-ops/script/prank.go +++ b/op-chain-ops/script/prank.go @@ -195,12 +195,14 @@ func (bt *BroadcastType) UnmarshalText(data []byte) error { // via vm.broadcast(). Actually submitting the transaction is left up // to other tools. type Broadcast struct { - From common.Address `json:"from"` - To common.Address `json:"to"` // set to expected contract address, if this is a deployment - Input hexutil.Bytes `json:"input"` // set to contract-creation code, if this is a deployment - Value *hexutil.U256 `json:"value"` - Salt common.Hash `json:"salt"` // set if this is a Create2 broadcast - Type BroadcastType `json:"type"` + From common.Address `json:"from"` + To common.Address `json:"to"` // set to expected contract address, if this is a deployment + Input hexutil.Bytes `json:"input"` // set to contract-creation code, if this is a deployment + Value *hexutil.U256 `json:"value"` + Salt common.Hash `json:"salt"` // set if this is a Create2 broadcast + GasUsed uint64 `json:"gasUsed"` + Type BroadcastType `json:"type"` + Nonce uint64 `json:"nonce"` // pre-state nonce of From, before any increment (always 0 if create2) } // NewBroadcast creates a Broadcast from a parent callframe, and the completed child callframe. @@ -225,13 +227,22 @@ func NewBroadcast(parent, current *CallFrame) Broadcast { From: ctx.Caller(), To: ctx.Address(), // Need to clone the input below since memory is reused in the VM - Input: bytes.Clone(input), - Value: (*hexutil.U256)(value.Clone()), + Input: bytes.Clone(input), + Value: (*hexutil.U256)(value.Clone()), + GasUsed: current.GasUsed, } switch parent.LastOp { case vm.CREATE: bcast.Type = BroadcastCreate + // Nonce bump was already applied, but we need the pre-state + bcast.Nonce = current.CallerNonce - 1 + expectedAddr := crypto.CreateAddress(bcast.From, bcast.Nonce) + if expectedAddr != bcast.To { + panic(fmt.Errorf("script bug: create broadcast has "+ + "unexpected address: %s, expected %s. Sender: %s, Nonce: %d", + bcast.To, expectedAddr, bcast.From, bcast.Nonce)) + } case vm.CREATE2: bcast.Salt = parent.LastCreate2Salt initHash := crypto.Keccak256Hash(bcast.Input) @@ -243,8 +254,11 @@ func NewBroadcast(parent, current *CallFrame) Broadcast { bcast.To, expectedAddr, bcast.From, bcast.Salt, initHash)) } bcast.Type = BroadcastCreate2 + bcast.Nonce = 0 // always 0. The nonce should not matter for create2. case vm.CALL: bcast.Type = BroadcastCall + // Nonce bump was already applied, but we need the pre-state + bcast.Nonce = current.CallerNonce - 1 default: panic(fmt.Errorf("unexpected broadcast operation %s", parent.LastOp)) } diff --git a/op-chain-ops/script/script.go b/op-chain-ops/script/script.go index 0512f4258e39..690ec6fdec65 100644 --- a/op-chain-ops/script/script.go +++ b/op-chain-ops/script/script.go @@ -55,6 +55,15 @@ type CallFrame struct { // Forge script does not support nested pranks on the same call-depth. // Pranks can also be broadcasting. Prank *Prank + + // GasUsed keeps track of the amount of gas used by this call frame. + // This is useful for broadcasts, which sometimes cannot correctly + // estimate gas when sending transactions in parallel. + GasUsed uint64 + + // CallerNonce keeps track of the nonce of the caller who entered the callframe + // (nonce of pranked caller, if pranked). + CallerNonce uint64 } // Host is an EVM executor that runs Forge scripts. @@ -91,6 +100,11 @@ type Host struct { onLabel []func(name string, addr common.Address) hooks *Hooks + + // isolateBroadcasts will flush the journal changes, + // and prepare the ephemeral tx context again, + // to make gas accounting of a broadcast sub-call more accurate. + isolateBroadcasts bool } type HostOption func(h *Host) @@ -107,6 +121,17 @@ func WithBroadcastHook(hook BroadcastHook) HostOption { } } +// WithIsolatedBroadcasts makes each broadcast clean the context, +// by flushing the dirty storage changes, and preparing the ephemeral state again. +// This then produces more accurate gas estimation for broadcast calls. +// This is not compatible with state-snapshots: upon cleaning, +// it is assumed that the state has to never revert back, similar to the state-dump guarantees. +func WithIsolatedBroadcasts() HostOption { + return func(h *Host) { + h.isolateBroadcasts = true + } +} + // NewHost creates a Host that can load contracts from the given Artifacts FS, // and with an EVM initialized to the given executionContext. // Optionally src-map loading may be enabled, by providing a non-nil srcFS to read sources from. @@ -217,6 +242,7 @@ func NewHost( // Hook up the Host to capture the EVM environment changes trHooks := &tracing.Hooks{ + OnEnter: h.onEnter, OnExit: h.onExit, OnOpcode: h.onOpcode, OnFault: h.onFault, @@ -336,6 +362,16 @@ func (h *Host) Wipe(addr common.Address) { h.state.SetBalance(addr, uint256.NewInt(0), tracing.BalanceChangeUnspecified) } +// SetNonce sets an account's nonce in state. +func (h *Host) SetNonce(addr common.Address, nonce uint64) { + h.state.SetNonce(addr, nonce) +} + +// GetNonce returs an account's nonce from state. +func (h *Host) GetNonce(addr common.Address) uint64 { + return h.state.GetNonce(addr) +} + // getPrecompile overrides any accounts during runtime, to insert special precompiles, if activated. func (h *Host) getPrecompile(rules params.Rules, original vm.PrecompiledContract, addr common.Address) vm.PrecompiledContract { if p, ok := h.precompiles[addr]; ok { @@ -365,6 +401,52 @@ func (h *Host) HasPrecompileOverride(addr common.Address) bool { return ok } +// onEnter is a trace-hook, which we use to apply changes to the state-DB, to simulate isolated broadcast calls, +// for better gas estimation of the exact broadcast call execution. +func (h *Host) onEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { + if len(h.callStack) == 0 { + return + } + parentCallFrame := h.callStack[len(h.callStack)-1] + if parentCallFrame.Prank == nil { + return + } + // sanity check our callframe is set up correctly + if parentCallFrame.LastOp != vm.OpCode(typ) { + panic(fmt.Errorf("parent call-frame has invalid last Op: %d", typ)) + } + if !parentCallFrame.Prank.Broadcast { + return + } + if to == VMAddr || to == ConsoleAddr { // no broadcasts to the cheatcode or console address + return + } + + // Bump nonce value, such that a broadcast Call appears like a tx + if parentCallFrame.LastOp == vm.CALL { + sender := parentCallFrame.Ctx.Address() + if parentCallFrame.Prank.Sender != nil { + sender = *parentCallFrame.Prank.Sender + } + h.state.SetNonce(sender, h.state.GetNonce(sender)+1) + } + + if h.isolateBroadcasts { + var dest *common.Address + switch parentCallFrame.LastOp { + case vm.CREATE, vm.CREATE2: + dest = nil // no destination address to warm up + case vm.CALL: + dest = &to + default: + return + } + h.state.Finalise(true) + // the prank msg.sender, if any, has already been applied to 'from' before onEnter + h.prelude(from, dest) + } +} + // onExit is a trace-hook, which we use to maintain an accurate view of functions, and log any revert warnings. func (h *Host) onExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) { // Note: onExit runs also when going deeper, exiting the context into a nested context. @@ -377,6 +459,8 @@ func (h *Host) onExit(depth int, output []byte, gasUsed uint64, err error, rever h.log.Warn("Revert", "addr", addr, "err", err, "revertData", hexutil.Bytes(output), "depth", depth) } } + + h.callStack[len(h.callStack)-1].GasUsed += gasUsed h.unwindCallstack(depth) } @@ -437,10 +521,11 @@ func (h *Host) onOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpCo // We do this here, instead of onEnter, to capture an initialized scope. if len(h.callStack) == 0 || h.callStack[len(h.callStack)-1].Depth < depth { h.callStack = append(h.callStack, &CallFrame{ - Depth: depth, - LastOp: vm.OpCode(op), - LastPC: pc, - Ctx: scopeCtx, + Depth: depth, + LastOp: vm.OpCode(op), + LastPC: pc, + Ctx: scopeCtx, + CallerNonce: h.GetNonce(scopeCtx.Caller()), }) } // Sanity check that top of the call-stack matches the scope context now diff --git a/op-chain-ops/script/script_test.go b/op-chain-ops/script/script_test.go index cf1f58751fa8..55dd70ff2eec 100644 --- a/op-chain-ops/script/script_test.go +++ b/op-chain-ops/script/script_test.go @@ -66,66 +66,89 @@ func TestScriptBroadcast(t *testing.T) { expectedInitCode = append(expectedInitCode, leftPad32(big.NewInt(1234).Bytes())...) salt := uint256.NewInt(42).Bytes32() - senderAddr := common.HexToAddress("0x5b73C5498c1E3b4dbA84de0F1833c4a029d90519") + senderAddr := common.HexToAddress("0x0000000000000000000000000000000000Badc0d") + scriptAddr := common.HexToAddress("0x5b73c5498c1e3b4dba84de0f1833c4a029d90519") + coffeeAddr := common.HexToAddress("0x0000000000000000000000000000000000C0FFEE") + cafeAddr := common.HexToAddress("0xcafe") expBroadcasts := []Broadcast{ { - From: senderAddr, - To: senderAddr, - Input: mustEncodeCalldata("call1", "single_call1"), - Value: (*hexutil.U256)(uint256.NewInt(0)), - Type: BroadcastCall, + From: scriptAddr, + To: scriptAddr, + Input: mustEncodeCalldata("call1", "single_call1"), + Value: (*hexutil.U256)(uint256.NewInt(0)), + GasUsed: 23421, + Type: BroadcastCall, + Nonce: 1, // first action by script (script already has a nonce of 1) }, { - From: common.HexToAddress("0x0000000000000000000000000000000000C0FFEE"), - To: senderAddr, - Input: mustEncodeCalldata("call1", "startstop_call1"), - Value: (*hexutil.U256)(uint256.NewInt(0)), - Type: BroadcastCall, + From: coffeeAddr, + To: scriptAddr, + Input: mustEncodeCalldata("call1", "startstop_call1"), + Value: (*hexutil.U256)(uint256.NewInt(0)), + GasUsed: 1521, + Type: BroadcastCall, + Nonce: 0, // first action by 0xc0ffee }, { - From: common.HexToAddress("0x0000000000000000000000000000000000C0FFEE"), - To: senderAddr, - Input: mustEncodeCalldata("call2", "startstop_call2"), - Value: (*hexutil.U256)(uint256.NewInt(0)), - Type: BroadcastCall, + From: coffeeAddr, + To: scriptAddr, + Input: mustEncodeCalldata("call2", "startstop_call2"), + Value: (*hexutil.U256)(uint256.NewInt(0)), + GasUsed: 1565, + Type: BroadcastCall, + Nonce: 1, // second action of 0xc0ffee }, { - From: common.HexToAddress("0x1234"), - To: senderAddr, - Input: mustEncodeCalldata("nested1", "nested"), - Value: (*hexutil.U256)(uint256.NewInt(0)), - Type: BroadcastCall, + From: common.HexToAddress("0x1234"), + To: scriptAddr, + Input: mustEncodeCalldata("nested1", "nested"), + Value: (*hexutil.U256)(uint256.NewInt(0)), + GasUsed: 2763, + Type: BroadcastCall, + Nonce: 0, // first action of 0x1234 }, { - From: common.HexToAddress("0x123456"), - To: crypto.CreateAddress(common.HexToAddress("0x123456"), 0), - Input: expectedInitCode, - Value: (*hexutil.U256)(uint256.NewInt(0)), - Type: BroadcastCreate, + From: common.HexToAddress("0x123456"), + To: crypto.CreateAddress(common.HexToAddress("0x123456"), 0), + Input: expectedInitCode, + Value: (*hexutil.U256)(uint256.NewInt(0)), + GasUsed: 39112, + Type: BroadcastCreate, + Nonce: 0, // first action of 0x123456 }, { - From: common.HexToAddress("0xcafe"), - To: crypto.CreateAddress2(common.HexToAddress("0xcafe"), salt, crypto.Keccak256(expectedInitCode)), - Input: expectedInitCode, - Value: (*hexutil.U256)(uint256.NewInt(0)), - Type: BroadcastCreate2, - Salt: salt, + From: cafeAddr, + To: crypto.CreateAddress2(cafeAddr, salt, crypto.Keccak256(expectedInitCode)), + Input: expectedInitCode, + Value: (*hexutil.U256)(uint256.NewInt(0)), + Type: BroadcastCreate2, + GasUsed: 39112, + Salt: salt, + Nonce: 0, // first action of 0xcafe + }, + { + From: scriptAddr, + To: crypto.CreateAddress(scriptAddr, 2), + Input: expectedInitCode, + Value: (*hexutil.U256)(uint256.NewInt(0)), + GasUsed: 39112, + Type: BroadcastCreate, + Nonce: 2, // second action, on top of starting at 1. }, } - scriptContext := DefaultContext var broadcasts []Broadcast hook := func(broadcast Broadcast) { broadcasts = append(broadcasts, broadcast) } - h := NewHost(logger, af, nil, scriptContext, WithBroadcastHook(hook)) + h := NewHost(logger, af, nil, DefaultContext, WithBroadcastHook(hook)) addr, err := h.LoadContract("ScriptExample.s.sol", "ScriptExample") require.NoError(t, err) require.NoError(t, h.EnableCheats()) input := bytes4("runBroadcast()") - returnData, _, err := h.Call(scriptContext.Sender, addr, input[:], DefaultFoundryGasLimit, uint256.NewInt(0)) + returnData, _, err := h.Call(senderAddr, addr, input[:], DefaultFoundryGasLimit, uint256.NewInt(0)) require.NoError(t, err, "call failed: %x", string(returnData)) expected, err := json.MarshalIndent(expBroadcasts, " ", " ") @@ -133,4 +156,13 @@ func TestScriptBroadcast(t *testing.T) { got, err := json.MarshalIndent(broadcasts, " ", " ") require.NoError(t, err) require.Equal(t, string(expected), string(got)) + + // Assert that the nonces for accounts participating in the + // broadcast increase. The scriptAddr check is set to 3 to + // account for the initial deployment of the contract and + // two additional calls. + require.EqualValues(t, 0, h.GetNonce(senderAddr)) + require.EqualValues(t, 3, h.GetNonce(scriptAddr)) + require.EqualValues(t, 2, h.GetNonce(coffeeAddr)) + require.EqualValues(t, 1, h.GetNonce(cafeAddr)) } diff --git a/op-chain-ops/script/testdata/scripts/ScriptExample.s.sol b/op-chain-ops/script/testdata/scripts/ScriptExample.s.sol index 637c900a46cc..f2f20e5ca14e 100644 --- a/op-chain-ops/script/testdata/scripts/ScriptExample.s.sol +++ b/op-chain-ops/script/testdata/scripts/ScriptExample.s.sol @@ -100,6 +100,8 @@ contract ScriptExample { /// @notice example function, to test vm.broadcast with. function runBroadcast() public { + console.log("nonce start", uint256(vm.getNonce(address(this)))); + console.log("testing single"); vm.broadcast(); this.call1("single_call1"); @@ -128,6 +130,12 @@ contract ScriptExample { FooBar y = new FooBar{salt: bytes32(uint256(42))}(1234); require(y.foo() == 1234); console.log("done!"); + + // Deploy a script without a pranked sender and check the nonce. + vm.broadcast(); + new FooBar(1234); + + console.log("nonce end", uint256(vm.getNonce(address(this)))); } /// @notice example external function, to force a CALL, and test vm.startPrank with. diff --git a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/FooBar.json b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/FooBar.json index f64c50b29b2d..ad4ac1569433 100644 --- a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/FooBar.json +++ b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/FooBar.json @@ -1 +1 @@ -{"abi":[{"type":"constructor","inputs":[{"name":"v","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"type":"function","name":"foo","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"}],"bytecode":{"object":"0x608060405234801561001057600080fd5b506040516100b23803806100b283398101604081905261002f91610037565b600055610050565b60006020828403121561004957600080fd5b5051919050565b60548061005e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b603560005481565b60405190815260200160405180910390f3fea164736f6c634300080f000a","sourceMap":"5632:96:0:-:0;;;5679:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5712:3;:7;5632:96;;14:184:1;84:6;137:2;125:9;116:7;112:23;108:32;105:52;;;153:1;150;143:12;105:52;-1:-1:-1;176:16:1;;14:184;-1:-1:-1;14:184:1:o;:::-;5632:96:0;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b603560005481565b60405190815260200160405180910390f3fea164736f6c634300080f000a","sourceMap":"5632:96:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5654:18;;;;;;;;;160:25:1;;;148:2;133:18;5654::0;;;;;;","linkReferences":{}},"methodIdentifiers":{"foo()":"c2985578"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"v\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"foo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"FooBar\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x4fc2ffeba31e146fc3a2edef7cc8b7e82fb2344454d32d6371a62c6d76dfcb4e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a517c69eba90ee5f3efb198a2247d5744bed8e17d332ce2dda4d3cf3a2c334f9\",\"dweb:/ipfs/QmciXeDt5EEhmjH5xECVk2VX6EbnER5UFv58dvGgemwkKK\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"uint256","name":"v","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"stateMutability":"view","type":"function","name":"foo","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"FooBar"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x4fc2ffeba31e146fc3a2edef7cc8b7e82fb2344454d32d6371a62c6d76dfcb4e","urls":["bzz-raw://a517c69eba90ee5f3efb198a2247d5744bed8e17d332ce2dda4d3cf3a2c334f9","dweb:/ipfs/QmciXeDt5EEhmjH5xECVk2VX6EbnER5UFv58dvGgemwkKK"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[{"astId":665,"contract":"scripts/ScriptExample.s.sol:FooBar","label":"foo","offset":0,"slot":"0","type":"t_uint256"}],"types":{"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"userdoc":{"version":1,"kind":"user"},"devdoc":{"version":1,"kind":"dev"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":677,"exportedSymbols":{"FooBar":[676],"ScriptExample":[663],"Vm":[55],"console":[192]},"nodeType":"SourceUnit","src":"32:5697:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":55,"nodeType":"ContractDefinition","src":"120:616:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":55,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":38,"nodeType":"FunctionDefinition","src":"516:30:0","nodes":[],"functionSelector":"afc98040","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"525:9:0","parameters":{"id":36,"nodeType":"ParameterList","parameters":[],"src":"534:2:0"},"returnParameters":{"id":37,"nodeType":"ParameterList","parameters":[],"src":"545:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":43,"nodeType":"FunctionDefinition","src":"551:47:0","nodes":[],"functionSelector":"e6962cdb","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"560:9:0","parameters":{"id":41,"nodeType":"ParameterList","parameters":[{"constant":false,"id":40,"mutability":"mutable","name":"msgSender","nameLocation":"578:9:0","nodeType":"VariableDeclaration","scope":43,"src":"570:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":39,"name":"address","nodeType":"ElementaryTypeName","src":"570:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"569:19:0"},"returnParameters":{"id":42,"nodeType":"ParameterList","parameters":[],"src":"597:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":48,"nodeType":"FunctionDefinition","src":"603:52:0","nodes":[],"functionSelector":"7fec2a8d","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"612:14:0","parameters":{"id":46,"nodeType":"ParameterList","parameters":[{"constant":false,"id":45,"mutability":"mutable","name":"msgSender","nameLocation":"635:9:0","nodeType":"VariableDeclaration","scope":48,"src":"627:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":44,"name":"address","nodeType":"ElementaryTypeName","src":"627:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"626:19:0"},"returnParameters":{"id":47,"nodeType":"ParameterList","parameters":[],"src":"654:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":51,"nodeType":"FunctionDefinition","src":"660:35:0","nodes":[],"functionSelector":"7fb5297f","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"669:14:0","parameters":{"id":49,"nodeType":"ParameterList","parameters":[],"src":"683:2:0"},"returnParameters":{"id":50,"nodeType":"ParameterList","parameters":[],"src":"694:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":54,"nodeType":"FunctionDefinition","src":"700:34:0","nodes":[],"functionSelector":"76eadd36","implemented":false,"kind":"function","modifiers":[],"name":"stopBroadcast","nameLocation":"709:13:0","parameters":{"id":52,"nodeType":"ParameterList","parameters":[],"src":"722:2:0"},"returnParameters":{"id":53,"nodeType":"ParameterList","parameters":[],"src":"733:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[55],"name":"Vm","nameLocation":"130:2:0","scope":677,"usedErrors":[]},{"id":192,"nodeType":"ContractDefinition","src":"791:1622:0","nodes":[{"id":61,"nodeType":"VariableDeclaration","src":"813:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"830:15:0","scope":192,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":56,"name":"address","nodeType":"ElementaryTypeName","src":"813:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":59,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"856:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":58,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"848:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":57,"name":"address","nodeType":"ElementaryTypeName","src":"848:7:0","typeDescriptions":{}}},"id":60,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"848:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":78,"nodeType":"FunctionDefinition","src":"906:221:0","nodes":[],"body":{"id":77,"nodeType":"Block","src":"1065:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"1084:37:0","statements":[{"nodeType":"YulAssignment","src":"1098:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"1107:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"1098:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":67,"isOffset":false,"isSlot":false,"src":"1107:4:0","valueSize":1},{"declaration":74,"isOffset":false,"isSlot":false,"src":"1098:5:0","valueSize":1}],"id":76,"nodeType":"InlineAssembly","src":"1075:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"915:25:0","parameters":{"id":68,"nodeType":"ParameterList","parameters":[{"constant":false,"id":67,"mutability":"mutable","name":"fnIn","nameLocation":"987:4:0","nodeType":"VariableDeclaration","scope":78,"src":"950:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":66,"nodeType":"FunctionTypeName","parameterTypes":{"id":64,"nodeType":"ParameterList","parameters":[{"constant":false,"id":63,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":66,"src":"959:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":62,"name":"bytes","nodeType":"ElementaryTypeName","src":"959:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"958:14:0"},"returnParameterTypes":{"id":65,"nodeType":"ParameterList","parameters":[],"src":"987:0:0"},"src":"950:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"940:57:0"},"returnParameters":{"id":75,"nodeType":"ParameterList","parameters":[{"constant":false,"id":74,"mutability":"mutable","name":"fnOut","nameLocation":"1058:5:0","nodeType":"VariableDeclaration","scope":78,"src":"1021:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":73,"nodeType":"FunctionTypeName","parameterTypes":{"id":71,"nodeType":"ParameterList","parameters":[{"constant":false,"id":70,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":73,"src":"1030:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":69,"name":"bytes","nodeType":"ElementaryTypeName","src":"1030:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1029:14:0"},"returnParameterTypes":{"id":72,"nodeType":"ParameterList","parameters":[],"src":"1058:0:0"},"src":"1021:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"1020:44:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":90,"nodeType":"FunctionDefinition","src":"1133:133:0","nodes":[],"body":{"id":89,"nodeType":"Block","src":"1194:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":86,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1251:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":84,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":106,"src":"1230:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":83,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":78,"src":"1204:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":85,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":87,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":88,"nodeType":"ExpressionStatement","src":"1204:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"1142:15:0","parameters":{"id":81,"nodeType":"ParameterList","parameters":[{"constant":false,"id":80,"mutability":"mutable","name":"payload","nameLocation":"1171:7:0","nodeType":"VariableDeclaration","scope":90,"src":"1158:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":79,"name":"bytes","nodeType":"ElementaryTypeName","src":"1158:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1157:22:0"},"returnParameters":{"id":82,"nodeType":"ParameterList","parameters":[],"src":"1194:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":106,"nodeType":"FunctionDefinition","src":"1272:380:0","nodes":[],"body":{"id":105,"nodeType":"Block","src":"1336:316:0","nodes":[],"statements":[{"assignments":[96],"declarations":[{"constant":false,"id":96,"mutability":"mutable","name":"payloadLength","nameLocation":"1354:13:0","nodeType":"VariableDeclaration","scope":105,"src":"1346:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":95,"name":"uint256","nodeType":"ElementaryTypeName","src":"1346:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":99,"initialValue":{"expression":{"id":97,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":92,"src":"1370:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":98,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1370:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1346:38:0"},{"assignments":[101],"declarations":[{"constant":false,"id":101,"mutability":"mutable","name":"consoleAddress","nameLocation":"1402:14:0","nodeType":"VariableDeclaration","scope":105,"src":"1394:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":100,"name":"address","nodeType":"ElementaryTypeName","src":"1394:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":103,"initialValue":{"id":102,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":61,"src":"1419:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1394:40:0"},{"AST":{"nodeType":"YulBlock","src":"1496:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1510:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1534:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1543:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1530:3:0"},"nodeType":"YulFunctionCall","src":"1530:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1514:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1559:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1579:3:0"},"nodeType":"YulFunctionCall","src":"1579:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1586:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1602:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1616:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1631:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1634:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1568:10:0"},"nodeType":"YulFunctionCall","src":"1568:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1563:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":101,"isOffset":false,"isSlot":false,"src":"1586:14:0","valueSize":1},{"declaration":92,"isOffset":false,"isSlot":false,"src":"1534:7:0","valueSize":1},{"declaration":96,"isOffset":false,"isSlot":false,"src":"1616:13:0","valueSize":1}],"id":104,"nodeType":"InlineAssembly","src":"1487:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1281:19:0","parameters":{"id":93,"nodeType":"ParameterList","parameters":[{"constant":false,"id":92,"mutability":"mutable","name":"payload","nameLocation":"1314:7:0","nodeType":"VariableDeclaration","scope":106,"src":"1301:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":91,"name":"bytes","nodeType":"ElementaryTypeName","src":"1301:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1300:22:0"},"returnParameters":{"id":94,"nodeType":"ParameterList","parameters":[],"src":"1336:0:0"},"scope":192,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":120,"nodeType":"FunctionDefinition","src":"1658:121:0","nodes":[],"body":{"id":119,"nodeType":"Block","src":"1703:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":114,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1753:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":115,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":108,"src":"1768:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":112,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1729:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":113,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1729:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":116,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1729:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":111,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1713:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":117,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1713:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":118,"nodeType":"ExpressionStatement","src":"1713:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1667:3:0","parameters":{"id":109,"nodeType":"ParameterList","parameters":[{"constant":false,"id":108,"mutability":"mutable","name":"p0","nameLocation":"1685:2:0","nodeType":"VariableDeclaration","scope":120,"src":"1671:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":107,"name":"string","nodeType":"ElementaryTypeName","src":"1671:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1670:18:0"},"returnParameters":{"id":110,"nodeType":"ParameterList","parameters":[],"src":"1703:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":137,"nodeType":"FunctionDefinition","src":"1785:139:0","nodes":[],"body":{"id":136,"nodeType":"Block","src":"1839:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":130,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1889:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":131,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":122,"src":"1909:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":132,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":124,"src":"1913:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":128,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1865:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":129,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1865:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":133,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1865:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":127,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1849:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":134,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1849:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":135,"nodeType":"ExpressionStatement","src":"1849:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1794:3:0","parameters":{"id":125,"nodeType":"ParameterList","parameters":[{"constant":false,"id":122,"mutability":"mutable","name":"p0","nameLocation":"1812:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1798:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":121,"name":"string","nodeType":"ElementaryTypeName","src":"1798:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":124,"mutability":"mutable","name":"p1","nameLocation":"1821:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1816:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":123,"name":"bool","nodeType":"ElementaryTypeName","src":"1816:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1797:27:0"},"returnParameters":{"id":126,"nodeType":"ParameterList","parameters":[],"src":"1839:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":154,"nodeType":"FunctionDefinition","src":"1930:145:0","nodes":[],"body":{"id":153,"nodeType":"Block","src":"1987:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":147,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2037:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":148,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":139,"src":"2060:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":149,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":141,"src":"2064:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":145,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2013:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":146,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2013:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":150,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2013:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":144,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1997:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":151,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1997:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":152,"nodeType":"ExpressionStatement","src":"1997:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1939:3:0","parameters":{"id":142,"nodeType":"ParameterList","parameters":[{"constant":false,"id":139,"mutability":"mutable","name":"p0","nameLocation":"1957:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1943:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":138,"name":"string","nodeType":"ElementaryTypeName","src":"1943:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":141,"mutability":"mutable","name":"p1","nameLocation":"1969:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1961:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":140,"name":"uint256","nodeType":"ElementaryTypeName","src":"1961:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1942:30:0"},"returnParameters":{"id":143,"nodeType":"ParameterList","parameters":[],"src":"1987:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":171,"nodeType":"FunctionDefinition","src":"2081:145:0","nodes":[],"body":{"id":170,"nodeType":"Block","src":"2138:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":164,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2188:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":165,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":156,"src":"2211:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":166,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":158,"src":"2215:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":162,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2164:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":163,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2164:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":167,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2164:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":161,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2148:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":168,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2148:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":169,"nodeType":"ExpressionStatement","src":"2148:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2090:3:0","parameters":{"id":159,"nodeType":"ParameterList","parameters":[{"constant":false,"id":156,"mutability":"mutable","name":"p0","nameLocation":"2108:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2094:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":155,"name":"string","nodeType":"ElementaryTypeName","src":"2094:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":158,"mutability":"mutable","name":"p1","nameLocation":"2120:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2112:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":157,"name":"address","nodeType":"ElementaryTypeName","src":"2112:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"2093:30:0"},"returnParameters":{"id":160,"nodeType":"ParameterList","parameters":[],"src":"2138:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":191,"nodeType":"FunctionDefinition","src":"2232:179:0","nodes":[],"body":{"id":190,"nodeType":"Block","src":"2313:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":183,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2363:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":184,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2392:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":185,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":175,"src":"2396:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":186,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":177,"src":"2400:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":181,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2339:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":182,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2339:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":187,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2339:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":180,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2323:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":188,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2323:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":189,"nodeType":"ExpressionStatement","src":"2323:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2241:3:0","parameters":{"id":178,"nodeType":"ParameterList","parameters":[{"constant":false,"id":173,"mutability":"mutable","name":"p0","nameLocation":"2259:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2245:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":172,"name":"string","nodeType":"ElementaryTypeName","src":"2245:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":175,"mutability":"mutable","name":"p1","nameLocation":"2277:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2263:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":174,"name":"string","nodeType":"ElementaryTypeName","src":"2263:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":177,"mutability":"mutable","name":"p2","nameLocation":"2295:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2281:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":176,"name":"string","nodeType":"ElementaryTypeName","src":"2281:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2244:54:0"},"returnParameters":{"id":179,"nodeType":"ParameterList","parameters":[],"src":"2313:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[192],"name":"console","nameLocation":"799:7:0","scope":677,"usedErrors":[]},{"id":663,"nodeType":"ContractDefinition","src":"2541:3089:0","nodes":[{"id":207,"nodeType":"VariableDeclaration","src":"2571:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2597:10:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":194,"name":"address","nodeType":"ElementaryTypeName","src":"2571:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2644:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":201,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2634:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":203,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2634:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":200,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2626:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":199,"name":"uint256","nodeType":"ElementaryTypeName","src":"2626:7:0","typeDescriptions":{}}},"id":204,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2626:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":198,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2618:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":197,"name":"uint160","nodeType":"ElementaryTypeName","src":"2618:7:0","typeDescriptions":{}}},"id":205,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2618:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":196,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2610:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":195,"name":"address","nodeType":"ElementaryTypeName","src":"2610:7:0","typeDescriptions":{}}},"id":206,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2610:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":213,"nodeType":"VariableDeclaration","src":"2671:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2692:2:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"},"typeName":{"id":209,"nodeType":"UserDefinedTypeName","pathNode":{"id":208,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":55,"src":"2671:2:0"},"referencedDeclaration":55,"src":"2671:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"value":{"arguments":[{"id":211,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":207,"src":"2700:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":210,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":55,"src":"2697:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$55_$","typeString":"type(contract Vm)"}},"id":212,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2697:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"visibility":"internal"},{"id":215,"nodeType":"VariableDeclaration","src":"2775:22:0","nodes":[],"constant":false,"functionSelector":"61bc221a","mutability":"mutable","name":"counter","nameLocation":"2790:7:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":214,"name":"uint256","nodeType":"ElementaryTypeName","src":"2775:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":378,"nodeType":"FunctionDefinition","src":"2887:949:0","nodes":[],"body":{"id":377,"nodeType":"Block","src":"2909:927:0","nodes":[],"statements":[{"assignments":[220],"declarations":[{"constant":false,"id":220,"mutability":"mutable","name":"x","nameLocation":"2924:1:0","nodeType":"VariableDeclaration","scope":377,"src":"2919:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":219,"name":"bool","nodeType":"ElementaryTypeName","src":"2919:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":226,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":223,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2937:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":224,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2953:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":221,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"2928:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":222,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2928:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":225,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2928:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2919:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":230,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2981:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":231,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":220,"src":"3004:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":227,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"2969:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":229,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":137,"src":"2969:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2969:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":233,"nodeType":"ExpressionStatement","src":"2969:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":237,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3029:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":240,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3054:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":239,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3046:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":238,"name":"address","nodeType":"ElementaryTypeName","src":"3046:7:0","typeDescriptions":{}}},"id":241,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3046:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":234,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3017:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":236,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3017:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":242,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3017:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":243,"nodeType":"ExpressionStatement","src":"3017:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":247,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3082:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":252,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3120:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":251,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3112:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":250,"name":"address","nodeType":"ElementaryTypeName","src":"3112:7:0","typeDescriptions":{}}},"id":253,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3112:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":248,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3100:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3100:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":254,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3100:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":244,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3070:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":246,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3070:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":255,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3070:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":256,"nodeType":"ExpressionStatement","src":"3070:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":260,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3149:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":263,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3172:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":264,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3172:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":262,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3164:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":261,"name":"address","nodeType":"ElementaryTypeName","src":"3164:7:0","typeDescriptions":{}}},"id":265,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3164:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":257,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3137:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":259,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3137:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":266,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3137:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":267,"nodeType":"ExpressionStatement","src":"3137:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":271,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3206:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":276,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3242:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":277,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3242:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":275,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3234:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":274,"name":"address","nodeType":"ElementaryTypeName","src":"3234:7:0","typeDescriptions":{}}},"id":278,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3234:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":272,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3222:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":273,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3222:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":279,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3222:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":268,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3194:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":270,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3194:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":280,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3194:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":281,"nodeType":"ExpressionStatement","src":"3194:61:0"},{"assignments":[283],"declarations":[{"constant":false,"id":283,"mutability":"mutable","name":"json","nameLocation":"3280:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3266:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":282,"name":"string","nodeType":"ElementaryTypeName","src":"3266:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":285,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3287:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"3266:55:0"},{"assignments":[290],"declarations":[{"constant":false,"id":290,"mutability":"mutable","name":"keys","nameLocation":"3347:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3331:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":288,"name":"string","nodeType":"ElementaryTypeName","src":"3331:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":289,"nodeType":"ArrayTypeName","src":"3331:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":296,"initialValue":{"arguments":[{"id":293,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":283,"src":"3371:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":294,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3377:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":291,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3354:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":292,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3354:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":295,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3354:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3331:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":300,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3414:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":301,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3422:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":303,"indexExpression":{"hexValue":"30","id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3427:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3422:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":304,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3431:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":306,"indexExpression":{"hexValue":"31","id":305,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3436:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3431:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":297,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3402:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":299,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":191,"src":"3402:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":307,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3402:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":308,"nodeType":"ExpressionStatement","src":"3402:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":312,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3461:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":309,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3450:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":311,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3450:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":313,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3450:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":314,"nodeType":"ExpressionStatement","src":"3450:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":322,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3517:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":321,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3509:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":320,"name":"uint160","nodeType":"ElementaryTypeName","src":"3509:7:0","typeDescriptions":{}}},"id":323,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3509:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":319,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3501:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":318,"name":"address","nodeType":"ElementaryTypeName","src":"3501:7:0","typeDescriptions":{}}},"id":324,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3501:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":315,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3487:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":317,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3487:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3487:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":326,"nodeType":"ExpressionStatement","src":"3487:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":330,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3545:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":327,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3534:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":329,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3534:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3534:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":332,"nodeType":"ExpressionStatement","src":"3534:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":336,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3582:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":339,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3617:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":340,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3617:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":338,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3609:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":337,"name":"address","nodeType":"ElementaryTypeName","src":"3609:7:0","typeDescriptions":{}}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3609:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":333,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3570:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":335,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3570:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3570:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3570:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3651:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":350,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3689:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":349,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3681:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":348,"name":"address","nodeType":"ElementaryTypeName","src":"3681:7:0","typeDescriptions":{}}},"id":351,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3681:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":344,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3639:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3639:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3639:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":353,"nodeType":"ExpressionStatement","src":"3639:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":357,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3716:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":354,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3705:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":356,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3705:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":358,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3705:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":359,"nodeType":"ExpressionStatement","src":"3705:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":360,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3741:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":362,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3741:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":363,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3741:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":364,"nodeType":"ExpressionStatement","src":"3741:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":368,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3776:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":365,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3765:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":367,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3765:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":369,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3765:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":370,"nodeType":"ExpressionStatement","src":"3765:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":374,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3821:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":371,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3809:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":373,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"3809:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":375,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3809:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":376,"nodeType":"ExpressionStatement","src":"3809:20:0"}]},"documentation":{"id":216,"nodeType":"StructuredDocumentation","src":"2804:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2896:3:0","parameters":{"id":217,"nodeType":"ParameterList","parameters":[],"src":"2899:2:0"},"returnParameters":{"id":218,"nodeType":"ParameterList","parameters":[],"src":"2909:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":566,"nodeType":"FunctionDefinition","src":"3903:988:0","nodes":[],"body":{"id":565,"nodeType":"Block","src":"3934:957:0","nodes":[],"statements":[{"expression":{"arguments":[{"hexValue":"74657374696e672073696e676c65","id":385,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3956:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""},"value":"testing single"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""}],"expression":{"id":382,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3944:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":384,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"3944:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":386,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3944:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":387,"nodeType":"ExpressionStatement","src":"3944:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":388,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3983:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":390,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"3983:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":391,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3983:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":392,"nodeType":"ExpressionStatement","src":"3983:14:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c31","id":396,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4018:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""},"value":"single_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""}],"expression":{"id":393,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4007:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":395,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4007:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":397,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4007:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":398,"nodeType":"ExpressionStatement","src":"4007:26:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c32","id":402,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4054:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""},"value":"single_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""}],"expression":{"id":399,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4043:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":401,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":620,"src":"4043:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":403,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4043:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":404,"nodeType":"ExpressionStatement","src":"4043:26:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073746172742f73746f70","id":408,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4092:20:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""},"value":"testing start/stop"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""}],"expression":{"id":405,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4080:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":407,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4080:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":409,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4080:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":410,"nodeType":"ExpressionStatement","src":"4080:33:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078633066666565","id":418,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4157:8:0","typeDescriptions":{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"},"value":"0xc0ffee"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"}],"id":417,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4149:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":416,"name":"uint160","nodeType":"ElementaryTypeName","src":"4149:7:0","typeDescriptions":{}}},"id":419,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4149:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":415,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4141:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":414,"name":"address","nodeType":"ElementaryTypeName","src":"4141:7:0","typeDescriptions":{}}},"id":420,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4141:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":411,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4123:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":413,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4123:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":421,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4123:45:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":422,"nodeType":"ExpressionStatement","src":"4123:45:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c31","id":426,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4189:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""},"value":"startstop_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""}],"expression":{"id":423,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4178:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":425,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4178:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":427,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4178:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":428,"nodeType":"ExpressionStatement","src":"4178:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c32","id":432,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4228:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""},"value":"startstop_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""}],"expression":{"id":429,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4217:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":431,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":620,"src":"4217:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":433,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4217:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":434,"nodeType":"ExpressionStatement","src":"4217:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f70757265","id":438,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4270:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""},"value":"startstop_pure"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""}],"expression":{"id":435,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4256:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":437,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"callPure","nodeType":"MemberAccess","referencedDeclaration":662,"src":"4256:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure external"}},"id":439,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4256:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":440,"nodeType":"ExpressionStatement","src":"4256:31:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":441,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4297:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":443,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4297:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":444,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4297:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":445,"nodeType":"ExpressionStatement","src":"4297:18:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c33","id":449,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4336:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""},"value":"startstop_call3"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""}],"expression":{"id":446,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4325:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":448,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4325:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":450,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4325:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":451,"nodeType":"ExpressionStatement","src":"4325:29:0"},{"expression":{"arguments":[{"hexValue":"74657374696e67206e6573746564","id":455,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4377:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""},"value":"testing nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""}],"expression":{"id":452,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4365:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":454,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4365:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":456,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4365:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":457,"nodeType":"ExpressionStatement","src":"4365:29:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307831323334","id":465,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4438:6:0","typeDescriptions":{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"},"value":"0x1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"}],"id":464,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4430:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":463,"name":"uint160","nodeType":"ElementaryTypeName","src":"4430:7:0","typeDescriptions":{}}},"id":466,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4430:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":462,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4422:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":461,"name":"address","nodeType":"ElementaryTypeName","src":"4422:7:0","typeDescriptions":{}}},"id":467,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4422:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":458,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4404:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":460,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4404:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":468,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4404:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":469,"nodeType":"ExpressionStatement","src":"4404:43:0"},{"expression":{"arguments":[{"hexValue":"6e6573746564","id":473,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4470:8:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""},"value":"nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""}],"expression":{"id":470,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4457:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":472,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested1","nodeType":"MemberAccess","referencedDeclaration":635,"src":"4457:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":474,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4457:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":475,"nodeType":"ExpressionStatement","src":"4457:22:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":476,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4489:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":478,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4489:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":479,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4489:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":480,"nodeType":"ExpressionStatement","src":"4489:18:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206465706c6f796d656e74","id":484,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4530:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""},"value":"contract deployment"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""}],"expression":{"id":481,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4518:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":483,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4518:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":485,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4518:34:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":486,"nodeType":"ExpressionStatement","src":"4518:34:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078313233343536","id":494,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4591:8:0","typeDescriptions":{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"},"value":"0x123456"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"}],"id":493,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4583:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":492,"name":"uint160","nodeType":"ElementaryTypeName","src":"4583:7:0","typeDescriptions":{}}},"id":495,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4583:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":491,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4575:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":490,"name":"address","nodeType":"ElementaryTypeName","src":"4575:7:0","typeDescriptions":{}}},"id":496,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4575:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":487,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4562:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":489,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4562:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":497,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4562:40:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":498,"nodeType":"ExpressionStatement","src":"4562:40:0"},{"assignments":[501],"declarations":[{"constant":false,"id":501,"mutability":"mutable","name":"x","nameLocation":"4619:1:0","nodeType":"VariableDeclaration","scope":565,"src":"4612:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"},"typeName":{"id":500,"nodeType":"UserDefinedTypeName","pathNode":{"id":499,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4612:6:0"},"referencedDeclaration":676,"src":"4612:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"visibility":"internal"}],"id":507,"initialValue":{"arguments":[{"hexValue":"31323334","id":505,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4634:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":504,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4623:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":503,"nodeType":"UserDefinedTypeName","pathNode":{"id":502,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4627:6:0"},"referencedDeclaration":676,"src":"4627:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}}},"id":506,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4623:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4612:27:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":513,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":509,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":501,"src":"4657:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"id":510,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":665,"src":"4657:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":511,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4657:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":512,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4668:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4657:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":508,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4649:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":514,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4649:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":515,"nodeType":"ExpressionStatement","src":"4649:24:0"},{"expression":{"arguments":[{"hexValue":"6372656174652032","id":519,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4696:10:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""},"value":"create 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""}],"expression":{"id":516,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4684:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":518,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4684:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":520,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4684:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":521,"nodeType":"ExpressionStatement","src":"4684:23:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307863616665","id":529,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4746:6:0","typeDescriptions":{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"},"value":"0xcafe"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"}],"id":528,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4738:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":527,"name":"uint160","nodeType":"ElementaryTypeName","src":"4738:7:0","typeDescriptions":{}}},"id":530,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4738:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":526,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4730:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":525,"name":"address","nodeType":"ElementaryTypeName","src":"4730:7:0","typeDescriptions":{}}},"id":531,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4730:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":522,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4717:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":524,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4717:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":532,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4717:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":533,"nodeType":"ExpressionStatement","src":"4717:38:0"},{"assignments":[536],"declarations":[{"constant":false,"id":536,"mutability":"mutable","name":"y","nameLocation":"4772:1:0","nodeType":"VariableDeclaration","scope":565,"src":"4765:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"},"typeName":{"id":535,"nodeType":"UserDefinedTypeName","pathNode":{"id":534,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4765:6:0"},"referencedDeclaration":676,"src":"4765:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"visibility":"internal"}],"id":550,"initialValue":{"arguments":[{"hexValue":"31323334","id":548,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4815:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":539,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4776:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":538,"nodeType":"UserDefinedTypeName","pathNode":{"id":537,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4780:6:0"},"referencedDeclaration":676,"src":"4780:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}}},"id":547,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"names":["salt"],"nodeType":"FunctionCallOptions","options":[{"arguments":[{"arguments":[{"hexValue":"3432","id":544,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4809:2:0","typeDescriptions":{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"},"value":"42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"}],"id":543,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4801:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":542,"name":"uint256","nodeType":"ElementaryTypeName","src":"4801:7:0","typeDescriptions":{}}},"id":545,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4801:11:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":541,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4793:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_bytes32_$","typeString":"type(bytes32)"},"typeName":{"id":540,"name":"bytes32","nodeType":"ElementaryTypeName","src":"4793:7:0","typeDescriptions":{}}},"id":546,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4793:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"src":"4776:38:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$salt","typeString":"function (uint256) returns (contract FooBar)"}},"id":549,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4776:44:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4765:55:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":556,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":552,"name":"y","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":536,"src":"4838:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"id":553,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":665,"src":"4838:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":554,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4838:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":555,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4849:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4838:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":551,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4830:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":557,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4830:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":558,"nodeType":"ExpressionStatement","src":"4830:24:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":562,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4876:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":559,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4864:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":561,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4864:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":563,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4864:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":564,"nodeType":"ExpressionStatement","src":"4864:20:0"}]},"documentation":{"id":379,"nodeType":"StructuredDocumentation","src":"3842:56:0","text":"@notice example function, to test vm.broadcast with."},"functionSelector":"bef03abc","implemented":true,"kind":"function","modifiers":[],"name":"runBroadcast","nameLocation":"3912:12:0","parameters":{"id":380,"nodeType":"ParameterList","parameters":[],"src":"3924:2:0"},"returnParameters":{"id":381,"nodeType":"ParameterList","parameters":[],"src":"3934:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":590,"nodeType":"FunctionDefinition","src":"4986:143:0","nodes":[],"body":{"id":589,"nodeType":"Block","src":"5035:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":575,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":569,"src":"5057:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":572,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5045:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":574,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5045:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":576,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5045:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":577,"nodeType":"ExpressionStatement","src":"5045:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":581,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"5082:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":584,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"5110:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":585,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"5110:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":583,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5102:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":582,"name":"address","nodeType":"ElementaryTypeName","src":"5102:7:0","typeDescriptions":{}}},"id":586,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5102:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":578,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5070:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":580,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"5070:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":587,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5070:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":588,"nodeType":"ExpressionStatement","src":"5070:52:0"}]},"documentation":{"id":567,"nodeType":"StructuredDocumentation","src":"4897:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"4995:5:0","parameters":{"id":570,"nodeType":"ParameterList","parameters":[{"constant":false,"id":569,"mutability":"mutable","name":"_v","nameLocation":"5017:2:0","nodeType":"VariableDeclaration","scope":590,"src":"5001:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":568,"name":"string","nodeType":"ElementaryTypeName","src":"5001:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5000:20:0"},"returnParameters":{"id":571,"nodeType":"ParameterList","parameters":[],"src":"5035:0:0"},"scope":663,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":605,"nodeType":"FunctionDefinition","src":"5135:95:0","nodes":[],"body":{"id":604,"nodeType":"Block","src":"5179:51:0","nodes":[],"statements":[{"expression":{"id":596,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5189:9:0","subExpression":{"id":595,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5189:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":597,"nodeType":"ExpressionStatement","src":"5189:9:0"},{"expression":{"arguments":[{"id":601,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":592,"src":"5220:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":598,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5208:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":600,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5208:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":602,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5208:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":603,"nodeType":"ExpressionStatement","src":"5208:15:0"}]},"functionSelector":"7e79255d","implemented":true,"kind":"function","modifiers":[],"name":"call1","nameLocation":"5144:5:0","parameters":{"id":593,"nodeType":"ParameterList","parameters":[{"constant":false,"id":592,"mutability":"mutable","name":"_v","nameLocation":"5166:2:0","nodeType":"VariableDeclaration","scope":605,"src":"5150:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":591,"name":"string","nodeType":"ElementaryTypeName","src":"5150:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5149:20:0"},"returnParameters":{"id":594,"nodeType":"ParameterList","parameters":[],"src":"5179:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":620,"nodeType":"FunctionDefinition","src":"5236:95:0","nodes":[],"body":{"id":619,"nodeType":"Block","src":"5280:51:0","nodes":[],"statements":[{"expression":{"id":611,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5290:9:0","subExpression":{"id":610,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5290:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":612,"nodeType":"ExpressionStatement","src":"5290:9:0"},{"expression":{"arguments":[{"id":616,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":607,"src":"5321:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":613,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5309:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":615,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5309:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":617,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5309:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":618,"nodeType":"ExpressionStatement","src":"5309:15:0"}]},"functionSelector":"8d3ef7ca","implemented":true,"kind":"function","modifiers":[],"name":"call2","nameLocation":"5245:5:0","parameters":{"id":608,"nodeType":"ParameterList","parameters":[{"constant":false,"id":607,"mutability":"mutable","name":"_v","nameLocation":"5267:2:0","nodeType":"VariableDeclaration","scope":620,"src":"5251:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":606,"name":"string","nodeType":"ElementaryTypeName","src":"5251:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5250:20:0"},"returnParameters":{"id":609,"nodeType":"ParameterList","parameters":[],"src":"5280:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":635,"nodeType":"FunctionDefinition","src":"5337:98:0","nodes":[],"body":{"id":634,"nodeType":"Block","src":"5383:52:0","nodes":[],"statements":[{"expression":{"id":626,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5393:9:0","subExpression":{"id":625,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5393:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":627,"nodeType":"ExpressionStatement","src":"5393:9:0"},{"expression":{"arguments":[{"id":631,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":622,"src":"5425:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":628,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"5412:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":630,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested2","nodeType":"MemberAccess","referencedDeclaration":650,"src":"5412:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":632,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5412:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":633,"nodeType":"ExpressionStatement","src":"5412:16:0"}]},"functionSelector":"a76ccdfa","implemented":true,"kind":"function","modifiers":[],"name":"nested1","nameLocation":"5346:7:0","parameters":{"id":623,"nodeType":"ParameterList","parameters":[{"constant":false,"id":622,"mutability":"mutable","name":"_v","nameLocation":"5370:2:0","nodeType":"VariableDeclaration","scope":635,"src":"5354:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":621,"name":"string","nodeType":"ElementaryTypeName","src":"5354:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5353:20:0"},"returnParameters":{"id":624,"nodeType":"ParameterList","parameters":[],"src":"5383:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":650,"nodeType":"FunctionDefinition","src":"5441:97:0","nodes":[],"body":{"id":649,"nodeType":"Block","src":"5487:51:0","nodes":[],"statements":[{"expression":{"id":641,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5497:9:0","subExpression":{"id":640,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5497:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":642,"nodeType":"ExpressionStatement","src":"5497:9:0"},{"expression":{"arguments":[{"id":646,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":637,"src":"5528:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":643,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5516:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":645,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5516:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":647,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5516:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":648,"nodeType":"ExpressionStatement","src":"5516:15:0"}]},"functionSelector":"dbf1282f","implemented":true,"kind":"function","modifiers":[],"name":"nested2","nameLocation":"5450:7:0","parameters":{"id":638,"nodeType":"ParameterList","parameters":[{"constant":false,"id":637,"mutability":"mutable","name":"_v","nameLocation":"5474:2:0","nodeType":"VariableDeclaration","scope":650,"src":"5458:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":636,"name":"string","nodeType":"ElementaryTypeName","src":"5458:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5457:20:0"},"returnParameters":{"id":639,"nodeType":"ParameterList","parameters":[],"src":"5487:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":662,"nodeType":"FunctionDefinition","src":"5544:84:0","nodes":[],"body":{"id":661,"nodeType":"Block","src":"5596:32:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":658,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":652,"src":"5618:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":655,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5606:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":657,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5606:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":659,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5606:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":660,"nodeType":"ExpressionStatement","src":"5606:15:0"}]},"functionSelector":"7f8b915c","implemented":true,"kind":"function","modifiers":[],"name":"callPure","nameLocation":"5553:8:0","parameters":{"id":653,"nodeType":"ParameterList","parameters":[{"constant":false,"id":652,"mutability":"mutable","name":"_v","nameLocation":"5578:2:0","nodeType":"VariableDeclaration","scope":662,"src":"5562:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":651,"name":"string","nodeType":"ElementaryTypeName","src":"5562:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5561:20:0"},"returnParameters":{"id":654,"nodeType":"ParameterList","parameters":[],"src":"5596:0:0"},"scope":663,"stateMutability":"pure","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[676],"contractKind":"contract","documentation":{"id":193,"nodeType":"StructuredDocumentation","src":"2415:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[663],"name":"ScriptExample","nameLocation":"2550:13:0","scope":677,"usedErrors":[]},{"id":676,"nodeType":"ContractDefinition","src":"5632:96:0","nodes":[{"id":665,"nodeType":"VariableDeclaration","src":"5654:18:0","nodes":[],"constant":false,"functionSelector":"c2985578","mutability":"mutable","name":"foo","nameLocation":"5669:3:0","scope":676,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":664,"name":"uint256","nodeType":"ElementaryTypeName","src":"5654:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":675,"nodeType":"FunctionDefinition","src":"5679:47:0","nodes":[],"body":{"id":674,"nodeType":"Block","src":"5702:24:0","nodes":[],"statements":[{"expression":{"id":672,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":670,"name":"foo","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":665,"src":"5712:3:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":671,"name":"v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":667,"src":"5718:1:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5712:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":673,"nodeType":"ExpressionStatement","src":"5712:7:0"}]},"implemented":true,"kind":"constructor","modifiers":[],"name":"","nameLocation":"-1:-1:-1","parameters":{"id":668,"nodeType":"ParameterList","parameters":[{"constant":false,"id":667,"mutability":"mutable","name":"v","nameLocation":"5699:1:0","nodeType":"VariableDeclaration","scope":675,"src":"5691:9:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":666,"name":"uint256","nodeType":"ElementaryTypeName","src":"5691:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"5690:11:0"},"returnParameters":{"id":669,"nodeType":"ParameterList","parameters":[],"src":"5702:0:0"},"scope":676,"stateMutability":"nonpayable","virtual":false,"visibility":"public"}],"abstract":false,"baseContracts":[],"canonicalName":"FooBar","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[676],"name":"FooBar","nameLocation":"5641:6:0","scope":677,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file +{"abi":[{"type":"constructor","inputs":[{"name":"v","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"type":"function","name":"foo","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"}],"bytecode":{"object":"0x608060405234801561001057600080fd5b506040516100b23803806100b283398101604081905261002f91610037565b600055610050565b60006020828403121561004957600080fd5b5051919050565b60548061005e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b603560005481565b60405190815260200160405180910390f3fea164736f6c634300080f000a","sourceMap":"5902:96:0:-:0;;;5949:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5982:3;:7;5902:96;;14:184:1;84:6;137:2;125:9;116:7;112:23;108:32;105:52;;;153:1;150;143:12;105:52;-1:-1:-1;176:16:1;;14:184;-1:-1:-1;14:184:1:o;:::-;5902:96:0;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b603560005481565b60405190815260200160405180910390f3fea164736f6c634300080f000a","sourceMap":"5902:96:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5924:18;;;;;;;;;160:25:1;;;148:2;133:18;5924::0;;;;;;","linkReferences":{}},"methodIdentifiers":{"foo()":"c2985578"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"v\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"foo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"FooBar\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x8d1dfa41908e7ccc3a498a2a2aa51c5275bedbb904ce32d08f8598e36f896d8d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5117bb7158363cae8b9dc0508d2852692fd36172f1c699ff680afbb5acebe1f3\",\"dweb:/ipfs/QmQdahJ8SPKfJ4yea5Ge9qaj5qh1TxVffhHvaWytBaL95h\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"uint256","name":"v","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"stateMutability":"view","type":"function","name":"foo","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"FooBar"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x8d1dfa41908e7ccc3a498a2a2aa51c5275bedbb904ce32d08f8598e36f896d8d","urls":["bzz-raw://5117bb7158363cae8b9dc0508d2852692fd36172f1c699ff680afbb5acebe1f3","dweb:/ipfs/QmQdahJ8SPKfJ4yea5Ge9qaj5qh1TxVffhHvaWytBaL95h"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[{"astId":708,"contract":"scripts/ScriptExample.s.sol:FooBar","label":"foo","offset":0,"slot":"0","type":"t_uint256"}],"types":{"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"userdoc":{"version":1,"kind":"user"},"devdoc":{"version":1,"kind":"dev"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":720,"exportedSymbols":{"FooBar":[719],"ScriptExample":[706],"Vm":[55],"console":[192]},"nodeType":"SourceUnit","src":"32:5967:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":55,"nodeType":"ContractDefinition","src":"120:616:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":55,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":38,"nodeType":"FunctionDefinition","src":"516:30:0","nodes":[],"functionSelector":"afc98040","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"525:9:0","parameters":{"id":36,"nodeType":"ParameterList","parameters":[],"src":"534:2:0"},"returnParameters":{"id":37,"nodeType":"ParameterList","parameters":[],"src":"545:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":43,"nodeType":"FunctionDefinition","src":"551:47:0","nodes":[],"functionSelector":"e6962cdb","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"560:9:0","parameters":{"id":41,"nodeType":"ParameterList","parameters":[{"constant":false,"id":40,"mutability":"mutable","name":"msgSender","nameLocation":"578:9:0","nodeType":"VariableDeclaration","scope":43,"src":"570:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":39,"name":"address","nodeType":"ElementaryTypeName","src":"570:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"569:19:0"},"returnParameters":{"id":42,"nodeType":"ParameterList","parameters":[],"src":"597:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":48,"nodeType":"FunctionDefinition","src":"603:52:0","nodes":[],"functionSelector":"7fec2a8d","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"612:14:0","parameters":{"id":46,"nodeType":"ParameterList","parameters":[{"constant":false,"id":45,"mutability":"mutable","name":"msgSender","nameLocation":"635:9:0","nodeType":"VariableDeclaration","scope":48,"src":"627:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":44,"name":"address","nodeType":"ElementaryTypeName","src":"627:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"626:19:0"},"returnParameters":{"id":47,"nodeType":"ParameterList","parameters":[],"src":"654:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":51,"nodeType":"FunctionDefinition","src":"660:35:0","nodes":[],"functionSelector":"7fb5297f","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"669:14:0","parameters":{"id":49,"nodeType":"ParameterList","parameters":[],"src":"683:2:0"},"returnParameters":{"id":50,"nodeType":"ParameterList","parameters":[],"src":"694:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":54,"nodeType":"FunctionDefinition","src":"700:34:0","nodes":[],"functionSelector":"76eadd36","implemented":false,"kind":"function","modifiers":[],"name":"stopBroadcast","nameLocation":"709:13:0","parameters":{"id":52,"nodeType":"ParameterList","parameters":[],"src":"722:2:0"},"returnParameters":{"id":53,"nodeType":"ParameterList","parameters":[],"src":"733:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[55],"name":"Vm","nameLocation":"130:2:0","scope":720,"usedErrors":[]},{"id":192,"nodeType":"ContractDefinition","src":"791:1622:0","nodes":[{"id":61,"nodeType":"VariableDeclaration","src":"813:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"830:15:0","scope":192,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":56,"name":"address","nodeType":"ElementaryTypeName","src":"813:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":59,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"856:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":58,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"848:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":57,"name":"address","nodeType":"ElementaryTypeName","src":"848:7:0","typeDescriptions":{}}},"id":60,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"848:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":78,"nodeType":"FunctionDefinition","src":"906:221:0","nodes":[],"body":{"id":77,"nodeType":"Block","src":"1065:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"1084:37:0","statements":[{"nodeType":"YulAssignment","src":"1098:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"1107:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"1098:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":67,"isOffset":false,"isSlot":false,"src":"1107:4:0","valueSize":1},{"declaration":74,"isOffset":false,"isSlot":false,"src":"1098:5:0","valueSize":1}],"id":76,"nodeType":"InlineAssembly","src":"1075:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"915:25:0","parameters":{"id":68,"nodeType":"ParameterList","parameters":[{"constant":false,"id":67,"mutability":"mutable","name":"fnIn","nameLocation":"987:4:0","nodeType":"VariableDeclaration","scope":78,"src":"950:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":66,"nodeType":"FunctionTypeName","parameterTypes":{"id":64,"nodeType":"ParameterList","parameters":[{"constant":false,"id":63,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":66,"src":"959:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":62,"name":"bytes","nodeType":"ElementaryTypeName","src":"959:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"958:14:0"},"returnParameterTypes":{"id":65,"nodeType":"ParameterList","parameters":[],"src":"987:0:0"},"src":"950:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"940:57:0"},"returnParameters":{"id":75,"nodeType":"ParameterList","parameters":[{"constant":false,"id":74,"mutability":"mutable","name":"fnOut","nameLocation":"1058:5:0","nodeType":"VariableDeclaration","scope":78,"src":"1021:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":73,"nodeType":"FunctionTypeName","parameterTypes":{"id":71,"nodeType":"ParameterList","parameters":[{"constant":false,"id":70,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":73,"src":"1030:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":69,"name":"bytes","nodeType":"ElementaryTypeName","src":"1030:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1029:14:0"},"returnParameterTypes":{"id":72,"nodeType":"ParameterList","parameters":[],"src":"1058:0:0"},"src":"1021:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"1020:44:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":90,"nodeType":"FunctionDefinition","src":"1133:133:0","nodes":[],"body":{"id":89,"nodeType":"Block","src":"1194:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":86,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1251:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":84,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":106,"src":"1230:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":83,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":78,"src":"1204:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":85,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":87,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":88,"nodeType":"ExpressionStatement","src":"1204:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"1142:15:0","parameters":{"id":81,"nodeType":"ParameterList","parameters":[{"constant":false,"id":80,"mutability":"mutable","name":"payload","nameLocation":"1171:7:0","nodeType":"VariableDeclaration","scope":90,"src":"1158:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":79,"name":"bytes","nodeType":"ElementaryTypeName","src":"1158:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1157:22:0"},"returnParameters":{"id":82,"nodeType":"ParameterList","parameters":[],"src":"1194:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":106,"nodeType":"FunctionDefinition","src":"1272:380:0","nodes":[],"body":{"id":105,"nodeType":"Block","src":"1336:316:0","nodes":[],"statements":[{"assignments":[96],"declarations":[{"constant":false,"id":96,"mutability":"mutable","name":"payloadLength","nameLocation":"1354:13:0","nodeType":"VariableDeclaration","scope":105,"src":"1346:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":95,"name":"uint256","nodeType":"ElementaryTypeName","src":"1346:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":99,"initialValue":{"expression":{"id":97,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":92,"src":"1370:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":98,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1370:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1346:38:0"},{"assignments":[101],"declarations":[{"constant":false,"id":101,"mutability":"mutable","name":"consoleAddress","nameLocation":"1402:14:0","nodeType":"VariableDeclaration","scope":105,"src":"1394:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":100,"name":"address","nodeType":"ElementaryTypeName","src":"1394:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":103,"initialValue":{"id":102,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":61,"src":"1419:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1394:40:0"},{"AST":{"nodeType":"YulBlock","src":"1496:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1510:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1534:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1543:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1530:3:0"},"nodeType":"YulFunctionCall","src":"1530:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1514:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1559:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1579:3:0"},"nodeType":"YulFunctionCall","src":"1579:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1586:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1602:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1616:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1631:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1634:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1568:10:0"},"nodeType":"YulFunctionCall","src":"1568:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1563:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":101,"isOffset":false,"isSlot":false,"src":"1586:14:0","valueSize":1},{"declaration":92,"isOffset":false,"isSlot":false,"src":"1534:7:0","valueSize":1},{"declaration":96,"isOffset":false,"isSlot":false,"src":"1616:13:0","valueSize":1}],"id":104,"nodeType":"InlineAssembly","src":"1487:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1281:19:0","parameters":{"id":93,"nodeType":"ParameterList","parameters":[{"constant":false,"id":92,"mutability":"mutable","name":"payload","nameLocation":"1314:7:0","nodeType":"VariableDeclaration","scope":106,"src":"1301:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":91,"name":"bytes","nodeType":"ElementaryTypeName","src":"1301:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1300:22:0"},"returnParameters":{"id":94,"nodeType":"ParameterList","parameters":[],"src":"1336:0:0"},"scope":192,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":120,"nodeType":"FunctionDefinition","src":"1658:121:0","nodes":[],"body":{"id":119,"nodeType":"Block","src":"1703:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":114,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1753:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":115,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":108,"src":"1768:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":112,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1729:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":113,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1729:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":116,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1729:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":111,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1713:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":117,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1713:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":118,"nodeType":"ExpressionStatement","src":"1713:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1667:3:0","parameters":{"id":109,"nodeType":"ParameterList","parameters":[{"constant":false,"id":108,"mutability":"mutable","name":"p0","nameLocation":"1685:2:0","nodeType":"VariableDeclaration","scope":120,"src":"1671:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":107,"name":"string","nodeType":"ElementaryTypeName","src":"1671:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1670:18:0"},"returnParameters":{"id":110,"nodeType":"ParameterList","parameters":[],"src":"1703:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":137,"nodeType":"FunctionDefinition","src":"1785:139:0","nodes":[],"body":{"id":136,"nodeType":"Block","src":"1839:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":130,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1889:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":131,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":122,"src":"1909:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":132,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":124,"src":"1913:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":128,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1865:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":129,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1865:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":133,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1865:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":127,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1849:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":134,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1849:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":135,"nodeType":"ExpressionStatement","src":"1849:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1794:3:0","parameters":{"id":125,"nodeType":"ParameterList","parameters":[{"constant":false,"id":122,"mutability":"mutable","name":"p0","nameLocation":"1812:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1798:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":121,"name":"string","nodeType":"ElementaryTypeName","src":"1798:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":124,"mutability":"mutable","name":"p1","nameLocation":"1821:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1816:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":123,"name":"bool","nodeType":"ElementaryTypeName","src":"1816:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1797:27:0"},"returnParameters":{"id":126,"nodeType":"ParameterList","parameters":[],"src":"1839:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":154,"nodeType":"FunctionDefinition","src":"1930:145:0","nodes":[],"body":{"id":153,"nodeType":"Block","src":"1987:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":147,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2037:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":148,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":139,"src":"2060:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":149,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":141,"src":"2064:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":145,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2013:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":146,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2013:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":150,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2013:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":144,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1997:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":151,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1997:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":152,"nodeType":"ExpressionStatement","src":"1997:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1939:3:0","parameters":{"id":142,"nodeType":"ParameterList","parameters":[{"constant":false,"id":139,"mutability":"mutable","name":"p0","nameLocation":"1957:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1943:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":138,"name":"string","nodeType":"ElementaryTypeName","src":"1943:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":141,"mutability":"mutable","name":"p1","nameLocation":"1969:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1961:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":140,"name":"uint256","nodeType":"ElementaryTypeName","src":"1961:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1942:30:0"},"returnParameters":{"id":143,"nodeType":"ParameterList","parameters":[],"src":"1987:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":171,"nodeType":"FunctionDefinition","src":"2081:145:0","nodes":[],"body":{"id":170,"nodeType":"Block","src":"2138:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":164,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2188:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":165,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":156,"src":"2211:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":166,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":158,"src":"2215:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":162,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2164:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":163,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2164:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":167,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2164:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":161,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2148:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":168,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2148:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":169,"nodeType":"ExpressionStatement","src":"2148:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2090:3:0","parameters":{"id":159,"nodeType":"ParameterList","parameters":[{"constant":false,"id":156,"mutability":"mutable","name":"p0","nameLocation":"2108:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2094:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":155,"name":"string","nodeType":"ElementaryTypeName","src":"2094:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":158,"mutability":"mutable","name":"p1","nameLocation":"2120:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2112:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":157,"name":"address","nodeType":"ElementaryTypeName","src":"2112:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"2093:30:0"},"returnParameters":{"id":160,"nodeType":"ParameterList","parameters":[],"src":"2138:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":191,"nodeType":"FunctionDefinition","src":"2232:179:0","nodes":[],"body":{"id":190,"nodeType":"Block","src":"2313:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":183,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2363:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":184,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2392:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":185,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":175,"src":"2396:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":186,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":177,"src":"2400:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":181,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2339:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":182,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2339:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":187,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2339:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":180,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2323:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":188,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2323:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":189,"nodeType":"ExpressionStatement","src":"2323:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2241:3:0","parameters":{"id":178,"nodeType":"ParameterList","parameters":[{"constant":false,"id":173,"mutability":"mutable","name":"p0","nameLocation":"2259:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2245:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":172,"name":"string","nodeType":"ElementaryTypeName","src":"2245:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":175,"mutability":"mutable","name":"p1","nameLocation":"2277:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2263:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":174,"name":"string","nodeType":"ElementaryTypeName","src":"2263:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":177,"mutability":"mutable","name":"p2","nameLocation":"2295:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2281:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":176,"name":"string","nodeType":"ElementaryTypeName","src":"2281:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2244:54:0"},"returnParameters":{"id":179,"nodeType":"ParameterList","parameters":[],"src":"2313:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[192],"name":"console","nameLocation":"799:7:0","scope":720,"usedErrors":[]},{"id":706,"nodeType":"ContractDefinition","src":"2541:3359:0","nodes":[{"id":207,"nodeType":"VariableDeclaration","src":"2571:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2597:10:0","scope":706,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":194,"name":"address","nodeType":"ElementaryTypeName","src":"2571:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2644:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":201,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2634:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":203,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2634:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":200,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2626:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":199,"name":"uint256","nodeType":"ElementaryTypeName","src":"2626:7:0","typeDescriptions":{}}},"id":204,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2626:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":198,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2618:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":197,"name":"uint160","nodeType":"ElementaryTypeName","src":"2618:7:0","typeDescriptions":{}}},"id":205,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2618:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":196,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2610:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":195,"name":"address","nodeType":"ElementaryTypeName","src":"2610:7:0","typeDescriptions":{}}},"id":206,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2610:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":213,"nodeType":"VariableDeclaration","src":"2671:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2692:2:0","scope":706,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"},"typeName":{"id":209,"nodeType":"UserDefinedTypeName","pathNode":{"id":208,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":55,"src":"2671:2:0"},"referencedDeclaration":55,"src":"2671:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"value":{"arguments":[{"id":211,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":207,"src":"2700:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":210,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":55,"src":"2697:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$55_$","typeString":"type(contract Vm)"}},"id":212,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2697:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"visibility":"internal"},{"id":215,"nodeType":"VariableDeclaration","src":"2775:22:0","nodes":[],"constant":false,"functionSelector":"61bc221a","mutability":"mutable","name":"counter","nameLocation":"2790:7:0","scope":706,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":214,"name":"uint256","nodeType":"ElementaryTypeName","src":"2775:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":378,"nodeType":"FunctionDefinition","src":"2887:949:0","nodes":[],"body":{"id":377,"nodeType":"Block","src":"2909:927:0","nodes":[],"statements":[{"assignments":[220],"declarations":[{"constant":false,"id":220,"mutability":"mutable","name":"x","nameLocation":"2924:1:0","nodeType":"VariableDeclaration","scope":377,"src":"2919:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":219,"name":"bool","nodeType":"ElementaryTypeName","src":"2919:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":226,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":223,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2937:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":224,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2953:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":221,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"2928:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":222,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2928:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":225,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2928:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2919:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":230,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2981:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":231,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":220,"src":"3004:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":227,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"2969:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":229,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":137,"src":"2969:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2969:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":233,"nodeType":"ExpressionStatement","src":"2969:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":237,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3029:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":240,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3054:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}],"id":239,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3046:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":238,"name":"address","nodeType":"ElementaryTypeName","src":"3046:7:0","typeDescriptions":{}}},"id":241,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3046:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":234,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3017:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":236,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3017:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":242,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3017:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":243,"nodeType":"ExpressionStatement","src":"3017:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":247,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3082:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":252,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3120:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}],"id":251,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3112:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":250,"name":"address","nodeType":"ElementaryTypeName","src":"3112:7:0","typeDescriptions":{}}},"id":253,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3112:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":248,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3100:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3100:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":254,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3100:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":244,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3070:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":246,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3070:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":255,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3070:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":256,"nodeType":"ExpressionStatement","src":"3070:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":260,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3149:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":263,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3172:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":264,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3172:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":262,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3164:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":261,"name":"address","nodeType":"ElementaryTypeName","src":"3164:7:0","typeDescriptions":{}}},"id":265,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3164:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":257,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3137:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":259,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3137:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":266,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3137:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":267,"nodeType":"ExpressionStatement","src":"3137:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":271,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3206:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":276,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3242:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":277,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3242:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":275,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3234:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":274,"name":"address","nodeType":"ElementaryTypeName","src":"3234:7:0","typeDescriptions":{}}},"id":278,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3234:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":272,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3222:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":273,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3222:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":279,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3222:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":268,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3194:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":270,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3194:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":280,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3194:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":281,"nodeType":"ExpressionStatement","src":"3194:61:0"},{"assignments":[283],"declarations":[{"constant":false,"id":283,"mutability":"mutable","name":"json","nameLocation":"3280:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3266:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":282,"name":"string","nodeType":"ElementaryTypeName","src":"3266:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":285,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3287:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"3266:55:0"},{"assignments":[290],"declarations":[{"constant":false,"id":290,"mutability":"mutable","name":"keys","nameLocation":"3347:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3331:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":288,"name":"string","nodeType":"ElementaryTypeName","src":"3331:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":289,"nodeType":"ArrayTypeName","src":"3331:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":296,"initialValue":{"arguments":[{"id":293,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":283,"src":"3371:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":294,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3377:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":291,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3354:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":292,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3354:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":295,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3354:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3331:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":300,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3414:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":301,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3422:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":303,"indexExpression":{"hexValue":"30","id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3427:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3422:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":304,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3431:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":306,"indexExpression":{"hexValue":"31","id":305,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3436:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3431:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":297,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3402:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":299,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":191,"src":"3402:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":307,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3402:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":308,"nodeType":"ExpressionStatement","src":"3402:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":312,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3461:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":309,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3450:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":311,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":633,"src":"3450:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":313,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3450:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":314,"nodeType":"ExpressionStatement","src":"3450:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":322,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3517:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":321,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3509:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":320,"name":"uint160","nodeType":"ElementaryTypeName","src":"3509:7:0","typeDescriptions":{}}},"id":323,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3509:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":319,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3501:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":318,"name":"address","nodeType":"ElementaryTypeName","src":"3501:7:0","typeDescriptions":{}}},"id":324,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3501:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":315,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3487:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":317,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3487:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3487:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":326,"nodeType":"ExpressionStatement","src":"3487:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":330,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3545:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":327,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3534:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":329,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":633,"src":"3534:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3534:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":332,"nodeType":"ExpressionStatement","src":"3534:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":336,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3582:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":339,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3617:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":340,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3617:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":338,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3609:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":337,"name":"address","nodeType":"ElementaryTypeName","src":"3609:7:0","typeDescriptions":{}}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3609:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":333,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3570:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":335,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3570:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3570:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3570:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3651:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":350,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3689:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}],"id":349,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3681:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":348,"name":"address","nodeType":"ElementaryTypeName","src":"3681:7:0","typeDescriptions":{}}},"id":351,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3681:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":344,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3639:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3639:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3639:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":353,"nodeType":"ExpressionStatement","src":"3639:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":357,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3716:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":354,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3705:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":356,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":633,"src":"3705:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":358,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3705:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":359,"nodeType":"ExpressionStatement","src":"3705:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":360,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3741:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":362,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3741:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":363,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3741:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":364,"nodeType":"ExpressionStatement","src":"3741:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":368,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3776:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":365,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3765:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":367,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":633,"src":"3765:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":369,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3765:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":370,"nodeType":"ExpressionStatement","src":"3765:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":374,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3821:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":371,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3809:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":373,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"3809:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":375,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3809:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":376,"nodeType":"ExpressionStatement","src":"3809:20:0"}]},"documentation":{"id":216,"nodeType":"StructuredDocumentation","src":"2804:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2896:3:0","parameters":{"id":217,"nodeType":"ParameterList","parameters":[],"src":"2899:2:0"},"returnParameters":{"id":218,"nodeType":"ParameterList","parameters":[],"src":"2909:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":609,"nodeType":"FunctionDefinition","src":"3903:1258:0","nodes":[],"body":{"id":608,"nodeType":"Block","src":"3934:1227:0","nodes":[],"statements":[{"expression":{"arguments":[{"hexValue":"6e6f6e6365207374617274","id":385,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3956:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_71efc69b9a13b6bc1e9a14d766ff01c79022262c6daa6532fb5dfb14f8511a20","typeString":"literal_string \"nonce start\""},"value":"nonce start"},{"arguments":[{"arguments":[{"arguments":[{"id":392,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3999:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}],"id":391,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3991:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":390,"name":"address","nodeType":"ElementaryTypeName","src":"3991:7:0","typeDescriptions":{}}},"id":393,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3991:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":388,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3979:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":389,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3979:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":394,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3979:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint64","typeString":"uint64"}],"id":387,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3971:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":386,"name":"uint256","nodeType":"ElementaryTypeName","src":"3971:7:0","typeDescriptions":{}}},"id":395,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3971:35:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_71efc69b9a13b6bc1e9a14d766ff01c79022262c6daa6532fb5dfb14f8511a20","typeString":"literal_string \"nonce start\""},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":382,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3944:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":384,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3944:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":396,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3944:63:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":397,"nodeType":"ExpressionStatement","src":"3944:63:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073696e676c65","id":401,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4030:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""},"value":"testing single"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""}],"expression":{"id":398,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4018:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":400,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4018:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":402,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4018:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":403,"nodeType":"ExpressionStatement","src":"4018:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":404,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4057:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":406,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"4057:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":407,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4057:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":408,"nodeType":"ExpressionStatement","src":"4057:14:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c31","id":412,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4092:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""},"value":"single_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""}],"expression":{"id":409,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4081:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":411,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":648,"src":"4081:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":413,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4081:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":414,"nodeType":"ExpressionStatement","src":"4081:26:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c32","id":418,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4128:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""},"value":"single_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""}],"expression":{"id":415,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4117:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":417,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":663,"src":"4117:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":419,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4117:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":420,"nodeType":"ExpressionStatement","src":"4117:26:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073746172742f73746f70","id":424,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4166:20:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""},"value":"testing start/stop"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""}],"expression":{"id":421,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4154:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":423,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4154:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":425,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4154:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":426,"nodeType":"ExpressionStatement","src":"4154:33:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078633066666565","id":434,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4231:8:0","typeDescriptions":{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"},"value":"0xc0ffee"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"}],"id":433,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4223:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":432,"name":"uint160","nodeType":"ElementaryTypeName","src":"4223:7:0","typeDescriptions":{}}},"id":435,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4223:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":431,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4215:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":430,"name":"address","nodeType":"ElementaryTypeName","src":"4215:7:0","typeDescriptions":{}}},"id":436,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4215:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":427,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4197:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":429,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4197:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":437,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4197:45:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":438,"nodeType":"ExpressionStatement","src":"4197:45:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c31","id":442,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4263:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""},"value":"startstop_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""}],"expression":{"id":439,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4252:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":441,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":648,"src":"4252:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":443,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4252:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":444,"nodeType":"ExpressionStatement","src":"4252:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c32","id":448,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4302:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""},"value":"startstop_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""}],"expression":{"id":445,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4291:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":447,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":663,"src":"4291:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":449,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4291:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":450,"nodeType":"ExpressionStatement","src":"4291:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f70757265","id":454,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4344:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""},"value":"startstop_pure"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""}],"expression":{"id":451,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4330:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":453,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"callPure","nodeType":"MemberAccess","referencedDeclaration":705,"src":"4330:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure external"}},"id":455,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4330:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":456,"nodeType":"ExpressionStatement","src":"4330:31:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":457,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4371:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":459,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4371:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":460,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4371:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":461,"nodeType":"ExpressionStatement","src":"4371:18:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c33","id":465,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4410:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""},"value":"startstop_call3"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""}],"expression":{"id":462,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4399:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":464,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":648,"src":"4399:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":466,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4399:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":467,"nodeType":"ExpressionStatement","src":"4399:29:0"},{"expression":{"arguments":[{"hexValue":"74657374696e67206e6573746564","id":471,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4451:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""},"value":"testing nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""}],"expression":{"id":468,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4439:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":470,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4439:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":472,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4439:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":473,"nodeType":"ExpressionStatement","src":"4439:29:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307831323334","id":481,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4512:6:0","typeDescriptions":{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"},"value":"0x1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"}],"id":480,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4504:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":479,"name":"uint160","nodeType":"ElementaryTypeName","src":"4504:7:0","typeDescriptions":{}}},"id":482,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4504:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":478,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4496:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":477,"name":"address","nodeType":"ElementaryTypeName","src":"4496:7:0","typeDescriptions":{}}},"id":483,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4496:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":474,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4478:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":476,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4478:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":484,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4478:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":485,"nodeType":"ExpressionStatement","src":"4478:43:0"},{"expression":{"arguments":[{"hexValue":"6e6573746564","id":489,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4544:8:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""},"value":"nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""}],"expression":{"id":486,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4531:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":488,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested1","nodeType":"MemberAccess","referencedDeclaration":678,"src":"4531:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":490,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4531:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":491,"nodeType":"ExpressionStatement","src":"4531:22:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":492,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4563:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":494,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4563:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":495,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4563:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":496,"nodeType":"ExpressionStatement","src":"4563:18:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206465706c6f796d656e74","id":500,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4604:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""},"value":"contract deployment"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""}],"expression":{"id":497,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4592:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":499,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4592:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":501,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4592:34:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":502,"nodeType":"ExpressionStatement","src":"4592:34:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078313233343536","id":510,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4665:8:0","typeDescriptions":{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"},"value":"0x123456"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"}],"id":509,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4657:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":508,"name":"uint160","nodeType":"ElementaryTypeName","src":"4657:7:0","typeDescriptions":{}}},"id":511,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4657:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":507,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4649:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":506,"name":"address","nodeType":"ElementaryTypeName","src":"4649:7:0","typeDescriptions":{}}},"id":512,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4649:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":503,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4636:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":505,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4636:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":513,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4636:40:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":514,"nodeType":"ExpressionStatement","src":"4636:40:0"},{"assignments":[517],"declarations":[{"constant":false,"id":517,"mutability":"mutable","name":"x","nameLocation":"4693:1:0","nodeType":"VariableDeclaration","scope":608,"src":"4686:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"},"typeName":{"id":516,"nodeType":"UserDefinedTypeName","pathNode":{"id":515,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":719,"src":"4686:6:0"},"referencedDeclaration":719,"src":"4686:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"visibility":"internal"}],"id":523,"initialValue":{"arguments":[{"hexValue":"31323334","id":521,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4708:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":520,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4697:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$719_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":519,"nodeType":"UserDefinedTypeName","pathNode":{"id":518,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":719,"src":"4701:6:0"},"referencedDeclaration":719,"src":"4701:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}}},"id":522,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4697:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4686:27:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":529,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":525,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":517,"src":"4731:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"id":526,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":708,"src":"4731:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":527,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4731:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":528,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4742:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4731:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":524,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4723:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":530,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4723:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":531,"nodeType":"ExpressionStatement","src":"4723:24:0"},{"expression":{"arguments":[{"hexValue":"6372656174652032","id":535,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4770:10:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""},"value":"create 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""}],"expression":{"id":532,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4758:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":534,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4758:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":536,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4758:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":537,"nodeType":"ExpressionStatement","src":"4758:23:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307863616665","id":545,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4820:6:0","typeDescriptions":{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"},"value":"0xcafe"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"}],"id":544,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4812:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":543,"name":"uint160","nodeType":"ElementaryTypeName","src":"4812:7:0","typeDescriptions":{}}},"id":546,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4812:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":542,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4804:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":541,"name":"address","nodeType":"ElementaryTypeName","src":"4804:7:0","typeDescriptions":{}}},"id":547,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4804:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":538,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4791:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":540,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4791:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":548,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4791:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":549,"nodeType":"ExpressionStatement","src":"4791:38:0"},{"assignments":[552],"declarations":[{"constant":false,"id":552,"mutability":"mutable","name":"y","nameLocation":"4846:1:0","nodeType":"VariableDeclaration","scope":608,"src":"4839:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"},"typeName":{"id":551,"nodeType":"UserDefinedTypeName","pathNode":{"id":550,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":719,"src":"4839:6:0"},"referencedDeclaration":719,"src":"4839:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"visibility":"internal"}],"id":566,"initialValue":{"arguments":[{"hexValue":"31323334","id":564,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4889:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":555,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4850:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$719_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":554,"nodeType":"UserDefinedTypeName","pathNode":{"id":553,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":719,"src":"4854:6:0"},"referencedDeclaration":719,"src":"4854:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}}},"id":563,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"names":["salt"],"nodeType":"FunctionCallOptions","options":[{"arguments":[{"arguments":[{"hexValue":"3432","id":560,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4883:2:0","typeDescriptions":{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"},"value":"42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"}],"id":559,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4875:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":558,"name":"uint256","nodeType":"ElementaryTypeName","src":"4875:7:0","typeDescriptions":{}}},"id":561,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4875:11:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":557,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4867:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_bytes32_$","typeString":"type(bytes32)"},"typeName":{"id":556,"name":"bytes32","nodeType":"ElementaryTypeName","src":"4867:7:0","typeDescriptions":{}}},"id":562,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4867:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"src":"4850:38:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$719_$salt","typeString":"function (uint256) returns (contract FooBar)"}},"id":565,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4850:44:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4839:55:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":572,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":568,"name":"y","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":552,"src":"4912:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"id":569,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":708,"src":"4912:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":570,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4912:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":571,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4923:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4912:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":567,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4904:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":573,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4904:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":574,"nodeType":"ExpressionStatement","src":"4904:24:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":578,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4950:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":575,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4938:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":577,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4938:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":579,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4938:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":580,"nodeType":"ExpressionStatement","src":"4938:20:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":581,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"5042:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":583,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"5042:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":584,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5042:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":585,"nodeType":"ExpressionStatement","src":"5042:14:0"},{"expression":{"arguments":[{"hexValue":"31323334","id":589,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"5077:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":588,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"5066:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$719_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":587,"nodeType":"UserDefinedTypeName","pathNode":{"id":586,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":719,"src":"5070:6:0"},"referencedDeclaration":719,"src":"5070:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}}},"id":590,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5066:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"id":591,"nodeType":"ExpressionStatement","src":"5066:16:0"},{"expression":{"arguments":[{"hexValue":"6e6f6e636520656e64","id":595,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"5105:11:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa629e6661ad2a2bdb09cf9a3a276ce0d722482ae5c2887650751be0938847e8","typeString":"literal_string \"nonce end\""},"value":"nonce end"},{"arguments":[{"arguments":[{"arguments":[{"id":602,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"5146:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}],"id":601,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5138:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":600,"name":"address","nodeType":"ElementaryTypeName","src":"5138:7:0","typeDescriptions":{}}},"id":603,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5138:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":598,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"5126:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":599,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"5126:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":604,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5126:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint64","typeString":"uint64"}],"id":597,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5118:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":596,"name":"uint256","nodeType":"ElementaryTypeName","src":"5118:7:0","typeDescriptions":{}}},"id":605,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5118:35:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa629e6661ad2a2bdb09cf9a3a276ce0d722482ae5c2887650751be0938847e8","typeString":"literal_string \"nonce end\""},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":592,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5093:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":594,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"5093:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":606,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5093:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":607,"nodeType":"ExpressionStatement","src":"5093:61:0"}]},"documentation":{"id":379,"nodeType":"StructuredDocumentation","src":"3842:56:0","text":"@notice example function, to test vm.broadcast with."},"functionSelector":"bef03abc","implemented":true,"kind":"function","modifiers":[],"name":"runBroadcast","nameLocation":"3912:12:0","parameters":{"id":380,"nodeType":"ParameterList","parameters":[],"src":"3924:2:0"},"returnParameters":{"id":381,"nodeType":"ParameterList","parameters":[],"src":"3934:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":633,"nodeType":"FunctionDefinition","src":"5256:143:0","nodes":[],"body":{"id":632,"nodeType":"Block","src":"5305:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":618,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":612,"src":"5327:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":615,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5315:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":617,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5315:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":619,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5315:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":620,"nodeType":"ExpressionStatement","src":"5315:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":624,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"5352:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":627,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"5380:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":628,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"5380:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":626,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5372:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":625,"name":"address","nodeType":"ElementaryTypeName","src":"5372:7:0","typeDescriptions":{}}},"id":629,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5372:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":621,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5340:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":623,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"5340:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":630,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5340:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":631,"nodeType":"ExpressionStatement","src":"5340:52:0"}]},"documentation":{"id":610,"nodeType":"StructuredDocumentation","src":"5167:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"5265:5:0","parameters":{"id":613,"nodeType":"ParameterList","parameters":[{"constant":false,"id":612,"mutability":"mutable","name":"_v","nameLocation":"5287:2:0","nodeType":"VariableDeclaration","scope":633,"src":"5271:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":611,"name":"string","nodeType":"ElementaryTypeName","src":"5271:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5270:20:0"},"returnParameters":{"id":614,"nodeType":"ParameterList","parameters":[],"src":"5305:0:0"},"scope":706,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":648,"nodeType":"FunctionDefinition","src":"5405:95:0","nodes":[],"body":{"id":647,"nodeType":"Block","src":"5449:51:0","nodes":[],"statements":[{"expression":{"id":639,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5459:9:0","subExpression":{"id":638,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5459:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":640,"nodeType":"ExpressionStatement","src":"5459:9:0"},{"expression":{"arguments":[{"id":644,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":635,"src":"5490:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":641,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5478:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":643,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5478:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":645,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5478:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":646,"nodeType":"ExpressionStatement","src":"5478:15:0"}]},"functionSelector":"7e79255d","implemented":true,"kind":"function","modifiers":[],"name":"call1","nameLocation":"5414:5:0","parameters":{"id":636,"nodeType":"ParameterList","parameters":[{"constant":false,"id":635,"mutability":"mutable","name":"_v","nameLocation":"5436:2:0","nodeType":"VariableDeclaration","scope":648,"src":"5420:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":634,"name":"string","nodeType":"ElementaryTypeName","src":"5420:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5419:20:0"},"returnParameters":{"id":637,"nodeType":"ParameterList","parameters":[],"src":"5449:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":663,"nodeType":"FunctionDefinition","src":"5506:95:0","nodes":[],"body":{"id":662,"nodeType":"Block","src":"5550:51:0","nodes":[],"statements":[{"expression":{"id":654,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5560:9:0","subExpression":{"id":653,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5560:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":655,"nodeType":"ExpressionStatement","src":"5560:9:0"},{"expression":{"arguments":[{"id":659,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":650,"src":"5591:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":656,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5579:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":658,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5579:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":660,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5579:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":661,"nodeType":"ExpressionStatement","src":"5579:15:0"}]},"functionSelector":"8d3ef7ca","implemented":true,"kind":"function","modifiers":[],"name":"call2","nameLocation":"5515:5:0","parameters":{"id":651,"nodeType":"ParameterList","parameters":[{"constant":false,"id":650,"mutability":"mutable","name":"_v","nameLocation":"5537:2:0","nodeType":"VariableDeclaration","scope":663,"src":"5521:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":649,"name":"string","nodeType":"ElementaryTypeName","src":"5521:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5520:20:0"},"returnParameters":{"id":652,"nodeType":"ParameterList","parameters":[],"src":"5550:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":678,"nodeType":"FunctionDefinition","src":"5607:98:0","nodes":[],"body":{"id":677,"nodeType":"Block","src":"5653:52:0","nodes":[],"statements":[{"expression":{"id":669,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5663:9:0","subExpression":{"id":668,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5663:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":670,"nodeType":"ExpressionStatement","src":"5663:9:0"},{"expression":{"arguments":[{"id":674,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":665,"src":"5695:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":671,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"5682:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":673,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested2","nodeType":"MemberAccess","referencedDeclaration":693,"src":"5682:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":675,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5682:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":676,"nodeType":"ExpressionStatement","src":"5682:16:0"}]},"functionSelector":"a76ccdfa","implemented":true,"kind":"function","modifiers":[],"name":"nested1","nameLocation":"5616:7:0","parameters":{"id":666,"nodeType":"ParameterList","parameters":[{"constant":false,"id":665,"mutability":"mutable","name":"_v","nameLocation":"5640:2:0","nodeType":"VariableDeclaration","scope":678,"src":"5624:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":664,"name":"string","nodeType":"ElementaryTypeName","src":"5624:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5623:20:0"},"returnParameters":{"id":667,"nodeType":"ParameterList","parameters":[],"src":"5653:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":693,"nodeType":"FunctionDefinition","src":"5711:97:0","nodes":[],"body":{"id":692,"nodeType":"Block","src":"5757:51:0","nodes":[],"statements":[{"expression":{"id":684,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5767:9:0","subExpression":{"id":683,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5767:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":685,"nodeType":"ExpressionStatement","src":"5767:9:0"},{"expression":{"arguments":[{"id":689,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":680,"src":"5798:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":686,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5786:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":688,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5786:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":690,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5786:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":691,"nodeType":"ExpressionStatement","src":"5786:15:0"}]},"functionSelector":"dbf1282f","implemented":true,"kind":"function","modifiers":[],"name":"nested2","nameLocation":"5720:7:0","parameters":{"id":681,"nodeType":"ParameterList","parameters":[{"constant":false,"id":680,"mutability":"mutable","name":"_v","nameLocation":"5744:2:0","nodeType":"VariableDeclaration","scope":693,"src":"5728:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":679,"name":"string","nodeType":"ElementaryTypeName","src":"5728:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5727:20:0"},"returnParameters":{"id":682,"nodeType":"ParameterList","parameters":[],"src":"5757:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":705,"nodeType":"FunctionDefinition","src":"5814:84:0","nodes":[],"body":{"id":704,"nodeType":"Block","src":"5866:32:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":701,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":695,"src":"5888:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":698,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5876:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":700,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5876:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":702,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5876:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":703,"nodeType":"ExpressionStatement","src":"5876:15:0"}]},"functionSelector":"7f8b915c","implemented":true,"kind":"function","modifiers":[],"name":"callPure","nameLocation":"5823:8:0","parameters":{"id":696,"nodeType":"ParameterList","parameters":[{"constant":false,"id":695,"mutability":"mutable","name":"_v","nameLocation":"5848:2:0","nodeType":"VariableDeclaration","scope":705,"src":"5832:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":694,"name":"string","nodeType":"ElementaryTypeName","src":"5832:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5831:20:0"},"returnParameters":{"id":697,"nodeType":"ParameterList","parameters":[],"src":"5866:0:0"},"scope":706,"stateMutability":"pure","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[719],"contractKind":"contract","documentation":{"id":193,"nodeType":"StructuredDocumentation","src":"2415:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[706],"name":"ScriptExample","nameLocation":"2550:13:0","scope":720,"usedErrors":[]},{"id":719,"nodeType":"ContractDefinition","src":"5902:96:0","nodes":[{"id":708,"nodeType":"VariableDeclaration","src":"5924:18:0","nodes":[],"constant":false,"functionSelector":"c2985578","mutability":"mutable","name":"foo","nameLocation":"5939:3:0","scope":719,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":707,"name":"uint256","nodeType":"ElementaryTypeName","src":"5924:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":718,"nodeType":"FunctionDefinition","src":"5949:47:0","nodes":[],"body":{"id":717,"nodeType":"Block","src":"5972:24:0","nodes":[],"statements":[{"expression":{"id":715,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":713,"name":"foo","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":708,"src":"5982:3:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":714,"name":"v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":710,"src":"5988:1:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5982:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":716,"nodeType":"ExpressionStatement","src":"5982:7:0"}]},"implemented":true,"kind":"constructor","modifiers":[],"name":"","nameLocation":"-1:-1:-1","parameters":{"id":711,"nodeType":"ParameterList","parameters":[{"constant":false,"id":710,"mutability":"mutable","name":"v","nameLocation":"5969:1:0","nodeType":"VariableDeclaration","scope":718,"src":"5961:9:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":709,"name":"uint256","nodeType":"ElementaryTypeName","src":"5961:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"5960:11:0"},"returnParameters":{"id":712,"nodeType":"ParameterList","parameters":[],"src":"5972:0:0"},"scope":719,"stateMutability":"nonpayable","virtual":false,"visibility":"public"}],"abstract":false,"baseContracts":[],"canonicalName":"FooBar","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[719],"name":"FooBar","nameLocation":"5911:6:0","scope":720,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file diff --git a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/ScriptExample.json b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/ScriptExample.json index 474fa84e4127..09a0bf47f02d 100644 --- a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/ScriptExample.json +++ b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/ScriptExample.json @@ -1 +1 @@ -{"abi":[{"type":"function","name":"call1","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"call2","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"callPure","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"pure"},{"type":"function","name":"counter","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"hello","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"view"},{"type":"function","name":"nested1","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"nested2","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"run","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"runBroadcast","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"bytecode":{"object":"0x608060405234801561001057600080fd5b50611e66806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063a76ccdfa11610076578063bef03abc1161005b578063bef03abc14610111578063c040622614610119578063dbf1282f146100c357600080fd5b8063a76ccdfa146100eb578063a777d0dc146100fe57600080fd5b806361bc221a146100a85780637e79255d146100c35780637f8b915c146100d85780638d3ef7ca146100c3575b600080fd5b6100b160005481565b60405190815260200160405180910390f35b6100d66100d136600461189c565b610121565b005b6100d66100e636600461189c565b610178565b6100d66100f936600461189c565b6101b7565b6100d661010c36600461189c565b61023f565b6100d66102bd565b6100d6610d44565b6000805490806101308361190e565b919050555061017482828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061159792505050565b5050565b61017482828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061159792505050565b6000805490806101c68361190e565b90915550506040517fdbf1282f000000000000000000000000000000000000000000000000000000008152309063dbf1282f90610209908590859060040161196d565b600060405180830381600087803b15801561022357600080fd5b505af1158015610237573d6000803e3d6000fd5b505050505050565b61027e82828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061159792505050565b6101746040518060400160405280601081526020017f68656c6c6f206d73672e73656e6465720000000000000000000000000000000081525033611629565b6102fb6040518060400160405280600e81526020017f74657374696e672073696e676c65000000000000000000000000000000000000815250611597565b7f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff1663afc980406040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561036657600080fd5b505af115801561037a573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f73696e676c655f63616c6c3100000000000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b1580156103fd57600080fd5b505af1158015610411573d6000803e3d6000fd5b50506040517f8d3ef7ca00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f73696e676c655f63616c6c3200000000000000000000000000000000000000006044820152309250638d3ef7ca9150606401600060405180830381600087803b15801561049457600080fd5b505af11580156104a8573d6000803e3d6000fd5b505050506104ea6040518060400160405280601281526020017f74657374696e672073746172742f73746f700000000000000000000000000000815250611597565b6040517f7fec2a8d00000000000000000000000000000000000000000000000000000000815262c0ffee6004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d90637fec2a8d90602401600060405180830381600087803b15801561055257600080fd5b505af1158015610566573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3100000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b1580156105e957600080fd5b505af11580156105fd573d6000803e3d6000fd5b50506040517f8d3ef7ca00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3200000000000000000000000000000000006044820152309250638d3ef7ca9150606401600060405180830381600087803b15801561068057600080fd5b505af1158015610694573d6000803e3d6000fd5b50506040517f7f8b915c00000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f737461727473746f705f707572650000000000000000000000000000000000006044820152309250637f8b915c915060640160006040518083038186803b15801561071557600080fd5b505afa158015610729573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166376eadd366040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561079857600080fd5b505af11580156107ac573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3300000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b15801561082f57600080fd5b505af1158015610843573d6000803e3d6000fd5b505050506108856040518060400160405280600e81526020017f74657374696e67206e6573746564000000000000000000000000000000000000815250611597565b6040517f7fec2a8d0000000000000000000000000000000000000000000000000000000081526112346004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d90637fec2a8d90602401600060405180830381600087803b1580156108ec57600080fd5b505af1158015610900573d6000803e3d6000fd5b50506040517fa76ccdfa00000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f6e65737465640000000000000000000000000000000000000000000000000000604482015230925063a76ccdfa9150606401600060405180830381600087803b15801561098357600080fd5b505af1158015610997573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166376eadd366040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610a0657600080fd5b505af1158015610a1a573d6000803e3d6000fd5b50505050610a5c6040518060400160405280601381526020017f636f6e7472616374206465706c6f796d656e7400000000000000000000000000815250611597565b6040517fe6962cdb000000000000000000000000000000000000000000000000000000008152621234566004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d9063e6962cdb90602401600060405180830381600087803b158015610ac457600080fd5b505af1158015610ad8573d6000803e3d6000fd5b5050505060006104d2604051610aed90611890565b908152602001604051809103906000f080158015610b0f573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff1663c29855786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8191906119ba565b6104d214610b8e57600080fd5b610bcc6040518060400160405280600881526020017f6372656174652032000000000000000000000000000000000000000000000000815250611597565b6040517fe6962cdb00000000000000000000000000000000000000000000000000000000815261cafe6004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d9063e6962cdb90602401600060405180830381600087803b158015610c3357600080fd5b505af1158015610c47573d6000803e3d6000fd5b505050506000602a60001b6104d2604051610c6190611890565b9081526020018190604051809103906000f5905080158015610c87573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff1663c29855786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf991906119ba565b6104d214610d0657600080fd5b6101746040518060400160405280600581526020017f646f6e6521000000000000000000000000000000000000000000000000000000815250611597565b604080517f4777f3cf0000000000000000000000000000000000000000000000000000000081526004810191909152600c60448201527f4558414d504c455f424f4f4c0000000000000000000000000000000000000000606482015260006024820181905290737109709ecfa91a80626ff3989d68f67f5b1dd12d90634777f3cf90608401602060405180830381865afa158015610de6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0a91906119d3565b9050610e4b6040518060400160405280601381526020017f626f6f6c2076616c75652066726f6d20656e7600000000000000000000000000815250826116ba565b610e8a6040518060400160405280600d81526020017f636f6e747261637420616464720000000000000000000000000000000000000081525030611629565b604080518082018252600e81527f636f6e7472616374206e6f6e6365000000000000000000000000000000000000602082015290517f2d0335ab000000000000000000000000000000000000000000000000000000008152306004820152610f5d9190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab906024015b602060405180830381865afa158015610f2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4e91906119fc565b67ffffffffffffffff1661174b565b610f9c6040518060400160405280600b81526020017f73656e646572206164647200000000000000000000000000000000000000000081525033611629565b604080518082018252600c81527f73656e646572206e6f6e63650000000000000000000000000000000000000000602082015290517f2d0335ab0000000000000000000000000000000000000000000000000000000081523360048201526110239190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab90602401610f0d565b60408051808201825260208082527f7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d9082015290517f213e4198000000000000000000000000000000000000000000000000000000008152600090737109709ecfa91a80626ff3989d68f67f5b1dd12d9063213e4198906110a8908590600401611aa0565b600060405180830381865afa1580156110c5573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261110b9190810190611b70565b90506111816040518060400160405280600481526020017f6b657973000000000000000000000000000000000000000000000000000000008152508260008151811061115957611159611ca4565b60200260200101518360018151811061117457611174611ca4565b60200260200101516117dc565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f66726f6d206f726967696e616c000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b1580156111fe57600080fd5b505afa158015611212573d6000803e3d6000fd5b50506040517f06447d5600000000000000000000000000000000000000000000000000000000815260426004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d92506306447d569150602401600060405180830381600087803b15801561127c57600080fd5b505af1158015611290573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b20310000000000000000000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b15801561131157600080fd5b505afa158015611325573d6000803e3d6000fd5b505050506113686040518060400160405280601781526020017f706172656e742073636f7065206d73672e73656e64657200000000000000000081525033611629565b6113a76040518060400160405280601a81526020017f706172656e742073636f706520636f6e74726163742e6164647200000000000081525030611629565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b203200000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b15801561142457600080fd5b505afa158015611438573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166390c5013b6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156114a757600080fd5b505af11580156114bb573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f66726f6d206f726967696e616c20616761696e00000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b15801561153c57600080fd5b505afa158015611550573d6000803e3d6000fd5b505050506115926040518060400160405280600581526020017f646f6e6521000000000000000000000000000000000000000000000000000000815250611597565b505050565b611626816040516024016115ab9190611cd3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f41304fac0000000000000000000000000000000000000000000000000000000017905261186b565b50565b610174828260405160240161163f929190611ce6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f319af3330000000000000000000000000000000000000000000000000000000017905261186b565b61017482826040516024016116d0929190611d1e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fc3b556350000000000000000000000000000000000000000000000000000000017905261186b565b6101748282604051602401611761929190611d42565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb60e72cc0000000000000000000000000000000000000000000000000000000017905261186b565b6115928383836040516024016117f493929190611d64565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f2ced7cef000000000000000000000000000000000000000000000000000000001790525b6116268180516a636f6e736f6c652e6c6f67602083016000808483855afa5050505050565b60b280611da883390190565b600080602083850312156118af57600080fd5b823567ffffffffffffffff808211156118c757600080fd5b818501915085601f8301126118db57600080fd5b8135818111156118ea57600080fd5b8660208285010111156118fc57600080fd5b60209290920196919550909350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611966577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000602082840312156119cc57600080fd5b5051919050565b6000602082840312156119e557600080fd5b815180151581146119f557600080fd5b9392505050565b600060208284031215611a0e57600080fd5b815167ffffffffffffffff811681146119f557600080fd5b60005b83811015611a41578181015183820152602001611a29565b83811115611a50576000848401525b50505050565b60008151808452611a6e816020860160208601611a26565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b604081526000611ab36040830184611a56565b8281036020840152600c81527f2e726f6f745f6b65795b305d000000000000000000000000000000000000000060208201526040810191505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611b6857611b68611af2565b604052919050565b60006020808385031215611b8357600080fd5b825167ffffffffffffffff80821115611b9b57600080fd5b8185019150601f8681840112611bb057600080fd5b825182811115611bc257611bc2611af2565b8060051b611bd1868201611b21565b918252848101860191868101908a841115611beb57600080fd5b87870192505b83831015611c9657825186811115611c095760008081fd5b8701603f81018c13611c1b5760008081fd5b88810151604088821115611c3157611c31611af2565b611c608b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08a85011601611b21565b8281528e82848601011115611c755760008081fd5b611c84838d8301848701611a26565b85525050509187019190870190611bf1565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020815260006119f56020830184611a56565b604081526000611cf96040830185611a56565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b604081526000611d316040830185611a56565b905082151560208301529392505050565b604081526000611d556040830185611a56565b90508260208301529392505050565b606081526000611d776060830186611a56565b8281036020840152611d898186611a56565b90508281036040840152611d9d8185611a56565b969550505050505056fe608060405234801561001057600080fd5b506040516100b23803806100b283398101604081905261002f91610037565b600055610050565b60006020828403121561004957600080fd5b5051919050565b60548061005e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b603560005481565b60405190815260200160405180910390f3fea164736f6c634300080f000aa164736f6c634300080f000a","sourceMap":"2541:3089:0:-:0;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405234801561001057600080fd5b50600436106100a35760003560e01c8063a76ccdfa11610076578063bef03abc1161005b578063bef03abc14610111578063c040622614610119578063dbf1282f146100c357600080fd5b8063a76ccdfa146100eb578063a777d0dc146100fe57600080fd5b806361bc221a146100a85780637e79255d146100c35780637f8b915c146100d85780638d3ef7ca146100c3575b600080fd5b6100b160005481565b60405190815260200160405180910390f35b6100d66100d136600461189c565b610121565b005b6100d66100e636600461189c565b610178565b6100d66100f936600461189c565b6101b7565b6100d661010c36600461189c565b61023f565b6100d66102bd565b6100d6610d44565b6000805490806101308361190e565b919050555061017482828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061159792505050565b5050565b61017482828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061159792505050565b6000805490806101c68361190e565b90915550506040517fdbf1282f000000000000000000000000000000000000000000000000000000008152309063dbf1282f90610209908590859060040161196d565b600060405180830381600087803b15801561022357600080fd5b505af1158015610237573d6000803e3d6000fd5b505050505050565b61027e82828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061159792505050565b6101746040518060400160405280601081526020017f68656c6c6f206d73672e73656e6465720000000000000000000000000000000081525033611629565b6102fb6040518060400160405280600e81526020017f74657374696e672073696e676c65000000000000000000000000000000000000815250611597565b7f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff1663afc980406040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561036657600080fd5b505af115801561037a573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f73696e676c655f63616c6c3100000000000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b1580156103fd57600080fd5b505af1158015610411573d6000803e3d6000fd5b50506040517f8d3ef7ca00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f73696e676c655f63616c6c3200000000000000000000000000000000000000006044820152309250638d3ef7ca9150606401600060405180830381600087803b15801561049457600080fd5b505af11580156104a8573d6000803e3d6000fd5b505050506104ea6040518060400160405280601281526020017f74657374696e672073746172742f73746f700000000000000000000000000000815250611597565b6040517f7fec2a8d00000000000000000000000000000000000000000000000000000000815262c0ffee6004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d90637fec2a8d90602401600060405180830381600087803b15801561055257600080fd5b505af1158015610566573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3100000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b1580156105e957600080fd5b505af11580156105fd573d6000803e3d6000fd5b50506040517f8d3ef7ca00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3200000000000000000000000000000000006044820152309250638d3ef7ca9150606401600060405180830381600087803b15801561068057600080fd5b505af1158015610694573d6000803e3d6000fd5b50506040517f7f8b915c00000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f737461727473746f705f707572650000000000000000000000000000000000006044820152309250637f8b915c915060640160006040518083038186803b15801561071557600080fd5b505afa158015610729573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166376eadd366040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561079857600080fd5b505af11580156107ac573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3300000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b15801561082f57600080fd5b505af1158015610843573d6000803e3d6000fd5b505050506108856040518060400160405280600e81526020017f74657374696e67206e6573746564000000000000000000000000000000000000815250611597565b6040517f7fec2a8d0000000000000000000000000000000000000000000000000000000081526112346004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d90637fec2a8d90602401600060405180830381600087803b1580156108ec57600080fd5b505af1158015610900573d6000803e3d6000fd5b50506040517fa76ccdfa00000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f6e65737465640000000000000000000000000000000000000000000000000000604482015230925063a76ccdfa9150606401600060405180830381600087803b15801561098357600080fd5b505af1158015610997573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166376eadd366040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610a0657600080fd5b505af1158015610a1a573d6000803e3d6000fd5b50505050610a5c6040518060400160405280601381526020017f636f6e7472616374206465706c6f796d656e7400000000000000000000000000815250611597565b6040517fe6962cdb000000000000000000000000000000000000000000000000000000008152621234566004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d9063e6962cdb90602401600060405180830381600087803b158015610ac457600080fd5b505af1158015610ad8573d6000803e3d6000fd5b5050505060006104d2604051610aed90611890565b908152602001604051809103906000f080158015610b0f573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff1663c29855786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8191906119ba565b6104d214610b8e57600080fd5b610bcc6040518060400160405280600881526020017f6372656174652032000000000000000000000000000000000000000000000000815250611597565b6040517fe6962cdb00000000000000000000000000000000000000000000000000000000815261cafe6004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d9063e6962cdb90602401600060405180830381600087803b158015610c3357600080fd5b505af1158015610c47573d6000803e3d6000fd5b505050506000602a60001b6104d2604051610c6190611890565b9081526020018190604051809103906000f5905080158015610c87573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff1663c29855786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf991906119ba565b6104d214610d0657600080fd5b6101746040518060400160405280600581526020017f646f6e6521000000000000000000000000000000000000000000000000000000815250611597565b604080517f4777f3cf0000000000000000000000000000000000000000000000000000000081526004810191909152600c60448201527f4558414d504c455f424f4f4c0000000000000000000000000000000000000000606482015260006024820181905290737109709ecfa91a80626ff3989d68f67f5b1dd12d90634777f3cf90608401602060405180830381865afa158015610de6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0a91906119d3565b9050610e4b6040518060400160405280601381526020017f626f6f6c2076616c75652066726f6d20656e7600000000000000000000000000815250826116ba565b610e8a6040518060400160405280600d81526020017f636f6e747261637420616464720000000000000000000000000000000000000081525030611629565b604080518082018252600e81527f636f6e7472616374206e6f6e6365000000000000000000000000000000000000602082015290517f2d0335ab000000000000000000000000000000000000000000000000000000008152306004820152610f5d9190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab906024015b602060405180830381865afa158015610f2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4e91906119fc565b67ffffffffffffffff1661174b565b610f9c6040518060400160405280600b81526020017f73656e646572206164647200000000000000000000000000000000000000000081525033611629565b604080518082018252600c81527f73656e646572206e6f6e63650000000000000000000000000000000000000000602082015290517f2d0335ab0000000000000000000000000000000000000000000000000000000081523360048201526110239190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab90602401610f0d565b60408051808201825260208082527f7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d9082015290517f213e4198000000000000000000000000000000000000000000000000000000008152600090737109709ecfa91a80626ff3989d68f67f5b1dd12d9063213e4198906110a8908590600401611aa0565b600060405180830381865afa1580156110c5573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261110b9190810190611b70565b90506111816040518060400160405280600481526020017f6b657973000000000000000000000000000000000000000000000000000000008152508260008151811061115957611159611ca4565b60200260200101518360018151811061117457611174611ca4565b60200260200101516117dc565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f66726f6d206f726967696e616c000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b1580156111fe57600080fd5b505afa158015611212573d6000803e3d6000fd5b50506040517f06447d5600000000000000000000000000000000000000000000000000000000815260426004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d92506306447d569150602401600060405180830381600087803b15801561127c57600080fd5b505af1158015611290573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b20310000000000000000000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b15801561131157600080fd5b505afa158015611325573d6000803e3d6000fd5b505050506113686040518060400160405280601781526020017f706172656e742073636f7065206d73672e73656e64657200000000000000000081525033611629565b6113a76040518060400160405280601a81526020017f706172656e742073636f706520636f6e74726163742e6164647200000000000081525030611629565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b203200000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b15801561142457600080fd5b505afa158015611438573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166390c5013b6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156114a757600080fd5b505af11580156114bb573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f66726f6d206f726967696e616c20616761696e00000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b15801561153c57600080fd5b505afa158015611550573d6000803e3d6000fd5b505050506115926040518060400160405280600581526020017f646f6e6521000000000000000000000000000000000000000000000000000000815250611597565b505050565b611626816040516024016115ab9190611cd3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f41304fac0000000000000000000000000000000000000000000000000000000017905261186b565b50565b610174828260405160240161163f929190611ce6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f319af3330000000000000000000000000000000000000000000000000000000017905261186b565b61017482826040516024016116d0929190611d1e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fc3b556350000000000000000000000000000000000000000000000000000000017905261186b565b6101748282604051602401611761929190611d42565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb60e72cc0000000000000000000000000000000000000000000000000000000017905261186b565b6115928383836040516024016117f493929190611d64565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f2ced7cef000000000000000000000000000000000000000000000000000000001790525b6116268180516a636f6e736f6c652e6c6f67602083016000808483855afa5050505050565b60b280611da883390190565b600080602083850312156118af57600080fd5b823567ffffffffffffffff808211156118c757600080fd5b818501915085601f8301126118db57600080fd5b8135818111156118ea57600080fd5b8660208285010111156118fc57600080fd5b60209290920196919550909350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611966577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000602082840312156119cc57600080fd5b5051919050565b6000602082840312156119e557600080fd5b815180151581146119f557600080fd5b9392505050565b600060208284031215611a0e57600080fd5b815167ffffffffffffffff811681146119f557600080fd5b60005b83811015611a41578181015183820152602001611a29565b83811115611a50576000848401525b50505050565b60008151808452611a6e816020860160208601611a26565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b604081526000611ab36040830184611a56565b8281036020840152600c81527f2e726f6f745f6b65795b305d000000000000000000000000000000000000000060208201526040810191505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611b6857611b68611af2565b604052919050565b60006020808385031215611b8357600080fd5b825167ffffffffffffffff80821115611b9b57600080fd5b8185019150601f8681840112611bb057600080fd5b825182811115611bc257611bc2611af2565b8060051b611bd1868201611b21565b918252848101860191868101908a841115611beb57600080fd5b87870192505b83831015611c9657825186811115611c095760008081fd5b8701603f81018c13611c1b5760008081fd5b88810151604088821115611c3157611c31611af2565b611c608b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08a85011601611b21565b8281528e82848601011115611c755760008081fd5b611c84838d8301848701611a26565b85525050509187019190870190611bf1565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020815260006119f56020830184611a56565b604081526000611cf96040830185611a56565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b604081526000611d316040830185611a56565b905082151560208301529392505050565b604081526000611d556040830185611a56565b90508260208301529392505050565b606081526000611d776060830186611a56565b8281036020840152611d898186611a56565b90508281036040840152611d9d8185611a56565b969550505050505056fe608060405234801561001057600080fd5b506040516100b23803806100b283398101604081905261002f91610037565b600055610050565b60006020828403121561004957600080fd5b5051919050565b60548061005e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b603560005481565b60405190815260200160405180910390f3fea164736f6c634300080f000aa164736f6c634300080f000a","sourceMap":"2541:3089:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2775:22;;;;;;;;;160:25:1;;;148:2;133:18;2775:22:0;;;;;;;5135:95;;;;;;:::i;:::-;;:::i;:::-;;5544:84;;;;;;:::i;:::-;;:::i;5337:98::-;;;;;;:::i;:::-;;:::i;4986:143::-;;;;;;:::i;:::-;;:::i;3903:988::-;;;:::i;2887:949::-;;;:::i;5135:95::-;5189:7;:9;;;:7;:9;;;:::i;:::-;;;;;;5208:15;5220:2;;5208:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5208:11:0;;-1:-1:-1;;;5208:15:0:i;:::-;5135:95;;:::o;5544:84::-;5606:15;5618:2;;5606:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5606:11:0;;-1:-1:-1;;;5606:15:0:i;5337:98::-;5393:7;:9;;;:7;:9;;;:::i;:::-;;;;-1:-1:-1;;5412:16:0;;;;;:4;;:12;;:16;;5425:2;;;;5412:16;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5337:98;;:::o;4986:143::-;5045:15;5057:2;;5045:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5045:11:0;;-1:-1:-1;;;5045:15:0:i;:::-;5070:52;;;;;;;;;;;;;;;;;;5110:10;5070:11;:52::i;3903:988::-;3944:29;;;;;;;;;;;;;;;;;;:11;:29::i;:::-;2634:28;2626:37;;3983:12;;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4007:26:0;;;;;1803:2:1;4007:26:0;;;1785:21:1;1842:2;1822:18;;;1815:30;1881:14;1861:18;;;1854:42;4007:4:0;;-1:-1:-1;4007:10:0;;-1:-1:-1;1913:18:1;;4007:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4043:26:0;;;;;2144:2:1;4043:26:0;;;2126:21:1;2183:2;2163:18;;;2156:30;2222:14;2202:18;;;2195:42;4043:4:0;;-1:-1:-1;4043:10:0;;-1:-1:-1;2254:18:1;;4043:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4080:33;;;;;;;;;;;;;;;;;;:11;:33::i;:::-;4123:45;;;;;4157:8;4123:45;;;2429:74:1;4123:17:0;;;;2402:18:1;;4123:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4178:29:0;;;;;2716:2:1;4178:29:0;;;2698:21:1;2755:2;2735:18;;;2728:30;2794:17;2774:18;;;2767:45;4178:4:0;;-1:-1:-1;4178:10:0;;-1:-1:-1;2829:18:1;;4178:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4217:29:0;;;;;3060:2:1;4217:29:0;;;3042:21:1;3099:2;3079:18;;;3072:30;3138:17;3118:18;;;3111:45;4217:4:0;;-1:-1:-1;4217:10:0;;-1:-1:-1;3173:18:1;;4217:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4256:31:0;;;;;3404:2:1;4256:31:0;;;3386:21:1;3443:2;3423:18;;;3416:30;3482:16;3462:18;;;3455:44;4256:4:0;;-1:-1:-1;4256:13:0;;-1:-1:-1;3516:18:1;;4256:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2634:28;2626:37;;4297:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4325:29:0;;;;;3747:2:1;4325:29:0;;;3729:21:1;3786:2;3766:18;;;3759:30;3825:17;3805:18;;;3798:45;4325:4:0;;-1:-1:-1;4325:10:0;;-1:-1:-1;3860:18:1;;4325:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4365;;;;;;;;;;;;;;;;;;:11;:29::i;:::-;4404:43;;;;;4438:6;4404:43;;;2429:74:1;4404:17:0;;;;2402:18:1;;4404:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4457:22:0;;;;;4091:2:1;4457:22:0;;;4073:21:1;4130:1;4110:18;;;4103:29;4168:8;4148:18;;;4141:36;4457:4:0;;-1:-1:-1;4457:12:0;;-1:-1:-1;4194:18:1;;4457:22:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2634:28;2626:37;;4489:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4518:34;;;;;;;;;;;;;;;;;;:11;:34::i;:::-;4562:40;;;;;4591:8;4562:40;;;2429:74:1;4562:12:0;;;;2402:18:1;;4562:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4612:8;4634:4;4623:16;;;;;:::i;:::-;160:25:1;;;148:2;133:18;4623:16:0;;;;;;;;;;;;;;;;;;;;;;;4612:27;;4657:1;:5;;;:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4668:4;4657:15;4649:24;;;;;;4684:23;;;;;;;;;;;;;;;;;;:11;:23::i;:::-;4717:38;;;;;4746:6;4717:38;;;2429:74:1;4717:12:0;;;;2402:18:1;;4717:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4765:8;4809:2;4793:20;;4815:4;4776:44;;;;;:::i;:::-;160:25:1;;;148:2;133:18;4776:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;4765:55;;4838:1;:5;;;:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4849:4;4838:15;4830:24;;;;;;4864:20;;;;;;;;;;;;;;;;;;:11;:20::i;2887:949::-;2928:31;;;;;;;;;4811:21:1;;;;4868:2;4848:18;;;4841:30;4907:14;4887:18;;;4880:42;2919:6:0;4974:20:1;;;4967:52;;;2919:6:0;2928:8;;;;4939:19:1;;2928:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2919:40;;2969:37;;;;;;;;;;;;;;;;;;3004:1;2969:11;:37::i;:::-;3017:43;;;;;;;;;;;;;;;;;;3054:4;3017:11;:43::i;:::-;3070:57;;;;;;;;;;;;;;;;3100:26;;;;;3120:4;3100:26;;;2429:74:1;3070:57:0;;;3100:11;;;;2402:18:1;;3100:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3070:57;;:11;:57::i;:::-;3137:47;;;;;;;;;;;;;;;;;;3172:10;3137:11;:47::i;:::-;3194:61;;;;;;;;;;;;;;;;3222:32;;;;;3242:10;3222:32;;;2429:74:1;3194:61:0;;;3222:11;;;;2402:18:1;;3222:32:0;2283:226:1;3194:61:0;3266:55;;;;;;;;;;;;;;;;;3354:38;;;;;3266:18;;3354:16;;;;:38;;3266:55;;3354:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3331:61;;3402:37;;;;;;;;;;;;;;;;;;3422:4;3427:1;3422:7;;;;;;;;:::i;:::-;;;;;;;3431:4;3436:1;3431:7;;;;;;;;:::i;:::-;;;;;;;3402:11;:37::i;:::-;3450:27;;;;;9413:2:1;3450:27:0;;;9395:21:1;9452:2;9432:18;;;9425:30;9491:15;9471:18;;;9464:43;3450:4:0;;:10;;9524:18:1;;3450:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3487:37:0;;;;;3517:4;3487:37;;;2429:74:1;3487:13:0;;-1:-1:-1;3487:13:0;;-1:-1:-1;2402:18:1;;3487:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3534:26:0;;;;;9755:2:1;3534:26:0;;;9737:21:1;9794:2;9774:18;;;9767:30;9833:14;9813:18;;;9806:42;3534:4:0;;-1:-1:-1;3534:10:0;;-1:-1:-1;9865:18:1;;3534:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3570:59;;;;;;;;;;;;;;;;;;3617:10;3570:11;:59::i;:::-;3639:56;;;;;;;;;;;;;;;;;;3689:4;3639:11;:56::i;:::-;3705:26;;;;;10096:2:1;3705:26:0;;;10078:21:1;10135:2;10115:18;;;10108:30;10174:14;10154:18;;;10147:42;3705:4:0;;:10;;10206:18:1;;3705:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2634:28;2626:37;;3741:12;;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3765:33:0;;;;;10437:2:1;3765:33:0;;;10419:21:1;10476:2;10456:18;;;10449:30;10515:21;10495:18;;;10488:49;3765:4:0;;-1:-1:-1;3765:10:0;;-1:-1:-1;10554:18:1;;3765:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3809:20;;;;;;;;;;;;;;;;;;:11;:20::i;:::-;2909:927;;;2887:949::o;1658:121::-;1713:59;1768:2;1729:42;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1713:15;:59::i;:::-;1658:121;:::o;2081:145::-;2148:71;2211:2;2215;2164:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;2148:15;:71::i;1785:139::-;1849:68;1909:2;1913;1865:51;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1849:15;:68::i;1930:145::-;1997:71;2060:2;2064;2013:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1997:15;:71::i;2232:179::-;2323:81;2392:2;2396;2400;2339:64;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1133:133;1204:55;1251:7;1370:14;;856:42;1543:2;1530:16;;1346:21;;1370:14;1530:16;856:42;1579:5;1568:68;1559:77;;1496:150;;1272:380;:::o;-1:-1:-1:-;;;;;;;;:::o;196:592:1:-;267:6;275;328:2;316:9;307:7;303:23;299:32;296:52;;;344:1;341;334:12;296:52;384:9;371:23;413:18;454:2;446:6;443:14;440:34;;;470:1;467;460:12;440:34;508:6;497:9;493:22;483:32;;553:7;546:4;542:2;538:13;534:27;524:55;;575:1;572;565:12;524:55;615:2;602:16;641:2;633:6;630:14;627:34;;;657:1;654;647:12;627:34;702:7;697:2;688:6;684:2;680:15;676:24;673:37;670:57;;;723:1;720;713:12;670:57;754:2;746:11;;;;;776:6;;-1:-1:-1;196:592:1;;-1:-1:-1;;;;196:592:1:o;793:349::-;832:3;863:66;856:5;853:77;850:257;;963:77;960:1;953:88;1064:4;1061:1;1054:15;1092:4;1089:1;1082:15;850:257;-1:-1:-1;1134:1:1;1123:13;;793:349::o;1147:449::-;1306:2;1295:9;1288:21;1345:6;1340:2;1329:9;1325:18;1318:34;1402:6;1394;1389:2;1378:9;1374:18;1361:48;1458:1;1429:22;;;1453:2;1425:31;;;1418:42;;;;1512:2;1500:15;;;1517:66;1496:88;1481:104;1477:113;;1147:449;-1:-1:-1;1147:449:1:o;4416:184::-;4486:6;4539:2;4527:9;4518:7;4514:23;4510:32;4507:52;;;4555:1;4552;4545:12;4507:52;-1:-1:-1;4578:16:1;;4416:184;-1:-1:-1;4416:184:1:o;5030:277::-;5097:6;5150:2;5138:9;5129:7;5125:23;5121:32;5118:52;;;5166:1;5163;5156:12;5118:52;5198:9;5192:16;5251:5;5244:13;5237:21;5230:5;5227:32;5217:60;;5273:1;5270;5263:12;5217:60;5296:5;5030:277;-1:-1:-1;;;5030:277:1:o;5312:288::-;5381:6;5434:2;5422:9;5413:7;5409:23;5405:32;5402:52;;;5450:1;5447;5440:12;5402:52;5482:9;5476:16;5532:18;5525:5;5521:30;5514:5;5511:41;5501:69;;5566:1;5563;5556:12;5605:258;5677:1;5687:113;5701:6;5698:1;5695:13;5687:113;;;5777:11;;;5771:18;5758:11;;;5751:39;5723:2;5716:10;5687:113;;;5818:6;5815:1;5812:13;5809:48;;;5853:1;5844:6;5839:3;5835:16;5828:27;5809:48;;5605:258;;;:::o;5868:317::-;5910:3;5948:5;5942:12;5975:6;5970:3;5963:19;5991:63;6047:6;6040:4;6035:3;6031:14;6024:4;6017:5;6013:16;5991:63;:::i;:::-;6099:2;6087:15;6104:66;6083:88;6074:98;;;;6174:4;6070:109;;5868:317;-1:-1:-1;;5868:317:1:o;6190:493::-;6440:2;6429:9;6422:21;6403:4;6466:45;6507:2;6496:9;6492:18;6484:6;6466:45;:::i;:::-;6559:9;6551:6;6547:22;6542:2;6531:9;6527:18;6520:50;6594:2;6586:6;6579:18;6630:14;6625:2;6617:6;6613:15;6606:39;6674:2;6666:6;6662:15;6654:23;;;6190:493;;;;:::o;6688:184::-;6740:77;6737:1;6730:88;6837:4;6834:1;6827:15;6861:4;6858:1;6851:15;6877:334;6948:2;6942:9;7004:2;6994:13;;7009:66;6990:86;6978:99;;7107:18;7092:34;;7128:22;;;7089:62;7086:88;;;7154:18;;:::i;:::-;7190:2;7183:22;6877:334;;-1:-1:-1;6877:334:1:o;7216:1801::-;7321:6;7352:2;7395;7383:9;7374:7;7370:23;7366:32;7363:52;;;7411:1;7408;7401:12;7363:52;7444:9;7438:16;7473:18;7514:2;7506:6;7503:14;7500:34;;;7530:1;7527;7520:12;7500:34;7568:6;7557:9;7553:22;7543:32;;7594:4;7634:7;7629:2;7625;7621:11;7617:25;7607:53;;7656:1;7653;7646:12;7607:53;7685:2;7679:9;7707:2;7703;7700:10;7697:36;;;7713:18;;:::i;:::-;7759:2;7756:1;7752:10;7782:28;7806:2;7802;7798:11;7782:28;:::i;:::-;7844:15;;;7914:11;;;7910:20;;;7875:12;;;;7942:19;;;7939:39;;;7974:1;7971;7964:12;7939:39;8006:2;8002;7998:11;7987:22;;8018:969;8034:6;8029:3;8026:15;8018:969;;;8113:3;8107:10;8149:2;8136:11;8133:19;8130:109;;;8193:1;8222:2;8218;8211:14;8130:109;8262:20;;8317:2;8309:11;;8305:25;-1:-1:-1;8295:123:1;;8372:1;8401:2;8397;8390:14;8295:123;8456:2;8452;8448:11;8442:18;8484:2;8510;8505:3;8502:11;8499:37;;;8516:18;;:::i;:::-;8562:111;8669:2;8600:66;8595:2;8590:3;8586:12;8582:85;8578:94;8562:111;:::i;:::-;8700:3;8693:5;8686:18;8747:7;8741:3;8735;8731:2;8727:12;8723:22;8720:35;8717:128;;;8797:1;8827:3;8822;8815:16;8717:128;8858:56;8910:3;8905:2;8898:5;8894:14;8888:3;8884:2;8880:12;8858:56;:::i;:::-;8927:18;;-1:-1:-1;;;8051:12:1;;;;8965;;;;8018:969;;;9006:5;7216:1801;-1:-1:-1;;;;;;;;;;7216:1801:1:o;9022:184::-;9074:77;9071:1;9064:88;9171:4;9168:1;9161:15;9195:4;9192:1;9185:15;10583:220;10732:2;10721:9;10714:21;10695:4;10752:45;10793:2;10782:9;10778:18;10770:6;10752:45;:::i;10808:340::-;10985:2;10974:9;10967:21;10948:4;11005:45;11046:2;11035:9;11031:18;11023:6;11005:45;:::i;:::-;10997:53;;11098:42;11090:6;11086:55;11081:2;11070:9;11066:18;11059:83;10808:340;;;;;:::o;11153:301::-;11324:2;11313:9;11306:21;11287:4;11344:45;11385:2;11374:9;11370:18;11362:6;11344:45;:::i;:::-;11336:53;;11439:6;11432:14;11425:22;11420:2;11409:9;11405:18;11398:50;11153:301;;;;;:::o;11459:291::-;11636:2;11625:9;11618:21;11599:4;11656:45;11697:2;11686:9;11682:18;11674:6;11656:45;:::i;:::-;11648:53;;11737:6;11732:2;11721:9;11717:18;11710:34;11459:291;;;;;:::o;11755:546::-;12000:2;11989:9;11982:21;11963:4;12026:45;12067:2;12056:9;12052:18;12044:6;12026:45;:::i;:::-;12119:9;12111:6;12107:22;12102:2;12091:9;12087:18;12080:50;12153:33;12179:6;12171;12153:33;:::i;:::-;12139:47;;12234:9;12226:6;12222:22;12217:2;12206:9;12202:18;12195:50;12262:33;12288:6;12280;12262:33;:::i;:::-;12254:41;11755:546;-1:-1:-1;;;;;;11755:546:1:o","linkReferences":{}},"methodIdentifiers":{"call1(string)":"7e79255d","call2(string)":"8d3ef7ca","callPure(string)":"7f8b915c","counter()":"61bc221a","hello(string)":"a777d0dc","nested1(string)":"a76ccdfa","nested2(string)":"dbf1282f","run()":"c0406226","runBroadcast()":"bef03abc"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"call1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"call2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"callPure\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"counter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"hello\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"nested1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"nested2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"run\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"runBroadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"title\":\"ScriptExample\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"hello(string)\":{\"notice\":\"example external function, to force a CALL, and test vm.startPrank with.\"},\"run()\":{\"notice\":\"example function, runs through basic cheat-codes and console logs.\"},\"runBroadcast()\":{\"notice\":\"example function, to test vm.broadcast with.\"}},\"notice\":\"ScriptExample is an example script. The Go forge script code tests that it can run this.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"ScriptExample\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x4fc2ffeba31e146fc3a2edef7cc8b7e82fb2344454d32d6371a62c6d76dfcb4e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a517c69eba90ee5f3efb198a2247d5744bed8e17d332ce2dda4d3cf3a2c334f9\",\"dweb:/ipfs/QmciXeDt5EEhmjH5xECVk2VX6EbnER5UFv58dvGgemwkKK\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"call1"},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"call2"},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"pure","type":"function","name":"callPure"},{"inputs":[],"stateMutability":"view","type":"function","name":"counter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"view","type":"function","name":"hello"},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"nested1"},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"nested2"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"run"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"runBroadcast"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{"hello(string)":{"notice":"example external function, to force a CALL, and test vm.startPrank with."},"run()":{"notice":"example function, runs through basic cheat-codes and console logs."},"runBroadcast()":{"notice":"example function, to test vm.broadcast with."}},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"ScriptExample"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x4fc2ffeba31e146fc3a2edef7cc8b7e82fb2344454d32d6371a62c6d76dfcb4e","urls":["bzz-raw://a517c69eba90ee5f3efb198a2247d5744bed8e17d332ce2dda4d3cf3a2c334f9","dweb:/ipfs/QmciXeDt5EEhmjH5xECVk2VX6EbnER5UFv58dvGgemwkKK"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[{"astId":215,"contract":"scripts/ScriptExample.s.sol:ScriptExample","label":"counter","offset":0,"slot":"0","type":"t_uint256"}],"types":{"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"userdoc":{"version":1,"kind":"user","methods":{"hello(string)":{"notice":"example external function, to force a CALL, and test vm.startPrank with."},"run()":{"notice":"example function, runs through basic cheat-codes and console logs."},"runBroadcast()":{"notice":"example function, to test vm.broadcast with."}},"notice":"ScriptExample is an example script. The Go forge script code tests that it can run this."},"devdoc":{"version":1,"kind":"dev","title":"ScriptExample"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":677,"exportedSymbols":{"FooBar":[676],"ScriptExample":[663],"Vm":[55],"console":[192]},"nodeType":"SourceUnit","src":"32:5697:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":55,"nodeType":"ContractDefinition","src":"120:616:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":55,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":38,"nodeType":"FunctionDefinition","src":"516:30:0","nodes":[],"functionSelector":"afc98040","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"525:9:0","parameters":{"id":36,"nodeType":"ParameterList","parameters":[],"src":"534:2:0"},"returnParameters":{"id":37,"nodeType":"ParameterList","parameters":[],"src":"545:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":43,"nodeType":"FunctionDefinition","src":"551:47:0","nodes":[],"functionSelector":"e6962cdb","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"560:9:0","parameters":{"id":41,"nodeType":"ParameterList","parameters":[{"constant":false,"id":40,"mutability":"mutable","name":"msgSender","nameLocation":"578:9:0","nodeType":"VariableDeclaration","scope":43,"src":"570:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":39,"name":"address","nodeType":"ElementaryTypeName","src":"570:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"569:19:0"},"returnParameters":{"id":42,"nodeType":"ParameterList","parameters":[],"src":"597:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":48,"nodeType":"FunctionDefinition","src":"603:52:0","nodes":[],"functionSelector":"7fec2a8d","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"612:14:0","parameters":{"id":46,"nodeType":"ParameterList","parameters":[{"constant":false,"id":45,"mutability":"mutable","name":"msgSender","nameLocation":"635:9:0","nodeType":"VariableDeclaration","scope":48,"src":"627:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":44,"name":"address","nodeType":"ElementaryTypeName","src":"627:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"626:19:0"},"returnParameters":{"id":47,"nodeType":"ParameterList","parameters":[],"src":"654:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":51,"nodeType":"FunctionDefinition","src":"660:35:0","nodes":[],"functionSelector":"7fb5297f","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"669:14:0","parameters":{"id":49,"nodeType":"ParameterList","parameters":[],"src":"683:2:0"},"returnParameters":{"id":50,"nodeType":"ParameterList","parameters":[],"src":"694:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":54,"nodeType":"FunctionDefinition","src":"700:34:0","nodes":[],"functionSelector":"76eadd36","implemented":false,"kind":"function","modifiers":[],"name":"stopBroadcast","nameLocation":"709:13:0","parameters":{"id":52,"nodeType":"ParameterList","parameters":[],"src":"722:2:0"},"returnParameters":{"id":53,"nodeType":"ParameterList","parameters":[],"src":"733:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[55],"name":"Vm","nameLocation":"130:2:0","scope":677,"usedErrors":[]},{"id":192,"nodeType":"ContractDefinition","src":"791:1622:0","nodes":[{"id":61,"nodeType":"VariableDeclaration","src":"813:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"830:15:0","scope":192,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":56,"name":"address","nodeType":"ElementaryTypeName","src":"813:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":59,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"856:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":58,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"848:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":57,"name":"address","nodeType":"ElementaryTypeName","src":"848:7:0","typeDescriptions":{}}},"id":60,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"848:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":78,"nodeType":"FunctionDefinition","src":"906:221:0","nodes":[],"body":{"id":77,"nodeType":"Block","src":"1065:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"1084:37:0","statements":[{"nodeType":"YulAssignment","src":"1098:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"1107:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"1098:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":67,"isOffset":false,"isSlot":false,"src":"1107:4:0","valueSize":1},{"declaration":74,"isOffset":false,"isSlot":false,"src":"1098:5:0","valueSize":1}],"id":76,"nodeType":"InlineAssembly","src":"1075:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"915:25:0","parameters":{"id":68,"nodeType":"ParameterList","parameters":[{"constant":false,"id":67,"mutability":"mutable","name":"fnIn","nameLocation":"987:4:0","nodeType":"VariableDeclaration","scope":78,"src":"950:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":66,"nodeType":"FunctionTypeName","parameterTypes":{"id":64,"nodeType":"ParameterList","parameters":[{"constant":false,"id":63,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":66,"src":"959:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":62,"name":"bytes","nodeType":"ElementaryTypeName","src":"959:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"958:14:0"},"returnParameterTypes":{"id":65,"nodeType":"ParameterList","parameters":[],"src":"987:0:0"},"src":"950:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"940:57:0"},"returnParameters":{"id":75,"nodeType":"ParameterList","parameters":[{"constant":false,"id":74,"mutability":"mutable","name":"fnOut","nameLocation":"1058:5:0","nodeType":"VariableDeclaration","scope":78,"src":"1021:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":73,"nodeType":"FunctionTypeName","parameterTypes":{"id":71,"nodeType":"ParameterList","parameters":[{"constant":false,"id":70,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":73,"src":"1030:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":69,"name":"bytes","nodeType":"ElementaryTypeName","src":"1030:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1029:14:0"},"returnParameterTypes":{"id":72,"nodeType":"ParameterList","parameters":[],"src":"1058:0:0"},"src":"1021:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"1020:44:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":90,"nodeType":"FunctionDefinition","src":"1133:133:0","nodes":[],"body":{"id":89,"nodeType":"Block","src":"1194:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":86,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1251:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":84,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":106,"src":"1230:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":83,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":78,"src":"1204:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":85,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":87,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":88,"nodeType":"ExpressionStatement","src":"1204:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"1142:15:0","parameters":{"id":81,"nodeType":"ParameterList","parameters":[{"constant":false,"id":80,"mutability":"mutable","name":"payload","nameLocation":"1171:7:0","nodeType":"VariableDeclaration","scope":90,"src":"1158:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":79,"name":"bytes","nodeType":"ElementaryTypeName","src":"1158:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1157:22:0"},"returnParameters":{"id":82,"nodeType":"ParameterList","parameters":[],"src":"1194:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":106,"nodeType":"FunctionDefinition","src":"1272:380:0","nodes":[],"body":{"id":105,"nodeType":"Block","src":"1336:316:0","nodes":[],"statements":[{"assignments":[96],"declarations":[{"constant":false,"id":96,"mutability":"mutable","name":"payloadLength","nameLocation":"1354:13:0","nodeType":"VariableDeclaration","scope":105,"src":"1346:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":95,"name":"uint256","nodeType":"ElementaryTypeName","src":"1346:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":99,"initialValue":{"expression":{"id":97,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":92,"src":"1370:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":98,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1370:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1346:38:0"},{"assignments":[101],"declarations":[{"constant":false,"id":101,"mutability":"mutable","name":"consoleAddress","nameLocation":"1402:14:0","nodeType":"VariableDeclaration","scope":105,"src":"1394:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":100,"name":"address","nodeType":"ElementaryTypeName","src":"1394:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":103,"initialValue":{"id":102,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":61,"src":"1419:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1394:40:0"},{"AST":{"nodeType":"YulBlock","src":"1496:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1510:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1534:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1543:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1530:3:0"},"nodeType":"YulFunctionCall","src":"1530:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1514:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1559:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1579:3:0"},"nodeType":"YulFunctionCall","src":"1579:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1586:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1602:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1616:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1631:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1634:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1568:10:0"},"nodeType":"YulFunctionCall","src":"1568:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1563:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":101,"isOffset":false,"isSlot":false,"src":"1586:14:0","valueSize":1},{"declaration":92,"isOffset":false,"isSlot":false,"src":"1534:7:0","valueSize":1},{"declaration":96,"isOffset":false,"isSlot":false,"src":"1616:13:0","valueSize":1}],"id":104,"nodeType":"InlineAssembly","src":"1487:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1281:19:0","parameters":{"id":93,"nodeType":"ParameterList","parameters":[{"constant":false,"id":92,"mutability":"mutable","name":"payload","nameLocation":"1314:7:0","nodeType":"VariableDeclaration","scope":106,"src":"1301:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":91,"name":"bytes","nodeType":"ElementaryTypeName","src":"1301:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1300:22:0"},"returnParameters":{"id":94,"nodeType":"ParameterList","parameters":[],"src":"1336:0:0"},"scope":192,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":120,"nodeType":"FunctionDefinition","src":"1658:121:0","nodes":[],"body":{"id":119,"nodeType":"Block","src":"1703:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":114,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1753:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":115,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":108,"src":"1768:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":112,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1729:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":113,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1729:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":116,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1729:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":111,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1713:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":117,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1713:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":118,"nodeType":"ExpressionStatement","src":"1713:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1667:3:0","parameters":{"id":109,"nodeType":"ParameterList","parameters":[{"constant":false,"id":108,"mutability":"mutable","name":"p0","nameLocation":"1685:2:0","nodeType":"VariableDeclaration","scope":120,"src":"1671:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":107,"name":"string","nodeType":"ElementaryTypeName","src":"1671:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1670:18:0"},"returnParameters":{"id":110,"nodeType":"ParameterList","parameters":[],"src":"1703:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":137,"nodeType":"FunctionDefinition","src":"1785:139:0","nodes":[],"body":{"id":136,"nodeType":"Block","src":"1839:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":130,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1889:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":131,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":122,"src":"1909:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":132,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":124,"src":"1913:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":128,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1865:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":129,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1865:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":133,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1865:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":127,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1849:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":134,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1849:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":135,"nodeType":"ExpressionStatement","src":"1849:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1794:3:0","parameters":{"id":125,"nodeType":"ParameterList","parameters":[{"constant":false,"id":122,"mutability":"mutable","name":"p0","nameLocation":"1812:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1798:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":121,"name":"string","nodeType":"ElementaryTypeName","src":"1798:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":124,"mutability":"mutable","name":"p1","nameLocation":"1821:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1816:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":123,"name":"bool","nodeType":"ElementaryTypeName","src":"1816:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1797:27:0"},"returnParameters":{"id":126,"nodeType":"ParameterList","parameters":[],"src":"1839:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":154,"nodeType":"FunctionDefinition","src":"1930:145:0","nodes":[],"body":{"id":153,"nodeType":"Block","src":"1987:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":147,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2037:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":148,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":139,"src":"2060:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":149,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":141,"src":"2064:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":145,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2013:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":146,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2013:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":150,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2013:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":144,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1997:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":151,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1997:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":152,"nodeType":"ExpressionStatement","src":"1997:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1939:3:0","parameters":{"id":142,"nodeType":"ParameterList","parameters":[{"constant":false,"id":139,"mutability":"mutable","name":"p0","nameLocation":"1957:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1943:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":138,"name":"string","nodeType":"ElementaryTypeName","src":"1943:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":141,"mutability":"mutable","name":"p1","nameLocation":"1969:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1961:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":140,"name":"uint256","nodeType":"ElementaryTypeName","src":"1961:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1942:30:0"},"returnParameters":{"id":143,"nodeType":"ParameterList","parameters":[],"src":"1987:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":171,"nodeType":"FunctionDefinition","src":"2081:145:0","nodes":[],"body":{"id":170,"nodeType":"Block","src":"2138:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":164,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2188:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":165,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":156,"src":"2211:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":166,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":158,"src":"2215:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":162,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2164:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":163,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2164:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":167,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2164:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":161,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2148:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":168,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2148:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":169,"nodeType":"ExpressionStatement","src":"2148:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2090:3:0","parameters":{"id":159,"nodeType":"ParameterList","parameters":[{"constant":false,"id":156,"mutability":"mutable","name":"p0","nameLocation":"2108:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2094:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":155,"name":"string","nodeType":"ElementaryTypeName","src":"2094:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":158,"mutability":"mutable","name":"p1","nameLocation":"2120:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2112:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":157,"name":"address","nodeType":"ElementaryTypeName","src":"2112:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"2093:30:0"},"returnParameters":{"id":160,"nodeType":"ParameterList","parameters":[],"src":"2138:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":191,"nodeType":"FunctionDefinition","src":"2232:179:0","nodes":[],"body":{"id":190,"nodeType":"Block","src":"2313:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":183,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2363:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":184,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2392:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":185,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":175,"src":"2396:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":186,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":177,"src":"2400:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":181,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2339:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":182,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2339:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":187,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2339:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":180,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2323:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":188,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2323:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":189,"nodeType":"ExpressionStatement","src":"2323:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2241:3:0","parameters":{"id":178,"nodeType":"ParameterList","parameters":[{"constant":false,"id":173,"mutability":"mutable","name":"p0","nameLocation":"2259:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2245:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":172,"name":"string","nodeType":"ElementaryTypeName","src":"2245:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":175,"mutability":"mutable","name":"p1","nameLocation":"2277:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2263:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":174,"name":"string","nodeType":"ElementaryTypeName","src":"2263:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":177,"mutability":"mutable","name":"p2","nameLocation":"2295:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2281:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":176,"name":"string","nodeType":"ElementaryTypeName","src":"2281:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2244:54:0"},"returnParameters":{"id":179,"nodeType":"ParameterList","parameters":[],"src":"2313:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[192],"name":"console","nameLocation":"799:7:0","scope":677,"usedErrors":[]},{"id":663,"nodeType":"ContractDefinition","src":"2541:3089:0","nodes":[{"id":207,"nodeType":"VariableDeclaration","src":"2571:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2597:10:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":194,"name":"address","nodeType":"ElementaryTypeName","src":"2571:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2644:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":201,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2634:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":203,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2634:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":200,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2626:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":199,"name":"uint256","nodeType":"ElementaryTypeName","src":"2626:7:0","typeDescriptions":{}}},"id":204,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2626:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":198,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2618:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":197,"name":"uint160","nodeType":"ElementaryTypeName","src":"2618:7:0","typeDescriptions":{}}},"id":205,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2618:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":196,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2610:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":195,"name":"address","nodeType":"ElementaryTypeName","src":"2610:7:0","typeDescriptions":{}}},"id":206,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2610:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":213,"nodeType":"VariableDeclaration","src":"2671:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2692:2:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"},"typeName":{"id":209,"nodeType":"UserDefinedTypeName","pathNode":{"id":208,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":55,"src":"2671:2:0"},"referencedDeclaration":55,"src":"2671:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"value":{"arguments":[{"id":211,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":207,"src":"2700:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":210,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":55,"src":"2697:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$55_$","typeString":"type(contract Vm)"}},"id":212,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2697:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"visibility":"internal"},{"id":215,"nodeType":"VariableDeclaration","src":"2775:22:0","nodes":[],"constant":false,"functionSelector":"61bc221a","mutability":"mutable","name":"counter","nameLocation":"2790:7:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":214,"name":"uint256","nodeType":"ElementaryTypeName","src":"2775:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":378,"nodeType":"FunctionDefinition","src":"2887:949:0","nodes":[],"body":{"id":377,"nodeType":"Block","src":"2909:927:0","nodes":[],"statements":[{"assignments":[220],"declarations":[{"constant":false,"id":220,"mutability":"mutable","name":"x","nameLocation":"2924:1:0","nodeType":"VariableDeclaration","scope":377,"src":"2919:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":219,"name":"bool","nodeType":"ElementaryTypeName","src":"2919:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":226,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":223,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2937:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":224,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2953:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":221,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"2928:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":222,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2928:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":225,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2928:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2919:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":230,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2981:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":231,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":220,"src":"3004:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":227,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"2969:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":229,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":137,"src":"2969:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2969:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":233,"nodeType":"ExpressionStatement","src":"2969:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":237,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3029:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":240,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3054:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":239,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3046:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":238,"name":"address","nodeType":"ElementaryTypeName","src":"3046:7:0","typeDescriptions":{}}},"id":241,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3046:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":234,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3017:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":236,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3017:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":242,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3017:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":243,"nodeType":"ExpressionStatement","src":"3017:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":247,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3082:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":252,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3120:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":251,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3112:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":250,"name":"address","nodeType":"ElementaryTypeName","src":"3112:7:0","typeDescriptions":{}}},"id":253,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3112:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":248,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3100:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3100:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":254,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3100:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":244,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3070:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":246,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3070:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":255,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3070:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":256,"nodeType":"ExpressionStatement","src":"3070:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":260,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3149:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":263,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3172:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":264,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3172:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":262,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3164:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":261,"name":"address","nodeType":"ElementaryTypeName","src":"3164:7:0","typeDescriptions":{}}},"id":265,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3164:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":257,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3137:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":259,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3137:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":266,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3137:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":267,"nodeType":"ExpressionStatement","src":"3137:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":271,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3206:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":276,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3242:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":277,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3242:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":275,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3234:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":274,"name":"address","nodeType":"ElementaryTypeName","src":"3234:7:0","typeDescriptions":{}}},"id":278,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3234:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":272,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3222:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":273,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3222:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":279,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3222:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":268,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3194:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":270,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3194:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":280,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3194:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":281,"nodeType":"ExpressionStatement","src":"3194:61:0"},{"assignments":[283],"declarations":[{"constant":false,"id":283,"mutability":"mutable","name":"json","nameLocation":"3280:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3266:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":282,"name":"string","nodeType":"ElementaryTypeName","src":"3266:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":285,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3287:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"3266:55:0"},{"assignments":[290],"declarations":[{"constant":false,"id":290,"mutability":"mutable","name":"keys","nameLocation":"3347:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3331:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":288,"name":"string","nodeType":"ElementaryTypeName","src":"3331:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":289,"nodeType":"ArrayTypeName","src":"3331:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":296,"initialValue":{"arguments":[{"id":293,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":283,"src":"3371:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":294,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3377:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":291,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3354:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":292,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3354:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":295,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3354:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3331:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":300,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3414:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":301,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3422:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":303,"indexExpression":{"hexValue":"30","id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3427:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3422:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":304,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3431:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":306,"indexExpression":{"hexValue":"31","id":305,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3436:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3431:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":297,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3402:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":299,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":191,"src":"3402:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":307,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3402:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":308,"nodeType":"ExpressionStatement","src":"3402:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":312,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3461:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":309,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3450:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":311,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3450:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":313,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3450:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":314,"nodeType":"ExpressionStatement","src":"3450:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":322,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3517:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":321,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3509:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":320,"name":"uint160","nodeType":"ElementaryTypeName","src":"3509:7:0","typeDescriptions":{}}},"id":323,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3509:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":319,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3501:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":318,"name":"address","nodeType":"ElementaryTypeName","src":"3501:7:0","typeDescriptions":{}}},"id":324,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3501:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":315,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3487:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":317,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3487:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3487:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":326,"nodeType":"ExpressionStatement","src":"3487:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":330,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3545:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":327,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3534:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":329,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3534:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3534:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":332,"nodeType":"ExpressionStatement","src":"3534:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":336,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3582:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":339,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3617:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":340,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3617:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":338,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3609:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":337,"name":"address","nodeType":"ElementaryTypeName","src":"3609:7:0","typeDescriptions":{}}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3609:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":333,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3570:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":335,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3570:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3570:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3570:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3651:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":350,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3689:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":349,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3681:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":348,"name":"address","nodeType":"ElementaryTypeName","src":"3681:7:0","typeDescriptions":{}}},"id":351,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3681:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":344,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3639:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3639:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3639:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":353,"nodeType":"ExpressionStatement","src":"3639:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":357,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3716:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":354,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3705:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":356,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3705:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":358,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3705:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":359,"nodeType":"ExpressionStatement","src":"3705:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":360,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3741:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":362,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3741:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":363,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3741:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":364,"nodeType":"ExpressionStatement","src":"3741:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":368,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3776:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":365,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3765:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":367,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3765:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":369,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3765:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":370,"nodeType":"ExpressionStatement","src":"3765:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":374,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3821:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":371,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3809:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":373,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"3809:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":375,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3809:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":376,"nodeType":"ExpressionStatement","src":"3809:20:0"}]},"documentation":{"id":216,"nodeType":"StructuredDocumentation","src":"2804:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2896:3:0","parameters":{"id":217,"nodeType":"ParameterList","parameters":[],"src":"2899:2:0"},"returnParameters":{"id":218,"nodeType":"ParameterList","parameters":[],"src":"2909:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":566,"nodeType":"FunctionDefinition","src":"3903:988:0","nodes":[],"body":{"id":565,"nodeType":"Block","src":"3934:957:0","nodes":[],"statements":[{"expression":{"arguments":[{"hexValue":"74657374696e672073696e676c65","id":385,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3956:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""},"value":"testing single"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""}],"expression":{"id":382,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3944:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":384,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"3944:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":386,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3944:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":387,"nodeType":"ExpressionStatement","src":"3944:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":388,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3983:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":390,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"3983:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":391,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3983:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":392,"nodeType":"ExpressionStatement","src":"3983:14:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c31","id":396,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4018:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""},"value":"single_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""}],"expression":{"id":393,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4007:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":395,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4007:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":397,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4007:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":398,"nodeType":"ExpressionStatement","src":"4007:26:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c32","id":402,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4054:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""},"value":"single_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""}],"expression":{"id":399,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4043:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":401,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":620,"src":"4043:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":403,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4043:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":404,"nodeType":"ExpressionStatement","src":"4043:26:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073746172742f73746f70","id":408,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4092:20:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""},"value":"testing start/stop"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""}],"expression":{"id":405,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4080:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":407,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4080:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":409,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4080:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":410,"nodeType":"ExpressionStatement","src":"4080:33:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078633066666565","id":418,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4157:8:0","typeDescriptions":{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"},"value":"0xc0ffee"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"}],"id":417,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4149:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":416,"name":"uint160","nodeType":"ElementaryTypeName","src":"4149:7:0","typeDescriptions":{}}},"id":419,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4149:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":415,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4141:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":414,"name":"address","nodeType":"ElementaryTypeName","src":"4141:7:0","typeDescriptions":{}}},"id":420,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4141:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":411,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4123:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":413,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4123:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":421,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4123:45:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":422,"nodeType":"ExpressionStatement","src":"4123:45:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c31","id":426,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4189:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""},"value":"startstop_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""}],"expression":{"id":423,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4178:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":425,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4178:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":427,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4178:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":428,"nodeType":"ExpressionStatement","src":"4178:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c32","id":432,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4228:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""},"value":"startstop_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""}],"expression":{"id":429,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4217:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":431,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":620,"src":"4217:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":433,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4217:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":434,"nodeType":"ExpressionStatement","src":"4217:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f70757265","id":438,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4270:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""},"value":"startstop_pure"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""}],"expression":{"id":435,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4256:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":437,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"callPure","nodeType":"MemberAccess","referencedDeclaration":662,"src":"4256:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure external"}},"id":439,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4256:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":440,"nodeType":"ExpressionStatement","src":"4256:31:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":441,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4297:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":443,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4297:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":444,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4297:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":445,"nodeType":"ExpressionStatement","src":"4297:18:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c33","id":449,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4336:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""},"value":"startstop_call3"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""}],"expression":{"id":446,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4325:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":448,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4325:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":450,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4325:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":451,"nodeType":"ExpressionStatement","src":"4325:29:0"},{"expression":{"arguments":[{"hexValue":"74657374696e67206e6573746564","id":455,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4377:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""},"value":"testing nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""}],"expression":{"id":452,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4365:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":454,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4365:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":456,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4365:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":457,"nodeType":"ExpressionStatement","src":"4365:29:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307831323334","id":465,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4438:6:0","typeDescriptions":{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"},"value":"0x1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"}],"id":464,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4430:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":463,"name":"uint160","nodeType":"ElementaryTypeName","src":"4430:7:0","typeDescriptions":{}}},"id":466,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4430:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":462,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4422:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":461,"name":"address","nodeType":"ElementaryTypeName","src":"4422:7:0","typeDescriptions":{}}},"id":467,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4422:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":458,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4404:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":460,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4404:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":468,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4404:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":469,"nodeType":"ExpressionStatement","src":"4404:43:0"},{"expression":{"arguments":[{"hexValue":"6e6573746564","id":473,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4470:8:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""},"value":"nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""}],"expression":{"id":470,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4457:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":472,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested1","nodeType":"MemberAccess","referencedDeclaration":635,"src":"4457:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":474,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4457:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":475,"nodeType":"ExpressionStatement","src":"4457:22:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":476,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4489:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":478,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4489:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":479,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4489:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":480,"nodeType":"ExpressionStatement","src":"4489:18:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206465706c6f796d656e74","id":484,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4530:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""},"value":"contract deployment"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""}],"expression":{"id":481,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4518:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":483,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4518:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":485,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4518:34:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":486,"nodeType":"ExpressionStatement","src":"4518:34:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078313233343536","id":494,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4591:8:0","typeDescriptions":{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"},"value":"0x123456"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"}],"id":493,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4583:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":492,"name":"uint160","nodeType":"ElementaryTypeName","src":"4583:7:0","typeDescriptions":{}}},"id":495,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4583:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":491,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4575:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":490,"name":"address","nodeType":"ElementaryTypeName","src":"4575:7:0","typeDescriptions":{}}},"id":496,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4575:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":487,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4562:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":489,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4562:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":497,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4562:40:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":498,"nodeType":"ExpressionStatement","src":"4562:40:0"},{"assignments":[501],"declarations":[{"constant":false,"id":501,"mutability":"mutable","name":"x","nameLocation":"4619:1:0","nodeType":"VariableDeclaration","scope":565,"src":"4612:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"},"typeName":{"id":500,"nodeType":"UserDefinedTypeName","pathNode":{"id":499,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4612:6:0"},"referencedDeclaration":676,"src":"4612:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"visibility":"internal"}],"id":507,"initialValue":{"arguments":[{"hexValue":"31323334","id":505,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4634:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":504,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4623:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":503,"nodeType":"UserDefinedTypeName","pathNode":{"id":502,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4627:6:0"},"referencedDeclaration":676,"src":"4627:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}}},"id":506,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4623:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4612:27:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":513,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":509,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":501,"src":"4657:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"id":510,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":665,"src":"4657:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":511,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4657:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":512,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4668:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4657:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":508,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4649:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":514,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4649:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":515,"nodeType":"ExpressionStatement","src":"4649:24:0"},{"expression":{"arguments":[{"hexValue":"6372656174652032","id":519,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4696:10:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""},"value":"create 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""}],"expression":{"id":516,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4684:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":518,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4684:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":520,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4684:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":521,"nodeType":"ExpressionStatement","src":"4684:23:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307863616665","id":529,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4746:6:0","typeDescriptions":{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"},"value":"0xcafe"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"}],"id":528,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4738:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":527,"name":"uint160","nodeType":"ElementaryTypeName","src":"4738:7:0","typeDescriptions":{}}},"id":530,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4738:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":526,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4730:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":525,"name":"address","nodeType":"ElementaryTypeName","src":"4730:7:0","typeDescriptions":{}}},"id":531,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4730:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":522,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4717:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":524,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4717:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":532,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4717:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":533,"nodeType":"ExpressionStatement","src":"4717:38:0"},{"assignments":[536],"declarations":[{"constant":false,"id":536,"mutability":"mutable","name":"y","nameLocation":"4772:1:0","nodeType":"VariableDeclaration","scope":565,"src":"4765:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"},"typeName":{"id":535,"nodeType":"UserDefinedTypeName","pathNode":{"id":534,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4765:6:0"},"referencedDeclaration":676,"src":"4765:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"visibility":"internal"}],"id":550,"initialValue":{"arguments":[{"hexValue":"31323334","id":548,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4815:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":539,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4776:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":538,"nodeType":"UserDefinedTypeName","pathNode":{"id":537,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4780:6:0"},"referencedDeclaration":676,"src":"4780:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}}},"id":547,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"names":["salt"],"nodeType":"FunctionCallOptions","options":[{"arguments":[{"arguments":[{"hexValue":"3432","id":544,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4809:2:0","typeDescriptions":{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"},"value":"42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"}],"id":543,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4801:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":542,"name":"uint256","nodeType":"ElementaryTypeName","src":"4801:7:0","typeDescriptions":{}}},"id":545,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4801:11:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":541,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4793:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_bytes32_$","typeString":"type(bytes32)"},"typeName":{"id":540,"name":"bytes32","nodeType":"ElementaryTypeName","src":"4793:7:0","typeDescriptions":{}}},"id":546,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4793:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"src":"4776:38:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$salt","typeString":"function (uint256) returns (contract FooBar)"}},"id":549,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4776:44:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4765:55:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":556,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":552,"name":"y","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":536,"src":"4838:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"id":553,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":665,"src":"4838:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":554,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4838:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":555,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4849:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4838:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":551,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4830:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":557,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4830:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":558,"nodeType":"ExpressionStatement","src":"4830:24:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":562,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4876:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":559,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4864:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":561,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4864:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":563,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4864:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":564,"nodeType":"ExpressionStatement","src":"4864:20:0"}]},"documentation":{"id":379,"nodeType":"StructuredDocumentation","src":"3842:56:0","text":"@notice example function, to test vm.broadcast with."},"functionSelector":"bef03abc","implemented":true,"kind":"function","modifiers":[],"name":"runBroadcast","nameLocation":"3912:12:0","parameters":{"id":380,"nodeType":"ParameterList","parameters":[],"src":"3924:2:0"},"returnParameters":{"id":381,"nodeType":"ParameterList","parameters":[],"src":"3934:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":590,"nodeType":"FunctionDefinition","src":"4986:143:0","nodes":[],"body":{"id":589,"nodeType":"Block","src":"5035:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":575,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":569,"src":"5057:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":572,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5045:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":574,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5045:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":576,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5045:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":577,"nodeType":"ExpressionStatement","src":"5045:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":581,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"5082:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":584,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"5110:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":585,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"5110:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":583,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5102:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":582,"name":"address","nodeType":"ElementaryTypeName","src":"5102:7:0","typeDescriptions":{}}},"id":586,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5102:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":578,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5070:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":580,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"5070:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":587,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5070:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":588,"nodeType":"ExpressionStatement","src":"5070:52:0"}]},"documentation":{"id":567,"nodeType":"StructuredDocumentation","src":"4897:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"4995:5:0","parameters":{"id":570,"nodeType":"ParameterList","parameters":[{"constant":false,"id":569,"mutability":"mutable","name":"_v","nameLocation":"5017:2:0","nodeType":"VariableDeclaration","scope":590,"src":"5001:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":568,"name":"string","nodeType":"ElementaryTypeName","src":"5001:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5000:20:0"},"returnParameters":{"id":571,"nodeType":"ParameterList","parameters":[],"src":"5035:0:0"},"scope":663,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":605,"nodeType":"FunctionDefinition","src":"5135:95:0","nodes":[],"body":{"id":604,"nodeType":"Block","src":"5179:51:0","nodes":[],"statements":[{"expression":{"id":596,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5189:9:0","subExpression":{"id":595,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5189:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":597,"nodeType":"ExpressionStatement","src":"5189:9:0"},{"expression":{"arguments":[{"id":601,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":592,"src":"5220:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":598,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5208:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":600,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5208:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":602,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5208:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":603,"nodeType":"ExpressionStatement","src":"5208:15:0"}]},"functionSelector":"7e79255d","implemented":true,"kind":"function","modifiers":[],"name":"call1","nameLocation":"5144:5:0","parameters":{"id":593,"nodeType":"ParameterList","parameters":[{"constant":false,"id":592,"mutability":"mutable","name":"_v","nameLocation":"5166:2:0","nodeType":"VariableDeclaration","scope":605,"src":"5150:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":591,"name":"string","nodeType":"ElementaryTypeName","src":"5150:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5149:20:0"},"returnParameters":{"id":594,"nodeType":"ParameterList","parameters":[],"src":"5179:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":620,"nodeType":"FunctionDefinition","src":"5236:95:0","nodes":[],"body":{"id":619,"nodeType":"Block","src":"5280:51:0","nodes":[],"statements":[{"expression":{"id":611,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5290:9:0","subExpression":{"id":610,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5290:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":612,"nodeType":"ExpressionStatement","src":"5290:9:0"},{"expression":{"arguments":[{"id":616,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":607,"src":"5321:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":613,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5309:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":615,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5309:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":617,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5309:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":618,"nodeType":"ExpressionStatement","src":"5309:15:0"}]},"functionSelector":"8d3ef7ca","implemented":true,"kind":"function","modifiers":[],"name":"call2","nameLocation":"5245:5:0","parameters":{"id":608,"nodeType":"ParameterList","parameters":[{"constant":false,"id":607,"mutability":"mutable","name":"_v","nameLocation":"5267:2:0","nodeType":"VariableDeclaration","scope":620,"src":"5251:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":606,"name":"string","nodeType":"ElementaryTypeName","src":"5251:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5250:20:0"},"returnParameters":{"id":609,"nodeType":"ParameterList","parameters":[],"src":"5280:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":635,"nodeType":"FunctionDefinition","src":"5337:98:0","nodes":[],"body":{"id":634,"nodeType":"Block","src":"5383:52:0","nodes":[],"statements":[{"expression":{"id":626,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5393:9:0","subExpression":{"id":625,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5393:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":627,"nodeType":"ExpressionStatement","src":"5393:9:0"},{"expression":{"arguments":[{"id":631,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":622,"src":"5425:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":628,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"5412:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":630,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested2","nodeType":"MemberAccess","referencedDeclaration":650,"src":"5412:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":632,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5412:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":633,"nodeType":"ExpressionStatement","src":"5412:16:0"}]},"functionSelector":"a76ccdfa","implemented":true,"kind":"function","modifiers":[],"name":"nested1","nameLocation":"5346:7:0","parameters":{"id":623,"nodeType":"ParameterList","parameters":[{"constant":false,"id":622,"mutability":"mutable","name":"_v","nameLocation":"5370:2:0","nodeType":"VariableDeclaration","scope":635,"src":"5354:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":621,"name":"string","nodeType":"ElementaryTypeName","src":"5354:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5353:20:0"},"returnParameters":{"id":624,"nodeType":"ParameterList","parameters":[],"src":"5383:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":650,"nodeType":"FunctionDefinition","src":"5441:97:0","nodes":[],"body":{"id":649,"nodeType":"Block","src":"5487:51:0","nodes":[],"statements":[{"expression":{"id":641,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5497:9:0","subExpression":{"id":640,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5497:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":642,"nodeType":"ExpressionStatement","src":"5497:9:0"},{"expression":{"arguments":[{"id":646,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":637,"src":"5528:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":643,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5516:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":645,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5516:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":647,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5516:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":648,"nodeType":"ExpressionStatement","src":"5516:15:0"}]},"functionSelector":"dbf1282f","implemented":true,"kind":"function","modifiers":[],"name":"nested2","nameLocation":"5450:7:0","parameters":{"id":638,"nodeType":"ParameterList","parameters":[{"constant":false,"id":637,"mutability":"mutable","name":"_v","nameLocation":"5474:2:0","nodeType":"VariableDeclaration","scope":650,"src":"5458:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":636,"name":"string","nodeType":"ElementaryTypeName","src":"5458:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5457:20:0"},"returnParameters":{"id":639,"nodeType":"ParameterList","parameters":[],"src":"5487:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":662,"nodeType":"FunctionDefinition","src":"5544:84:0","nodes":[],"body":{"id":661,"nodeType":"Block","src":"5596:32:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":658,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":652,"src":"5618:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":655,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5606:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":657,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5606:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":659,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5606:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":660,"nodeType":"ExpressionStatement","src":"5606:15:0"}]},"functionSelector":"7f8b915c","implemented":true,"kind":"function","modifiers":[],"name":"callPure","nameLocation":"5553:8:0","parameters":{"id":653,"nodeType":"ParameterList","parameters":[{"constant":false,"id":652,"mutability":"mutable","name":"_v","nameLocation":"5578:2:0","nodeType":"VariableDeclaration","scope":662,"src":"5562:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":651,"name":"string","nodeType":"ElementaryTypeName","src":"5562:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5561:20:0"},"returnParameters":{"id":654,"nodeType":"ParameterList","parameters":[],"src":"5596:0:0"},"scope":663,"stateMutability":"pure","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[676],"contractKind":"contract","documentation":{"id":193,"nodeType":"StructuredDocumentation","src":"2415:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[663],"name":"ScriptExample","nameLocation":"2550:13:0","scope":677,"usedErrors":[]},{"id":676,"nodeType":"ContractDefinition","src":"5632:96:0","nodes":[{"id":665,"nodeType":"VariableDeclaration","src":"5654:18:0","nodes":[],"constant":false,"functionSelector":"c2985578","mutability":"mutable","name":"foo","nameLocation":"5669:3:0","scope":676,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":664,"name":"uint256","nodeType":"ElementaryTypeName","src":"5654:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":675,"nodeType":"FunctionDefinition","src":"5679:47:0","nodes":[],"body":{"id":674,"nodeType":"Block","src":"5702:24:0","nodes":[],"statements":[{"expression":{"id":672,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":670,"name":"foo","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":665,"src":"5712:3:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":671,"name":"v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":667,"src":"5718:1:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5712:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":673,"nodeType":"ExpressionStatement","src":"5712:7:0"}]},"implemented":true,"kind":"constructor","modifiers":[],"name":"","nameLocation":"-1:-1:-1","parameters":{"id":668,"nodeType":"ParameterList","parameters":[{"constant":false,"id":667,"mutability":"mutable","name":"v","nameLocation":"5699:1:0","nodeType":"VariableDeclaration","scope":675,"src":"5691:9:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":666,"name":"uint256","nodeType":"ElementaryTypeName","src":"5691:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"5690:11:0"},"returnParameters":{"id":669,"nodeType":"ParameterList","parameters":[],"src":"5702:0:0"},"scope":676,"stateMutability":"nonpayable","virtual":false,"visibility":"public"}],"abstract":false,"baseContracts":[],"canonicalName":"FooBar","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[676],"name":"FooBar","nameLocation":"5641:6:0","scope":677,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file +{"abi":[{"type":"function","name":"call1","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"call2","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"callPure","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"pure"},{"type":"function","name":"counter","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"hello","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"view"},{"type":"function","name":"nested1","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"nested2","inputs":[{"name":"_v","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"run","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"runBroadcast","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"bytecode":{"object":"0x608060405234801561001057600080fd5b5061202a806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063a76ccdfa11610076578063bef03abc1161005b578063bef03abc14610111578063c040622614610119578063dbf1282f146100c357600080fd5b8063a76ccdfa146100eb578063a777d0dc146100fe57600080fd5b806361bc221a146100a85780637e79255d146100c35780637f8b915c146100d85780638d3ef7ca146100c3575b600080fd5b6100b160005481565b60405190815260200160405180910390f35b6100d66100d1366004611a60565b610121565b005b6100d66100e6366004611a60565b610178565b6100d66100f9366004611a60565b6101b7565b6100d661010c366004611a60565b61023f565b6100d66102bd565b6100d6610f54565b60008054908061013083611ad2565b919050555061017482828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061175b92505050565b5050565b61017482828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061175b92505050565b6000805490806101c683611ad2565b90915550506040517fdbf1282f000000000000000000000000000000000000000000000000000000008152309063dbf1282f906102099085908590600401611b31565b600060405180830381600087803b15801561022357600080fd5b505af1158015610237573d6000803e3d6000fd5b505050505050565b61027e82828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061175b92505050565b6101746040518060400160405280601081526020017f68656c6c6f206d73672e73656e64657200000000000000000000000000000000815250336117ed565b604080518082018252600b81527f6e6f6e6365207374617274000000000000000000000000000000000000000000602082015290517f2d0335ab0000000000000000000000000000000000000000000000000000000081523060048201526103909190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab906024015b602060405180830381865afa15801561035d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103819190611b7e565b67ffffffffffffffff1661187e565b6103ce6040518060400160405280600e81526020017f74657374696e672073696e676c6500000000000000000000000000000000000081525061175b565b7f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff1663afc980406040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561043957600080fd5b505af115801561044d573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f73696e676c655f63616c6c3100000000000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b1580156104d057600080fd5b505af11580156104e4573d6000803e3d6000fd5b50506040517f8d3ef7ca00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f73696e676c655f63616c6c3200000000000000000000000000000000000000006044820152309250638d3ef7ca9150606401600060405180830381600087803b15801561056757600080fd5b505af115801561057b573d6000803e3d6000fd5b505050506105bd6040518060400160405280601281526020017f74657374696e672073746172742f73746f70000000000000000000000000000081525061175b565b6040517f7fec2a8d00000000000000000000000000000000000000000000000000000000815262c0ffee6004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d90637fec2a8d90602401600060405180830381600087803b15801561062557600080fd5b505af1158015610639573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3100000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b1580156106bc57600080fd5b505af11580156106d0573d6000803e3d6000fd5b50506040517f8d3ef7ca00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3200000000000000000000000000000000006044820152309250638d3ef7ca9150606401600060405180830381600087803b15801561075357600080fd5b505af1158015610767573d6000803e3d6000fd5b50506040517f7f8b915c00000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f737461727473746f705f707572650000000000000000000000000000000000006044820152309250637f8b915c915060640160006040518083038186803b1580156107e857600080fd5b505afa1580156107fc573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166376eadd366040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561086b57600080fd5b505af115801561087f573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3300000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b15801561090257600080fd5b505af1158015610916573d6000803e3d6000fd5b505050506109586040518060400160405280600e81526020017f74657374696e67206e657374656400000000000000000000000000000000000081525061175b565b6040517f7fec2a8d0000000000000000000000000000000000000000000000000000000081526112346004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d90637fec2a8d90602401600060405180830381600087803b1580156109bf57600080fd5b505af11580156109d3573d6000803e3d6000fd5b50506040517fa76ccdfa00000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f6e65737465640000000000000000000000000000000000000000000000000000604482015230925063a76ccdfa9150606401600060405180830381600087803b158015610a5657600080fd5b505af1158015610a6a573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166376eadd366040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610ad957600080fd5b505af1158015610aed573d6000803e3d6000fd5b50505050610b2f6040518060400160405280601381526020017f636f6e7472616374206465706c6f796d656e740000000000000000000000000081525061175b565b6040517fe6962cdb000000000000000000000000000000000000000000000000000000008152621234566004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d9063e6962cdb90602401600060405180830381600087803b158015610b9757600080fd5b505af1158015610bab573d6000803e3d6000fd5b5050505060006104d2604051610bc090611a54565b908152602001604051809103906000f080158015610be2573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff1663c29855786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c549190611baf565b6104d214610c6157600080fd5b610c9f6040518060400160405280600881526020017f637265617465203200000000000000000000000000000000000000000000000081525061175b565b6040517fe6962cdb00000000000000000000000000000000000000000000000000000000815261cafe6004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d9063e6962cdb90602401600060405180830381600087803b158015610d0657600080fd5b505af1158015610d1a573d6000803e3d6000fd5b505050506000602a60001b6104d2604051610d3490611a54565b9081526020018190604051809103906000f5905080158015610d5a573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff1663c29855786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610da8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcc9190611baf565b6104d214610dd957600080fd5b610e176040518060400160405280600581526020017f646f6e652100000000000000000000000000000000000000000000000000000081525061175b565b7f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff1663afc980406040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610e8257600080fd5b505af1158015610e96573d6000803e3d6000fd5b505050506104d2604051610ea990611a54565b908152602001604051809103906000f080158015610ecb573d6000803e3d6000fd5b5050604080518082018252600981527f6e6f6e636520656e640000000000000000000000000000000000000000000000602082015290517f2d0335ab0000000000000000000000000000000000000000000000000000000081523060048201526101749190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab90602401610340565b604080517f4777f3cf0000000000000000000000000000000000000000000000000000000081526004810191909152600c60448201527f4558414d504c455f424f4f4c0000000000000000000000000000000000000000606482015260006024820181905290737109709ecfa91a80626ff3989d68f67f5b1dd12d90634777f3cf90608401602060405180830381865afa158015610ff6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061101a9190611bc8565b905061105b6040518060400160405280601381526020017f626f6f6c2076616c75652066726f6d20656e76000000000000000000000000008152508261190f565b61109a6040518060400160405280600d81526020017f636f6e7472616374206164647200000000000000000000000000000000000000815250306117ed565b604080518082018252600e81527f636f6e7472616374206e6f6e6365000000000000000000000000000000000000602082015290517f2d0335ab0000000000000000000000000000000000000000000000000000000081523060048201526111219190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab90602401610340565b6111606040518060400160405280600b81526020017f73656e6465722061646472000000000000000000000000000000000000000000815250336117ed565b604080518082018252600c81527f73656e646572206e6f6e63650000000000000000000000000000000000000000602082015290517f2d0335ab0000000000000000000000000000000000000000000000000000000081523360048201526111e79190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab90602401610340565b60408051808201825260208082527f7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d9082015290517f213e4198000000000000000000000000000000000000000000000000000000008152600090737109709ecfa91a80626ff3989d68f67f5b1dd12d9063213e41989061126c908590600401611c64565b600060405180830381865afa158015611289573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526112cf9190810190611d34565b90506113456040518060400160405280600481526020017f6b657973000000000000000000000000000000000000000000000000000000008152508260008151811061131d5761131d611e68565b60200260200101518360018151811061133857611338611e68565b60200260200101516119a0565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f66726f6d206f726967696e616c000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b1580156113c257600080fd5b505afa1580156113d6573d6000803e3d6000fd5b50506040517f06447d5600000000000000000000000000000000000000000000000000000000815260426004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d92506306447d569150602401600060405180830381600087803b15801561144057600080fd5b505af1158015611454573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b20310000000000000000000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b1580156114d557600080fd5b505afa1580156114e9573d6000803e3d6000fd5b5050505061152c6040518060400160405280601781526020017f706172656e742073636f7065206d73672e73656e646572000000000000000000815250336117ed565b61156b6040518060400160405280601a81526020017f706172656e742073636f706520636f6e74726163742e61646472000000000000815250306117ed565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b203200000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b1580156115e857600080fd5b505afa1580156115fc573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166390c5013b6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561166b57600080fd5b505af115801561167f573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f66726f6d206f726967696e616c20616761696e00000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b15801561170057600080fd5b505afa158015611714573d6000803e3d6000fd5b505050506117566040518060400160405280600581526020017f646f6e652100000000000000000000000000000000000000000000000000000081525061175b565b505050565b6117ea8160405160240161176f9190611e97565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f41304fac00000000000000000000000000000000000000000000000000000000179052611a2f565b50565b6101748282604051602401611803929190611eaa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f319af33300000000000000000000000000000000000000000000000000000000179052611a2f565b6101748282604051602401611894929190611ee2565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb60e72cc00000000000000000000000000000000000000000000000000000000179052611a2f565b6101748282604051602401611925929190611f04565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fc3b5563500000000000000000000000000000000000000000000000000000000179052611a2f565b6117568383836040516024016119b893929190611f28565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f2ced7cef000000000000000000000000000000000000000000000000000000001790525b6117ea8180516a636f6e736f6c652e6c6f67602083016000808483855afa5050505050565b60b280611f6c83390190565b60008060208385031215611a7357600080fd5b823567ffffffffffffffff80821115611a8b57600080fd5b818501915085601f830112611a9f57600080fd5b813581811115611aae57600080fd5b866020828501011115611ac057600080fd5b60209290920196919550909350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611b2a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b600060208284031215611b9057600080fd5b815167ffffffffffffffff81168114611ba857600080fd5b9392505050565b600060208284031215611bc157600080fd5b5051919050565b600060208284031215611bda57600080fd5b81518015158114611ba857600080fd5b60005b83811015611c05578181015183820152602001611bed565b83811115611c14576000848401525b50505050565b60008151808452611c32816020860160208601611bea565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b604081526000611c776040830184611c1a565b8281036020840152600c81527f2e726f6f745f6b65795b305d000000000000000000000000000000000000000060208201526040810191505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611d2c57611d2c611cb6565b604052919050565b60006020808385031215611d4757600080fd5b825167ffffffffffffffff80821115611d5f57600080fd5b8185019150601f8681840112611d7457600080fd5b825182811115611d8657611d86611cb6565b8060051b611d95868201611ce5565b918252848101860191868101908a841115611daf57600080fd5b87870192505b83831015611e5a57825186811115611dcd5760008081fd5b8701603f81018c13611ddf5760008081fd5b88810151604088821115611df557611df5611cb6565b611e248b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08a85011601611ce5565b8281528e82848601011115611e395760008081fd5b611e48838d8301848701611bea565b85525050509187019190870190611db5565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602081526000611ba86020830184611c1a565b604081526000611ebd6040830185611c1a565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b604081526000611ef56040830185611c1a565b90508260208301529392505050565b604081526000611f176040830185611c1a565b905082151560208301529392505050565b606081526000611f3b6060830186611c1a565b8281036020840152611f4d8186611c1a565b90508281036040840152611f618185611c1a565b969550505050505056fe608060405234801561001057600080fd5b506040516100b23803806100b283398101604081905261002f91610037565b600055610050565b60006020828403121561004957600080fd5b5051919050565b60548061005e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b603560005481565b60405190815260200160405180910390f3fea164736f6c634300080f000aa164736f6c634300080f000a","sourceMap":"2541:3359:0:-:0;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405234801561001057600080fd5b50600436106100a35760003560e01c8063a76ccdfa11610076578063bef03abc1161005b578063bef03abc14610111578063c040622614610119578063dbf1282f146100c357600080fd5b8063a76ccdfa146100eb578063a777d0dc146100fe57600080fd5b806361bc221a146100a85780637e79255d146100c35780637f8b915c146100d85780638d3ef7ca146100c3575b600080fd5b6100b160005481565b60405190815260200160405180910390f35b6100d66100d1366004611a60565b610121565b005b6100d66100e6366004611a60565b610178565b6100d66100f9366004611a60565b6101b7565b6100d661010c366004611a60565b61023f565b6100d66102bd565b6100d6610f54565b60008054908061013083611ad2565b919050555061017482828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061175b92505050565b5050565b61017482828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061175b92505050565b6000805490806101c683611ad2565b90915550506040517fdbf1282f000000000000000000000000000000000000000000000000000000008152309063dbf1282f906102099085908590600401611b31565b600060405180830381600087803b15801561022357600080fd5b505af1158015610237573d6000803e3d6000fd5b505050505050565b61027e82828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061175b92505050565b6101746040518060400160405280601081526020017f68656c6c6f206d73672e73656e64657200000000000000000000000000000000815250336117ed565b604080518082018252600b81527f6e6f6e6365207374617274000000000000000000000000000000000000000000602082015290517f2d0335ab0000000000000000000000000000000000000000000000000000000081523060048201526103909190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab906024015b602060405180830381865afa15801561035d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103819190611b7e565b67ffffffffffffffff1661187e565b6103ce6040518060400160405280600e81526020017f74657374696e672073696e676c6500000000000000000000000000000000000081525061175b565b7f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff1663afc980406040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561043957600080fd5b505af115801561044d573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f73696e676c655f63616c6c3100000000000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b1580156104d057600080fd5b505af11580156104e4573d6000803e3d6000fd5b50506040517f8d3ef7ca00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f73696e676c655f63616c6c3200000000000000000000000000000000000000006044820152309250638d3ef7ca9150606401600060405180830381600087803b15801561056757600080fd5b505af115801561057b573d6000803e3d6000fd5b505050506105bd6040518060400160405280601281526020017f74657374696e672073746172742f73746f70000000000000000000000000000081525061175b565b6040517f7fec2a8d00000000000000000000000000000000000000000000000000000000815262c0ffee6004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d90637fec2a8d90602401600060405180830381600087803b15801561062557600080fd5b505af1158015610639573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3100000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b1580156106bc57600080fd5b505af11580156106d0573d6000803e3d6000fd5b50506040517f8d3ef7ca00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3200000000000000000000000000000000006044820152309250638d3ef7ca9150606401600060405180830381600087803b15801561075357600080fd5b505af1158015610767573d6000803e3d6000fd5b50506040517f7f8b915c00000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f737461727473746f705f707572650000000000000000000000000000000000006044820152309250637f8b915c915060640160006040518083038186803b1580156107e857600080fd5b505afa1580156107fc573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166376eadd366040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561086b57600080fd5b505af115801561087f573d6000803e3d6000fd5b50506040517f7e79255d00000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f737461727473746f705f63616c6c3300000000000000000000000000000000006044820152309250637e79255d9150606401600060405180830381600087803b15801561090257600080fd5b505af1158015610916573d6000803e3d6000fd5b505050506109586040518060400160405280600e81526020017f74657374696e67206e657374656400000000000000000000000000000000000081525061175b565b6040517f7fec2a8d0000000000000000000000000000000000000000000000000000000081526112346004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d90637fec2a8d90602401600060405180830381600087803b1580156109bf57600080fd5b505af11580156109d3573d6000803e3d6000fd5b50506040517fa76ccdfa00000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f6e65737465640000000000000000000000000000000000000000000000000000604482015230925063a76ccdfa9150606401600060405180830381600087803b158015610a5657600080fd5b505af1158015610a6a573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166376eadd366040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610ad957600080fd5b505af1158015610aed573d6000803e3d6000fd5b50505050610b2f6040518060400160405280601381526020017f636f6e7472616374206465706c6f796d656e740000000000000000000000000081525061175b565b6040517fe6962cdb000000000000000000000000000000000000000000000000000000008152621234566004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d9063e6962cdb90602401600060405180830381600087803b158015610b9757600080fd5b505af1158015610bab573d6000803e3d6000fd5b5050505060006104d2604051610bc090611a54565b908152602001604051809103906000f080158015610be2573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff1663c29855786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c549190611baf565b6104d214610c6157600080fd5b610c9f6040518060400160405280600881526020017f637265617465203200000000000000000000000000000000000000000000000081525061175b565b6040517fe6962cdb00000000000000000000000000000000000000000000000000000000815261cafe6004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d9063e6962cdb90602401600060405180830381600087803b158015610d0657600080fd5b505af1158015610d1a573d6000803e3d6000fd5b505050506000602a60001b6104d2604051610d3490611a54565b9081526020018190604051809103906000f5905080158015610d5a573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff1663c29855786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610da8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcc9190611baf565b6104d214610dd957600080fd5b610e176040518060400160405280600581526020017f646f6e652100000000000000000000000000000000000000000000000000000081525061175b565b7f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff1663afc980406040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610e8257600080fd5b505af1158015610e96573d6000803e3d6000fd5b505050506104d2604051610ea990611a54565b908152602001604051809103906000f080158015610ecb573d6000803e3d6000fd5b5050604080518082018252600981527f6e6f6e636520656e640000000000000000000000000000000000000000000000602082015290517f2d0335ab0000000000000000000000000000000000000000000000000000000081523060048201526101749190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab90602401610340565b604080517f4777f3cf0000000000000000000000000000000000000000000000000000000081526004810191909152600c60448201527f4558414d504c455f424f4f4c0000000000000000000000000000000000000000606482015260006024820181905290737109709ecfa91a80626ff3989d68f67f5b1dd12d90634777f3cf90608401602060405180830381865afa158015610ff6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061101a9190611bc8565b905061105b6040518060400160405280601381526020017f626f6f6c2076616c75652066726f6d20656e76000000000000000000000000008152508261190f565b61109a6040518060400160405280600d81526020017f636f6e7472616374206164647200000000000000000000000000000000000000815250306117ed565b604080518082018252600e81527f636f6e7472616374206e6f6e6365000000000000000000000000000000000000602082015290517f2d0335ab0000000000000000000000000000000000000000000000000000000081523060048201526111219190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab90602401610340565b6111606040518060400160405280600b81526020017f73656e6465722061646472000000000000000000000000000000000000000000815250336117ed565b604080518082018252600c81527f73656e646572206e6f6e63650000000000000000000000000000000000000000602082015290517f2d0335ab0000000000000000000000000000000000000000000000000000000081523360048201526111e79190737109709ecfa91a80626ff3989d68f67f5b1dd12d90632d0335ab90602401610340565b60408051808201825260208082527f7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d9082015290517f213e4198000000000000000000000000000000000000000000000000000000008152600090737109709ecfa91a80626ff3989d68f67f5b1dd12d9063213e41989061126c908590600401611c64565b600060405180830381865afa158015611289573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526112cf9190810190611d34565b90506113456040518060400160405280600481526020017f6b657973000000000000000000000000000000000000000000000000000000008152508260008151811061131d5761131d611e68565b60200260200101518360018151811061133857611338611e68565b60200260200101516119a0565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f66726f6d206f726967696e616c000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b1580156113c257600080fd5b505afa1580156113d6573d6000803e3d6000fd5b50506040517f06447d5600000000000000000000000000000000000000000000000000000000815260426004820152737109709ecfa91a80626ff3989d68f67f5b1dd12d92506306447d569150602401600060405180830381600087803b15801561144057600080fd5b505af1158015611454573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b20310000000000000000000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b1580156114d557600080fd5b505afa1580156114e9573d6000803e3d6000fd5b5050505061152c6040518060400160405280601781526020017f706172656e742073636f7065206d73672e73656e646572000000000000000000815250336117ed565b61156b6040518060400160405280601a81526020017f706172656e742073636f706520636f6e74726163742e61646472000000000000815250306117ed565b6040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f66726f6d207072616e6b203200000000000000000000000000000000000000006044820152309063a777d0dc9060640160006040518083038186803b1580156115e857600080fd5b505afa1580156115fc573d6000803e3d6000fd5b505050507f885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d60001c73ffffffffffffffffffffffffffffffffffffffff166390c5013b6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561166b57600080fd5b505af115801561167f573d6000803e3d6000fd5b50506040517fa777d0dc00000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f66726f6d206f726967696e616c20616761696e00000000000000000000000000604482015230925063a777d0dc915060640160006040518083038186803b15801561170057600080fd5b505afa158015611714573d6000803e3d6000fd5b505050506117566040518060400160405280600581526020017f646f6e652100000000000000000000000000000000000000000000000000000081525061175b565b505050565b6117ea8160405160240161176f9190611e97565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f41304fac00000000000000000000000000000000000000000000000000000000179052611a2f565b50565b6101748282604051602401611803929190611eaa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f319af33300000000000000000000000000000000000000000000000000000000179052611a2f565b6101748282604051602401611894929190611ee2565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb60e72cc00000000000000000000000000000000000000000000000000000000179052611a2f565b6101748282604051602401611925929190611f04565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fc3b5563500000000000000000000000000000000000000000000000000000000179052611a2f565b6117568383836040516024016119b893929190611f28565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f2ced7cef000000000000000000000000000000000000000000000000000000001790525b6117ea8180516a636f6e736f6c652e6c6f67602083016000808483855afa5050505050565b60b280611f6c83390190565b60008060208385031215611a7357600080fd5b823567ffffffffffffffff80821115611a8b57600080fd5b818501915085601f830112611a9f57600080fd5b813581811115611aae57600080fd5b866020828501011115611ac057600080fd5b60209290920196919550909350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611b2a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b600060208284031215611b9057600080fd5b815167ffffffffffffffff81168114611ba857600080fd5b9392505050565b600060208284031215611bc157600080fd5b5051919050565b600060208284031215611bda57600080fd5b81518015158114611ba857600080fd5b60005b83811015611c05578181015183820152602001611bed565b83811115611c14576000848401525b50505050565b60008151808452611c32816020860160208601611bea565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b604081526000611c776040830184611c1a565b8281036020840152600c81527f2e726f6f745f6b65795b305d000000000000000000000000000000000000000060208201526040810191505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611d2c57611d2c611cb6565b604052919050565b60006020808385031215611d4757600080fd5b825167ffffffffffffffff80821115611d5f57600080fd5b8185019150601f8681840112611d7457600080fd5b825182811115611d8657611d86611cb6565b8060051b611d95868201611ce5565b918252848101860191868101908a841115611daf57600080fd5b87870192505b83831015611e5a57825186811115611dcd5760008081fd5b8701603f81018c13611ddf5760008081fd5b88810151604088821115611df557611df5611cb6565b611e248b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08a85011601611ce5565b8281528e82848601011115611e395760008081fd5b611e48838d8301848701611bea565b85525050509187019190870190611db5565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602081526000611ba86020830184611c1a565b604081526000611ebd6040830185611c1a565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b604081526000611ef56040830185611c1a565b90508260208301529392505050565b604081526000611f176040830185611c1a565b905082151560208301529392505050565b606081526000611f3b6060830186611c1a565b8281036020840152611f4d8186611c1a565b90508281036040840152611f618185611c1a565b969550505050505056fe608060405234801561001057600080fd5b506040516100b23803806100b283398101604081905261002f91610037565b600055610050565b60006020828403121561004957600080fd5b5051919050565b60548061005e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b603560005481565b60405190815260200160405180910390f3fea164736f6c634300080f000aa164736f6c634300080f000a","sourceMap":"2541:3359:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2775:22;;;;;;;;;160:25:1;;;148:2;133:18;2775:22:0;;;;;;;5405:95;;;;;;:::i;:::-;;:::i;:::-;;5814:84;;;;;;:::i;:::-;;:::i;5607:98::-;;;;;;:::i;:::-;;:::i;5256:143::-;;;;;;:::i;:::-;;:::i;3903:1258::-;;;:::i;2887:949::-;;;:::i;5405:95::-;5459:7;:9;;;:7;:9;;;:::i;:::-;;;;;;5478:15;5490:2;;5478:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5478:11:0;;-1:-1:-1;;;5478:15:0:i;:::-;5405:95;;:::o;5814:84::-;5876:15;5888:2;;5876:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5876:11:0;;-1:-1:-1;;;5876:15:0:i;5607:98::-;5663:7;:9;;;:7;:9;;;:::i;:::-;;;;-1:-1:-1;;5682:16:0;;;;;:4;;:12;;:16;;5695:2;;;;5682:16;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5607:98;;:::o;5256:143::-;5315:15;5327:2;;5315:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5315:11:0;;-1:-1:-1;;;5315:15:0:i;:::-;5340:52;;;;;;;;;;;;;;;;;;5380:10;5340:11;:52::i;3903:1258::-;3944:63;;;;;;;;;;;;;;;;3979:26;;;;;3999:4;3979:26;;;1747:74:1;3944:63:0;;;3979:11;;;;1720:18:1;;3979:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3971:35;;3944:11;:63::i;:::-;4018:29;;;;;;;;;;;;;;;;;;:11;:29::i;:::-;2634:28;2626:37;;4057:12;;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4081:26:0;;;;;2327:2:1;4081:26:0;;;2309:21:1;2366:2;2346:18;;;2339:30;2405:14;2385:18;;;2378:42;4081:4:0;;-1:-1:-1;4081:10:0;;-1:-1:-1;2437:18:1;;4081:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4117:26:0;;;;;2668:2:1;4117:26:0;;;2650:21:1;2707:2;2687:18;;;2680:30;2746:14;2726:18;;;2719:42;4117:4:0;;-1:-1:-1;4117:10:0;;-1:-1:-1;2778:18:1;;4117:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4154:33;;;;;;;;;;;;;;;;;;:11;:33::i;:::-;4197:45;;;;;4231:8;4197:45;;;1747:74:1;4197:17:0;;;;1720:18:1;;4197:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4252:29:0;;;;;3009:2:1;4252:29:0;;;2991:21:1;3048:2;3028:18;;;3021:30;3087:17;3067:18;;;3060:45;4252:4:0;;-1:-1:-1;4252:10:0;;-1:-1:-1;3122:18:1;;4252:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4291:29:0;;;;;3353:2:1;4291:29:0;;;3335:21:1;3392:2;3372:18;;;3365:30;3431:17;3411:18;;;3404:45;4291:4:0;;-1:-1:-1;4291:10:0;;-1:-1:-1;3466:18:1;;4291:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4330:31:0;;;;;3697:2:1;4330:31:0;;;3679:21:1;3736:2;3716:18;;;3709:30;3775:16;3755:18;;;3748:44;4330:4:0;;-1:-1:-1;4330:13:0;;-1:-1:-1;3809:18:1;;4330:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2634:28;2626:37;;4371:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4399:29:0;;;;;4040:2:1;4399:29:0;;;4022:21:1;4079:2;4059:18;;;4052:30;4118:17;4098:18;;;4091:45;4399:4:0;;-1:-1:-1;4399:10:0;;-1:-1:-1;4153:18:1;;4399:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4439;;;;;;;;;;;;;;;;;;:11;:29::i;:::-;4478:43;;;;;4512:6;4478:43;;;1747:74:1;4478:17:0;;;;1720:18:1;;4478:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4531:22:0;;;;;4384:2:1;4531:22:0;;;4366:21:1;4423:1;4403:18;;;4396:29;4461:8;4441:18;;;4434:36;4531:4:0;;-1:-1:-1;4531:12:0;;-1:-1:-1;4487:18:1;;4531:22:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2634:28;2626:37;;4563:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4592:34;;;;;;;;;;;;;;;;;;:11;:34::i;:::-;4636:40;;;;;4665:8;4636:40;;;1747:74:1;4636:12:0;;;;1720:18:1;;4636:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4686:8;4708:4;4697:16;;;;;:::i;:::-;160:25:1;;;148:2;133:18;4697:16:0;;;;;;;;;;;;;;;;;;;;;;;4686:27;;4731:1;:5;;;:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4742:4;4731:15;4723:24;;;;;;4758:23;;;;;;;;;;;;;;;;;;:11;:23::i;:::-;4791:38;;;;;4820:6;4791:38;;;1747:74:1;4791:12:0;;;;1720:18:1;;4791:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4839:8;4883:2;4867:20;;4889:4;4850:44;;;;;:::i;:::-;160:25:1;;;148:2;133:18;4850:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;4839:55;;4912:1;:5;;;:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4923:4;4912:15;4904:24;;;;;;4938:20;;;;;;;;;;;;;;;;;;:11;:20::i;:::-;2634:28;2626:37;;5042:12;;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5077:4;5066:16;;;;;:::i;:::-;160:25:1;;;148:2;133:18;5066:16:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5093:61:0;;;;;;;;;;;;;;;;5126:26;;;;;5146:4;5126:26;;;1747:74:1;5093:61:0;;;5126:11;;;;1720:18:1;;5126:26:0;1601:226:1;2887:949:0;2928:31;;;;;;;;;5104:21:1;;;;5161:2;5141:18;;;5134:30;5200:14;5180:18;;;5173:42;2919:6:0;5267:20:1;;;5260:52;;;2919:6:0;2928:8;;;;5232:19:1;;2928:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2919:40;;2969:37;;;;;;;;;;;;;;;;;;3004:1;2969:11;:37::i;:::-;3017:43;;;;;;;;;;;;;;;;;;3054:4;3017:11;:43::i;:::-;3070:57;;;;;;;;;;;;;;;;3100:26;;;;;3120:4;3100:26;;;1747:74:1;3070:57:0;;;3100:11;;;;1720:18:1;;3100:26:0;1601:226:1;3070:57:0;3137:47;;;;;;;;;;;;;;;;;;3172:10;3137:11;:47::i;:::-;3194:61;;;;;;;;;;;;;;;;3222:32;;;;;3242:10;3222:32;;;1747:74:1;3194:61:0;;;3222:11;;;;1720:18:1;;3222:32:0;1601:226:1;3194:61:0;3266:55;;;;;;;;;;;;;;;;;3354:38;;;;;3266:18;;3354:16;;;;:38;;3266:55;;3354:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3331:61;;3402:37;;;;;;;;;;;;;;;;;;3422:4;3427:1;3422:7;;;;;;;;:::i;:::-;;;;;;;3431:4;3436:1;3431:7;;;;;;;;:::i;:::-;;;;;;;3402:11;:37::i;:::-;3450:27;;;;;9413:2:1;3450:27:0;;;9395:21:1;9452:2;9432:18;;;9425:30;9491:15;9471:18;;;9464:43;3450:4:0;;:10;;9524:18:1;;3450:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3487:37:0;;;;;3517:4;3487:37;;;1747:74:1;3487:13:0;;-1:-1:-1;3487:13:0;;-1:-1:-1;1720:18:1;;3487:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3534:26:0;;;;;9755:2:1;3534:26:0;;;9737:21:1;9794:2;9774:18;;;9767:30;9833:14;9813:18;;;9806:42;3534:4:0;;-1:-1:-1;3534:10:0;;-1:-1:-1;9865:18:1;;3534:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3570:59;;;;;;;;;;;;;;;;;;3617:10;3570:11;:59::i;:::-;3639:56;;;;;;;;;;;;;;;;;;3689:4;3639:11;:56::i;:::-;3705:26;;;;;10096:2:1;3705:26:0;;;10078:21:1;10135:2;10115:18;;;10108:30;10174:14;10154:18;;;10147:42;3705:4:0;;:10;;10206:18:1;;3705:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2634:28;2626:37;;3741:12;;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3765:33:0;;;;;10437:2:1;3765:33:0;;;10419:21:1;10476:2;10456:18;;;10449:30;10515:21;10495:18;;;10488:49;3765:4:0;;-1:-1:-1;3765:10:0;;-1:-1:-1;10554:18:1;;3765:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3809:20;;;;;;;;;;;;;;;;;;:11;:20::i;:::-;2909:927;;;2887:949::o;1658:121::-;1713:59;1768:2;1729:42;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1713:15;:59::i;:::-;1658:121;:::o;2081:145::-;2148:71;2211:2;2215;2164:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;2148:15;:71::i;1930:145::-;1997:71;2060:2;2064;2013:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1997:15;:71::i;1785:139::-;1849:68;1909:2;1913;1865:51;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1849:15;:68::i;2232:179::-;2323:81;2392:2;2396;2400;2339:64;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1133:133;1204:55;1251:7;1370:14;;856:42;1543:2;1530:16;;1346:21;;1370:14;1530:16;856:42;1579:5;1568:68;1559:77;;1496:150;;1272:380;:::o;-1:-1:-1:-;;;;;;;;:::o;196:592:1:-;267:6;275;328:2;316:9;307:7;303:23;299:32;296:52;;;344:1;341;334:12;296:52;384:9;371:23;413:18;454:2;446:6;443:14;440:34;;;470:1;467;460:12;440:34;508:6;497:9;493:22;483:32;;553:7;546:4;542:2;538:13;534:27;524:55;;575:1;572;565:12;524:55;615:2;602:16;641:2;633:6;630:14;627:34;;;657:1;654;647:12;627:34;702:7;697:2;688:6;684:2;680:15;676:24;673:37;670:57;;;723:1;720;713:12;670:57;754:2;746:11;;;;;776:6;;-1:-1:-1;196:592:1;;-1:-1:-1;;;;196:592:1:o;793:349::-;832:3;863:66;856:5;853:77;850:257;;963:77;960:1;953:88;1064:4;1061:1;1054:15;1092:4;1089:1;1082:15;850:257;-1:-1:-1;1134:1:1;1123:13;;793:349::o;1147:449::-;1306:2;1295:9;1288:21;1345:6;1340:2;1329:9;1325:18;1318:34;1402:6;1394;1389:2;1378:9;1374:18;1361:48;1458:1;1429:22;;;1453:2;1425:31;;;1418:42;;;;1512:2;1500:15;;;1517:66;1496:88;1481:104;1477:113;;1147:449;-1:-1:-1;1147:449:1:o;1832:288::-;1901:6;1954:2;1942:9;1933:7;1929:23;1925:32;1922:52;;;1970:1;1967;1960:12;1922:52;2002:9;1996:16;2052:18;2045:5;2041:30;2034:5;2031:41;2021:69;;2086:1;2083;2076:12;2021:69;2109:5;1832:288;-1:-1:-1;;;1832:288:1:o;4709:184::-;4779:6;4832:2;4820:9;4811:7;4807:23;4803:32;4800:52;;;4848:1;4845;4838:12;4800:52;-1:-1:-1;4871:16:1;;4709:184;-1:-1:-1;4709:184:1:o;5323:277::-;5390:6;5443:2;5431:9;5422:7;5418:23;5414:32;5411:52;;;5459:1;5456;5449:12;5411:52;5491:9;5485:16;5544:5;5537:13;5530:21;5523:5;5520:32;5510:60;;5566:1;5563;5556:12;5605:258;5677:1;5687:113;5701:6;5698:1;5695:13;5687:113;;;5777:11;;;5771:18;5758:11;;;5751:39;5723:2;5716:10;5687:113;;;5818:6;5815:1;5812:13;5809:48;;;5853:1;5844:6;5839:3;5835:16;5828:27;5809:48;;5605:258;;;:::o;5868:317::-;5910:3;5948:5;5942:12;5975:6;5970:3;5963:19;5991:63;6047:6;6040:4;6035:3;6031:14;6024:4;6017:5;6013:16;5991:63;:::i;:::-;6099:2;6087:15;6104:66;6083:88;6074:98;;;;6174:4;6070:109;;5868:317;-1:-1:-1;;5868:317:1:o;6190:493::-;6440:2;6429:9;6422:21;6403:4;6466:45;6507:2;6496:9;6492:18;6484:6;6466:45;:::i;:::-;6559:9;6551:6;6547:22;6542:2;6531:9;6527:18;6520:50;6594:2;6586:6;6579:18;6630:14;6625:2;6617:6;6613:15;6606:39;6674:2;6666:6;6662:15;6654:23;;;6190:493;;;;:::o;6688:184::-;6740:77;6737:1;6730:88;6837:4;6834:1;6827:15;6861:4;6858:1;6851:15;6877:334;6948:2;6942:9;7004:2;6994:13;;7009:66;6990:86;6978:99;;7107:18;7092:34;;7128:22;;;7089:62;7086:88;;;7154:18;;:::i;:::-;7190:2;7183:22;6877:334;;-1:-1:-1;6877:334:1:o;7216:1801::-;7321:6;7352:2;7395;7383:9;7374:7;7370:23;7366:32;7363:52;;;7411:1;7408;7401:12;7363:52;7444:9;7438:16;7473:18;7514:2;7506:6;7503:14;7500:34;;;7530:1;7527;7520:12;7500:34;7568:6;7557:9;7553:22;7543:32;;7594:4;7634:7;7629:2;7625;7621:11;7617:25;7607:53;;7656:1;7653;7646:12;7607:53;7685:2;7679:9;7707:2;7703;7700:10;7697:36;;;7713:18;;:::i;:::-;7759:2;7756:1;7752:10;7782:28;7806:2;7802;7798:11;7782:28;:::i;:::-;7844:15;;;7914:11;;;7910:20;;;7875:12;;;;7942:19;;;7939:39;;;7974:1;7971;7964:12;7939:39;8006:2;8002;7998:11;7987:22;;8018:969;8034:6;8029:3;8026:15;8018:969;;;8113:3;8107:10;8149:2;8136:11;8133:19;8130:109;;;8193:1;8222:2;8218;8211:14;8130:109;8262:20;;8317:2;8309:11;;8305:25;-1:-1:-1;8295:123:1;;8372:1;8401:2;8397;8390:14;8295:123;8456:2;8452;8448:11;8442:18;8484:2;8510;8505:3;8502:11;8499:37;;;8516:18;;:::i;:::-;8562:111;8669:2;8600:66;8595:2;8590:3;8586:12;8582:85;8578:94;8562:111;:::i;:::-;8700:3;8693:5;8686:18;8747:7;8741:3;8735;8731:2;8727:12;8723:22;8720:35;8717:128;;;8797:1;8827:3;8822;8815:16;8717:128;8858:56;8910:3;8905:2;8898:5;8894:14;8888:3;8884:2;8880:12;8858:56;:::i;:::-;8927:18;;-1:-1:-1;;;8051:12:1;;;;8965;;;;8018:969;;;9006:5;7216:1801;-1:-1:-1;;;;;;;;;;7216:1801:1:o;9022:184::-;9074:77;9071:1;9064:88;9171:4;9168:1;9161:15;9195:4;9192:1;9185:15;10583:220;10732:2;10721:9;10714:21;10695:4;10752:45;10793:2;10782:9;10778:18;10770:6;10752:45;:::i;10808:340::-;10985:2;10974:9;10967:21;10948:4;11005:45;11046:2;11035:9;11031:18;11023:6;11005:45;:::i;:::-;10997:53;;11098:42;11090:6;11086:55;11081:2;11070:9;11066:18;11059:83;10808:340;;;;;:::o;11153:291::-;11330:2;11319:9;11312:21;11293:4;11350:45;11391:2;11380:9;11376:18;11368:6;11350:45;:::i;:::-;11342:53;;11431:6;11426:2;11415:9;11411:18;11404:34;11153:291;;;;;:::o;11449:301::-;11620:2;11609:9;11602:21;11583:4;11640:45;11681:2;11670:9;11666:18;11658:6;11640:45;:::i;:::-;11632:53;;11735:6;11728:14;11721:22;11716:2;11705:9;11701:18;11694:50;11449:301;;;;;:::o;11755:546::-;12000:2;11989:9;11982:21;11963:4;12026:45;12067:2;12056:9;12052:18;12044:6;12026:45;:::i;:::-;12119:9;12111:6;12107:22;12102:2;12091:9;12087:18;12080:50;12153:33;12179:6;12171;12153:33;:::i;:::-;12139:47;;12234:9;12226:6;12222:22;12217:2;12206:9;12202:18;12195:50;12262:33;12288:6;12280;12262:33;:::i;:::-;12254:41;11755:546;-1:-1:-1;;;;;;11755:546:1:o","linkReferences":{}},"methodIdentifiers":{"call1(string)":"7e79255d","call2(string)":"8d3ef7ca","callPure(string)":"7f8b915c","counter()":"61bc221a","hello(string)":"a777d0dc","nested1(string)":"a76ccdfa","nested2(string)":"dbf1282f","run()":"c0406226","runBroadcast()":"bef03abc"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"call1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"call2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"callPure\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"counter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"hello\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"nested1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_v\",\"type\":\"string\"}],\"name\":\"nested2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"run\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"runBroadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"title\":\"ScriptExample\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"hello(string)\":{\"notice\":\"example external function, to force a CALL, and test vm.startPrank with.\"},\"run()\":{\"notice\":\"example function, runs through basic cheat-codes and console logs.\"},\"runBroadcast()\":{\"notice\":\"example function, to test vm.broadcast with.\"}},\"notice\":\"ScriptExample is an example script. The Go forge script code tests that it can run this.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"ScriptExample\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x8d1dfa41908e7ccc3a498a2a2aa51c5275bedbb904ce32d08f8598e36f896d8d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5117bb7158363cae8b9dc0508d2852692fd36172f1c699ff680afbb5acebe1f3\",\"dweb:/ipfs/QmQdahJ8SPKfJ4yea5Ge9qaj5qh1TxVffhHvaWytBaL95h\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"call1"},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"call2"},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"pure","type":"function","name":"callPure"},{"inputs":[],"stateMutability":"view","type":"function","name":"counter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"view","type":"function","name":"hello"},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"nested1"},{"inputs":[{"internalType":"string","name":"_v","type":"string"}],"stateMutability":"nonpayable","type":"function","name":"nested2"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"run"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"runBroadcast"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{"hello(string)":{"notice":"example external function, to force a CALL, and test vm.startPrank with."},"run()":{"notice":"example function, runs through basic cheat-codes and console logs."},"runBroadcast()":{"notice":"example function, to test vm.broadcast with."}},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"ScriptExample"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x8d1dfa41908e7ccc3a498a2a2aa51c5275bedbb904ce32d08f8598e36f896d8d","urls":["bzz-raw://5117bb7158363cae8b9dc0508d2852692fd36172f1c699ff680afbb5acebe1f3","dweb:/ipfs/QmQdahJ8SPKfJ4yea5Ge9qaj5qh1TxVffhHvaWytBaL95h"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[{"astId":215,"contract":"scripts/ScriptExample.s.sol:ScriptExample","label":"counter","offset":0,"slot":"0","type":"t_uint256"}],"types":{"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"userdoc":{"version":1,"kind":"user","methods":{"hello(string)":{"notice":"example external function, to force a CALL, and test vm.startPrank with."},"run()":{"notice":"example function, runs through basic cheat-codes and console logs."},"runBroadcast()":{"notice":"example function, to test vm.broadcast with."}},"notice":"ScriptExample is an example script. The Go forge script code tests that it can run this."},"devdoc":{"version":1,"kind":"dev","title":"ScriptExample"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":720,"exportedSymbols":{"FooBar":[719],"ScriptExample":[706],"Vm":[55],"console":[192]},"nodeType":"SourceUnit","src":"32:5967:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":55,"nodeType":"ContractDefinition","src":"120:616:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":55,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":38,"nodeType":"FunctionDefinition","src":"516:30:0","nodes":[],"functionSelector":"afc98040","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"525:9:0","parameters":{"id":36,"nodeType":"ParameterList","parameters":[],"src":"534:2:0"},"returnParameters":{"id":37,"nodeType":"ParameterList","parameters":[],"src":"545:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":43,"nodeType":"FunctionDefinition","src":"551:47:0","nodes":[],"functionSelector":"e6962cdb","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"560:9:0","parameters":{"id":41,"nodeType":"ParameterList","parameters":[{"constant":false,"id":40,"mutability":"mutable","name":"msgSender","nameLocation":"578:9:0","nodeType":"VariableDeclaration","scope":43,"src":"570:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":39,"name":"address","nodeType":"ElementaryTypeName","src":"570:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"569:19:0"},"returnParameters":{"id":42,"nodeType":"ParameterList","parameters":[],"src":"597:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":48,"nodeType":"FunctionDefinition","src":"603:52:0","nodes":[],"functionSelector":"7fec2a8d","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"612:14:0","parameters":{"id":46,"nodeType":"ParameterList","parameters":[{"constant":false,"id":45,"mutability":"mutable","name":"msgSender","nameLocation":"635:9:0","nodeType":"VariableDeclaration","scope":48,"src":"627:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":44,"name":"address","nodeType":"ElementaryTypeName","src":"627:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"626:19:0"},"returnParameters":{"id":47,"nodeType":"ParameterList","parameters":[],"src":"654:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":51,"nodeType":"FunctionDefinition","src":"660:35:0","nodes":[],"functionSelector":"7fb5297f","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"669:14:0","parameters":{"id":49,"nodeType":"ParameterList","parameters":[],"src":"683:2:0"},"returnParameters":{"id":50,"nodeType":"ParameterList","parameters":[],"src":"694:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":54,"nodeType":"FunctionDefinition","src":"700:34:0","nodes":[],"functionSelector":"76eadd36","implemented":false,"kind":"function","modifiers":[],"name":"stopBroadcast","nameLocation":"709:13:0","parameters":{"id":52,"nodeType":"ParameterList","parameters":[],"src":"722:2:0"},"returnParameters":{"id":53,"nodeType":"ParameterList","parameters":[],"src":"733:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[55],"name":"Vm","nameLocation":"130:2:0","scope":720,"usedErrors":[]},{"id":192,"nodeType":"ContractDefinition","src":"791:1622:0","nodes":[{"id":61,"nodeType":"VariableDeclaration","src":"813:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"830:15:0","scope":192,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":56,"name":"address","nodeType":"ElementaryTypeName","src":"813:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":59,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"856:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":58,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"848:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":57,"name":"address","nodeType":"ElementaryTypeName","src":"848:7:0","typeDescriptions":{}}},"id":60,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"848:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":78,"nodeType":"FunctionDefinition","src":"906:221:0","nodes":[],"body":{"id":77,"nodeType":"Block","src":"1065:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"1084:37:0","statements":[{"nodeType":"YulAssignment","src":"1098:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"1107:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"1098:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":67,"isOffset":false,"isSlot":false,"src":"1107:4:0","valueSize":1},{"declaration":74,"isOffset":false,"isSlot":false,"src":"1098:5:0","valueSize":1}],"id":76,"nodeType":"InlineAssembly","src":"1075:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"915:25:0","parameters":{"id":68,"nodeType":"ParameterList","parameters":[{"constant":false,"id":67,"mutability":"mutable","name":"fnIn","nameLocation":"987:4:0","nodeType":"VariableDeclaration","scope":78,"src":"950:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":66,"nodeType":"FunctionTypeName","parameterTypes":{"id":64,"nodeType":"ParameterList","parameters":[{"constant":false,"id":63,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":66,"src":"959:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":62,"name":"bytes","nodeType":"ElementaryTypeName","src":"959:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"958:14:0"},"returnParameterTypes":{"id":65,"nodeType":"ParameterList","parameters":[],"src":"987:0:0"},"src":"950:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"940:57:0"},"returnParameters":{"id":75,"nodeType":"ParameterList","parameters":[{"constant":false,"id":74,"mutability":"mutable","name":"fnOut","nameLocation":"1058:5:0","nodeType":"VariableDeclaration","scope":78,"src":"1021:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":73,"nodeType":"FunctionTypeName","parameterTypes":{"id":71,"nodeType":"ParameterList","parameters":[{"constant":false,"id":70,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":73,"src":"1030:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":69,"name":"bytes","nodeType":"ElementaryTypeName","src":"1030:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1029:14:0"},"returnParameterTypes":{"id":72,"nodeType":"ParameterList","parameters":[],"src":"1058:0:0"},"src":"1021:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"1020:44:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":90,"nodeType":"FunctionDefinition","src":"1133:133:0","nodes":[],"body":{"id":89,"nodeType":"Block","src":"1194:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":86,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1251:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":84,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":106,"src":"1230:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":83,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":78,"src":"1204:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":85,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":87,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":88,"nodeType":"ExpressionStatement","src":"1204:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"1142:15:0","parameters":{"id":81,"nodeType":"ParameterList","parameters":[{"constant":false,"id":80,"mutability":"mutable","name":"payload","nameLocation":"1171:7:0","nodeType":"VariableDeclaration","scope":90,"src":"1158:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":79,"name":"bytes","nodeType":"ElementaryTypeName","src":"1158:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1157:22:0"},"returnParameters":{"id":82,"nodeType":"ParameterList","parameters":[],"src":"1194:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":106,"nodeType":"FunctionDefinition","src":"1272:380:0","nodes":[],"body":{"id":105,"nodeType":"Block","src":"1336:316:0","nodes":[],"statements":[{"assignments":[96],"declarations":[{"constant":false,"id":96,"mutability":"mutable","name":"payloadLength","nameLocation":"1354:13:0","nodeType":"VariableDeclaration","scope":105,"src":"1346:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":95,"name":"uint256","nodeType":"ElementaryTypeName","src":"1346:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":99,"initialValue":{"expression":{"id":97,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":92,"src":"1370:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":98,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1370:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1346:38:0"},{"assignments":[101],"declarations":[{"constant":false,"id":101,"mutability":"mutable","name":"consoleAddress","nameLocation":"1402:14:0","nodeType":"VariableDeclaration","scope":105,"src":"1394:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":100,"name":"address","nodeType":"ElementaryTypeName","src":"1394:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":103,"initialValue":{"id":102,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":61,"src":"1419:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1394:40:0"},{"AST":{"nodeType":"YulBlock","src":"1496:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1510:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1534:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1543:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1530:3:0"},"nodeType":"YulFunctionCall","src":"1530:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1514:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1559:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1579:3:0"},"nodeType":"YulFunctionCall","src":"1579:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1586:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1602:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1616:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1631:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1634:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1568:10:0"},"nodeType":"YulFunctionCall","src":"1568:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1563:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":101,"isOffset":false,"isSlot":false,"src":"1586:14:0","valueSize":1},{"declaration":92,"isOffset":false,"isSlot":false,"src":"1534:7:0","valueSize":1},{"declaration":96,"isOffset":false,"isSlot":false,"src":"1616:13:0","valueSize":1}],"id":104,"nodeType":"InlineAssembly","src":"1487:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1281:19:0","parameters":{"id":93,"nodeType":"ParameterList","parameters":[{"constant":false,"id":92,"mutability":"mutable","name":"payload","nameLocation":"1314:7:0","nodeType":"VariableDeclaration","scope":106,"src":"1301:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":91,"name":"bytes","nodeType":"ElementaryTypeName","src":"1301:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1300:22:0"},"returnParameters":{"id":94,"nodeType":"ParameterList","parameters":[],"src":"1336:0:0"},"scope":192,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":120,"nodeType":"FunctionDefinition","src":"1658:121:0","nodes":[],"body":{"id":119,"nodeType":"Block","src":"1703:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":114,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1753:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":115,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":108,"src":"1768:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":112,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1729:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":113,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1729:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":116,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1729:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":111,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1713:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":117,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1713:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":118,"nodeType":"ExpressionStatement","src":"1713:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1667:3:0","parameters":{"id":109,"nodeType":"ParameterList","parameters":[{"constant":false,"id":108,"mutability":"mutable","name":"p0","nameLocation":"1685:2:0","nodeType":"VariableDeclaration","scope":120,"src":"1671:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":107,"name":"string","nodeType":"ElementaryTypeName","src":"1671:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1670:18:0"},"returnParameters":{"id":110,"nodeType":"ParameterList","parameters":[],"src":"1703:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":137,"nodeType":"FunctionDefinition","src":"1785:139:0","nodes":[],"body":{"id":136,"nodeType":"Block","src":"1839:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":130,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1889:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":131,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":122,"src":"1909:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":132,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":124,"src":"1913:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":128,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1865:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":129,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1865:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":133,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1865:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":127,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1849:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":134,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1849:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":135,"nodeType":"ExpressionStatement","src":"1849:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1794:3:0","parameters":{"id":125,"nodeType":"ParameterList","parameters":[{"constant":false,"id":122,"mutability":"mutable","name":"p0","nameLocation":"1812:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1798:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":121,"name":"string","nodeType":"ElementaryTypeName","src":"1798:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":124,"mutability":"mutable","name":"p1","nameLocation":"1821:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1816:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":123,"name":"bool","nodeType":"ElementaryTypeName","src":"1816:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1797:27:0"},"returnParameters":{"id":126,"nodeType":"ParameterList","parameters":[],"src":"1839:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":154,"nodeType":"FunctionDefinition","src":"1930:145:0","nodes":[],"body":{"id":153,"nodeType":"Block","src":"1987:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":147,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2037:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":148,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":139,"src":"2060:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":149,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":141,"src":"2064:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":145,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2013:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":146,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2013:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":150,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2013:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":144,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1997:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":151,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1997:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":152,"nodeType":"ExpressionStatement","src":"1997:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1939:3:0","parameters":{"id":142,"nodeType":"ParameterList","parameters":[{"constant":false,"id":139,"mutability":"mutable","name":"p0","nameLocation":"1957:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1943:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":138,"name":"string","nodeType":"ElementaryTypeName","src":"1943:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":141,"mutability":"mutable","name":"p1","nameLocation":"1969:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1961:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":140,"name":"uint256","nodeType":"ElementaryTypeName","src":"1961:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1942:30:0"},"returnParameters":{"id":143,"nodeType":"ParameterList","parameters":[],"src":"1987:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":171,"nodeType":"FunctionDefinition","src":"2081:145:0","nodes":[],"body":{"id":170,"nodeType":"Block","src":"2138:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":164,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2188:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":165,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":156,"src":"2211:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":166,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":158,"src":"2215:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":162,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2164:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":163,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2164:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":167,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2164:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":161,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2148:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":168,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2148:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":169,"nodeType":"ExpressionStatement","src":"2148:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2090:3:0","parameters":{"id":159,"nodeType":"ParameterList","parameters":[{"constant":false,"id":156,"mutability":"mutable","name":"p0","nameLocation":"2108:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2094:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":155,"name":"string","nodeType":"ElementaryTypeName","src":"2094:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":158,"mutability":"mutable","name":"p1","nameLocation":"2120:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2112:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":157,"name":"address","nodeType":"ElementaryTypeName","src":"2112:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"2093:30:0"},"returnParameters":{"id":160,"nodeType":"ParameterList","parameters":[],"src":"2138:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":191,"nodeType":"FunctionDefinition","src":"2232:179:0","nodes":[],"body":{"id":190,"nodeType":"Block","src":"2313:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":183,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2363:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":184,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2392:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":185,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":175,"src":"2396:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":186,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":177,"src":"2400:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":181,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2339:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":182,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2339:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":187,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2339:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":180,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2323:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":188,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2323:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":189,"nodeType":"ExpressionStatement","src":"2323:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2241:3:0","parameters":{"id":178,"nodeType":"ParameterList","parameters":[{"constant":false,"id":173,"mutability":"mutable","name":"p0","nameLocation":"2259:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2245:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":172,"name":"string","nodeType":"ElementaryTypeName","src":"2245:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":175,"mutability":"mutable","name":"p1","nameLocation":"2277:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2263:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":174,"name":"string","nodeType":"ElementaryTypeName","src":"2263:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":177,"mutability":"mutable","name":"p2","nameLocation":"2295:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2281:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":176,"name":"string","nodeType":"ElementaryTypeName","src":"2281:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2244:54:0"},"returnParameters":{"id":179,"nodeType":"ParameterList","parameters":[],"src":"2313:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[192],"name":"console","nameLocation":"799:7:0","scope":720,"usedErrors":[]},{"id":706,"nodeType":"ContractDefinition","src":"2541:3359:0","nodes":[{"id":207,"nodeType":"VariableDeclaration","src":"2571:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2597:10:0","scope":706,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":194,"name":"address","nodeType":"ElementaryTypeName","src":"2571:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2644:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":201,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2634:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":203,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2634:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":200,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2626:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":199,"name":"uint256","nodeType":"ElementaryTypeName","src":"2626:7:0","typeDescriptions":{}}},"id":204,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2626:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":198,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2618:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":197,"name":"uint160","nodeType":"ElementaryTypeName","src":"2618:7:0","typeDescriptions":{}}},"id":205,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2618:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":196,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2610:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":195,"name":"address","nodeType":"ElementaryTypeName","src":"2610:7:0","typeDescriptions":{}}},"id":206,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2610:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":213,"nodeType":"VariableDeclaration","src":"2671:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2692:2:0","scope":706,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"},"typeName":{"id":209,"nodeType":"UserDefinedTypeName","pathNode":{"id":208,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":55,"src":"2671:2:0"},"referencedDeclaration":55,"src":"2671:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"value":{"arguments":[{"id":211,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":207,"src":"2700:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":210,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":55,"src":"2697:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$55_$","typeString":"type(contract Vm)"}},"id":212,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2697:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"visibility":"internal"},{"id":215,"nodeType":"VariableDeclaration","src":"2775:22:0","nodes":[],"constant":false,"functionSelector":"61bc221a","mutability":"mutable","name":"counter","nameLocation":"2790:7:0","scope":706,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":214,"name":"uint256","nodeType":"ElementaryTypeName","src":"2775:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":378,"nodeType":"FunctionDefinition","src":"2887:949:0","nodes":[],"body":{"id":377,"nodeType":"Block","src":"2909:927:0","nodes":[],"statements":[{"assignments":[220],"declarations":[{"constant":false,"id":220,"mutability":"mutable","name":"x","nameLocation":"2924:1:0","nodeType":"VariableDeclaration","scope":377,"src":"2919:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":219,"name":"bool","nodeType":"ElementaryTypeName","src":"2919:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":226,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":223,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2937:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":224,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2953:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":221,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"2928:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":222,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2928:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":225,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2928:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2919:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":230,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2981:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":231,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":220,"src":"3004:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":227,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"2969:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":229,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":137,"src":"2969:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2969:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":233,"nodeType":"ExpressionStatement","src":"2969:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":237,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3029:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":240,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3054:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}],"id":239,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3046:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":238,"name":"address","nodeType":"ElementaryTypeName","src":"3046:7:0","typeDescriptions":{}}},"id":241,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3046:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":234,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3017:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":236,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3017:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":242,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3017:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":243,"nodeType":"ExpressionStatement","src":"3017:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":247,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3082:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":252,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3120:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}],"id":251,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3112:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":250,"name":"address","nodeType":"ElementaryTypeName","src":"3112:7:0","typeDescriptions":{}}},"id":253,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3112:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":248,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3100:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3100:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":254,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3100:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":244,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3070:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":246,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3070:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":255,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3070:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":256,"nodeType":"ExpressionStatement","src":"3070:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":260,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3149:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":263,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3172:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":264,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3172:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":262,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3164:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":261,"name":"address","nodeType":"ElementaryTypeName","src":"3164:7:0","typeDescriptions":{}}},"id":265,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3164:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":257,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3137:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":259,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3137:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":266,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3137:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":267,"nodeType":"ExpressionStatement","src":"3137:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":271,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3206:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":276,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3242:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":277,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3242:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":275,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3234:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":274,"name":"address","nodeType":"ElementaryTypeName","src":"3234:7:0","typeDescriptions":{}}},"id":278,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3234:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":272,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3222:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":273,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3222:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":279,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3222:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":268,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3194:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":270,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3194:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":280,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3194:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":281,"nodeType":"ExpressionStatement","src":"3194:61:0"},{"assignments":[283],"declarations":[{"constant":false,"id":283,"mutability":"mutable","name":"json","nameLocation":"3280:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3266:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":282,"name":"string","nodeType":"ElementaryTypeName","src":"3266:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":285,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3287:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"3266:55:0"},{"assignments":[290],"declarations":[{"constant":false,"id":290,"mutability":"mutable","name":"keys","nameLocation":"3347:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3331:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":288,"name":"string","nodeType":"ElementaryTypeName","src":"3331:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":289,"nodeType":"ArrayTypeName","src":"3331:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":296,"initialValue":{"arguments":[{"id":293,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":283,"src":"3371:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":294,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3377:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":291,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3354:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":292,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3354:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":295,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3354:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3331:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":300,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3414:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":301,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3422:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":303,"indexExpression":{"hexValue":"30","id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3427:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3422:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":304,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3431:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":306,"indexExpression":{"hexValue":"31","id":305,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3436:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3431:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":297,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3402:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":299,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":191,"src":"3402:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":307,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3402:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":308,"nodeType":"ExpressionStatement","src":"3402:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":312,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3461:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":309,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3450:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":311,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":633,"src":"3450:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":313,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3450:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":314,"nodeType":"ExpressionStatement","src":"3450:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":322,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3517:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":321,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3509:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":320,"name":"uint160","nodeType":"ElementaryTypeName","src":"3509:7:0","typeDescriptions":{}}},"id":323,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3509:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":319,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3501:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":318,"name":"address","nodeType":"ElementaryTypeName","src":"3501:7:0","typeDescriptions":{}}},"id":324,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3501:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":315,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3487:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":317,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3487:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3487:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":326,"nodeType":"ExpressionStatement","src":"3487:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":330,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3545:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":327,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3534:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":329,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":633,"src":"3534:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3534:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":332,"nodeType":"ExpressionStatement","src":"3534:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":336,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3582:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":339,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3617:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":340,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3617:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":338,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3609:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":337,"name":"address","nodeType":"ElementaryTypeName","src":"3609:7:0","typeDescriptions":{}}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3609:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":333,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3570:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":335,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3570:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3570:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3570:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3651:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":350,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3689:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}],"id":349,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3681:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":348,"name":"address","nodeType":"ElementaryTypeName","src":"3681:7:0","typeDescriptions":{}}},"id":351,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3681:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":344,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3639:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3639:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3639:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":353,"nodeType":"ExpressionStatement","src":"3639:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":357,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3716:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":354,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3705:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":356,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":633,"src":"3705:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":358,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3705:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":359,"nodeType":"ExpressionStatement","src":"3705:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":360,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3741:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":362,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3741:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":363,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3741:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":364,"nodeType":"ExpressionStatement","src":"3741:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":368,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3776:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":365,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3765:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":367,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":633,"src":"3765:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":369,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3765:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":370,"nodeType":"ExpressionStatement","src":"3765:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":374,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3821:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":371,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3809:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":373,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"3809:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":375,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3809:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":376,"nodeType":"ExpressionStatement","src":"3809:20:0"}]},"documentation":{"id":216,"nodeType":"StructuredDocumentation","src":"2804:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2896:3:0","parameters":{"id":217,"nodeType":"ParameterList","parameters":[],"src":"2899:2:0"},"returnParameters":{"id":218,"nodeType":"ParameterList","parameters":[],"src":"2909:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":609,"nodeType":"FunctionDefinition","src":"3903:1258:0","nodes":[],"body":{"id":608,"nodeType":"Block","src":"3934:1227:0","nodes":[],"statements":[{"expression":{"arguments":[{"hexValue":"6e6f6e6365207374617274","id":385,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3956:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_71efc69b9a13b6bc1e9a14d766ff01c79022262c6daa6532fb5dfb14f8511a20","typeString":"literal_string \"nonce start\""},"value":"nonce start"},{"arguments":[{"arguments":[{"arguments":[{"id":392,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3999:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}],"id":391,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3991:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":390,"name":"address","nodeType":"ElementaryTypeName","src":"3991:7:0","typeDescriptions":{}}},"id":393,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3991:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":388,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3979:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":389,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3979:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":394,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3979:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint64","typeString":"uint64"}],"id":387,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3971:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":386,"name":"uint256","nodeType":"ElementaryTypeName","src":"3971:7:0","typeDescriptions":{}}},"id":395,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3971:35:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_71efc69b9a13b6bc1e9a14d766ff01c79022262c6daa6532fb5dfb14f8511a20","typeString":"literal_string \"nonce start\""},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":382,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3944:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":384,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3944:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":396,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3944:63:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":397,"nodeType":"ExpressionStatement","src":"3944:63:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073696e676c65","id":401,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4030:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""},"value":"testing single"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""}],"expression":{"id":398,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4018:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":400,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4018:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":402,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4018:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":403,"nodeType":"ExpressionStatement","src":"4018:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":404,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4057:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":406,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"4057:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":407,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4057:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":408,"nodeType":"ExpressionStatement","src":"4057:14:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c31","id":412,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4092:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""},"value":"single_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""}],"expression":{"id":409,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4081:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":411,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":648,"src":"4081:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":413,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4081:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":414,"nodeType":"ExpressionStatement","src":"4081:26:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c32","id":418,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4128:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""},"value":"single_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""}],"expression":{"id":415,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4117:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":417,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":663,"src":"4117:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":419,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4117:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":420,"nodeType":"ExpressionStatement","src":"4117:26:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073746172742f73746f70","id":424,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4166:20:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""},"value":"testing start/stop"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""}],"expression":{"id":421,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4154:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":423,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4154:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":425,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4154:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":426,"nodeType":"ExpressionStatement","src":"4154:33:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078633066666565","id":434,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4231:8:0","typeDescriptions":{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"},"value":"0xc0ffee"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"}],"id":433,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4223:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":432,"name":"uint160","nodeType":"ElementaryTypeName","src":"4223:7:0","typeDescriptions":{}}},"id":435,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4223:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":431,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4215:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":430,"name":"address","nodeType":"ElementaryTypeName","src":"4215:7:0","typeDescriptions":{}}},"id":436,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4215:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":427,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4197:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":429,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4197:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":437,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4197:45:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":438,"nodeType":"ExpressionStatement","src":"4197:45:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c31","id":442,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4263:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""},"value":"startstop_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""}],"expression":{"id":439,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4252:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":441,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":648,"src":"4252:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":443,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4252:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":444,"nodeType":"ExpressionStatement","src":"4252:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c32","id":448,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4302:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""},"value":"startstop_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""}],"expression":{"id":445,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4291:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":447,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":663,"src":"4291:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":449,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4291:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":450,"nodeType":"ExpressionStatement","src":"4291:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f70757265","id":454,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4344:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""},"value":"startstop_pure"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""}],"expression":{"id":451,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4330:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":453,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"callPure","nodeType":"MemberAccess","referencedDeclaration":705,"src":"4330:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure external"}},"id":455,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4330:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":456,"nodeType":"ExpressionStatement","src":"4330:31:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":457,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4371:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":459,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4371:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":460,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4371:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":461,"nodeType":"ExpressionStatement","src":"4371:18:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c33","id":465,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4410:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""},"value":"startstop_call3"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""}],"expression":{"id":462,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4399:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":464,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":648,"src":"4399:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":466,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4399:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":467,"nodeType":"ExpressionStatement","src":"4399:29:0"},{"expression":{"arguments":[{"hexValue":"74657374696e67206e6573746564","id":471,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4451:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""},"value":"testing nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""}],"expression":{"id":468,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4439:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":470,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4439:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":472,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4439:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":473,"nodeType":"ExpressionStatement","src":"4439:29:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307831323334","id":481,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4512:6:0","typeDescriptions":{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"},"value":"0x1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"}],"id":480,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4504:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":479,"name":"uint160","nodeType":"ElementaryTypeName","src":"4504:7:0","typeDescriptions":{}}},"id":482,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4504:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":478,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4496:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":477,"name":"address","nodeType":"ElementaryTypeName","src":"4496:7:0","typeDescriptions":{}}},"id":483,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4496:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":474,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4478:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":476,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4478:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":484,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4478:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":485,"nodeType":"ExpressionStatement","src":"4478:43:0"},{"expression":{"arguments":[{"hexValue":"6e6573746564","id":489,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4544:8:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""},"value":"nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""}],"expression":{"id":486,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4531:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":488,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested1","nodeType":"MemberAccess","referencedDeclaration":678,"src":"4531:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":490,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4531:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":491,"nodeType":"ExpressionStatement","src":"4531:22:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":492,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4563:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":494,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4563:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":495,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4563:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":496,"nodeType":"ExpressionStatement","src":"4563:18:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206465706c6f796d656e74","id":500,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4604:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""},"value":"contract deployment"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""}],"expression":{"id":497,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4592:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":499,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4592:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":501,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4592:34:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":502,"nodeType":"ExpressionStatement","src":"4592:34:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078313233343536","id":510,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4665:8:0","typeDescriptions":{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"},"value":"0x123456"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"}],"id":509,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4657:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":508,"name":"uint160","nodeType":"ElementaryTypeName","src":"4657:7:0","typeDescriptions":{}}},"id":511,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4657:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":507,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4649:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":506,"name":"address","nodeType":"ElementaryTypeName","src":"4649:7:0","typeDescriptions":{}}},"id":512,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4649:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":503,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4636:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":505,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4636:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":513,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4636:40:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":514,"nodeType":"ExpressionStatement","src":"4636:40:0"},{"assignments":[517],"declarations":[{"constant":false,"id":517,"mutability":"mutable","name":"x","nameLocation":"4693:1:0","nodeType":"VariableDeclaration","scope":608,"src":"4686:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"},"typeName":{"id":516,"nodeType":"UserDefinedTypeName","pathNode":{"id":515,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":719,"src":"4686:6:0"},"referencedDeclaration":719,"src":"4686:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"visibility":"internal"}],"id":523,"initialValue":{"arguments":[{"hexValue":"31323334","id":521,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4708:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":520,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4697:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$719_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":519,"nodeType":"UserDefinedTypeName","pathNode":{"id":518,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":719,"src":"4701:6:0"},"referencedDeclaration":719,"src":"4701:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}}},"id":522,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4697:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4686:27:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":529,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":525,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":517,"src":"4731:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"id":526,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":708,"src":"4731:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":527,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4731:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":528,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4742:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4731:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":524,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4723:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":530,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4723:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":531,"nodeType":"ExpressionStatement","src":"4723:24:0"},{"expression":{"arguments":[{"hexValue":"6372656174652032","id":535,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4770:10:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""},"value":"create 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""}],"expression":{"id":532,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4758:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":534,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4758:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":536,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4758:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":537,"nodeType":"ExpressionStatement","src":"4758:23:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307863616665","id":545,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4820:6:0","typeDescriptions":{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"},"value":"0xcafe"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"}],"id":544,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4812:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":543,"name":"uint160","nodeType":"ElementaryTypeName","src":"4812:7:0","typeDescriptions":{}}},"id":546,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4812:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":542,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4804:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":541,"name":"address","nodeType":"ElementaryTypeName","src":"4804:7:0","typeDescriptions":{}}},"id":547,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4804:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":538,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4791:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":540,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4791:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":548,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4791:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":549,"nodeType":"ExpressionStatement","src":"4791:38:0"},{"assignments":[552],"declarations":[{"constant":false,"id":552,"mutability":"mutable","name":"y","nameLocation":"4846:1:0","nodeType":"VariableDeclaration","scope":608,"src":"4839:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"},"typeName":{"id":551,"nodeType":"UserDefinedTypeName","pathNode":{"id":550,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":719,"src":"4839:6:0"},"referencedDeclaration":719,"src":"4839:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"visibility":"internal"}],"id":566,"initialValue":{"arguments":[{"hexValue":"31323334","id":564,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4889:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":555,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4850:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$719_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":554,"nodeType":"UserDefinedTypeName","pathNode":{"id":553,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":719,"src":"4854:6:0"},"referencedDeclaration":719,"src":"4854:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}}},"id":563,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"names":["salt"],"nodeType":"FunctionCallOptions","options":[{"arguments":[{"arguments":[{"hexValue":"3432","id":560,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4883:2:0","typeDescriptions":{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"},"value":"42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"}],"id":559,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4875:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":558,"name":"uint256","nodeType":"ElementaryTypeName","src":"4875:7:0","typeDescriptions":{}}},"id":561,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4875:11:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":557,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4867:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_bytes32_$","typeString":"type(bytes32)"},"typeName":{"id":556,"name":"bytes32","nodeType":"ElementaryTypeName","src":"4867:7:0","typeDescriptions":{}}},"id":562,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4867:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"src":"4850:38:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$719_$salt","typeString":"function (uint256) returns (contract FooBar)"}},"id":565,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4850:44:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4839:55:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":572,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":568,"name":"y","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":552,"src":"4912:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"id":569,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":708,"src":"4912:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":570,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4912:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":571,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4923:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4912:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":567,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4904:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":573,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4904:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":574,"nodeType":"ExpressionStatement","src":"4904:24:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":578,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4950:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":575,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4938:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":577,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4938:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":579,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4938:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":580,"nodeType":"ExpressionStatement","src":"4938:20:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":581,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"5042:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":583,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"5042:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":584,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5042:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":585,"nodeType":"ExpressionStatement","src":"5042:14:0"},{"expression":{"arguments":[{"hexValue":"31323334","id":589,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"5077:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":588,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"5066:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$719_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":587,"nodeType":"UserDefinedTypeName","pathNode":{"id":586,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":719,"src":"5070:6:0"},"referencedDeclaration":719,"src":"5070:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}}},"id":590,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5066:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"id":591,"nodeType":"ExpressionStatement","src":"5066:16:0"},{"expression":{"arguments":[{"hexValue":"6e6f6e636520656e64","id":595,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"5105:11:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa629e6661ad2a2bdb09cf9a3a276ce0d722482ae5c2887650751be0938847e8","typeString":"literal_string \"nonce end\""},"value":"nonce end"},{"arguments":[{"arguments":[{"arguments":[{"id":602,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"5146:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}],"id":601,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5138:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":600,"name":"address","nodeType":"ElementaryTypeName","src":"5138:7:0","typeDescriptions":{}}},"id":603,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5138:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":598,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"5126:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":599,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"5126:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":604,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5126:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint64","typeString":"uint64"}],"id":597,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5118:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":596,"name":"uint256","nodeType":"ElementaryTypeName","src":"5118:7:0","typeDescriptions":{}}},"id":605,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5118:35:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa629e6661ad2a2bdb09cf9a3a276ce0d722482ae5c2887650751be0938847e8","typeString":"literal_string \"nonce end\""},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":592,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5093:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":594,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"5093:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":606,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5093:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":607,"nodeType":"ExpressionStatement","src":"5093:61:0"}]},"documentation":{"id":379,"nodeType":"StructuredDocumentation","src":"3842:56:0","text":"@notice example function, to test vm.broadcast with."},"functionSelector":"bef03abc","implemented":true,"kind":"function","modifiers":[],"name":"runBroadcast","nameLocation":"3912:12:0","parameters":{"id":380,"nodeType":"ParameterList","parameters":[],"src":"3924:2:0"},"returnParameters":{"id":381,"nodeType":"ParameterList","parameters":[],"src":"3934:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":633,"nodeType":"FunctionDefinition","src":"5256:143:0","nodes":[],"body":{"id":632,"nodeType":"Block","src":"5305:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":618,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":612,"src":"5327:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":615,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5315:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":617,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5315:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":619,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5315:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":620,"nodeType":"ExpressionStatement","src":"5315:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":624,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"5352:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":627,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"5380:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":628,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"5380:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":626,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5372:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":625,"name":"address","nodeType":"ElementaryTypeName","src":"5372:7:0","typeDescriptions":{}}},"id":629,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5372:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":621,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5340:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":623,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"5340:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":630,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5340:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":631,"nodeType":"ExpressionStatement","src":"5340:52:0"}]},"documentation":{"id":610,"nodeType":"StructuredDocumentation","src":"5167:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"5265:5:0","parameters":{"id":613,"nodeType":"ParameterList","parameters":[{"constant":false,"id":612,"mutability":"mutable","name":"_v","nameLocation":"5287:2:0","nodeType":"VariableDeclaration","scope":633,"src":"5271:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":611,"name":"string","nodeType":"ElementaryTypeName","src":"5271:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5270:20:0"},"returnParameters":{"id":614,"nodeType":"ParameterList","parameters":[],"src":"5305:0:0"},"scope":706,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":648,"nodeType":"FunctionDefinition","src":"5405:95:0","nodes":[],"body":{"id":647,"nodeType":"Block","src":"5449:51:0","nodes":[],"statements":[{"expression":{"id":639,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5459:9:0","subExpression":{"id":638,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5459:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":640,"nodeType":"ExpressionStatement","src":"5459:9:0"},{"expression":{"arguments":[{"id":644,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":635,"src":"5490:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":641,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5478:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":643,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5478:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":645,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5478:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":646,"nodeType":"ExpressionStatement","src":"5478:15:0"}]},"functionSelector":"7e79255d","implemented":true,"kind":"function","modifiers":[],"name":"call1","nameLocation":"5414:5:0","parameters":{"id":636,"nodeType":"ParameterList","parameters":[{"constant":false,"id":635,"mutability":"mutable","name":"_v","nameLocation":"5436:2:0","nodeType":"VariableDeclaration","scope":648,"src":"5420:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":634,"name":"string","nodeType":"ElementaryTypeName","src":"5420:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5419:20:0"},"returnParameters":{"id":637,"nodeType":"ParameterList","parameters":[],"src":"5449:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":663,"nodeType":"FunctionDefinition","src":"5506:95:0","nodes":[],"body":{"id":662,"nodeType":"Block","src":"5550:51:0","nodes":[],"statements":[{"expression":{"id":654,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5560:9:0","subExpression":{"id":653,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5560:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":655,"nodeType":"ExpressionStatement","src":"5560:9:0"},{"expression":{"arguments":[{"id":659,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":650,"src":"5591:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":656,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5579:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":658,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5579:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":660,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5579:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":661,"nodeType":"ExpressionStatement","src":"5579:15:0"}]},"functionSelector":"8d3ef7ca","implemented":true,"kind":"function","modifiers":[],"name":"call2","nameLocation":"5515:5:0","parameters":{"id":651,"nodeType":"ParameterList","parameters":[{"constant":false,"id":650,"mutability":"mutable","name":"_v","nameLocation":"5537:2:0","nodeType":"VariableDeclaration","scope":663,"src":"5521:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":649,"name":"string","nodeType":"ElementaryTypeName","src":"5521:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5520:20:0"},"returnParameters":{"id":652,"nodeType":"ParameterList","parameters":[],"src":"5550:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":678,"nodeType":"FunctionDefinition","src":"5607:98:0","nodes":[],"body":{"id":677,"nodeType":"Block","src":"5653:52:0","nodes":[],"statements":[{"expression":{"id":669,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5663:9:0","subExpression":{"id":668,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5663:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":670,"nodeType":"ExpressionStatement","src":"5663:9:0"},{"expression":{"arguments":[{"id":674,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":665,"src":"5695:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":671,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"5682:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":673,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested2","nodeType":"MemberAccess","referencedDeclaration":693,"src":"5682:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":675,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5682:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":676,"nodeType":"ExpressionStatement","src":"5682:16:0"}]},"functionSelector":"a76ccdfa","implemented":true,"kind":"function","modifiers":[],"name":"nested1","nameLocation":"5616:7:0","parameters":{"id":666,"nodeType":"ParameterList","parameters":[{"constant":false,"id":665,"mutability":"mutable","name":"_v","nameLocation":"5640:2:0","nodeType":"VariableDeclaration","scope":678,"src":"5624:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":664,"name":"string","nodeType":"ElementaryTypeName","src":"5624:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5623:20:0"},"returnParameters":{"id":667,"nodeType":"ParameterList","parameters":[],"src":"5653:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":693,"nodeType":"FunctionDefinition","src":"5711:97:0","nodes":[],"body":{"id":692,"nodeType":"Block","src":"5757:51:0","nodes":[],"statements":[{"expression":{"id":684,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5767:9:0","subExpression":{"id":683,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5767:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":685,"nodeType":"ExpressionStatement","src":"5767:9:0"},{"expression":{"arguments":[{"id":689,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":680,"src":"5798:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":686,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5786:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":688,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5786:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":690,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5786:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":691,"nodeType":"ExpressionStatement","src":"5786:15:0"}]},"functionSelector":"dbf1282f","implemented":true,"kind":"function","modifiers":[],"name":"nested2","nameLocation":"5720:7:0","parameters":{"id":681,"nodeType":"ParameterList","parameters":[{"constant":false,"id":680,"mutability":"mutable","name":"_v","nameLocation":"5744:2:0","nodeType":"VariableDeclaration","scope":693,"src":"5728:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":679,"name":"string","nodeType":"ElementaryTypeName","src":"5728:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5727:20:0"},"returnParameters":{"id":682,"nodeType":"ParameterList","parameters":[],"src":"5757:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":705,"nodeType":"FunctionDefinition","src":"5814:84:0","nodes":[],"body":{"id":704,"nodeType":"Block","src":"5866:32:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":701,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":695,"src":"5888:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":698,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5876:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":700,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5876:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":702,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5876:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":703,"nodeType":"ExpressionStatement","src":"5876:15:0"}]},"functionSelector":"7f8b915c","implemented":true,"kind":"function","modifiers":[],"name":"callPure","nameLocation":"5823:8:0","parameters":{"id":696,"nodeType":"ParameterList","parameters":[{"constant":false,"id":695,"mutability":"mutable","name":"_v","nameLocation":"5848:2:0","nodeType":"VariableDeclaration","scope":705,"src":"5832:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":694,"name":"string","nodeType":"ElementaryTypeName","src":"5832:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5831:20:0"},"returnParameters":{"id":697,"nodeType":"ParameterList","parameters":[],"src":"5866:0:0"},"scope":706,"stateMutability":"pure","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[719],"contractKind":"contract","documentation":{"id":193,"nodeType":"StructuredDocumentation","src":"2415:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[706],"name":"ScriptExample","nameLocation":"2550:13:0","scope":720,"usedErrors":[]},{"id":719,"nodeType":"ContractDefinition","src":"5902:96:0","nodes":[{"id":708,"nodeType":"VariableDeclaration","src":"5924:18:0","nodes":[],"constant":false,"functionSelector":"c2985578","mutability":"mutable","name":"foo","nameLocation":"5939:3:0","scope":719,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":707,"name":"uint256","nodeType":"ElementaryTypeName","src":"5924:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":718,"nodeType":"FunctionDefinition","src":"5949:47:0","nodes":[],"body":{"id":717,"nodeType":"Block","src":"5972:24:0","nodes":[],"statements":[{"expression":{"id":715,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":713,"name":"foo","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":708,"src":"5982:3:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":714,"name":"v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":710,"src":"5988:1:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5982:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":716,"nodeType":"ExpressionStatement","src":"5982:7:0"}]},"implemented":true,"kind":"constructor","modifiers":[],"name":"","nameLocation":"-1:-1:-1","parameters":{"id":711,"nodeType":"ParameterList","parameters":[{"constant":false,"id":710,"mutability":"mutable","name":"v","nameLocation":"5969:1:0","nodeType":"VariableDeclaration","scope":718,"src":"5961:9:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":709,"name":"uint256","nodeType":"ElementaryTypeName","src":"5961:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"5960:11:0"},"returnParameters":{"id":712,"nodeType":"ParameterList","parameters":[],"src":"5972:0:0"},"scope":719,"stateMutability":"nonpayable","virtual":false,"visibility":"public"}],"abstract":false,"baseContracts":[],"canonicalName":"FooBar","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[719],"name":"FooBar","nameLocation":"5911:6:0","scope":720,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file diff --git a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/Vm.json b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/Vm.json index dd1f6760babb..34175684c5aa 100644 --- a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/Vm.json +++ b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/Vm.json @@ -1 +1 @@ -{"abi":[{"type":"function","name":"broadcast","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"broadcast","inputs":[{"name":"msgSender","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"envOr","inputs":[{"name":"name","type":"string","internalType":"string"},{"name":"defaultValue","type":"bool","internalType":"bool"}],"outputs":[{"name":"value","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"getNonce","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"nonce","type":"uint64","internalType":"uint64"}],"stateMutability":"view"},{"type":"function","name":"parseJsonKeys","inputs":[{"name":"json","type":"string","internalType":"string"},{"name":"key","type":"string","internalType":"string"}],"outputs":[{"name":"keys","type":"string[]","internalType":"string[]"}],"stateMutability":"pure"},{"type":"function","name":"startBroadcast","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"startBroadcast","inputs":[{"name":"msgSender","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"startPrank","inputs":[{"name":"msgSender","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"stopBroadcast","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"stopPrank","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{"broadcast()":"afc98040","broadcast(address)":"e6962cdb","envOr(string,bool)":"4777f3cf","getNonce(address)":"2d0335ab","parseJsonKeys(string,string)":"213e4198","startBroadcast()":"7fb5297f","startBroadcast(address)":"7fec2a8d","startPrank(address)":"06447d56","stopBroadcast()":"76eadd36","stopPrank()":"90c5013b"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"broadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"msgSender\",\"type\":\"address\"}],\"name\":\"broadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"defaultValue\",\"type\":\"bool\"}],\"name\":\"envOr\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"json\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"}],\"name\":\"parseJsonKeys\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"keys\",\"type\":\"string[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startBroadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"msgSender\",\"type\":\"address\"}],\"name\":\"startBroadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"msgSender\",\"type\":\"address\"}],\"name\":\"startPrank\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stopBroadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stopPrank\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"Vm\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x4fc2ffeba31e146fc3a2edef7cc8b7e82fb2344454d32d6371a62c6d76dfcb4e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a517c69eba90ee5f3efb198a2247d5744bed8e17d332ce2dda4d3cf3a2c334f9\",\"dweb:/ipfs/QmciXeDt5EEhmjH5xECVk2VX6EbnER5UFv58dvGgemwkKK\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"broadcast"},{"inputs":[{"internalType":"address","name":"msgSender","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"broadcast"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"bool","name":"defaultValue","type":"bool"}],"stateMutability":"view","type":"function","name":"envOr","outputs":[{"internalType":"bool","name":"value","type":"bool"}]},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"stateMutability":"view","type":"function","name":"getNonce","outputs":[{"internalType":"uint64","name":"nonce","type":"uint64"}]},{"inputs":[{"internalType":"string","name":"json","type":"string"},{"internalType":"string","name":"key","type":"string"}],"stateMutability":"pure","type":"function","name":"parseJsonKeys","outputs":[{"internalType":"string[]","name":"keys","type":"string[]"}]},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"startBroadcast"},{"inputs":[{"internalType":"address","name":"msgSender","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"startBroadcast"},{"inputs":[{"internalType":"address","name":"msgSender","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"startPrank"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"stopBroadcast"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"stopPrank"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"Vm"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x4fc2ffeba31e146fc3a2edef7cc8b7e82fb2344454d32d6371a62c6d76dfcb4e","urls":["bzz-raw://a517c69eba90ee5f3efb198a2247d5744bed8e17d332ce2dda4d3cf3a2c334f9","dweb:/ipfs/QmciXeDt5EEhmjH5xECVk2VX6EbnER5UFv58dvGgemwkKK"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[],"types":{}},"userdoc":{"version":1,"kind":"user"},"devdoc":{"version":1,"kind":"dev"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":677,"exportedSymbols":{"FooBar":[676],"ScriptExample":[663],"Vm":[55],"console":[192]},"nodeType":"SourceUnit","src":"32:5697:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":55,"nodeType":"ContractDefinition","src":"120:616:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":55,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":38,"nodeType":"FunctionDefinition","src":"516:30:0","nodes":[],"functionSelector":"afc98040","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"525:9:0","parameters":{"id":36,"nodeType":"ParameterList","parameters":[],"src":"534:2:0"},"returnParameters":{"id":37,"nodeType":"ParameterList","parameters":[],"src":"545:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":43,"nodeType":"FunctionDefinition","src":"551:47:0","nodes":[],"functionSelector":"e6962cdb","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"560:9:0","parameters":{"id":41,"nodeType":"ParameterList","parameters":[{"constant":false,"id":40,"mutability":"mutable","name":"msgSender","nameLocation":"578:9:0","nodeType":"VariableDeclaration","scope":43,"src":"570:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":39,"name":"address","nodeType":"ElementaryTypeName","src":"570:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"569:19:0"},"returnParameters":{"id":42,"nodeType":"ParameterList","parameters":[],"src":"597:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":48,"nodeType":"FunctionDefinition","src":"603:52:0","nodes":[],"functionSelector":"7fec2a8d","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"612:14:0","parameters":{"id":46,"nodeType":"ParameterList","parameters":[{"constant":false,"id":45,"mutability":"mutable","name":"msgSender","nameLocation":"635:9:0","nodeType":"VariableDeclaration","scope":48,"src":"627:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":44,"name":"address","nodeType":"ElementaryTypeName","src":"627:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"626:19:0"},"returnParameters":{"id":47,"nodeType":"ParameterList","parameters":[],"src":"654:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":51,"nodeType":"FunctionDefinition","src":"660:35:0","nodes":[],"functionSelector":"7fb5297f","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"669:14:0","parameters":{"id":49,"nodeType":"ParameterList","parameters":[],"src":"683:2:0"},"returnParameters":{"id":50,"nodeType":"ParameterList","parameters":[],"src":"694:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":54,"nodeType":"FunctionDefinition","src":"700:34:0","nodes":[],"functionSelector":"76eadd36","implemented":false,"kind":"function","modifiers":[],"name":"stopBroadcast","nameLocation":"709:13:0","parameters":{"id":52,"nodeType":"ParameterList","parameters":[],"src":"722:2:0"},"returnParameters":{"id":53,"nodeType":"ParameterList","parameters":[],"src":"733:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[55],"name":"Vm","nameLocation":"130:2:0","scope":677,"usedErrors":[]},{"id":192,"nodeType":"ContractDefinition","src":"791:1622:0","nodes":[{"id":61,"nodeType":"VariableDeclaration","src":"813:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"830:15:0","scope":192,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":56,"name":"address","nodeType":"ElementaryTypeName","src":"813:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":59,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"856:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":58,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"848:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":57,"name":"address","nodeType":"ElementaryTypeName","src":"848:7:0","typeDescriptions":{}}},"id":60,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"848:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":78,"nodeType":"FunctionDefinition","src":"906:221:0","nodes":[],"body":{"id":77,"nodeType":"Block","src":"1065:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"1084:37:0","statements":[{"nodeType":"YulAssignment","src":"1098:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"1107:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"1098:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":67,"isOffset":false,"isSlot":false,"src":"1107:4:0","valueSize":1},{"declaration":74,"isOffset":false,"isSlot":false,"src":"1098:5:0","valueSize":1}],"id":76,"nodeType":"InlineAssembly","src":"1075:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"915:25:0","parameters":{"id":68,"nodeType":"ParameterList","parameters":[{"constant":false,"id":67,"mutability":"mutable","name":"fnIn","nameLocation":"987:4:0","nodeType":"VariableDeclaration","scope":78,"src":"950:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":66,"nodeType":"FunctionTypeName","parameterTypes":{"id":64,"nodeType":"ParameterList","parameters":[{"constant":false,"id":63,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":66,"src":"959:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":62,"name":"bytes","nodeType":"ElementaryTypeName","src":"959:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"958:14:0"},"returnParameterTypes":{"id":65,"nodeType":"ParameterList","parameters":[],"src":"987:0:0"},"src":"950:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"940:57:0"},"returnParameters":{"id":75,"nodeType":"ParameterList","parameters":[{"constant":false,"id":74,"mutability":"mutable","name":"fnOut","nameLocation":"1058:5:0","nodeType":"VariableDeclaration","scope":78,"src":"1021:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":73,"nodeType":"FunctionTypeName","parameterTypes":{"id":71,"nodeType":"ParameterList","parameters":[{"constant":false,"id":70,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":73,"src":"1030:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":69,"name":"bytes","nodeType":"ElementaryTypeName","src":"1030:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1029:14:0"},"returnParameterTypes":{"id":72,"nodeType":"ParameterList","parameters":[],"src":"1058:0:0"},"src":"1021:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"1020:44:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":90,"nodeType":"FunctionDefinition","src":"1133:133:0","nodes":[],"body":{"id":89,"nodeType":"Block","src":"1194:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":86,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1251:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":84,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":106,"src":"1230:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":83,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":78,"src":"1204:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":85,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":87,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":88,"nodeType":"ExpressionStatement","src":"1204:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"1142:15:0","parameters":{"id":81,"nodeType":"ParameterList","parameters":[{"constant":false,"id":80,"mutability":"mutable","name":"payload","nameLocation":"1171:7:0","nodeType":"VariableDeclaration","scope":90,"src":"1158:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":79,"name":"bytes","nodeType":"ElementaryTypeName","src":"1158:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1157:22:0"},"returnParameters":{"id":82,"nodeType":"ParameterList","parameters":[],"src":"1194:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":106,"nodeType":"FunctionDefinition","src":"1272:380:0","nodes":[],"body":{"id":105,"nodeType":"Block","src":"1336:316:0","nodes":[],"statements":[{"assignments":[96],"declarations":[{"constant":false,"id":96,"mutability":"mutable","name":"payloadLength","nameLocation":"1354:13:0","nodeType":"VariableDeclaration","scope":105,"src":"1346:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":95,"name":"uint256","nodeType":"ElementaryTypeName","src":"1346:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":99,"initialValue":{"expression":{"id":97,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":92,"src":"1370:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":98,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1370:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1346:38:0"},{"assignments":[101],"declarations":[{"constant":false,"id":101,"mutability":"mutable","name":"consoleAddress","nameLocation":"1402:14:0","nodeType":"VariableDeclaration","scope":105,"src":"1394:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":100,"name":"address","nodeType":"ElementaryTypeName","src":"1394:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":103,"initialValue":{"id":102,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":61,"src":"1419:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1394:40:0"},{"AST":{"nodeType":"YulBlock","src":"1496:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1510:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1534:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1543:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1530:3:0"},"nodeType":"YulFunctionCall","src":"1530:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1514:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1559:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1579:3:0"},"nodeType":"YulFunctionCall","src":"1579:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1586:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1602:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1616:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1631:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1634:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1568:10:0"},"nodeType":"YulFunctionCall","src":"1568:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1563:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":101,"isOffset":false,"isSlot":false,"src":"1586:14:0","valueSize":1},{"declaration":92,"isOffset":false,"isSlot":false,"src":"1534:7:0","valueSize":1},{"declaration":96,"isOffset":false,"isSlot":false,"src":"1616:13:0","valueSize":1}],"id":104,"nodeType":"InlineAssembly","src":"1487:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1281:19:0","parameters":{"id":93,"nodeType":"ParameterList","parameters":[{"constant":false,"id":92,"mutability":"mutable","name":"payload","nameLocation":"1314:7:0","nodeType":"VariableDeclaration","scope":106,"src":"1301:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":91,"name":"bytes","nodeType":"ElementaryTypeName","src":"1301:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1300:22:0"},"returnParameters":{"id":94,"nodeType":"ParameterList","parameters":[],"src":"1336:0:0"},"scope":192,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":120,"nodeType":"FunctionDefinition","src":"1658:121:0","nodes":[],"body":{"id":119,"nodeType":"Block","src":"1703:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":114,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1753:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":115,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":108,"src":"1768:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":112,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1729:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":113,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1729:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":116,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1729:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":111,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1713:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":117,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1713:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":118,"nodeType":"ExpressionStatement","src":"1713:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1667:3:0","parameters":{"id":109,"nodeType":"ParameterList","parameters":[{"constant":false,"id":108,"mutability":"mutable","name":"p0","nameLocation":"1685:2:0","nodeType":"VariableDeclaration","scope":120,"src":"1671:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":107,"name":"string","nodeType":"ElementaryTypeName","src":"1671:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1670:18:0"},"returnParameters":{"id":110,"nodeType":"ParameterList","parameters":[],"src":"1703:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":137,"nodeType":"FunctionDefinition","src":"1785:139:0","nodes":[],"body":{"id":136,"nodeType":"Block","src":"1839:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":130,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1889:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":131,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":122,"src":"1909:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":132,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":124,"src":"1913:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":128,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1865:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":129,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1865:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":133,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1865:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":127,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1849:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":134,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1849:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":135,"nodeType":"ExpressionStatement","src":"1849:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1794:3:0","parameters":{"id":125,"nodeType":"ParameterList","parameters":[{"constant":false,"id":122,"mutability":"mutable","name":"p0","nameLocation":"1812:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1798:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":121,"name":"string","nodeType":"ElementaryTypeName","src":"1798:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":124,"mutability":"mutable","name":"p1","nameLocation":"1821:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1816:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":123,"name":"bool","nodeType":"ElementaryTypeName","src":"1816:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1797:27:0"},"returnParameters":{"id":126,"nodeType":"ParameterList","parameters":[],"src":"1839:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":154,"nodeType":"FunctionDefinition","src":"1930:145:0","nodes":[],"body":{"id":153,"nodeType":"Block","src":"1987:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":147,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2037:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":148,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":139,"src":"2060:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":149,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":141,"src":"2064:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":145,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2013:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":146,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2013:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":150,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2013:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":144,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1997:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":151,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1997:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":152,"nodeType":"ExpressionStatement","src":"1997:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1939:3:0","parameters":{"id":142,"nodeType":"ParameterList","parameters":[{"constant":false,"id":139,"mutability":"mutable","name":"p0","nameLocation":"1957:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1943:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":138,"name":"string","nodeType":"ElementaryTypeName","src":"1943:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":141,"mutability":"mutable","name":"p1","nameLocation":"1969:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1961:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":140,"name":"uint256","nodeType":"ElementaryTypeName","src":"1961:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1942:30:0"},"returnParameters":{"id":143,"nodeType":"ParameterList","parameters":[],"src":"1987:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":171,"nodeType":"FunctionDefinition","src":"2081:145:0","nodes":[],"body":{"id":170,"nodeType":"Block","src":"2138:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":164,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2188:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":165,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":156,"src":"2211:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":166,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":158,"src":"2215:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":162,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2164:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":163,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2164:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":167,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2164:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":161,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2148:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":168,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2148:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":169,"nodeType":"ExpressionStatement","src":"2148:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2090:3:0","parameters":{"id":159,"nodeType":"ParameterList","parameters":[{"constant":false,"id":156,"mutability":"mutable","name":"p0","nameLocation":"2108:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2094:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":155,"name":"string","nodeType":"ElementaryTypeName","src":"2094:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":158,"mutability":"mutable","name":"p1","nameLocation":"2120:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2112:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":157,"name":"address","nodeType":"ElementaryTypeName","src":"2112:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"2093:30:0"},"returnParameters":{"id":160,"nodeType":"ParameterList","parameters":[],"src":"2138:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":191,"nodeType":"FunctionDefinition","src":"2232:179:0","nodes":[],"body":{"id":190,"nodeType":"Block","src":"2313:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":183,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2363:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":184,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2392:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":185,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":175,"src":"2396:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":186,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":177,"src":"2400:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":181,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2339:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":182,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2339:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":187,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2339:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":180,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2323:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":188,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2323:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":189,"nodeType":"ExpressionStatement","src":"2323:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2241:3:0","parameters":{"id":178,"nodeType":"ParameterList","parameters":[{"constant":false,"id":173,"mutability":"mutable","name":"p0","nameLocation":"2259:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2245:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":172,"name":"string","nodeType":"ElementaryTypeName","src":"2245:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":175,"mutability":"mutable","name":"p1","nameLocation":"2277:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2263:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":174,"name":"string","nodeType":"ElementaryTypeName","src":"2263:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":177,"mutability":"mutable","name":"p2","nameLocation":"2295:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2281:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":176,"name":"string","nodeType":"ElementaryTypeName","src":"2281:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2244:54:0"},"returnParameters":{"id":179,"nodeType":"ParameterList","parameters":[],"src":"2313:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[192],"name":"console","nameLocation":"799:7:0","scope":677,"usedErrors":[]},{"id":663,"nodeType":"ContractDefinition","src":"2541:3089:0","nodes":[{"id":207,"nodeType":"VariableDeclaration","src":"2571:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2597:10:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":194,"name":"address","nodeType":"ElementaryTypeName","src":"2571:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2644:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":201,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2634:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":203,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2634:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":200,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2626:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":199,"name":"uint256","nodeType":"ElementaryTypeName","src":"2626:7:0","typeDescriptions":{}}},"id":204,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2626:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":198,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2618:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":197,"name":"uint160","nodeType":"ElementaryTypeName","src":"2618:7:0","typeDescriptions":{}}},"id":205,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2618:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":196,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2610:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":195,"name":"address","nodeType":"ElementaryTypeName","src":"2610:7:0","typeDescriptions":{}}},"id":206,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2610:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":213,"nodeType":"VariableDeclaration","src":"2671:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2692:2:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"},"typeName":{"id":209,"nodeType":"UserDefinedTypeName","pathNode":{"id":208,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":55,"src":"2671:2:0"},"referencedDeclaration":55,"src":"2671:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"value":{"arguments":[{"id":211,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":207,"src":"2700:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":210,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":55,"src":"2697:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$55_$","typeString":"type(contract Vm)"}},"id":212,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2697:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"visibility":"internal"},{"id":215,"nodeType":"VariableDeclaration","src":"2775:22:0","nodes":[],"constant":false,"functionSelector":"61bc221a","mutability":"mutable","name":"counter","nameLocation":"2790:7:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":214,"name":"uint256","nodeType":"ElementaryTypeName","src":"2775:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":378,"nodeType":"FunctionDefinition","src":"2887:949:0","nodes":[],"body":{"id":377,"nodeType":"Block","src":"2909:927:0","nodes":[],"statements":[{"assignments":[220],"declarations":[{"constant":false,"id":220,"mutability":"mutable","name":"x","nameLocation":"2924:1:0","nodeType":"VariableDeclaration","scope":377,"src":"2919:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":219,"name":"bool","nodeType":"ElementaryTypeName","src":"2919:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":226,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":223,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2937:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":224,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2953:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":221,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"2928:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":222,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2928:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":225,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2928:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2919:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":230,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2981:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":231,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":220,"src":"3004:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":227,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"2969:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":229,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":137,"src":"2969:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2969:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":233,"nodeType":"ExpressionStatement","src":"2969:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":237,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3029:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":240,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3054:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":239,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3046:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":238,"name":"address","nodeType":"ElementaryTypeName","src":"3046:7:0","typeDescriptions":{}}},"id":241,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3046:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":234,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3017:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":236,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3017:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":242,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3017:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":243,"nodeType":"ExpressionStatement","src":"3017:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":247,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3082:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":252,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3120:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":251,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3112:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":250,"name":"address","nodeType":"ElementaryTypeName","src":"3112:7:0","typeDescriptions":{}}},"id":253,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3112:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":248,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3100:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3100:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":254,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3100:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":244,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3070:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":246,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3070:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":255,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3070:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":256,"nodeType":"ExpressionStatement","src":"3070:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":260,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3149:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":263,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3172:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":264,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3172:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":262,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3164:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":261,"name":"address","nodeType":"ElementaryTypeName","src":"3164:7:0","typeDescriptions":{}}},"id":265,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3164:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":257,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3137:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":259,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3137:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":266,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3137:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":267,"nodeType":"ExpressionStatement","src":"3137:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":271,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3206:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":276,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3242:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":277,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3242:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":275,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3234:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":274,"name":"address","nodeType":"ElementaryTypeName","src":"3234:7:0","typeDescriptions":{}}},"id":278,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3234:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":272,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3222:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":273,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3222:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":279,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3222:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":268,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3194:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":270,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3194:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":280,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3194:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":281,"nodeType":"ExpressionStatement","src":"3194:61:0"},{"assignments":[283],"declarations":[{"constant":false,"id":283,"mutability":"mutable","name":"json","nameLocation":"3280:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3266:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":282,"name":"string","nodeType":"ElementaryTypeName","src":"3266:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":285,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3287:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"3266:55:0"},{"assignments":[290],"declarations":[{"constant":false,"id":290,"mutability":"mutable","name":"keys","nameLocation":"3347:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3331:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":288,"name":"string","nodeType":"ElementaryTypeName","src":"3331:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":289,"nodeType":"ArrayTypeName","src":"3331:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":296,"initialValue":{"arguments":[{"id":293,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":283,"src":"3371:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":294,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3377:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":291,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3354:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":292,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3354:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":295,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3354:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3331:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":300,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3414:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":301,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3422:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":303,"indexExpression":{"hexValue":"30","id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3427:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3422:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":304,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3431:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":306,"indexExpression":{"hexValue":"31","id":305,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3436:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3431:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":297,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3402:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":299,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":191,"src":"3402:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":307,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3402:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":308,"nodeType":"ExpressionStatement","src":"3402:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":312,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3461:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":309,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3450:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":311,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3450:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":313,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3450:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":314,"nodeType":"ExpressionStatement","src":"3450:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":322,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3517:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":321,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3509:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":320,"name":"uint160","nodeType":"ElementaryTypeName","src":"3509:7:0","typeDescriptions":{}}},"id":323,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3509:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":319,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3501:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":318,"name":"address","nodeType":"ElementaryTypeName","src":"3501:7:0","typeDescriptions":{}}},"id":324,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3501:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":315,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3487:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":317,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3487:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3487:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":326,"nodeType":"ExpressionStatement","src":"3487:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":330,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3545:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":327,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3534:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":329,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3534:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3534:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":332,"nodeType":"ExpressionStatement","src":"3534:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":336,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3582:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":339,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3617:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":340,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3617:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":338,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3609:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":337,"name":"address","nodeType":"ElementaryTypeName","src":"3609:7:0","typeDescriptions":{}}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3609:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":333,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3570:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":335,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3570:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3570:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3570:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3651:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":350,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3689:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":349,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3681:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":348,"name":"address","nodeType":"ElementaryTypeName","src":"3681:7:0","typeDescriptions":{}}},"id":351,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3681:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":344,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3639:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3639:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3639:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":353,"nodeType":"ExpressionStatement","src":"3639:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":357,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3716:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":354,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3705:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":356,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3705:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":358,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3705:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":359,"nodeType":"ExpressionStatement","src":"3705:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":360,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3741:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":362,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3741:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":363,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3741:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":364,"nodeType":"ExpressionStatement","src":"3741:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":368,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3776:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":365,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3765:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":367,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3765:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":369,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3765:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":370,"nodeType":"ExpressionStatement","src":"3765:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":374,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3821:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":371,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3809:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":373,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"3809:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":375,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3809:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":376,"nodeType":"ExpressionStatement","src":"3809:20:0"}]},"documentation":{"id":216,"nodeType":"StructuredDocumentation","src":"2804:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2896:3:0","parameters":{"id":217,"nodeType":"ParameterList","parameters":[],"src":"2899:2:0"},"returnParameters":{"id":218,"nodeType":"ParameterList","parameters":[],"src":"2909:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":566,"nodeType":"FunctionDefinition","src":"3903:988:0","nodes":[],"body":{"id":565,"nodeType":"Block","src":"3934:957:0","nodes":[],"statements":[{"expression":{"arguments":[{"hexValue":"74657374696e672073696e676c65","id":385,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3956:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""},"value":"testing single"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""}],"expression":{"id":382,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3944:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":384,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"3944:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":386,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3944:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":387,"nodeType":"ExpressionStatement","src":"3944:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":388,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3983:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":390,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"3983:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":391,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3983:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":392,"nodeType":"ExpressionStatement","src":"3983:14:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c31","id":396,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4018:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""},"value":"single_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""}],"expression":{"id":393,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4007:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":395,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4007:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":397,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4007:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":398,"nodeType":"ExpressionStatement","src":"4007:26:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c32","id":402,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4054:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""},"value":"single_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""}],"expression":{"id":399,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4043:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":401,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":620,"src":"4043:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":403,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4043:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":404,"nodeType":"ExpressionStatement","src":"4043:26:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073746172742f73746f70","id":408,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4092:20:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""},"value":"testing start/stop"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""}],"expression":{"id":405,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4080:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":407,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4080:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":409,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4080:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":410,"nodeType":"ExpressionStatement","src":"4080:33:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078633066666565","id":418,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4157:8:0","typeDescriptions":{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"},"value":"0xc0ffee"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"}],"id":417,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4149:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":416,"name":"uint160","nodeType":"ElementaryTypeName","src":"4149:7:0","typeDescriptions":{}}},"id":419,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4149:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":415,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4141:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":414,"name":"address","nodeType":"ElementaryTypeName","src":"4141:7:0","typeDescriptions":{}}},"id":420,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4141:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":411,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4123:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":413,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4123:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":421,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4123:45:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":422,"nodeType":"ExpressionStatement","src":"4123:45:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c31","id":426,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4189:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""},"value":"startstop_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""}],"expression":{"id":423,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4178:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":425,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4178:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":427,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4178:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":428,"nodeType":"ExpressionStatement","src":"4178:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c32","id":432,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4228:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""},"value":"startstop_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""}],"expression":{"id":429,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4217:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":431,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":620,"src":"4217:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":433,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4217:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":434,"nodeType":"ExpressionStatement","src":"4217:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f70757265","id":438,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4270:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""},"value":"startstop_pure"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""}],"expression":{"id":435,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4256:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":437,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"callPure","nodeType":"MemberAccess","referencedDeclaration":662,"src":"4256:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure external"}},"id":439,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4256:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":440,"nodeType":"ExpressionStatement","src":"4256:31:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":441,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4297:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":443,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4297:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":444,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4297:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":445,"nodeType":"ExpressionStatement","src":"4297:18:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c33","id":449,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4336:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""},"value":"startstop_call3"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""}],"expression":{"id":446,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4325:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":448,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4325:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":450,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4325:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":451,"nodeType":"ExpressionStatement","src":"4325:29:0"},{"expression":{"arguments":[{"hexValue":"74657374696e67206e6573746564","id":455,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4377:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""},"value":"testing nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""}],"expression":{"id":452,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4365:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":454,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4365:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":456,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4365:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":457,"nodeType":"ExpressionStatement","src":"4365:29:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307831323334","id":465,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4438:6:0","typeDescriptions":{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"},"value":"0x1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"}],"id":464,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4430:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":463,"name":"uint160","nodeType":"ElementaryTypeName","src":"4430:7:0","typeDescriptions":{}}},"id":466,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4430:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":462,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4422:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":461,"name":"address","nodeType":"ElementaryTypeName","src":"4422:7:0","typeDescriptions":{}}},"id":467,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4422:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":458,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4404:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":460,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4404:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":468,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4404:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":469,"nodeType":"ExpressionStatement","src":"4404:43:0"},{"expression":{"arguments":[{"hexValue":"6e6573746564","id":473,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4470:8:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""},"value":"nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""}],"expression":{"id":470,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4457:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":472,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested1","nodeType":"MemberAccess","referencedDeclaration":635,"src":"4457:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":474,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4457:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":475,"nodeType":"ExpressionStatement","src":"4457:22:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":476,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4489:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":478,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4489:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":479,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4489:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":480,"nodeType":"ExpressionStatement","src":"4489:18:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206465706c6f796d656e74","id":484,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4530:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""},"value":"contract deployment"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""}],"expression":{"id":481,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4518:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":483,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4518:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":485,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4518:34:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":486,"nodeType":"ExpressionStatement","src":"4518:34:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078313233343536","id":494,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4591:8:0","typeDescriptions":{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"},"value":"0x123456"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"}],"id":493,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4583:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":492,"name":"uint160","nodeType":"ElementaryTypeName","src":"4583:7:0","typeDescriptions":{}}},"id":495,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4583:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":491,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4575:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":490,"name":"address","nodeType":"ElementaryTypeName","src":"4575:7:0","typeDescriptions":{}}},"id":496,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4575:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":487,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4562:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":489,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4562:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":497,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4562:40:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":498,"nodeType":"ExpressionStatement","src":"4562:40:0"},{"assignments":[501],"declarations":[{"constant":false,"id":501,"mutability":"mutable","name":"x","nameLocation":"4619:1:0","nodeType":"VariableDeclaration","scope":565,"src":"4612:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"},"typeName":{"id":500,"nodeType":"UserDefinedTypeName","pathNode":{"id":499,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4612:6:0"},"referencedDeclaration":676,"src":"4612:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"visibility":"internal"}],"id":507,"initialValue":{"arguments":[{"hexValue":"31323334","id":505,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4634:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":504,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4623:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":503,"nodeType":"UserDefinedTypeName","pathNode":{"id":502,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4627:6:0"},"referencedDeclaration":676,"src":"4627:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}}},"id":506,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4623:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4612:27:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":513,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":509,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":501,"src":"4657:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"id":510,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":665,"src":"4657:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":511,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4657:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":512,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4668:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4657:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":508,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4649:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":514,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4649:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":515,"nodeType":"ExpressionStatement","src":"4649:24:0"},{"expression":{"arguments":[{"hexValue":"6372656174652032","id":519,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4696:10:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""},"value":"create 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""}],"expression":{"id":516,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4684:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":518,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4684:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":520,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4684:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":521,"nodeType":"ExpressionStatement","src":"4684:23:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307863616665","id":529,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4746:6:0","typeDescriptions":{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"},"value":"0xcafe"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"}],"id":528,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4738:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":527,"name":"uint160","nodeType":"ElementaryTypeName","src":"4738:7:0","typeDescriptions":{}}},"id":530,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4738:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":526,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4730:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":525,"name":"address","nodeType":"ElementaryTypeName","src":"4730:7:0","typeDescriptions":{}}},"id":531,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4730:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":522,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4717:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":524,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4717:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":532,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4717:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":533,"nodeType":"ExpressionStatement","src":"4717:38:0"},{"assignments":[536],"declarations":[{"constant":false,"id":536,"mutability":"mutable","name":"y","nameLocation":"4772:1:0","nodeType":"VariableDeclaration","scope":565,"src":"4765:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"},"typeName":{"id":535,"nodeType":"UserDefinedTypeName","pathNode":{"id":534,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4765:6:0"},"referencedDeclaration":676,"src":"4765:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"visibility":"internal"}],"id":550,"initialValue":{"arguments":[{"hexValue":"31323334","id":548,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4815:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":539,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4776:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":538,"nodeType":"UserDefinedTypeName","pathNode":{"id":537,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4780:6:0"},"referencedDeclaration":676,"src":"4780:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}}},"id":547,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"names":["salt"],"nodeType":"FunctionCallOptions","options":[{"arguments":[{"arguments":[{"hexValue":"3432","id":544,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4809:2:0","typeDescriptions":{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"},"value":"42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"}],"id":543,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4801:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":542,"name":"uint256","nodeType":"ElementaryTypeName","src":"4801:7:0","typeDescriptions":{}}},"id":545,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4801:11:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":541,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4793:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_bytes32_$","typeString":"type(bytes32)"},"typeName":{"id":540,"name":"bytes32","nodeType":"ElementaryTypeName","src":"4793:7:0","typeDescriptions":{}}},"id":546,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4793:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"src":"4776:38:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$salt","typeString":"function (uint256) returns (contract FooBar)"}},"id":549,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4776:44:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4765:55:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":556,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":552,"name":"y","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":536,"src":"4838:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"id":553,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":665,"src":"4838:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":554,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4838:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":555,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4849:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4838:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":551,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4830:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":557,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4830:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":558,"nodeType":"ExpressionStatement","src":"4830:24:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":562,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4876:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":559,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4864:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":561,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4864:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":563,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4864:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":564,"nodeType":"ExpressionStatement","src":"4864:20:0"}]},"documentation":{"id":379,"nodeType":"StructuredDocumentation","src":"3842:56:0","text":"@notice example function, to test vm.broadcast with."},"functionSelector":"bef03abc","implemented":true,"kind":"function","modifiers":[],"name":"runBroadcast","nameLocation":"3912:12:0","parameters":{"id":380,"nodeType":"ParameterList","parameters":[],"src":"3924:2:0"},"returnParameters":{"id":381,"nodeType":"ParameterList","parameters":[],"src":"3934:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":590,"nodeType":"FunctionDefinition","src":"4986:143:0","nodes":[],"body":{"id":589,"nodeType":"Block","src":"5035:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":575,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":569,"src":"5057:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":572,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5045:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":574,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5045:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":576,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5045:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":577,"nodeType":"ExpressionStatement","src":"5045:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":581,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"5082:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":584,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"5110:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":585,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"5110:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":583,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5102:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":582,"name":"address","nodeType":"ElementaryTypeName","src":"5102:7:0","typeDescriptions":{}}},"id":586,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5102:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":578,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5070:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":580,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"5070:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":587,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5070:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":588,"nodeType":"ExpressionStatement","src":"5070:52:0"}]},"documentation":{"id":567,"nodeType":"StructuredDocumentation","src":"4897:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"4995:5:0","parameters":{"id":570,"nodeType":"ParameterList","parameters":[{"constant":false,"id":569,"mutability":"mutable","name":"_v","nameLocation":"5017:2:0","nodeType":"VariableDeclaration","scope":590,"src":"5001:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":568,"name":"string","nodeType":"ElementaryTypeName","src":"5001:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5000:20:0"},"returnParameters":{"id":571,"nodeType":"ParameterList","parameters":[],"src":"5035:0:0"},"scope":663,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":605,"nodeType":"FunctionDefinition","src":"5135:95:0","nodes":[],"body":{"id":604,"nodeType":"Block","src":"5179:51:0","nodes":[],"statements":[{"expression":{"id":596,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5189:9:0","subExpression":{"id":595,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5189:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":597,"nodeType":"ExpressionStatement","src":"5189:9:0"},{"expression":{"arguments":[{"id":601,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":592,"src":"5220:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":598,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5208:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":600,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5208:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":602,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5208:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":603,"nodeType":"ExpressionStatement","src":"5208:15:0"}]},"functionSelector":"7e79255d","implemented":true,"kind":"function","modifiers":[],"name":"call1","nameLocation":"5144:5:0","parameters":{"id":593,"nodeType":"ParameterList","parameters":[{"constant":false,"id":592,"mutability":"mutable","name":"_v","nameLocation":"5166:2:0","nodeType":"VariableDeclaration","scope":605,"src":"5150:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":591,"name":"string","nodeType":"ElementaryTypeName","src":"5150:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5149:20:0"},"returnParameters":{"id":594,"nodeType":"ParameterList","parameters":[],"src":"5179:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":620,"nodeType":"FunctionDefinition","src":"5236:95:0","nodes":[],"body":{"id":619,"nodeType":"Block","src":"5280:51:0","nodes":[],"statements":[{"expression":{"id":611,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5290:9:0","subExpression":{"id":610,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5290:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":612,"nodeType":"ExpressionStatement","src":"5290:9:0"},{"expression":{"arguments":[{"id":616,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":607,"src":"5321:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":613,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5309:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":615,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5309:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":617,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5309:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":618,"nodeType":"ExpressionStatement","src":"5309:15:0"}]},"functionSelector":"8d3ef7ca","implemented":true,"kind":"function","modifiers":[],"name":"call2","nameLocation":"5245:5:0","parameters":{"id":608,"nodeType":"ParameterList","parameters":[{"constant":false,"id":607,"mutability":"mutable","name":"_v","nameLocation":"5267:2:0","nodeType":"VariableDeclaration","scope":620,"src":"5251:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":606,"name":"string","nodeType":"ElementaryTypeName","src":"5251:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5250:20:0"},"returnParameters":{"id":609,"nodeType":"ParameterList","parameters":[],"src":"5280:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":635,"nodeType":"FunctionDefinition","src":"5337:98:0","nodes":[],"body":{"id":634,"nodeType":"Block","src":"5383:52:0","nodes":[],"statements":[{"expression":{"id":626,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5393:9:0","subExpression":{"id":625,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5393:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":627,"nodeType":"ExpressionStatement","src":"5393:9:0"},{"expression":{"arguments":[{"id":631,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":622,"src":"5425:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":628,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"5412:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":630,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested2","nodeType":"MemberAccess","referencedDeclaration":650,"src":"5412:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":632,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5412:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":633,"nodeType":"ExpressionStatement","src":"5412:16:0"}]},"functionSelector":"a76ccdfa","implemented":true,"kind":"function","modifiers":[],"name":"nested1","nameLocation":"5346:7:0","parameters":{"id":623,"nodeType":"ParameterList","parameters":[{"constant":false,"id":622,"mutability":"mutable","name":"_v","nameLocation":"5370:2:0","nodeType":"VariableDeclaration","scope":635,"src":"5354:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":621,"name":"string","nodeType":"ElementaryTypeName","src":"5354:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5353:20:0"},"returnParameters":{"id":624,"nodeType":"ParameterList","parameters":[],"src":"5383:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":650,"nodeType":"FunctionDefinition","src":"5441:97:0","nodes":[],"body":{"id":649,"nodeType":"Block","src":"5487:51:0","nodes":[],"statements":[{"expression":{"id":641,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5497:9:0","subExpression":{"id":640,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5497:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":642,"nodeType":"ExpressionStatement","src":"5497:9:0"},{"expression":{"arguments":[{"id":646,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":637,"src":"5528:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":643,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5516:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":645,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5516:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":647,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5516:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":648,"nodeType":"ExpressionStatement","src":"5516:15:0"}]},"functionSelector":"dbf1282f","implemented":true,"kind":"function","modifiers":[],"name":"nested2","nameLocation":"5450:7:0","parameters":{"id":638,"nodeType":"ParameterList","parameters":[{"constant":false,"id":637,"mutability":"mutable","name":"_v","nameLocation":"5474:2:0","nodeType":"VariableDeclaration","scope":650,"src":"5458:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":636,"name":"string","nodeType":"ElementaryTypeName","src":"5458:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5457:20:0"},"returnParameters":{"id":639,"nodeType":"ParameterList","parameters":[],"src":"5487:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":662,"nodeType":"FunctionDefinition","src":"5544:84:0","nodes":[],"body":{"id":661,"nodeType":"Block","src":"5596:32:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":658,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":652,"src":"5618:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":655,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5606:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":657,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5606:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":659,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5606:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":660,"nodeType":"ExpressionStatement","src":"5606:15:0"}]},"functionSelector":"7f8b915c","implemented":true,"kind":"function","modifiers":[],"name":"callPure","nameLocation":"5553:8:0","parameters":{"id":653,"nodeType":"ParameterList","parameters":[{"constant":false,"id":652,"mutability":"mutable","name":"_v","nameLocation":"5578:2:0","nodeType":"VariableDeclaration","scope":662,"src":"5562:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":651,"name":"string","nodeType":"ElementaryTypeName","src":"5562:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5561:20:0"},"returnParameters":{"id":654,"nodeType":"ParameterList","parameters":[],"src":"5596:0:0"},"scope":663,"stateMutability":"pure","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[676],"contractKind":"contract","documentation":{"id":193,"nodeType":"StructuredDocumentation","src":"2415:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[663],"name":"ScriptExample","nameLocation":"2550:13:0","scope":677,"usedErrors":[]},{"id":676,"nodeType":"ContractDefinition","src":"5632:96:0","nodes":[{"id":665,"nodeType":"VariableDeclaration","src":"5654:18:0","nodes":[],"constant":false,"functionSelector":"c2985578","mutability":"mutable","name":"foo","nameLocation":"5669:3:0","scope":676,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":664,"name":"uint256","nodeType":"ElementaryTypeName","src":"5654:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":675,"nodeType":"FunctionDefinition","src":"5679:47:0","nodes":[],"body":{"id":674,"nodeType":"Block","src":"5702:24:0","nodes":[],"statements":[{"expression":{"id":672,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":670,"name":"foo","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":665,"src":"5712:3:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":671,"name":"v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":667,"src":"5718:1:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5712:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":673,"nodeType":"ExpressionStatement","src":"5712:7:0"}]},"implemented":true,"kind":"constructor","modifiers":[],"name":"","nameLocation":"-1:-1:-1","parameters":{"id":668,"nodeType":"ParameterList","parameters":[{"constant":false,"id":667,"mutability":"mutable","name":"v","nameLocation":"5699:1:0","nodeType":"VariableDeclaration","scope":675,"src":"5691:9:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":666,"name":"uint256","nodeType":"ElementaryTypeName","src":"5691:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"5690:11:0"},"returnParameters":{"id":669,"nodeType":"ParameterList","parameters":[],"src":"5702:0:0"},"scope":676,"stateMutability":"nonpayable","virtual":false,"visibility":"public"}],"abstract":false,"baseContracts":[],"canonicalName":"FooBar","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[676],"name":"FooBar","nameLocation":"5641:6:0","scope":677,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file +{"abi":[{"type":"function","name":"broadcast","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"broadcast","inputs":[{"name":"msgSender","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"envOr","inputs":[{"name":"name","type":"string","internalType":"string"},{"name":"defaultValue","type":"bool","internalType":"bool"}],"outputs":[{"name":"value","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"getNonce","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"nonce","type":"uint64","internalType":"uint64"}],"stateMutability":"view"},{"type":"function","name":"parseJsonKeys","inputs":[{"name":"json","type":"string","internalType":"string"},{"name":"key","type":"string","internalType":"string"}],"outputs":[{"name":"keys","type":"string[]","internalType":"string[]"}],"stateMutability":"pure"},{"type":"function","name":"startBroadcast","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"startBroadcast","inputs":[{"name":"msgSender","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"startPrank","inputs":[{"name":"msgSender","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"stopBroadcast","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"stopPrank","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{"broadcast()":"afc98040","broadcast(address)":"e6962cdb","envOr(string,bool)":"4777f3cf","getNonce(address)":"2d0335ab","parseJsonKeys(string,string)":"213e4198","startBroadcast()":"7fb5297f","startBroadcast(address)":"7fec2a8d","startPrank(address)":"06447d56","stopBroadcast()":"76eadd36","stopPrank()":"90c5013b"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"broadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"msgSender\",\"type\":\"address\"}],\"name\":\"broadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"defaultValue\",\"type\":\"bool\"}],\"name\":\"envOr\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"json\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"}],\"name\":\"parseJsonKeys\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"keys\",\"type\":\"string[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startBroadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"msgSender\",\"type\":\"address\"}],\"name\":\"startBroadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"msgSender\",\"type\":\"address\"}],\"name\":\"startPrank\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stopBroadcast\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stopPrank\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"Vm\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x8d1dfa41908e7ccc3a498a2a2aa51c5275bedbb904ce32d08f8598e36f896d8d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5117bb7158363cae8b9dc0508d2852692fd36172f1c699ff680afbb5acebe1f3\",\"dweb:/ipfs/QmQdahJ8SPKfJ4yea5Ge9qaj5qh1TxVffhHvaWytBaL95h\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"broadcast"},{"inputs":[{"internalType":"address","name":"msgSender","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"broadcast"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"bool","name":"defaultValue","type":"bool"}],"stateMutability":"view","type":"function","name":"envOr","outputs":[{"internalType":"bool","name":"value","type":"bool"}]},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"stateMutability":"view","type":"function","name":"getNonce","outputs":[{"internalType":"uint64","name":"nonce","type":"uint64"}]},{"inputs":[{"internalType":"string","name":"json","type":"string"},{"internalType":"string","name":"key","type":"string"}],"stateMutability":"pure","type":"function","name":"parseJsonKeys","outputs":[{"internalType":"string[]","name":"keys","type":"string[]"}]},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"startBroadcast"},{"inputs":[{"internalType":"address","name":"msgSender","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"startBroadcast"},{"inputs":[{"internalType":"address","name":"msgSender","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"startPrank"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"stopBroadcast"},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"stopPrank"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"Vm"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x8d1dfa41908e7ccc3a498a2a2aa51c5275bedbb904ce32d08f8598e36f896d8d","urls":["bzz-raw://5117bb7158363cae8b9dc0508d2852692fd36172f1c699ff680afbb5acebe1f3","dweb:/ipfs/QmQdahJ8SPKfJ4yea5Ge9qaj5qh1TxVffhHvaWytBaL95h"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[],"types":{}},"userdoc":{"version":1,"kind":"user"},"devdoc":{"version":1,"kind":"dev"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":720,"exportedSymbols":{"FooBar":[719],"ScriptExample":[706],"Vm":[55],"console":[192]},"nodeType":"SourceUnit","src":"32:5967:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":55,"nodeType":"ContractDefinition","src":"120:616:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":55,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":38,"nodeType":"FunctionDefinition","src":"516:30:0","nodes":[],"functionSelector":"afc98040","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"525:9:0","parameters":{"id":36,"nodeType":"ParameterList","parameters":[],"src":"534:2:0"},"returnParameters":{"id":37,"nodeType":"ParameterList","parameters":[],"src":"545:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":43,"nodeType":"FunctionDefinition","src":"551:47:0","nodes":[],"functionSelector":"e6962cdb","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"560:9:0","parameters":{"id":41,"nodeType":"ParameterList","parameters":[{"constant":false,"id":40,"mutability":"mutable","name":"msgSender","nameLocation":"578:9:0","nodeType":"VariableDeclaration","scope":43,"src":"570:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":39,"name":"address","nodeType":"ElementaryTypeName","src":"570:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"569:19:0"},"returnParameters":{"id":42,"nodeType":"ParameterList","parameters":[],"src":"597:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":48,"nodeType":"FunctionDefinition","src":"603:52:0","nodes":[],"functionSelector":"7fec2a8d","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"612:14:0","parameters":{"id":46,"nodeType":"ParameterList","parameters":[{"constant":false,"id":45,"mutability":"mutable","name":"msgSender","nameLocation":"635:9:0","nodeType":"VariableDeclaration","scope":48,"src":"627:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":44,"name":"address","nodeType":"ElementaryTypeName","src":"627:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"626:19:0"},"returnParameters":{"id":47,"nodeType":"ParameterList","parameters":[],"src":"654:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":51,"nodeType":"FunctionDefinition","src":"660:35:0","nodes":[],"functionSelector":"7fb5297f","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"669:14:0","parameters":{"id":49,"nodeType":"ParameterList","parameters":[],"src":"683:2:0"},"returnParameters":{"id":50,"nodeType":"ParameterList","parameters":[],"src":"694:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":54,"nodeType":"FunctionDefinition","src":"700:34:0","nodes":[],"functionSelector":"76eadd36","implemented":false,"kind":"function","modifiers":[],"name":"stopBroadcast","nameLocation":"709:13:0","parameters":{"id":52,"nodeType":"ParameterList","parameters":[],"src":"722:2:0"},"returnParameters":{"id":53,"nodeType":"ParameterList","parameters":[],"src":"733:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[55],"name":"Vm","nameLocation":"130:2:0","scope":720,"usedErrors":[]},{"id":192,"nodeType":"ContractDefinition","src":"791:1622:0","nodes":[{"id":61,"nodeType":"VariableDeclaration","src":"813:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"830:15:0","scope":192,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":56,"name":"address","nodeType":"ElementaryTypeName","src":"813:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":59,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"856:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":58,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"848:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":57,"name":"address","nodeType":"ElementaryTypeName","src":"848:7:0","typeDescriptions":{}}},"id":60,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"848:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":78,"nodeType":"FunctionDefinition","src":"906:221:0","nodes":[],"body":{"id":77,"nodeType":"Block","src":"1065:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"1084:37:0","statements":[{"nodeType":"YulAssignment","src":"1098:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"1107:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"1098:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":67,"isOffset":false,"isSlot":false,"src":"1107:4:0","valueSize":1},{"declaration":74,"isOffset":false,"isSlot":false,"src":"1098:5:0","valueSize":1}],"id":76,"nodeType":"InlineAssembly","src":"1075:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"915:25:0","parameters":{"id":68,"nodeType":"ParameterList","parameters":[{"constant":false,"id":67,"mutability":"mutable","name":"fnIn","nameLocation":"987:4:0","nodeType":"VariableDeclaration","scope":78,"src":"950:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":66,"nodeType":"FunctionTypeName","parameterTypes":{"id":64,"nodeType":"ParameterList","parameters":[{"constant":false,"id":63,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":66,"src":"959:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":62,"name":"bytes","nodeType":"ElementaryTypeName","src":"959:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"958:14:0"},"returnParameterTypes":{"id":65,"nodeType":"ParameterList","parameters":[],"src":"987:0:0"},"src":"950:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"940:57:0"},"returnParameters":{"id":75,"nodeType":"ParameterList","parameters":[{"constant":false,"id":74,"mutability":"mutable","name":"fnOut","nameLocation":"1058:5:0","nodeType":"VariableDeclaration","scope":78,"src":"1021:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":73,"nodeType":"FunctionTypeName","parameterTypes":{"id":71,"nodeType":"ParameterList","parameters":[{"constant":false,"id":70,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":73,"src":"1030:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":69,"name":"bytes","nodeType":"ElementaryTypeName","src":"1030:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1029:14:0"},"returnParameterTypes":{"id":72,"nodeType":"ParameterList","parameters":[],"src":"1058:0:0"},"src":"1021:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"1020:44:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":90,"nodeType":"FunctionDefinition","src":"1133:133:0","nodes":[],"body":{"id":89,"nodeType":"Block","src":"1194:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":86,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1251:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":84,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":106,"src":"1230:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":83,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":78,"src":"1204:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":85,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":87,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":88,"nodeType":"ExpressionStatement","src":"1204:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"1142:15:0","parameters":{"id":81,"nodeType":"ParameterList","parameters":[{"constant":false,"id":80,"mutability":"mutable","name":"payload","nameLocation":"1171:7:0","nodeType":"VariableDeclaration","scope":90,"src":"1158:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":79,"name":"bytes","nodeType":"ElementaryTypeName","src":"1158:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1157:22:0"},"returnParameters":{"id":82,"nodeType":"ParameterList","parameters":[],"src":"1194:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":106,"nodeType":"FunctionDefinition","src":"1272:380:0","nodes":[],"body":{"id":105,"nodeType":"Block","src":"1336:316:0","nodes":[],"statements":[{"assignments":[96],"declarations":[{"constant":false,"id":96,"mutability":"mutable","name":"payloadLength","nameLocation":"1354:13:0","nodeType":"VariableDeclaration","scope":105,"src":"1346:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":95,"name":"uint256","nodeType":"ElementaryTypeName","src":"1346:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":99,"initialValue":{"expression":{"id":97,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":92,"src":"1370:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":98,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1370:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1346:38:0"},{"assignments":[101],"declarations":[{"constant":false,"id":101,"mutability":"mutable","name":"consoleAddress","nameLocation":"1402:14:0","nodeType":"VariableDeclaration","scope":105,"src":"1394:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":100,"name":"address","nodeType":"ElementaryTypeName","src":"1394:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":103,"initialValue":{"id":102,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":61,"src":"1419:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1394:40:0"},{"AST":{"nodeType":"YulBlock","src":"1496:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1510:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1534:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1543:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1530:3:0"},"nodeType":"YulFunctionCall","src":"1530:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1514:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1559:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1579:3:0"},"nodeType":"YulFunctionCall","src":"1579:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1586:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1602:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1616:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1631:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1634:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1568:10:0"},"nodeType":"YulFunctionCall","src":"1568:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1563:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":101,"isOffset":false,"isSlot":false,"src":"1586:14:0","valueSize":1},{"declaration":92,"isOffset":false,"isSlot":false,"src":"1534:7:0","valueSize":1},{"declaration":96,"isOffset":false,"isSlot":false,"src":"1616:13:0","valueSize":1}],"id":104,"nodeType":"InlineAssembly","src":"1487:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1281:19:0","parameters":{"id":93,"nodeType":"ParameterList","parameters":[{"constant":false,"id":92,"mutability":"mutable","name":"payload","nameLocation":"1314:7:0","nodeType":"VariableDeclaration","scope":106,"src":"1301:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":91,"name":"bytes","nodeType":"ElementaryTypeName","src":"1301:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1300:22:0"},"returnParameters":{"id":94,"nodeType":"ParameterList","parameters":[],"src":"1336:0:0"},"scope":192,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":120,"nodeType":"FunctionDefinition","src":"1658:121:0","nodes":[],"body":{"id":119,"nodeType":"Block","src":"1703:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":114,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1753:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":115,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":108,"src":"1768:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":112,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1729:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":113,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1729:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":116,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1729:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":111,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1713:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":117,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1713:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":118,"nodeType":"ExpressionStatement","src":"1713:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1667:3:0","parameters":{"id":109,"nodeType":"ParameterList","parameters":[{"constant":false,"id":108,"mutability":"mutable","name":"p0","nameLocation":"1685:2:0","nodeType":"VariableDeclaration","scope":120,"src":"1671:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":107,"name":"string","nodeType":"ElementaryTypeName","src":"1671:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1670:18:0"},"returnParameters":{"id":110,"nodeType":"ParameterList","parameters":[],"src":"1703:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":137,"nodeType":"FunctionDefinition","src":"1785:139:0","nodes":[],"body":{"id":136,"nodeType":"Block","src":"1839:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":130,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1889:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":131,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":122,"src":"1909:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":132,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":124,"src":"1913:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":128,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1865:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":129,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1865:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":133,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1865:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":127,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1849:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":134,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1849:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":135,"nodeType":"ExpressionStatement","src":"1849:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1794:3:0","parameters":{"id":125,"nodeType":"ParameterList","parameters":[{"constant":false,"id":122,"mutability":"mutable","name":"p0","nameLocation":"1812:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1798:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":121,"name":"string","nodeType":"ElementaryTypeName","src":"1798:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":124,"mutability":"mutable","name":"p1","nameLocation":"1821:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1816:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":123,"name":"bool","nodeType":"ElementaryTypeName","src":"1816:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1797:27:0"},"returnParameters":{"id":126,"nodeType":"ParameterList","parameters":[],"src":"1839:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":154,"nodeType":"FunctionDefinition","src":"1930:145:0","nodes":[],"body":{"id":153,"nodeType":"Block","src":"1987:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":147,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2037:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":148,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":139,"src":"2060:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":149,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":141,"src":"2064:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":145,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2013:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":146,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2013:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":150,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2013:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":144,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1997:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":151,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1997:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":152,"nodeType":"ExpressionStatement","src":"1997:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1939:3:0","parameters":{"id":142,"nodeType":"ParameterList","parameters":[{"constant":false,"id":139,"mutability":"mutable","name":"p0","nameLocation":"1957:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1943:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":138,"name":"string","nodeType":"ElementaryTypeName","src":"1943:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":141,"mutability":"mutable","name":"p1","nameLocation":"1969:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1961:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":140,"name":"uint256","nodeType":"ElementaryTypeName","src":"1961:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1942:30:0"},"returnParameters":{"id":143,"nodeType":"ParameterList","parameters":[],"src":"1987:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":171,"nodeType":"FunctionDefinition","src":"2081:145:0","nodes":[],"body":{"id":170,"nodeType":"Block","src":"2138:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":164,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2188:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":165,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":156,"src":"2211:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":166,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":158,"src":"2215:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":162,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2164:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":163,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2164:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":167,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2164:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":161,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2148:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":168,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2148:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":169,"nodeType":"ExpressionStatement","src":"2148:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2090:3:0","parameters":{"id":159,"nodeType":"ParameterList","parameters":[{"constant":false,"id":156,"mutability":"mutable","name":"p0","nameLocation":"2108:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2094:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":155,"name":"string","nodeType":"ElementaryTypeName","src":"2094:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":158,"mutability":"mutable","name":"p1","nameLocation":"2120:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2112:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":157,"name":"address","nodeType":"ElementaryTypeName","src":"2112:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"2093:30:0"},"returnParameters":{"id":160,"nodeType":"ParameterList","parameters":[],"src":"2138:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":191,"nodeType":"FunctionDefinition","src":"2232:179:0","nodes":[],"body":{"id":190,"nodeType":"Block","src":"2313:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":183,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2363:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":184,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2392:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":185,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":175,"src":"2396:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":186,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":177,"src":"2400:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":181,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2339:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":182,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2339:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":187,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2339:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":180,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2323:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":188,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2323:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":189,"nodeType":"ExpressionStatement","src":"2323:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2241:3:0","parameters":{"id":178,"nodeType":"ParameterList","parameters":[{"constant":false,"id":173,"mutability":"mutable","name":"p0","nameLocation":"2259:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2245:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":172,"name":"string","nodeType":"ElementaryTypeName","src":"2245:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":175,"mutability":"mutable","name":"p1","nameLocation":"2277:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2263:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":174,"name":"string","nodeType":"ElementaryTypeName","src":"2263:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":177,"mutability":"mutable","name":"p2","nameLocation":"2295:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2281:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":176,"name":"string","nodeType":"ElementaryTypeName","src":"2281:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2244:54:0"},"returnParameters":{"id":179,"nodeType":"ParameterList","parameters":[],"src":"2313:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[192],"name":"console","nameLocation":"799:7:0","scope":720,"usedErrors":[]},{"id":706,"nodeType":"ContractDefinition","src":"2541:3359:0","nodes":[{"id":207,"nodeType":"VariableDeclaration","src":"2571:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2597:10:0","scope":706,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":194,"name":"address","nodeType":"ElementaryTypeName","src":"2571:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2644:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":201,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2634:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":203,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2634:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":200,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2626:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":199,"name":"uint256","nodeType":"ElementaryTypeName","src":"2626:7:0","typeDescriptions":{}}},"id":204,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2626:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":198,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2618:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":197,"name":"uint160","nodeType":"ElementaryTypeName","src":"2618:7:0","typeDescriptions":{}}},"id":205,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2618:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":196,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2610:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":195,"name":"address","nodeType":"ElementaryTypeName","src":"2610:7:0","typeDescriptions":{}}},"id":206,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2610:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":213,"nodeType":"VariableDeclaration","src":"2671:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2692:2:0","scope":706,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"},"typeName":{"id":209,"nodeType":"UserDefinedTypeName","pathNode":{"id":208,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":55,"src":"2671:2:0"},"referencedDeclaration":55,"src":"2671:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"value":{"arguments":[{"id":211,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":207,"src":"2700:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":210,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":55,"src":"2697:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$55_$","typeString":"type(contract Vm)"}},"id":212,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2697:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"visibility":"internal"},{"id":215,"nodeType":"VariableDeclaration","src":"2775:22:0","nodes":[],"constant":false,"functionSelector":"61bc221a","mutability":"mutable","name":"counter","nameLocation":"2790:7:0","scope":706,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":214,"name":"uint256","nodeType":"ElementaryTypeName","src":"2775:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":378,"nodeType":"FunctionDefinition","src":"2887:949:0","nodes":[],"body":{"id":377,"nodeType":"Block","src":"2909:927:0","nodes":[],"statements":[{"assignments":[220],"declarations":[{"constant":false,"id":220,"mutability":"mutable","name":"x","nameLocation":"2924:1:0","nodeType":"VariableDeclaration","scope":377,"src":"2919:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":219,"name":"bool","nodeType":"ElementaryTypeName","src":"2919:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":226,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":223,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2937:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":224,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2953:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":221,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"2928:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":222,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2928:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":225,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2928:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2919:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":230,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2981:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":231,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":220,"src":"3004:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":227,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"2969:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":229,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":137,"src":"2969:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2969:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":233,"nodeType":"ExpressionStatement","src":"2969:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":237,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3029:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":240,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3054:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}],"id":239,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3046:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":238,"name":"address","nodeType":"ElementaryTypeName","src":"3046:7:0","typeDescriptions":{}}},"id":241,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3046:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":234,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3017:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":236,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3017:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":242,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3017:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":243,"nodeType":"ExpressionStatement","src":"3017:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":247,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3082:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":252,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3120:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}],"id":251,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3112:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":250,"name":"address","nodeType":"ElementaryTypeName","src":"3112:7:0","typeDescriptions":{}}},"id":253,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3112:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":248,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3100:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3100:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":254,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3100:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":244,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3070:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":246,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3070:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":255,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3070:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":256,"nodeType":"ExpressionStatement","src":"3070:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":260,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3149:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":263,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3172:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":264,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3172:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":262,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3164:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":261,"name":"address","nodeType":"ElementaryTypeName","src":"3164:7:0","typeDescriptions":{}}},"id":265,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3164:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":257,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3137:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":259,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3137:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":266,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3137:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":267,"nodeType":"ExpressionStatement","src":"3137:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":271,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3206:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":276,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3242:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":277,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3242:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":275,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3234:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":274,"name":"address","nodeType":"ElementaryTypeName","src":"3234:7:0","typeDescriptions":{}}},"id":278,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3234:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":272,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3222:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":273,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3222:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":279,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3222:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":268,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3194:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":270,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3194:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":280,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3194:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":281,"nodeType":"ExpressionStatement","src":"3194:61:0"},{"assignments":[283],"declarations":[{"constant":false,"id":283,"mutability":"mutable","name":"json","nameLocation":"3280:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3266:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":282,"name":"string","nodeType":"ElementaryTypeName","src":"3266:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":285,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3287:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"3266:55:0"},{"assignments":[290],"declarations":[{"constant":false,"id":290,"mutability":"mutable","name":"keys","nameLocation":"3347:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3331:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":288,"name":"string","nodeType":"ElementaryTypeName","src":"3331:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":289,"nodeType":"ArrayTypeName","src":"3331:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":296,"initialValue":{"arguments":[{"id":293,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":283,"src":"3371:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":294,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3377:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":291,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3354:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":292,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3354:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":295,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3354:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3331:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":300,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3414:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":301,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3422:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":303,"indexExpression":{"hexValue":"30","id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3427:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3422:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":304,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3431:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":306,"indexExpression":{"hexValue":"31","id":305,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3436:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3431:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":297,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3402:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":299,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":191,"src":"3402:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":307,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3402:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":308,"nodeType":"ExpressionStatement","src":"3402:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":312,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3461:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":309,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3450:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":311,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":633,"src":"3450:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":313,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3450:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":314,"nodeType":"ExpressionStatement","src":"3450:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":322,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3517:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":321,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3509:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":320,"name":"uint160","nodeType":"ElementaryTypeName","src":"3509:7:0","typeDescriptions":{}}},"id":323,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3509:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":319,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3501:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":318,"name":"address","nodeType":"ElementaryTypeName","src":"3501:7:0","typeDescriptions":{}}},"id":324,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3501:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":315,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3487:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":317,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3487:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3487:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":326,"nodeType":"ExpressionStatement","src":"3487:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":330,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3545:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":327,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3534:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":329,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":633,"src":"3534:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3534:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":332,"nodeType":"ExpressionStatement","src":"3534:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":336,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3582:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":339,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3617:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":340,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3617:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":338,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3609:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":337,"name":"address","nodeType":"ElementaryTypeName","src":"3609:7:0","typeDescriptions":{}}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3609:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":333,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3570:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":335,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3570:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3570:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3570:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3651:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":350,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3689:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}],"id":349,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3681:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":348,"name":"address","nodeType":"ElementaryTypeName","src":"3681:7:0","typeDescriptions":{}}},"id":351,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3681:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":344,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3639:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3639:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3639:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":353,"nodeType":"ExpressionStatement","src":"3639:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":357,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3716:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":354,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3705:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":356,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":633,"src":"3705:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":358,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3705:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":359,"nodeType":"ExpressionStatement","src":"3705:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":360,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3741:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":362,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3741:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":363,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3741:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":364,"nodeType":"ExpressionStatement","src":"3741:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":368,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3776:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":365,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3765:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":367,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":633,"src":"3765:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":369,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3765:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":370,"nodeType":"ExpressionStatement","src":"3765:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":374,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3821:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":371,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3809:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":373,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"3809:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":375,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3809:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":376,"nodeType":"ExpressionStatement","src":"3809:20:0"}]},"documentation":{"id":216,"nodeType":"StructuredDocumentation","src":"2804:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2896:3:0","parameters":{"id":217,"nodeType":"ParameterList","parameters":[],"src":"2899:2:0"},"returnParameters":{"id":218,"nodeType":"ParameterList","parameters":[],"src":"2909:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":609,"nodeType":"FunctionDefinition","src":"3903:1258:0","nodes":[],"body":{"id":608,"nodeType":"Block","src":"3934:1227:0","nodes":[],"statements":[{"expression":{"arguments":[{"hexValue":"6e6f6e6365207374617274","id":385,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3956:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_71efc69b9a13b6bc1e9a14d766ff01c79022262c6daa6532fb5dfb14f8511a20","typeString":"literal_string \"nonce start\""},"value":"nonce start"},{"arguments":[{"arguments":[{"arguments":[{"id":392,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3999:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}],"id":391,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3991:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":390,"name":"address","nodeType":"ElementaryTypeName","src":"3991:7:0","typeDescriptions":{}}},"id":393,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3991:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":388,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3979:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":389,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3979:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":394,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3979:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint64","typeString":"uint64"}],"id":387,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3971:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":386,"name":"uint256","nodeType":"ElementaryTypeName","src":"3971:7:0","typeDescriptions":{}}},"id":395,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3971:35:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_71efc69b9a13b6bc1e9a14d766ff01c79022262c6daa6532fb5dfb14f8511a20","typeString":"literal_string \"nonce start\""},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":382,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3944:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":384,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3944:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":396,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3944:63:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":397,"nodeType":"ExpressionStatement","src":"3944:63:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073696e676c65","id":401,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4030:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""},"value":"testing single"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""}],"expression":{"id":398,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4018:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":400,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4018:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":402,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4018:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":403,"nodeType":"ExpressionStatement","src":"4018:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":404,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4057:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":406,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"4057:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":407,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4057:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":408,"nodeType":"ExpressionStatement","src":"4057:14:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c31","id":412,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4092:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""},"value":"single_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""}],"expression":{"id":409,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4081:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":411,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":648,"src":"4081:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":413,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4081:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":414,"nodeType":"ExpressionStatement","src":"4081:26:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c32","id":418,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4128:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""},"value":"single_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""}],"expression":{"id":415,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4117:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":417,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":663,"src":"4117:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":419,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4117:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":420,"nodeType":"ExpressionStatement","src":"4117:26:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073746172742f73746f70","id":424,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4166:20:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""},"value":"testing start/stop"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""}],"expression":{"id":421,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4154:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":423,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4154:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":425,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4154:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":426,"nodeType":"ExpressionStatement","src":"4154:33:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078633066666565","id":434,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4231:8:0","typeDescriptions":{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"},"value":"0xc0ffee"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"}],"id":433,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4223:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":432,"name":"uint160","nodeType":"ElementaryTypeName","src":"4223:7:0","typeDescriptions":{}}},"id":435,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4223:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":431,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4215:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":430,"name":"address","nodeType":"ElementaryTypeName","src":"4215:7:0","typeDescriptions":{}}},"id":436,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4215:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":427,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4197:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":429,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4197:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":437,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4197:45:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":438,"nodeType":"ExpressionStatement","src":"4197:45:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c31","id":442,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4263:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""},"value":"startstop_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""}],"expression":{"id":439,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4252:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":441,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":648,"src":"4252:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":443,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4252:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":444,"nodeType":"ExpressionStatement","src":"4252:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c32","id":448,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4302:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""},"value":"startstop_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""}],"expression":{"id":445,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4291:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":447,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":663,"src":"4291:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":449,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4291:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":450,"nodeType":"ExpressionStatement","src":"4291:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f70757265","id":454,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4344:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""},"value":"startstop_pure"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""}],"expression":{"id":451,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4330:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":453,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"callPure","nodeType":"MemberAccess","referencedDeclaration":705,"src":"4330:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure external"}},"id":455,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4330:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":456,"nodeType":"ExpressionStatement","src":"4330:31:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":457,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4371:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":459,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4371:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":460,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4371:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":461,"nodeType":"ExpressionStatement","src":"4371:18:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c33","id":465,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4410:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""},"value":"startstop_call3"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""}],"expression":{"id":462,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4399:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":464,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":648,"src":"4399:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":466,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4399:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":467,"nodeType":"ExpressionStatement","src":"4399:29:0"},{"expression":{"arguments":[{"hexValue":"74657374696e67206e6573746564","id":471,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4451:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""},"value":"testing nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""}],"expression":{"id":468,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4439:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":470,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4439:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":472,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4439:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":473,"nodeType":"ExpressionStatement","src":"4439:29:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307831323334","id":481,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4512:6:0","typeDescriptions":{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"},"value":"0x1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"}],"id":480,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4504:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":479,"name":"uint160","nodeType":"ElementaryTypeName","src":"4504:7:0","typeDescriptions":{}}},"id":482,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4504:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":478,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4496:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":477,"name":"address","nodeType":"ElementaryTypeName","src":"4496:7:0","typeDescriptions":{}}},"id":483,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4496:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":474,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4478:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":476,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4478:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":484,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4478:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":485,"nodeType":"ExpressionStatement","src":"4478:43:0"},{"expression":{"arguments":[{"hexValue":"6e6573746564","id":489,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4544:8:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""},"value":"nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""}],"expression":{"id":486,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4531:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":488,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested1","nodeType":"MemberAccess","referencedDeclaration":678,"src":"4531:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":490,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4531:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":491,"nodeType":"ExpressionStatement","src":"4531:22:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":492,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4563:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":494,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4563:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":495,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4563:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":496,"nodeType":"ExpressionStatement","src":"4563:18:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206465706c6f796d656e74","id":500,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4604:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""},"value":"contract deployment"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""}],"expression":{"id":497,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4592:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":499,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4592:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":501,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4592:34:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":502,"nodeType":"ExpressionStatement","src":"4592:34:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078313233343536","id":510,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4665:8:0","typeDescriptions":{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"},"value":"0x123456"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"}],"id":509,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4657:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":508,"name":"uint160","nodeType":"ElementaryTypeName","src":"4657:7:0","typeDescriptions":{}}},"id":511,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4657:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":507,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4649:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":506,"name":"address","nodeType":"ElementaryTypeName","src":"4649:7:0","typeDescriptions":{}}},"id":512,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4649:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":503,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4636:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":505,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4636:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":513,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4636:40:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":514,"nodeType":"ExpressionStatement","src":"4636:40:0"},{"assignments":[517],"declarations":[{"constant":false,"id":517,"mutability":"mutable","name":"x","nameLocation":"4693:1:0","nodeType":"VariableDeclaration","scope":608,"src":"4686:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"},"typeName":{"id":516,"nodeType":"UserDefinedTypeName","pathNode":{"id":515,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":719,"src":"4686:6:0"},"referencedDeclaration":719,"src":"4686:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"visibility":"internal"}],"id":523,"initialValue":{"arguments":[{"hexValue":"31323334","id":521,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4708:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":520,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4697:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$719_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":519,"nodeType":"UserDefinedTypeName","pathNode":{"id":518,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":719,"src":"4701:6:0"},"referencedDeclaration":719,"src":"4701:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}}},"id":522,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4697:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4686:27:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":529,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":525,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":517,"src":"4731:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"id":526,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":708,"src":"4731:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":527,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4731:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":528,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4742:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4731:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":524,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4723:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":530,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4723:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":531,"nodeType":"ExpressionStatement","src":"4723:24:0"},{"expression":{"arguments":[{"hexValue":"6372656174652032","id":535,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4770:10:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""},"value":"create 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""}],"expression":{"id":532,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4758:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":534,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4758:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":536,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4758:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":537,"nodeType":"ExpressionStatement","src":"4758:23:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307863616665","id":545,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4820:6:0","typeDescriptions":{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"},"value":"0xcafe"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"}],"id":544,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4812:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":543,"name":"uint160","nodeType":"ElementaryTypeName","src":"4812:7:0","typeDescriptions":{}}},"id":546,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4812:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":542,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4804:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":541,"name":"address","nodeType":"ElementaryTypeName","src":"4804:7:0","typeDescriptions":{}}},"id":547,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4804:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":538,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4791:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":540,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4791:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":548,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4791:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":549,"nodeType":"ExpressionStatement","src":"4791:38:0"},{"assignments":[552],"declarations":[{"constant":false,"id":552,"mutability":"mutable","name":"y","nameLocation":"4846:1:0","nodeType":"VariableDeclaration","scope":608,"src":"4839:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"},"typeName":{"id":551,"nodeType":"UserDefinedTypeName","pathNode":{"id":550,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":719,"src":"4839:6:0"},"referencedDeclaration":719,"src":"4839:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"visibility":"internal"}],"id":566,"initialValue":{"arguments":[{"hexValue":"31323334","id":564,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4889:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":555,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4850:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$719_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":554,"nodeType":"UserDefinedTypeName","pathNode":{"id":553,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":719,"src":"4854:6:0"},"referencedDeclaration":719,"src":"4854:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}}},"id":563,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"names":["salt"],"nodeType":"FunctionCallOptions","options":[{"arguments":[{"arguments":[{"hexValue":"3432","id":560,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4883:2:0","typeDescriptions":{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"},"value":"42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"}],"id":559,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4875:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":558,"name":"uint256","nodeType":"ElementaryTypeName","src":"4875:7:0","typeDescriptions":{}}},"id":561,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4875:11:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":557,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4867:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_bytes32_$","typeString":"type(bytes32)"},"typeName":{"id":556,"name":"bytes32","nodeType":"ElementaryTypeName","src":"4867:7:0","typeDescriptions":{}}},"id":562,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4867:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"src":"4850:38:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$719_$salt","typeString":"function (uint256) returns (contract FooBar)"}},"id":565,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4850:44:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4839:55:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":572,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":568,"name":"y","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":552,"src":"4912:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"id":569,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":708,"src":"4912:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":570,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4912:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":571,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4923:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4912:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":567,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4904:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":573,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4904:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":574,"nodeType":"ExpressionStatement","src":"4904:24:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":578,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4950:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":575,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4938:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":577,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4938:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":579,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4938:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":580,"nodeType":"ExpressionStatement","src":"4938:20:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":581,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"5042:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":583,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"5042:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":584,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5042:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":585,"nodeType":"ExpressionStatement","src":"5042:14:0"},{"expression":{"arguments":[{"hexValue":"31323334","id":589,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"5077:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":588,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"5066:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$719_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":587,"nodeType":"UserDefinedTypeName","pathNode":{"id":586,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":719,"src":"5070:6:0"},"referencedDeclaration":719,"src":"5070:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}}},"id":590,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5066:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"id":591,"nodeType":"ExpressionStatement","src":"5066:16:0"},{"expression":{"arguments":[{"hexValue":"6e6f6e636520656e64","id":595,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"5105:11:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa629e6661ad2a2bdb09cf9a3a276ce0d722482ae5c2887650751be0938847e8","typeString":"literal_string \"nonce end\""},"value":"nonce end"},{"arguments":[{"arguments":[{"arguments":[{"id":602,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"5146:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}],"id":601,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5138:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":600,"name":"address","nodeType":"ElementaryTypeName","src":"5138:7:0","typeDescriptions":{}}},"id":603,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5138:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":598,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"5126:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":599,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"5126:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":604,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5126:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint64","typeString":"uint64"}],"id":597,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5118:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":596,"name":"uint256","nodeType":"ElementaryTypeName","src":"5118:7:0","typeDescriptions":{}}},"id":605,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5118:35:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa629e6661ad2a2bdb09cf9a3a276ce0d722482ae5c2887650751be0938847e8","typeString":"literal_string \"nonce end\""},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":592,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5093:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":594,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"5093:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":606,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5093:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":607,"nodeType":"ExpressionStatement","src":"5093:61:0"}]},"documentation":{"id":379,"nodeType":"StructuredDocumentation","src":"3842:56:0","text":"@notice example function, to test vm.broadcast with."},"functionSelector":"bef03abc","implemented":true,"kind":"function","modifiers":[],"name":"runBroadcast","nameLocation":"3912:12:0","parameters":{"id":380,"nodeType":"ParameterList","parameters":[],"src":"3924:2:0"},"returnParameters":{"id":381,"nodeType":"ParameterList","parameters":[],"src":"3934:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":633,"nodeType":"FunctionDefinition","src":"5256:143:0","nodes":[],"body":{"id":632,"nodeType":"Block","src":"5305:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":618,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":612,"src":"5327:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":615,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5315:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":617,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5315:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":619,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5315:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":620,"nodeType":"ExpressionStatement","src":"5315:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":624,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"5352:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":627,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"5380:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":628,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"5380:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":626,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5372:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":625,"name":"address","nodeType":"ElementaryTypeName","src":"5372:7:0","typeDescriptions":{}}},"id":629,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5372:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":621,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5340:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":623,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"5340:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":630,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5340:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":631,"nodeType":"ExpressionStatement","src":"5340:52:0"}]},"documentation":{"id":610,"nodeType":"StructuredDocumentation","src":"5167:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"5265:5:0","parameters":{"id":613,"nodeType":"ParameterList","parameters":[{"constant":false,"id":612,"mutability":"mutable","name":"_v","nameLocation":"5287:2:0","nodeType":"VariableDeclaration","scope":633,"src":"5271:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":611,"name":"string","nodeType":"ElementaryTypeName","src":"5271:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5270:20:0"},"returnParameters":{"id":614,"nodeType":"ParameterList","parameters":[],"src":"5305:0:0"},"scope":706,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":648,"nodeType":"FunctionDefinition","src":"5405:95:0","nodes":[],"body":{"id":647,"nodeType":"Block","src":"5449:51:0","nodes":[],"statements":[{"expression":{"id":639,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5459:9:0","subExpression":{"id":638,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5459:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":640,"nodeType":"ExpressionStatement","src":"5459:9:0"},{"expression":{"arguments":[{"id":644,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":635,"src":"5490:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":641,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5478:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":643,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5478:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":645,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5478:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":646,"nodeType":"ExpressionStatement","src":"5478:15:0"}]},"functionSelector":"7e79255d","implemented":true,"kind":"function","modifiers":[],"name":"call1","nameLocation":"5414:5:0","parameters":{"id":636,"nodeType":"ParameterList","parameters":[{"constant":false,"id":635,"mutability":"mutable","name":"_v","nameLocation":"5436:2:0","nodeType":"VariableDeclaration","scope":648,"src":"5420:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":634,"name":"string","nodeType":"ElementaryTypeName","src":"5420:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5419:20:0"},"returnParameters":{"id":637,"nodeType":"ParameterList","parameters":[],"src":"5449:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":663,"nodeType":"FunctionDefinition","src":"5506:95:0","nodes":[],"body":{"id":662,"nodeType":"Block","src":"5550:51:0","nodes":[],"statements":[{"expression":{"id":654,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5560:9:0","subExpression":{"id":653,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5560:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":655,"nodeType":"ExpressionStatement","src":"5560:9:0"},{"expression":{"arguments":[{"id":659,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":650,"src":"5591:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":656,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5579:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":658,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5579:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":660,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5579:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":661,"nodeType":"ExpressionStatement","src":"5579:15:0"}]},"functionSelector":"8d3ef7ca","implemented":true,"kind":"function","modifiers":[],"name":"call2","nameLocation":"5515:5:0","parameters":{"id":651,"nodeType":"ParameterList","parameters":[{"constant":false,"id":650,"mutability":"mutable","name":"_v","nameLocation":"5537:2:0","nodeType":"VariableDeclaration","scope":663,"src":"5521:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":649,"name":"string","nodeType":"ElementaryTypeName","src":"5521:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5520:20:0"},"returnParameters":{"id":652,"nodeType":"ParameterList","parameters":[],"src":"5550:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":678,"nodeType":"FunctionDefinition","src":"5607:98:0","nodes":[],"body":{"id":677,"nodeType":"Block","src":"5653:52:0","nodes":[],"statements":[{"expression":{"id":669,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5663:9:0","subExpression":{"id":668,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5663:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":670,"nodeType":"ExpressionStatement","src":"5663:9:0"},{"expression":{"arguments":[{"id":674,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":665,"src":"5695:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":671,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"5682:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":673,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested2","nodeType":"MemberAccess","referencedDeclaration":693,"src":"5682:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":675,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5682:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":676,"nodeType":"ExpressionStatement","src":"5682:16:0"}]},"functionSelector":"a76ccdfa","implemented":true,"kind":"function","modifiers":[],"name":"nested1","nameLocation":"5616:7:0","parameters":{"id":666,"nodeType":"ParameterList","parameters":[{"constant":false,"id":665,"mutability":"mutable","name":"_v","nameLocation":"5640:2:0","nodeType":"VariableDeclaration","scope":678,"src":"5624:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":664,"name":"string","nodeType":"ElementaryTypeName","src":"5624:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5623:20:0"},"returnParameters":{"id":667,"nodeType":"ParameterList","parameters":[],"src":"5653:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":693,"nodeType":"FunctionDefinition","src":"5711:97:0","nodes":[],"body":{"id":692,"nodeType":"Block","src":"5757:51:0","nodes":[],"statements":[{"expression":{"id":684,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5767:9:0","subExpression":{"id":683,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5767:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":685,"nodeType":"ExpressionStatement","src":"5767:9:0"},{"expression":{"arguments":[{"id":689,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":680,"src":"5798:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":686,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5786:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":688,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5786:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":690,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5786:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":691,"nodeType":"ExpressionStatement","src":"5786:15:0"}]},"functionSelector":"dbf1282f","implemented":true,"kind":"function","modifiers":[],"name":"nested2","nameLocation":"5720:7:0","parameters":{"id":681,"nodeType":"ParameterList","parameters":[{"constant":false,"id":680,"mutability":"mutable","name":"_v","nameLocation":"5744:2:0","nodeType":"VariableDeclaration","scope":693,"src":"5728:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":679,"name":"string","nodeType":"ElementaryTypeName","src":"5728:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5727:20:0"},"returnParameters":{"id":682,"nodeType":"ParameterList","parameters":[],"src":"5757:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":705,"nodeType":"FunctionDefinition","src":"5814:84:0","nodes":[],"body":{"id":704,"nodeType":"Block","src":"5866:32:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":701,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":695,"src":"5888:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":698,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5876:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":700,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5876:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":702,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5876:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":703,"nodeType":"ExpressionStatement","src":"5876:15:0"}]},"functionSelector":"7f8b915c","implemented":true,"kind":"function","modifiers":[],"name":"callPure","nameLocation":"5823:8:0","parameters":{"id":696,"nodeType":"ParameterList","parameters":[{"constant":false,"id":695,"mutability":"mutable","name":"_v","nameLocation":"5848:2:0","nodeType":"VariableDeclaration","scope":705,"src":"5832:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":694,"name":"string","nodeType":"ElementaryTypeName","src":"5832:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5831:20:0"},"returnParameters":{"id":697,"nodeType":"ParameterList","parameters":[],"src":"5866:0:0"},"scope":706,"stateMutability":"pure","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[719],"contractKind":"contract","documentation":{"id":193,"nodeType":"StructuredDocumentation","src":"2415:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[706],"name":"ScriptExample","nameLocation":"2550:13:0","scope":720,"usedErrors":[]},{"id":719,"nodeType":"ContractDefinition","src":"5902:96:0","nodes":[{"id":708,"nodeType":"VariableDeclaration","src":"5924:18:0","nodes":[],"constant":false,"functionSelector":"c2985578","mutability":"mutable","name":"foo","nameLocation":"5939:3:0","scope":719,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":707,"name":"uint256","nodeType":"ElementaryTypeName","src":"5924:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":718,"nodeType":"FunctionDefinition","src":"5949:47:0","nodes":[],"body":{"id":717,"nodeType":"Block","src":"5972:24:0","nodes":[],"statements":[{"expression":{"id":715,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":713,"name":"foo","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":708,"src":"5982:3:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":714,"name":"v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":710,"src":"5988:1:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5982:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":716,"nodeType":"ExpressionStatement","src":"5982:7:0"}]},"implemented":true,"kind":"constructor","modifiers":[],"name":"","nameLocation":"-1:-1:-1","parameters":{"id":711,"nodeType":"ParameterList","parameters":[{"constant":false,"id":710,"mutability":"mutable","name":"v","nameLocation":"5969:1:0","nodeType":"VariableDeclaration","scope":718,"src":"5961:9:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":709,"name":"uint256","nodeType":"ElementaryTypeName","src":"5961:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"5960:11:0"},"returnParameters":{"id":712,"nodeType":"ParameterList","parameters":[],"src":"5972:0:0"},"scope":719,"stateMutability":"nonpayable","virtual":false,"visibility":"public"}],"abstract":false,"baseContracts":[],"canonicalName":"FooBar","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[719],"name":"FooBar","nameLocation":"5911:6:0","scope":720,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file diff --git a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/console.json b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/console.json index d051823361a1..390e798a4701 100644 --- a/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/console.json +++ b/op-chain-ops/script/testdata/test-artifacts/ScriptExample.s.sol/console.json @@ -1 +1 @@ -{"abi":[],"bytecode":{"object":"0x602d6037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300080f000a","sourceMap":"791:1622:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;791:1622:0;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300080f000a","sourceMap":"791:1622:0:-:0;;;;;;;;","linkReferences":{}},"methodIdentifiers":{},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"console\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x4fc2ffeba31e146fc3a2edef7cc8b7e82fb2344454d32d6371a62c6d76dfcb4e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a517c69eba90ee5f3efb198a2247d5744bed8e17d332ce2dda4d3cf3a2c334f9\",\"dweb:/ipfs/QmciXeDt5EEhmjH5xECVk2VX6EbnER5UFv58dvGgemwkKK\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"console"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x4fc2ffeba31e146fc3a2edef7cc8b7e82fb2344454d32d6371a62c6d76dfcb4e","urls":["bzz-raw://a517c69eba90ee5f3efb198a2247d5744bed8e17d332ce2dda4d3cf3a2c334f9","dweb:/ipfs/QmciXeDt5EEhmjH5xECVk2VX6EbnER5UFv58dvGgemwkKK"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[],"types":{}},"userdoc":{"version":1,"kind":"user"},"devdoc":{"version":1,"kind":"dev"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":677,"exportedSymbols":{"FooBar":[676],"ScriptExample":[663],"Vm":[55],"console":[192]},"nodeType":"SourceUnit","src":"32:5697:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":55,"nodeType":"ContractDefinition","src":"120:616:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":55,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":38,"nodeType":"FunctionDefinition","src":"516:30:0","nodes":[],"functionSelector":"afc98040","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"525:9:0","parameters":{"id":36,"nodeType":"ParameterList","parameters":[],"src":"534:2:0"},"returnParameters":{"id":37,"nodeType":"ParameterList","parameters":[],"src":"545:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":43,"nodeType":"FunctionDefinition","src":"551:47:0","nodes":[],"functionSelector":"e6962cdb","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"560:9:0","parameters":{"id":41,"nodeType":"ParameterList","parameters":[{"constant":false,"id":40,"mutability":"mutable","name":"msgSender","nameLocation":"578:9:0","nodeType":"VariableDeclaration","scope":43,"src":"570:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":39,"name":"address","nodeType":"ElementaryTypeName","src":"570:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"569:19:0"},"returnParameters":{"id":42,"nodeType":"ParameterList","parameters":[],"src":"597:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":48,"nodeType":"FunctionDefinition","src":"603:52:0","nodes":[],"functionSelector":"7fec2a8d","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"612:14:0","parameters":{"id":46,"nodeType":"ParameterList","parameters":[{"constant":false,"id":45,"mutability":"mutable","name":"msgSender","nameLocation":"635:9:0","nodeType":"VariableDeclaration","scope":48,"src":"627:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":44,"name":"address","nodeType":"ElementaryTypeName","src":"627:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"626:19:0"},"returnParameters":{"id":47,"nodeType":"ParameterList","parameters":[],"src":"654:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":51,"nodeType":"FunctionDefinition","src":"660:35:0","nodes":[],"functionSelector":"7fb5297f","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"669:14:0","parameters":{"id":49,"nodeType":"ParameterList","parameters":[],"src":"683:2:0"},"returnParameters":{"id":50,"nodeType":"ParameterList","parameters":[],"src":"694:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":54,"nodeType":"FunctionDefinition","src":"700:34:0","nodes":[],"functionSelector":"76eadd36","implemented":false,"kind":"function","modifiers":[],"name":"stopBroadcast","nameLocation":"709:13:0","parameters":{"id":52,"nodeType":"ParameterList","parameters":[],"src":"722:2:0"},"returnParameters":{"id":53,"nodeType":"ParameterList","parameters":[],"src":"733:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[55],"name":"Vm","nameLocation":"130:2:0","scope":677,"usedErrors":[]},{"id":192,"nodeType":"ContractDefinition","src":"791:1622:0","nodes":[{"id":61,"nodeType":"VariableDeclaration","src":"813:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"830:15:0","scope":192,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":56,"name":"address","nodeType":"ElementaryTypeName","src":"813:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":59,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"856:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":58,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"848:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":57,"name":"address","nodeType":"ElementaryTypeName","src":"848:7:0","typeDescriptions":{}}},"id":60,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"848:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":78,"nodeType":"FunctionDefinition","src":"906:221:0","nodes":[],"body":{"id":77,"nodeType":"Block","src":"1065:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"1084:37:0","statements":[{"nodeType":"YulAssignment","src":"1098:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"1107:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"1098:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":67,"isOffset":false,"isSlot":false,"src":"1107:4:0","valueSize":1},{"declaration":74,"isOffset":false,"isSlot":false,"src":"1098:5:0","valueSize":1}],"id":76,"nodeType":"InlineAssembly","src":"1075:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"915:25:0","parameters":{"id":68,"nodeType":"ParameterList","parameters":[{"constant":false,"id":67,"mutability":"mutable","name":"fnIn","nameLocation":"987:4:0","nodeType":"VariableDeclaration","scope":78,"src":"950:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":66,"nodeType":"FunctionTypeName","parameterTypes":{"id":64,"nodeType":"ParameterList","parameters":[{"constant":false,"id":63,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":66,"src":"959:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":62,"name":"bytes","nodeType":"ElementaryTypeName","src":"959:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"958:14:0"},"returnParameterTypes":{"id":65,"nodeType":"ParameterList","parameters":[],"src":"987:0:0"},"src":"950:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"940:57:0"},"returnParameters":{"id":75,"nodeType":"ParameterList","parameters":[{"constant":false,"id":74,"mutability":"mutable","name":"fnOut","nameLocation":"1058:5:0","nodeType":"VariableDeclaration","scope":78,"src":"1021:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":73,"nodeType":"FunctionTypeName","parameterTypes":{"id":71,"nodeType":"ParameterList","parameters":[{"constant":false,"id":70,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":73,"src":"1030:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":69,"name":"bytes","nodeType":"ElementaryTypeName","src":"1030:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1029:14:0"},"returnParameterTypes":{"id":72,"nodeType":"ParameterList","parameters":[],"src":"1058:0:0"},"src":"1021:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"1020:44:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":90,"nodeType":"FunctionDefinition","src":"1133:133:0","nodes":[],"body":{"id":89,"nodeType":"Block","src":"1194:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":86,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1251:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":84,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":106,"src":"1230:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":83,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":78,"src":"1204:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":85,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":87,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":88,"nodeType":"ExpressionStatement","src":"1204:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"1142:15:0","parameters":{"id":81,"nodeType":"ParameterList","parameters":[{"constant":false,"id":80,"mutability":"mutable","name":"payload","nameLocation":"1171:7:0","nodeType":"VariableDeclaration","scope":90,"src":"1158:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":79,"name":"bytes","nodeType":"ElementaryTypeName","src":"1158:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1157:22:0"},"returnParameters":{"id":82,"nodeType":"ParameterList","parameters":[],"src":"1194:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":106,"nodeType":"FunctionDefinition","src":"1272:380:0","nodes":[],"body":{"id":105,"nodeType":"Block","src":"1336:316:0","nodes":[],"statements":[{"assignments":[96],"declarations":[{"constant":false,"id":96,"mutability":"mutable","name":"payloadLength","nameLocation":"1354:13:0","nodeType":"VariableDeclaration","scope":105,"src":"1346:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":95,"name":"uint256","nodeType":"ElementaryTypeName","src":"1346:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":99,"initialValue":{"expression":{"id":97,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":92,"src":"1370:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":98,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1370:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1346:38:0"},{"assignments":[101],"declarations":[{"constant":false,"id":101,"mutability":"mutable","name":"consoleAddress","nameLocation":"1402:14:0","nodeType":"VariableDeclaration","scope":105,"src":"1394:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":100,"name":"address","nodeType":"ElementaryTypeName","src":"1394:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":103,"initialValue":{"id":102,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":61,"src":"1419:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1394:40:0"},{"AST":{"nodeType":"YulBlock","src":"1496:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1510:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1534:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1543:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1530:3:0"},"nodeType":"YulFunctionCall","src":"1530:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1514:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1559:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1579:3:0"},"nodeType":"YulFunctionCall","src":"1579:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1586:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1602:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1616:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1631:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1634:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1568:10:0"},"nodeType":"YulFunctionCall","src":"1568:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1563:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":101,"isOffset":false,"isSlot":false,"src":"1586:14:0","valueSize":1},{"declaration":92,"isOffset":false,"isSlot":false,"src":"1534:7:0","valueSize":1},{"declaration":96,"isOffset":false,"isSlot":false,"src":"1616:13:0","valueSize":1}],"id":104,"nodeType":"InlineAssembly","src":"1487:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1281:19:0","parameters":{"id":93,"nodeType":"ParameterList","parameters":[{"constant":false,"id":92,"mutability":"mutable","name":"payload","nameLocation":"1314:7:0","nodeType":"VariableDeclaration","scope":106,"src":"1301:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":91,"name":"bytes","nodeType":"ElementaryTypeName","src":"1301:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1300:22:0"},"returnParameters":{"id":94,"nodeType":"ParameterList","parameters":[],"src":"1336:0:0"},"scope":192,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":120,"nodeType":"FunctionDefinition","src":"1658:121:0","nodes":[],"body":{"id":119,"nodeType":"Block","src":"1703:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":114,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1753:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":115,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":108,"src":"1768:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":112,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1729:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":113,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1729:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":116,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1729:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":111,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1713:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":117,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1713:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":118,"nodeType":"ExpressionStatement","src":"1713:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1667:3:0","parameters":{"id":109,"nodeType":"ParameterList","parameters":[{"constant":false,"id":108,"mutability":"mutable","name":"p0","nameLocation":"1685:2:0","nodeType":"VariableDeclaration","scope":120,"src":"1671:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":107,"name":"string","nodeType":"ElementaryTypeName","src":"1671:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1670:18:0"},"returnParameters":{"id":110,"nodeType":"ParameterList","parameters":[],"src":"1703:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":137,"nodeType":"FunctionDefinition","src":"1785:139:0","nodes":[],"body":{"id":136,"nodeType":"Block","src":"1839:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":130,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1889:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":131,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":122,"src":"1909:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":132,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":124,"src":"1913:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":128,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1865:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":129,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1865:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":133,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1865:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":127,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1849:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":134,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1849:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":135,"nodeType":"ExpressionStatement","src":"1849:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1794:3:0","parameters":{"id":125,"nodeType":"ParameterList","parameters":[{"constant":false,"id":122,"mutability":"mutable","name":"p0","nameLocation":"1812:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1798:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":121,"name":"string","nodeType":"ElementaryTypeName","src":"1798:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":124,"mutability":"mutable","name":"p1","nameLocation":"1821:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1816:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":123,"name":"bool","nodeType":"ElementaryTypeName","src":"1816:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1797:27:0"},"returnParameters":{"id":126,"nodeType":"ParameterList","parameters":[],"src":"1839:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":154,"nodeType":"FunctionDefinition","src":"1930:145:0","nodes":[],"body":{"id":153,"nodeType":"Block","src":"1987:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":147,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2037:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":148,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":139,"src":"2060:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":149,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":141,"src":"2064:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":145,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2013:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":146,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2013:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":150,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2013:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":144,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1997:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":151,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1997:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":152,"nodeType":"ExpressionStatement","src":"1997:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1939:3:0","parameters":{"id":142,"nodeType":"ParameterList","parameters":[{"constant":false,"id":139,"mutability":"mutable","name":"p0","nameLocation":"1957:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1943:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":138,"name":"string","nodeType":"ElementaryTypeName","src":"1943:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":141,"mutability":"mutable","name":"p1","nameLocation":"1969:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1961:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":140,"name":"uint256","nodeType":"ElementaryTypeName","src":"1961:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1942:30:0"},"returnParameters":{"id":143,"nodeType":"ParameterList","parameters":[],"src":"1987:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":171,"nodeType":"FunctionDefinition","src":"2081:145:0","nodes":[],"body":{"id":170,"nodeType":"Block","src":"2138:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":164,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2188:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":165,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":156,"src":"2211:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":166,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":158,"src":"2215:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":162,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2164:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":163,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2164:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":167,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2164:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":161,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2148:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":168,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2148:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":169,"nodeType":"ExpressionStatement","src":"2148:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2090:3:0","parameters":{"id":159,"nodeType":"ParameterList","parameters":[{"constant":false,"id":156,"mutability":"mutable","name":"p0","nameLocation":"2108:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2094:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":155,"name":"string","nodeType":"ElementaryTypeName","src":"2094:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":158,"mutability":"mutable","name":"p1","nameLocation":"2120:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2112:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":157,"name":"address","nodeType":"ElementaryTypeName","src":"2112:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"2093:30:0"},"returnParameters":{"id":160,"nodeType":"ParameterList","parameters":[],"src":"2138:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":191,"nodeType":"FunctionDefinition","src":"2232:179:0","nodes":[],"body":{"id":190,"nodeType":"Block","src":"2313:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":183,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2363:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":184,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2392:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":185,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":175,"src":"2396:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":186,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":177,"src":"2400:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":181,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2339:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":182,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2339:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":187,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2339:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":180,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2323:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":188,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2323:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":189,"nodeType":"ExpressionStatement","src":"2323:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2241:3:0","parameters":{"id":178,"nodeType":"ParameterList","parameters":[{"constant":false,"id":173,"mutability":"mutable","name":"p0","nameLocation":"2259:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2245:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":172,"name":"string","nodeType":"ElementaryTypeName","src":"2245:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":175,"mutability":"mutable","name":"p1","nameLocation":"2277:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2263:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":174,"name":"string","nodeType":"ElementaryTypeName","src":"2263:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":177,"mutability":"mutable","name":"p2","nameLocation":"2295:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2281:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":176,"name":"string","nodeType":"ElementaryTypeName","src":"2281:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2244:54:0"},"returnParameters":{"id":179,"nodeType":"ParameterList","parameters":[],"src":"2313:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[192],"name":"console","nameLocation":"799:7:0","scope":677,"usedErrors":[]},{"id":663,"nodeType":"ContractDefinition","src":"2541:3089:0","nodes":[{"id":207,"nodeType":"VariableDeclaration","src":"2571:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2597:10:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":194,"name":"address","nodeType":"ElementaryTypeName","src":"2571:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2644:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":201,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2634:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":203,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2634:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":200,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2626:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":199,"name":"uint256","nodeType":"ElementaryTypeName","src":"2626:7:0","typeDescriptions":{}}},"id":204,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2626:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":198,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2618:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":197,"name":"uint160","nodeType":"ElementaryTypeName","src":"2618:7:0","typeDescriptions":{}}},"id":205,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2618:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":196,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2610:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":195,"name":"address","nodeType":"ElementaryTypeName","src":"2610:7:0","typeDescriptions":{}}},"id":206,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2610:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":213,"nodeType":"VariableDeclaration","src":"2671:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2692:2:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"},"typeName":{"id":209,"nodeType":"UserDefinedTypeName","pathNode":{"id":208,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":55,"src":"2671:2:0"},"referencedDeclaration":55,"src":"2671:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"value":{"arguments":[{"id":211,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":207,"src":"2700:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":210,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":55,"src":"2697:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$55_$","typeString":"type(contract Vm)"}},"id":212,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2697:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"visibility":"internal"},{"id":215,"nodeType":"VariableDeclaration","src":"2775:22:0","nodes":[],"constant":false,"functionSelector":"61bc221a","mutability":"mutable","name":"counter","nameLocation":"2790:7:0","scope":663,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":214,"name":"uint256","nodeType":"ElementaryTypeName","src":"2775:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":378,"nodeType":"FunctionDefinition","src":"2887:949:0","nodes":[],"body":{"id":377,"nodeType":"Block","src":"2909:927:0","nodes":[],"statements":[{"assignments":[220],"declarations":[{"constant":false,"id":220,"mutability":"mutable","name":"x","nameLocation":"2924:1:0","nodeType":"VariableDeclaration","scope":377,"src":"2919:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":219,"name":"bool","nodeType":"ElementaryTypeName","src":"2919:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":226,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":223,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2937:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":224,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2953:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":221,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"2928:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":222,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2928:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":225,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2928:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2919:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":230,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2981:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":231,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":220,"src":"3004:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":227,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"2969:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":229,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":137,"src":"2969:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2969:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":233,"nodeType":"ExpressionStatement","src":"2969:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":237,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3029:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":240,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3054:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":239,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3046:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":238,"name":"address","nodeType":"ElementaryTypeName","src":"3046:7:0","typeDescriptions":{}}},"id":241,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3046:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":234,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3017:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":236,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3017:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":242,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3017:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":243,"nodeType":"ExpressionStatement","src":"3017:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":247,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3082:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":252,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3120:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":251,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3112:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":250,"name":"address","nodeType":"ElementaryTypeName","src":"3112:7:0","typeDescriptions":{}}},"id":253,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3112:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":248,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3100:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3100:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":254,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3100:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":244,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3070:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":246,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3070:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":255,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3070:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":256,"nodeType":"ExpressionStatement","src":"3070:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":260,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3149:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":263,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3172:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":264,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3172:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":262,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3164:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":261,"name":"address","nodeType":"ElementaryTypeName","src":"3164:7:0","typeDescriptions":{}}},"id":265,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3164:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":257,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3137:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":259,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3137:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":266,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3137:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":267,"nodeType":"ExpressionStatement","src":"3137:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":271,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3206:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":276,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3242:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":277,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3242:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":275,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3234:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":274,"name":"address","nodeType":"ElementaryTypeName","src":"3234:7:0","typeDescriptions":{}}},"id":278,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3234:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":272,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3222:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":273,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3222:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":279,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3222:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":268,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3194:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":270,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3194:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":280,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3194:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":281,"nodeType":"ExpressionStatement","src":"3194:61:0"},{"assignments":[283],"declarations":[{"constant":false,"id":283,"mutability":"mutable","name":"json","nameLocation":"3280:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3266:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":282,"name":"string","nodeType":"ElementaryTypeName","src":"3266:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":285,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3287:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"3266:55:0"},{"assignments":[290],"declarations":[{"constant":false,"id":290,"mutability":"mutable","name":"keys","nameLocation":"3347:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3331:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":288,"name":"string","nodeType":"ElementaryTypeName","src":"3331:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":289,"nodeType":"ArrayTypeName","src":"3331:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":296,"initialValue":{"arguments":[{"id":293,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":283,"src":"3371:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":294,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3377:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":291,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3354:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":292,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3354:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":295,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3354:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3331:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":300,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3414:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":301,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3422:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":303,"indexExpression":{"hexValue":"30","id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3427:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3422:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":304,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3431:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":306,"indexExpression":{"hexValue":"31","id":305,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3436:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3431:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":297,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3402:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":299,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":191,"src":"3402:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":307,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3402:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":308,"nodeType":"ExpressionStatement","src":"3402:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":312,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3461:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":309,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3450:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":311,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3450:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":313,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3450:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":314,"nodeType":"ExpressionStatement","src":"3450:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":322,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3517:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":321,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3509:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":320,"name":"uint160","nodeType":"ElementaryTypeName","src":"3509:7:0","typeDescriptions":{}}},"id":323,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3509:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":319,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3501:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":318,"name":"address","nodeType":"ElementaryTypeName","src":"3501:7:0","typeDescriptions":{}}},"id":324,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3501:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":315,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3487:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":317,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3487:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3487:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":326,"nodeType":"ExpressionStatement","src":"3487:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":330,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3545:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":327,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3534:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":329,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3534:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3534:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":332,"nodeType":"ExpressionStatement","src":"3534:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":336,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3582:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":339,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3617:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":340,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3617:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":338,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3609:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":337,"name":"address","nodeType":"ElementaryTypeName","src":"3609:7:0","typeDescriptions":{}}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3609:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":333,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3570:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":335,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3570:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3570:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3570:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3651:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":350,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3689:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}],"id":349,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3681:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":348,"name":"address","nodeType":"ElementaryTypeName","src":"3681:7:0","typeDescriptions":{}}},"id":351,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3681:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":344,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3639:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3639:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3639:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":353,"nodeType":"ExpressionStatement","src":"3639:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":357,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3716:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":354,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3705:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":356,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3705:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":358,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3705:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":359,"nodeType":"ExpressionStatement","src":"3705:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":360,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3741:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":362,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3741:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":363,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3741:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":364,"nodeType":"ExpressionStatement","src":"3741:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":368,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3776:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":365,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3765:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":367,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":590,"src":"3765:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":369,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3765:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":370,"nodeType":"ExpressionStatement","src":"3765:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":374,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3821:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":371,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3809:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":373,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"3809:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":375,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3809:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":376,"nodeType":"ExpressionStatement","src":"3809:20:0"}]},"documentation":{"id":216,"nodeType":"StructuredDocumentation","src":"2804:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2896:3:0","parameters":{"id":217,"nodeType":"ParameterList","parameters":[],"src":"2899:2:0"},"returnParameters":{"id":218,"nodeType":"ParameterList","parameters":[],"src":"2909:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":566,"nodeType":"FunctionDefinition","src":"3903:988:0","nodes":[],"body":{"id":565,"nodeType":"Block","src":"3934:957:0","nodes":[],"statements":[{"expression":{"arguments":[{"hexValue":"74657374696e672073696e676c65","id":385,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3956:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""},"value":"testing single"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""}],"expression":{"id":382,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3944:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":384,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"3944:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":386,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3944:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":387,"nodeType":"ExpressionStatement","src":"3944:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":388,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3983:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":390,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"3983:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":391,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3983:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":392,"nodeType":"ExpressionStatement","src":"3983:14:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c31","id":396,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4018:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""},"value":"single_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""}],"expression":{"id":393,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4007:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":395,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4007:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":397,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4007:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":398,"nodeType":"ExpressionStatement","src":"4007:26:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c32","id":402,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4054:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""},"value":"single_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""}],"expression":{"id":399,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4043:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":401,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":620,"src":"4043:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":403,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4043:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":404,"nodeType":"ExpressionStatement","src":"4043:26:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073746172742f73746f70","id":408,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4092:20:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""},"value":"testing start/stop"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""}],"expression":{"id":405,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4080:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":407,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4080:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":409,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4080:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":410,"nodeType":"ExpressionStatement","src":"4080:33:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078633066666565","id":418,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4157:8:0","typeDescriptions":{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"},"value":"0xc0ffee"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"}],"id":417,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4149:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":416,"name":"uint160","nodeType":"ElementaryTypeName","src":"4149:7:0","typeDescriptions":{}}},"id":419,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4149:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":415,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4141:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":414,"name":"address","nodeType":"ElementaryTypeName","src":"4141:7:0","typeDescriptions":{}}},"id":420,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4141:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":411,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4123:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":413,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4123:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":421,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4123:45:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":422,"nodeType":"ExpressionStatement","src":"4123:45:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c31","id":426,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4189:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""},"value":"startstop_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""}],"expression":{"id":423,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4178:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":425,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4178:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":427,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4178:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":428,"nodeType":"ExpressionStatement","src":"4178:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c32","id":432,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4228:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""},"value":"startstop_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""}],"expression":{"id":429,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4217:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":431,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":620,"src":"4217:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":433,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4217:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":434,"nodeType":"ExpressionStatement","src":"4217:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f70757265","id":438,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4270:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""},"value":"startstop_pure"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""}],"expression":{"id":435,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4256:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":437,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"callPure","nodeType":"MemberAccess","referencedDeclaration":662,"src":"4256:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure external"}},"id":439,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4256:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":440,"nodeType":"ExpressionStatement","src":"4256:31:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":441,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4297:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":443,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4297:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":444,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4297:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":445,"nodeType":"ExpressionStatement","src":"4297:18:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c33","id":449,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4336:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""},"value":"startstop_call3"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""}],"expression":{"id":446,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4325:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":448,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":605,"src":"4325:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":450,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4325:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":451,"nodeType":"ExpressionStatement","src":"4325:29:0"},{"expression":{"arguments":[{"hexValue":"74657374696e67206e6573746564","id":455,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4377:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""},"value":"testing nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""}],"expression":{"id":452,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4365:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":454,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4365:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":456,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4365:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":457,"nodeType":"ExpressionStatement","src":"4365:29:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307831323334","id":465,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4438:6:0","typeDescriptions":{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"},"value":"0x1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"}],"id":464,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4430:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":463,"name":"uint160","nodeType":"ElementaryTypeName","src":"4430:7:0","typeDescriptions":{}}},"id":466,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4430:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":462,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4422:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":461,"name":"address","nodeType":"ElementaryTypeName","src":"4422:7:0","typeDescriptions":{}}},"id":467,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4422:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":458,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4404:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":460,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4404:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":468,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4404:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":469,"nodeType":"ExpressionStatement","src":"4404:43:0"},{"expression":{"arguments":[{"hexValue":"6e6573746564","id":473,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4470:8:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""},"value":"nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""}],"expression":{"id":470,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4457:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":472,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested1","nodeType":"MemberAccess","referencedDeclaration":635,"src":"4457:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":474,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4457:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":475,"nodeType":"ExpressionStatement","src":"4457:22:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":476,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4489:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":478,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4489:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":479,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4489:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":480,"nodeType":"ExpressionStatement","src":"4489:18:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206465706c6f796d656e74","id":484,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4530:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""},"value":"contract deployment"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""}],"expression":{"id":481,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4518:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":483,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4518:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":485,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4518:34:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":486,"nodeType":"ExpressionStatement","src":"4518:34:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078313233343536","id":494,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4591:8:0","typeDescriptions":{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"},"value":"0x123456"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"}],"id":493,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4583:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":492,"name":"uint160","nodeType":"ElementaryTypeName","src":"4583:7:0","typeDescriptions":{}}},"id":495,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4583:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":491,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4575:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":490,"name":"address","nodeType":"ElementaryTypeName","src":"4575:7:0","typeDescriptions":{}}},"id":496,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4575:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":487,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4562:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":489,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4562:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":497,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4562:40:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":498,"nodeType":"ExpressionStatement","src":"4562:40:0"},{"assignments":[501],"declarations":[{"constant":false,"id":501,"mutability":"mutable","name":"x","nameLocation":"4619:1:0","nodeType":"VariableDeclaration","scope":565,"src":"4612:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"},"typeName":{"id":500,"nodeType":"UserDefinedTypeName","pathNode":{"id":499,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4612:6:0"},"referencedDeclaration":676,"src":"4612:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"visibility":"internal"}],"id":507,"initialValue":{"arguments":[{"hexValue":"31323334","id":505,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4634:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":504,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4623:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":503,"nodeType":"UserDefinedTypeName","pathNode":{"id":502,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4627:6:0"},"referencedDeclaration":676,"src":"4627:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}}},"id":506,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4623:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4612:27:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":513,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":509,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":501,"src":"4657:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"id":510,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":665,"src":"4657:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":511,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4657:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":512,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4668:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4657:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":508,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4649:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":514,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4649:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":515,"nodeType":"ExpressionStatement","src":"4649:24:0"},{"expression":{"arguments":[{"hexValue":"6372656174652032","id":519,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4696:10:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""},"value":"create 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""}],"expression":{"id":516,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4684:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":518,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4684:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":520,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4684:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":521,"nodeType":"ExpressionStatement","src":"4684:23:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307863616665","id":529,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4746:6:0","typeDescriptions":{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"},"value":"0xcafe"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"}],"id":528,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4738:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":527,"name":"uint160","nodeType":"ElementaryTypeName","src":"4738:7:0","typeDescriptions":{}}},"id":530,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4738:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":526,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4730:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":525,"name":"address","nodeType":"ElementaryTypeName","src":"4730:7:0","typeDescriptions":{}}},"id":531,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4730:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":522,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4717:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":524,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4717:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":532,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4717:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":533,"nodeType":"ExpressionStatement","src":"4717:38:0"},{"assignments":[536],"declarations":[{"constant":false,"id":536,"mutability":"mutable","name":"y","nameLocation":"4772:1:0","nodeType":"VariableDeclaration","scope":565,"src":"4765:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"},"typeName":{"id":535,"nodeType":"UserDefinedTypeName","pathNode":{"id":534,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4765:6:0"},"referencedDeclaration":676,"src":"4765:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"visibility":"internal"}],"id":550,"initialValue":{"arguments":[{"hexValue":"31323334","id":548,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4815:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":539,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4776:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":538,"nodeType":"UserDefinedTypeName","pathNode":{"id":537,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":676,"src":"4780:6:0"},"referencedDeclaration":676,"src":"4780:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}}},"id":547,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"names":["salt"],"nodeType":"FunctionCallOptions","options":[{"arguments":[{"arguments":[{"hexValue":"3432","id":544,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4809:2:0","typeDescriptions":{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"},"value":"42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"}],"id":543,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4801:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":542,"name":"uint256","nodeType":"ElementaryTypeName","src":"4801:7:0","typeDescriptions":{}}},"id":545,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4801:11:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":541,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4793:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_bytes32_$","typeString":"type(bytes32)"},"typeName":{"id":540,"name":"bytes32","nodeType":"ElementaryTypeName","src":"4793:7:0","typeDescriptions":{}}},"id":546,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4793:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"src":"4776:38:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$676_$salt","typeString":"function (uint256) returns (contract FooBar)"}},"id":549,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4776:44:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4765:55:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":556,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":552,"name":"y","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":536,"src":"4838:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$676","typeString":"contract FooBar"}},"id":553,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":665,"src":"4838:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":554,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4838:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":555,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4849:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4838:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":551,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4830:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":557,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4830:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":558,"nodeType":"ExpressionStatement","src":"4830:24:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":562,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4876:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":559,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4864:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":561,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4864:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":563,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4864:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":564,"nodeType":"ExpressionStatement","src":"4864:20:0"}]},"documentation":{"id":379,"nodeType":"StructuredDocumentation","src":"3842:56:0","text":"@notice example function, to test vm.broadcast with."},"functionSelector":"bef03abc","implemented":true,"kind":"function","modifiers":[],"name":"runBroadcast","nameLocation":"3912:12:0","parameters":{"id":380,"nodeType":"ParameterList","parameters":[],"src":"3924:2:0"},"returnParameters":{"id":381,"nodeType":"ParameterList","parameters":[],"src":"3934:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":590,"nodeType":"FunctionDefinition","src":"4986:143:0","nodes":[],"body":{"id":589,"nodeType":"Block","src":"5035:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":575,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":569,"src":"5057:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":572,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5045:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":574,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5045:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":576,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5045:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":577,"nodeType":"ExpressionStatement","src":"5045:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":581,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"5082:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":584,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"5110:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":585,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"5110:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":583,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5102:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":582,"name":"address","nodeType":"ElementaryTypeName","src":"5102:7:0","typeDescriptions":{}}},"id":586,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5102:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":578,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5070:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":580,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"5070:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":587,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5070:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":588,"nodeType":"ExpressionStatement","src":"5070:52:0"}]},"documentation":{"id":567,"nodeType":"StructuredDocumentation","src":"4897:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"4995:5:0","parameters":{"id":570,"nodeType":"ParameterList","parameters":[{"constant":false,"id":569,"mutability":"mutable","name":"_v","nameLocation":"5017:2:0","nodeType":"VariableDeclaration","scope":590,"src":"5001:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":568,"name":"string","nodeType":"ElementaryTypeName","src":"5001:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5000:20:0"},"returnParameters":{"id":571,"nodeType":"ParameterList","parameters":[],"src":"5035:0:0"},"scope":663,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":605,"nodeType":"FunctionDefinition","src":"5135:95:0","nodes":[],"body":{"id":604,"nodeType":"Block","src":"5179:51:0","nodes":[],"statements":[{"expression":{"id":596,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5189:9:0","subExpression":{"id":595,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5189:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":597,"nodeType":"ExpressionStatement","src":"5189:9:0"},{"expression":{"arguments":[{"id":601,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":592,"src":"5220:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":598,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5208:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":600,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5208:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":602,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5208:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":603,"nodeType":"ExpressionStatement","src":"5208:15:0"}]},"functionSelector":"7e79255d","implemented":true,"kind":"function","modifiers":[],"name":"call1","nameLocation":"5144:5:0","parameters":{"id":593,"nodeType":"ParameterList","parameters":[{"constant":false,"id":592,"mutability":"mutable","name":"_v","nameLocation":"5166:2:0","nodeType":"VariableDeclaration","scope":605,"src":"5150:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":591,"name":"string","nodeType":"ElementaryTypeName","src":"5150:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5149:20:0"},"returnParameters":{"id":594,"nodeType":"ParameterList","parameters":[],"src":"5179:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":620,"nodeType":"FunctionDefinition","src":"5236:95:0","nodes":[],"body":{"id":619,"nodeType":"Block","src":"5280:51:0","nodes":[],"statements":[{"expression":{"id":611,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5290:9:0","subExpression":{"id":610,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5290:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":612,"nodeType":"ExpressionStatement","src":"5290:9:0"},{"expression":{"arguments":[{"id":616,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":607,"src":"5321:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":613,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5309:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":615,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5309:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":617,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5309:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":618,"nodeType":"ExpressionStatement","src":"5309:15:0"}]},"functionSelector":"8d3ef7ca","implemented":true,"kind":"function","modifiers":[],"name":"call2","nameLocation":"5245:5:0","parameters":{"id":608,"nodeType":"ParameterList","parameters":[{"constant":false,"id":607,"mutability":"mutable","name":"_v","nameLocation":"5267:2:0","nodeType":"VariableDeclaration","scope":620,"src":"5251:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":606,"name":"string","nodeType":"ElementaryTypeName","src":"5251:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5250:20:0"},"returnParameters":{"id":609,"nodeType":"ParameterList","parameters":[],"src":"5280:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":635,"nodeType":"FunctionDefinition","src":"5337:98:0","nodes":[],"body":{"id":634,"nodeType":"Block","src":"5383:52:0","nodes":[],"statements":[{"expression":{"id":626,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5393:9:0","subExpression":{"id":625,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5393:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":627,"nodeType":"ExpressionStatement","src":"5393:9:0"},{"expression":{"arguments":[{"id":631,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":622,"src":"5425:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":628,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"5412:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$663","typeString":"contract ScriptExample"}},"id":630,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested2","nodeType":"MemberAccess","referencedDeclaration":650,"src":"5412:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":632,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5412:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":633,"nodeType":"ExpressionStatement","src":"5412:16:0"}]},"functionSelector":"a76ccdfa","implemented":true,"kind":"function","modifiers":[],"name":"nested1","nameLocation":"5346:7:0","parameters":{"id":623,"nodeType":"ParameterList","parameters":[{"constant":false,"id":622,"mutability":"mutable","name":"_v","nameLocation":"5370:2:0","nodeType":"VariableDeclaration","scope":635,"src":"5354:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":621,"name":"string","nodeType":"ElementaryTypeName","src":"5354:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5353:20:0"},"returnParameters":{"id":624,"nodeType":"ParameterList","parameters":[],"src":"5383:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":650,"nodeType":"FunctionDefinition","src":"5441:97:0","nodes":[],"body":{"id":649,"nodeType":"Block","src":"5487:51:0","nodes":[],"statements":[{"expression":{"id":641,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5497:9:0","subExpression":{"id":640,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5497:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":642,"nodeType":"ExpressionStatement","src":"5497:9:0"},{"expression":{"arguments":[{"id":646,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":637,"src":"5528:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":643,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5516:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":645,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5516:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":647,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5516:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":648,"nodeType":"ExpressionStatement","src":"5516:15:0"}]},"functionSelector":"dbf1282f","implemented":true,"kind":"function","modifiers":[],"name":"nested2","nameLocation":"5450:7:0","parameters":{"id":638,"nodeType":"ParameterList","parameters":[{"constant":false,"id":637,"mutability":"mutable","name":"_v","nameLocation":"5474:2:0","nodeType":"VariableDeclaration","scope":650,"src":"5458:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":636,"name":"string","nodeType":"ElementaryTypeName","src":"5458:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5457:20:0"},"returnParameters":{"id":639,"nodeType":"ParameterList","parameters":[],"src":"5487:0:0"},"scope":663,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":662,"nodeType":"FunctionDefinition","src":"5544:84:0","nodes":[],"body":{"id":661,"nodeType":"Block","src":"5596:32:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":658,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":652,"src":"5618:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":655,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5606:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":657,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5606:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":659,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5606:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":660,"nodeType":"ExpressionStatement","src":"5606:15:0"}]},"functionSelector":"7f8b915c","implemented":true,"kind":"function","modifiers":[],"name":"callPure","nameLocation":"5553:8:0","parameters":{"id":653,"nodeType":"ParameterList","parameters":[{"constant":false,"id":652,"mutability":"mutable","name":"_v","nameLocation":"5578:2:0","nodeType":"VariableDeclaration","scope":662,"src":"5562:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":651,"name":"string","nodeType":"ElementaryTypeName","src":"5562:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5561:20:0"},"returnParameters":{"id":654,"nodeType":"ParameterList","parameters":[],"src":"5596:0:0"},"scope":663,"stateMutability":"pure","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[676],"contractKind":"contract","documentation":{"id":193,"nodeType":"StructuredDocumentation","src":"2415:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[663],"name":"ScriptExample","nameLocation":"2550:13:0","scope":677,"usedErrors":[]},{"id":676,"nodeType":"ContractDefinition","src":"5632:96:0","nodes":[{"id":665,"nodeType":"VariableDeclaration","src":"5654:18:0","nodes":[],"constant":false,"functionSelector":"c2985578","mutability":"mutable","name":"foo","nameLocation":"5669:3:0","scope":676,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":664,"name":"uint256","nodeType":"ElementaryTypeName","src":"5654:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":675,"nodeType":"FunctionDefinition","src":"5679:47:0","nodes":[],"body":{"id":674,"nodeType":"Block","src":"5702:24:0","nodes":[],"statements":[{"expression":{"id":672,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":670,"name":"foo","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":665,"src":"5712:3:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":671,"name":"v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":667,"src":"5718:1:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5712:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":673,"nodeType":"ExpressionStatement","src":"5712:7:0"}]},"implemented":true,"kind":"constructor","modifiers":[],"name":"","nameLocation":"-1:-1:-1","parameters":{"id":668,"nodeType":"ParameterList","parameters":[{"constant":false,"id":667,"mutability":"mutable","name":"v","nameLocation":"5699:1:0","nodeType":"VariableDeclaration","scope":675,"src":"5691:9:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":666,"name":"uint256","nodeType":"ElementaryTypeName","src":"5691:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"5690:11:0"},"returnParameters":{"id":669,"nodeType":"ParameterList","parameters":[],"src":"5702:0:0"},"scope":676,"stateMutability":"nonpayable","virtual":false,"visibility":"public"}],"abstract":false,"baseContracts":[],"canonicalName":"FooBar","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[676],"name":"FooBar","nameLocation":"5641:6:0","scope":677,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file +{"abi":[],"bytecode":{"object":"0x602d6037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300080f000a","sourceMap":"791:1622:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;791:1622:0;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300080f000a","sourceMap":"791:1622:0:-:0;;;;;;;;","linkReferences":{}},"methodIdentifiers":{},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/ScriptExample.s.sol\":\"console\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"scripts/ScriptExample.s.sol\":{\"keccak256\":\"0x8d1dfa41908e7ccc3a498a2a2aa51c5275bedbb904ce32d08f8598e36f896d8d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5117bb7158363cae8b9dc0508d2852692fd36172f1c699ff680afbb5acebe1f3\",\"dweb:/ipfs/QmQdahJ8SPKfJ4yea5Ge9qaj5qh1TxVffhHvaWytBaL95h\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.15+commit.e14f2714"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"scripts/ScriptExample.s.sol":"console"},"evmVersion":"london","libraries":{}},"sources":{"scripts/ScriptExample.s.sol":{"keccak256":"0x8d1dfa41908e7ccc3a498a2a2aa51c5275bedbb904ce32d08f8598e36f896d8d","urls":["bzz-raw://5117bb7158363cae8b9dc0508d2852692fd36172f1c699ff680afbb5acebe1f3","dweb:/ipfs/QmQdahJ8SPKfJ4yea5Ge9qaj5qh1TxVffhHvaWytBaL95h"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[],"types":{}},"userdoc":{"version":1,"kind":"user"},"devdoc":{"version":1,"kind":"dev"},"ast":{"absolutePath":"scripts/ScriptExample.s.sol","id":720,"exportedSymbols":{"FooBar":[719],"ScriptExample":[706],"Vm":[55],"console":[192]},"nodeType":"SourceUnit","src":"32:5967:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:23:0","nodes":[],"literals":["solidity","0.8",".15"]},{"id":55,"nodeType":"ContractDefinition","src":"120:616:0","nodes":[{"id":10,"nodeType":"FunctionDefinition","src":"139:91:0","nodes":[],"functionSelector":"4777f3cf","implemented":false,"kind":"function","modifiers":[],"name":"envOr","nameLocation":"148:5:0","parameters":{"id":6,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"mutability":"mutable","name":"name","nameLocation":"170:4:0","nodeType":"VariableDeclaration","scope":10,"src":"154:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2,"name":"string","nodeType":"ElementaryTypeName","src":"154:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":5,"mutability":"mutable","name":"defaultValue","nameLocation":"181:12:0","nodeType":"VariableDeclaration","scope":10,"src":"176:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":4,"name":"bool","nodeType":"ElementaryTypeName","src":"176:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"153:41:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[{"constant":false,"id":8,"mutability":"mutable","name":"value","nameLocation":"223:5:0","nodeType":"VariableDeclaration","scope":10,"src":"218:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":7,"name":"bool","nodeType":"ElementaryTypeName","src":"218:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"217:12:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":17,"nodeType":"FunctionDefinition","src":"235:72:0","nodes":[],"functionSelector":"2d0335ab","implemented":false,"kind":"function","modifiers":[],"name":"getNonce","nameLocation":"244:8:0","parameters":{"id":13,"nodeType":"ParameterList","parameters":[{"constant":false,"id":12,"mutability":"mutable","name":"account","nameLocation":"261:7:0","nodeType":"VariableDeclaration","scope":17,"src":"253:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":11,"name":"address","nodeType":"ElementaryTypeName","src":"253:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"252:17:0"},"returnParameters":{"id":16,"nodeType":"ParameterList","parameters":[{"constant":false,"id":15,"mutability":"mutable","name":"nonce","nameLocation":"300:5:0","nodeType":"VariableDeclaration","scope":17,"src":"293:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"},"typeName":{"id":14,"name":"uint64","nodeType":"ElementaryTypeName","src":"293:6:0","typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}},"visibility":"internal"}],"src":"292:14:0"},"scope":55,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":27,"nodeType":"FunctionDefinition","src":"312:111:0","nodes":[],"functionSelector":"213e4198","implemented":false,"kind":"function","modifiers":[],"name":"parseJsonKeys","nameLocation":"321:13:0","parameters":{"id":22,"nodeType":"ParameterList","parameters":[{"constant":false,"id":19,"mutability":"mutable","name":"json","nameLocation":"351:4:0","nodeType":"VariableDeclaration","scope":27,"src":"335:20:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":18,"name":"string","nodeType":"ElementaryTypeName","src":"335:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":21,"mutability":"mutable","name":"key","nameLocation":"373:3:0","nodeType":"VariableDeclaration","scope":27,"src":"357:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":20,"name":"string","nodeType":"ElementaryTypeName","src":"357:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"334:43:0"},"returnParameters":{"id":26,"nodeType":"ParameterList","parameters":[{"constant":false,"id":25,"mutability":"mutable","name":"keys","nameLocation":"417:4:0","nodeType":"VariableDeclaration","scope":27,"src":"401:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":23,"name":"string","nodeType":"ElementaryTypeName","src":"401:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":24,"nodeType":"ArrayTypeName","src":"401:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"src":"400:22:0"},"scope":55,"stateMutability":"pure","virtual":false,"visibility":"external"},{"id":32,"nodeType":"FunctionDefinition","src":"428:48:0","nodes":[],"functionSelector":"06447d56","implemented":false,"kind":"function","modifiers":[],"name":"startPrank","nameLocation":"437:10:0","parameters":{"id":30,"nodeType":"ParameterList","parameters":[{"constant":false,"id":29,"mutability":"mutable","name":"msgSender","nameLocation":"456:9:0","nodeType":"VariableDeclaration","scope":32,"src":"448:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":28,"name":"address","nodeType":"ElementaryTypeName","src":"448:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"447:19:0"},"returnParameters":{"id":31,"nodeType":"ParameterList","parameters":[],"src":"475:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":35,"nodeType":"FunctionDefinition","src":"481:30:0","nodes":[],"functionSelector":"90c5013b","implemented":false,"kind":"function","modifiers":[],"name":"stopPrank","nameLocation":"490:9:0","parameters":{"id":33,"nodeType":"ParameterList","parameters":[],"src":"499:2:0"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[],"src":"510:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":38,"nodeType":"FunctionDefinition","src":"516:30:0","nodes":[],"functionSelector":"afc98040","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"525:9:0","parameters":{"id":36,"nodeType":"ParameterList","parameters":[],"src":"534:2:0"},"returnParameters":{"id":37,"nodeType":"ParameterList","parameters":[],"src":"545:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":43,"nodeType":"FunctionDefinition","src":"551:47:0","nodes":[],"functionSelector":"e6962cdb","implemented":false,"kind":"function","modifiers":[],"name":"broadcast","nameLocation":"560:9:0","parameters":{"id":41,"nodeType":"ParameterList","parameters":[{"constant":false,"id":40,"mutability":"mutable","name":"msgSender","nameLocation":"578:9:0","nodeType":"VariableDeclaration","scope":43,"src":"570:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":39,"name":"address","nodeType":"ElementaryTypeName","src":"570:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"569:19:0"},"returnParameters":{"id":42,"nodeType":"ParameterList","parameters":[],"src":"597:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":48,"nodeType":"FunctionDefinition","src":"603:52:0","nodes":[],"functionSelector":"7fec2a8d","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"612:14:0","parameters":{"id":46,"nodeType":"ParameterList","parameters":[{"constant":false,"id":45,"mutability":"mutable","name":"msgSender","nameLocation":"635:9:0","nodeType":"VariableDeclaration","scope":48,"src":"627:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":44,"name":"address","nodeType":"ElementaryTypeName","src":"627:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"626:19:0"},"returnParameters":{"id":47,"nodeType":"ParameterList","parameters":[],"src":"654:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":51,"nodeType":"FunctionDefinition","src":"660:35:0","nodes":[],"functionSelector":"7fb5297f","implemented":false,"kind":"function","modifiers":[],"name":"startBroadcast","nameLocation":"669:14:0","parameters":{"id":49,"nodeType":"ParameterList","parameters":[],"src":"683:2:0"},"returnParameters":{"id":50,"nodeType":"ParameterList","parameters":[],"src":"694:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":54,"nodeType":"FunctionDefinition","src":"700:34:0","nodes":[],"functionSelector":"76eadd36","implemented":false,"kind":"function","modifiers":[],"name":"stopBroadcast","nameLocation":"709:13:0","parameters":{"id":52,"nodeType":"ParameterList","parameters":[],"src":"722:2:0"},"returnParameters":{"id":53,"nodeType":"ParameterList","parameters":[],"src":"733:0:0"},"scope":55,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"Vm","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[55],"name":"Vm","nameLocation":"130:2:0","scope":720,"usedErrors":[]},{"id":192,"nodeType":"ContractDefinition","src":"791:1622:0","nodes":[{"id":61,"nodeType":"VariableDeclaration","src":"813:86:0","nodes":[],"constant":true,"mutability":"constant","name":"CONSOLE_ADDRESS","nameLocation":"830:15:0","scope":192,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":56,"name":"address","nodeType":"ElementaryTypeName","src":"813:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"hexValue":"307830303030303030303030303030303030303036333646366537333646366336353265366336663637","id":59,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"856:42:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x000000000000000000636F6e736F6c652e6c6f67"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":58,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"848:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":57,"name":"address","nodeType":"ElementaryTypeName","src":"848:7:0","typeDescriptions":{}}},"id":60,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"848:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":78,"nodeType":"FunctionDefinition","src":"906:221:0","nodes":[],"body":{"id":77,"nodeType":"Block","src":"1065:62:0","nodes":[],"statements":[{"AST":{"nodeType":"YulBlock","src":"1084:37:0","statements":[{"nodeType":"YulAssignment","src":"1098:13:0","value":{"name":"fnIn","nodeType":"YulIdentifier","src":"1107:4:0"},"variableNames":[{"name":"fnOut","nodeType":"YulIdentifier","src":"1098:5:0"}]}]},"evmVersion":"london","externalReferences":[{"declaration":67,"isOffset":false,"isSlot":false,"src":"1107:4:0","valueSize":1},{"declaration":74,"isOffset":false,"isSlot":false,"src":"1098:5:0","valueSize":1}],"id":76,"nodeType":"InlineAssembly","src":"1075:46:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_castLogPayloadViewToPure","nameLocation":"915:25:0","parameters":{"id":68,"nodeType":"ParameterList","parameters":[{"constant":false,"id":67,"mutability":"mutable","name":"fnIn","nameLocation":"987:4:0","nodeType":"VariableDeclaration","scope":78,"src":"950:41:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"typeName":{"id":66,"nodeType":"FunctionTypeName","parameterTypes":{"id":64,"nodeType":"ParameterList","parameters":[{"constant":false,"id":63,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":66,"src":"959:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":62,"name":"bytes","nodeType":"ElementaryTypeName","src":"959:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"958:14:0"},"returnParameterTypes":{"id":65,"nodeType":"ParameterList","parameters":[],"src":"987:0:0"},"src":"950:41:0","stateMutability":"view","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) view"},"visibility":"internal"},"visibility":"internal"}],"src":"940:57:0"},"returnParameters":{"id":75,"nodeType":"ParameterList","parameters":[{"constant":false,"id":74,"mutability":"mutable","name":"fnOut","nameLocation":"1058:5:0","nodeType":"VariableDeclaration","scope":78,"src":"1021:42:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"typeName":{"id":73,"nodeType":"FunctionTypeName","parameterTypes":{"id":71,"nodeType":"ParameterList","parameters":[{"constant":false,"id":70,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":73,"src":"1030:12:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":69,"name":"bytes","nodeType":"ElementaryTypeName","src":"1030:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1029:14:0"},"returnParameterTypes":{"id":72,"nodeType":"ParameterList","parameters":[],"src":"1058:0:0"},"src":"1021:42:0","stateMutability":"pure","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes) pure"},"visibility":"internal"},"visibility":"internal"}],"src":"1020:44:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":90,"nodeType":"FunctionDefinition","src":"1133:133:0","nodes":[],"body":{"id":89,"nodeType":"Block","src":"1194:72:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":86,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":80,"src":"1251:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"arguments":[{"id":84,"name":"_sendLogPayloadView","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":106,"src":"1230:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_function_internal_view$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) view"}],"id":83,"name":"_castLogPayloadViewToPure","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":78,"src":"1204:25:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_function_internal_view$_t_bytes_memory_ptr_$returns$__$_$returns$_t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$_$","typeString":"function (function (bytes memory) view) pure returns (function (bytes memory) pure)"}},"id":85,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":87,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1204:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":88,"nodeType":"ExpressionStatement","src":"1204:55:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayload","nameLocation":"1142:15:0","parameters":{"id":81,"nodeType":"ParameterList","parameters":[{"constant":false,"id":80,"mutability":"mutable","name":"payload","nameLocation":"1171:7:0","nodeType":"VariableDeclaration","scope":90,"src":"1158:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":79,"name":"bytes","nodeType":"ElementaryTypeName","src":"1158:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1157:22:0"},"returnParameters":{"id":82,"nodeType":"ParameterList","parameters":[],"src":"1194:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":106,"nodeType":"FunctionDefinition","src":"1272:380:0","nodes":[],"body":{"id":105,"nodeType":"Block","src":"1336:316:0","nodes":[],"statements":[{"assignments":[96],"declarations":[{"constant":false,"id":96,"mutability":"mutable","name":"payloadLength","nameLocation":"1354:13:0","nodeType":"VariableDeclaration","scope":105,"src":"1346:21:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":95,"name":"uint256","nodeType":"ElementaryTypeName","src":"1346:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":99,"initialValue":{"expression":{"id":97,"name":"payload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":92,"src":"1370:7:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":98,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"length","nodeType":"MemberAccess","src":"1370:14:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"1346:38:0"},{"assignments":[101],"declarations":[{"constant":false,"id":101,"mutability":"mutable","name":"consoleAddress","nameLocation":"1402:14:0","nodeType":"VariableDeclaration","scope":105,"src":"1394:22:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":100,"name":"address","nodeType":"ElementaryTypeName","src":"1394:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":103,"initialValue":{"id":102,"name":"CONSOLE_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":61,"src":"1419:15:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"1394:40:0"},{"AST":{"nodeType":"YulBlock","src":"1496:150:0","statements":[{"nodeType":"YulVariableDeclaration","src":"1510:36:0","value":{"arguments":[{"name":"payload","nodeType":"YulIdentifier","src":"1534:7:0"},{"kind":"number","nodeType":"YulLiteral","src":"1543:2:0","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1530:3:0"},"nodeType":"YulFunctionCall","src":"1530:16:0"},"variables":[{"name":"payloadStart","nodeType":"YulTypedName","src":"1514:12:0","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1559:77:0","value":{"arguments":[{"arguments":[],"functionName":{"name":"gas","nodeType":"YulIdentifier","src":"1579:3:0"},"nodeType":"YulFunctionCall","src":"1579:5:0"},{"name":"consoleAddress","nodeType":"YulIdentifier","src":"1586:14:0"},{"name":"payloadStart","nodeType":"YulIdentifier","src":"1602:12:0"},{"name":"payloadLength","nodeType":"YulIdentifier","src":"1616:13:0"},{"kind":"number","nodeType":"YulLiteral","src":"1631:1:0","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1634:1:0","type":"","value":"0"}],"functionName":{"name":"staticcall","nodeType":"YulIdentifier","src":"1568:10:0"},"nodeType":"YulFunctionCall","src":"1568:68:0"},"variables":[{"name":"r","nodeType":"YulTypedName","src":"1563:1:0","type":""}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":101,"isOffset":false,"isSlot":false,"src":"1586:14:0","valueSize":1},{"declaration":92,"isOffset":false,"isSlot":false,"src":"1534:7:0","valueSize":1},{"declaration":96,"isOffset":false,"isSlot":false,"src":"1616:13:0","valueSize":1}],"id":104,"nodeType":"InlineAssembly","src":"1487:159:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"_sendLogPayloadView","nameLocation":"1281:19:0","parameters":{"id":93,"nodeType":"ParameterList","parameters":[{"constant":false,"id":92,"mutability":"mutable","name":"payload","nameLocation":"1314:7:0","nodeType":"VariableDeclaration","scope":106,"src":"1301:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":91,"name":"bytes","nodeType":"ElementaryTypeName","src":"1301:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1300:22:0"},"returnParameters":{"id":94,"nodeType":"ParameterList","parameters":[],"src":"1336:0:0"},"scope":192,"stateMutability":"view","virtual":false,"visibility":"private"},{"id":120,"nodeType":"FunctionDefinition","src":"1658:121:0","nodes":[],"body":{"id":119,"nodeType":"Block","src":"1703:76:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e6729","id":114,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1753:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},"value":"log(string)"},{"id":115,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":108,"src":"1768:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50","typeString":"literal_string \"log(string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":112,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1729:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":113,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1729:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":116,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1729:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":111,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1713:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":117,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1713:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":118,"nodeType":"ExpressionStatement","src":"1713:59:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1667:3:0","parameters":{"id":109,"nodeType":"ParameterList","parameters":[{"constant":false,"id":108,"mutability":"mutable","name":"p0","nameLocation":"1685:2:0","nodeType":"VariableDeclaration","scope":120,"src":"1671:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":107,"name":"string","nodeType":"ElementaryTypeName","src":"1671:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1670:18:0"},"returnParameters":{"id":110,"nodeType":"ParameterList","parameters":[],"src":"1703:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":137,"nodeType":"FunctionDefinition","src":"1785:139:0","nodes":[],"body":{"id":136,"nodeType":"Block","src":"1839:85:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c626f6f6c29","id":130,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1889:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},"value":"log(string,bool)"},{"id":131,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":122,"src":"1909:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":132,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":124,"src":"1913:2:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c3b556354c088fbb43886eb83c2a04bc7089663f964d22be308197a236f5b870","typeString":"literal_string \"log(string,bool)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":128,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1865:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":129,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"1865:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":133,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1865:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":127,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1849:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":134,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1849:68:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":135,"nodeType":"ExpressionStatement","src":"1849:68:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1794:3:0","parameters":{"id":125,"nodeType":"ParameterList","parameters":[{"constant":false,"id":122,"mutability":"mutable","name":"p0","nameLocation":"1812:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1798:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":121,"name":"string","nodeType":"ElementaryTypeName","src":"1798:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":124,"mutability":"mutable","name":"p1","nameLocation":"1821:2:0","nodeType":"VariableDeclaration","scope":137,"src":"1816:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":123,"name":"bool","nodeType":"ElementaryTypeName","src":"1816:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1797:27:0"},"returnParameters":{"id":126,"nodeType":"ParameterList","parameters":[],"src":"1839:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":154,"nodeType":"FunctionDefinition","src":"1930:145:0","nodes":[],"body":{"id":153,"nodeType":"Block","src":"1987:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c75696e7432353629","id":147,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2037:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},"value":"log(string,uint256)"},{"id":148,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":139,"src":"2060:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":149,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":141,"src":"2064:2:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b60e72ccf6d57ab53eb84d7e94a9545806ed7f93c4d5673f11a64f03471e584e","typeString":"literal_string \"log(string,uint256)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":145,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2013:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":146,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2013:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":150,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2013:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":144,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"1997:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":151,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"1997:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":152,"nodeType":"ExpressionStatement","src":"1997:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"1939:3:0","parameters":{"id":142,"nodeType":"ParameterList","parameters":[{"constant":false,"id":139,"mutability":"mutable","name":"p0","nameLocation":"1957:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1943:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":138,"name":"string","nodeType":"ElementaryTypeName","src":"1943:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":141,"mutability":"mutable","name":"p1","nameLocation":"1969:2:0","nodeType":"VariableDeclaration","scope":154,"src":"1961:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":140,"name":"uint256","nodeType":"ElementaryTypeName","src":"1961:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1942:30:0"},"returnParameters":{"id":143,"nodeType":"ParameterList","parameters":[],"src":"1987:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":171,"nodeType":"FunctionDefinition","src":"2081:145:0","nodes":[],"body":{"id":170,"nodeType":"Block","src":"2138:88:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c6164647265737329","id":164,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2188:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},"value":"log(string,address)"},{"id":165,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":156,"src":"2211:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":166,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":158,"src":"2215:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_319af333460570a1937bf195dd33445c0d0951c59127da6f1f038b9fdce3fd72","typeString":"literal_string \"log(string,address)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":162,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2164:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":163,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2164:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":167,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2164:54:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":161,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2148:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":168,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2148:71:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":169,"nodeType":"ExpressionStatement","src":"2148:71:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2090:3:0","parameters":{"id":159,"nodeType":"ParameterList","parameters":[{"constant":false,"id":156,"mutability":"mutable","name":"p0","nameLocation":"2108:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2094:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":155,"name":"string","nodeType":"ElementaryTypeName","src":"2094:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":158,"mutability":"mutable","name":"p1","nameLocation":"2120:2:0","nodeType":"VariableDeclaration","scope":171,"src":"2112:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":157,"name":"address","nodeType":"ElementaryTypeName","src":"2112:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"2093:30:0"},"returnParameters":{"id":160,"nodeType":"ParameterList","parameters":[],"src":"2138:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"},{"id":191,"nodeType":"FunctionDefinition","src":"2232:179:0","nodes":[],"body":{"id":190,"nodeType":"Block","src":"2313:98:0","nodes":[],"statements":[{"expression":{"arguments":[{"arguments":[{"hexValue":"6c6f6728737472696e672c737472696e672c737472696e6729","id":183,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2363:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},"value":"log(string,string,string)"},{"id":184,"name":"p0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":173,"src":"2392:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":185,"name":"p1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":175,"src":"2396:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":186,"name":"p2","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":177,"src":"2400:2:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2ced7cef693312206c21f0e92e3b54e2e16bf33db5eec350c78866822c665e1f","typeString":"literal_string \"log(string,string,string)\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":181,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"2339:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":182,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberName":"encodeWithSignature","nodeType":"MemberAccess","src":"2339:23:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (string memory) pure returns (bytes memory)"}},"id":187,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2339:64:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":180,"name":"_sendLogPayload","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":90,"src":"2323:15:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory) pure"}},"id":188,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2323:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":189,"nodeType":"ExpressionStatement","src":"2323:81:0"}]},"implemented":true,"kind":"function","modifiers":[],"name":"log","nameLocation":"2241:3:0","parameters":{"id":178,"nodeType":"ParameterList","parameters":[{"constant":false,"id":173,"mutability":"mutable","name":"p0","nameLocation":"2259:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2245:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":172,"name":"string","nodeType":"ElementaryTypeName","src":"2245:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":175,"mutability":"mutable","name":"p1","nameLocation":"2277:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2263:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":174,"name":"string","nodeType":"ElementaryTypeName","src":"2263:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":177,"mutability":"mutable","name":"p2","nameLocation":"2295:2:0","nodeType":"VariableDeclaration","scope":191,"src":"2281:16:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":176,"name":"string","nodeType":"ElementaryTypeName","src":"2281:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2244:54:0"},"returnParameters":{"id":179,"nodeType":"ParameterList","parameters":[],"src":"2313:0:0"},"scope":192,"stateMutability":"pure","virtual":false,"visibility":"internal"}],"abstract":false,"baseContracts":[],"canonicalName":"console","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"linearizedBaseContracts":[192],"name":"console","nameLocation":"799:7:0","scope":720,"usedErrors":[]},{"id":706,"nodeType":"ContractDefinition","src":"2541:3359:0","nodes":[{"id":207,"nodeType":"VariableDeclaration","src":"2571:94:0","nodes":[],"constant":true,"mutability":"constant","name":"VM_ADDRESS","nameLocation":"2597:10:0","scope":706,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":194,"name":"address","nodeType":"ElementaryTypeName","src":"2571:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"hexValue":"6865766d20636865617420636f6465","id":202,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2644:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""},"value":"hevm cheat code"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_885cb69240a935d632d79c317109709ecfa91a80626ff3989d68f67f5b1dd12d","typeString":"literal_string \"hevm cheat code\""}],"id":201,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2634:9:0","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":203,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2634:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"id":200,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2626:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":199,"name":"uint256","nodeType":"ElementaryTypeName","src":"2626:7:0","typeDescriptions":{}}},"id":204,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2626:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":198,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2618:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":197,"name":"uint160","nodeType":"ElementaryTypeName","src":"2618:7:0","typeDescriptions":{}}},"id":205,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2618:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":196,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2610:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":195,"name":"address","nodeType":"ElementaryTypeName","src":"2610:7:0","typeDescriptions":{}}},"id":206,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2610:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"id":213,"nodeType":"VariableDeclaration","src":"2671:40:0","nodes":[],"constant":true,"mutability":"constant","name":"vm","nameLocation":"2692:2:0","scope":706,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"},"typeName":{"id":209,"nodeType":"UserDefinedTypeName","pathNode":{"id":208,"name":"Vm","nodeType":"IdentifierPath","referencedDeclaration":55,"src":"2671:2:0"},"referencedDeclaration":55,"src":"2671:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"value":{"arguments":[{"id":211,"name":"VM_ADDRESS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":207,"src":"2700:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":210,"name":"Vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":55,"src":"2697:2:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Vm_$55_$","typeString":"type(contract Vm)"}},"id":212,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2697:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"visibility":"internal"},{"id":215,"nodeType":"VariableDeclaration","src":"2775:22:0","nodes":[],"constant":false,"functionSelector":"61bc221a","mutability":"mutable","name":"counter","nameLocation":"2790:7:0","scope":706,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":214,"name":"uint256","nodeType":"ElementaryTypeName","src":"2775:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":378,"nodeType":"FunctionDefinition","src":"2887:949:0","nodes":[],"body":{"id":377,"nodeType":"Block","src":"2909:927:0","nodes":[],"statements":[{"assignments":[220],"declarations":[{"constant":false,"id":220,"mutability":"mutable","name":"x","nameLocation":"2924:1:0","nodeType":"VariableDeclaration","scope":377,"src":"2919:6:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":219,"name":"bool","nodeType":"ElementaryTypeName","src":"2919:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":226,"initialValue":{"arguments":[{"hexValue":"4558414d504c455f424f4f4c","id":223,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2937:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},"value":"EXAMPLE_BOOL"},{"hexValue":"66616c7365","id":224,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"2953:5:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a634dae177a0e138ae7aaa2afae347412e148992e88c7aabd33ee71be146cb7f","typeString":"literal_string \"EXAMPLE_BOOL\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":221,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"2928:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":222,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"envOr","nodeType":"MemberAccess","referencedDeclaration":10,"src":"2928:8:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$_t_bool_$returns$_t_bool_$","typeString":"function (string memory,bool) view external returns (bool)"}},"id":225,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2928:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"2919:40:0"},{"expression":{"arguments":[{"hexValue":"626f6f6c2076616c75652066726f6d20656e76","id":230,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2981:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},"value":"bool value from env"},{"id":231,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":220,"src":"3004:1:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5a607d0b5a1295325aa8901721d78ba402601bba6f62cebdd5235dd0204a590b","typeString":"literal_string \"bool value from env\""},{"typeIdentifier":"t_bool","typeString":"bool"}],"expression":{"id":227,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"2969:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":229,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":137,"src":"2969:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_bool_$returns$__$","typeString":"function (string memory,bool) pure"}},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"2969:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":233,"nodeType":"ExpressionStatement","src":"2969:37:0"},{"expression":{"arguments":[{"hexValue":"636f6e74726163742061646472","id":237,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3029:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},"value":"contract addr"},{"arguments":[{"id":240,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3054:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}],"id":239,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3046:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":238,"name":"address","nodeType":"ElementaryTypeName","src":"3046:7:0","typeDescriptions":{}}},"id":241,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3046:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa50728770d00fe8f6a0592f3565bbfaf063ee4077f1f5bbc003d091d33cd0c4","typeString":"literal_string \"contract addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":234,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3017:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":236,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3017:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":242,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3017:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":243,"nodeType":"ExpressionStatement","src":"3017:43:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206e6f6e6365","id":247,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3082:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},"value":"contract nonce"},{"arguments":[{"arguments":[{"id":252,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3120:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}],"id":251,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3112:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":250,"name":"address","nodeType":"ElementaryTypeName","src":"3112:7:0","typeDescriptions":{}}},"id":253,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3112:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":248,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3100:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":249,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3100:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":254,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3100:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_3a23091615a5de8c0a35ffd8857a37e2c4e0b72f3ef8a34d6caf65efcd562e2f","typeString":"literal_string \"contract nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":244,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3070:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":246,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3070:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":255,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3070:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":256,"nodeType":"ExpressionStatement","src":"3070:57:0"},{"expression":{"arguments":[{"hexValue":"73656e6465722061646472","id":260,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3149:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},"value":"sender addr"},{"arguments":[{"expression":{"id":263,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3172:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":264,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3172:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":262,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3164:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":261,"name":"address","nodeType":"ElementaryTypeName","src":"3164:7:0","typeDescriptions":{}}},"id":265,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3164:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8125ca2decf812b25b65606ff16dad37cb198ff0433485a7926e50feafacfc35","typeString":"literal_string \"sender addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":257,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3137:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":259,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3137:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":266,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3137:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":267,"nodeType":"ExpressionStatement","src":"3137:47:0"},{"expression":{"arguments":[{"hexValue":"73656e646572206e6f6e6365","id":271,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3206:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},"value":"sender nonce"},{"arguments":[{"arguments":[{"expression":{"id":276,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3242:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":277,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3242:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":275,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3234:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":274,"name":"address","nodeType":"ElementaryTypeName","src":"3234:7:0","typeDescriptions":{}}},"id":278,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3234:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":272,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3222:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":273,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3222:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":279,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3222:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_db7deb43f2f9e0404016de53b7e64c4976b54149581f7534daae2551e8cf4e40","typeString":"literal_string \"sender nonce\""},{"typeIdentifier":"t_uint64","typeString":"uint64"}],"expression":{"id":268,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3194:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":270,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3194:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":280,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3194:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":281,"nodeType":"ExpressionStatement","src":"3194:61:0"},{"assignments":[283],"declarations":[{"constant":false,"id":283,"mutability":"mutable","name":"json","nameLocation":"3280:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3266:18:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":282,"name":"string","nodeType":"ElementaryTypeName","src":"3266:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":285,"initialValue":{"hexValue":"7b22726f6f745f6b6579223a205b7b2261223a20312c202262223a20327d5d7d","id":284,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3287:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_e95522e99766888d0261f55bd1eae5e3f3e26eaf009a16e2433eafaf0a4ecdf2","typeString":"literal_string \"{\"root_key\": [{\"a\": 1, \"b\": 2}]}\""},"value":"{\"root_key\": [{\"a\": 1, \"b\": 2}]}"},"nodeType":"VariableDeclarationStatement","src":"3266:55:0"},{"assignments":[290],"declarations":[{"constant":false,"id":290,"mutability":"mutable","name":"keys","nameLocation":"3347:4:0","nodeType":"VariableDeclaration","scope":377,"src":"3331:20:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string[]"},"typeName":{"baseType":{"id":288,"name":"string","nodeType":"ElementaryTypeName","src":"3331:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"id":289,"nodeType":"ArrayTypeName","src":"3331:8:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_storage_$dyn_storage_ptr","typeString":"string[]"}},"visibility":"internal"}],"id":296,"initialValue":{"arguments":[{"id":293,"name":"json","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":283,"src":"3371:4:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"hexValue":"2e726f6f745f6b65795b305d","id":294,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3377:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""},"value":".root_key[0]"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_stringliteral_d82f67100edb80050915e1ec4b565c9a8319a22efb1075e1298b7bb60101d266","typeString":"literal_string \".root_key[0]\""}],"expression":{"id":291,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3354:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":292,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"parseJsonKeys","nodeType":"MemberAccess","referencedDeclaration":27,"src":"3354:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$_t_array$_t_string_memory_ptr_$dyn_memory_ptr_$","typeString":"function (string memory,string memory) pure external returns (string memory[] memory)"}},"id":295,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3354:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"nodeType":"VariableDeclarationStatement","src":"3331:61:0"},{"expression":{"arguments":[{"hexValue":"6b657973","id":300,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3414:6:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},"value":"keys"},{"baseExpression":{"id":301,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3422:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":303,"indexExpression":{"hexValue":"30","id":302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3427:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3422:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"baseExpression":{"id":304,"name":"keys","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":290,"src":"3431:4:0","typeDescriptions":{"typeIdentifier":"t_array$_t_string_memory_ptr_$dyn_memory_ptr","typeString":"string memory[] memory"}},"id":306,"indexExpression":{"hexValue":"31","id":305,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3436:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"3431:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f29790a80c4ce5f42f59892f424f9c92856c6b656c3378e2cf305b260c6f4195","typeString":"literal_string \"keys\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":297,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3402:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":299,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":191,"src":"3402:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory,string memory,string memory) pure"}},"id":307,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3402:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":308,"nodeType":"ExpressionStatement","src":"3402:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c","id":312,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3461:15:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""},"value":"from original"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_77928970c8757d110f3c23e003246f49e0de890480ba9717ba659b2f56f316b2","typeString":"literal_string \"from original\""}],"expression":{"id":309,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3450:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":311,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":633,"src":"3450:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":313,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3450:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":314,"nodeType":"ExpressionStatement","src":"3450:27:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30783432","id":322,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3517:4:0","typeDescriptions":{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"},"value":"0x42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_66_by_1","typeString":"int_const 66"}],"id":321,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3509:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":320,"name":"uint160","nodeType":"ElementaryTypeName","src":"3509:7:0","typeDescriptions":{}}},"id":323,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3509:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":319,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3501:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":318,"name":"address","nodeType":"ElementaryTypeName","src":"3501:7:0","typeDescriptions":{}}},"id":324,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3501:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":315,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3487:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":317,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startPrank","nodeType":"MemberAccess","referencedDeclaration":32,"src":"3487:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3487:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":326,"nodeType":"ExpressionStatement","src":"3487:37:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2031","id":330,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3545:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""},"value":"from prank 1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42b34abfe37a8b0add910cda7b4a379e6538fa7a1dcafce47a02bd38f6c88e2a","typeString":"literal_string \"from prank 1\""}],"expression":{"id":327,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3534:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":329,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":633,"src":"3534:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":331,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3534:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":332,"nodeType":"ExpressionStatement","src":"3534:26:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f7065206d73672e73656e646572","id":336,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3582:25:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},"value":"parent scope msg.sender"},{"arguments":[{"expression":{"id":339,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"3617:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":340,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"3617:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":338,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3609:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":337,"name":"address","nodeType":"ElementaryTypeName","src":"3609:7:0","typeDescriptions":{}}},"id":341,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3609:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83ec9246154d8845de47aafc5c2865c9985d2efe84472c27283879f2fbf5cc94","typeString":"literal_string \"parent scope msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":333,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3570:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":335,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3570:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":342,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3570:59:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":343,"nodeType":"ExpressionStatement","src":"3570:59:0"},{"expression":{"arguments":[{"hexValue":"706172656e742073636f706520636f6e74726163742e61646472","id":347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3651:28:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},"value":"parent scope contract.addr"},{"arguments":[{"id":350,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3689:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}],"id":349,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3681:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":348,"name":"address","nodeType":"ElementaryTypeName","src":"3681:7:0","typeDescriptions":{}}},"id":351,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3681:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_97df66250e0b2b48f0ec8d0e01eb1b8ca012d95f1572895622aa1ea433e5570f","typeString":"literal_string \"parent scope contract.addr\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":344,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3639:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"3639:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3639:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":353,"nodeType":"ExpressionStatement","src":"3639:56:0"},{"expression":{"arguments":[{"hexValue":"66726f6d207072616e6b2032","id":357,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3716:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""},"value":"from prank 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_a38a34f8cad750a79aa097a92971f8f405b51ee9d53d25c5b14fc129ba3684bb","typeString":"literal_string \"from prank 2\""}],"expression":{"id":354,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3705:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":356,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":633,"src":"3705:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":358,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3705:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":359,"nodeType":"ExpressionStatement","src":"3705:26:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":360,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3741:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":362,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopPrank","nodeType":"MemberAccess","referencedDeclaration":35,"src":"3741:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":363,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3741:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":364,"nodeType":"ExpressionStatement","src":"3741:14:0"},{"expression":{"arguments":[{"hexValue":"66726f6d206f726967696e616c20616761696e","id":368,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3776:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""},"value":"from original again"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0c805c6579e20a9c4c8e11aeab23330910a9f2da629191dc119d1730e8ed6860","typeString":"literal_string \"from original again\""}],"expression":{"id":365,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3765:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":367,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"hello","nodeType":"MemberAccess","referencedDeclaration":633,"src":"3765:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) view external"}},"id":369,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3765:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":370,"nodeType":"ExpressionStatement","src":"3765:33:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":374,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3821:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":371,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3809:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":373,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"3809:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":375,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3809:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":376,"nodeType":"ExpressionStatement","src":"3809:20:0"}]},"documentation":{"id":216,"nodeType":"StructuredDocumentation","src":"2804:78:0","text":"@notice example function, runs through basic cheat-codes and console logs."},"functionSelector":"c0406226","implemented":true,"kind":"function","modifiers":[],"name":"run","nameLocation":"2896:3:0","parameters":{"id":217,"nodeType":"ParameterList","parameters":[],"src":"2899:2:0"},"returnParameters":{"id":218,"nodeType":"ParameterList","parameters":[],"src":"2909:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":609,"nodeType":"FunctionDefinition","src":"3903:1258:0","nodes":[],"body":{"id":608,"nodeType":"Block","src":"3934:1227:0","nodes":[],"statements":[{"expression":{"arguments":[{"hexValue":"6e6f6e6365207374617274","id":385,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3956:13:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_71efc69b9a13b6bc1e9a14d766ff01c79022262c6daa6532fb5dfb14f8511a20","typeString":"literal_string \"nonce start\""},"value":"nonce start"},{"arguments":[{"arguments":[{"arguments":[{"id":392,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"3999:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}],"id":391,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3991:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":390,"name":"address","nodeType":"ElementaryTypeName","src":"3991:7:0","typeDescriptions":{}}},"id":393,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3991:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":388,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"3979:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":389,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"3979:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":394,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3979:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint64","typeString":"uint64"}],"id":387,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3971:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":386,"name":"uint256","nodeType":"ElementaryTypeName","src":"3971:7:0","typeDescriptions":{}}},"id":395,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3971:35:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_71efc69b9a13b6bc1e9a14d766ff01c79022262c6daa6532fb5dfb14f8511a20","typeString":"literal_string \"nonce start\""},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":382,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"3944:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":384,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"3944:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":396,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"3944:63:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":397,"nodeType":"ExpressionStatement","src":"3944:63:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073696e676c65","id":401,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4030:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""},"value":"testing single"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b75103528423218e7569082dad569ed0d2ce7c0ac770c0812b220e2d369fe474","typeString":"literal_string \"testing single\""}],"expression":{"id":398,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4018:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":400,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4018:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":402,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4018:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":403,"nodeType":"ExpressionStatement","src":"4018:29:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":404,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4057:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":406,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"4057:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":407,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4057:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":408,"nodeType":"ExpressionStatement","src":"4057:14:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c31","id":412,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4092:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""},"value":"single_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5e1cad6d7a968cfacf2731373e1248ffb11f4886bced66a02a6de1a67ac8f777","typeString":"literal_string \"single_call1\""}],"expression":{"id":409,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4081:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":411,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":648,"src":"4081:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":413,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4081:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":414,"nodeType":"ExpressionStatement","src":"4081:26:0"},{"expression":{"arguments":[{"hexValue":"73696e676c655f63616c6c32","id":418,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4128:14:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""},"value":"single_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b37ddaf5d00ad9e6371de3fb71b91eef731fae1e86b768666380f7d44e1ada25","typeString":"literal_string \"single_call2\""}],"expression":{"id":415,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4117:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":417,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":663,"src":"4117:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":419,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4117:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":420,"nodeType":"ExpressionStatement","src":"4117:26:0"},{"expression":{"arguments":[{"hexValue":"74657374696e672073746172742f73746f70","id":424,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4166:20:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""},"value":"testing start/stop"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_778e886e3a1c3c5096aca76228832105f3f9269f362effd0e8ce3737787cb784","typeString":"literal_string \"testing start/stop\""}],"expression":{"id":421,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4154:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":423,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4154:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":425,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4154:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":426,"nodeType":"ExpressionStatement","src":"4154:33:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078633066666565","id":434,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4231:8:0","typeDescriptions":{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"},"value":"0xc0ffee"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_12648430_by_1","typeString":"int_const 12648430"}],"id":433,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4223:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":432,"name":"uint160","nodeType":"ElementaryTypeName","src":"4223:7:0","typeDescriptions":{}}},"id":435,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4223:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":431,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4215:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":430,"name":"address","nodeType":"ElementaryTypeName","src":"4215:7:0","typeDescriptions":{}}},"id":436,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4215:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":427,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4197:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":429,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4197:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":437,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4197:45:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":438,"nodeType":"ExpressionStatement","src":"4197:45:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c31","id":442,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4263:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""},"value":"startstop_call1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_2fc2682edf10ed478ee3b9a190f6b1c88bb492b300935ce44545a1613cf8f041","typeString":"literal_string \"startstop_call1\""}],"expression":{"id":439,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4252:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":441,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":648,"src":"4252:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":443,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4252:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":444,"nodeType":"ExpressionStatement","src":"4252:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c32","id":448,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4302:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""},"value":"startstop_call2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_1a6fd77f04b28bf45d6d0e2dd4c65c0bbfeba174f849e43bb67ebca1c019cda4","typeString":"literal_string \"startstop_call2\""}],"expression":{"id":445,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4291:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":447,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call2","nodeType":"MemberAccess","referencedDeclaration":663,"src":"4291:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":449,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4291:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":450,"nodeType":"ExpressionStatement","src":"4291:29:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f70757265","id":454,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4344:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""},"value":"startstop_pure"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b6e9eb1efd186b1d92b54da45026aa97a178e6eaffdf9dbf9f666fc751fb0ff9","typeString":"literal_string \"startstop_pure\""}],"expression":{"id":451,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4330:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":453,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"callPure","nodeType":"MemberAccess","referencedDeclaration":705,"src":"4330:13:0","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure external"}},"id":455,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4330:31:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":456,"nodeType":"ExpressionStatement","src":"4330:31:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":457,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4371:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":459,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4371:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":460,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4371:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":461,"nodeType":"ExpressionStatement","src":"4371:18:0"},{"expression":{"arguments":[{"hexValue":"737461727473746f705f63616c6c33","id":465,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4410:17:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""},"value":"startstop_call3"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_8eb502bfdc4adda22bd960aa2ae13ce4c0ed8cc3b3791ed65e321a38cdd36f72","typeString":"literal_string \"startstop_call3\""}],"expression":{"id":462,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4399:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":464,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"call1","nodeType":"MemberAccess","referencedDeclaration":648,"src":"4399:10:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":466,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4399:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":467,"nodeType":"ExpressionStatement","src":"4399:29:0"},{"expression":{"arguments":[{"hexValue":"74657374696e67206e6573746564","id":471,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4451:16:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""},"value":"testing nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_f92f19f7a5b5b9ce341188bf4e15925f184cdb5ac135c4846ced718f259dbde5","typeString":"literal_string \"testing nested\""}],"expression":{"id":468,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4439:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":470,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4439:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":472,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4439:29:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":473,"nodeType":"ExpressionStatement","src":"4439:29:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307831323334","id":481,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4512:6:0","typeDescriptions":{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"},"value":"0x1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_4660_by_1","typeString":"int_const 4660"}],"id":480,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4504:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":479,"name":"uint160","nodeType":"ElementaryTypeName","src":"4504:7:0","typeDescriptions":{}}},"id":482,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4504:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":478,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4496:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":477,"name":"address","nodeType":"ElementaryTypeName","src":"4496:7:0","typeDescriptions":{}}},"id":483,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4496:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":474,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4478:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":476,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"startBroadcast","nodeType":"MemberAccess","referencedDeclaration":48,"src":"4478:17:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":484,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4478:43:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":485,"nodeType":"ExpressionStatement","src":"4478:43:0"},{"expression":{"arguments":[{"hexValue":"6e6573746564","id":489,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4544:8:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""},"value":"nested"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4d5b14044d78fbf0c9dd8b9c49e35f09ee5a6f5b1b3b8117b5d0e15c8dd2cb09","typeString":"literal_string \"nested\""}],"expression":{"id":486,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"4531:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":488,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested1","nodeType":"MemberAccess","referencedDeclaration":678,"src":"4531:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":490,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4531:22:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":491,"nodeType":"ExpressionStatement","src":"4531:22:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":492,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4563:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":494,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"stopBroadcast","nodeType":"MemberAccess","referencedDeclaration":54,"src":"4563:16:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":495,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4563:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":496,"nodeType":"ExpressionStatement","src":"4563:18:0"},{"expression":{"arguments":[{"hexValue":"636f6e7472616374206465706c6f796d656e74","id":500,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4604:21:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""},"value":"contract deployment"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_aaf9be86adf9b6872d87eed3526f7c55f3c5d61f4e4dd6d55ef2fcbb8ad0bd57","typeString":"literal_string \"contract deployment\""}],"expression":{"id":497,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4592:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":499,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4592:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":501,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4592:34:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":502,"nodeType":"ExpressionStatement","src":"4592:34:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"3078313233343536","id":510,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4665:8:0","typeDescriptions":{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"},"value":"0x123456"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1193046_by_1","typeString":"int_const 1193046"}],"id":509,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4657:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":508,"name":"uint160","nodeType":"ElementaryTypeName","src":"4657:7:0","typeDescriptions":{}}},"id":511,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4657:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":507,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4649:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":506,"name":"address","nodeType":"ElementaryTypeName","src":"4649:7:0","typeDescriptions":{}}},"id":512,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4649:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":503,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4636:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":505,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4636:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":513,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4636:40:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":514,"nodeType":"ExpressionStatement","src":"4636:40:0"},{"assignments":[517],"declarations":[{"constant":false,"id":517,"mutability":"mutable","name":"x","nameLocation":"4693:1:0","nodeType":"VariableDeclaration","scope":608,"src":"4686:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"},"typeName":{"id":516,"nodeType":"UserDefinedTypeName","pathNode":{"id":515,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":719,"src":"4686:6:0"},"referencedDeclaration":719,"src":"4686:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"visibility":"internal"}],"id":523,"initialValue":{"arguments":[{"hexValue":"31323334","id":521,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4708:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":520,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4697:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$719_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":519,"nodeType":"UserDefinedTypeName","pathNode":{"id":518,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":719,"src":"4701:6:0"},"referencedDeclaration":719,"src":"4701:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}}},"id":522,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4697:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4686:27:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":529,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":525,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":517,"src":"4731:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"id":526,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":708,"src":"4731:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":527,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4731:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":528,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4742:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4731:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":524,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4723:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":530,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4723:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":531,"nodeType":"ExpressionStatement","src":"4723:24:0"},{"expression":{"arguments":[{"hexValue":"6372656174652032","id":535,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4770:10:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""},"value":"create 2"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4411d6d4ffcd00382a95255a63761e69de9810e1236042a5c64948a7b6c04daa","typeString":"literal_string \"create 2\""}],"expression":{"id":532,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4758:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":534,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4758:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":536,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4758:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":537,"nodeType":"ExpressionStatement","src":"4758:23:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"307863616665","id":545,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4820:6:0","typeDescriptions":{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"},"value":"0xcafe"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_51966_by_1","typeString":"int_const 51966"}],"id":544,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4812:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":543,"name":"uint160","nodeType":"ElementaryTypeName","src":"4812:7:0","typeDescriptions":{}}},"id":546,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4812:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":542,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4804:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":541,"name":"address","nodeType":"ElementaryTypeName","src":"4804:7:0","typeDescriptions":{}}},"id":547,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4804:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":538,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"4791:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":540,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":43,"src":"4791:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$returns$__$","typeString":"function (address) external"}},"id":548,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4791:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":549,"nodeType":"ExpressionStatement","src":"4791:38:0"},{"assignments":[552],"declarations":[{"constant":false,"id":552,"mutability":"mutable","name":"y","nameLocation":"4846:1:0","nodeType":"VariableDeclaration","scope":608,"src":"4839:8:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"},"typeName":{"id":551,"nodeType":"UserDefinedTypeName","pathNode":{"id":550,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":719,"src":"4839:6:0"},"referencedDeclaration":719,"src":"4839:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"visibility":"internal"}],"id":566,"initialValue":{"arguments":[{"hexValue":"31323334","id":564,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4889:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":555,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"4850:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$719_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":554,"nodeType":"UserDefinedTypeName","pathNode":{"id":553,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":719,"src":"4854:6:0"},"referencedDeclaration":719,"src":"4854:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}}},"id":563,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"names":["salt"],"nodeType":"FunctionCallOptions","options":[{"arguments":[{"arguments":[{"hexValue":"3432","id":560,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4883:2:0","typeDescriptions":{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"},"value":"42"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_42_by_1","typeString":"int_const 42"}],"id":559,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4875:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":558,"name":"uint256","nodeType":"ElementaryTypeName","src":"4875:7:0","typeDescriptions":{}}},"id":561,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4875:11:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":557,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4867:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_bytes32_$","typeString":"type(bytes32)"},"typeName":{"id":556,"name":"bytes32","nodeType":"ElementaryTypeName","src":"4867:7:0","typeDescriptions":{}}},"id":562,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4867:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}}],"src":"4850:38:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$719_$salt","typeString":"function (uint256) returns (contract FooBar)"}},"id":565,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4850:44:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"nodeType":"VariableDeclarationStatement","src":"4839:55:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":572,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":568,"name":"y","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":552,"src":"4912:1:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"id":569,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"foo","nodeType":"MemberAccess","referencedDeclaration":708,"src":"4912:5:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$__$returns$_t_uint256_$","typeString":"function () view external returns (uint256)"}},"id":570,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4912:7:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"31323334","id":571,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4923:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"},"src":"4912:15:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"id":567,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4904:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$returns$__$","typeString":"function (bool) pure"}},"id":573,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4904:24:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":574,"nodeType":"ExpressionStatement","src":"4904:24:0"},{"expression":{"arguments":[{"hexValue":"646f6e6521","id":578,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4950:7:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""},"value":"done!"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_080382d5c9e9e7c5e3d1d33f5e7422740375955180fadff167d8130e0c35f3fc","typeString":"literal_string \"done!\""}],"expression":{"id":575,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"4938:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":577,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"4938:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":579,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"4938:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":580,"nodeType":"ExpressionStatement","src":"4938:20:0"},{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":581,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"5042:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":583,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"broadcast","nodeType":"MemberAccess","referencedDeclaration":38,"src":"5042:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$__$returns$__$","typeString":"function () external"}},"id":584,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5042:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":585,"nodeType":"ExpressionStatement","src":"5042:14:0"},{"expression":{"arguments":[{"hexValue":"31323334","id":589,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"5077:4:0","typeDescriptions":{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"},"value":"1234"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_1234_by_1","typeString":"int_const 1234"}],"id":588,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"NewExpression","src":"5066:10:0","typeDescriptions":{"typeIdentifier":"t_function_creation_nonpayable$_t_uint256_$returns$_t_contract$_FooBar_$719_$","typeString":"function (uint256) returns (contract FooBar)"},"typeName":{"id":587,"nodeType":"UserDefinedTypeName","pathNode":{"id":586,"name":"FooBar","nodeType":"IdentifierPath","referencedDeclaration":719,"src":"5070:6:0"},"referencedDeclaration":719,"src":"5070:6:0","typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}}},"id":590,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5066:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_FooBar_$719","typeString":"contract FooBar"}},"id":591,"nodeType":"ExpressionStatement","src":"5066:16:0"},{"expression":{"arguments":[{"hexValue":"6e6f6e636520656e64","id":595,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"5105:11:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_fa629e6661ad2a2bdb09cf9a3a276ce0d722482ae5c2887650751be0938847e8","typeString":"literal_string \"nonce end\""},"value":"nonce end"},{"arguments":[{"arguments":[{"arguments":[{"id":602,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"5146:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}],"id":601,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5138:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":600,"name":"address","nodeType":"ElementaryTypeName","src":"5138:7:0","typeDescriptions":{}}},"id":603,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5138:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":598,"name":"vm","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"5126:2:0","typeDescriptions":{"typeIdentifier":"t_contract$_Vm_$55","typeString":"contract Vm"}},"id":599,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"getNonce","nodeType":"MemberAccess","referencedDeclaration":17,"src":"5126:11:0","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$returns$_t_uint64_$","typeString":"function (address) view external returns (uint64)"}},"id":604,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5126:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint64","typeString":"uint64"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint64","typeString":"uint64"}],"id":597,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5118:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":596,"name":"uint256","nodeType":"ElementaryTypeName","src":"5118:7:0","typeDescriptions":{}}},"id":605,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5118:35:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_fa629e6661ad2a2bdb09cf9a3a276ce0d722482ae5c2887650751be0938847e8","typeString":"literal_string \"nonce end\""},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":592,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5093:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":594,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":154,"src":"5093:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_uint256_$returns$__$","typeString":"function (string memory,uint256) pure"}},"id":606,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5093:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":607,"nodeType":"ExpressionStatement","src":"5093:61:0"}]},"documentation":{"id":379,"nodeType":"StructuredDocumentation","src":"3842:56:0","text":"@notice example function, to test vm.broadcast with."},"functionSelector":"bef03abc","implemented":true,"kind":"function","modifiers":[],"name":"runBroadcast","nameLocation":"3912:12:0","parameters":{"id":380,"nodeType":"ParameterList","parameters":[],"src":"3924:2:0"},"returnParameters":{"id":381,"nodeType":"ParameterList","parameters":[],"src":"3934:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"id":633,"nodeType":"FunctionDefinition","src":"5256:143:0","nodes":[],"body":{"id":632,"nodeType":"Block","src":"5305:94:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":618,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":612,"src":"5327:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":615,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5315:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":617,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5315:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":619,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5315:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":620,"nodeType":"ExpressionStatement","src":"5315:15:0"},{"expression":{"arguments":[{"hexValue":"68656c6c6f206d73672e73656e646572","id":624,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"5352:18:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},"value":"hello msg.sender"},{"arguments":[{"expression":{"id":627,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"5380:3:0","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":628,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"sender","nodeType":"MemberAccess","src":"5380:10:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":626,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5372:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":625,"name":"address","nodeType":"ElementaryTypeName","src":"5372:7:0","typeDescriptions":{}}},"id":629,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5372:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_b3cc13bc51228b2c4c4334d82a4772908254dc0e1c512893dd16208ef13efb8e","typeString":"literal_string \"hello msg.sender\""},{"typeIdentifier":"t_address","typeString":"address"}],"expression":{"id":621,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5340:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":623,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":171,"src":"5340:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$_t_address_$returns$__$","typeString":"function (string memory,address) pure"}},"id":630,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5340:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":631,"nodeType":"ExpressionStatement","src":"5340:52:0"}]},"documentation":{"id":610,"nodeType":"StructuredDocumentation","src":"5167:84:0","text":"@notice example external function, to force a CALL, and test vm.startPrank with."},"functionSelector":"a777d0dc","implemented":true,"kind":"function","modifiers":[],"name":"hello","nameLocation":"5265:5:0","parameters":{"id":613,"nodeType":"ParameterList","parameters":[{"constant":false,"id":612,"mutability":"mutable","name":"_v","nameLocation":"5287:2:0","nodeType":"VariableDeclaration","scope":633,"src":"5271:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":611,"name":"string","nodeType":"ElementaryTypeName","src":"5271:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5270:20:0"},"returnParameters":{"id":614,"nodeType":"ParameterList","parameters":[],"src":"5305:0:0"},"scope":706,"stateMutability":"view","virtual":false,"visibility":"external"},{"id":648,"nodeType":"FunctionDefinition","src":"5405:95:0","nodes":[],"body":{"id":647,"nodeType":"Block","src":"5449:51:0","nodes":[],"statements":[{"expression":{"id":639,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5459:9:0","subExpression":{"id":638,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5459:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":640,"nodeType":"ExpressionStatement","src":"5459:9:0"},{"expression":{"arguments":[{"id":644,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":635,"src":"5490:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":641,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5478:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":643,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5478:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":645,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5478:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":646,"nodeType":"ExpressionStatement","src":"5478:15:0"}]},"functionSelector":"7e79255d","implemented":true,"kind":"function","modifiers":[],"name":"call1","nameLocation":"5414:5:0","parameters":{"id":636,"nodeType":"ParameterList","parameters":[{"constant":false,"id":635,"mutability":"mutable","name":"_v","nameLocation":"5436:2:0","nodeType":"VariableDeclaration","scope":648,"src":"5420:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":634,"name":"string","nodeType":"ElementaryTypeName","src":"5420:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5419:20:0"},"returnParameters":{"id":637,"nodeType":"ParameterList","parameters":[],"src":"5449:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":663,"nodeType":"FunctionDefinition","src":"5506:95:0","nodes":[],"body":{"id":662,"nodeType":"Block","src":"5550:51:0","nodes":[],"statements":[{"expression":{"id":654,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5560:9:0","subExpression":{"id":653,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5560:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":655,"nodeType":"ExpressionStatement","src":"5560:9:0"},{"expression":{"arguments":[{"id":659,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":650,"src":"5591:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":656,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5579:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":658,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5579:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":660,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5579:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":661,"nodeType":"ExpressionStatement","src":"5579:15:0"}]},"functionSelector":"8d3ef7ca","implemented":true,"kind":"function","modifiers":[],"name":"call2","nameLocation":"5515:5:0","parameters":{"id":651,"nodeType":"ParameterList","parameters":[{"constant":false,"id":650,"mutability":"mutable","name":"_v","nameLocation":"5537:2:0","nodeType":"VariableDeclaration","scope":663,"src":"5521:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":649,"name":"string","nodeType":"ElementaryTypeName","src":"5521:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5520:20:0"},"returnParameters":{"id":652,"nodeType":"ParameterList","parameters":[],"src":"5550:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":678,"nodeType":"FunctionDefinition","src":"5607:98:0","nodes":[],"body":{"id":677,"nodeType":"Block","src":"5653:52:0","nodes":[],"statements":[{"expression":{"id":669,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5663:9:0","subExpression":{"id":668,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5663:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":670,"nodeType":"ExpressionStatement","src":"5663:9:0"},{"expression":{"arguments":[{"id":674,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":665,"src":"5695:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":671,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"5682:4:0","typeDescriptions":{"typeIdentifier":"t_contract$_ScriptExample_$706","typeString":"contract ScriptExample"}},"id":673,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"nested2","nodeType":"MemberAccess","referencedDeclaration":693,"src":"5682:12:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) external"}},"id":675,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5682:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":676,"nodeType":"ExpressionStatement","src":"5682:16:0"}]},"functionSelector":"a76ccdfa","implemented":true,"kind":"function","modifiers":[],"name":"nested1","nameLocation":"5616:7:0","parameters":{"id":666,"nodeType":"ParameterList","parameters":[{"constant":false,"id":665,"mutability":"mutable","name":"_v","nameLocation":"5640:2:0","nodeType":"VariableDeclaration","scope":678,"src":"5624:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":664,"name":"string","nodeType":"ElementaryTypeName","src":"5624:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5623:20:0"},"returnParameters":{"id":667,"nodeType":"ParameterList","parameters":[],"src":"5653:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":693,"nodeType":"FunctionDefinition","src":"5711:97:0","nodes":[],"body":{"id":692,"nodeType":"Block","src":"5757:51:0","nodes":[],"statements":[{"expression":{"id":684,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"5767:9:0","subExpression":{"id":683,"name":"counter","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":215,"src":"5767:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":685,"nodeType":"ExpressionStatement","src":"5767:9:0"},{"expression":{"arguments":[{"id":689,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":680,"src":"5798:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":686,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5786:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":688,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5786:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":690,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5786:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":691,"nodeType":"ExpressionStatement","src":"5786:15:0"}]},"functionSelector":"dbf1282f","implemented":true,"kind":"function","modifiers":[],"name":"nested2","nameLocation":"5720:7:0","parameters":{"id":681,"nodeType":"ParameterList","parameters":[{"constant":false,"id":680,"mutability":"mutable","name":"_v","nameLocation":"5744:2:0","nodeType":"VariableDeclaration","scope":693,"src":"5728:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":679,"name":"string","nodeType":"ElementaryTypeName","src":"5728:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5727:20:0"},"returnParameters":{"id":682,"nodeType":"ParameterList","parameters":[],"src":"5757:0:0"},"scope":706,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"id":705,"nodeType":"FunctionDefinition","src":"5814:84:0","nodes":[],"body":{"id":704,"nodeType":"Block","src":"5866:32:0","nodes":[],"statements":[{"expression":{"arguments":[{"id":701,"name":"_v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":695,"src":"5888:2:0","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_calldata_ptr","typeString":"string calldata"}],"expression":{"id":698,"name":"console","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":192,"src":"5876:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_console_$192_$","typeString":"type(library console)"}},"id":700,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberName":"log","nodeType":"MemberAccess","referencedDeclaration":120,"src":"5876:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":702,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"names":[],"nodeType":"FunctionCall","src":"5876:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":703,"nodeType":"ExpressionStatement","src":"5876:15:0"}]},"functionSelector":"7f8b915c","implemented":true,"kind":"function","modifiers":[],"name":"callPure","nameLocation":"5823:8:0","parameters":{"id":696,"nodeType":"ParameterList","parameters":[{"constant":false,"id":695,"mutability":"mutable","name":"_v","nameLocation":"5848:2:0","nodeType":"VariableDeclaration","scope":705,"src":"5832:18:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":694,"name":"string","nodeType":"ElementaryTypeName","src":"5832:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5831:20:0"},"returnParameters":{"id":697,"nodeType":"ParameterList","parameters":[],"src":"5866:0:0"},"scope":706,"stateMutability":"pure","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"ScriptExample","contractDependencies":[719],"contractKind":"contract","documentation":{"id":193,"nodeType":"StructuredDocumentation","src":"2415:126:0","text":"@title ScriptExample\n @notice ScriptExample is an example script. The Go forge script code tests that it can run this."},"fullyImplemented":true,"linearizedBaseContracts":[706],"name":"ScriptExample","nameLocation":"2550:13:0","scope":720,"usedErrors":[]},{"id":719,"nodeType":"ContractDefinition","src":"5902:96:0","nodes":[{"id":708,"nodeType":"VariableDeclaration","src":"5924:18:0","nodes":[],"constant":false,"functionSelector":"c2985578","mutability":"mutable","name":"foo","nameLocation":"5939:3:0","scope":719,"stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":707,"name":"uint256","nodeType":"ElementaryTypeName","src":"5924:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"id":718,"nodeType":"FunctionDefinition","src":"5949:47:0","nodes":[],"body":{"id":717,"nodeType":"Block","src":"5972:24:0","nodes":[],"statements":[{"expression":{"id":715,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":713,"name":"foo","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":708,"src":"5982:3:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":714,"name":"v","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":710,"src":"5988:1:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5982:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":716,"nodeType":"ExpressionStatement","src":"5982:7:0"}]},"implemented":true,"kind":"constructor","modifiers":[],"name":"","nameLocation":"-1:-1:-1","parameters":{"id":711,"nodeType":"ParameterList","parameters":[{"constant":false,"id":710,"mutability":"mutable","name":"v","nameLocation":"5969:1:0","nodeType":"VariableDeclaration","scope":718,"src":"5961:9:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":709,"name":"uint256","nodeType":"ElementaryTypeName","src":"5961:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"5960:11:0"},"returnParameters":{"id":712,"nodeType":"ParameterList","parameters":[],"src":"5972:0:0"},"scope":719,"stateMutability":"nonpayable","virtual":false,"visibility":"public"}],"abstract":false,"baseContracts":[],"canonicalName":"FooBar","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[719],"name":"FooBar","nameLocation":"5911:6:0","scope":720,"usedErrors":[]}],"license":"MIT"},"id":0} \ No newline at end of file From 9a2224074b5e828805633c8a96efb8e3a268180b Mon Sep 17 00:00:00 2001 From: Matt Solomon Date: Wed, 11 Sep 2024 10:23:32 -0700 Subject: [PATCH 092/264] OPSM: remove structs from `DeploySuperchain` (#11833) * refactor: remove structs from DeploySuperchainInput and DeploySuperchainOutput * test: fix tests * test: fix test * chore: remove outdated struct references * pr feedback * chore: code comments --- .../scripts/DeploySuperchain.s.sol | 262 +++++++------- .../test/DeployOPChain.t.sol | 81 ++--- .../test/DeploySuperchain.t.sol | 329 +++++++++--------- 3 files changed, 339 insertions(+), 333 deletions(-) diff --git a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol index 2a6c104e66e5..dc0362879664 100644 --- a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol +++ b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.15; import { Script } from "forge-std/Script.sol"; import { CommonBase } from "forge-std/Base.sol"; +import { stdToml } from "forge-std/StdToml.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { ProtocolVersions, ProtocolVersion } from "src/L1/ProtocolVersions.sol"; @@ -24,7 +25,7 @@ import { Solarray } from "scripts/libraries/Solarray.sol"; // // We want each user to interact with the scripts in the way that's simplest for their use case: // 1. End users: TOML input files that define config, and TOML output files with all output data. -// 2. Solidity developers: Direct calls to the script with input structs and output structs. +// 2. Solidity developers: Direct calls to the script, with the input and output contracts configured. // 3. Go developers: The forge scripts can be executed directly in Go. // // The following architecture is used to meet the requirements of each user. We use this file's @@ -38,7 +39,7 @@ import { Solarray } from "scripts/libraries/Solarray.sol"; // // Because the core script performs calls to the input and output contracts, Go developers can // intercept calls to these addresses (analogous to how forge intercepts calls to the `Vm` address -// to execute cheatcodes), to avoid the need for file I/O or hardcoding the input/output structs. +// to execute cheatcodes), to avoid the need for file I/O or hardcoding the input/output values. // // Public getter methods on the input and output contracts allow individual fields to be accessed // in a strong, type-safe manner (as opposed to a single struct getter where the caller may @@ -57,180 +58,187 @@ import { Solarray } from "scripts/libraries/Solarray.sol"; // Additionally, we intentionally use "Input" and "Output" terminology to clearly distinguish these // scripts from the existing ones that use the "Config" and "Artifacts" terminology. contract DeploySuperchainInput is CommonBase { - // The input struct contains all the input data required for the deployment. - // The fields must be in alphabetical order for vm.parseToml to work. - struct Input { - bool paused; - ProtocolVersion recommendedProtocolVersion; - ProtocolVersion requiredProtocolVersion; - Roles roles; + using stdToml for string; + + // All inputs are set in storage individually. We put any roles first, followed by the remaining + // inputs. Inputs are internal and prefixed with an underscore, because we will expose a getter + // method that returns the input value. We use a getter method to allow us to make assertions on + // the input to ensure it's valid before returning it. We also intentionally do not use a struct + // to hold all inputs, because as features are developed the set of inputs will change, and + // modifying structs in Solidity is not very simple. + + // Role inputs. + address internal _guardian; + address internal _protocolVersionsOwner; + address internal _proxyAdminOwner; + + // Other inputs. + bool internal _paused; + ProtocolVersion internal _recommendedProtocolVersion; + ProtocolVersion internal _requiredProtocolVersion; + + // These `set` methods let each input be set individually. The selector of an input's getter method + // is used to determine which field to set. + function set(bytes4 _sel, address _address) public { + require(_address != address(0), "DeploySuperchainInput: cannot set null address"); + if (_sel == this.guardian.selector) _guardian = _address; + else if (_sel == this.protocolVersionsOwner.selector) _protocolVersionsOwner = _address; + else if (_sel == this.proxyAdminOwner.selector) _proxyAdminOwner = _address; + else revert("DeploySuperchainInput: unknown selector"); } - struct Roles { - address guardian; - address protocolVersionsOwner; - address proxyAdminOwner; + function set(bytes4 _sel, bool _value) public { + if (_sel == this.paused.selector) _paused = _value; + else revert("DeploySuperchainInput: unknown selector"); } - // This flag tells us if all inputs have been set. An `input()` getter method that returns all - // inputs reverts if this flag is false. This ensures the deploy script cannot proceed until all - // inputs are validated and set. - bool public inputSet = false; - - // The full input struct is kept in storage. It is not exposed because the return type would be - // a tuple, and it's more convenient for the return type to be the struct itself. Therefore the - // struct is exposed via the `input()` getter method below. - Input internal inputs; + function set(bytes4 _sel, ProtocolVersion _value) public { + require(ProtocolVersion.unwrap(_value) != 0, "DeploySuperchainInput: cannot set null protocol version"); + if (_sel == this.recommendedProtocolVersion.selector) _recommendedProtocolVersion = _value; + else if (_sel == this.requiredProtocolVersion.selector) _requiredProtocolVersion = _value; + else revert("DeploySuperchainInput: unknown selector"); + } // Load the input from a TOML file. + // When setting inputs from a TOML file, we use the setter methods instead of writing directly + // to storage. This allows us to validate each input as it is set. function loadInputFile(string memory _infile) public { string memory toml = vm.readFile(_infile); - bytes memory data = vm.parseToml(toml); - Input memory parsedInput = abi.decode(data, (Input)); - loadInput(parsedInput); - } - // Load the input from a struct. - function loadInput(Input memory _input) public { - // As a defensive measure, we only allow inputs to be set once. - require(!inputSet, "DeploySuperchainInput: input already set"); - - // All assertions on inputs happen here. You cannot set any inputs in Solidity unless - // they're all valid. For Go testing, the input and outputs are set individually by - // treating the input and output contracts as precompiles and intercepting calls to them. - require(_input.roles.proxyAdminOwner != address(0), "DeploySuperchainInput: null proxyAdminOwner"); - require(_input.roles.protocolVersionsOwner != address(0), "DeploySuperchainInput: null protocolVersionsOwner"); - require(_input.roles.guardian != address(0), "DeploySuperchainInput: null guardian"); - - // We now set all values in storage. - inputSet = true; - inputs = _input; - } + // Parse and set role inputs. + set(this.guardian.selector, toml.readAddress(".roles.guardian")); + set(this.protocolVersionsOwner.selector, toml.readAddress(".roles.protocolVersionsOwner")); + set(this.proxyAdminOwner.selector, toml.readAddress(".roles.proxyAdminOwner")); - function assertInputSet() internal view { - require(inputSet, "DeploySuperchainInput: input not set"); - } + // Parse and set other inputs. + set(this.paused.selector, toml.readBool(".paused")); - // This exposes the full input data as a struct, and it reverts if the input has not been set. - function input() public view returns (Input memory) { - assertInputSet(); - return inputs; + uint256 recVersion = toml.readUint(".recommendedProtocolVersion"); + set(this.recommendedProtocolVersion.selector, ProtocolVersion.wrap(recVersion)); + + uint256 reqVersion = toml.readUint(".requiredProtocolVersion"); + set(this.requiredProtocolVersion.selector, ProtocolVersion.wrap(reqVersion)); } - // Each field of the input struct is exposed via it's own getter method. Using public storage - // variables here would be more verbose, but would also be more error-prone, as it would - // require the caller to remember to check the `inputSet` flag before accessing any of the - // fields. With getter methods, we can be sure that the input is set before accessing any field. + // Each input field is exposed via it's own getter method. Using public storage variables here + // would be less verbose, but would also be more error-prone, as it would require the caller to + // validate that each input is set before accessing it. With getter methods, we can automatically + // validate that each input is set before allowing any field to be accessed. function proxyAdminOwner() public view returns (address) { - assertInputSet(); - return inputs.roles.proxyAdminOwner; + require(_proxyAdminOwner != address(0), "DeploySuperchainInput: proxyAdminOwner not set"); + return _proxyAdminOwner; } function protocolVersionsOwner() public view returns (address) { - assertInputSet(); - return inputs.roles.protocolVersionsOwner; + require(_protocolVersionsOwner != address(0), "DeploySuperchainInput: protocolVersionsOwner not set"); + return _protocolVersionsOwner; } function guardian() public view returns (address) { - assertInputSet(); - return inputs.roles.guardian; + require(_guardian != address(0), "DeploySuperchainInput: guardian not set"); + return _guardian; } function paused() public view returns (bool) { - assertInputSet(); - return inputs.paused; + return _paused; } function requiredProtocolVersion() public view returns (ProtocolVersion) { - assertInputSet(); - return inputs.requiredProtocolVersion; + require( + ProtocolVersion.unwrap(_requiredProtocolVersion) != 0, + "DeploySuperchainInput: requiredProtocolVersion not set" + ); + return _requiredProtocolVersion; } function recommendedProtocolVersion() public view returns (ProtocolVersion) { - assertInputSet(); - return inputs.recommendedProtocolVersion; + require( + ProtocolVersion.unwrap(_recommendedProtocolVersion) != 0, + "DeploySuperchainInput: recommendedProtocolVersion not set" + ); + return _recommendedProtocolVersion; } } contract DeploySuperchainOutput is CommonBase { - // The output struct contains all the output data from the deployment. - // The fields must be in alphabetical order for vm.parseToml to work. - struct Output { - ProtocolVersions protocolVersionsImpl; - ProtocolVersions protocolVersionsProxy; - SuperchainConfig superchainConfigImpl; - SuperchainConfig superchainConfigProxy; - ProxyAdmin superchainProxyAdmin; - } - - // We use a similar pattern as the input contract to expose outputs. Because outputs are set - // individually, and deployment steps are modular and composable, we do not have an equivalent - // to the overall `inputSet` variable. However, we do hold everything in a struct, then - // similarly expose each field via a getter method. This getter method reverts if the output has - // not been set, ensuring that the caller cannot access any output fields until they have been set. - Output internal outputs; + // All outputs are stored in storage individually, with the same rationale as doing so for + // inputs, and the same pattern is used below to expose the outputs. + ProtocolVersions internal _protocolVersionsImpl; + ProtocolVersions internal _protocolVersionsProxy; + SuperchainConfig internal _superchainConfigImpl; + SuperchainConfig internal _superchainConfigProxy; + ProxyAdmin internal _superchainProxyAdmin; // This method lets each field be set individually. The selector of an output's getter method // is used to determine which field to set. function set(bytes4 sel, address _address) public { - if (sel == this.superchainProxyAdmin.selector) outputs.superchainProxyAdmin = ProxyAdmin(_address); - else if (sel == this.superchainConfigImpl.selector) outputs.superchainConfigImpl = SuperchainConfig(_address); - else if (sel == this.superchainConfigProxy.selector) outputs.superchainConfigProxy = SuperchainConfig(_address); - else if (sel == this.protocolVersionsImpl.selector) outputs.protocolVersionsImpl = ProtocolVersions(_address); - else if (sel == this.protocolVersionsProxy.selector) outputs.protocolVersionsProxy = ProtocolVersions(_address); + if (sel == this.superchainProxyAdmin.selector) _superchainProxyAdmin = ProxyAdmin(_address); + else if (sel == this.superchainConfigImpl.selector) _superchainConfigImpl = SuperchainConfig(_address); + else if (sel == this.superchainConfigProxy.selector) _superchainConfigProxy = SuperchainConfig(_address); + else if (sel == this.protocolVersionsImpl.selector) _protocolVersionsImpl = ProtocolVersions(_address); + else if (sel == this.protocolVersionsProxy.selector) _protocolVersionsProxy = ProtocolVersions(_address); else revert("DeploySuperchainOutput: unknown selector"); } // Save the output to a TOML file. + // We fetch the output values using external calls to the getters to verify that all outputs are + // set correctly before writing them to the file. function writeOutputFile(string memory _outfile) public { string memory key = "dso-outfile"; - vm.serializeAddress(key, "superchainProxyAdmin", address(outputs.superchainProxyAdmin)); - vm.serializeAddress(key, "superchainConfigImpl", address(outputs.superchainConfigImpl)); - vm.serializeAddress(key, "superchainConfigProxy", address(outputs.superchainConfigProxy)); - vm.serializeAddress(key, "protocolVersionsImpl", address(outputs.protocolVersionsImpl)); - string memory out = vm.serializeAddress(key, "protocolVersionsProxy", address(outputs.protocolVersionsProxy)); + vm.serializeAddress(key, "superchainProxyAdmin", address(this.superchainProxyAdmin())); + vm.serializeAddress(key, "superchainConfigImpl", address(this.superchainConfigImpl())); + vm.serializeAddress(key, "superchainConfigProxy", address(this.superchainConfigProxy())); + vm.serializeAddress(key, "protocolVersionsImpl", address(this.protocolVersionsImpl())); + string memory out = vm.serializeAddress(key, "protocolVersionsProxy", address(this.protocolVersionsProxy())); vm.writeToml(out, _outfile); } - function output() public view returns (Output memory) { - return outputs; - } - - function checkOutput() public view { + // This function can be called to ensure all outputs are correct. Similar to `writeOutputFile`, + // it fetches the output values using external calls to the getter methods for safety. + function checkOutput() public { address[] memory addrs = Solarray.addresses( - address(outputs.superchainProxyAdmin), - address(outputs.superchainConfigImpl), - address(outputs.superchainConfigProxy), - address(outputs.protocolVersionsImpl), - address(outputs.protocolVersionsProxy) + address(this.superchainProxyAdmin()), + address(this.superchainConfigImpl()), + address(this.superchainConfigProxy()), + address(this.protocolVersionsImpl()), + address(this.protocolVersionsProxy()) ); DeployUtils.assertValidContractAddresses(addrs); + + // To read the implementations we prank as the zero address due to the proxyCallIfNotAdmin modifier. + vm.startPrank(address(0)); + address actualSuperchainConfigImpl = Proxy(payable(address(_superchainConfigProxy))).implementation(); + address actualProtocolVersionsImpl = Proxy(payable(address(_protocolVersionsProxy))).implementation(); + vm.stopPrank(); + + require(actualSuperchainConfigImpl == address(_superchainConfigImpl), "100"); + require(actualProtocolVersionsImpl == address(_protocolVersionsImpl), "200"); } function superchainProxyAdmin() public view returns (ProxyAdmin) { - DeployUtils.assertValidContractAddress(address(outputs.superchainProxyAdmin)); - return outputs.superchainProxyAdmin; + // This does not have to be a contract address, it could be an EOA. + return _superchainProxyAdmin; } function superchainConfigImpl() public view returns (SuperchainConfig) { - DeployUtils.assertValidContractAddress(address(outputs.superchainConfigImpl)); - return outputs.superchainConfigImpl; + DeployUtils.assertValidContractAddress(address(_superchainConfigImpl)); + return _superchainConfigImpl; } function superchainConfigProxy() public view returns (SuperchainConfig) { - DeployUtils.assertValidContractAddress(address(outputs.superchainConfigProxy)); - return outputs.superchainConfigProxy; + DeployUtils.assertValidContractAddress(address(_superchainConfigProxy)); + return _superchainConfigProxy; } function protocolVersionsImpl() public view returns (ProtocolVersions) { - DeployUtils.assertValidContractAddress(address(outputs.protocolVersionsImpl)); - return outputs.protocolVersionsImpl; + DeployUtils.assertValidContractAddress(address(_protocolVersionsImpl)); + return _protocolVersionsImpl; } function protocolVersionsProxy() public view returns (ProtocolVersions) { - DeployUtils.assertValidContractAddress(address(outputs.protocolVersionsProxy)); - return outputs.protocolVersionsProxy; + DeployUtils.assertValidContractAddress(address(_protocolVersionsProxy)); + return _protocolVersionsProxy; } } @@ -258,25 +266,16 @@ contract DeploySuperchain is Script { dso.writeOutputFile(_outfile); } - // This entrypoint is for use with Solidity tests, where the input and outputs are structs. - function run(DeploySuperchainInput.Input memory _input) public returns (DeploySuperchainOutput.Output memory) { - // Solidity without file IO, so etch the IO helper contracts. - (DeploySuperchainInput dsi, DeploySuperchainOutput dso) = etchIOContracts(); - - // Load the input struct into the input contract. - dsi.loadInput(_input); - - // Run the deployment script and write outputs to the DeploySuperchainOutput contract. - run(dsi, dso); - - // Return the output struct from the output contract. - return dso.output(); - } - // This entrypoint is useful for testing purposes, as it doesn't use any file I/O. function run(DeploySuperchainInput _dsi, DeploySuperchainOutput _dso) public { - // Verify that the input contract has been set. - require(_dsi.inputSet(), "DeploySuperchain: input not set"); + // Notice that we do not do any explicit verification here that inputs are set. This is because + // the verification happens elsewhere: + // - Getter methods on the input contract provide sanity checks that values are set, when applicable. + // - The individual methods below that we use to compose the deployment are responsible for handling + // their own verification. + // This pattern ensures that other deploy scripts that might compose these contracts and + // methods in different ways are still protected from invalid inputs without need to implement + // additional verification logic. // Deploy the proxy admin, with the owner set to the deployer. deploySuperchainProxyAdmin(_dsi, _dso); @@ -377,7 +376,11 @@ contract DeploySuperchain is Script { // -------- Utilities -------- - function etchIOContracts() internal returns (DeploySuperchainInput dsi_, DeploySuperchainOutput dso_) { + // This etches the IO contracts into memory so that we can use them in tests. When using file IO + // we don't need to call this directly, as the `DeploySuperchain.run(file, file)` entrypoint + // handles it. But when interacting with the script programmatically (e.g. in a Solidity test), + // this must be called. + function etchIOContracts() public returns (DeploySuperchainInput dsi_, DeploySuperchainOutput dso_) { (dsi_, dso_) = getIOContracts(); vm.etch(address(dsi_), type(DeploySuperchainInput).runtimeCode); vm.etch(address(dso_), type(DeploySuperchainOutput).runtimeCode); @@ -385,6 +388,7 @@ contract DeploySuperchain is Script { vm.allowCheatcodes(address(dso_)); } + // This returns the addresses of the IO contracts for this script. function getIOContracts() public view returns (DeploySuperchainInput dsi_, DeploySuperchainOutput dso_) { dsi_ = DeploySuperchainInput(DeployUtils.toIOAddress(msg.sender, "optimism.DeploySuperchainInput")); dso_ = DeploySuperchainOutput(DeployUtils.toIOAddress(msg.sender, "optimism.DeploySuperchainOutput")); diff --git a/packages/contracts-bedrock/test/DeployOPChain.t.sol b/packages/contracts-bedrock/test/DeployOPChain.t.sol index a9fde919d3d7..7cf975946d28 100644 --- a/packages/contracts-bedrock/test/DeployOPChain.t.sol +++ b/packages/contracts-bedrock/test/DeployOPChain.t.sol @@ -321,22 +321,17 @@ contract DeployOPChainOutput_Test is Test { // DeploySuperchain and DeployImplementations scripts. contract DeployOPChain_TestBase is Test { DeployOPChain deployOPChain; - DeployOPChainInput dsi; - DeployOPChainOutput dso; - - // We define a default initial input struct for DeploySuperchain. The other input structs are - // dependent on the outputs of the previous scripts, so we initialize them here and populate - // the null values in the `setUp` method.assert - DeploySuperchainInput.Input deploySuperchainInput = DeploySuperchainInput.Input({ - roles: DeploySuperchainInput.Roles({ - proxyAdminOwner: makeAddr("defaultProxyAdminOwner"), - protocolVersionsOwner: makeAddr("defaultProtocolVersionsOwner"), - guardian: makeAddr("defaultGuardian") - }), - paused: false, - requiredProtocolVersion: ProtocolVersion.wrap(1), - recommendedProtocolVersion: ProtocolVersion.wrap(2) - }); + DeployOPChainInput doi; + DeployOPChainOutput doo; + + // We define a default initial input set for DeploySuperchain. The other inputs are dependent + // on the outputs of the previous scripts, so we initialize them in the `setUp` method. + address proxyAdminOwner = makeAddr("defaultProxyAdminOwner"); + address protocolVersionsOwner = makeAddr("defaultProtocolVersionsOwner"); + address guardian = makeAddr("defaultGuardian"); + bool paused = false; + ProtocolVersion requiredProtocolVersion = ProtocolVersion.wrap(1); + ProtocolVersion recommendedProtocolVersion = ProtocolVersion.wrap(2); DeployImplementationsInput.Input deployImplementationsInput = DeployImplementationsInput.Input({ withdrawalDelaySeconds: 100, @@ -372,16 +367,24 @@ contract DeployOPChain_TestBase is Test { function setUp() public { // Initialize deploy scripts. DeploySuperchain deploySuperchain = new DeploySuperchain(); + (DeploySuperchainInput dsi, DeploySuperchainOutput dso) = deploySuperchain.etchIOContracts(); + dsi.set(dsi.proxyAdminOwner.selector, proxyAdminOwner); + dsi.set(dsi.protocolVersionsOwner.selector, protocolVersionsOwner); + dsi.set(dsi.guardian.selector, guardian); + dsi.set(dsi.paused.selector, paused); + dsi.set(dsi.requiredProtocolVersion.selector, requiredProtocolVersion); + dsi.set(dsi.recommendedProtocolVersion.selector, recommendedProtocolVersion); + DeployImplementations deployImplementations = new DeployImplementations(); deployOPChain = new DeployOPChain(); - (dsi, dso) = deployOPChain.getIOContracts(); + (doi, doo) = deployOPChain.getIOContracts(); // Deploy the superchain contracts. - DeploySuperchainOutput.Output memory superchainOutput = deploySuperchain.run(deploySuperchainInput); + deploySuperchain.run(dsi, dso); // Populate the input struct for DeployImplementations based on the output of DeploySuperchain. - deployImplementationsInput.superchainConfigProxy = superchainOutput.superchainConfigProxy; - deployImplementationsInput.protocolVersionsProxy = superchainOutput.protocolVersionsProxy; + deployImplementationsInput.superchainConfigProxy = dso.superchainConfigProxy(); + deployImplementationsInput.protocolVersionsProxy = dso.protocolVersionsProxy(); // Deploy the implementations using the updated DeployImplementations input struct. deployImplementationsOutput = deployImplementations.run(deployImplementationsInput); @@ -414,31 +417,31 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { // TODO Add fault proof contract assertions below once OPSM fully supports them. // Assert that individual input fields were properly set based on the input struct. - assertEq(_input.roles.opChainProxyAdminOwner, dsi.opChainProxyAdminOwner(), "100"); - assertEq(_input.roles.systemConfigOwner, dsi.systemConfigOwner(), "200"); - assertEq(_input.roles.batcher, dsi.batcher(), "300"); - assertEq(_input.roles.unsafeBlockSigner, dsi.unsafeBlockSigner(), "400"); - assertEq(_input.roles.proposer, dsi.proposer(), "500"); - assertEq(_input.roles.challenger, dsi.challenger(), "600"); - assertEq(_input.basefeeScalar, dsi.basefeeScalar(), "700"); - assertEq(_input.blobBaseFeeScalar, dsi.blobBaseFeeScalar(), "800"); - assertEq(_input.l2ChainId, dsi.l2ChainId(), "900"); + assertEq(_input.roles.opChainProxyAdminOwner, doi.opChainProxyAdminOwner(), "100"); + assertEq(_input.roles.systemConfigOwner, doi.systemConfigOwner(), "200"); + assertEq(_input.roles.batcher, doi.batcher(), "300"); + assertEq(_input.roles.unsafeBlockSigner, doi.unsafeBlockSigner(), "400"); + assertEq(_input.roles.proposer, doi.proposer(), "500"); + assertEq(_input.roles.challenger, doi.challenger(), "600"); + assertEq(_input.basefeeScalar, doi.basefeeScalar(), "700"); + assertEq(_input.blobBaseFeeScalar, doi.blobBaseFeeScalar(), "800"); + assertEq(_input.l2ChainId, doi.l2ChainId(), "900"); // Assert that individual output fields were properly set based on the output struct. - assertEq(address(output.opChainProxyAdmin), address(dso.opChainProxyAdmin()), "1100"); - assertEq(address(output.addressManager), address(dso.addressManager()), "1200"); - assertEq(address(output.l1ERC721BridgeProxy), address(dso.l1ERC721BridgeProxy()), "1300"); - assertEq(address(output.systemConfigProxy), address(dso.systemConfigProxy()), "1400"); + assertEq(address(output.opChainProxyAdmin), address(doo.opChainProxyAdmin()), "1100"); + assertEq(address(output.addressManager), address(doo.addressManager()), "1200"); + assertEq(address(output.l1ERC721BridgeProxy), address(doo.l1ERC721BridgeProxy()), "1300"); + assertEq(address(output.systemConfigProxy), address(doo.systemConfigProxy()), "1400"); assertEq( - address(output.optimismMintableERC20FactoryProxy), address(dso.optimismMintableERC20FactoryProxy()), "1500" + address(output.optimismMintableERC20FactoryProxy), address(doo.optimismMintableERC20FactoryProxy()), "1500" ); - assertEq(address(output.l1StandardBridgeProxy), address(dso.l1StandardBridgeProxy()), "1600"); - assertEq(address(output.l1CrossDomainMessengerProxy), address(dso.l1CrossDomainMessengerProxy()), "1700"); - assertEq(address(output.optimismPortalProxy), address(dso.optimismPortalProxy()), "1800"); + assertEq(address(output.l1StandardBridgeProxy), address(doo.l1StandardBridgeProxy()), "1600"); + assertEq(address(output.l1CrossDomainMessengerProxy), address(doo.l1CrossDomainMessengerProxy()), "1700"); + assertEq(address(output.optimismPortalProxy), address(doo.optimismPortalProxy()), "1800"); // Assert that the full input and output structs were properly set. - assertEq(keccak256(abi.encode(_input)), keccak256(abi.encode(DeployOPChainInput(dsi).input())), "1900"); - assertEq(keccak256(abi.encode(output)), keccak256(abi.encode(DeployOPChainOutput(dso).output())), "2000"); + assertEq(keccak256(abi.encode(_input)), keccak256(abi.encode(DeployOPChainInput(doi).input())), "1900"); + assertEq(keccak256(abi.encode(output)), keccak256(abi.encode(DeployOPChainOutput(doo).output())), "2000"); // Assert inputs were properly passed through to the contract initializers. assertEq(address(output.opChainProxyAdmin.owner()), _input.roles.opChainProxyAdminOwner, "2100"); diff --git a/packages/contracts-bedrock/test/DeploySuperchain.t.sol b/packages/contracts-bedrock/test/DeploySuperchain.t.sol index 8babb4877a25..62f241d02340 100644 --- a/packages/contracts-bedrock/test/DeploySuperchain.t.sol +++ b/packages/contracts-bedrock/test/DeploySuperchain.t.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Test } from "forge-std/Test.sol"; +import { Test, stdStorage, StdStorage } from "forge-std/Test.sol"; +import { stdToml } from "forge-std/StdToml.sol"; import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { Proxy } from "src/universal/Proxy.sol"; @@ -12,84 +13,60 @@ import { DeploySuperchainInput, DeploySuperchain, DeploySuperchainOutput } from contract DeploySuperchainInput_Test is Test { DeploySuperchainInput dsi; - DeploySuperchainInput.Input input = DeploySuperchainInput.Input({ - roles: DeploySuperchainInput.Roles({ - proxyAdminOwner: makeAddr("defaultProxyAdminOwner"), - protocolVersionsOwner: makeAddr("defaultProtocolVersionsOwner"), - guardian: makeAddr("defaultGuardian") - }), - paused: false, - requiredProtocolVersion: ProtocolVersion.wrap(1), - recommendedProtocolVersion: ProtocolVersion.wrap(2) - }); + address proxyAdminOwner = makeAddr("defaultProxyAdminOwner"); + address protocolVersionsOwner = makeAddr("defaultProtocolVersionsOwner"); + address guardian = makeAddr("defaultGuardian"); + bool paused = false; + ProtocolVersion requiredProtocolVersion = ProtocolVersion.wrap(1); + ProtocolVersion recommendedProtocolVersion = ProtocolVersion.wrap(2); function setUp() public { dsi = new DeploySuperchainInput(); } - function test_loadInput_succeeds() public { - // We avoid using a fuzz test here because we'd need to modify the inputs of multiple - // parameters to e.g. avoid the zero address. Therefore we hardcode a concrete test case - // which is simpler and still sufficient. - dsi.loadInput(input); - assertLoadInput(); - } - function test_loadInputFile_succeeds() public { string memory root = vm.projectRoot(); string memory path = string.concat(root, "/test/fixtures/test-deploy-superchain-in.toml"); dsi.loadInputFile(path); - assertLoadInput(); + + assertEq(proxyAdminOwner, dsi.proxyAdminOwner(), "100"); + assertEq(protocolVersionsOwner, dsi.protocolVersionsOwner(), "200"); + assertEq(guardian, dsi.guardian(), "300"); + assertEq(paused, dsi.paused(), "400"); + assertEq( + ProtocolVersion.unwrap(requiredProtocolVersion), + ProtocolVersion.unwrap(dsi.requiredProtocolVersion()), + "500" + ); + assertEq( + ProtocolVersion.unwrap(recommendedProtocolVersion), + ProtocolVersion.unwrap(dsi.recommendedProtocolVersion()), + "600" + ); } function test_getters_whenNotSet_revert() public { - bytes memory expectedErr = "DeploySuperchainInput: input not set"; - - vm.expectRevert(expectedErr); + vm.expectRevert("DeploySuperchainInput: proxyAdminOwner not set"); dsi.proxyAdminOwner(); - vm.expectRevert(expectedErr); + vm.expectRevert("DeploySuperchainInput: protocolVersionsOwner not set"); dsi.protocolVersionsOwner(); - vm.expectRevert(expectedErr); + vm.expectRevert("DeploySuperchainInput: guardian not set"); dsi.guardian(); - vm.expectRevert(expectedErr); - dsi.paused(); - - vm.expectRevert(expectedErr); + vm.expectRevert("DeploySuperchainInput: requiredProtocolVersion not set"); dsi.requiredProtocolVersion(); - vm.expectRevert(expectedErr); + vm.expectRevert("DeploySuperchainInput: recommendedProtocolVersion not set"); dsi.recommendedProtocolVersion(); } - - function assertLoadInput() internal view { - assertTrue(dsi.inputSet(), "100"); - - // Compare the test input struct to the getter methods. - assertEq(input.roles.proxyAdminOwner, dsi.proxyAdminOwner(), "200"); - assertEq(input.roles.protocolVersionsOwner, dsi.protocolVersionsOwner(), "300"); - assertEq(input.roles.guardian, dsi.guardian(), "400"); - assertEq(input.paused, dsi.paused(), "500"); - assertEq( - ProtocolVersion.unwrap(input.requiredProtocolVersion), - ProtocolVersion.unwrap(dsi.requiredProtocolVersion()), - "600" - ); - assertEq( - ProtocolVersion.unwrap(input.recommendedProtocolVersion), - ProtocolVersion.unwrap(dsi.recommendedProtocolVersion()), - "700" - ); - - // Compare the test input struct to the `input` getter method. - assertEq(keccak256(abi.encode(input)), keccak256(abi.encode(dsi.input())), "800"); - } } contract DeploySuperchainOutput_Test is Test { + using stdToml for string; + DeploySuperchainOutput dso; function setUp() public { @@ -100,55 +77,45 @@ contract DeploySuperchainOutput_Test is Test { // We don't fuzz, because we need code at the address, and we can't etch code if the fuzzer // provides precompiles, so we end up with a lot of boilerplate logic to get valid inputs. // Hardcoding a concrete set of valid addresses is simpler and still sufficient. - DeploySuperchainOutput.Output memory output = DeploySuperchainOutput.Output({ - superchainProxyAdmin: ProxyAdmin(makeAddr("superchainProxyAdmin")), - superchainConfigImpl: SuperchainConfig(makeAddr("superchainConfigImpl")), - superchainConfigProxy: SuperchainConfig(makeAddr("superchainConfigProxy")), - protocolVersionsImpl: ProtocolVersions(makeAddr("protocolVersionsImpl")), - protocolVersionsProxy: ProtocolVersions(makeAddr("protocolVersionsProxy")) - }); + ProxyAdmin superchainProxyAdmin = ProxyAdmin(makeAddr("superchainProxyAdmin")); + SuperchainConfig superchainConfigImpl = SuperchainConfig(makeAddr("superchainConfigImpl")); + SuperchainConfig superchainConfigProxy = SuperchainConfig(makeAddr("superchainConfigProxy")); + ProtocolVersions protocolVersionsImpl = ProtocolVersions(makeAddr("protocolVersionsImpl")); + ProtocolVersions protocolVersionsProxy = ProtocolVersions(makeAddr("protocolVersionsProxy")); // Ensure each address has code, since these are expected to be contracts. - vm.etch(address(output.superchainProxyAdmin), hex"01"); - vm.etch(address(output.superchainConfigImpl), hex"01"); - vm.etch(address(output.superchainConfigProxy), hex"01"); - vm.etch(address(output.protocolVersionsImpl), hex"01"); - vm.etch(address(output.protocolVersionsProxy), hex"01"); + vm.etch(address(superchainProxyAdmin), hex"01"); + vm.etch(address(superchainConfigImpl), hex"01"); + vm.etch(address(superchainConfigProxy), hex"01"); + vm.etch(address(protocolVersionsImpl), hex"01"); + vm.etch(address(protocolVersionsProxy), hex"01"); // Set the output data. - dso.set(dso.superchainProxyAdmin.selector, address(output.superchainProxyAdmin)); - dso.set(dso.superchainConfigImpl.selector, address(output.superchainConfigImpl)); - dso.set(dso.superchainConfigProxy.selector, address(output.superchainConfigProxy)); - dso.set(dso.protocolVersionsImpl.selector, address(output.protocolVersionsImpl)); - dso.set(dso.protocolVersionsProxy.selector, address(output.protocolVersionsProxy)); - - // Compare the test output struct to the getter methods. - assertEq(address(output.superchainProxyAdmin), address(dso.superchainProxyAdmin()), "100"); - assertEq(address(output.superchainConfigImpl), address(dso.superchainConfigImpl()), "200"); - assertEq(address(output.superchainConfigProxy), address(dso.superchainConfigProxy()), "300"); - assertEq(address(output.protocolVersionsImpl), address(dso.protocolVersionsImpl()), "400"); - assertEq(address(output.protocolVersionsProxy), address(dso.protocolVersionsProxy()), "500"); - - // Compare the test output struct to the `output` getter method. - assertEq(keccak256(abi.encode(output)), keccak256(abi.encode(dso.output())), "600"); + dso.set(dso.superchainProxyAdmin.selector, address(superchainProxyAdmin)); + dso.set(dso.superchainConfigImpl.selector, address(superchainConfigImpl)); + dso.set(dso.superchainConfigProxy.selector, address(superchainConfigProxy)); + dso.set(dso.protocolVersionsImpl.selector, address(protocolVersionsImpl)); + dso.set(dso.protocolVersionsProxy.selector, address(protocolVersionsProxy)); + + // Compare the test data to the getter methods. + assertEq(address(superchainProxyAdmin), address(dso.superchainProxyAdmin()), "100"); + assertEq(address(superchainConfigImpl), address(dso.superchainConfigImpl()), "200"); + assertEq(address(superchainConfigProxy), address(dso.superchainConfigProxy()), "300"); + assertEq(address(protocolVersionsImpl), address(dso.protocolVersionsImpl()), "400"); + assertEq(address(protocolVersionsProxy), address(dso.protocolVersionsProxy()), "500"); } function test_getters_whenNotSet_revert() public { - bytes memory expectedErr = "DeployUtils: zero address"; - - vm.expectRevert(expectedErr); - dso.superchainProxyAdmin(); - - vm.expectRevert(expectedErr); + vm.expectRevert("DeployUtils: zero address"); dso.superchainConfigImpl(); - vm.expectRevert(expectedErr); + vm.expectRevert("DeployUtils: zero address"); dso.superchainConfigProxy(); - vm.expectRevert(expectedErr); + vm.expectRevert("DeployUtils: zero address"); dso.protocolVersionsImpl(); - vm.expectRevert(expectedErr); + vm.expectRevert("DeployUtils: zero address"); dso.protocolVersionsProxy(); } @@ -156,10 +123,6 @@ contract DeploySuperchainOutput_Test is Test { address emptyAddr = makeAddr("emptyAddr"); bytes memory expectedErr = bytes(string.concat("DeployUtils: no code at ", vm.toString(emptyAddr))); - dso.set(dso.superchainProxyAdmin.selector, emptyAddr); - vm.expectRevert(expectedErr); - dso.superchainProxyAdmin(); - dso.set(dso.superchainConfigImpl.selector, emptyAddr); vm.expectRevert(expectedErr); dso.superchainConfigImpl(); @@ -183,14 +146,26 @@ contract DeploySuperchainOutput_Test is Test { // Use the expected data from the test fixture. string memory expOutPath = string.concat(root, "/test/fixtures/test-deploy-superchain-out.toml"); string memory expOutToml = vm.readFile(expOutPath); - bytes memory expOutData = vm.parseToml(expOutToml); - DeploySuperchainOutput.Output memory expOutput = abi.decode(expOutData, (DeploySuperchainOutput.Output)); - dso.set(dso.superchainProxyAdmin.selector, address(expOutput.superchainProxyAdmin)); - dso.set(dso.superchainConfigImpl.selector, address(expOutput.superchainConfigImpl)); - dso.set(dso.superchainConfigProxy.selector, address(expOutput.superchainConfigProxy)); - dso.set(dso.protocolVersionsImpl.selector, address(expOutput.protocolVersionsImpl)); - dso.set(dso.protocolVersionsProxy.selector, address(expOutput.protocolVersionsProxy)); + // Parse each field of expOutToml individually. + ProxyAdmin expSuperchainProxyAdmin = ProxyAdmin(expOutToml.readAddress(".superchainProxyAdmin")); + SuperchainConfig expSuperchainConfigImpl = SuperchainConfig(expOutToml.readAddress(".superchainConfigImpl")); + SuperchainConfig expSuperchainConfigProxy = SuperchainConfig(expOutToml.readAddress(".superchainConfigProxy")); + ProtocolVersions expProtocolVersionsImpl = ProtocolVersions(expOutToml.readAddress(".protocolVersionsImpl")); + ProtocolVersions expProtocolVersionsProxy = ProtocolVersions(expOutToml.readAddress(".protocolVersionsProxy")); + + // Etch code at each address so the code checks pass when settings values. + vm.etch(address(expSuperchainConfigImpl), hex"01"); + vm.etch(address(expSuperchainConfigProxy), hex"01"); + vm.etch(address(expProtocolVersionsImpl), hex"01"); + vm.etch(address(expProtocolVersionsProxy), hex"01"); + + dso.set(dso.superchainProxyAdmin.selector, address(expSuperchainProxyAdmin)); + dso.set(dso.superchainProxyAdmin.selector, address(expSuperchainProxyAdmin)); + dso.set(dso.superchainConfigImpl.selector, address(expSuperchainConfigImpl)); + dso.set(dso.superchainConfigProxy.selector, address(expSuperchainConfigProxy)); + dso.set(dso.protocolVersionsImpl.selector, address(expProtocolVersionsImpl)); + dso.set(dso.protocolVersionsProxy.selector, address(expProtocolVersionsProxy)); string memory actOutPath = string.concat(root, "/.testdata/test-deploy-superchain-output.toml"); dso.writeOutputFile(actOutPath); @@ -204,75 +179,73 @@ contract DeploySuperchainOutput_Test is Test { } contract DeploySuperchain_Test is Test { + using stdStorage for StdStorage; + DeploySuperchain deploySuperchain; DeploySuperchainInput dsi; DeploySuperchainOutput dso; - // Define a default input struct for testing. - DeploySuperchainInput.Input input = DeploySuperchainInput.Input({ - roles: DeploySuperchainInput.Roles({ - proxyAdminOwner: makeAddr("defaultProxyAdminOwner"), - protocolVersionsOwner: makeAddr("defaultProtocolVersionsOwner"), - guardian: makeAddr("defaultGuardian") - }), - paused: false, - requiredProtocolVersion: ProtocolVersion.wrap(1), - recommendedProtocolVersion: ProtocolVersion.wrap(2) - }); + // Define default input variables for testing. + address defaultProxyAdminOwner = makeAddr("defaultProxyAdminOwner"); + address defaultProtocolVersionsOwner = makeAddr("defaultProtocolVersionsOwner"); + address defaultGuardian = makeAddr("defaultGuardian"); + bool defaultPaused = false; + ProtocolVersion defaultRequiredProtocolVersion = ProtocolVersion.wrap(1); + ProtocolVersion defaultRecommendedProtocolVersion = ProtocolVersion.wrap(2); function setUp() public { deploySuperchain = new DeploySuperchain(); - (dsi, dso) = deploySuperchain.getIOContracts(); + (dsi, dso) = deploySuperchain.etchIOContracts(); } function unwrap(ProtocolVersion _pv) internal pure returns (uint256) { return ProtocolVersion.unwrap(_pv); } - function test_run_memory_succeeds(DeploySuperchainInput.Input memory _input) public { - vm.assume(_input.roles.proxyAdminOwner != address(0)); - vm.assume(_input.roles.protocolVersionsOwner != address(0)); - vm.assume(_input.roles.guardian != address(0)); - - DeploySuperchainOutput.Output memory output = deploySuperchain.run(_input); - - // Assert that individual input fields were properly set based on the input struct. - assertEq(_input.roles.proxyAdminOwner, dsi.proxyAdminOwner(), "100"); - assertEq(_input.roles.protocolVersionsOwner, dsi.protocolVersionsOwner(), "200"); - assertEq(_input.roles.guardian, dsi.guardian(), "300"); - assertEq(_input.paused, dsi.paused(), "400"); - assertEq(unwrap(_input.requiredProtocolVersion), unwrap(dsi.requiredProtocolVersion()), "500"); - assertEq(unwrap(_input.recommendedProtocolVersion), unwrap(dsi.recommendedProtocolVersion()), "600"); - - // Assert that individual output fields were properly set based on the output struct. - assertEq(address(output.superchainProxyAdmin), address(dso.superchainProxyAdmin()), "700"); - assertEq(address(output.superchainConfigImpl), address(dso.superchainConfigImpl()), "800"); - assertEq(address(output.superchainConfigProxy), address(dso.superchainConfigProxy()), "900"); - assertEq(address(output.protocolVersionsImpl), address(dso.protocolVersionsImpl()), "1000"); - assertEq(address(output.protocolVersionsProxy), address(dso.protocolVersionsProxy()), "1100"); + function hash(bytes32 _seed, uint256 _i) internal pure returns (bytes32) { + return keccak256(abi.encode(_seed, _i)); + } - // Assert that the full input and output structs were properly set. - assertEq(keccak256(abi.encode(_input)), keccak256(abi.encode(DeploySuperchainInput(dsi).input())), "1200"); - assertEq(keccak256(abi.encode(output)), keccak256(abi.encode(DeploySuperchainOutput(dso).output())), "1300"); + function test_run_memory_succeeds(bytes32 _seed) public { + // Generate random input values from the seed. This doesn't give us the benefit of the forge + // fuzzer's dictionary, but that's ok because we are just testing that values are set and + // passed correctly. + address proxyAdminOwner = address(uint160(uint256(hash(_seed, 0)))); + address protocolVersionsOwner = address(uint160(uint256(hash(_seed, 1)))); + address guardian = address(uint160(uint256(hash(_seed, 2)))); + bool paused = bool(uint8(uint256(hash(_seed, 3))) % 2 == 0); + ProtocolVersion requiredProtocolVersion = ProtocolVersion.wrap(uint256(hash(_seed, 4))); + ProtocolVersion recommendedProtocolVersion = ProtocolVersion.wrap(uint256(hash(_seed, 5))); + + // Set the input values on the input contract. + dsi.set(dsi.proxyAdminOwner.selector, proxyAdminOwner); + dsi.set(dsi.protocolVersionsOwner.selector, protocolVersionsOwner); + dsi.set(dsi.guardian.selector, guardian); + dsi.set(dsi.paused.selector, paused); + dsi.set(dsi.requiredProtocolVersion.selector, requiredProtocolVersion); + dsi.set(dsi.recommendedProtocolVersion.selector, recommendedProtocolVersion); + + // Run the deployment script. + deploySuperchain.run(dsi, dso); // Assert inputs were properly passed through to the contract initializers. - assertEq(address(output.superchainProxyAdmin.owner()), _input.roles.proxyAdminOwner, "1400"); - assertEq(address(output.protocolVersionsProxy.owner()), _input.roles.protocolVersionsOwner, "1500"); - assertEq(address(output.superchainConfigProxy.guardian()), _input.roles.guardian, "1600"); - assertEq(output.superchainConfigProxy.paused(), _input.paused, "1700"); - assertEq(unwrap(output.protocolVersionsProxy.required()), unwrap(_input.requiredProtocolVersion), "1800"); - assertEq(unwrap(output.protocolVersionsProxy.recommended()), unwrap(_input.recommendedProtocolVersion), "1900"); + assertEq(address(dso.superchainProxyAdmin().owner()), proxyAdminOwner, "100"); + assertEq(address(dso.protocolVersionsProxy().owner()), protocolVersionsOwner, "200"); + assertEq(address(dso.superchainConfigProxy().guardian()), guardian, "300"); + assertEq(dso.superchainConfigProxy().paused(), paused, "400"); + assertEq(unwrap(dso.protocolVersionsProxy().required()), unwrap(requiredProtocolVersion), "500"); + assertEq(unwrap(dso.protocolVersionsProxy().recommended()), unwrap(recommendedProtocolVersion), "600"); // Architecture assertions. // We prank as the zero address due to the Proxy's `proxyCallIfNotAdmin` modifier. - Proxy superchainConfigProxy = Proxy(payable(address(output.superchainConfigProxy))); - Proxy protocolVersionsProxy = Proxy(payable(address(output.protocolVersionsProxy))); + Proxy superchainConfigProxy = Proxy(payable(address(dso.superchainConfigProxy()))); + Proxy protocolVersionsProxy = Proxy(payable(address(dso.protocolVersionsProxy()))); vm.startPrank(address(0)); - assertEq(superchainConfigProxy.implementation(), address(output.superchainConfigImpl), "900"); - assertEq(protocolVersionsProxy.implementation(), address(output.protocolVersionsImpl), "1000"); - assertEq(superchainConfigProxy.admin(), protocolVersionsProxy.admin(), "1100"); - assertEq(superchainConfigProxy.admin(), address(output.superchainProxyAdmin), "1200"); + assertEq(superchainConfigProxy.implementation(), address(dso.superchainConfigImpl()), "700"); + assertEq(protocolVersionsProxy.implementation(), address(dso.protocolVersionsImpl()), "800"); + assertEq(superchainConfigProxy.admin(), protocolVersionsProxy.admin(), "900"); + assertEq(superchainConfigProxy.admin(), address(dso.superchainProxyAdmin()), "1000"); vm.stopPrank(); // Ensure that `checkOutput` passes. This is called by the `run` function during execution, @@ -289,28 +262,54 @@ contract DeploySuperchain_Test is Test { string memory actOutToml = vm.readFile(outpath); string memory expOutToml = vm.readFile(string.concat(root, "/test/fixtures/test-deploy-superchain-out.toml")); + // Clean up before asserting so that we don't leave any files behind. vm.removeFile(outpath); assertEq(expOutToml, actOutToml); } - function test_run_ZeroAddressRoleInput_reverts() public { - // Snapshot the state so we can revert to the default `input` struct between assertions. - uint256 snapshotId = vm.snapshot(); - - // Assert over each role being set to the zero address. - input.roles.proxyAdminOwner = address(0); - vm.expectRevert("DeploySuperchainInput: null proxyAdminOwner"); - deploySuperchain.run(input); - - vm.revertTo(snapshotId); - input.roles.protocolVersionsOwner = address(0); - vm.expectRevert("DeploySuperchainInput: null protocolVersionsOwner"); - deploySuperchain.run(input); + function test_run_NullInput_reverts() public { + // Set default values for all inputs. + dsi.set(dsi.proxyAdminOwner.selector, defaultProxyAdminOwner); + dsi.set(dsi.protocolVersionsOwner.selector, defaultProtocolVersionsOwner); + dsi.set(dsi.guardian.selector, defaultGuardian); + dsi.set(dsi.paused.selector, defaultPaused); + dsi.set(dsi.requiredProtocolVersion.selector, defaultRequiredProtocolVersion); + dsi.set(dsi.recommendedProtocolVersion.selector, defaultRecommendedProtocolVersion); + + // Assert over each role being set to the zero address. We aren't allowed to use the setter + // methods to set the zero address, so we use StdStorage. We can't use the `checked_write` + // method, because it does a final call to test that the value was set correctly, but for us + // that would revert. Therefore we use StdStorage to find the slot, then we write to it. + uint256 slot = zeroOutSlotForSelector(dsi.proxyAdminOwner.selector); + vm.expectRevert("DeploySuperchainInput: proxyAdminOwner not set"); + deploySuperchain.run(dsi, dso); + vm.store(address(dsi), bytes32(slot), bytes32(uint256(uint160(defaultProxyAdminOwner)))); // Restore the value + // we just tested. + + slot = zeroOutSlotForSelector(dsi.protocolVersionsOwner.selector); + vm.expectRevert("DeploySuperchainInput: protocolVersionsOwner not set"); + deploySuperchain.run(dsi, dso); + vm.store(address(dsi), bytes32(slot), bytes32(uint256(uint160(defaultProtocolVersionsOwner)))); + + slot = zeroOutSlotForSelector(dsi.guardian.selector); + vm.expectRevert("DeploySuperchainInput: guardian not set"); + deploySuperchain.run(dsi, dso); + vm.store(address(dsi), bytes32(slot), bytes32(uint256(uint160(defaultGuardian)))); + + slot = zeroOutSlotForSelector(dsi.requiredProtocolVersion.selector); + vm.expectRevert("DeploySuperchainInput: requiredProtocolVersion not set"); + deploySuperchain.run(dsi, dso); + vm.store(address(dsi), bytes32(slot), bytes32(unwrap(defaultRequiredProtocolVersion))); + + slot = zeroOutSlotForSelector(dsi.recommendedProtocolVersion.selector); + vm.expectRevert("DeploySuperchainInput: recommendedProtocolVersion not set"); + deploySuperchain.run(dsi, dso); + vm.store(address(dsi), bytes32(slot), bytes32(unwrap(defaultRecommendedProtocolVersion))); + } - vm.revertTo(snapshotId); - input.roles.guardian = address(0); - vm.expectRevert("DeploySuperchainInput: null guardian"); - deploySuperchain.run(input); + function zeroOutSlotForSelector(bytes4 _selector) internal returns (uint256 slot_) { + slot_ = stdstore.enable_packed_slots().target(address(dsi)).sig(_selector).find(); + vm.store(address(dsi), bytes32(slot_), bytes32(0)); } } From de869226098a5aad92e3fffe84140b03cd8836ce Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Wed, 11 Sep 2024 13:37:35 -0400 Subject: [PATCH 093/264] maint: add more L1 interfaces (#11822) Another PR adding contract interfaces. L1 contract interfaces are way more involved than everything else so we're required to start replacing the contracts with interfaces all over the place. --- packages/contracts-bedrock/.gas-snapshot | 16 +- .../invariant-docs/OptimismPortal.md | 8 +- .../invariant-docs/OptimismPortal2.md | 8 +- .../invariant-docs/ResourceMetering.md | 14 +- .../invariant-docs/SystemConfig.md | 2 +- .../contracts-bedrock/scripts/L2Genesis.s.sol | 6 +- .../scripts/checks/check-interfaces.sh | 18 ++- .../scripts/deploy/ChainAssertions.sol | 57 ++++--- .../scripts/deploy/Deploy.s.sol | 153 ++++++++---------- .../scripts/deploy/DeployOwnership.s.sol | 6 +- .../scripts/fpac/FPACOPS.s.sol | 4 +- .../scripts/fpac/FPACOPS2.s.sol | 4 +- .../scripts/interfaces/ISystemConfigV0.sol | 4 +- packages/contracts-bedrock/semver-lock.json | 36 ++--- .../snapshots/abi/AnchorStateRegistry.json | 4 +- .../snapshots/abi/DelayedWETH.json | 4 +- .../snapshots/abi/DeputyGuardianModule.json | 8 +- .../snapshots/abi/L1CrossDomainMessenger.json | 14 +- .../snapshots/abi/L1ERC721Bridge.json | 10 +- .../snapshots/abi/L1StandardBridge.json | 14 +- .../snapshots/abi/L2ERC721Bridge.json | 4 +- .../snapshots/abi/L2StandardBridge.json | 4 +- .../abi/L2StandardBridgeInterop.json | 4 +- .../snapshots/abi/OptimismPortal.json | 8 +- .../snapshots/abi/OptimismPortal2.json | 12 +- .../snapshots/abi/OptimismPortalInterop.json | 17 +- .../snapshots/abi/SystemConfig.json | 4 +- .../snapshots/abi/SystemConfigInterop.json | 6 +- .../storageLayout/AnchorStateRegistry.json | 2 +- .../snapshots/storageLayout/DelayedWETH.json | 2 +- .../storageLayout/L1CrossDomainMessenger.json | 6 +- .../storageLayout/L1ERC721Bridge.json | 4 +- .../storageLayout/L1StandardBridge.json | 6 +- .../storageLayout/L2ERC721Bridge.json | 2 +- .../storageLayout/L2StandardBridge.json | 2 +- .../L2StandardBridgeInterop.json | 2 +- .../storageLayout/OptimismPortal.json | 4 +- .../storageLayout/OptimismPortal2.json | 6 +- .../storageLayout/OptimismPortalInterop.json | 6 +- .../snapshots/storageLayout/SystemConfig.json | 2 +- .../storageLayout/SystemConfigInterop.json | 2 +- .../src/L1/DataAvailabilityChallenge.sol | 7 +- .../src/L1/DelayedVetoable.sol | 1 + .../src/L1/L1CrossDomainMessenger.sol | 33 ++-- .../src/L1/L1ERC721Bridge.sol | 20 ++- .../src/L1/L1StandardBridge.sol | 30 ++-- .../src/L1/OptimismPortal.sol | 48 ++++-- .../src/L1/OptimismPortal2.sol | 54 ++++--- .../src/L1/OptimismPortalInterop.sol | 7 +- .../src/L1/ResourceMetering.sol | 3 + .../contracts-bedrock/src/L1/SystemConfig.sol | 25 +-- .../src/L1/SystemConfigInterop.sol | 21 ++- .../interfaces/IDataAvailabilityChallenge.sol | 92 +++++++++++ .../src/L1/interfaces/IDelayedVetoable.sol | 21 +++ .../L1/interfaces/IL1CrossDomainMessenger.sol | 53 ++++++ .../src/L1/interfaces/IOptimismPortal.sol | 85 ++++++++++ .../src/L1/interfaces/IOptimismPortal2.sol | 116 +++++++++++++ .../L1/interfaces/IOptimismPortalInterop.sol | 118 ++++++++++++++ .../src/L1/interfaces/IResourceMetering.sol | 25 +++ .../src/L1/interfaces/ISuperchainConfig.sol | 22 +++ .../src/L1/interfaces/ISystemConfig.sol | 81 ++++++++++ .../src/L2/L2ERC721Bridge.sol | 4 +- .../src/L2/L2StandardBridge.sol | 4 +- .../src/Safe/DeputyGuardianModule.sol | 31 ++-- .../src/dispute/AnchorStateRegistry.sol | 6 +- .../src/dispute/weth/DelayedWETH.sol | 8 +- .../src/libraries/Constants.sol | 6 +- .../src/universal/ERC721Bridge.sol | 9 +- .../src/universal/StandardBridge.sol | 8 +- .../interfaces/ICrossDomainMessenger.sol | 38 +++++ .../test/BenchmarkTest.t.sol | 11 +- .../test/ExtendedPause.t.sol | 1 - .../test/L1/DataAvailabilityChallenge.t.sol | 44 ++--- .../test/L1/DelayedVetoable.t.sol | 19 ++- .../test/L1/L1CrossDomainMessenger.t.sol | 18 +-- .../test/L1/L1ERC721Bridge.t.sol | 8 +- .../test/L1/L1StandardBridge.t.sol | 68 ++++---- .../test/L1/OptimismPortal.t.sol | 17 +- .../test/L1/OptimismPortal2.t.sol | 15 +- .../test/L1/OptimismPortalInterop.t.sol | 8 +- .../test/L1/ResourceMetering.t.sol | 21 ++- .../test/L1/SuperchainConfig.t.sol | 9 +- .../test/L1/SystemConfig.t.sol | 44 ++--- .../test/L1/SystemConfigInterop.t.sol | 13 +- .../test/L2/L2CrossDomainMessenger.t.sol | 1 - .../test/L2/L2StandardBridge.t.sol | 26 +-- .../test/Safe/DeployOwnership.t.sol | 1 - .../test/Safe/DeputyGuardianModule.t.sol | 8 +- packages/contracts-bedrock/test/Specs.t.sol | 100 +++++++----- .../invariants/CrossDomainMessenger.t.sol | 10 +- .../test/invariants/OptimismPortal.t.sol | 15 +- .../test/invariants/OptimismPortal2.t.sol | 16 +- .../test/invariants/ResourceMetering.t.sol | 9 +- .../test/invariants/SystemConfig.t.sol | 9 +- .../contracts-bedrock/test/setup/Setup.sol | 69 ++++---- .../test/universal/CrossDomainMessenger.t.sol | 6 +- .../test/vendor/Initializable.t.sol | 42 +++-- 97 files changed, 1438 insertions(+), 641 deletions(-) create mode 100644 packages/contracts-bedrock/src/L1/interfaces/IDataAvailabilityChallenge.sol create mode 100644 packages/contracts-bedrock/src/L1/interfaces/IDelayedVetoable.sol create mode 100644 packages/contracts-bedrock/src/L1/interfaces/IL1CrossDomainMessenger.sol create mode 100644 packages/contracts-bedrock/src/L1/interfaces/IOptimismPortal.sol create mode 100644 packages/contracts-bedrock/src/L1/interfaces/IOptimismPortal2.sol create mode 100644 packages/contracts-bedrock/src/L1/interfaces/IOptimismPortalInterop.sol create mode 100644 packages/contracts-bedrock/src/L1/interfaces/IResourceMetering.sol create mode 100644 packages/contracts-bedrock/src/L1/interfaces/ISuperchainConfig.sol create mode 100644 packages/contracts-bedrock/src/L1/interfaces/ISystemConfig.sol create mode 100644 packages/contracts-bedrock/src/universal/interfaces/ICrossDomainMessenger.sol diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index b28d6b6c9cad..af4acca99719 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -4,14 +4,14 @@ GasBenchMark_L1BlockIsthmus_SetValuesIsthmus:test_setL1BlockValuesIsthmus_benchm GasBenchMark_L1BlockIsthmus_SetValuesIsthmus_Warm:test_setL1BlockValuesIsthmus_benchmark() (gas: 5121) GasBenchMark_L1Block_SetValuesEcotone:test_setL1BlockValuesEcotone_benchmark() (gas: 158531) GasBenchMark_L1Block_SetValuesEcotone_Warm:test_setL1BlockValuesEcotone_benchmark() (gas: 7597) -GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 369356) -GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2967496) -GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 564483) -GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4076526) -GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 466947) -GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3512629) +GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 369242) +GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2967382) +GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 564365) +GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4076580) +GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 467007) +GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3512689) GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 72624) GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 92973) -GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68433) -GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68903) +GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68320) +GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68962) GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 155618) \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/OptimismPortal.md b/packages/contracts-bedrock/invariant-docs/OptimismPortal.md index c13d0212128d..b1b2c38cb278 100644 --- a/packages/contracts-bedrock/invariant-docs/OptimismPortal.md +++ b/packages/contracts-bedrock/invariant-docs/OptimismPortal.md @@ -1,21 +1,21 @@ # `OptimismPortal` Invariants ## Deposits of any value should always succeed unless `_to` = `address(0)` or `_isCreation` = `true`. -**Test:** [`OptimismPortal.t.sol#L148`](../test/invariants/OptimismPortal.t.sol#L148) +**Test:** [`OptimismPortal.t.sol#L151`](../test/invariants/OptimismPortal.t.sol#L151) All deposits, barring creation transactions and transactions sent to `address(0)`, should always succeed. ## `finalizeWithdrawalTransaction` should revert if the finalization period has not elapsed. -**Test:** [`OptimismPortal.t.sol#L171`](../test/invariants/OptimismPortal.t.sol#L171) +**Test:** [`OptimismPortal.t.sol#L174`](../test/invariants/OptimismPortal.t.sol#L174) A withdrawal that has been proven should not be able to be finalized until after the finalization period has elapsed. ## `finalizeWithdrawalTransaction` should revert if the withdrawal has already been finalized. -**Test:** [`OptimismPortal.t.sol#L201`](../test/invariants/OptimismPortal.t.sol#L201) +**Test:** [`OptimismPortal.t.sol#L204`](../test/invariants/OptimismPortal.t.sol#L204) Ensures that there is no chain of calls that can be made that allows a withdrawal to be finalized twice. ## A withdrawal should **always** be able to be finalized `FINALIZATION_PERIOD_SECONDS` after it was successfully proven. -**Test:** [`OptimismPortal.t.sol#L230`](../test/invariants/OptimismPortal.t.sol#L230) +**Test:** [`OptimismPortal.t.sol#L233`](../test/invariants/OptimismPortal.t.sol#L233) This invariant asserts that there is no chain of calls that can be made that will prevent a withdrawal from being finalized exactly `FINALIZATION_PERIOD_SECONDS` after it was successfully proven. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/OptimismPortal2.md b/packages/contracts-bedrock/invariant-docs/OptimismPortal2.md index c9a00ec0941e..b3c1eb0d4576 100644 --- a/packages/contracts-bedrock/invariant-docs/OptimismPortal2.md +++ b/packages/contracts-bedrock/invariant-docs/OptimismPortal2.md @@ -1,21 +1,21 @@ # `OptimismPortal2` Invariants ## Deposits of any value should always succeed unless `_to` = `address(0)` or `_isCreation` = `true`. -**Test:** [`OptimismPortal2.t.sol#L161`](../test/invariants/OptimismPortal2.t.sol#L161) +**Test:** [`OptimismPortal2.t.sol#L163`](../test/invariants/OptimismPortal2.t.sol#L163) All deposits, barring creation transactions and transactions sent to `address(0)`, should always succeed. ## `finalizeWithdrawalTransaction` should revert if the proof maturity period has not elapsed. -**Test:** [`OptimismPortal2.t.sol#L183`](../test/invariants/OptimismPortal2.t.sol#L183) +**Test:** [`OptimismPortal2.t.sol#L185`](../test/invariants/OptimismPortal2.t.sol#L185) A withdrawal that has been proven should not be able to be finalized until after the proof maturity period has elapsed. ## `finalizeWithdrawalTransaction` should revert if the withdrawal has already been finalized. -**Test:** [`OptimismPortal2.t.sol#L212`](../test/invariants/OptimismPortal2.t.sol#L212) +**Test:** [`OptimismPortal2.t.sol#L214`](../test/invariants/OptimismPortal2.t.sol#L214) Ensures that there is no chain of calls that can be made that allows a withdrawal to be finalized twice. ## A withdrawal should **always** be able to be finalized `PROOF_MATURITY_DELAY_SECONDS` after it was successfully proven, if the game has resolved and passed the air-gap. -**Test:** [`OptimismPortal2.t.sol#L240`](../test/invariants/OptimismPortal2.t.sol#L240) +**Test:** [`OptimismPortal2.t.sol#L242`](../test/invariants/OptimismPortal2.t.sol#L242) This invariant asserts that there is no chain of calls that can be made that will prevent a withdrawal from being finalized exactly `PROOF_MATURITY_DELAY_SECONDS` after it was successfully proven and the game has resolved and passed the air-gap. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/ResourceMetering.md b/packages/contracts-bedrock/invariant-docs/ResourceMetering.md index 967c24bf886f..2f97937d2b84 100644 --- a/packages/contracts-bedrock/invariant-docs/ResourceMetering.md +++ b/packages/contracts-bedrock/invariant-docs/ResourceMetering.md @@ -1,36 +1,36 @@ # `ResourceMetering` Invariants ## The base fee should increase if the last block used more than the target amount of gas. -**Test:** [`ResourceMetering.t.sol#L163`](../test/invariants/ResourceMetering.t.sol#L163) +**Test:** [`ResourceMetering.t.sol#L166`](../test/invariants/ResourceMetering.t.sol#L166) If the last block used more than the target amount of gas (and there were no empty blocks in between), ensure this block's baseFee increased, but not by more than the max amount per block. ## The base fee should decrease if the last block used less than the target amount of gas. -**Test:** [`ResourceMetering.t.sol#L172`](../test/invariants/ResourceMetering.t.sol#L172) +**Test:** [`ResourceMetering.t.sol#L175`](../test/invariants/ResourceMetering.t.sol#L175) If the previous block used less than the target amount of gas, the base fee should decrease, but not more than the max amount. ## A block's base fee should never be below `MINIMUM_BASE_FEE`. -**Test:** [`ResourceMetering.t.sol#L180`](../test/invariants/ResourceMetering.t.sol#L180) +**Test:** [`ResourceMetering.t.sol#L183`](../test/invariants/ResourceMetering.t.sol#L183) This test asserts that a block's base fee can never drop below the `MINIMUM_BASE_FEE` threshold. ## A block can never consume more than `MAX_RESOURCE_LIMIT` gas. -**Test:** [`ResourceMetering.t.sol#L188`](../test/invariants/ResourceMetering.t.sol#L188) +**Test:** [`ResourceMetering.t.sol#L191`](../test/invariants/ResourceMetering.t.sol#L191) This test asserts that a block can never consume more than the `MAX_RESOURCE_LIMIT` gas threshold. ## The base fee can never be raised more than the max base fee change. -**Test:** [`ResourceMetering.t.sol#L198`](../test/invariants/ResourceMetering.t.sol#L198) +**Test:** [`ResourceMetering.t.sol#L201`](../test/invariants/ResourceMetering.t.sol#L201) After a block consumes more gas than the target gas, the base fee cannot be raised more than the maximum amount allowed. The max base fee change (per-block) is derived as follows: `prevBaseFee / BASE_FEE_MAX_CHANGE_DENOMINATOR` ## The base fee can never be lowered more than the max base fee change. -**Test:** [`ResourceMetering.t.sol#L208`](../test/invariants/ResourceMetering.t.sol#L208) +**Test:** [`ResourceMetering.t.sol#L211`](../test/invariants/ResourceMetering.t.sol#L211) After a block consumes less than the target gas, the base fee cannot be lowered more than the maximum amount allowed. The max base fee change (per-block) is derived as follows: `prevBaseFee / BASE_FEE_MAX_CHANGE_DENOMINATOR` ## The `maxBaseFeeChange` calculation over multiple blocks can never underflow. -**Test:** [`ResourceMetering.t.sol#L217`](../test/invariants/ResourceMetering.t.sol#L217) +**Test:** [`ResourceMetering.t.sol#L220`](../test/invariants/ResourceMetering.t.sol#L220) When calculating the `maxBaseFeeChange` after multiple empty blocks, the calculation should never be allowed to underflow. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/SystemConfig.md b/packages/contracts-bedrock/invariant-docs/SystemConfig.md index 59f9a999f10c..b3d711972f6b 100644 --- a/packages/contracts-bedrock/invariant-docs/SystemConfig.md +++ b/packages/contracts-bedrock/invariant-docs/SystemConfig.md @@ -1,6 +1,6 @@ # `SystemConfig` Invariants ## Gas limit boundaries -**Test:** [`SystemConfig.t.sol#L70`](../test/invariants/SystemConfig.t.sol#L70) +**Test:** [`SystemConfig.t.sol#L71`](../test/invariants/SystemConfig.t.sol#L71) The gas limit of the `SystemConfig` contract can never be lower than the hard-coded lower bound or higher than the hard-coded upper bound. The lower bound must never be higher than the upper bound. \ No newline at end of file diff --git a/packages/contracts-bedrock/scripts/L2Genesis.s.sol b/packages/contracts-bedrock/scripts/L2Genesis.s.sol index eb2f8d396365..e6040f4eec2f 100644 --- a/packages/contracts-bedrock/scripts/L2Genesis.s.sol +++ b/packages/contracts-bedrock/scripts/L2Genesis.s.sol @@ -21,7 +21,7 @@ import { OptimismMintableERC721Factory } from "src/universal/OptimismMintableERC import { BaseFeeVault } from "src/L2/BaseFeeVault.sol"; import { L1FeeVault } from "src/L2/L1FeeVault.sol"; import { GovernanceToken } from "src/governance/GovernanceToken.sol"; -import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; +import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { FeeVault } from "src/universal/FeeVault.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; @@ -277,10 +277,10 @@ contract L2Genesis is Deployer { function setL2CrossDomainMessenger(address payable _l1CrossDomainMessengerProxy) public { address impl = _setImplementationCode(Predeploys.L2_CROSS_DOMAIN_MESSENGER); - L2CrossDomainMessenger(impl).initialize({ _l1CrossDomainMessenger: L1CrossDomainMessenger(address(0)) }); + L2CrossDomainMessenger(impl).initialize({ _l1CrossDomainMessenger: CrossDomainMessenger(address(0)) }); L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER).initialize({ - _l1CrossDomainMessenger: L1CrossDomainMessenger(_l1CrossDomainMessengerProxy) + _l1CrossDomainMessenger: CrossDomainMessenger(_l1CrossDomainMessengerProxy) }); } diff --git a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh index 827ae5ee4452..89a62e3c4ce0 100755 --- a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh +++ b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh @@ -180,8 +180,24 @@ for interface_file in $JSON_FILES; do interface_abi=$(jq '[.abi[] | select(.type != "constructor")]' < "$interface_file") contract_abi=$(jq '[.abi[] | select(.type != "constructor")]' < "$corresponding_contract_file") + # Function to normalize ABI by replacing interface name with contract name. + # Base contracts aren't allowed to inherit from their interfaces in order + # to guarantee a 1:1 match between interfaces and contracts. This means + # that the interface will redefine types in the base contract. We normalize + # the ABI as if the interface and contract are the same name + normalize_abi() { + local abi="$1" + local interface_name="$2" + local contract_name="$3" + echo "${abi//$interface_name/$contract_name}" + } + + # Normalize the ABIs + normalized_interface_abi=$(normalize_abi "$interface_abi" "$contract_name" "$contract_basename") + normalized_contract_abi="$contract_abi" + # Use jq to compare the ABIs - if ! diff_result=$(diff -u <(echo "$interface_abi" | jq -S .) <(echo "$contract_abi" | jq -S .)); then + if ! diff_result=$(diff -u <(echo "$normalized_interface_abi" | jq -S .) <(echo "$normalized_contract_abi" | jq -S .)); then if ! grep -q "^$contract_name$" "$REPORTED_INTERFACES_FILE"; then echo "$contract_name" >> "$REPORTED_INTERFACES_FILE" if ! is_excluded "$contract_name"; then diff --git a/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol b/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol index ce10bb0993f7..0ebb848f23a3 100644 --- a/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol +++ b/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol @@ -1,28 +1,37 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; -import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +// Testing +import { Vm } from "forge-std/Vm.sol"; +import { console2 as console } from "forge-std/console2.sol"; + +// Scripts import { DeployConfig } from "scripts/deploy/DeployConfig.s.sol"; import { Deployer } from "scripts/deploy/Deployer.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; -import { Constants } from "src/libraries/Constants.sol"; + +// Contracts +import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; -import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; import { ProtocolVersion, ProtocolVersions } from "src/L1/ProtocolVersions.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; -import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; -import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; + +// Libraries +import { Constants } from "src/libraries/Constants.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { Types } from "scripts/libraries/Types.sol"; -import { Vm } from "forge-std/Vm.sol"; + +// Interfaces +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; +import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; +import { IL1CrossDomainMessenger } from "src/L1/interfaces/IL1CrossDomainMessenger.sol"; +import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; +import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; import { ISystemConfigV0 } from "scripts/interfaces/ISystemConfigV0.sol"; -import { console2 as console } from "forge-std/console2.sol"; library ChainAssertions { Vm internal constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); @@ -39,8 +48,8 @@ library ChainAssertions { view { console.log("Running post-deploy assertions"); - ResourceMetering.ResourceConfig memory rcfg = SystemConfig(_prox.SystemConfig).resourceConfig(); - ResourceMetering.ResourceConfig memory dflt = Constants.DEFAULT_RESOURCE_CONFIG(); + IResourceMetering.ResourceConfig memory rcfg = ISystemConfig(_prox.SystemConfig).resourceConfig(); + IResourceMetering.ResourceConfig memory dflt = Constants.DEFAULT_RESOURCE_CONFIG(); require(keccak256(abi.encode(rcfg)) == keccak256(abi.encode(dflt))); checkSystemConfig({ _contracts: _prox, _cfg: _cfg, _isProxy: true }); @@ -62,12 +71,12 @@ library ChainAssertions { /// @notice Asserts that the SystemConfig is setup correctly function checkSystemConfig(Types.ContractSet memory _contracts, DeployConfig _cfg, bool _isProxy) internal view { console.log("Running chain assertions on the SystemConfig"); - SystemConfig config = SystemConfig(_contracts.SystemConfig); + ISystemConfig config = ISystemConfig(_contracts.SystemConfig); // Check that the contract is initialized assertSlotValueIsOne({ _contractAddress: address(config), _slot: 0, _offset: 0 }); - ResourceMetering.ResourceConfig memory resourceConfig = config.resourceConfig(); + IResourceMetering.ResourceConfig memory resourceConfig = config.resourceConfig(); if (_isProxy) { require(config.owner() == _cfg.finalSystemOwner()); @@ -78,7 +87,7 @@ library ChainAssertions { require(config.unsafeBlockSigner() == _cfg.p2pSequencerAddress()); require(config.scalar() >> 248 == 1); // Check _config - ResourceMetering.ResourceConfig memory rconfig = Constants.DEFAULT_RESOURCE_CONFIG(); + IResourceMetering.ResourceConfig memory rconfig = Constants.DEFAULT_RESOURCE_CONFIG(); require(resourceConfig.maxResourceLimit == rconfig.maxResourceLimit); require(resourceConfig.elasticityMultiplier == rconfig.elasticityMultiplier); require(resourceConfig.baseFeeMaxChangeDenominator == rconfig.baseFeeMaxChangeDenominator); @@ -127,7 +136,7 @@ library ChainAssertions { /// @notice Asserts that the L1CrossDomainMessenger is setup correctly function checkL1CrossDomainMessenger(Types.ContractSet memory _contracts, Vm _vm, bool _isProxy) internal view { console.log("Running chain assertions on the L1CrossDomainMessenger"); - L1CrossDomainMessenger messenger = L1CrossDomainMessenger(_contracts.L1CrossDomainMessenger); + IL1CrossDomainMessenger messenger = IL1CrossDomainMessenger(_contracts.L1CrossDomainMessenger); // Check that the contract is initialized assertSlotValueIsOne({ _contractAddress: address(messenger), _slot: 0, _offset: 20 }); @@ -201,7 +210,7 @@ library ChainAssertions { if (_isProxy) { require(weth.owner() == _expectedOwner); require(weth.delay() == _cfg.faultGameWithdrawalDelay()); - require(weth.config() == SuperchainConfig(_contracts.SuperchainConfig)); + require(weth.config() == ISuperchainConfig(_contracts.SuperchainConfig)); } else { require(weth.owner() == _expectedOwner); require(weth.delay() == _cfg.faultGameWithdrawalDelay()); @@ -227,7 +236,7 @@ library ChainAssertions { if (_isProxy) { require(weth.owner() == _expectedOwner); require(weth.delay() == _cfg.faultGameWithdrawalDelay()); - require(weth.config() == SuperchainConfig(_contracts.SuperchainConfig)); + require(weth.config() == ISuperchainConfig(_contracts.SuperchainConfig)); } else { require(weth.owner() == _expectedOwner); require(weth.delay() == _cfg.faultGameWithdrawalDelay()); @@ -322,7 +331,7 @@ library ChainAssertions { function checkOptimismPortal(Types.ContractSet memory _contracts, DeployConfig _cfg, bool _isProxy) internal view { console.log("Running chain assertions on the OptimismPortal"); - OptimismPortal portal = OptimismPortal(payable(_contracts.OptimismPortal)); + IOptimismPortal portal = IOptimismPortal(payable(_contracts.OptimismPortal)); // Check that the contract is initialized assertSlotValueIsOne({ _contractAddress: address(portal), _slot: 0, _offset: 0 }); @@ -337,7 +346,7 @@ library ChainAssertions { require(address(portal.systemConfig()) == _contracts.SystemConfig); require(portal.guardian() == guardian); require(address(portal.superchainConfig()) == address(_contracts.SuperchainConfig)); - require(portal.paused() == SuperchainConfig(_contracts.SuperchainConfig).paused()); + require(portal.paused() == ISuperchainConfig(_contracts.SuperchainConfig).paused()); require(portal.l2Sender() == Constants.DEFAULT_L2_SENDER); } else { require(address(portal.l2Oracle()) == address(0)); @@ -358,7 +367,7 @@ library ChainAssertions { { console.log("Running chain assertions on the OptimismPortal2"); - OptimismPortal2 portal = OptimismPortal2(payable(_contracts.OptimismPortal2)); + IOptimismPortal2 portal = IOptimismPortal2(payable(_contracts.OptimismPortal2)); // Check that the contract is initialized assertSlotValueIsOne({ _contractAddress: address(portal), _slot: 0, _offset: 0 }); @@ -373,7 +382,7 @@ library ChainAssertions { require(address(portal.systemConfig()) == _contracts.SystemConfig); require(portal.guardian() == guardian); require(address(portal.superchainConfig()) == address(_contracts.SuperchainConfig)); - require(portal.paused() == SuperchainConfig(_contracts.SuperchainConfig).paused()); + require(portal.paused() == ISuperchainConfig(_contracts.SuperchainConfig).paused()); require(portal.l2Sender() == Constants.DEFAULT_L2_SENDER); } else { require(address(portal.disputeGameFactory()) == address(0)); @@ -422,7 +431,7 @@ library ChainAssertions { view { console.log("Running chain assertions on the SuperchainConfig"); - SuperchainConfig superchainConfig = SuperchainConfig(_contracts.SuperchainConfig); + ISuperchainConfig superchainConfig = ISuperchainConfig(_contracts.SuperchainConfig); // Check that the contract is initialized assertSlotValueIsOne({ _contractAddress: address(superchainConfig), _slot: 0, _offset: 0 }); diff --git a/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol b/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol index 659eb2b338dd..71828ebc3ba1 100644 --- a/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol @@ -1,38 +1,39 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +// Testing import { VmSafe } from "forge-std/Vm.sol"; import { Script } from "forge-std/Script.sol"; - import { console2 as console } from "forge-std/console2.sol"; import { stdJson } from "forge-std/StdJson.sol"; +import { AlphabetVM } from "test/mocks/AlphabetVM.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; +// Safe import { GnosisSafe as Safe } from "safe-contracts/GnosisSafe.sol"; import { OwnerManager } from "safe-contracts/base/OwnerManager.sol"; import { GnosisSafeProxyFactory as SafeProxyFactory } from "safe-contracts/proxies/GnosisSafeProxyFactory.sol"; import { Enum as SafeOps } from "safe-contracts/common/Enum.sol"; +// Scripts import { Deployer } from "scripts/deploy/Deployer.sol"; +import { Chains } from "scripts/libraries/Chains.sol"; +import { Config } from "scripts/libraries/Config.sol"; +import { LibStateDiff } from "scripts/libraries/LibStateDiff.sol"; +import { Process } from "scripts/libraries/Process.sol"; +import { ForgeArtifacts } from "scripts/libraries/ForgeArtifacts.sol"; +import { ChainAssertions } from "scripts/deploy/ChainAssertions.sol"; +// Contracts import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { AddressManager } from "src/legacy/AddressManager.sol"; import { Proxy } from "src/universal/Proxy.sol"; import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol"; -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; -import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; -import { OptimismPortalInterop } from "src/L1/OptimismPortalInterop.sol"; import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol"; import { ResolvedDelegateProxy } from "src/legacy/ResolvedDelegateProxy.sol"; -import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; -import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; import { SystemConfigInterop } from "src/L1/SystemConfigInterop.sol"; -import { ResourceMetering } from "src/L1/ResourceMetering.sol"; -import { DataAvailabilityChallenge } from "src/L1/DataAvailabilityChallenge.sol"; -import { Constants } from "src/libraries/Constants.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; @@ -43,20 +44,25 @@ import { MIPS } from "src/cannon/MIPS.sol"; import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; import { ProtocolVersions, ProtocolVersion } from "src/L1/ProtocolVersions.sol"; import { StorageSetter } from "src/universal/StorageSetter.sol"; + +// Libraries +import { Constants } from "src/libraries/Constants.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; -import { Chains } from "scripts/libraries/Chains.sol"; -import { Config } from "scripts/libraries/Config.sol"; +import { Types } from "scripts/libraries/Types.sol"; +import "src/dispute/lib/Types.sol"; +// Interfaces +import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; +import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; +import { IOptimismPortalInterop } from "src/L1/interfaces/IOptimismPortalInterop.sol"; +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; +import { IL1CrossDomainMessenger } from "src/L1/interfaces/IL1CrossDomainMessenger.sol"; +import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; +import { IDataAvailabilityChallenge } from "src/L1/interfaces/IDataAvailabilityChallenge.sol"; import { IBigStepper } from "src/dispute/interfaces/IBigStepper.sol"; import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol"; -import { AlphabetVM } from "test/mocks/AlphabetVM.sol"; -import "src/dispute/lib/Types.sol"; -import { ChainAssertions } from "scripts/deploy/ChainAssertions.sol"; -import { Types } from "scripts/libraries/Types.sol"; -import { LibStateDiff } from "scripts/libraries/LibStateDiff.sol"; -import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; -import { ForgeArtifacts } from "scripts/libraries/ForgeArtifacts.sol"; -import { Process } from "scripts/libraries/Process.sol"; /// @title Deploy /// @notice Script used to deploy a bedrock system. The entire system is deployed within the `run` function. @@ -613,23 +619,16 @@ contract Deploy is Deployer { /// @notice Deploy the SuperchainConfig contract function deploySuperchainConfig() public broadcast { - SuperchainConfig superchainConfig = new SuperchainConfig{ salt: _implSalt() }(); + ISuperchainConfig superchainConfig = ISuperchainConfig(_deploy("SuperchainConfig", hex"")); require(superchainConfig.guardian() == address(0)); bytes32 initialized = vm.load(address(superchainConfig), bytes32(0)); require(initialized != 0); - - save("SuperchainConfig", address(superchainConfig)); - console.log("SuperchainConfig deployed at %s", address(superchainConfig)); } /// @notice Deploy the L1CrossDomainMessenger function deployL1CrossDomainMessenger() public broadcast returns (address addr_) { - console.log("Deploying L1CrossDomainMessenger implementation"); - L1CrossDomainMessenger messenger = new L1CrossDomainMessenger{ salt: _implSalt() }(); - - save("L1CrossDomainMessenger", address(messenger)); - console.log("L1CrossDomainMessenger deployed at %s", address(messenger)); + IL1CrossDomainMessenger messenger = IL1CrossDomainMessenger(_deploy("L1CrossDomainMessenger", hex"")); // Override the `L1CrossDomainMessenger` contract to the deployed implementation. This is necessary // to check the `L1CrossDomainMessenger` implementation alongside dependent contracts, which @@ -643,13 +642,11 @@ contract Deploy is Deployer { /// @notice Deploy the OptimismPortal function deployOptimismPortal() public broadcast returns (address addr_) { - console.log("Deploying OptimismPortal implementation"); if (cfg.useInterop()) { console.log("Attempting to deploy OptimismPortal with interop, this config is a noop"); } - addr_ = address(new OptimismPortal{ salt: _implSalt() }()); - save("OptimismPortal", addr_); - console.log("OptimismPortal deployed at %s", addr_); + + addr_ = _deploy("OptimismPortal", hex""); // Override the `OptimismPortal` contract to the deployed implementation. This is necessary // to check the `OptimismPortal` implementation alongside dependent contracts, which @@ -661,32 +658,23 @@ contract Deploy is Deployer { /// @notice Deploy the OptimismPortal2 function deployOptimismPortal2() public broadcast returns (address addr_) { - console.log("Deploying OptimismPortal2 implementation"); - // Could also verify this inside DeployConfig but doing it here is a bit more reliable. require( uint32(cfg.respectedGameType()) == cfg.respectedGameType(), "Deploy: respectedGameType must fit into uint32" ); if (cfg.useInterop()) { - addr_ = address( - new OptimismPortalInterop{ salt: _implSalt() }({ - _proofMaturityDelaySeconds: cfg.proofMaturityDelaySeconds(), - _disputeGameFinalityDelaySeconds: cfg.disputeGameFinalityDelaySeconds() - }) + addr_ = _deploy( + "OptimismPortalInterop", + abi.encode(cfg.proofMaturityDelaySeconds(), cfg.disputeGameFinalityDelaySeconds()) ); + save("OptimismPortal2", addr_); } else { - addr_ = address( - new OptimismPortal2{ salt: _implSalt() }({ - _proofMaturityDelaySeconds: cfg.proofMaturityDelaySeconds(), - _disputeGameFinalityDelaySeconds: cfg.disputeGameFinalityDelaySeconds() - }) + addr_ = _deploy( + "OptimismPortal2", abi.encode(cfg.proofMaturityDelaySeconds(), cfg.disputeGameFinalityDelaySeconds()) ); } - save("OptimismPortal2", addr_); - console.log("OptimismPortal2 deployed at %s", addr_); - // Override the `OptimismPortal2` contract to the deployed implementation. This is necessary // to check the `OptimismPortal2` implementation alongside dependent contracts, which // are always proxies. @@ -822,14 +810,12 @@ contract Deploy is Deployer { /// @notice Deploy the SystemConfig function deploySystemConfig() public broadcast returns (address addr_) { - console.log("Deploying SystemConfig implementation"); if (cfg.useInterop()) { - addr_ = address(new SystemConfigInterop{ salt: _implSalt() }()); + addr_ = _deploy("SystemConfigInterop", hex""); + save("SystemConfig", addr_); } else { - addr_ = address(new SystemConfig{ salt: _implSalt() }()); + addr_ = _deploy("SystemConfig", hex""); } - save("SystemConfig", addr_); - console.log("SystemConfig deployed at %s", addr_); // Override the `SystemConfig` contract to the deployed implementation. This is necessary // to check the `SystemConfig` implementation alongside dependent contracts, which @@ -893,11 +879,8 @@ contract Deploy is Deployer { /// @notice Deploy the DataAvailabilityChallenge function deployDataAvailabilityChallenge() public broadcast returns (address addr_) { - console.log("Deploying DataAvailabilityChallenge implementation"); - DataAvailabilityChallenge dac = new DataAvailabilityChallenge(); - save("DataAvailabilityChallenge", address(dac)); - console.log("DataAvailabilityChallenge deployed at %s", address(dac)); - + IDataAvailabilityChallenge dac = + IDataAvailabilityChallenge(payable(_deploy("DataAvailabilityChallenge", hex""))); addr_ = address(dac); } @@ -912,7 +895,7 @@ contract Deploy is Deployer { _upgradeAndCallViaSafe({ _proxy: superchainConfigProxy, _implementation: superchainConfig, - _innerCallData: abi.encodeCall(SuperchainConfig.initialize, (cfg.superchainConfigGuardian(), false)) + _innerCallData: abi.encodeCall(ISuperchainConfig.initialize, (cfg.superchainConfigGuardian(), false)) }); ChainAssertions.checkSuperchainConfig({ _contracts: _proxiesUnstrict(), _cfg: cfg, _isPaused: false }); @@ -945,7 +928,7 @@ contract Deploy is Deployer { _upgradeAndCallViaSafe({ _proxy: payable(delayedWETHProxy), _implementation: delayedWETH, - _innerCallData: abi.encodeCall(DelayedWETH.initialize, (msg.sender, SuperchainConfig(superchainConfigProxy))) + _innerCallData: abi.encodeCall(DelayedWETH.initialize, (msg.sender, ISuperchainConfig(superchainConfigProxy))) }); string memory version = DelayedWETH(payable(delayedWETHProxy)).version(); @@ -968,7 +951,7 @@ contract Deploy is Deployer { _upgradeAndCallViaSafe({ _proxy: payable(delayedWETHProxy), _implementation: delayedWETH, - _innerCallData: abi.encodeCall(DelayedWETH.initialize, (msg.sender, SuperchainConfig(superchainConfigProxy))) + _innerCallData: abi.encodeCall(DelayedWETH.initialize, (msg.sender, ISuperchainConfig(superchainConfigProxy))) }); string memory version = DelayedWETH(payable(delayedWETHProxy)).version(); @@ -986,7 +969,7 @@ contract Deploy is Deployer { console.log("Upgrading and initializing AnchorStateRegistry proxy"); address anchorStateRegistryProxy = mustGetAddress("AnchorStateRegistryProxy"); address anchorStateRegistry = mustGetAddress("AnchorStateRegistry"); - SuperchainConfig superchainConfig = SuperchainConfig(mustGetAddress("SuperchainConfigProxy")); + ISuperchainConfig superchainConfig = ISuperchainConfig(mustGetAddress("SuperchainConfigProxy")); AnchorStateRegistry.StartingAnchorRoot[] memory roots = new AnchorStateRegistry.StartingAnchorRoot[](5); roots[0] = AnchorStateRegistry.StartingAnchorRoot({ @@ -1052,7 +1035,7 @@ contract Deploy is Deployer { _proxy: payable(systemConfigProxy), _implementation: systemConfig, _innerCallData: abi.encodeCall( - SystemConfig.initialize, + ISystemConfig.initialize, ( cfg.finalSystemOwner(), cfg.basefeeScalar(), @@ -1062,7 +1045,7 @@ contract Deploy is Deployer { cfg.p2pSequencerAddress(), Constants.DEFAULT_RESOURCE_CONFIG(), cfg.batchInboxAddress(), - SystemConfig.Addresses({ + ISystemConfig.Addresses({ l1CrossDomainMessenger: mustGetAddress("L1CrossDomainMessengerProxy"), l1ERC721Bridge: mustGetAddress("L1ERC721BridgeProxy"), l1StandardBridge: mustGetAddress("L1StandardBridgeProxy"), @@ -1075,7 +1058,7 @@ contract Deploy is Deployer { ) }); - SystemConfig config = SystemConfig(systemConfigProxy); + ISystemConfig config = ISystemConfig(systemConfigProxy); string memory version = config.version(); console.log("SystemConfig version: %s", version); @@ -1109,9 +1092,9 @@ contract Deploy is Deployer { _innerCallData: abi.encodeCall( L1StandardBridge.initialize, ( - L1CrossDomainMessenger(l1CrossDomainMessengerProxy), - SuperchainConfig(superchainConfigProxy), - SystemConfig(systemConfigProxy) + ICrossDomainMessenger(l1CrossDomainMessengerProxy), + ISuperchainConfig(superchainConfigProxy), + ISystemConfig(systemConfigProxy) ) ) }); @@ -1135,7 +1118,7 @@ contract Deploy is Deployer { _implementation: l1ERC721Bridge, _innerCallData: abi.encodeCall( L1ERC721Bridge.initialize, - (L1CrossDomainMessenger(payable(l1CrossDomainMessengerProxy)), SuperchainConfig(superchainConfigProxy)) + (ICrossDomainMessenger(payable(l1CrossDomainMessengerProxy)), ISuperchainConfig(superchainConfigProxy)) ) }); @@ -1205,16 +1188,16 @@ contract Deploy is Deployer { _proxy: payable(l1CrossDomainMessengerProxy), _implementation: l1CrossDomainMessenger, _innerCallData: abi.encodeCall( - L1CrossDomainMessenger.initialize, + IL1CrossDomainMessenger.initialize, ( - SuperchainConfig(superchainConfigProxy), - OptimismPortal(payable(optimismPortalProxy)), - SystemConfig(systemConfigProxy) + ISuperchainConfig(superchainConfigProxy), + IOptimismPortal(payable(optimismPortalProxy)), + ISystemConfig(systemConfigProxy) ) ) }); - L1CrossDomainMessenger messenger = L1CrossDomainMessenger(l1CrossDomainMessengerProxy); + IL1CrossDomainMessenger messenger = IL1CrossDomainMessenger(l1CrossDomainMessengerProxy); string memory version = messenger.version(); console.log("L1CrossDomainMessenger version: %s", version); @@ -1269,16 +1252,16 @@ contract Deploy is Deployer { _proxy: payable(optimismPortalProxy), _implementation: optimismPortal, _innerCallData: abi.encodeCall( - OptimismPortal.initialize, + IOptimismPortal.initialize, ( IL2OutputOracle(l2OutputOracleProxy), - SystemConfig(systemConfigProxy), - SuperchainConfig(superchainConfigProxy) + ISystemConfig(systemConfigProxy), + ISuperchainConfig(superchainConfigProxy) ) ) }); - OptimismPortal portal = OptimismPortal(payable(optimismPortalProxy)); + IOptimismPortal portal = IOptimismPortal(payable(optimismPortalProxy)); string memory version = portal.version(); console.log("OptimismPortal version: %s", version); @@ -1298,17 +1281,17 @@ contract Deploy is Deployer { _proxy: payable(optimismPortalProxy), _implementation: optimismPortal2, _innerCallData: abi.encodeCall( - OptimismPortal2.initialize, + IOptimismPortal2.initialize, ( DisputeGameFactory(disputeGameFactoryProxy), - SystemConfig(systemConfigProxy), - SuperchainConfig(superchainConfigProxy), + ISystemConfig(systemConfigProxy), + ISuperchainConfig(superchainConfigProxy), GameType.wrap(uint32(cfg.respectedGameType())) ) ) }); - OptimismPortal2 portal = OptimismPortal2(payable(optimismPortalProxy)); + IOptimismPortal2 portal = IOptimismPortal2(payable(optimismPortalProxy)); string memory version = portal.version(); console.log("OptimismPortal2 version: %s", version); @@ -1596,12 +1579,12 @@ contract Deploy is Deployer { _proxy: payable(dataAvailabilityChallengeProxy), _implementation: dataAvailabilityChallenge, _innerCallData: abi.encodeCall( - DataAvailabilityChallenge.initialize, + IDataAvailabilityChallenge.initialize, (finalSystemOwner, daChallengeWindow, daResolveWindow, daBondSize, daResolverRefundPercentage) ) }); - DataAvailabilityChallenge dac = DataAvailabilityChallenge(payable(dataAvailabilityChallengeProxy)); + IDataAvailabilityChallenge dac = IDataAvailabilityChallenge(payable(dataAvailabilityChallengeProxy)); string memory version = dac.version(); console.log("DataAvailabilityChallenge version: %s", version); diff --git a/packages/contracts-bedrock/scripts/deploy/DeployOwnership.s.sol b/packages/contracts-bedrock/scripts/deploy/DeployOwnership.s.sol index 05fbfd54df93..a40c06a17c0f 100644 --- a/packages/contracts-bedrock/scripts/deploy/DeployOwnership.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/DeployOwnership.s.sol @@ -14,7 +14,7 @@ import { Deployer } from "scripts/deploy/Deployer.sol"; import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; import { LivenessModule } from "src/Safe/LivenessModule.sol"; import { DeputyGuardianModule } from "src/Safe/DeputyGuardianModule.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { Deploy } from "./Deploy.s.sol"; @@ -41,7 +41,7 @@ struct SecurityCouncilConfig { /// @notice Configuration for the Deputy Guardian Module struct DeputyGuardianModuleConfig { address deputyGuardian; - SuperchainConfig superchainConfig; + ISuperchainConfig superchainConfig; } /// @notice Configuration for the Guardian Safe. @@ -89,7 +89,7 @@ contract DeployOwnership is Deploy { safeConfig: SafeConfig({ threshold: 1, owners: exampleGuardianOwners }), deputyGuardianModuleConfig: DeputyGuardianModuleConfig({ deputyGuardian: mustGetAddress("FoundationOperationsSafe"), - superchainConfig: SuperchainConfig(mustGetAddress("SuperchainConfig")) + superchainConfig: ISuperchainConfig(mustGetAddress("SuperchainConfig")) }) }); } diff --git a/packages/contracts-bedrock/scripts/fpac/FPACOPS.s.sol b/packages/contracts-bedrock/scripts/fpac/FPACOPS.s.sol index 9d6ad4b719e7..cc00d1a8c866 100644 --- a/packages/contracts-bedrock/scripts/fpac/FPACOPS.s.sol +++ b/packages/contracts-bedrock/scripts/fpac/FPACOPS.s.sol @@ -86,14 +86,14 @@ contract FPACOPS is Deploy, StdAssertions { address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy"); Proxy(payable(wethProxy)).upgradeToAndCall( mustGetAddress("DelayedWETH"), - abi.encodeCall(DelayedWETH.initialize, (msg.sender, SuperchainConfig(superchainConfigProxy))) + abi.encodeCall(DelayedWETH.initialize, (msg.sender, ISuperchainConfig(superchainConfigProxy))) ); } function initializeAnchorStateRegistryProxy() internal broadcast { console.log("Initializing AnchorStateRegistryProxy with AnchorStateRegistry."); address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy"); - SuperchainConfig superchainConfig = SuperchainConfig(superchainConfigProxy); + ISuperchainConfig superchainConfig = ISuperchainConfig(superchainConfigProxy); AnchorStateRegistry.StartingAnchorRoot[] memory roots = new AnchorStateRegistry.StartingAnchorRoot[](2); roots[0] = AnchorStateRegistry.StartingAnchorRoot({ diff --git a/packages/contracts-bedrock/scripts/fpac/FPACOPS2.s.sol b/packages/contracts-bedrock/scripts/fpac/FPACOPS2.s.sol index 09171538010c..4d5f3e4d9af3 100644 --- a/packages/contracts-bedrock/scripts/fpac/FPACOPS2.s.sol +++ b/packages/contracts-bedrock/scripts/fpac/FPACOPS2.s.sol @@ -134,7 +134,7 @@ contract FPACOPS2 is Deploy, StdAssertions { address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy"); Proxy(payable(wethProxy)).upgradeToAndCall( mustGetAddress("DelayedWETH"), - abi.encodeCall(DelayedWETH.initialize, (msg.sender, SuperchainConfig(superchainConfigProxy))) + abi.encodeCall(DelayedWETH.initialize, (msg.sender, ISuperchainConfig(superchainConfigProxy))) ); } @@ -146,7 +146,7 @@ contract FPACOPS2 is Deploy, StdAssertions { address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy"); Proxy(payable(wethProxy)).upgradeToAndCall( mustGetAddress("DelayedWETH"), - abi.encodeCall(DelayedWETH.initialize, (msg.sender, SuperchainConfig(superchainConfigProxy))) + abi.encodeCall(DelayedWETH.initialize, (msg.sender, ISuperchainConfig(superchainConfigProxy))) ); } diff --git a/packages/contracts-bedrock/scripts/interfaces/ISystemConfigV0.sol b/packages/contracts-bedrock/scripts/interfaces/ISystemConfigV0.sol index 07f911e762a9..af1397d72645 100644 --- a/packages/contracts-bedrock/scripts/interfaces/ISystemConfigV0.sol +++ b/packages/contracts-bedrock/scripts/interfaces/ISystemConfigV0.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; /// @title ISystemConfigV0 /// @notice Minimal interface of the Legacy SystemConfig containing only getters. @@ -14,6 +14,6 @@ interface ISystemConfigV0 { function scalar() external view returns (uint256); function batcherHash() external view returns (bytes32); function gasLimit() external view returns (uint64); - function resourceConfig() external view returns (ResourceMetering.ResourceConfig memory); + function resourceConfig() external view returns (IResourceMetering.ResourceConfig memory); function unsafeBlockSigner() external view returns (address); } diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 5f885b995732..8f44a70958a7 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -9,23 +9,23 @@ }, "src/L1/DataAvailabilityChallenge.sol": { "initCodeHash": "0xcc96cf2e4d841adb7ecb9dd84abeb0893dd62d913c0d47ab5b66a893c6e47e88", - "sourceCodeHash": "0x3260f2721af58ab77d4eae50365f3afe021a03b6383139e69779ac40f511b792" + "sourceCodeHash": "0xce01773740f4d50ac77f868343d654f6ca24f85d2770eb7e4043e98f609b1c15" }, "src/L1/DelayedVetoable.sol": { "initCodeHash": "0xd504ab0568719a0fb960ebe73d0437645f5c4bd8f6619219858209ef002516dd", - "sourceCodeHash": "0x1806db090be1a0bd8cba1b0b44a4f1c28a3cfc58a174a025fc292163bfff8cee" + "sourceCodeHash": "0x60af558156543d639a0a92e983ad0f045aac1f9ac4c3adaa1d4d97b37175e03a" }, "src/L1/L1CrossDomainMessenger.sol": { "initCodeHash": "0x48db42620b9f16e0dec2355f4076314f82fd0f60ef04c10cdbc266eac9472515", - "sourceCodeHash": "0xca37e50dd6c1aa86bbc5f9ec640410bf234cd911158ba91af984fd2ed94c19c5" + "sourceCodeHash": "0xb77342e6b55b835e9597f7a1c4a2d52ddd56f5cfb7cd38da0bcc488c79a9011e" }, "src/L1/L1ERC721Bridge.sol": { "initCodeHash": "0xda80d225e332f9ab38d5f3ae655df3eea1dd56dbb523036a25c78859d2931ada", - "sourceCodeHash": "0xcef23f69992fa6cb5ad051858dbec924a06fa3b7b44f03caa2415804d6ce7bd0" + "sourceCodeHash": "0x0454bb88f7b52c362309935fa21ecc8be7bd6f0d888270b8a00677c60c1014cb" }, "src/L1/L1StandardBridge.sol": { "initCodeHash": "0x2868b09ecbe9f2bbc885605c2886b4c79f1c8e4171626c63776603b1b84698a8", - "sourceCodeHash": "0x35f27059e5a7421ddf6394f9739a8c9f434de17e1736644695791c19b8240e74" + "sourceCodeHash": "0xc03da137b3ea72e0109fb284229283b21a0303104afbe37d2fe86ad806392a7f" }, "src/L1/L2OutputOracle.sol": { "initCodeHash": "0x433fac9de52d8ce8fc3471b78ef6cc9cff1019f480c9ad91b6e09ab8738a8edb", @@ -36,16 +36,16 @@ "sourceCodeHash": "0x5182a2678dadb200dd255ecdfa395e5f7b1e1e27288e78ddf8802ab51ed2dd81" }, "src/L1/OptimismPortal.sol": { - "initCodeHash": "0x6bf59539298b20221de6c51db21016be8d3278bdbe0be1cdd49638dc828e003e", - "sourceCodeHash": "0x07f6f4c0cc14be4aeb9a29ec4a238ea3748d5cb6b244e0054845a18308c16ab5" + "initCodeHash": "0xb7a7a28d5b3b88334e7cb4bc1c5fbbf9f691d934e907a2fed6a30e461eb1c0f6", + "sourceCodeHash": "0x17404b6cc3f62f66786c314e2abdf021a19c00845e2cbb2ec7796f2fa469991c" }, "src/L1/OptimismPortal2.sol": { - "initCodeHash": "0x414ad1fdb6296ac32fc67ce01288b6e67bedd2ed239d7eb8ed40c7f55f9021f2", - "sourceCodeHash": "0xa70bdc0bb666baa731ab32c79a7b8b15cee23bd46ddfec5f259eaf19b5653fe1" + "initCodeHash": "0x6c1168834a0d2a23d9bfb995dd458ef5c2fd059c874d453988ef648de8300730", + "sourceCodeHash": "0xa8053edf2ddd421615c7570e5dbb435980b88e0f08e3189e2fc69b7a476e80a2" }, "src/L1/OptimismPortalInterop.sol": { - "initCodeHash": "0x9222fba222d1ab66898eef09ecea3ea757e64c8ae98def4da7808cd7cc8f39a8", - "sourceCodeHash": "0x57353b84bbcb05634f135ad8090d96f07467dd3dbf159650714449d0667efc62" + "initCodeHash": "0xc95dd89962e301ce1fe773337463ea6e3b32b362971e5ad4f69e0881af7f4b7d", + "sourceCodeHash": "0xe6a7794799915f408cb57c73af266670de8a3f02408d3dbc2c97db25d3e42635" }, "src/L1/ProtocolVersions.sol": { "initCodeHash": "0x8f033874dd8b36615b2209d553660dcff1ff91ca2bad3ca1de7b441dbfba4842", @@ -57,11 +57,11 @@ }, "src/L1/SystemConfig.sol": { "initCodeHash": "0x2fc36af5b3c493a423a19e0b597f6ff230b756b861b68099f3192d69b6088dc0", - "sourceCodeHash": "0xacffbb4e73d39a642adc24baaa50c92604f4c0b04ff31287e24a46bda5277033" + "sourceCodeHash": "0x06a50ac992175fdb434b13e8461893e83862c23ce399e697e6e8109728ad1a3d" }, "src/L1/SystemConfigInterop.sol": { "initCodeHash": "0xc5a3ffc59dd7bf1ef238087414cfa04b37f0d83fc9a4f5e6d62a1059a23359f3", - "sourceCodeHash": "0x272bcfafab62516609250c85cd73815bf0a243fdb9d34fc603f71e801299b57c" + "sourceCodeHash": "0xd7b6ebf03ead541917b1bdfcf1293ca3c8a8e3865b8a8548bee69956a4ce71cc" }, "src/L2/BaseFeeVault.sol": { "initCodeHash": "0x3bfcd57e25ad54b66c374f63e24e33a6cf107044aa8f5f69ef21202c380b5c5b", @@ -97,11 +97,11 @@ }, "src/L2/L2ERC721Bridge.sol": { "initCodeHash": "0x827077e1a0ce6c8f9ee1196c409ea77d831efd440992b3969b05259083cdf0bd", - "sourceCodeHash": "0xaef911601556f93deac78cb3329fdcc1507ea248c3986548e76997938c43391b" + "sourceCodeHash": "0xdc5e08a5a9ee8d61e843ac630126629ccfedb49a3b0dd167863dd48d75629a95" }, "src/L2/L2StandardBridge.sol": { "initCodeHash": "0x01692b613e3d4e649d877a0fd8f0798a26401ba8ccc4cda0e61f1f9079729320", - "sourceCodeHash": "0x3efb2dabff452f5d2584839d1460183cb8aecd5456fbfa3a72d80de40df783b7" + "sourceCodeHash": "0x5c8e8ba3ecdae116f98caf67cca5fb3594bf7085e186f0a14bad1d6f143b6bc8" }, "src/L2/L2StandardBridgeInterop.sol": { "initCodeHash": "0x5c9ef6b0817f715d1b8b097f3fc19e33bc54453426ca12bb48e4cea143076339", @@ -133,7 +133,7 @@ }, "src/Safe/DeputyGuardianModule.sol": { "initCodeHash": "0xce6cd0e4f21693a32e7a8ef463b8233b0dde83bdb426f5adc3eef822d4de7bec", - "sourceCodeHash": "0x45fdf6b414a6eae662392051a5e0acc5b95f23ca33f739ddfb35ae2e7ce81728" + "sourceCodeHash": "0x7b0f24df9af4cf5a52e23b98898b884d8175ad89cc24046d6463c3e9b3599d4d" }, "src/Safe/LivenessGuard.sol": { "initCodeHash": "0xfd74ff89e7b689b38ab97515d64429ffaf6c0cd1ea6488c6a4743a0665419c85", @@ -157,7 +157,7 @@ }, "src/dispute/AnchorStateRegistry.sol": { "initCodeHash": "0x6198f305686e6fdfd94db7aeb840a12e263036dcdc234550db49d3f0b87039a8", - "sourceCodeHash": "0x384d4e7067d423dc32b8588341b61a504a28505aa5ed7dd76f115991be072ee0" + "sourceCodeHash": "0x8450bdccf5039bad48284c73c9cfa657cbcc0a435965d9e13ac88f388c591779" }, "src/dispute/DisputeGameFactory.sol": { "initCodeHash": "0xc1a10f65287c414076b68a7de6c238b91bc6252213187bdef35657d0f00f9382", @@ -169,7 +169,7 @@ }, "src/dispute/weth/DelayedWETH.sol": { "initCodeHash": "0x3e687c928b6c890b91c82584ccb1fec47b025b8e58cd9cbfa65229b38b304bae", - "sourceCodeHash": "0x7ebe0d9771fc8adfd97386972a571eb1753065a202d4711c0b9587d99f3bd261" + "sourceCodeHash": "0x9d6667536161b3fa655dfb3e9a01db070cd0e84d800e34947b10b3b2168a3d56" }, "src/legacy/DeployerWhitelist.sol": { "initCodeHash": "0x0b8177ed75b69eddbb9ce6537683f69a9935efed86a1d6faa8feaafbd151c1bd", diff --git a/packages/contracts-bedrock/snapshots/abi/AnchorStateRegistry.json b/packages/contracts-bedrock/snapshots/abi/AnchorStateRegistry.json index aaa832eb1b70..c1a0fc693a9a 100644 --- a/packages/contracts-bedrock/snapshots/abi/AnchorStateRegistry.json +++ b/packages/contracts-bedrock/snapshots/abi/AnchorStateRegistry.json @@ -79,7 +79,7 @@ "type": "tuple[]" }, { - "internalType": "contract SuperchainConfig", + "internalType": "contract ISuperchainConfig", "name": "_superchainConfig", "type": "address" } @@ -107,7 +107,7 @@ "name": "superchainConfig", "outputs": [ { - "internalType": "contract SuperchainConfig", + "internalType": "contract ISuperchainConfig", "name": "", "type": "address" } diff --git a/packages/contracts-bedrock/snapshots/abi/DelayedWETH.json b/packages/contracts-bedrock/snapshots/abi/DelayedWETH.json index fe4fd5b63f61..a84394e6b003 100644 --- a/packages/contracts-bedrock/snapshots/abi/DelayedWETH.json +++ b/packages/contracts-bedrock/snapshots/abi/DelayedWETH.json @@ -90,7 +90,7 @@ "name": "config", "outputs": [ { - "internalType": "contract SuperchainConfig", + "internalType": "contract ISuperchainConfig", "name": "", "type": "address" } @@ -157,7 +157,7 @@ "type": "address" }, { - "internalType": "contract SuperchainConfig", + "internalType": "contract ISuperchainConfig", "name": "_config", "type": "address" } diff --git a/packages/contracts-bedrock/snapshots/abi/DeputyGuardianModule.json b/packages/contracts-bedrock/snapshots/abi/DeputyGuardianModule.json index 688d68f6f271..6e5c45fc3d8a 100644 --- a/packages/contracts-bedrock/snapshots/abi/DeputyGuardianModule.json +++ b/packages/contracts-bedrock/snapshots/abi/DeputyGuardianModule.json @@ -7,7 +7,7 @@ "type": "address" }, { - "internalType": "contract SuperchainConfig", + "internalType": "contract ISuperchainConfig", "name": "_superchainConfig", "type": "address" }, @@ -23,7 +23,7 @@ { "inputs": [ { - "internalType": "contract OptimismPortal2", + "internalType": "contract IOptimismPortal2", "name": "_portal", "type": "address" }, @@ -92,7 +92,7 @@ { "inputs": [ { - "internalType": "contract OptimismPortal2", + "internalType": "contract IOptimismPortal2", "name": "_portal", "type": "address" }, @@ -112,7 +112,7 @@ "name": "superchainConfig", "outputs": [ { - "internalType": "contract SuperchainConfig", + "internalType": "contract ISuperchainConfig", "name": "superchainConfig_", "type": "address" } diff --git a/packages/contracts-bedrock/snapshots/abi/L1CrossDomainMessenger.json b/packages/contracts-bedrock/snapshots/abi/L1CrossDomainMessenger.json index cc99f64c449e..22a4353cc656 100644 --- a/packages/contracts-bedrock/snapshots/abi/L1CrossDomainMessenger.json +++ b/packages/contracts-bedrock/snapshots/abi/L1CrossDomainMessenger.json @@ -74,7 +74,7 @@ "name": "PORTAL", "outputs": [ { - "internalType": "contract OptimismPortal", + "internalType": "contract IOptimismPortal", "name": "", "type": "address" } @@ -180,17 +180,17 @@ { "inputs": [ { - "internalType": "contract SuperchainConfig", + "internalType": "contract ISuperchainConfig", "name": "_superchainConfig", "type": "address" }, { - "internalType": "contract OptimismPortal", + "internalType": "contract IOptimismPortal", "name": "_portal", "type": "address" }, { - "internalType": "contract SystemConfig", + "internalType": "contract ISystemConfig", "name": "_systemConfig", "type": "address" } @@ -244,7 +244,7 @@ "name": "portal", "outputs": [ { - "internalType": "contract OptimismPortal", + "internalType": "contract IOptimismPortal", "name": "", "type": "address" } @@ -337,7 +337,7 @@ "name": "superchainConfig", "outputs": [ { - "internalType": "contract SuperchainConfig", + "internalType": "contract ISuperchainConfig", "name": "", "type": "address" } @@ -350,7 +350,7 @@ "name": "systemConfig", "outputs": [ { - "internalType": "contract SystemConfig", + "internalType": "contract ISystemConfig", "name": "", "type": "address" } diff --git a/packages/contracts-bedrock/snapshots/abi/L1ERC721Bridge.json b/packages/contracts-bedrock/snapshots/abi/L1ERC721Bridge.json index 386c8413a9ff..33cd5b0a850b 100644 --- a/packages/contracts-bedrock/snapshots/abi/L1ERC721Bridge.json +++ b/packages/contracts-bedrock/snapshots/abi/L1ERC721Bridge.json @@ -9,7 +9,7 @@ "name": "MESSENGER", "outputs": [ { - "internalType": "contract CrossDomainMessenger", + "internalType": "contract ICrossDomainMessenger", "name": "", "type": "address" } @@ -171,12 +171,12 @@ { "inputs": [ { - "internalType": "contract CrossDomainMessenger", + "internalType": "contract ICrossDomainMessenger", "name": "_messenger", "type": "address" }, { - "internalType": "contract SuperchainConfig", + "internalType": "contract ISuperchainConfig", "name": "_superchainConfig", "type": "address" } @@ -191,7 +191,7 @@ "name": "messenger", "outputs": [ { - "internalType": "contract CrossDomainMessenger", + "internalType": "contract ICrossDomainMessenger", "name": "", "type": "address" } @@ -230,7 +230,7 @@ "name": "superchainConfig", "outputs": [ { - "internalType": "contract SuperchainConfig", + "internalType": "contract ISuperchainConfig", "name": "", "type": "address" } diff --git a/packages/contracts-bedrock/snapshots/abi/L1StandardBridge.json b/packages/contracts-bedrock/snapshots/abi/L1StandardBridge.json index 2a93a9f8da24..45480499fe9f 100644 --- a/packages/contracts-bedrock/snapshots/abi/L1StandardBridge.json +++ b/packages/contracts-bedrock/snapshots/abi/L1StandardBridge.json @@ -13,7 +13,7 @@ "name": "MESSENGER", "outputs": [ { - "internalType": "contract CrossDomainMessenger", + "internalType": "contract ICrossDomainMessenger", "name": "", "type": "address" } @@ -417,17 +417,17 @@ { "inputs": [ { - "internalType": "contract CrossDomainMessenger", + "internalType": "contract ICrossDomainMessenger", "name": "_messenger", "type": "address" }, { - "internalType": "contract SuperchainConfig", + "internalType": "contract ISuperchainConfig", "name": "_superchainConfig", "type": "address" }, { - "internalType": "contract SystemConfig", + "internalType": "contract ISystemConfig", "name": "_systemConfig", "type": "address" } @@ -455,7 +455,7 @@ "name": "messenger", "outputs": [ { - "internalType": "contract CrossDomainMessenger", + "internalType": "contract ICrossDomainMessenger", "name": "", "type": "address" } @@ -494,7 +494,7 @@ "name": "superchainConfig", "outputs": [ { - "internalType": "contract SuperchainConfig", + "internalType": "contract ISuperchainConfig", "name": "", "type": "address" } @@ -507,7 +507,7 @@ "name": "systemConfig", "outputs": [ { - "internalType": "contract SystemConfig", + "internalType": "contract ISystemConfig", "name": "", "type": "address" } diff --git a/packages/contracts-bedrock/snapshots/abi/L2ERC721Bridge.json b/packages/contracts-bedrock/snapshots/abi/L2ERC721Bridge.json index d0df33b56960..e9578ad9726c 100644 --- a/packages/contracts-bedrock/snapshots/abi/L2ERC721Bridge.json +++ b/packages/contracts-bedrock/snapshots/abi/L2ERC721Bridge.json @@ -9,7 +9,7 @@ "name": "MESSENGER", "outputs": [ { - "internalType": "contract CrossDomainMessenger", + "internalType": "contract ICrossDomainMessenger", "name": "", "type": "address" } @@ -157,7 +157,7 @@ "name": "messenger", "outputs": [ { - "internalType": "contract CrossDomainMessenger", + "internalType": "contract ICrossDomainMessenger", "name": "", "type": "address" } diff --git a/packages/contracts-bedrock/snapshots/abi/L2StandardBridge.json b/packages/contracts-bedrock/snapshots/abi/L2StandardBridge.json index da71bae10f06..e562034818d5 100644 --- a/packages/contracts-bedrock/snapshots/abi/L2StandardBridge.json +++ b/packages/contracts-bedrock/snapshots/abi/L2StandardBridge.json @@ -13,7 +13,7 @@ "name": "MESSENGER", "outputs": [ { - "internalType": "contract CrossDomainMessenger", + "internalType": "contract ICrossDomainMessenger", "name": "", "type": "address" } @@ -267,7 +267,7 @@ "name": "messenger", "outputs": [ { - "internalType": "contract CrossDomainMessenger", + "internalType": "contract ICrossDomainMessenger", "name": "", "type": "address" } diff --git a/packages/contracts-bedrock/snapshots/abi/L2StandardBridgeInterop.json b/packages/contracts-bedrock/snapshots/abi/L2StandardBridgeInterop.json index d870c7180a30..b2dc8dddd050 100644 --- a/packages/contracts-bedrock/snapshots/abi/L2StandardBridgeInterop.json +++ b/packages/contracts-bedrock/snapshots/abi/L2StandardBridgeInterop.json @@ -8,7 +8,7 @@ "name": "MESSENGER", "outputs": [ { - "internalType": "contract CrossDomainMessenger", + "internalType": "contract ICrossDomainMessenger", "name": "", "type": "address" } @@ -285,7 +285,7 @@ "name": "messenger", "outputs": [ { - "internalType": "contract CrossDomainMessenger", + "internalType": "contract ICrossDomainMessenger", "name": "", "type": "address" } diff --git a/packages/contracts-bedrock/snapshots/abi/OptimismPortal.json b/packages/contracts-bedrock/snapshots/abi/OptimismPortal.json index 12ab9e26b9b3..7ccee328a984 100644 --- a/packages/contracts-bedrock/snapshots/abi/OptimismPortal.json +++ b/packages/contracts-bedrock/snapshots/abi/OptimismPortal.json @@ -184,12 +184,12 @@ "type": "address" }, { - "internalType": "contract SystemConfig", + "internalType": "contract ISystemConfig", "name": "_systemConfig", "type": "address" }, { - "internalType": "contract SuperchainConfig", + "internalType": "contract ISuperchainConfig", "name": "_superchainConfig", "type": "address" } @@ -443,7 +443,7 @@ "name": "superchainConfig", "outputs": [ { - "internalType": "contract SuperchainConfig", + "internalType": "contract ISuperchainConfig", "name": "", "type": "address" } @@ -456,7 +456,7 @@ "name": "systemConfig", "outputs": [ { - "internalType": "contract SystemConfig", + "internalType": "contract ISystemConfig", "name": "", "type": "address" } diff --git a/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json b/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json index 92610763d6f0..2f52ed573d37 100644 --- a/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json +++ b/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json @@ -158,7 +158,7 @@ "name": "disputeGameFactory", "outputs": [ { - "internalType": "contract DisputeGameFactory", + "internalType": "contract IDisputeGameFactory", "name": "", "type": "address" } @@ -316,17 +316,17 @@ { "inputs": [ { - "internalType": "contract DisputeGameFactory", + "internalType": "contract IDisputeGameFactory", "name": "_disputeGameFactory", "type": "address" }, { - "internalType": "contract SystemConfig", + "internalType": "contract ISystemConfig", "name": "_systemConfig", "type": "address" }, { - "internalType": "contract SuperchainConfig", + "internalType": "contract ISuperchainConfig", "name": "_superchainConfig", "type": "address" }, @@ -648,7 +648,7 @@ "name": "superchainConfig", "outputs": [ { - "internalType": "contract SuperchainConfig", + "internalType": "contract ISuperchainConfig", "name": "", "type": "address" } @@ -661,7 +661,7 @@ "name": "systemConfig", "outputs": [ { - "internalType": "contract SystemConfig", + "internalType": "contract ISystemConfig", "name": "", "type": "address" } diff --git a/packages/contracts-bedrock/snapshots/abi/OptimismPortalInterop.json b/packages/contracts-bedrock/snapshots/abi/OptimismPortalInterop.json index 4d9979bee344..5b9f72b9446c 100644 --- a/packages/contracts-bedrock/snapshots/abi/OptimismPortalInterop.json +++ b/packages/contracts-bedrock/snapshots/abi/OptimismPortalInterop.json @@ -158,7 +158,7 @@ "name": "disputeGameFactory", "outputs": [ { - "internalType": "contract DisputeGameFactory", + "internalType": "contract IDisputeGameFactory", "name": "", "type": "address" } @@ -316,17 +316,17 @@ { "inputs": [ { - "internalType": "contract DisputeGameFactory", + "internalType": "contract IDisputeGameFactory", "name": "_disputeGameFactory", "type": "address" }, { - "internalType": "contract SystemConfig", + "internalType": "contract ISystemConfig", "name": "_systemConfig", "type": "address" }, { - "internalType": "contract SuperchainConfig", + "internalType": "contract ISuperchainConfig", "name": "_superchainConfig", "type": "address" }, @@ -666,7 +666,7 @@ "name": "superchainConfig", "outputs": [ { - "internalType": "contract SuperchainConfig", + "internalType": "contract ISuperchainConfig", "name": "", "type": "address" } @@ -679,7 +679,7 @@ "name": "systemConfig", "outputs": [ { - "internalType": "contract SystemConfig", + "internalType": "contract ISystemConfig", "name": "", "type": "address" } @@ -949,11 +949,6 @@ "name": "Unauthorized", "type": "error" }, - { - "inputs": [], - "name": "Unauthorized", - "type": "error" - }, { "inputs": [], "name": "UnexpectedList", diff --git a/packages/contracts-bedrock/snapshots/abi/SystemConfig.json b/packages/contracts-bedrock/snapshots/abi/SystemConfig.json index 4b4ddd6c70a1..695231b9b119 100644 --- a/packages/contracts-bedrock/snapshots/abi/SystemConfig.json +++ b/packages/contracts-bedrock/snapshots/abi/SystemConfig.json @@ -321,7 +321,7 @@ "type": "uint128" } ], - "internalType": "struct ResourceMetering.ResourceConfig", + "internalType": "struct IResourceMetering.ResourceConfig", "name": "_config", "type": "tuple" }, @@ -552,7 +552,7 @@ "type": "uint128" } ], - "internalType": "struct ResourceMetering.ResourceConfig", + "internalType": "struct IResourceMetering.ResourceConfig", "name": "", "type": "tuple" } diff --git a/packages/contracts-bedrock/snapshots/abi/SystemConfigInterop.json b/packages/contracts-bedrock/snapshots/abi/SystemConfigInterop.json index b32316ec9e42..64f72945615b 100644 --- a/packages/contracts-bedrock/snapshots/abi/SystemConfigInterop.json +++ b/packages/contracts-bedrock/snapshots/abi/SystemConfigInterop.json @@ -342,7 +342,7 @@ "type": "uint128" } ], - "internalType": "struct ResourceMetering.ResourceConfig", + "internalType": "struct IResourceMetering.ResourceConfig", "name": "_config", "type": "tuple" }, @@ -469,7 +469,7 @@ "type": "uint128" } ], - "internalType": "struct ResourceMetering.ResourceConfig", + "internalType": "struct IResourceMetering.ResourceConfig", "name": "_config", "type": "tuple" }, @@ -713,7 +713,7 @@ "type": "uint128" } ], - "internalType": "struct ResourceMetering.ResourceConfig", + "internalType": "struct IResourceMetering.ResourceConfig", "name": "", "type": "tuple" } diff --git a/packages/contracts-bedrock/snapshots/storageLayout/AnchorStateRegistry.json b/packages/contracts-bedrock/snapshots/storageLayout/AnchorStateRegistry.json index 3511e68eb879..3900f4552584 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/AnchorStateRegistry.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/AnchorStateRegistry.json @@ -25,6 +25,6 @@ "label": "superchainConfig", "offset": 0, "slot": "2", - "type": "contract SuperchainConfig" + "type": "contract ISuperchainConfig" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/DelayedWETH.json b/packages/contracts-bedrock/snapshots/storageLayout/DelayedWETH.json index efc43f45893c..b20b276476e9 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/DelayedWETH.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/DelayedWETH.json @@ -60,6 +60,6 @@ "label": "config", "offset": 0, "slot": "104", - "type": "contract SuperchainConfig" + "type": "contract ISuperchainConfig" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L1CrossDomainMessenger.json b/packages/contracts-bedrock/snapshots/storageLayout/L1CrossDomainMessenger.json index 5c88be3ca9ae..c68ec541baba 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/L1CrossDomainMessenger.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/L1CrossDomainMessenger.json @@ -130,20 +130,20 @@ "label": "superchainConfig", "offset": 0, "slot": "251", - "type": "contract SuperchainConfig" + "type": "contract ISuperchainConfig" }, { "bytes": "20", "label": "portal", "offset": 0, "slot": "252", - "type": "contract OptimismPortal" + "type": "contract IOptimismPortal" }, { "bytes": "20", "label": "systemConfig", "offset": 0, "slot": "253", - "type": "contract SystemConfig" + "type": "contract ISystemConfig" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L1ERC721Bridge.json b/packages/contracts-bedrock/snapshots/storageLayout/L1ERC721Bridge.json index b08068ee9aeb..2c14ad25904b 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/L1ERC721Bridge.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/L1ERC721Bridge.json @@ -25,7 +25,7 @@ "label": "messenger", "offset": 0, "slot": "1", - "type": "contract CrossDomainMessenger" + "type": "contract ICrossDomainMessenger" }, { "bytes": "20", @@ -53,6 +53,6 @@ "label": "superchainConfig", "offset": 0, "slot": "50", - "type": "contract SuperchainConfig" + "type": "contract ISuperchainConfig" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L1StandardBridge.json b/packages/contracts-bedrock/snapshots/storageLayout/L1StandardBridge.json index 1ed5eac5d183..5562a214e4fe 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/L1StandardBridge.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/L1StandardBridge.json @@ -39,7 +39,7 @@ "label": "messenger", "offset": 0, "slot": "3", - "type": "contract CrossDomainMessenger" + "type": "contract ICrossDomainMessenger" }, { "bytes": "20", @@ -60,13 +60,13 @@ "label": "superchainConfig", "offset": 0, "slot": "50", - "type": "contract SuperchainConfig" + "type": "contract ISuperchainConfig" }, { "bytes": "20", "label": "systemConfig", "offset": 0, "slot": "51", - "type": "contract SystemConfig" + "type": "contract ISystemConfig" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L2ERC721Bridge.json b/packages/contracts-bedrock/snapshots/storageLayout/L2ERC721Bridge.json index e9facc6579e6..546b37ba6398 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/L2ERC721Bridge.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/L2ERC721Bridge.json @@ -25,7 +25,7 @@ "label": "messenger", "offset": 0, "slot": "1", - "type": "contract CrossDomainMessenger" + "type": "contract ICrossDomainMessenger" }, { "bytes": "20", diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L2StandardBridge.json b/packages/contracts-bedrock/snapshots/storageLayout/L2StandardBridge.json index f5effc6ae799..c6ccc0fc2e03 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/L2StandardBridge.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/L2StandardBridge.json @@ -39,7 +39,7 @@ "label": "messenger", "offset": 0, "slot": "3", - "type": "contract CrossDomainMessenger" + "type": "contract ICrossDomainMessenger" }, { "bytes": "20", diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L2StandardBridgeInterop.json b/packages/contracts-bedrock/snapshots/storageLayout/L2StandardBridgeInterop.json index f5effc6ae799..c6ccc0fc2e03 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/L2StandardBridgeInterop.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/L2StandardBridgeInterop.json @@ -39,7 +39,7 @@ "label": "messenger", "offset": 0, "slot": "3", - "type": "contract CrossDomainMessenger" + "type": "contract ICrossDomainMessenger" }, { "bytes": "20", diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal.json b/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal.json index 3795f987b280..d129ef1b87e3 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal.json @@ -60,7 +60,7 @@ "label": "superchainConfig", "offset": 1, "slot": "53", - "type": "contract SuperchainConfig" + "type": "contract ISuperchainConfig" }, { "bytes": "20", @@ -74,7 +74,7 @@ "label": "systemConfig", "offset": 0, "slot": "55", - "type": "contract SystemConfig" + "type": "contract ISystemConfig" }, { "bytes": "20", diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal2.json b/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal2.json index 807e966b6edd..0fdd65b3e88f 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal2.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal2.json @@ -60,7 +60,7 @@ "label": "superchainConfig", "offset": 1, "slot": "53", - "type": "contract SuperchainConfig" + "type": "contract ISuperchainConfig" }, { "bytes": "20", @@ -74,14 +74,14 @@ "label": "systemConfig", "offset": 0, "slot": "55", - "type": "contract SystemConfig" + "type": "contract ISystemConfig" }, { "bytes": "20", "label": "disputeGameFactory", "offset": 0, "slot": "56", - "type": "contract DisputeGameFactory" + "type": "contract IDisputeGameFactory" }, { "bytes": "32", diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortalInterop.json b/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortalInterop.json index 807e966b6edd..0fdd65b3e88f 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortalInterop.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortalInterop.json @@ -60,7 +60,7 @@ "label": "superchainConfig", "offset": 1, "slot": "53", - "type": "contract SuperchainConfig" + "type": "contract ISuperchainConfig" }, { "bytes": "20", @@ -74,14 +74,14 @@ "label": "systemConfig", "offset": 0, "slot": "55", - "type": "contract SystemConfig" + "type": "contract ISystemConfig" }, { "bytes": "20", "label": "disputeGameFactory", "offset": 0, "slot": "56", - "type": "contract DisputeGameFactory" + "type": "contract IDisputeGameFactory" }, { "bytes": "32", diff --git a/packages/contracts-bedrock/snapshots/storageLayout/SystemConfig.json b/packages/contracts-bedrock/snapshots/storageLayout/SystemConfig.json index 648245156248..b0946e1bc4db 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/SystemConfig.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/SystemConfig.json @@ -81,6 +81,6 @@ "label": "_resourceConfig", "offset": 0, "slot": "105", - "type": "struct ResourceMetering.ResourceConfig" + "type": "struct IResourceMetering.ResourceConfig" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/SystemConfigInterop.json b/packages/contracts-bedrock/snapshots/storageLayout/SystemConfigInterop.json index 648245156248..b0946e1bc4db 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/SystemConfigInterop.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/SystemConfigInterop.json @@ -81,6 +81,6 @@ "label": "_resourceConfig", "offset": 0, "slot": "105", - "type": "struct ResourceMetering.ResourceConfig" + "type": "struct IResourceMetering.ResourceConfig" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/src/L1/DataAvailabilityChallenge.sol b/packages/contracts-bedrock/src/L1/DataAvailabilityChallenge.sol index fa45c47b2d09..1bb0d1bf6680 100644 --- a/packages/contracts-bedrock/src/L1/DataAvailabilityChallenge.sol +++ b/packages/contracts-bedrock/src/L1/DataAvailabilityChallenge.sol @@ -1,10 +1,15 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Contracts import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import { ISemver } from "src/universal/interfaces/ISemver.sol"; + +// Libraries import { SafeCall } from "src/libraries/SafeCall.sol"; +// Interfaces +import { ISemver } from "src/universal/interfaces/ISemver.sol"; + /// @dev An enum representing the status of a DA challenge. enum ChallengeStatus { Uninitialized, diff --git a/packages/contracts-bedrock/src/L1/DelayedVetoable.sol b/packages/contracts-bedrock/src/L1/DelayedVetoable.sol index 113f8a03bea2..ad45b4c9b20a 100644 --- a/packages/contracts-bedrock/src/L1/DelayedVetoable.sol +++ b/packages/contracts-bedrock/src/L1/DelayedVetoable.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Interfaces import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @title DelayedVetoable diff --git a/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol index 56d8218ac08c..8df4d9bfe765 100644 --- a/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol +++ b/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol @@ -1,12 +1,17 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Predeploys } from "src/libraries/Predeploys.sol"; -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; +// Contracts import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; + +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Interfaces import { ISemver } from "src/universal/interfaces/ISemver.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; +import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; /// @custom:proxied true /// @title L1CrossDomainMessenger @@ -15,14 +20,14 @@ import { SystemConfig } from "src/L1/SystemConfig.sol"; /// interface instead of interacting with lower-level contracts directly. contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver { /// @notice Contract of the SuperchainConfig. - SuperchainConfig public superchainConfig; + ISuperchainConfig public superchainConfig; /// @notice Contract of the OptimismPortal. /// @custom:network-specific - OptimismPortal public portal; + IOptimismPortal public portal; /// @notice Address of the SystemConfig contract. - SystemConfig public systemConfig; + ISystemConfig public systemConfig; /// @notice Semantic version. /// @custom:semver 2.4.1-beta.1 @@ -31,9 +36,9 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver { /// @notice Constructs the L1CrossDomainMessenger contract. constructor() CrossDomainMessenger() { initialize({ - _superchainConfig: SuperchainConfig(address(0)), - _portal: OptimismPortal(payable(address(0))), - _systemConfig: SystemConfig(address(0)) + _superchainConfig: ISuperchainConfig(address(0)), + _portal: IOptimismPortal(payable(address(0))), + _systemConfig: ISystemConfig(address(0)) }); } @@ -42,9 +47,9 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver { /// @param _portal Contract of the OptimismPortal contract on this network. /// @param _systemConfig Contract of the SystemConfig contract on this network. function initialize( - SuperchainConfig _superchainConfig, - OptimismPortal _portal, - SystemConfig _systemConfig + ISuperchainConfig _superchainConfig, + IOptimismPortal _portal, + ISystemConfig _systemConfig ) public initializer @@ -64,7 +69,7 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver { /// Public getter is legacy and will be removed in the future. Use `portal()` instead. /// @return Contract of the OptimismPortal on this chain. /// @custom:legacy - function PORTAL() external view returns (OptimismPortal) { + function PORTAL() external view returns (IOptimismPortal) { return portal; } diff --git a/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol b/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol index 014a501f58c9..04ea2a6cc82e 100644 --- a/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol +++ b/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol @@ -1,15 +1,19 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Contracts import { ERC721Bridge } from "src/universal/ERC721Bridge.sol"; -import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; -import { ISemver } from "src/universal/interfaces/ISemver.sol"; + +// Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; -import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { StandardBridge } from "src/universal/StandardBridge.sol"; import { Constants } from "src/libraries/Constants.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; + +// Interfaces +import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; /// @custom:proxied true /// @title L1ERC721Bridge @@ -22,7 +26,7 @@ contract L1ERC721Bridge is ERC721Bridge, ISemver { mapping(address => mapping(address => mapping(uint256 => bool))) public deposits; /// @notice Address of the SuperchainConfig contract. - SuperchainConfig public superchainConfig; + ISuperchainConfig public superchainConfig; /// @notice Semantic version. /// @custom:semver 2.1.1-beta.2 @@ -30,13 +34,13 @@ contract L1ERC721Bridge is ERC721Bridge, ISemver { /// @notice Constructs the L1ERC721Bridge contract. constructor() ERC721Bridge() { - initialize({ _messenger: CrossDomainMessenger(address(0)), _superchainConfig: SuperchainConfig(address(0)) }); + initialize({ _messenger: ICrossDomainMessenger(address(0)), _superchainConfig: ISuperchainConfig(address(0)) }); } /// @notice Initializes the contract. /// @param _messenger Contract of the CrossDomainMessenger on this network. /// @param _superchainConfig Contract of the SuperchainConfig contract on this network. - function initialize(CrossDomainMessenger _messenger, SuperchainConfig _superchainConfig) public initializer { + function initialize(ICrossDomainMessenger _messenger, ISuperchainConfig _superchainConfig) public initializer { superchainConfig = _superchainConfig; __ERC721Bridge_init({ _messenger: _messenger, _otherBridge: ERC721Bridge(payable(Predeploys.L2_ERC721_BRIDGE)) }); } diff --git a/packages/contracts-bedrock/src/L1/L1StandardBridge.sol b/packages/contracts-bedrock/src/L1/L1StandardBridge.sol index 107be4851e1e..6dd648f0d541 100644 --- a/packages/contracts-bedrock/src/L1/L1StandardBridge.sol +++ b/packages/contracts-bedrock/src/L1/L1StandardBridge.sol @@ -1,13 +1,17 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Predeploys } from "src/libraries/Predeploys.sol"; +// Contracts import { StandardBridge } from "src/universal/StandardBridge.sol"; + +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Interfaces import { ISemver } from "src/universal/interfaces/ISemver.sol"; -import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; /// @custom:proxied true /// @title L1StandardBridge @@ -75,17 +79,17 @@ contract L1StandardBridge is StandardBridge, ISemver { string public constant version = "2.2.1-beta.1"; /// @notice Address of the SuperchainConfig contract. - SuperchainConfig public superchainConfig; + ISuperchainConfig public superchainConfig; /// @notice Address of the SystemConfig contract. - SystemConfig public systemConfig; + ISystemConfig public systemConfig; /// @notice Constructs the L1StandardBridge contract. constructor() StandardBridge() { initialize({ - _messenger: CrossDomainMessenger(address(0)), - _superchainConfig: SuperchainConfig(address(0)), - _systemConfig: SystemConfig(address(0)) + _messenger: ICrossDomainMessenger(address(0)), + _superchainConfig: ISuperchainConfig(address(0)), + _systemConfig: ISystemConfig(address(0)) }); } @@ -93,9 +97,9 @@ contract L1StandardBridge is StandardBridge, ISemver { /// @param _messenger Contract for the CrossDomainMessenger on this network. /// @param _superchainConfig Contract for the SuperchainConfig on this network. function initialize( - CrossDomainMessenger _messenger, - SuperchainConfig _superchainConfig, - SystemConfig _systemConfig + ICrossDomainMessenger _messenger, + ISuperchainConfig _superchainConfig, + ISystemConfig _systemConfig ) public initializer diff --git a/packages/contracts-bedrock/src/L1/OptimismPortal.sol b/packages/contracts-bedrock/src/L1/OptimismPortal.sol index 517131d400cc..24eaccf8cc47 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortal.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortal.sol @@ -1,24 +1,30 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Contracts import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; +import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { L1Block } from "src/L2/L1Block.sol"; + +// Libraries +import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { SafeCall } from "src/libraries/SafeCall.sol"; -import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { Constants } from "src/libraries/Constants.sol"; import { Types } from "src/libraries/Types.sol"; import { Hashing } from "src/libraries/Hashing.sol"; import { SecureMerkleTrie } from "src/libraries/trie/SecureMerkleTrie.sol"; -import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; -import { ResourceMetering } from "src/L1/ResourceMetering.sol"; -import { ISemver } from "src/universal/interfaces/ISemver.sol"; -import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { L1Block } from "src/L2/L1Block.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import "src/libraries/PortalErrors.sol"; +// Interfaces +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; + /// @custom:proxied true /// @title OptimismPortal /// @notice The OptimismPortal is a low-level contract responsible for passing messages between L1 @@ -64,7 +70,7 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver { bool private spacer_53_0_1; /// @notice Contract of the Superchain Config. - SuperchainConfig public superchainConfig; + ISuperchainConfig public superchainConfig; /// @notice Contract of the L2OutputOracle. /// @custom:network-specific @@ -72,7 +78,7 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver { /// @notice Contract of the SystemConfig. /// @custom:network-specific - SystemConfig public systemConfig; + ISystemConfig public systemConfig; /// @custom:spacer disputeGameFactory /// @notice Spacer for backwards compatibility. @@ -137,8 +143,8 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver { constructor() { initialize({ _l2Oracle: IL2OutputOracle(address(0)), - _systemConfig: SystemConfig(address(0)), - _superchainConfig: SuperchainConfig(address(0)) + _systemConfig: ISystemConfig(address(0)), + _superchainConfig: ISuperchainConfig(address(0)) }); } @@ -148,8 +154,8 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver { /// @param _superchainConfig Contract of the SuperchainConfig. function initialize( IL2OutputOracle _l2Oracle, - SystemConfig _systemConfig, - SuperchainConfig _superchainConfig + ISystemConfig _systemConfig, + ISuperchainConfig _superchainConfig ) public initializer @@ -222,8 +228,16 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver { /// Used internally by the ResourceMetering contract. /// The SystemConfig is the source of truth for the resource config. /// @return ResourceMetering ResourceConfig - function _resourceConfig() internal view override returns (ResourceMetering.ResourceConfig memory) { - return systemConfig.resourceConfig(); + function _resourceConfig() internal view override returns (ResourceConfig memory) { + IResourceMetering.ResourceConfig memory config = systemConfig.resourceConfig(); + return ResourceConfig({ + maxResourceLimit: config.maxResourceLimit, + elasticityMultiplier: config.elasticityMultiplier, + baseFeeMaxChangeDenominator: config.baseFeeMaxChangeDenominator, + minimumBaseFee: config.minimumBaseFee, + systemTxMaxGas: config.systemTxMaxGas, + maximumBaseFee: config.maximumBaseFee + }); } /// @notice Proves a withdrawal transaction. diff --git a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol index ea1c4b602512..ad47652919c2 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol @@ -1,27 +1,32 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Contracts import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; +import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { L1Block } from "src/L2/L1Block.sol"; + +// Libraries +import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { SafeCall } from "src/libraries/SafeCall.sol"; -import { DisputeGameFactory, IDisputeGame } from "src/dispute/DisputeGameFactory.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { Constants } from "src/libraries/Constants.sol"; import { Types } from "src/libraries/Types.sol"; import { Hashing } from "src/libraries/Hashing.sol"; import { SecureMerkleTrie } from "src/libraries/trie/SecureMerkleTrie.sol"; -import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; -import { ResourceMetering } from "src/L1/ResourceMetering.sol"; -import { ISemver } from "src/universal/interfaces/ISemver.sol"; -import { Constants } from "src/libraries/Constants.sol"; -import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { L1Block } from "src/L2/L1Block.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; - +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import "src/libraries/PortalErrors.sol"; import "src/dispute/lib/Types.sol"; +// Interfaces +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; +import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol"; +import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; + /// @custom:proxied true /// @title OptimismPortal2 /// @notice The OptimismPortal is a low-level contract responsible for passing messages between L1 @@ -74,7 +79,7 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { bool private spacer_53_0_1; /// @notice Contract of the Superchain Config. - SuperchainConfig public superchainConfig; + ISuperchainConfig public superchainConfig; /// @custom:legacy /// @custom:spacer l2Oracle @@ -83,11 +88,11 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { /// @notice Contract of the SystemConfig. /// @custom:network-specific - SystemConfig public systemConfig; + ISystemConfig public systemConfig; /// @notice Address of the DisputeGameFactory. /// @custom:network-specific - DisputeGameFactory public disputeGameFactory; + IDisputeGameFactory public disputeGameFactory; /// @notice A mapping of withdrawal hashes to proof submitters to `ProvenWithdrawal` data. mapping(bytes32 => mapping(address => ProvenWithdrawal)) public provenWithdrawals; @@ -164,9 +169,9 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { DISPUTE_GAME_FINALITY_DELAY_SECONDS = _disputeGameFinalityDelaySeconds; initialize({ - _disputeGameFactory: DisputeGameFactory(address(0)), - _systemConfig: SystemConfig(address(0)), - _superchainConfig: SuperchainConfig(address(0)), + _disputeGameFactory: IDisputeGameFactory(address(0)), + _systemConfig: ISystemConfig(address(0)), + _superchainConfig: ISuperchainConfig(address(0)), _initialRespectedGameType: GameType.wrap(0) }); } @@ -176,9 +181,9 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { /// @param _systemConfig Contract of the SystemConfig. /// @param _superchainConfig Contract of the SuperchainConfig. function initialize( - DisputeGameFactory _disputeGameFactory, - SystemConfig _systemConfig, - SuperchainConfig _superchainConfig, + IDisputeGameFactory _disputeGameFactory, + ISystemConfig _systemConfig, + ISuperchainConfig _superchainConfig, GameType _initialRespectedGameType ) public @@ -271,9 +276,12 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { /// @notice Getter for the resource config. /// Used internally by the ResourceMetering contract. /// The SystemConfig is the source of truth for the resource config. - /// @return ResourceMetering ResourceConfig - function _resourceConfig() internal view override returns (ResourceMetering.ResourceConfig memory) { - return systemConfig.resourceConfig(); + /// @return config_ ResourceMetering ResourceConfig + function _resourceConfig() internal view override returns (ResourceMetering.ResourceConfig memory config_) { + IResourceMetering.ResourceConfig memory config = systemConfig.resourceConfig(); + assembly ("memory-safe") { + config_ := config + } } /// @notice Proves a withdrawal transaction. diff --git a/packages/contracts-bedrock/src/L1/OptimismPortalInterop.sol b/packages/contracts-bedrock/src/L1/OptimismPortalInterop.sol index ffbb1afefa5a..fd33c5286ebd 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortalInterop.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortalInterop.sol @@ -1,10 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Contracts import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; import { L1BlockIsthmus, ConfigType } from "src/L2/L1BlockIsthmus.sol"; + +// Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; import { Constants } from "src/libraries/Constants.sol"; +import "src/libraries/PortalErrors.sol"; /// @custom:proxied true /// @title OptimismPortalInterop @@ -12,9 +16,6 @@ import { Constants } from "src/libraries/Constants.sol"; /// and L2. Messages sent directly to the OptimismPortal have no form of replayability. /// Users are encouraged to use the L1CrossDomainMessenger for a higher-level interface. contract OptimismPortalInterop is OptimismPortal2 { - /// @notice Thrown when a non-depositor account attempts update static configuration. - error Unauthorized(); - constructor( uint256 _proofMaturityDelaySeconds, uint256 _disputeGameFinalityDelaySeconds diff --git a/packages/contracts-bedrock/src/L1/ResourceMetering.sol b/packages/contracts-bedrock/src/L1/ResourceMetering.sol index feeabe14ee17..196a1573d7e4 100644 --- a/packages/contracts-bedrock/src/L1/ResourceMetering.sol +++ b/packages/contracts-bedrock/src/L1/ResourceMetering.sol @@ -1,7 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Contracts import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; + +// Libraries import { Math } from "@openzeppelin/contracts/utils/math/Math.sol"; import { Burn } from "src/libraries/Burn.sol"; import { Arithmetic } from "src/libraries/Arithmetic.sol"; diff --git a/packages/contracts-bedrock/src/L1/SystemConfig.sol b/packages/contracts-bedrock/src/L1/SystemConfig.sol index d1dc30fb75ec..032cb3227984 100644 --- a/packages/contracts-bedrock/src/L1/SystemConfig.sol +++ b/packages/contracts-bedrock/src/L1/SystemConfig.sol @@ -1,14 +1,19 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Contracts import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import { ISemver } from "src/universal/interfaces/ISemver.sol"; -import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +// Libraries import { Storage } from "src/libraries/Storage.sol"; import { Constants } from "src/libraries/Constants.sol"; -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; import { GasPayingToken, IGasToken } from "src/libraries/GasPayingToken.sol"; -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +// Interfaces +import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; /// @custom:proxied true /// @title SystemConfig @@ -116,7 +121,7 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { /// @notice The configuration for the deposit fee market. /// Used by the OptimismPortal to meter the cost of buying L2 gas on L1. /// Set as internal with a getter so that the struct is returned instead of a tuple. - ResourceMetering.ResourceConfig internal _resourceConfig; + IResourceMetering.ResourceConfig internal _resourceConfig; /// @notice Emitted when configuration is updated. /// @param version SystemConfig version. @@ -144,7 +149,7 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { _batcherHash: bytes32(0), _gasLimit: 1, _unsafeBlockSigner: address(0), - _config: ResourceMetering.ResourceConfig({ + _config: IResourceMetering.ResourceConfig({ maxResourceLimit: 1, elasticityMultiplier: 1, baseFeeMaxChangeDenominator: 2, @@ -184,7 +189,7 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { bytes32 _batcherHash, uint64 _gasLimit, address _unsafeBlockSigner, - ResourceMetering.ResourceConfig memory _config, + IResourceMetering.ResourceConfig memory _config, address _batchInbox, SystemConfig.Addresses memory _addresses ) @@ -318,7 +323,7 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { // Set the gas paying token in storage and in the OptimismPortal. GasPayingToken.set({ _token: _token, _decimals: GAS_PAYING_TOKEN_DECIMALS, _name: name, _symbol: symbol }); - OptimismPortal(payable(optimismPortal())).setGasPayingToken({ + IOptimismPortal(payable(optimismPortal())).setGasPayingToken({ _token: _token, _decimals: GAS_PAYING_TOKEN_DECIMALS, _name: name, @@ -433,7 +438,7 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { /// @notice A getter for the resource config. /// Ensures that the struct is returned instead of a tuple. /// @return ResourceConfig - function resourceConfig() external view returns (ResourceMetering.ResourceConfig memory) { + function resourceConfig() external view returns (IResourceMetering.ResourceConfig memory) { return _resourceConfig; } @@ -442,7 +447,7 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { /// In the future, this method may emit an event that the `op-node` picks up /// for when the resource config is changed. /// @param _config The new resource config. - function _setResourceConfig(ResourceMetering.ResourceConfig memory _config) internal { + function _setResourceConfig(IResourceMetering.ResourceConfig memory _config) internal { // Min base fee must be less than or equal to max base fee. require( _config.minimumBaseFee <= _config.maximumBaseFee, "SystemConfig: min base fee must be less than max base" diff --git a/packages/contracts-bedrock/src/L1/SystemConfigInterop.sol b/packages/contracts-bedrock/src/L1/SystemConfigInterop.sol index 0033bfa54fae..f948459f5e38 100644 --- a/packages/contracts-bedrock/src/L1/SystemConfigInterop.sol +++ b/packages/contracts-bedrock/src/L1/SystemConfigInterop.sol @@ -1,16 +1,21 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Constants } from "src/libraries/Constants.sol"; -import { OptimismPortalInterop as OptimismPortal } from "src/L1/OptimismPortalInterop.sol"; -import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; +// Contracts import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { IOptimismPortalInterop as IOptimismPortal } from "src/L1/interfaces/IOptimismPortalInterop.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { ConfigType } from "src/L2/L1BlockIsthmus.sol"; + +// Libraries +import { Constants } from "src/libraries/Constants.sol"; +import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; import { StaticConfig } from "src/libraries/StaticConfig.sol"; -import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { Storage } from "src/libraries/Storage.sol"; +// Interfaces +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; + /// @custom:proxied true /// @title SystemConfigInterop /// @notice The SystemConfig contract is used to manage configuration of an Optimism network. @@ -41,7 +46,7 @@ contract SystemConfigInterop is SystemConfig { bytes32 _batcherHash, uint64 _gasLimit, address _unsafeBlockSigner, - ResourceMetering.ResourceConfig memory _config, + IResourceMetering.ResourceConfig memory _config, address _batchInbox, SystemConfig.Addresses memory _addresses, address _dependencyManager @@ -85,7 +90,7 @@ contract SystemConfigInterop is SystemConfig { // Set the gas paying token in storage and in the OptimismPortal. GasPayingToken.set({ _token: _token, _decimals: GAS_PAYING_TOKEN_DECIMALS, _name: name, _symbol: symbol }); - OptimismPortal(payable(optimismPortal())).setConfig( + IOptimismPortal(payable(optimismPortal())).setConfig( ConfigType.SET_GAS_PAYING_TOKEN, StaticConfig.encodeSetGasPayingToken({ _token: _token, @@ -101,7 +106,7 @@ contract SystemConfigInterop is SystemConfig { /// @param _chainId Chain ID of chain to add. function addDependency(uint256 _chainId) external { require(msg.sender == dependencyManager(), "SystemConfig: caller is not the dependency manager"); - OptimismPortal(payable(optimismPortal())).setConfig( + IOptimismPortal(payable(optimismPortal())).setConfig( ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId) ); } @@ -110,7 +115,7 @@ contract SystemConfigInterop is SystemConfig { /// @param _chainId Chain ID of the chain to remove. function removeDependency(uint256 _chainId) external { require(msg.sender == dependencyManager(), "SystemConfig: caller is not the dependency manager"); - OptimismPortal(payable(optimismPortal())).setConfig( + IOptimismPortal(payable(optimismPortal())).setConfig( ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(_chainId) ); } diff --git a/packages/contracts-bedrock/src/L1/interfaces/IDataAvailabilityChallenge.sol b/packages/contracts-bedrock/src/L1/interfaces/IDataAvailabilityChallenge.sol new file mode 100644 index 000000000000..5d89c2dac19c --- /dev/null +++ b/packages/contracts-bedrock/src/L1/interfaces/IDataAvailabilityChallenge.sol @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +enum ChallengeStatus { + Uninitialized, + Active, + Resolved, + Expired +} + +enum CommitmentType { + Keccak256 +} + +struct Challenge { + address challenger; + uint256 lockedBond; + uint256 startBlock; + uint256 resolvedBlock; +} + +interface IDataAvailabilityChallenge { + error BondTooLow(uint256 balance, uint256 required); + error ChallengeExists(); + error ChallengeNotActive(); + error ChallengeNotExpired(); + error ChallengeWindowNotOpen(); + error InvalidCommitmentLength(uint8 commitmentType, uint256 expectedLength, uint256 actualLength); + error InvalidInputData(bytes providedDataCommitment, bytes expectedCommitment); + error InvalidResolverRefundPercentage(uint256 invalidResolverRefundPercentage); + error UnknownCommitmentType(uint8 commitmentType); + error WithdrawalFailed(); + + event BalanceChanged(address account, uint256 balance); + event ChallengeStatusChanged( + uint256 indexed challengedBlockNumber, bytes challengedCommitment, ChallengeStatus status + ); + event Initialized(uint8 version); + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + event RequiredBondSizeChanged(uint256 challengeWindow); + event ResolverRefundPercentageChanged(uint256 resolverRefundPercentage); + + receive() external payable; + + function balances(address) external view returns (uint256); + function bondSize() external view returns (uint256); + function challenge(uint256 challengedBlockNumber, bytes memory challengedCommitment) external payable; + function challengeWindow() external view returns (uint256); + function deposit() external payable; + function fixedResolutionCost() external view returns (uint256); + function getChallenge( + uint256 challengedBlockNumber, + bytes memory challengedCommitment + ) + external + view + returns (Challenge memory); + function getChallengeStatus( + uint256 challengedBlockNumber, + bytes memory challengedCommitment + ) + external + view + returns (ChallengeStatus); + function initialize( + address _owner, + uint256 _challengeWindow, + uint256 _resolveWindow, + uint256 _bondSize, + uint256 _resolverRefundPercentage + ) + external; + function owner() external view returns (address); + function renounceOwnership() external; + function resolve( + uint256 challengedBlockNumber, + bytes memory challengedCommitment, + bytes memory resolveData + ) + external; + function resolveWindow() external view returns (uint256); + function resolverRefundPercentage() external view returns (uint256); + function setBondSize(uint256 _bondSize) external; + function setResolverRefundPercentage(uint256 _resolverRefundPercentage) external; + function transferOwnership(address newOwner) external; + function unlockBond(uint256 challengedBlockNumber, bytes memory challengedCommitment) external; + function validateCommitment(bytes memory commitment) external pure; + function variableResolutionCost() external view returns (uint256); + function variableResolutionCostPrecision() external view returns (uint256); + function version() external view returns (string memory); + function withdraw() external; +} diff --git a/packages/contracts-bedrock/src/L1/interfaces/IDelayedVetoable.sol b/packages/contracts-bedrock/src/L1/interfaces/IDelayedVetoable.sol new file mode 100644 index 000000000000..08e7b30ca6a1 --- /dev/null +++ b/packages/contracts-bedrock/src/L1/interfaces/IDelayedVetoable.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IDelayedVetoable { + error ForwardingEarly(); + error Unauthorized(address expected, address actual); + + event DelayActivated(uint256 delay); + event Forwarded(bytes32 indexed callHash, bytes data); + event Initiated(bytes32 indexed callHash, bytes data); + event Vetoed(bytes32 indexed callHash, bytes data); + + fallback() external; + + function delay() external returns (uint256 delay_); + function initiator() external returns (address initiator_); + function queuedAt(bytes32 callHash) external returns (uint256 queuedAt_); + function target() external returns (address target_); + function version() external view returns (string memory); + function vetoer() external returns (address vetoer_); +} diff --git a/packages/contracts-bedrock/src/L1/interfaces/IL1CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L1/interfaces/IL1CrossDomainMessenger.sol new file mode 100644 index 000000000000..85478cfa257b --- /dev/null +++ b/packages/contracts-bedrock/src/L1/interfaces/IL1CrossDomainMessenger.sol @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; +import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; + +interface IL1CrossDomainMessenger { + event FailedRelayedMessage(bytes32 indexed msgHash); + event Initialized(uint8 version); + event RelayedMessage(bytes32 indexed msgHash); + event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit); + event SentMessageExtension1(address indexed sender, uint256 value); + + function MESSAGE_VERSION() external view returns (uint16); + function MIN_GAS_CALLDATA_OVERHEAD() external view returns (uint64); + function MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR() external view returns (uint64); + function MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR() external view returns (uint64); + function OTHER_MESSENGER() external view returns (address); + function PORTAL() external view returns (address); + function RELAY_CALL_OVERHEAD() external view returns (uint64); + function RELAY_CONSTANT_OVERHEAD() external view returns (uint64); + function RELAY_GAS_CHECK_BUFFER() external view returns (uint64); + function RELAY_RESERVED_GAS() external view returns (uint64); + function baseGas(bytes memory _message, uint32 _minGasLimit) external pure returns (uint64); + function failedMessages(bytes32) external view returns (bool); + function initialize( + ISuperchainConfig _superchainConfig, + IOptimismPortal _portal, + ISystemConfig _systemConfig + ) + external; + function messageNonce() external view returns (uint256); + function otherMessenger() external view returns (address); + function paused() external view returns (bool); + function portal() external view returns (address); + function relayMessage( + uint256 _nonce, + address _sender, + address _target, + uint256 _value, + uint256 _minGasLimit, + bytes memory _message + ) + external + payable; + function sendMessage(address _target, bytes memory _message, uint32 _minGasLimit) external payable; + function successfulMessages(bytes32) external view returns (bool); + function superchainConfig() external view returns (address); + function systemConfig() external view returns (address); + function version() external view returns (string memory); + function xDomainMessageSender() external view returns (address); +} diff --git a/packages/contracts-bedrock/src/L1/interfaces/IOptimismPortal.sol b/packages/contracts-bedrock/src/L1/interfaces/IOptimismPortal.sol new file mode 100644 index 000000000000..e80bad00b910 --- /dev/null +++ b/packages/contracts-bedrock/src/L1/interfaces/IOptimismPortal.sol @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { Types } from "src/libraries/Types.sol"; +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; +import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; + +interface IOptimismPortal { + error BadTarget(); + error CallPaused(); + error ContentLengthMismatch(); + error EmptyItem(); + error GasEstimation(); + error InvalidDataRemainder(); + error InvalidHeader(); + error LargeCalldata(); + error NoValue(); + error NonReentrant(); + error OnlyCustomGasToken(); + error OutOfGas(); + error SmallGasLimit(); + error TransferFailed(); + error Unauthorized(); + error UnexpectedList(); + error UnexpectedString(); + + event Initialized(uint8 version); + event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData); + event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success); + event WithdrawalProven(bytes32 indexed withdrawalHash, address indexed from, address indexed to); + + receive() external payable; + + function balance() external view returns (uint256); + function depositERC20Transaction( + address _to, + uint256 _mint, + uint256 _value, + uint64 _gasLimit, + bool _isCreation, + bytes memory _data + ) + external; + function depositTransaction( + address _to, + uint256 _value, + uint64 _gasLimit, + bool _isCreation, + bytes memory _data + ) + external + payable; + function donateETH() external payable; + function finalizeWithdrawalTransaction(Types.WithdrawalTransaction memory _tx) external; + function finalizedWithdrawals(bytes32) external view returns (bool); + function guardian() external view returns (address); + function initialize( + IL2OutputOracle _l2Oracle, + ISystemConfig _systemConfig, + ISuperchainConfig _superchainConfig + ) + external; + function isOutputFinalized(uint256 _l2OutputIndex) external view returns (bool); + function l2Oracle() external view returns (IL2OutputOracle); + function l2Sender() external view returns (address); + function minimumGasLimit(uint64 _byteCount) external pure returns (uint64); + function params() external view returns (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum); + function paused() external view returns (bool paused_); + function proveWithdrawalTransaction( + Types.WithdrawalTransaction memory _tx, + uint256 _l2OutputIndex, + Types.OutputRootProof memory _outputRootProof, + bytes[] memory _withdrawalProof + ) + external; + function provenWithdrawals(bytes32) + external + view + returns (bytes32 outputRoot, uint128 timestamp, uint128 l2OutputIndex); + function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external; + function superchainConfig() external view returns (ISuperchainConfig); + function systemConfig() external view returns (ISystemConfig); + function version() external pure returns (string memory); +} diff --git a/packages/contracts-bedrock/src/L1/interfaces/IOptimismPortal2.sol b/packages/contracts-bedrock/src/L1/interfaces/IOptimismPortal2.sol new file mode 100644 index 000000000000..2060b2088247 --- /dev/null +++ b/packages/contracts-bedrock/src/L1/interfaces/IOptimismPortal2.sol @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { Types } from "src/libraries/Types.sol"; +import { GameType, Timestamp } from "src/dispute/lib/LibUDT.sol"; +import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; +import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol"; +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; + +interface IOptimismPortal2 { + error AlreadyFinalized(); + error BadTarget(); + error Blacklisted(); + error CallPaused(); + error ContentLengthMismatch(); + error EmptyItem(); + error GasEstimation(); + error InvalidDataRemainder(); + error InvalidDisputeGame(); + error InvalidGameType(); + error InvalidHeader(); + error InvalidMerkleProof(); + error InvalidProof(); + error LargeCalldata(); + error NoValue(); + error NonReentrant(); + error OnlyCustomGasToken(); + error OutOfGas(); + error ProposalNotValidated(); + error SmallGasLimit(); + error TransferFailed(); + error Unauthorized(); + error UnexpectedList(); + error UnexpectedString(); + error Unproven(); + + event DisputeGameBlacklisted(IDisputeGame indexed disputeGame); + event Initialized(uint8 version); + event RespectedGameTypeSet(GameType indexed newGameType, Timestamp indexed updatedAt); + event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData); + event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success); + event WithdrawalProven(bytes32 indexed withdrawalHash, address indexed from, address indexed to); + event WithdrawalProvenExtension1(bytes32 indexed withdrawalHash, address indexed proofSubmitter); + + receive() external payable; + + function balance() external view returns (uint256); + function blacklistDisputeGame(IDisputeGame _disputeGame) external; + function checkWithdrawal(bytes32 _withdrawalHash, address _proofSubmitter) external view; + function depositERC20Transaction( + address _to, + uint256 _mint, + uint256 _value, + uint64 _gasLimit, + bool _isCreation, + bytes memory _data + ) + external; + function depositTransaction( + address _to, + uint256 _value, + uint64 _gasLimit, + bool _isCreation, + bytes memory _data + ) + external + payable; + function disputeGameBlacklist(IDisputeGame) external view returns (bool); + function disputeGameFactory() external view returns (IDisputeGameFactory); + function disputeGameFinalityDelaySeconds() external view returns (uint256); + function donateETH() external payable; + function finalizeWithdrawalTransaction(Types.WithdrawalTransaction memory _tx) external; + function finalizeWithdrawalTransactionExternalProof( + Types.WithdrawalTransaction memory _tx, + address _proofSubmitter + ) + external; + function finalizedWithdrawals(bytes32) external view returns (bool); + function guardian() external view returns (address); + function initialize( + IDisputeGameFactory _disputeGameFactory, + ISystemConfig _systemConfig, + ISuperchainConfig _superchainConfig, + GameType _initialRespectedGameType + ) + external; + function l2Sender() external view returns (address); + function minimumGasLimit(uint64 _byteCount) external pure returns (uint64); + function numProofSubmitters(bytes32 _withdrawalHash) external view returns (uint256); + function params() external view returns (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum); + function paused() external view returns (bool); + function proofMaturityDelaySeconds() external view returns (uint256); + function proofSubmitters(bytes32, uint256) external view returns (address); + function proveWithdrawalTransaction( + Types.WithdrawalTransaction memory _tx, + uint256 _disputeGameIndex, + Types.OutputRootProof memory _outputRootProof, + bytes[] memory _withdrawalProof + ) + external; + function provenWithdrawals( + bytes32, + address + ) + external + view + returns (IDisputeGame disputeGameProxy, uint64 timestamp); + function respectedGameType() external view returns (GameType); + function respectedGameTypeUpdatedAt() external view returns (uint64); + function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external; + function setRespectedGameType(GameType _gameType) external; + function superchainConfig() external view returns (ISuperchainConfig); + function systemConfig() external view returns (ISystemConfig); + function version() external pure returns (string memory); +} diff --git a/packages/contracts-bedrock/src/L1/interfaces/IOptimismPortalInterop.sol b/packages/contracts-bedrock/src/L1/interfaces/IOptimismPortalInterop.sol new file mode 100644 index 000000000000..0102b3462ed1 --- /dev/null +++ b/packages/contracts-bedrock/src/L1/interfaces/IOptimismPortalInterop.sol @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { Types } from "src/libraries/Types.sol"; +import { GameType, Timestamp } from "src/dispute/lib/LibUDT.sol"; +import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; +import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol"; +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; +import { ConfigType } from "src/L2/L1BlockIsthmus.sol"; + +interface IOptimismPortalInterop { + error AlreadyFinalized(); + error BadTarget(); + error Blacklisted(); + error CallPaused(); + error ContentLengthMismatch(); + error EmptyItem(); + error GasEstimation(); + error InvalidDataRemainder(); + error InvalidDisputeGame(); + error InvalidGameType(); + error InvalidHeader(); + error InvalidMerkleProof(); + error InvalidProof(); + error LargeCalldata(); + error NoValue(); + error NonReentrant(); + error OnlyCustomGasToken(); + error OutOfGas(); + error ProposalNotValidated(); + error SmallGasLimit(); + error TransferFailed(); + error Unauthorized(); + error UnexpectedList(); + error UnexpectedString(); + error Unproven(); + + event DisputeGameBlacklisted(IDisputeGame indexed disputeGame); + event Initialized(uint8 version); + event RespectedGameTypeSet(GameType indexed newGameType, Timestamp indexed updatedAt); + event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData); + event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success); + event WithdrawalProven(bytes32 indexed withdrawalHash, address indexed from, address indexed to); + event WithdrawalProvenExtension1(bytes32 indexed withdrawalHash, address indexed proofSubmitter); + + receive() external payable; + + function balance() external view returns (uint256); + function blacklistDisputeGame(IDisputeGame _disputeGame) external; + function checkWithdrawal(bytes32 _withdrawalHash, address _proofSubmitter) external view; + function depositERC20Transaction( + address _to, + uint256 _mint, + uint256 _value, + uint64 _gasLimit, + bool _isCreation, + bytes memory _data + ) + external; + function depositTransaction( + address _to, + uint256 _value, + uint64 _gasLimit, + bool _isCreation, + bytes memory _data + ) + external + payable; + function disputeGameBlacklist(IDisputeGame) external view returns (bool); + function disputeGameFactory() external view returns (IDisputeGameFactory); + function disputeGameFinalityDelaySeconds() external view returns (uint256); + function donateETH() external payable; + function finalizeWithdrawalTransaction(Types.WithdrawalTransaction memory _tx) external; + function finalizeWithdrawalTransactionExternalProof( + Types.WithdrawalTransaction memory _tx, + address _proofSubmitter + ) + external; + function finalizedWithdrawals(bytes32) external view returns (bool); + function guardian() external view returns (address); + function initialize( + IDisputeGameFactory _disputeGameFactory, + ISystemConfig _systemConfig, + ISuperchainConfig _superchainConfig, + GameType _initialRespectedGameType + ) + external; + function l2Sender() external view returns (address); + function minimumGasLimit(uint64 _byteCount) external pure returns (uint64); + function numProofSubmitters(bytes32 _withdrawalHash) external view returns (uint256); + function params() external view returns (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum); + function paused() external view returns (bool); + function proofMaturityDelaySeconds() external view returns (uint256); + function proofSubmitters(bytes32, uint256) external view returns (address); + function proveWithdrawalTransaction( + Types.WithdrawalTransaction memory _tx, + uint256 _disputeGameIndex, + Types.OutputRootProof memory _outputRootProof, + bytes[] memory _withdrawalProof + ) + external; + function provenWithdrawals( + bytes32, + address + ) + external + view + returns (IDisputeGame disputeGameProxy, uint64 timestamp); + function respectedGameType() external view returns (GameType); + function respectedGameTypeUpdatedAt() external view returns (uint64); + function setConfig(ConfigType _type, bytes memory _value) external; + function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external; + function setRespectedGameType(GameType _gameType) external; + function superchainConfig() external view returns (ISuperchainConfig); + function systemConfig() external view returns (ISystemConfig); + function version() external pure returns (string memory); +} diff --git a/packages/contracts-bedrock/src/L1/interfaces/IResourceMetering.sol b/packages/contracts-bedrock/src/L1/interfaces/IResourceMetering.sol new file mode 100644 index 000000000000..4a4ccc133bb8 --- /dev/null +++ b/packages/contracts-bedrock/src/L1/interfaces/IResourceMetering.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IResourceMetering { + struct ResourceParams { + uint128 prevBaseFee; + uint64 prevBoughtGas; + uint64 prevBlockNum; + } + + struct ResourceConfig { + uint32 maxResourceLimit; + uint8 elasticityMultiplier; + uint8 baseFeeMaxChangeDenominator; + uint32 minimumBaseFee; + uint32 systemTxMaxGas; + uint128 maximumBaseFee; + } + + error OutOfGas(); + + event Initialized(uint8 version); + + function params() external view returns (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum); +} diff --git a/packages/contracts-bedrock/src/L1/interfaces/ISuperchainConfig.sol b/packages/contracts-bedrock/src/L1/interfaces/ISuperchainConfig.sol new file mode 100644 index 000000000000..d30c0e074f59 --- /dev/null +++ b/packages/contracts-bedrock/src/L1/interfaces/ISuperchainConfig.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface ISuperchainConfig { + enum UpdateType { + GUARDIAN + } + + event ConfigUpdate(UpdateType indexed updateType, bytes data); + event Initialized(uint8 version); + event Paused(string identifier); + event Unpaused(); + + function GUARDIAN_SLOT() external view returns (bytes32); + function PAUSED_SLOT() external view returns (bytes32); + function guardian() external view returns (address guardian_); + function initialize(address _guardian, bool _paused) external; + function pause(string memory _identifier) external; + function paused() external view returns (bool paused_); + function unpause() external; + function version() external view returns (string memory); +} diff --git a/packages/contracts-bedrock/src/L1/interfaces/ISystemConfig.sol b/packages/contracts-bedrock/src/L1/interfaces/ISystemConfig.sol new file mode 100644 index 000000000000..fa4a597df307 --- /dev/null +++ b/packages/contracts-bedrock/src/L1/interfaces/ISystemConfig.sol @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; + +interface ISystemConfig { + enum UpdateType { + BATCHER, + GAS_CONFIG, + GAS_LIMIT, + UNSAFE_BLOCK_SIGNER + } + + struct Addresses { + address l1CrossDomainMessenger; + address l1ERC721Bridge; + address l1StandardBridge; + address disputeGameFactory; + address optimismPortal; + address optimismMintableERC20Factory; + address gasPayingToken; + } + + event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data); + event Initialized(uint8 version); + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + function BATCH_INBOX_SLOT() external view returns (bytes32); + function DISPUTE_GAME_FACTORY_SLOT() external view returns (bytes32); + function L1_CROSS_DOMAIN_MESSENGER_SLOT() external view returns (bytes32); + function L1_ERC_721_BRIDGE_SLOT() external view returns (bytes32); + function L1_STANDARD_BRIDGE_SLOT() external view returns (bytes32); + function OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT() external view returns (bytes32); + function OPTIMISM_PORTAL_SLOT() external view returns (bytes32); + function START_BLOCK_SLOT() external view returns (bytes32); + function UNSAFE_BLOCK_SIGNER_SLOT() external view returns (bytes32); + function VERSION() external view returns (uint256); + function basefeeScalar() external view returns (uint32); + function batchInbox() external view returns (address addr_); + function batcherHash() external view returns (bytes32); + function blobbasefeeScalar() external view returns (uint32); + function disputeGameFactory() external view returns (address addr_); + function gasLimit() external view returns (uint64); + function gasPayingToken() external view returns (address addr_, uint8 decimals_); + function gasPayingTokenName() external view returns (string memory name_); + function gasPayingTokenSymbol() external view returns (string memory symbol_); + function initialize( + address _owner, + uint32 _basefeeScalar, + uint32 _blobbasefeeScalar, + bytes32 _batcherHash, + uint64 _gasLimit, + address _unsafeBlockSigner, + IResourceMetering.ResourceConfig memory _config, + address _batchInbox, + Addresses memory _addresses + ) + external; + function isCustomGasToken() external view returns (bool); + function l1CrossDomainMessenger() external view returns (address addr_); + function l1ERC721Bridge() external view returns (address addr_); + function l1StandardBridge() external view returns (address addr_); + function maximumGasLimit() external pure returns (uint64); + function minimumGasLimit() external view returns (uint64); + function optimismMintableERC20Factory() external view returns (address addr_); + function optimismPortal() external view returns (address addr_); + function overhead() external view returns (uint256); + function owner() external view returns (address); + function renounceOwnership() external; + function resourceConfig() external view returns (IResourceMetering.ResourceConfig memory); + function scalar() external view returns (uint256); + function setBatcherHash(bytes32 _batcherHash) external; + function setGasConfig(uint256 _overhead, uint256 _scalar) external; + function setGasConfigEcotone(uint32 _basefeeScalar, uint32 _blobbasefeeScalar) external; + function setGasLimit(uint64 _gasLimit) external; + function setUnsafeBlockSigner(address _unsafeBlockSigner) external; + function startBlock() external view returns (uint256 startBlock_); + function transferOwnership(address newOwner) external; + function unsafeBlockSigner() external view returns (address addr_); + function version() external pure returns (string memory); +} diff --git a/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol b/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol index 66fa24c3ef49..3ff30e8b7272 100644 --- a/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol +++ b/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol @@ -5,7 +5,7 @@ import { ERC721Bridge } from "src/universal/ERC721Bridge.sol"; import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; import { IOptimismMintableERC721 } from "src/universal/interfaces/IOptimismMintableERC721.sol"; -import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { Constants } from "src/libraries/Constants.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; @@ -34,7 +34,7 @@ contract L2ERC721Bridge is ERC721Bridge, ISemver { /// @param _l1ERC721Bridge Address of the ERC721 bridge contract on the other network. function initialize(address payable _l1ERC721Bridge) public initializer { __ERC721Bridge_init({ - _messenger: CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER), + _messenger: ICrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER), _otherBridge: ERC721Bridge(_l1ERC721Bridge) }); } diff --git a/packages/contracts-bedrock/src/L2/L2StandardBridge.sol b/packages/contracts-bedrock/src/L2/L2StandardBridge.sol index 4ba8c62f863c..063ee398f770 100644 --- a/packages/contracts-bedrock/src/L2/L2StandardBridge.sol +++ b/packages/contracts-bedrock/src/L2/L2StandardBridge.sol @@ -5,7 +5,7 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; -import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; import { L1Block } from "src/L2/L1Block.sol"; /// @custom:proxied true @@ -67,7 +67,7 @@ contract L2StandardBridge is StandardBridge, ISemver { /// @param _otherBridge Contract for the corresponding bridge on the other chain. function initialize(StandardBridge _otherBridge) public initializer { __StandardBridge_init({ - _messenger: CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER), + _messenger: ICrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER), _otherBridge: _otherBridge }); } diff --git a/packages/contracts-bedrock/src/Safe/DeputyGuardianModule.sol b/packages/contracts-bedrock/src/Safe/DeputyGuardianModule.sol index abb3a7aaa9ca..c1ac18fdc0c1 100644 --- a/packages/contracts-bedrock/src/Safe/DeputyGuardianModule.sol +++ b/packages/contracts-bedrock/src/Safe/DeputyGuardianModule.sol @@ -1,19 +1,24 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Safe import { GnosisSafe as Safe } from "safe-contracts/GnosisSafe.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; -import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; -import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; -import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; -import { ISemver } from "src/universal/interfaces/ISemver.sol"; -import { Unauthorized } from "src/libraries/PortalErrors.sol"; +// Contracts import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; +// Libraries +import { Unauthorized } from "src/libraries/PortalErrors.sol"; import "src/dispute/lib/Types.sol"; +// Interfaces +import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; +import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; +import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; + /// @title DeputyGuardianModule /// @notice This module is intended to be enabled on the Security Council Safe, which will own the Guardian role in the /// SuperchainConfig contract. The DeputyGuardianModule should allow a Deputy Guardian to administer any of the @@ -39,7 +44,7 @@ contract DeputyGuardianModule is ISemver { Safe internal immutable SAFE; /// @notice The SuperchainConfig's address - SuperchainConfig internal immutable SUPERCHAIN_CONFIG; + ISuperchainConfig internal immutable SUPERCHAIN_CONFIG; /// @notice The deputy guardian's address address internal immutable DEPUTY_GUARDIAN; @@ -49,7 +54,7 @@ contract DeputyGuardianModule is ISemver { string public constant version = "2.0.1-beta.1"; // Constructor to initialize the Safe and baseModule instances - constructor(Safe _safe, SuperchainConfig _superchainConfig, address _deputyGuardian) { + constructor(Safe _safe, ISuperchainConfig _superchainConfig, address _deputyGuardian) { SAFE = _safe; SUPERCHAIN_CONFIG = _superchainConfig; DEPUTY_GUARDIAN = _deputyGuardian; @@ -63,7 +68,7 @@ contract DeputyGuardianModule is ISemver { /// @notice Getter function for the SuperchainConfig's address /// @return superchainConfig_ The SuperchainConfig's address - function superchainConfig() public view returns (SuperchainConfig superchainConfig_) { + function superchainConfig() public view returns (ISuperchainConfig superchainConfig_) { superchainConfig_ = SUPERCHAIN_CONFIG; } @@ -131,10 +136,10 @@ contract DeputyGuardianModule is ISemver { /// Only the deputy guardian can call this function. /// @param _portal The `OptimismPortal2` contract instance. /// @param _game The `IDisputeGame` contract instance. - function blacklistDisputeGame(OptimismPortal2 _portal, IDisputeGame _game) external { + function blacklistDisputeGame(IOptimismPortal2 _portal, IDisputeGame _game) external { _onlyDeputyGuardian(); - bytes memory data = abi.encodeCall(OptimismPortal2.blacklistDisputeGame, (_game)); + bytes memory data = abi.encodeCall(IOptimismPortal2.blacklistDisputeGame, (_game)); (bool success, bytes memory returnData) = SAFE.execTransactionFromModuleReturnData(address(_portal), 0, data, Enum.Operation.Call); if (!success) { @@ -148,10 +153,10 @@ contract DeputyGuardianModule is ISemver { /// Only the deputy guardian can call this function. /// @param _portal The `OptimismPortal2` contract instance. /// @param _gameType The `GameType` to set as the respected game type. - function setRespectedGameType(OptimismPortal2 _portal, GameType _gameType) external { + function setRespectedGameType(IOptimismPortal2 _portal, GameType _gameType) external { _onlyDeputyGuardian(); - bytes memory data = abi.encodeCall(OptimismPortal2.setRespectedGameType, (_gameType)); + bytes memory data = abi.encodeCall(IOptimismPortal2.setRespectedGameType, (_gameType)); (bool success, bytes memory returnData) = SAFE.execTransactionFromModuleReturnData(address(_portal), 0, data, Enum.Operation.Call); if (!success) { diff --git a/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol b/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol index 9ac81302991a..3425ec2e394b 100644 --- a/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol +++ b/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol @@ -8,7 +8,7 @@ import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistr import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import "src/dispute/lib/Types.sol"; import { Unauthorized } from "src/libraries/errors/CommonErrors.sol"; @@ -38,7 +38,7 @@ contract AnchorStateRegistry is Initializable, IAnchorStateRegistry, ISemver { mapping(GameType => OutputRoot) public anchors; /// @notice Address of the SuperchainConfig contract. - SuperchainConfig public superchainConfig; + ISuperchainConfig public superchainConfig; /// @param _disputeGameFactory DisputeGameFactory address. constructor(IDisputeGameFactory _disputeGameFactory) { @@ -51,7 +51,7 @@ contract AnchorStateRegistry is Initializable, IAnchorStateRegistry, ISemver { /// @param _superchainConfig The address of the SuperchainConfig contract. function initialize( StartingAnchorRoot[] memory _startingAnchorRoots, - SuperchainConfig _superchainConfig + ISuperchainConfig _superchainConfig ) public initializer diff --git a/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol b/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol index 144d8d451798..7945c7f51d5d 100644 --- a/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol +++ b/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol @@ -8,7 +8,7 @@ import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; import { IWETH } from "src/dispute/interfaces/IWETH.sol"; import { WETH98 } from "src/dispute/weth/WETH98.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; /// @custom:proxied true /// @title DelayedWETH @@ -32,18 +32,18 @@ contract DelayedWETH is OwnableUpgradeable, WETH98, IDelayedWETH, ISemver { uint256 internal immutable DELAY_SECONDS; /// @notice Address of the SuperchainConfig contract. - SuperchainConfig public config; + ISuperchainConfig public config; /// @param _delay The delay for withdrawals in seconds. constructor(uint256 _delay) { DELAY_SECONDS = _delay; - initialize({ _owner: address(0), _config: SuperchainConfig(address(0)) }); + initialize({ _owner: address(0), _config: ISuperchainConfig(address(0)) }); } /// @notice Initializes the contract. /// @param _owner The address of the owner. /// @param _config Address of the SuperchainConfig contract. - function initialize(address _owner, SuperchainConfig _config) public initializer { + function initialize(address _owner, ISuperchainConfig _config) public initializer { __Ownable_init(); _transferOwnership(_owner); config = _config; diff --git a/packages/contracts-bedrock/src/libraries/Constants.sol b/packages/contracts-bedrock/src/libraries/Constants.sol index e86010421d34..1cbd61d21a5e 100644 --- a/packages/contracts-bedrock/src/libraries/Constants.sol +++ b/packages/contracts-bedrock/src/libraries/Constants.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; /// @title Constants /// @notice Constants is a library for storing constants. Simple! Don't put everything in here, just @@ -39,8 +39,8 @@ library Constants { /// @notice Returns the default values for the ResourceConfig. These are the recommended values /// for a production network. - function DEFAULT_RESOURCE_CONFIG() internal pure returns (ResourceMetering.ResourceConfig memory) { - ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({ + function DEFAULT_RESOURCE_CONFIG() internal pure returns (IResourceMetering.ResourceConfig memory) { + IResourceMetering.ResourceConfig memory config = IResourceMetering.ResourceConfig({ maxResourceLimit: 20_000_000, elasticityMultiplier: 10, baseFeeMaxChangeDenominator: 8, diff --git a/packages/contracts-bedrock/src/universal/ERC721Bridge.sol b/packages/contracts-bedrock/src/universal/ERC721Bridge.sol index 9c5c325f7184..52217fab713c 100644 --- a/packages/contracts-bedrock/src/universal/ERC721Bridge.sol +++ b/packages/contracts-bedrock/src/universal/ERC721Bridge.sol @@ -1,8 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; import { Address } from "@openzeppelin/contracts/utils/Address.sol"; import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; @@ -15,7 +14,7 @@ abstract contract ERC721Bridge is Initializable { /// @notice Messenger contract on this domain. /// @custom:network-specific - CrossDomainMessenger public messenger; + ICrossDomainMessenger public messenger; /// @notice Contract of the bridge on the other network. /// @custom:network-specific @@ -69,7 +68,7 @@ abstract contract ERC721Bridge is Initializable { /// @param _messenger Contract of the CrossDomainMessenger on this network. /// @param _otherBridge Contract of the ERC721 bridge on the other network. function __ERC721Bridge_init( - CrossDomainMessenger _messenger, + ICrossDomainMessenger _messenger, ERC721Bridge _otherBridge ) internal @@ -83,7 +82,7 @@ abstract contract ERC721Bridge is Initializable { /// Public getter is legacy and will be removed in the future. Use `messenger` instead. /// @return Messenger contract on this domain. /// @custom:legacy - function MESSENGER() external view returns (CrossDomainMessenger) { + function MESSENGER() external view returns (ICrossDomainMessenger) { return messenger; } diff --git a/packages/contracts-bedrock/src/universal/StandardBridge.sol b/packages/contracts-bedrock/src/universal/StandardBridge.sol index 92440fdbad38..476d3ba54c93 100644 --- a/packages/contracts-bedrock/src/universal/StandardBridge.sol +++ b/packages/contracts-bedrock/src/universal/StandardBridge.sol @@ -7,7 +7,7 @@ import { Address } from "@openzeppelin/contracts/utils/Address.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { SafeCall } from "src/libraries/SafeCall.sol"; import { IOptimismMintableERC20, ILegacyMintableERC20 } from "src/universal/interfaces/IOptimismMintableERC20.sol"; -import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import { Constants } from "src/libraries/Constants.sol"; @@ -38,7 +38,7 @@ abstract contract StandardBridge is Initializable { /// @notice Messenger contract on this domain. /// @custom:network-specific - CrossDomainMessenger public messenger; + ICrossDomainMessenger public messenger; /// @notice Corresponding bridge on the other domain. /// @custom:network-specific @@ -116,7 +116,7 @@ abstract contract StandardBridge is Initializable { /// @param _messenger Contract for CrossDomainMessenger on this network. /// @param _otherBridge Contract for the other StandardBridge contract. function __StandardBridge_init( - CrossDomainMessenger _messenger, + ICrossDomainMessenger _messenger, StandardBridge _otherBridge ) internal @@ -143,7 +143,7 @@ abstract contract StandardBridge is Initializable { /// Public getter is legacy and will be removed in the future. Use `messenger` instead. /// @return Contract of the messenger on this domain. /// @custom:legacy - function MESSENGER() external view returns (CrossDomainMessenger) { + function MESSENGER() external view returns (ICrossDomainMessenger) { return messenger; } diff --git a/packages/contracts-bedrock/src/universal/interfaces/ICrossDomainMessenger.sol b/packages/contracts-bedrock/src/universal/interfaces/ICrossDomainMessenger.sol new file mode 100644 index 000000000000..ed2fb20ea453 --- /dev/null +++ b/packages/contracts-bedrock/src/universal/interfaces/ICrossDomainMessenger.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface ICrossDomainMessenger { + event FailedRelayedMessage(bytes32 indexed msgHash); + event Initialized(uint8 version); + event RelayedMessage(bytes32 indexed msgHash); + event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit); + event SentMessageExtension1(address indexed sender, uint256 value); + + function MESSAGE_VERSION() external view returns (uint16); + function MIN_GAS_CALLDATA_OVERHEAD() external view returns (uint64); + function MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR() external view returns (uint64); + function MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR() external view returns (uint64); + function OTHER_MESSENGER() external view returns (ICrossDomainMessenger); + function RELAY_CALL_OVERHEAD() external view returns (uint64); + function RELAY_CONSTANT_OVERHEAD() external view returns (uint64); + function RELAY_GAS_CHECK_BUFFER() external view returns (uint64); + function RELAY_RESERVED_GAS() external view returns (uint64); + function baseGas(bytes memory _message, uint32 _minGasLimit) external pure returns (uint64); + function failedMessages(bytes32) external view returns (bool); + function messageNonce() external view returns (uint256); + function otherMessenger() external view returns (ICrossDomainMessenger); + function paused() external view returns (bool); + function relayMessage( + uint256 _nonce, + address _sender, + address _target, + uint256 _value, + uint256 _minGasLimit, + bytes memory _message + ) + external + payable; + function sendMessage(address _target, bytes memory _message, uint32 _minGasLimit) external payable; + function successfulMessages(bytes32) external view returns (bool); + function xDomainMessageSender() external view returns (address); +} diff --git a/packages/contracts-bedrock/test/BenchmarkTest.t.sol b/packages/contracts-bedrock/test/BenchmarkTest.t.sol index 060ceddcc136..063ed6944946 100644 --- a/packages/contracts-bedrock/test/BenchmarkTest.t.sol +++ b/packages/contracts-bedrock/test/BenchmarkTest.t.sol @@ -1,18 +1,21 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Testing utilities +// Testing import { Test } from "forge-std/Test.sol"; import { Vm } from "forge-std/Vm.sol"; import { CommonTest } from "test/setup/CommonTest.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; -import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { ResourceMetering } from "src/L1/ResourceMetering.sol"; + +// Libraries import { Types } from "src/libraries/Types.sol"; import { SafeCall } from "src/libraries/SafeCall.sol"; import { L1BlockIsthmus } from "src/L2/L1BlockIsthmus.sol"; import { Encoding } from "src/libraries/Encoding.sol"; +// Interfaces +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; + // Free function for setting the prevBaseFee param in the OptimismPortal. function setPrevBaseFee(Vm _vm, address _op, uint128 _prevBaseFee) { _vm.store(address(_op), bytes32(uint256(1)), bytes32((block.number << 192) | _prevBaseFee)); @@ -182,7 +185,7 @@ contract GasBenchMark_L1StandardBridge_Finalize is Bridge_Initializer { deal(address(L1Token), address(l1StandardBridge), 100, true); vm.mockCall( address(l1StandardBridge.messenger()), - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encodeWithSelector(ICrossDomainMessenger.xDomainMessageSender.selector), abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) ); vm.startPrank(address(l1StandardBridge.messenger())); diff --git a/packages/contracts-bedrock/test/ExtendedPause.t.sol b/packages/contracts-bedrock/test/ExtendedPause.t.sol index 93e207ac6e9d..df6e9d39132b 100644 --- a/packages/contracts-bedrock/test/ExtendedPause.t.sol +++ b/packages/contracts-bedrock/test/ExtendedPause.t.sol @@ -2,7 +2,6 @@ pragma solidity 0.8.15; import { CommonTest } from "test/setup/CommonTest.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; /// @dev These tests are somewhat redundant with tests in the SuperchainConfig and other pausable contracts, however /// it is worthwhile to pull them into one location to ensure that the behavior is consistent. diff --git a/packages/contracts-bedrock/test/L1/DataAvailabilityChallenge.t.sol b/packages/contracts-bedrock/test/L1/DataAvailabilityChallenge.t.sol index fd8e82c9320f..584a28d7a189 100644 --- a/packages/contracts-bedrock/test/L1/DataAvailabilityChallenge.t.sol +++ b/packages/contracts-bedrock/test/L1/DataAvailabilityChallenge.t.sol @@ -2,12 +2,12 @@ pragma solidity 0.8.15; import { - DataAvailabilityChallenge, + IDataAvailabilityChallenge, ChallengeStatus, Challenge, - CommitmentType, - computeCommitmentKeccak256 -} from "src/L1/DataAvailabilityChallenge.sol"; + CommitmentType +} from "src/L1/interfaces/IDataAvailabilityChallenge.sol"; +import { computeCommitmentKeccak256 } from "src/L1/DataAvailabilityChallenge.sol"; import { Proxy } from "src/universal/Proxy.sol"; import { CommonTest } from "test/setup/CommonTest.sol"; @@ -145,7 +145,9 @@ contract DataAvailabilityChallengeTest is CommonTest { uint256 actualBond = requiredBond - 1; dataAvailabilityChallenge.deposit{ value: actualBond }(); - vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.BondTooLow.selector, actualBond, requiredBond)); + vm.expectRevert( + abi.encodeWithSelector(IDataAvailabilityChallenge.BondTooLow.selector, actualBond, requiredBond) + ); dataAvailabilityChallenge.challenge(0, computeCommitmentKeccak256("some hash")); } @@ -160,7 +162,7 @@ contract DataAvailabilityChallengeTest is CommonTest { // Second challenge of the same hash/blockNumber fails dataAvailabilityChallenge.deposit{ value: dataAvailabilityChallenge.bondSize() }(); - vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.ChallengeExists.selector)); + vm.expectRevert(abi.encodeWithSelector(IDataAvailabilityChallenge.ChallengeExists.selector)); dataAvailabilityChallenge.challenge(0, challengedCommitment); // Challenge succeed if the challenged block number is different @@ -181,7 +183,7 @@ contract DataAvailabilityChallengeTest is CommonTest { // Challenge fails because the current block number must be after the challenged block dataAvailabilityChallenge.deposit{ value: dataAvailabilityChallenge.bondSize() }(); - vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.ChallengeWindowNotOpen.selector)); + vm.expectRevert(abi.encodeWithSelector(IDataAvailabilityChallenge.ChallengeWindowNotOpen.selector)); dataAvailabilityChallenge.challenge(challengedBlockNumber, challengedCommitment); } @@ -194,7 +196,7 @@ contract DataAvailabilityChallengeTest is CommonTest { // Challenge fails because the block number is after the challenge window dataAvailabilityChallenge.deposit{ value: dataAvailabilityChallenge.bondSize() }(); - vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.ChallengeWindowNotOpen.selector)); + vm.expectRevert(abi.encodeWithSelector(IDataAvailabilityChallenge.ChallengeWindowNotOpen.selector)); dataAvailabilityChallenge.challenge(challengedBlockNumber, challengedCommitment); } @@ -287,7 +289,7 @@ contract DataAvailabilityChallengeTest is CommonTest { vm.roll(challengedBlockNumber + 1); // Resolving a non-existent challenge fails - vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.ChallengeNotActive.selector)); + vm.expectRevert(abi.encodeWithSelector(IDataAvailabilityChallenge.ChallengeNotActive.selector)); dataAvailabilityChallenge.resolve(challengedBlockNumber, computeCommitmentKeccak256(preImage), preImage); } @@ -307,7 +309,7 @@ contract DataAvailabilityChallengeTest is CommonTest { dataAvailabilityChallenge.resolve(challengedBlockNumber, challengedCommitment, preImage); // Resolving an already resolved challenge fails - vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.ChallengeNotActive.selector)); + vm.expectRevert(abi.encodeWithSelector(IDataAvailabilityChallenge.ChallengeNotActive.selector)); dataAvailabilityChallenge.resolve(challengedBlockNumber, challengedCommitment, preImage); } @@ -327,7 +329,7 @@ contract DataAvailabilityChallengeTest is CommonTest { vm.roll(block.number + dataAvailabilityChallenge.resolveWindow() + 1); // Resolving an expired challenge fails - vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.ChallengeNotActive.selector)); + vm.expectRevert(abi.encodeWithSelector(IDataAvailabilityChallenge.ChallengeNotActive.selector)); dataAvailabilityChallenge.resolve(challengedBlockNumber, challengedCommitment, preImage); } @@ -347,7 +349,7 @@ contract DataAvailabilityChallengeTest is CommonTest { vm.roll(block.number + dataAvailabilityChallenge.resolveWindow() + 1); // Resolve the challenge - vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.ChallengeNotActive.selector)); + vm.expectRevert(abi.encodeWithSelector(IDataAvailabilityChallenge.ChallengeNotActive.selector)); dataAvailabilityChallenge.resolve(challengedBlockNumber, challengedCommitment, preImage); } @@ -405,7 +407,7 @@ contract DataAvailabilityChallengeTest is CommonTest { vm.roll(challengedBlockNumber + 1); // Unlock a bond of a non-existent challenge fails - vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.ChallengeNotExpired.selector)); + vm.expectRevert(abi.encodeWithSelector(IDataAvailabilityChallenge.ChallengeNotExpired.selector)); dataAvailabilityChallenge.unlockBond(challengedBlockNumber, challengedCommitment); } @@ -425,7 +427,7 @@ contract DataAvailabilityChallengeTest is CommonTest { dataAvailabilityChallenge.resolve(challengedBlockNumber, challengedCommitment, preImage); // Attempting to unlock a bond of a resolved challenge fails - vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.ChallengeNotExpired.selector)); + vm.expectRevert(abi.encodeWithSelector(IDataAvailabilityChallenge.ChallengeNotExpired.selector)); dataAvailabilityChallenge.unlockBond(challengedBlockNumber, challengedCommitment); } @@ -469,7 +471,7 @@ contract DataAvailabilityChallengeTest is CommonTest { vm.roll(block.number + dataAvailabilityChallenge.resolveWindow() - 1); // Expiring the challenge before the resolve window closes fails - vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.ChallengeNotExpired.selector)); + vm.expectRevert(abi.encodeWithSelector(IDataAvailabilityChallenge.ChallengeNotExpired.selector)); dataAvailabilityChallenge.unlockBond(challengedBlockNumber, challengedCommitment); } @@ -480,7 +482,9 @@ contract DataAvailabilityChallengeTest is CommonTest { // Expect the challenge to fail because the bond is too low bytes memory challengedCommitment = computeCommitmentKeccak256("some hash"); - vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.BondTooLow.selector, actualBond, requiredBond)); + vm.expectRevert( + abi.encodeWithSelector(IDataAvailabilityChallenge.BondTooLow.selector, actualBond, requiredBond) + ); dataAvailabilityChallenge.challenge(0, challengedCommitment); // Reduce the required bond @@ -500,7 +504,9 @@ contract DataAvailabilityChallengeTest is CommonTest { function testSetResolverRefundPercentageFail() public { address owner = dataAvailabilityChallenge.owner(); - vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.InvalidResolverRefundPercentage.selector, 101)); + vm.expectRevert( + abi.encodeWithSelector(IDataAvailabilityChallenge.InvalidResolverRefundPercentage.selector, 101) + ); vm.prank(owner); dataAvailabilityChallenge.setResolverRefundPercentage(101); } @@ -520,13 +526,13 @@ contract DataAvailabilityChallengeTest is CommonTest { dataAvailabilityChallenge.validateCommitment(validCommitment); // Should revert if the commitment type is unknown - vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.UnknownCommitmentType.selector, uint8(1))); + vm.expectRevert(abi.encodeWithSelector(IDataAvailabilityChallenge.UnknownCommitmentType.selector, uint8(1))); bytes memory unknownType = abi.encodePacked(uint8(1), keccak256("test")); dataAvailabilityChallenge.validateCommitment(unknownType); // Should revert if the commitment length does not match vm.expectRevert( - abi.encodeWithSelector(DataAvailabilityChallenge.InvalidCommitmentLength.selector, uint8(0), 33, 34) + abi.encodeWithSelector(IDataAvailabilityChallenge.InvalidCommitmentLength.selector, uint8(0), 33, 34) ); bytes memory invalidLength = abi.encodePacked(CommitmentType.Keccak256, keccak256("test"), "x"); dataAvailabilityChallenge.validateCommitment(invalidLength); diff --git a/packages/contracts-bedrock/test/L1/DelayedVetoable.t.sol b/packages/contracts-bedrock/test/L1/DelayedVetoable.t.sol index 5e67a7ba5cf9..8c35ced064d5 100644 --- a/packages/contracts-bedrock/test/L1/DelayedVetoable.t.sol +++ b/packages/contracts-bedrock/test/L1/DelayedVetoable.t.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; import { DelayedVetoable } from "src/L1/DelayedVetoable.sol"; +import { IDelayedVetoable } from "src/L1/interfaces/IDelayedVetoable.sol"; contract DelayedVetoable_Init is Test { error Unauthorized(address expected, address actual); @@ -16,7 +17,7 @@ contract DelayedVetoable_Init is Test { address initiator; address vetoer; uint256 operatingDelay = 14 days; - DelayedVetoable delayedVetoable; + IDelayedVetoable delayedVetoable; function setUp() public { initiator = makeAddr("initiator"); @@ -25,12 +26,16 @@ contract DelayedVetoable_Init is Test { vm.deal(initiator, 10000 ether); vm.deal(vetoer, 10000 ether); - delayedVetoable = new DelayedVetoable({ - initiator_: initiator, - vetoer_: vetoer, - target_: address(target), - operatingDelay_: operatingDelay - }); + delayedVetoable = IDelayedVetoable( + address( + new DelayedVetoable({ + initiator_: initiator, + vetoer_: vetoer, + target_: address(target), + operatingDelay_: operatingDelay + }) + ) + ); // Most tests will use the operating delay, so we call as the initiator with null data // to set the delay. For tests that need to use the initial zero delay, we'll modify the diff --git a/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol index 3f585f795762..8740c09d38ca 100644 --- a/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol @@ -13,10 +13,10 @@ import { Encoding } from "src/libraries/Encoding.sol"; import { Constants } from "src/libraries/Constants.sol"; // Target contract dependencies -import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { IL1CrossDomainMessenger } from "src/L1/interfaces/IL1CrossDomainMessenger.sol"; +import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; contract L1CrossDomainMessenger_Test is Bridge_Initializer { /// @dev The receiver address @@ -29,7 +29,7 @@ contract L1CrossDomainMessenger_Test is Bridge_Initializer { /// @notice Marked virtual to be overridden in /// test/kontrol/deployment/DeploymentSummary.t.sol function test_constructor_succeeds() external virtual { - L1CrossDomainMessenger impl = L1CrossDomainMessenger(deploy.mustGetAddress("L1CrossDomainMessenger")); + IL1CrossDomainMessenger impl = IL1CrossDomainMessenger(deploy.mustGetAddress("L1CrossDomainMessenger")); assertEq(address(impl.superchainConfig()), address(0)); assertEq(address(impl.PORTAL()), address(0)); assertEq(address(impl.portal()), address(0)); @@ -60,7 +60,7 @@ contract L1CrossDomainMessenger_Test is Bridge_Initializer { vm.expectCall( address(optimismPortal), abi.encodeWithSelector( - OptimismPortal.depositTransaction.selector, + IOptimismPortal.depositTransaction.selector, Predeploys.L2_CROSS_DOMAIN_MESSENGER, 0, l1CrossDomainMessenger.baseGas(hex"ff", 100), @@ -605,7 +605,7 @@ contract L1CrossDomainMessenger_Test is Bridge_Initializer { /// @dev Tests that the superchain config is called by the messengers paused function function test_pause_callsSuperchainConfig_succeeds() external { - vm.expectCall(address(superchainConfig), abi.encodeWithSelector(SuperchainConfig.paused.selector)); + vm.expectCall(address(superchainConfig), abi.encodeWithSelector(ISuperchainConfig.paused.selector)); l1CrossDomainMessenger.paused(); } @@ -632,7 +632,7 @@ contract L1CrossDomainMessenger_Test is Bridge_Initializer { vm.expectCall( address(optimismPortal), abi.encodeWithSelector( - OptimismPortal.depositTransaction.selector, + IOptimismPortal.depositTransaction.selector, Predeploys.L2_CROSS_DOMAIN_MESSENGER, 0, l1CrossDomainMessenger.baseGas(hex"ff", 100), @@ -770,7 +770,7 @@ contract L1CrossDomainMessenger_ReinitReentryTest is Bridge_Initializer { // call the initializer function l1CrossDomainMessenger.initialize( - SuperchainConfig(superchainConfig), OptimismPortal(optimismPortal), SystemConfig(systemConfig) + ISuperchainConfig(superchainConfig), IOptimismPortal(optimismPortal), ISystemConfig(systemConfig) ); // attempt to re-replay the withdrawal diff --git a/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol b/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol index 3c8abcb4843d..ce3d949e333e 100644 --- a/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol +++ b/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol @@ -8,8 +8,8 @@ import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; // Target contract dependencies import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; -import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; // Target contract import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; @@ -323,7 +323,7 @@ contract L1ERC721Bridge_Pause_Test is Bridge_Initializer { /// @dev Ensures that the `paused` function of the bridge contract actually calls the `paused` function of the /// `superchainConfig`. function test_pause_callsSuperchainConfig_succeeds() external { - vm.expectCall(address(superchainConfig), abi.encodeWithSelector(SuperchainConfig.paused.selector)); + vm.expectCall(address(superchainConfig), abi.encodeWithSelector(ISuperchainConfig.paused.selector)); l1ERC721Bridge.paused(); } @@ -352,7 +352,7 @@ contract L1ERC721Bridge_Pause_TestFail is Bridge_Initializer { vm.mockCall( address(l1ERC721Bridge.messenger()), - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encodeWithSelector(ICrossDomainMessenger.xDomainMessageSender.selector), abi.encode(address(l1ERC721Bridge.otherBridge())) ); } diff --git a/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol b/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol index d01fb1c26048..bcba92adf6ba 100644 --- a/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol +++ b/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol @@ -14,20 +14,20 @@ import { Constants } from "src/libraries/Constants.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol"; import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; -import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; // Target contract -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; +import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; contract L1StandardBridge_Getter_Test is Bridge_Initializer { /// @dev Test that the accessors return the correct initialized values. function test_getters_succeeds() external view { assert(l1StandardBridge.l2TokenBridge() == address(l2StandardBridge)); assert(l1StandardBridge.OTHER_BRIDGE() == l2StandardBridge); - assert(l1StandardBridge.messenger() == l1CrossDomainMessenger); - assert(l1StandardBridge.MESSENGER() == l1CrossDomainMessenger); + assert(address(l1StandardBridge.messenger()) == address(l1CrossDomainMessenger)); + assert(address(l1StandardBridge.MESSENGER()) == address(l1CrossDomainMessenger)); assert(l1StandardBridge.superchainConfig() == superchainConfig); assert(l1StandardBridge.systemConfig() == systemConfig); } @@ -70,7 +70,7 @@ contract L1StandardBridge_Pause_Test is Bridge_Initializer { /// @dev Ensures that the `paused` function of the bridge contract actually calls the `paused` function of the /// `superchainConfig`. function test_pause_callsSuperchainConfig_succeeds() external { - vm.expectCall(address(superchainConfig), abi.encodeWithSelector(SuperchainConfig.paused.selector)); + vm.expectCall(address(superchainConfig), abi.encodeWithSelector(ISuperchainConfig.paused.selector)); l1StandardBridge.paused(); } @@ -101,7 +101,7 @@ contract L1StandardBridge_Pause_TestFail is Bridge_Initializer { vm.mockCall( address(l1StandardBridge.messenger()), - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encodeWithSelector(ICrossDomainMessenger.xDomainMessageSender.selector), abi.encode(address(l1StandardBridge.otherBridge())) ); } @@ -176,7 +176,7 @@ contract L1StandardBridge_Receive_Test is Bridge_Initializer { vm.expectCall( address(l1CrossDomainMessenger), abi.encodeWithSelector( - CrossDomainMessenger.sendMessage.selector, + ICrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 100, hex""), 200_000 @@ -235,11 +235,13 @@ contract PreBridgeETH is Bridge_Initializer { vm.expectCall( address(l1CrossDomainMessenger), value, - abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), message, 50000) + abi.encodeWithSelector( + ICrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), message, 50000 + ) ); bytes memory innerMessage = abi.encodeWithSelector( - CrossDomainMessenger.relayMessage.selector, + ICrossDomainMessenger.relayMessage.selector, nonce, address(l1StandardBridge), address(l2StandardBridge), @@ -253,7 +255,7 @@ contract PreBridgeETH is Bridge_Initializer { address(optimismPortal), value, abi.encodeWithSelector( - OptimismPortal.depositTransaction.selector, + IOptimismPortal.depositTransaction.selector, address(l2CrossDomainMessenger), value, baseGas, @@ -375,11 +377,13 @@ contract PreBridgeETHTo is Bridge_Initializer { // L1CrossDomainMessenger.sendMessage vm.expectCall( address(l1CrossDomainMessenger), - abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), message, 60000) + abi.encodeWithSelector( + ICrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), message, 60000 + ) ); bytes memory innerMessage = abi.encodeWithSelector( - CrossDomainMessenger.relayMessage.selector, + ICrossDomainMessenger.relayMessage.selector, nonce, address(l1StandardBridge), address(l2StandardBridge), @@ -392,7 +396,7 @@ contract PreBridgeETHTo is Bridge_Initializer { vm.expectCall( address(optimismPortal), abi.encodeWithSelector( - OptimismPortal.depositTransaction.selector, + IOptimismPortal.depositTransaction.selector, address(l2CrossDomainMessenger), value, baseGas, @@ -527,11 +531,13 @@ contract L1StandardBridge_DepositERC20_Test is Bridge_Initializer { // the L1 bridge should call L1CrossDomainMessenger.sendMessage vm.expectCall( address(l1CrossDomainMessenger), - abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), message, 10000) + abi.encodeWithSelector( + ICrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), message, 10000 + ) ); bytes memory innerMessage = abi.encodeWithSelector( - CrossDomainMessenger.relayMessage.selector, + ICrossDomainMessenger.relayMessage.selector, nonce, address(l1StandardBridge), address(l2StandardBridge), @@ -544,7 +550,7 @@ contract L1StandardBridge_DepositERC20_Test is Bridge_Initializer { vm.expectCall( address(optimismPortal), abi.encodeWithSelector( - OptimismPortal.depositTransaction.selector, + IOptimismPortal.depositTransaction.selector, address(l2CrossDomainMessenger), 0, baseGas, @@ -610,7 +616,7 @@ contract L1StandardBridge_DepositERC20To_Test is Bridge_Initializer { ); bytes memory innerMessage = abi.encodeWithSelector( - CrossDomainMessenger.relayMessage.selector, + ICrossDomainMessenger.relayMessage.selector, nonce, address(l1StandardBridge), address(l2StandardBridge), @@ -649,13 +655,15 @@ contract L1StandardBridge_DepositERC20To_Test is Bridge_Initializer { // the L1 bridge should call L1CrossDomainMessenger.sendMessage vm.expectCall( address(l1CrossDomainMessenger), - abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), message, 10000) + abi.encodeWithSelector( + ICrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), message, 10000 + ) ); // The L1 XDM should call OptimismPortal.depositTransaction vm.expectCall( address(optimismPortal), abi.encodeWithSelector( - OptimismPortal.depositTransaction.selector, + IOptimismPortal.depositTransaction.selector, address(l2CrossDomainMessenger), 0, baseGas, @@ -694,7 +702,7 @@ contract L1StandardBridge_FinalizeETHWithdrawal_Test is Bridge_Initializer { vm.mockCall( address(l1StandardBridge.messenger()), - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encodeWithSelector(ICrossDomainMessenger.xDomainMessageSender.selector), abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) ); // ensure that the messenger has ETH to call with @@ -720,7 +728,7 @@ contract L1StandardBridge_FinalizeETHWithdrawal_TestFail is Bridge_Initializer { ); vm.mockCall( address(l1StandardBridge.messenger()), - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encodeWithSelector(ICrossDomainMessenger.xDomainMessageSender.selector), abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) ); vm.deal(address(l1StandardBridge.messenger()), _value); @@ -759,7 +767,7 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer { vm.mockCall( address(l1StandardBridge.messenger()), - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encodeWithSelector(ICrossDomainMessenger.xDomainMessageSender.selector), abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) ); vm.prank(address(l1StandardBridge.messenger())); @@ -775,7 +783,7 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_TestFail is Bridge_Initializer function test_finalizeERC20Withdrawal_notMessenger_reverts() external { vm.mockCall( address(l1StandardBridge.messenger()), - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encodeWithSelector(ICrossDomainMessenger.xDomainMessageSender.selector), abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) ); vm.prank(address(28)); @@ -787,7 +795,7 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_TestFail is Bridge_Initializer function test_finalizeERC20Withdrawal_notOtherBridge_reverts() external { vm.mockCall( address(l1StandardBridge.messenger()), - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encodeWithSelector(ICrossDomainMessenger.xDomainMessageSender.selector), abi.encode(address(address(0))) ); vm.prank(address(l1StandardBridge.messenger())); @@ -802,7 +810,7 @@ contract L1StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer { address messenger = address(l1StandardBridge.messenger()); vm.mockCall( messenger, - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encodeWithSelector(ICrossDomainMessenger.xDomainMessageSender.selector), abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) ); vm.deal(messenger, 100); @@ -820,7 +828,7 @@ contract L1StandardBridge_FinalizeBridgeETH_TestFail is Bridge_Initializer { function testFuzz_finalizeBridgeETH_customGasToken_reverts(uint256 _value, bytes calldata _extraData) external { vm.mockCall( address(l1StandardBridge.messenger()), - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encodeWithSelector(ICrossDomainMessenger.xDomainMessageSender.selector), abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) ); vm.deal(address(l1CrossDomainMessenger), _value); @@ -838,7 +846,7 @@ contract L1StandardBridge_FinalizeBridgeETH_TestFail is Bridge_Initializer { address messenger = address(l1StandardBridge.messenger()); vm.mockCall( messenger, - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encodeWithSelector(ICrossDomainMessenger.xDomainMessageSender.selector), abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) ); vm.deal(messenger, 100); @@ -852,7 +860,7 @@ contract L1StandardBridge_FinalizeBridgeETH_TestFail is Bridge_Initializer { address messenger = address(l1StandardBridge.messenger()); vm.mockCall( messenger, - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encodeWithSelector(ICrossDomainMessenger.xDomainMessageSender.selector), abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) ); vm.deal(messenger, 100); @@ -866,7 +874,7 @@ contract L1StandardBridge_FinalizeBridgeETH_TestFail is Bridge_Initializer { address messenger = address(l1StandardBridge.messenger()); vm.mockCall( messenger, - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encodeWithSelector(ICrossDomainMessenger.xDomainMessageSender.selector), abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) ); vm.deal(messenger, 100); diff --git a/packages/contracts-bedrock/test/L1/OptimismPortal.t.sol b/packages/contracts-bedrock/test/L1/OptimismPortal.t.sol index b47bad8e4173..35c9d0fb4ee5 100644 --- a/packages/contracts-bedrock/test/L1/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/L1/OptimismPortal.t.sol @@ -16,14 +16,13 @@ import { Constants } from "src/libraries/Constants.sol"; // Target contract dependencies import { Proxy } from "src/universal/Proxy.sol"; -import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { L1Block } from "src/L2/L1Block.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; +import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; import { MockERC20 } from "solmate/test/utils/mocks/MockERC20.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; @@ -43,7 +42,7 @@ contract OptimismPortal_Test is CommonTest { /// @notice Marked virtual to be overridden in /// test/kontrol/deployment/DeploymentSummary.t.sol function test_constructor_succeeds() external virtual { - OptimismPortal opImpl = OptimismPortal(payable(deploy.mustGetAddress("OptimismPortal"))); + IOptimismPortal opImpl = IOptimismPortal(payable(deploy.mustGetAddress("OptimismPortal"))); assertEq(address(opImpl.l2Oracle()), address(0)); assertEq(address(opImpl.systemConfig()), address(0)); assertEq(address(opImpl.superchainConfig()), address(0)); @@ -170,7 +169,7 @@ contract OptimismPortal_Test is CommonTest { _to = address(0); } vm.assume(_data.length <= 120_000); - ResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); + IResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); _gasLimit = uint64(bound(_gasLimit, optimismPortal.minimumGasLimit(uint64(_data.length)), rcfg.maxResourceLimit)); @@ -1156,7 +1155,7 @@ contract OptimismPortalUpgradeable_Test is CommonTest { /// @dev Tests that the proxy is initialized correctly. function test_params_initValuesOnProxy_succeeds() external view { (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = optimismPortal.params(); - ResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); + IResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); assertEq(prevBaseFee, rcfg.minimumBaseFee); assertEq(prevBoughtGas, 0); @@ -1240,7 +1239,7 @@ contract OptimismPortalResourceFuzz_Test is CommonTest { vm.roll(uint256(keccak256(abi.encode(_blockDiff))) % uint256(type(uint16).max) + uint256(_blockDiff)); // Create a resource config to mock the call to the system config with - ResourceMetering.ResourceConfig memory rcfg = ResourceMetering.ResourceConfig({ + IResourceMetering.ResourceConfig memory rcfg = IResourceMetering.ResourceConfig({ maxResourceLimit: _maxResourceLimit, elasticityMultiplier: _elasticityMultiplier, baseFeeMaxChangeDenominator: _baseFeeMaxChangeDenominator, @@ -1299,7 +1298,7 @@ contract OptimismPortalWithMockERC20_Test is OptimismPortal_FinalizeWithdrawal_T _to = address(0); } vm.assume(_data.length <= 120_000); - ResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); + IResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); _gasLimit = uint64(bound(_gasLimit, optimismPortal.minimumGasLimit(uint64(_data.length)), rcfg.maxResourceLimit)); @@ -1514,7 +1513,7 @@ contract OptimismPortalWithMockERC20_Test is OptimismPortal_FinalizeWithdrawal_T _to = address(0); } vm.assume(_data.length <= 120_000); - ResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); + IResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); _gasLimit = uint64(bound(_gasLimit, optimismPortal.minimumGasLimit(uint64(_data.length)), rcfg.maxResourceLimit)); diff --git a/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol b/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol index 91ea566dfce0..c0423ff2806e 100644 --- a/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol +++ b/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol @@ -17,12 +17,11 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; // Target contract dependencies import { Proxy } from "src/universal/Proxy.sol"; -import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; import { L1Block } from "src/L2/L1Block.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; -import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; +import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; import { MockERC20 } from "solmate/test/utils/mocks/MockERC20.sol"; @@ -50,7 +49,7 @@ contract OptimismPortal2_Test is CommonTest { /// @notice Marked virtual to be overridden in /// test/kontrol/deployment/DeploymentSummary.t.sol function test_constructor_succeeds() external virtual { - OptimismPortal2 opImpl = OptimismPortal2(payable(deploy.mustGetAddress("OptimismPortal2"))); + IOptimismPortal2 opImpl = IOptimismPortal2(payable(deploy.mustGetAddress("OptimismPortal2"))); assertEq(address(opImpl.disputeGameFactory()), address(0)); assertEq(address(opImpl.systemConfig()), address(0)); assertEq(address(opImpl.superchainConfig()), address(0)); @@ -1404,7 +1403,7 @@ contract OptimismPortal2_Upgradeable_Test is CommonTest { /// @dev Tests that the proxy is initialized correctly. function test_params_initValuesOnProxy_succeeds() external view { (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = optimismPortal2.params(); - ResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); + IResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); assertEq(prevBaseFee, rcfg.minimumBaseFee); assertEq(prevBoughtGas, 0); @@ -1494,7 +1493,7 @@ contract OptimismPortal2_ResourceFuzz_Test is CommonTest { vm.roll(uint256(keccak256(abi.encode(_blockDiff))) % uint256(type(uint16).max) + uint256(_blockDiff)); // Create a resource config to mock the call to the system config with - ResourceMetering.ResourceConfig memory rcfg = ResourceMetering.ResourceConfig({ + IResourceMetering.ResourceConfig memory rcfg = IResourceMetering.ResourceConfig({ maxResourceLimit: _maxResourceLimit, elasticityMultiplier: _elasticityMultiplier, baseFeeMaxChangeDenominator: _baseFeeMaxChangeDenominator, @@ -1553,7 +1552,7 @@ contract OptimismPortal2WithMockERC20_Test is OptimismPortal2_FinalizeWithdrawal _to = address(0); } vm.assume(_data.length <= 120_000); - ResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); + IResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); _gasLimit = uint64(bound(_gasLimit, optimismPortal2.minimumGasLimit(uint64(_data.length)), rcfg.maxResourceLimit)); @@ -1777,7 +1776,7 @@ contract OptimismPortal2WithMockERC20_Test is OptimismPortal2_FinalizeWithdrawal _to = address(0); } vm.assume(_data.length <= 120_000); - ResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); + IResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); _gasLimit = uint64(bound(_gasLimit, optimismPortal2.minimumGasLimit(uint64(_data.length)), rcfg.maxResourceLimit)); diff --git a/packages/contracts-bedrock/test/L1/OptimismPortalInterop.t.sol b/packages/contracts-bedrock/test/L1/OptimismPortalInterop.t.sol index 6fb9a1aab6ed..6e0235774df6 100644 --- a/packages/contracts-bedrock/test/L1/OptimismPortalInterop.t.sol +++ b/packages/contracts-bedrock/test/L1/OptimismPortalInterop.t.sol @@ -7,12 +7,16 @@ import { CommonTest } from "test/setup/CommonTest.sol"; // Libraries import { Constants } from "src/libraries/Constants.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; +import "src/libraries/PortalErrors.sol"; // Target contract dependencies import "src/libraries/PortalErrors.sol"; import { OptimismPortalInterop } from "src/L1/OptimismPortalInterop.sol"; import { L1BlockIsthmus, ConfigType } from "src/L2/L1BlockIsthmus.sol"; +// Interfaces +import { IOptimismPortalInterop } from "src/L1/interfaces/IOptimismPortalInterop.sol"; + contract OptimismPortalInterop_Test is CommonTest { /// @notice Marked virtual to be overridden in /// test/kontrol/deployment/DeploymentSummary.t.sol @@ -91,7 +95,7 @@ contract OptimismPortalInterop_Test is CommonTest { } /// @dev Returns the OptimismPortalInterop instance. - function _optimismPortalInterop() internal view returns (OptimismPortalInterop) { - return OptimismPortalInterop(payable(address(optimismPortal))); + function _optimismPortalInterop() internal view returns (IOptimismPortalInterop) { + return IOptimismPortalInterop(payable(address(optimismPortal))); } } diff --git a/packages/contracts-bedrock/test/L1/ResourceMetering.t.sol b/packages/contracts-bedrock/test/L1/ResourceMetering.t.sol index f4bca39ea418..f315b5212fd6 100644 --- a/packages/contracts-bedrock/test/L1/ResourceMetering.t.sol +++ b/packages/contracts-bedrock/test/L1/ResourceMetering.t.sol @@ -12,13 +12,22 @@ import { Proxy } from "src/universal/Proxy.sol"; // Target contract import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; contract MeterUser is ResourceMetering { ResourceMetering.ResourceConfig public innerConfig; constructor() { initialize(); - innerConfig = Constants.DEFAULT_RESOURCE_CONFIG(); + IResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG(); + innerConfig = ResourceMetering.ResourceConfig({ + maxResourceLimit: rcfg.maxResourceLimit, + elasticityMultiplier: rcfg.elasticityMultiplier, + baseFeeMaxChangeDenominator: rcfg.baseFeeMaxChangeDenominator, + minimumBaseFee: rcfg.minimumBaseFee, + systemTxMaxGas: rcfg.systemTxMaxGas, + maximumBaseFee: rcfg.maximumBaseFee + }); } function initialize() public initializer { @@ -231,7 +240,15 @@ contract CustomMeterUser is ResourceMetering { } function _resourceConfig() internal pure override returns (ResourceMetering.ResourceConfig memory) { - return Constants.DEFAULT_RESOURCE_CONFIG(); + IResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG(); + return ResourceMetering.ResourceConfig({ + maxResourceLimit: rcfg.maxResourceLimit, + elasticityMultiplier: rcfg.elasticityMultiplier, + baseFeeMaxChangeDenominator: rcfg.baseFeeMaxChangeDenominator, + minimumBaseFee: rcfg.minimumBaseFee, + systemTxMaxGas: rcfg.systemTxMaxGas, + maximumBaseFee: rcfg.maximumBaseFee + }); } function use(uint64 _amount) public returns (uint256) { diff --git a/packages/contracts-bedrock/test/L1/SuperchainConfig.t.sol b/packages/contracts-bedrock/test/L1/SuperchainConfig.t.sol index 97b25f3f611a..409bb0003941 100644 --- a/packages/contracts-bedrock/test/L1/SuperchainConfig.t.sol +++ b/packages/contracts-bedrock/test/L1/SuperchainConfig.t.sol @@ -12,6 +12,7 @@ import { Proxy } from "src/universal/Proxy.sol"; // Target contract import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; contract SuperchainConfig_Init_Test is CommonTest { /// @dev Tests that initialization sets the correct values. These are defined in CommonTest.sol. @@ -23,16 +24,16 @@ contract SuperchainConfig_Init_Test is CommonTest { /// @dev Tests that it can be intialized as paused. function test_initialize_paused_succeeds() external { Proxy newProxy = new Proxy(alice); - SuperchainConfig newImpl = new SuperchainConfig(); + ISuperchainConfig newImpl = ISuperchainConfig(address(new SuperchainConfig())); vm.startPrank(alice); newProxy.upgradeToAndCall( address(newImpl), - abi.encodeWithSelector(SuperchainConfig.initialize.selector, deploy.cfg().superchainConfigGuardian(), true) + abi.encodeWithSelector(ISuperchainConfig.initialize.selector, deploy.cfg().superchainConfigGuardian(), true) ); - assertTrue(SuperchainConfig(address(newProxy)).paused()); - assertEq(SuperchainConfig(address(newProxy)).guardian(), deploy.cfg().superchainConfigGuardian()); + assertTrue(ISuperchainConfig(address(newProxy)).paused()); + assertEq(ISuperchainConfig(address(newProxy)).guardian(), deploy.cfg().superchainConfigGuardian()); } } diff --git a/packages/contracts-bedrock/test/L1/SystemConfig.t.sol b/packages/contracts-bedrock/test/L1/SystemConfig.t.sol index 9b48f354d248..8b21fbcf3646 100644 --- a/packages/contracts-bedrock/test/L1/SystemConfig.t.sol +++ b/packages/contracts-bedrock/test/L1/SystemConfig.t.sol @@ -11,16 +11,16 @@ import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; // Target contract dependencies -import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { Proxy } from "src/universal/Proxy.sol"; import { L1Block } from "src/L2/L1Block.sol"; import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; // Target contract -import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; contract SystemConfig_Init is CommonTest { - event ConfigUpdate(uint256 indexed version, SystemConfig.UpdateType indexed updateType, bytes data); + event ConfigUpdate(uint256 indexed version, ISystemConfig.UpdateType indexed updateType, bytes data); } contract SystemConfig_Initialize_Test is SystemConfig_Init { @@ -49,7 +49,7 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { /// @dev Tests that constructor sets the correct values. function test_constructor_succeeds() external view { - SystemConfig impl = SystemConfig(systemConfigImpl); + ISystemConfig impl = ISystemConfig(systemConfigImpl); assertEq(impl.owner(), address(0xdEaD)); assertEq(impl.overhead(), 0); assertEq(impl.scalar(), uint256(0x01) << 248); @@ -58,7 +58,7 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { assertEq(impl.unsafeBlockSigner(), address(0)); assertEq(impl.basefeeScalar(), 0); assertEq(impl.blobbasefeeScalar(), 0); - ResourceMetering.ResourceConfig memory actual = impl.resourceConfig(); + IResourceMetering.ResourceConfig memory actual = impl.resourceConfig(); assertEq(actual.maxResourceLimit, 1); assertEq(actual.elasticityMultiplier, 1); assertEq(actual.baseFeeMaxChangeDenominator, 2); @@ -91,8 +91,8 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { assertEq(systemConfig.basefeeScalar(), basefeeScalar); assertEq(systemConfig.blobbasefeeScalar(), blobbasefeeScalar); // Depends on `initialize` being called with defaults - ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG(); - ResourceMetering.ResourceConfig memory actual = systemConfig.resourceConfig(); + IResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG(); + IResourceMetering.ResourceConfig memory actual = systemConfig.resourceConfig(); assertEq(actual.maxResourceLimit, rcfg.maxResourceLimit); assertEq(actual.elasticityMultiplier, rcfg.elasticityMultiplier); assertEq(actual.baseFeeMaxChangeDenominator, rcfg.baseFeeMaxChangeDenominator); @@ -138,7 +138,7 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test { _unsafeBlockSigner: address(1), _config: Constants.DEFAULT_RESOURCE_CONFIG(), _batchInbox: address(0), - _addresses: SystemConfig.Addresses({ + _addresses: ISystemConfig.Addresses({ l1CrossDomainMessenger: address(0), l1ERC721Bridge: address(0), l1StandardBridge: address(0), @@ -168,7 +168,7 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test { _unsafeBlockSigner: address(1), _config: Constants.DEFAULT_RESOURCE_CONFIG(), _batchInbox: address(0), - _addresses: SystemConfig.Addresses({ + _addresses: ISystemConfig.Addresses({ l1CrossDomainMessenger: address(0), l1ERC721Bridge: address(0), l1StandardBridge: address(0), @@ -199,7 +199,7 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test { _unsafeBlockSigner: address(1), _config: Constants.DEFAULT_RESOURCE_CONFIG(), _batchInbox: address(0), - _addresses: SystemConfig.Addresses({ + _addresses: ISystemConfig.Addresses({ l1CrossDomainMessenger: address(0), l1ERC721Bridge: address(0), l1StandardBridge: address(0), @@ -217,7 +217,7 @@ contract SystemConfig_Init_ResourceConfig is SystemConfig_Init { /// @dev Tests that `setResourceConfig` reverts if the min base fee /// is greater than the maximum allowed base fee. function test_setResourceConfig_badMinMax_reverts() external { - ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({ + IResourceMetering.ResourceConfig memory config = IResourceMetering.ResourceConfig({ maxResourceLimit: 20_000_000, elasticityMultiplier: 10, baseFeeMaxChangeDenominator: 8, @@ -231,7 +231,7 @@ contract SystemConfig_Init_ResourceConfig is SystemConfig_Init { /// @dev Tests that `setResourceConfig` reverts if the baseFeeMaxChangeDenominator /// is zero. function test_setResourceConfig_zeroDenominator_reverts() external { - ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({ + IResourceMetering.ResourceConfig memory config = IResourceMetering.ResourceConfig({ maxResourceLimit: 20_000_000, elasticityMultiplier: 10, baseFeeMaxChangeDenominator: 0, @@ -246,7 +246,7 @@ contract SystemConfig_Init_ResourceConfig is SystemConfig_Init { function test_setResourceConfig_lowGasLimit_reverts() external { uint64 gasLimit = systemConfig.gasLimit(); - ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({ + IResourceMetering.ResourceConfig memory config = IResourceMetering.ResourceConfig({ maxResourceLimit: uint32(gasLimit), elasticityMultiplier: 10, baseFeeMaxChangeDenominator: 8, @@ -260,7 +260,7 @@ contract SystemConfig_Init_ResourceConfig is SystemConfig_Init { /// @dev Tests that `setResourceConfig` reverts if the elasticity multiplier /// and max resource limit are configured such that there is a loss of precision. function test_setResourceConfig_badPrecision_reverts() external { - ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({ + IResourceMetering.ResourceConfig memory config = IResourceMetering.ResourceConfig({ maxResourceLimit: 20_000_000, elasticityMultiplier: 11, baseFeeMaxChangeDenominator: 8, @@ -274,7 +274,7 @@ contract SystemConfig_Init_ResourceConfig is SystemConfig_Init { /// @dev Helper to initialize the system config with a resource config and default values, and expect a revert /// with the given message. function _initializeWithResourceConfig( - ResourceMetering.ResourceConfig memory config, + IResourceMetering.ResourceConfig memory config, string memory revertMessage ) internal @@ -294,7 +294,7 @@ contract SystemConfig_Init_ResourceConfig is SystemConfig_Init { _unsafeBlockSigner: address(0), _config: config, _batchInbox: address(0), - _addresses: SystemConfig.Addresses({ + _addresses: ISystemConfig.Addresses({ l1CrossDomainMessenger: address(0), l1ERC721Bridge: address(0), l1StandardBridge: address(0), @@ -332,7 +332,7 @@ contract SystemConfig_Init_CustomGasToken is SystemConfig_Init { _unsafeBlockSigner: address(1), _config: Constants.DEFAULT_RESOURCE_CONFIG(), _batchInbox: address(0), - _addresses: SystemConfig.Addresses({ + _addresses: ISystemConfig.Addresses({ l1CrossDomainMessenger: address(0), l1ERC721Bridge: address(0), disputeGameFactory: address(0), @@ -533,7 +533,7 @@ contract SystemConfig_Setters_Test is SystemConfig_Init { /// @dev Tests that `setBatcherHash` updates the batcher hash successfully. function testFuzz_setBatcherHash_succeeds(bytes32 newBatcherHash) external { vm.expectEmit(address(systemConfig)); - emit ConfigUpdate(0, SystemConfig.UpdateType.BATCHER, abi.encode(newBatcherHash)); + emit ConfigUpdate(0, ISystemConfig.UpdateType.BATCHER, abi.encode(newBatcherHash)); vm.prank(systemConfig.owner()); systemConfig.setBatcherHash(newBatcherHash); @@ -545,7 +545,7 @@ contract SystemConfig_Setters_Test is SystemConfig_Init { // always zero out most significant byte newScalar = (newScalar << 16) >> 16; vm.expectEmit(address(systemConfig)); - emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_CONFIG, abi.encode(newOverhead, newScalar)); + emit ConfigUpdate(0, ISystemConfig.UpdateType.GAS_CONFIG, abi.encode(newOverhead, newScalar)); vm.prank(systemConfig.owner()); systemConfig.setGasConfig(newOverhead, newScalar); @@ -558,7 +558,7 @@ contract SystemConfig_Setters_Test is SystemConfig_Init { ffi.encodeScalarEcotone({ _basefeeScalar: _basefeeScalar, _blobbasefeeScalar: _blobbasefeeScalar }); vm.expectEmit(address(systemConfig)); - emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_CONFIG, abi.encode(systemConfig.overhead(), encoded)); + emit ConfigUpdate(0, ISystemConfig.UpdateType.GAS_CONFIG, abi.encode(systemConfig.overhead(), encoded)); vm.prank(systemConfig.owner()); systemConfig.setGasConfigEcotone({ _basefeeScalar: _basefeeScalar, _blobbasefeeScalar: _blobbasefeeScalar }); @@ -578,7 +578,7 @@ contract SystemConfig_Setters_Test is SystemConfig_Init { newGasLimit = uint64(bound(uint256(newGasLimit), uint256(minimumGasLimit), uint256(maximumGasLimit))); vm.expectEmit(address(systemConfig)); - emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_LIMIT, abi.encode(newGasLimit)); + emit ConfigUpdate(0, ISystemConfig.UpdateType.GAS_LIMIT, abi.encode(newGasLimit)); vm.prank(systemConfig.owner()); systemConfig.setGasLimit(newGasLimit); @@ -588,7 +588,7 @@ contract SystemConfig_Setters_Test is SystemConfig_Init { /// @dev Tests that `setUnsafeBlockSigner` updates the block signer successfully. function testFuzz_setUnsafeBlockSigner_succeeds(address newUnsafeSigner) external { vm.expectEmit(address(systemConfig)); - emit ConfigUpdate(0, SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER, abi.encode(newUnsafeSigner)); + emit ConfigUpdate(0, ISystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER, abi.encode(newUnsafeSigner)); vm.prank(systemConfig.owner()); systemConfig.setUnsafeBlockSigner(newUnsafeSigner); diff --git a/packages/contracts-bedrock/test/L1/SystemConfigInterop.t.sol b/packages/contracts-bedrock/test/L1/SystemConfigInterop.t.sol index c861331b1387..191949e29f6f 100644 --- a/packages/contracts-bedrock/test/L1/SystemConfigInterop.t.sol +++ b/packages/contracts-bedrock/test/L1/SystemConfigInterop.t.sol @@ -10,9 +10,9 @@ import { StaticConfig } from "src/libraries/StaticConfig.sol"; import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; // Target contract dependencies -import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { SystemConfigInterop } from "src/L1/SystemConfigInterop.sol"; -import { OptimismPortalInterop } from "src/L1/OptimismPortalInterop.sol"; +import { IOptimismPortalInterop } from "src/L1/interfaces/IOptimismPortalInterop.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { ConfigType } from "src/L2/L1BlockIsthmus.sol"; @@ -46,7 +46,7 @@ contract SystemConfigInterop_Test is CommonTest { vm.expectCall( address(optimismPortal), abi.encodeCall( - OptimismPortalInterop.setConfig, + IOptimismPortalInterop.setConfig, ( ConfigType.SET_GAS_PAYING_TOKEN, StaticConfig.encodeSetGasPayingToken({ @@ -67,7 +67,8 @@ contract SystemConfigInterop_Test is CommonTest { vm.expectCall( address(optimismPortal), abi.encodeCall( - OptimismPortalInterop.setConfig, (ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)) + IOptimismPortalInterop.setConfig, + (ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)) ) ); @@ -86,7 +87,7 @@ contract SystemConfigInterop_Test is CommonTest { vm.expectCall( address(optimismPortal), abi.encodeCall( - OptimismPortalInterop.setConfig, + IOptimismPortalInterop.setConfig, (ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(_chainId)) ) ); @@ -118,7 +119,7 @@ contract SystemConfigInterop_Test is CommonTest { _unsafeBlockSigner: address(1), _config: Constants.DEFAULT_RESOURCE_CONFIG(), _batchInbox: address(0), - _addresses: SystemConfig.Addresses({ + _addresses: ISystemConfig.Addresses({ l1CrossDomainMessenger: address(0), l1ERC721Bridge: address(0), disputeGameFactory: address(0), diff --git a/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol index c3805b991261..9892ba51cb3e 100644 --- a/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol @@ -16,7 +16,6 @@ import { Constants } from "src/libraries/Constants.sol"; import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol"; import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; contract L2CrossDomainMessenger_Test is Bridge_Initializer { /// @dev Receiver address for testing diff --git a/packages/contracts-bedrock/test/L2/L2StandardBridge.t.sol b/packages/contracts-bedrock/test/L2/L2StandardBridge.t.sol index e07fc0086bd8..6f794c175a25 100644 --- a/packages/contracts-bedrock/test/L2/L2StandardBridge.t.sol +++ b/packages/contracts-bedrock/test/L2/L2StandardBridge.t.sol @@ -7,7 +7,7 @@ import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; // Target contract is imported by the `Bridge_Initializer` import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { stdStorage, StdStorage } from "forge-std/Test.sol"; -import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; @@ -60,7 +60,7 @@ contract L2StandardBridge_Test is Bridge_Initializer { abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 100, hex""); uint64 baseGas = l2CrossDomainMessenger.baseGas(message, 200_000); bytes memory withdrawalData = abi.encodeWithSelector( - CrossDomainMessenger.relayMessage.selector, + ICrossDomainMessenger.relayMessage.selector, nonce, address(l2StandardBridge), address(l1StandardBridge), @@ -108,7 +108,7 @@ contract L2StandardBridge_Test is Bridge_Initializer { vm.expectCall( address(l2CrossDomainMessenger), abi.encodeWithSelector( - CrossDomainMessenger.sendMessage.selector, + ICrossDomainMessenger.sendMessage.selector, address(l1StandardBridge), message, 200_000 // StandardBridge's RECEIVE_DEFAULT_GAS_LIMIT @@ -282,7 +282,7 @@ contract PreBridgeERC20 is Bridge_Initializer { ); uint64 baseGas = l2CrossDomainMessenger.baseGas(message, 1000); bytes memory withdrawalData = abi.encodeWithSelector( - CrossDomainMessenger.relayMessage.selector, + ICrossDomainMessenger.relayMessage.selector, nonce, address(l2StandardBridge), address(l1StandardBridge), @@ -317,7 +317,7 @@ contract PreBridgeERC20 is Bridge_Initializer { vm.expectCall( address(l2CrossDomainMessenger), - abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l1StandardBridge), message, 1000) + abi.encodeWithSelector(ICrossDomainMessenger.sendMessage.selector, address(l1StandardBridge), message, 1000) ); vm.expectCall( @@ -420,7 +420,7 @@ contract PreBridgeERC20To is Bridge_Initializer { ); uint64 baseGas = l2CrossDomainMessenger.baseGas(message, 1000); bytes memory withdrawalData = abi.encodeWithSelector( - CrossDomainMessenger.relayMessage.selector, + ICrossDomainMessenger.relayMessage.selector, nonce, address(l2StandardBridge), address(l1StandardBridge), @@ -480,7 +480,7 @@ contract PreBridgeERC20To is Bridge_Initializer { vm.expectCall( address(l2CrossDomainMessenger), - abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l1StandardBridge), message, 1000) + abi.encodeWithSelector(ICrossDomainMessenger.sendMessage.selector, address(l1StandardBridge), message, 1000) ); vm.expectCall( @@ -524,7 +524,7 @@ contract L2StandardBridge_Bridge_Test is Bridge_Initializer { function test_finalizeBridgeETH_sendToSelf_reverts() external { vm.mockCall( address(l2StandardBridge.messenger()), - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encodeWithSelector(ICrossDomainMessenger.xDomainMessageSender.selector), abi.encode(address(l2StandardBridge.OTHER_BRIDGE())) ); vm.deal(address(l2CrossDomainMessenger), 100); @@ -537,7 +537,7 @@ contract L2StandardBridge_Bridge_Test is Bridge_Initializer { function test_finalizeBridgeETH_sendToMessenger_reverts() external { vm.mockCall( address(l2StandardBridge.messenger()), - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encodeWithSelector(ICrossDomainMessenger.xDomainMessageSender.selector), abi.encode(address(l2StandardBridge.OTHER_BRIDGE())) ); vm.deal(address(l2CrossDomainMessenger), 100); @@ -563,7 +563,7 @@ contract L2StandardBridge_Bridge_Test is Bridge_Initializer { address(l2CrossDomainMessenger), _value, abi.encodeWithSelector( - CrossDomainMessenger.sendMessage.selector, address(l1StandardBridge), message, _minGasLimit + ICrossDomainMessenger.sendMessage.selector, address(l1StandardBridge), message, _minGasLimit ) ); @@ -611,7 +611,7 @@ contract L2StandardBridge_Bridge_Test is Bridge_Initializer { vm.expectCall( address(l2CrossDomainMessenger), abi.encodeWithSelector( - CrossDomainMessenger.sendMessage.selector, address(l1StandardBridge), message, _minGasLimit + ICrossDomainMessenger.sendMessage.selector, address(l1StandardBridge), message, _minGasLimit ) ); @@ -654,7 +654,7 @@ contract L2StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer { address messenger = address(l2StandardBridge.messenger()); vm.mockCall( messenger, - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encodeWithSelector(ICrossDomainMessenger.xDomainMessageSender.selector), abi.encode(address(l2StandardBridge.OTHER_BRIDGE())) ); vm.deal(messenger, 100); @@ -674,7 +674,7 @@ contract L2StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer { address messenger = address(l2StandardBridge.messenger()); vm.mockCall( messenger, - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encodeWithSelector(ICrossDomainMessenger.xDomainMessageSender.selector), abi.encode(address(l2StandardBridge.OTHER_BRIDGE())) ); vm.deal(address(l2CrossDomainMessenger), 1); diff --git a/packages/contracts-bedrock/test/Safe/DeployOwnership.t.sol b/packages/contracts-bedrock/test/Safe/DeployOwnership.t.sol index b3a856e68a40..516c8443f035 100644 --- a/packages/contracts-bedrock/test/Safe/DeployOwnership.t.sol +++ b/packages/contracts-bedrock/test/Safe/DeployOwnership.t.sol @@ -18,7 +18,6 @@ import { GuardManager } from "safe-contracts/base/GuardManager.sol"; import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; import { LivenessModule } from "src/Safe/LivenessModule.sol"; import { DeputyGuardianModule } from "src/Safe/DeputyGuardianModule.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; contract DeployOwnershipTest is Test, DeployOwnership { address internal constant SENTINEL_MODULES = address(0x1); diff --git a/packages/contracts-bedrock/test/Safe/DeputyGuardianModule.t.sol b/packages/contracts-bedrock/test/Safe/DeputyGuardianModule.t.sol index 5470fe33a5e2..4bc5879bbf64 100644 --- a/packages/contracts-bedrock/test/Safe/DeputyGuardianModule.t.sol +++ b/packages/contracts-bedrock/test/Safe/DeputyGuardianModule.t.sol @@ -278,10 +278,12 @@ contract DeputyGuardianModule_NoPortalCollisions_Test is DeputyGuardianModule_Te /// @dev tests that no function selectors in the L1 contracts collide with the OptimismPortal2 functions called by /// the DeputyGuardianModule. function test_noPortalCollisions_succeeds() external { - string[] memory excludes = new string[](3); - excludes[0] = "src/L1/OptimismPortal2.sol"; - excludes[1] = "src/dispute/lib/*"; + string[] memory excludes = new string[](5); + excludes[0] = "src/dispute/lib/*"; + excludes[1] = "src/L1/OptimismPortal2.sol"; excludes[2] = "src/L1/OptimismPortalInterop.sol"; + excludes[3] = "src/L1/interfaces/IOptimismPortal2.sol"; + excludes[4] = "src/L1/interfaces/IOptimismPortalInterop.sol"; Abi[] memory abis = ForgeArtifacts.getContractFunctionAbis("src/{L1,dispute,universal}", excludes); for (uint256 i; i < abis.length; i++) { for (uint256 j; j < abis[i].entries.length; j++) { diff --git a/packages/contracts-bedrock/test/Specs.t.sol b/packages/contracts-bedrock/test/Specs.t.sol index f9d6a0145bb3..d8b918acf8bc 100644 --- a/packages/contracts-bedrock/test/Specs.t.sol +++ b/packages/contracts-bedrock/test/Specs.t.sol @@ -1,16 +1,24 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.15; +// Testing import { CommonTest } from "test/setup/CommonTest.sol"; import { console2 as console } from "forge-std/console2.sol"; + +// Scripts +import { Executables } from "scripts/libraries/Executables.sol"; +import { ForgeArtifacts, Abi, AbiEntry } from "scripts/libraries/ForgeArtifacts.sol"; + +// Contracts import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; -import { OptimismPortalInterop } from "src/L1/OptimismPortalInterop.sol"; -import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; -import { DataAvailabilityChallenge } from "src/L1/DataAvailabilityChallenge.sol"; import { OPStackManager } from "src/L1/OPStackManager.sol"; -import { ForgeArtifacts, Abi, AbiEntry } from "scripts/libraries/ForgeArtifacts.sol"; + +// Interfaces +import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; +import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; +import { IOptimismPortalInterop } from "src/L1/interfaces/IOptimismPortalInterop.sol"; +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; +import { IDataAvailabilityChallenge } from "src/L1/interfaces/IDataAvailabilityChallenge.sol"; /// @title Specification_Test /// @dev Specifies common security properties of entrypoints to L1 contracts, including authorization and @@ -79,25 +87,25 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "DataAvailabilityChallenge", _sel: _getSel("resolveWindow()") }); _addSpec({ _name: "DataAvailabilityChallenge", _sel: _getSel("resolverRefundPercentage()") }); _addSpec({ _name: "DataAvailabilityChallenge", _sel: _getSel("balances(address)") }); - _addSpec({ _name: "DataAvailabilityChallenge", _sel: DataAvailabilityChallenge.initialize.selector }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: IDataAvailabilityChallenge.initialize.selector }); _addSpec({ _name: "DataAvailabilityChallenge", - _sel: DataAvailabilityChallenge.setBondSize.selector, + _sel: IDataAvailabilityChallenge.setBondSize.selector, _auth: Role.DATAAVAILABILITYCHALLENGEOWNER }); _addSpec({ _name: "DataAvailabilityChallenge", - _sel: DataAvailabilityChallenge.setResolverRefundPercentage.selector, + _sel: IDataAvailabilityChallenge.setResolverRefundPercentage.selector, _auth: Role.DATAAVAILABILITYCHALLENGEOWNER }); - _addSpec({ _name: "DataAvailabilityChallenge", _sel: DataAvailabilityChallenge.deposit.selector }); - _addSpec({ _name: "DataAvailabilityChallenge", _sel: DataAvailabilityChallenge.withdraw.selector }); - _addSpec({ _name: "DataAvailabilityChallenge", _sel: DataAvailabilityChallenge.getChallenge.selector }); - _addSpec({ _name: "DataAvailabilityChallenge", _sel: DataAvailabilityChallenge.getChallengeStatus.selector }); - _addSpec({ _name: "DataAvailabilityChallenge", _sel: DataAvailabilityChallenge.validateCommitment.selector }); - _addSpec({ _name: "DataAvailabilityChallenge", _sel: DataAvailabilityChallenge.challenge.selector }); - _addSpec({ _name: "DataAvailabilityChallenge", _sel: DataAvailabilityChallenge.resolve.selector }); - _addSpec({ _name: "DataAvailabilityChallenge", _sel: DataAvailabilityChallenge.unlockBond.selector }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: IDataAvailabilityChallenge.deposit.selector }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: IDataAvailabilityChallenge.withdraw.selector }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: IDataAvailabilityChallenge.getChallenge.selector }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: IDataAvailabilityChallenge.getChallengeStatus.selector }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: IDataAvailabilityChallenge.validateCommitment.selector }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: IDataAvailabilityChallenge.challenge.selector }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: IDataAvailabilityChallenge.resolve.selector }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: IDataAvailabilityChallenge.unlockBond.selector }); // DelayedVetoable _addSpec({ _name: "DelayedVetoable", _sel: _getSel("delay()") }); @@ -247,7 +255,7 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "OptimismPortal", _sel: _getSel("donateETH()") }); _addSpec({ _name: "OptimismPortal", - _sel: OptimismPortal.finalizeWithdrawalTransaction.selector, + _sel: IOptimismPortal.finalizeWithdrawalTransaction.selector, _pausable: true }); _addSpec({ _name: "OptimismPortal", _sel: _getSel("finalizedWithdrawals(bytes32)") }); @@ -259,7 +267,7 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "OptimismPortal", _sel: _getSel("minimumGasLimit(uint64)") }); _addSpec({ _name: "OptimismPortal", _sel: _getSel("params()") }); _addSpec({ _name: "OptimismPortal", _sel: _getSel("paused()") }); - _addSpec({ _name: "OptimismPortal", _sel: OptimismPortal.proveWithdrawalTransaction.selector, _pausable: true }); + _addSpec({ _name: "OptimismPortal", _sel: IOptimismPortal.proveWithdrawalTransaction.selector, _pausable: true }); _addSpec({ _name: "OptimismPortal", _sel: _getSel("provenWithdrawals(bytes32)") }); _addSpec({ _name: "OptimismPortal", _sel: _getSel("superchainConfig()") }); _addSpec({ _name: "OptimismPortal", _sel: _getSel("systemConfig()") }); @@ -279,12 +287,12 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "OptimismPortalInterop", _sel: _getSel("donateETH()") }); _addSpec({ _name: "OptimismPortalInterop", - _sel: OptimismPortal2.finalizeWithdrawalTransaction.selector, + _sel: IOptimismPortal2.finalizeWithdrawalTransaction.selector, _pausable: true }); _addSpec({ _name: "OptimismPortalInterop", - _sel: OptimismPortal2.finalizeWithdrawalTransactionExternalProof.selector, + _sel: IOptimismPortal2.finalizeWithdrawalTransactionExternalProof.selector, _pausable: true }); _addSpec({ _name: "OptimismPortalInterop", _sel: _getSel("finalizedWithdrawals(bytes32)") }); @@ -296,7 +304,7 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "OptimismPortalInterop", _sel: _getSel("paused()") }); _addSpec({ _name: "OptimismPortalInterop", - _sel: OptimismPortal2.proveWithdrawalTransaction.selector, + _sel: IOptimismPortal2.proveWithdrawalTransaction.selector, _pausable: true }); _addSpec({ _name: "OptimismPortalInterop", _sel: _getSel("provenWithdrawals(bytes32,address)") }); @@ -331,7 +339,7 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "OptimismPortalInterop", _sel: _getSel("setGasPayingToken(address,uint8,bytes32,bytes32)") }); _addSpec({ _name: "OptimismPortalInterop", - _sel: OptimismPortalInterop.setConfig.selector, + _sel: IOptimismPortalInterop.setConfig.selector, _auth: Role.SYSTEMCONFIGOWNER }); @@ -340,12 +348,12 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "OptimismPortal2", _sel: _getSel("donateETH()") }); _addSpec({ _name: "OptimismPortal2", - _sel: OptimismPortal2.finalizeWithdrawalTransaction.selector, + _sel: IOptimismPortal2.finalizeWithdrawalTransaction.selector, _pausable: true }); _addSpec({ _name: "OptimismPortal2", - _sel: OptimismPortal2.finalizeWithdrawalTransactionExternalProof.selector, + _sel: IOptimismPortal2.finalizeWithdrawalTransactionExternalProof.selector, _pausable: true }); _addSpec({ _name: "OptimismPortal2", _sel: _getSel("finalizedWithdrawals(bytes32)") }); @@ -355,7 +363,11 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "OptimismPortal2", _sel: _getSel("minimumGasLimit(uint64)") }); _addSpec({ _name: "OptimismPortal2", _sel: _getSel("params()") }); _addSpec({ _name: "OptimismPortal2", _sel: _getSel("paused()") }); - _addSpec({ _name: "OptimismPortal2", _sel: OptimismPortal2.proveWithdrawalTransaction.selector, _pausable: true }); + _addSpec({ + _name: "OptimismPortal2", + _sel: IOptimismPortal2.proveWithdrawalTransaction.selector, + _pausable: true + }); _addSpec({ _name: "OptimismPortal2", _sel: _getSel("provenWithdrawals(bytes32,address)") }); _addSpec({ _name: "OptimismPortal2", _sel: _getSel("superchainConfig()") }); _addSpec({ _name: "OptimismPortal2", _sel: _getSel("systemConfig()") }); @@ -419,23 +431,23 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "SystemConfig", _sel: _getSel("VERSION()") }); _addSpec({ _name: "SystemConfig", _sel: _getSel("batcherHash()") }); _addSpec({ _name: "SystemConfig", _sel: _getSel("gasLimit()") }); - _addSpec({ _name: "SystemConfig", _sel: SystemConfig.initialize.selector }); - _addSpec({ _name: "SystemConfig", _sel: SystemConfig.minimumGasLimit.selector }); + _addSpec({ _name: "SystemConfig", _sel: ISystemConfig.initialize.selector }); + _addSpec({ _name: "SystemConfig", _sel: ISystemConfig.minimumGasLimit.selector }); _addSpec({ _name: "SystemConfig", _sel: _getSel("overhead()") }); _addSpec({ _name: "SystemConfig", _sel: _getSel("owner()") }); _addSpec({ _name: "SystemConfig", _sel: _getSel("renounceOwnership()"), _auth: Role.SYSTEMCONFIGOWNER }); - _addSpec({ _name: "SystemConfig", _sel: SystemConfig.resourceConfig.selector }); + _addSpec({ _name: "SystemConfig", _sel: ISystemConfig.resourceConfig.selector }); _addSpec({ _name: "SystemConfig", _sel: _getSel("scalar()") }); - _addSpec({ _name: "SystemConfig", _sel: SystemConfig.setBatcherHash.selector, _auth: Role.SYSTEMCONFIGOWNER }); - _addSpec({ _name: "SystemConfig", _sel: SystemConfig.setGasConfig.selector, _auth: Role.SYSTEMCONFIGOWNER }); - _addSpec({ _name: "SystemConfig", _sel: SystemConfig.setGasLimit.selector, _auth: Role.SYSTEMCONFIGOWNER }); + _addSpec({ _name: "SystemConfig", _sel: ISystemConfig.setBatcherHash.selector, _auth: Role.SYSTEMCONFIGOWNER }); + _addSpec({ _name: "SystemConfig", _sel: ISystemConfig.setGasConfig.selector, _auth: Role.SYSTEMCONFIGOWNER }); + _addSpec({ _name: "SystemConfig", _sel: ISystemConfig.setGasLimit.selector, _auth: Role.SYSTEMCONFIGOWNER }); _addSpec({ _name: "SystemConfig", - _sel: SystemConfig.setUnsafeBlockSigner.selector, + _sel: ISystemConfig.setUnsafeBlockSigner.selector, _auth: Role.SYSTEMCONFIGOWNER }); _addSpec({ _name: "SystemConfig", _sel: _getSel("transferOwnership(address)"), _auth: Role.SYSTEMCONFIGOWNER }); - _addSpec({ _name: "SystemConfig", _sel: SystemConfig.unsafeBlockSigner.selector }); + _addSpec({ _name: "SystemConfig", _sel: ISystemConfig.unsafeBlockSigner.selector }); _addSpec({ _name: "SystemConfig", _sel: _getSel("version()") }); _addSpec({ _name: "SystemConfig", _sel: _getSel("l1CrossDomainMessenger()") }); _addSpec({ _name: "SystemConfig", _sel: _getSel("l1ERC721Bridge()") }); @@ -471,27 +483,31 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("VERSION()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("batcherHash()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("gasLimit()") }); - _addSpec({ _name: "SystemConfigInterop", _sel: SystemConfig.initialize.selector }); - _addSpec({ _name: "SystemConfigInterop", _sel: SystemConfig.minimumGasLimit.selector }); + _addSpec({ _name: "SystemConfigInterop", _sel: ISystemConfig.initialize.selector }); + _addSpec({ _name: "SystemConfigInterop", _sel: ISystemConfig.minimumGasLimit.selector }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("overhead()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("owner()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("renounceOwnership()"), _auth: Role.SYSTEMCONFIGOWNER }); - _addSpec({ _name: "SystemConfigInterop", _sel: SystemConfig.resourceConfig.selector }); + _addSpec({ _name: "SystemConfigInterop", _sel: ISystemConfig.resourceConfig.selector }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("scalar()") }); _addSpec({ _name: "SystemConfigInterop", - _sel: SystemConfig.setBatcherHash.selector, + _sel: ISystemConfig.setBatcherHash.selector, + _auth: Role.SYSTEMCONFIGOWNER + }); + _addSpec({ + _name: "SystemConfigInterop", + _sel: ISystemConfig.setGasConfig.selector, _auth: Role.SYSTEMCONFIGOWNER }); _addSpec({ _name: "SystemConfigInterop", - _sel: SystemConfig.setGasConfig.selector, + _sel: ISystemConfig.setGasLimit.selector, _auth: Role.SYSTEMCONFIGOWNER }); - _addSpec({ _name: "SystemConfigInterop", _sel: SystemConfig.setGasLimit.selector, _auth: Role.SYSTEMCONFIGOWNER }); _addSpec({ _name: "SystemConfigInterop", - _sel: SystemConfig.setUnsafeBlockSigner.selector, + _sel: ISystemConfig.setUnsafeBlockSigner.selector, _auth: Role.SYSTEMCONFIGOWNER }); _addSpec({ @@ -499,7 +515,7 @@ contract Specification_Test is CommonTest { _sel: _getSel("transferOwnership(address)"), _auth: Role.SYSTEMCONFIGOWNER }); - _addSpec({ _name: "SystemConfigInterop", _sel: SystemConfig.unsafeBlockSigner.selector }); + _addSpec({ _name: "SystemConfigInterop", _sel: ISystemConfig.unsafeBlockSigner.selector }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("version()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("l1CrossDomainMessenger()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("l1ERC721Bridge()") }); diff --git a/packages/contracts-bedrock/test/invariants/CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/invariants/CrossDomainMessenger.t.sol index b0b64253493b..08a0c0027763 100644 --- a/packages/contracts-bedrock/test/invariants/CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/invariants/CrossDomainMessenger.t.sol @@ -3,8 +3,8 @@ pragma solidity 0.8.15; import { StdUtils } from "forge-std/StdUtils.sol"; import { Vm } from "forge-std/Vm.sol"; -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; -import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; +import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; +import { IL1CrossDomainMessenger } from "src/L1/interfaces/IL1CrossDomainMessenger.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { Constants } from "src/libraries/Constants.sol"; @@ -20,12 +20,12 @@ contract RelayActor is StdUtils { bytes32[] public hashes; bool public reverted = false; - OptimismPortal op; - L1CrossDomainMessenger xdm; + IOptimismPortal op; + IL1CrossDomainMessenger xdm; Vm vm; bool doFail; - constructor(OptimismPortal _op, L1CrossDomainMessenger _xdm, Vm _vm, bool _doFail) { + constructor(IOptimismPortal _op, IL1CrossDomainMessenger _xdm, Vm _vm, bool _doFail) { op = _op; xdm = _xdm; vm = _vm; diff --git a/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol b/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol index 0dc020f9d7fa..8e5319d9aeb6 100644 --- a/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol @@ -4,8 +4,9 @@ pragma solidity 0.8.15; import { StdUtils } from "forge-std/Test.sol"; import { Vm } from "forge-std/Vm.sol"; -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; +import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { Constants } from "src/libraries/Constants.sol"; import { CommonTest } from "test/setup/CommonTest.sol"; @@ -14,10 +15,10 @@ import { Types } from "src/libraries/Types.sol"; contract OptimismPortal_Depositor is StdUtils, ResourceMetering { Vm internal vm; - OptimismPortal internal portal; + IOptimismPortal internal portal; bool public failedToComplete; - constructor(Vm _vm, OptimismPortal _portal) { + constructor(Vm _vm, IOptimismPortal _portal) { vm = _vm; portal = _portal; initialize(); @@ -31,9 +32,11 @@ contract OptimismPortal_Depositor is StdUtils, ResourceMetering { return _resourceConfig(); } - function _resourceConfig() internal pure override returns (ResourceMetering.ResourceConfig memory) { - ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG(); - return rcfg; + function _resourceConfig() internal pure override returns (ResourceMetering.ResourceConfig memory config_) { + IResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG(); + assembly ("memory-safe") { + config_ := rcfg + } } // A test intended to identify any unexpected halting conditions diff --git a/packages/contracts-bedrock/test/invariants/OptimismPortal2.t.sol b/packages/contracts-bedrock/test/invariants/OptimismPortal2.t.sol index 56c2c1849feb..ef96f3eb5c4f 100644 --- a/packages/contracts-bedrock/test/invariants/OptimismPortal2.t.sol +++ b/packages/contracts-bedrock/test/invariants/OptimismPortal2.t.sol @@ -4,10 +4,10 @@ pragma solidity 0.8.15; import { StdUtils } from "forge-std/Test.sol"; import { Vm } from "forge-std/Vm.sol"; -import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; +import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { Constants } from "src/libraries/Constants.sol"; import { CommonTest } from "test/setup/CommonTest.sol"; @@ -20,10 +20,10 @@ import "src/libraries/PortalErrors.sol"; contract OptimismPortal2_Depositor is StdUtils, ResourceMetering { Vm internal vm; - OptimismPortal2 internal portal; + IOptimismPortal2 internal portal; bool public failedToComplete; - constructor(Vm _vm, OptimismPortal2 _portal) { + constructor(Vm _vm, IOptimismPortal2 _portal) { vm = _vm; portal = _portal; initialize(); @@ -37,9 +37,11 @@ contract OptimismPortal2_Depositor is StdUtils, ResourceMetering { return _resourceConfig(); } - function _resourceConfig() internal pure override returns (ResourceMetering.ResourceConfig memory) { - ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG(); - return rcfg; + function _resourceConfig() internal pure override returns (ResourceMetering.ResourceConfig memory config_) { + IResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG(); + assembly ("memory-safe") { + config_ := rcfg + } } // A test intended to identify any unexpected halting conditions diff --git a/packages/contracts-bedrock/test/invariants/ResourceMetering.t.sol b/packages/contracts-bedrock/test/invariants/ResourceMetering.t.sol index 39e54590efbb..4652f9b9e36e 100644 --- a/packages/contracts-bedrock/test/invariants/ResourceMetering.t.sol +++ b/packages/contracts-bedrock/test/invariants/ResourceMetering.t.sol @@ -8,6 +8,7 @@ import { StdInvariant } from "forge-std/StdInvariant.sol"; import { Arithmetic } from "src/libraries/Arithmetic.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { Constants } from "src/libraries/Constants.sol"; import { InvariantTest } from "test/invariants/InvariantTest.sol"; @@ -35,9 +36,11 @@ contract ResourceMetering_User is StdUtils, ResourceMetering { return _resourceConfig(); } - function _resourceConfig() internal pure override returns (ResourceMetering.ResourceConfig memory) { - ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG(); - return rcfg; + function _resourceConfig() internal pure override returns (ResourceMetering.ResourceConfig memory config_) { + IResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG(); + assembly ("memory-safe") { + config_ := rcfg + } } /// @notice Takes the necessary parameters to allow us to burn arbitrary amounts of gas to test diff --git a/packages/contracts-bedrock/test/invariants/SystemConfig.t.sol b/packages/contracts-bedrock/test/invariants/SystemConfig.t.sol index 8419113917f4..1321499462b7 100644 --- a/packages/contracts-bedrock/test/invariants/SystemConfig.t.sol +++ b/packages/contracts-bedrock/test/invariants/SystemConfig.t.sol @@ -3,15 +3,16 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { Proxy } from "src/universal/Proxy.sol"; import { Constants } from "src/libraries/Constants.sol"; contract SystemConfig_GasLimitBoundaries_Invariant is Test { - SystemConfig public config; + ISystemConfig public config; function setUp() external { Proxy proxy = new Proxy(msg.sender); - SystemConfig configImpl = new SystemConfig(); + ISystemConfig configImpl = ISystemConfig(address(new SystemConfig())); vm.prank(msg.sender); proxy.upgradeToAndCall( @@ -27,7 +28,7 @@ contract SystemConfig_GasLimitBoundaries_Invariant is Test { address(1), // unsafe block signer Constants.DEFAULT_RESOURCE_CONFIG(), address(0), // _batchInbox - SystemConfig.Addresses({ // _addrs + ISystemConfig.Addresses({ // _addrs l1CrossDomainMessenger: address(0), l1ERC721Bridge: address(0), l1StandardBridge: address(0), @@ -40,7 +41,7 @@ contract SystemConfig_GasLimitBoundaries_Invariant is Test { ) ); - config = SystemConfig(address(proxy)); + config = ISystemConfig(address(proxy)); // Set the target contract to the `config` targetContract(address(config)); diff --git a/packages/contracts-bedrock/test/setup/Setup.sol b/packages/contracts-bedrock/test/setup/Setup.sol index a39c996d7bfe..0d8db00009cb 100644 --- a/packages/contracts-bedrock/test/setup/Setup.sol +++ b/packages/contracts-bedrock/test/setup/Setup.sol @@ -1,9 +1,19 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Testing import { console2 as console } from "forge-std/console2.sol"; -import { Predeploys } from "src/libraries/Predeploys.sol"; -import { Preinstalls } from "src/libraries/Preinstalls.sol"; +import { Vm } from "forge-std/Vm.sol"; + +// Scripts +import { DeployConfig } from "scripts/deploy/DeployConfig.s.sol"; +import { Deploy } from "scripts/deploy/Deploy.s.sol"; +import { Fork, LATEST_FORK } from "scripts/libraries/Config.sol"; +import { L2Genesis, L1Dependencies } from "scripts/L2Genesis.s.sol"; +import { OutputMode, Fork, ForkUtils } from "scripts/libraries/Config.sol"; +import { Executables } from "scripts/libraries/Executables.sol"; + +// Contracts import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol"; import { L2StandardBridgeInterop } from "src/L2/L2StandardBridgeInterop.sol"; import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; @@ -18,31 +28,30 @@ import { GovernanceToken } from "src/governance/GovernanceToken.sol"; import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol"; import { FeeVault } from "src/universal/FeeVault.sol"; -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; -import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; -import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; -import { DeployConfig } from "scripts/deploy/DeployConfig.s.sol"; -import { Deploy } from "scripts/deploy/Deploy.s.sol"; -import { Fork, LATEST_FORK } from "scripts/libraries/Config.sol"; -import { L2Genesis, L1Dependencies } from "scripts/L2Genesis.s.sol"; -import { OutputMode, Fork, ForkUtils } from "scripts/libraries/Config.sol"; -import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { AddressManager } from "src/legacy/AddressManager.sol"; -import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; -import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; -import { Executables } from "scripts/libraries/Executables.sol"; -import { Vm } from "forge-std/Vm.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; -import { DataAvailabilityChallenge } from "src/L1/DataAvailabilityChallenge.sol"; import { WETH } from "src/L2/WETH.sol"; import { SuperchainWETH } from "src/L2/SuperchainWETH.sol"; import { ETHLiquidity } from "src/L2/ETHLiquidity.sol"; +import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; + +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { Preinstalls } from "src/libraries/Preinstalls.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; + +// Interfaces +import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; +import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; +import { IL1CrossDomainMessenger } from "src/L1/interfaces/IL1CrossDomainMessenger.sol"; +import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; +import { IDataAvailabilityChallenge } from "src/L1/interfaces/IDataAvailabilityChallenge.sol"; /// @title Setup /// @dev This contact is responsible for setting up the contracts in state. It currently @@ -65,20 +74,20 @@ contract Setup { // @notice Allows users of Setup to override what L2 genesis is being created. Fork l2Fork = LATEST_FORK; - OptimismPortal optimismPortal; - OptimismPortal2 optimismPortal2; + IOptimismPortal optimismPortal; + IOptimismPortal2 optimismPortal2; DisputeGameFactory disputeGameFactory; DelayedWETH delayedWeth; IL2OutputOracle l2OutputOracle; - SystemConfig systemConfig; + ISystemConfig systemConfig; L1StandardBridge l1StandardBridge; - L1CrossDomainMessenger l1CrossDomainMessenger; + IL1CrossDomainMessenger l1CrossDomainMessenger; AddressManager addressManager; L1ERC721Bridge l1ERC721Bridge; OptimismMintableERC20Factory l1OptimismMintableERC20Factory; ProtocolVersions protocolVersions; - SuperchainConfig superchainConfig; - DataAvailabilityChallenge dataAvailabilityChallenge; + ISuperchainConfig superchainConfig; + IDataAvailabilityChallenge dataAvailabilityChallenge; AnchorStateRegistry anchorStateRegistry; L2CrossDomainMessenger l2CrossDomainMessenger = @@ -131,20 +140,20 @@ contract Setup { deploy.run(); console.log("Setup: completed L1 deployment, registering addresses now"); - optimismPortal = OptimismPortal(deploy.mustGetAddress("OptimismPortalProxy")); - optimismPortal2 = OptimismPortal2(deploy.mustGetAddress("OptimismPortalProxy")); + optimismPortal = IOptimismPortal(deploy.mustGetAddress("OptimismPortalProxy")); + optimismPortal2 = IOptimismPortal2(deploy.mustGetAddress("OptimismPortalProxy")); disputeGameFactory = DisputeGameFactory(deploy.mustGetAddress("DisputeGameFactoryProxy")); delayedWeth = DelayedWETH(deploy.mustGetAddress("DelayedWETHProxy")); l2OutputOracle = IL2OutputOracle(deploy.mustGetAddress("L2OutputOracleProxy")); - systemConfig = SystemConfig(deploy.mustGetAddress("SystemConfigProxy")); + systemConfig = ISystemConfig(deploy.mustGetAddress("SystemConfigProxy")); l1StandardBridge = L1StandardBridge(deploy.mustGetAddress("L1StandardBridgeProxy")); - l1CrossDomainMessenger = L1CrossDomainMessenger(deploy.mustGetAddress("L1CrossDomainMessengerProxy")); + l1CrossDomainMessenger = IL1CrossDomainMessenger(deploy.mustGetAddress("L1CrossDomainMessengerProxy")); addressManager = AddressManager(deploy.mustGetAddress("AddressManager")); l1ERC721Bridge = L1ERC721Bridge(deploy.mustGetAddress("L1ERC721BridgeProxy")); l1OptimismMintableERC20Factory = OptimismMintableERC20Factory(deploy.mustGetAddress("OptimismMintableERC20FactoryProxy")); protocolVersions = ProtocolVersions(deploy.mustGetAddress("ProtocolVersionsProxy")); - superchainConfig = SuperchainConfig(deploy.mustGetAddress("SuperchainConfigProxy")); + superchainConfig = ISuperchainConfig(deploy.mustGetAddress("SuperchainConfigProxy")); anchorStateRegistry = AnchorStateRegistry(deploy.mustGetAddress("AnchorStateRegistryProxy")); vm.label(address(l2OutputOracle), "L2OutputOracle"); @@ -174,7 +183,7 @@ contract Setup { if (deploy.cfg().useAltDA()) { dataAvailabilityChallenge = - DataAvailabilityChallenge(deploy.mustGetAddress("DataAvailabilityChallengeProxy")); + IDataAvailabilityChallenge(deploy.mustGetAddress("DataAvailabilityChallengeProxy")); vm.label(address(dataAvailabilityChallenge), "DataAvailabilityChallengeProxy"); vm.label(deploy.mustGetAddress("DataAvailabilityChallenge"), "DataAvailabilityChallenge"); } diff --git a/packages/contracts-bedrock/test/universal/CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/universal/CrossDomainMessenger.t.sol index f2a9a8d43d85..1fab9c6db1ce 100644 --- a/packages/contracts-bedrock/test/universal/CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/universal/CrossDomainMessenger.t.sol @@ -11,7 +11,7 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; import { Hashing } from "src/libraries/Hashing.sol"; import { Encoding } from "src/libraries/Encoding.sol"; -import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; +import { IL1CrossDomainMessenger } from "src/L1/interfaces/IL1CrossDomainMessenger.sol"; // CrossDomainMessenger_Test is for testing functionality which is common to both the L1 and L2 // CrossDomainMessenger contracts. For simplicity, we use the L1 Messenger as the test contract. @@ -45,11 +45,11 @@ contract CrossDomainMessenger_BaseGas_Test is Bridge_Initializer { contract ExternalRelay is Test { address internal op; address internal fuzzedSender; - L1CrossDomainMessenger internal l1CrossDomainMessenger; + IL1CrossDomainMessenger internal l1CrossDomainMessenger; event FailedRelayedMessage(bytes32 indexed msgHash); - constructor(L1CrossDomainMessenger _l1Messenger, address _op) { + constructor(IL1CrossDomainMessenger _l1Messenger, address _op) { l1CrossDomainMessenger = _l1Messenger; op = _op; } diff --git a/packages/contracts-bedrock/test/vendor/Initializable.t.sol b/packages/contracts-bedrock/test/vendor/Initializable.t.sol index 1f3ab1951ae3..52566f95ec1b 100644 --- a/packages/contracts-bedrock/test/vendor/Initializable.t.sol +++ b/packages/contracts-bedrock/test/vendor/Initializable.t.sol @@ -6,11 +6,11 @@ import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { Executables } from "scripts/libraries/Executables.sol"; import { Constants } from "src/libraries/Constants.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { SystemConfigInterop } from "src/L1/SystemConfigInterop.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; -import { ResourceMetering } from "src/L1/ResourceMetering.sol"; -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; @@ -108,7 +108,7 @@ contract Initializer_Test is Bridge_Initializer { InitializeableContract({ name: "DelayedWETH", target: deploy.mustGetAddress("DelayedWETH"), - initCalldata: abi.encodeCall(delayedWeth.initialize, (address(0), SuperchainConfig(address(0)))) + initCalldata: abi.encodeCall(delayedWeth.initialize, (address(0), ISuperchainConfig(address(0)))) }) ); // DelayedWETHProxy @@ -116,7 +116,7 @@ contract Initializer_Test is Bridge_Initializer { InitializeableContract({ name: "DelayedWETHProxy", target: address(delayedWeth), - initCalldata: abi.encodeCall(delayedWeth.initialize, (address(0), SuperchainConfig(address(0)))) + initCalldata: abi.encodeCall(delayedWeth.initialize, (address(0), ISuperchainConfig(address(0)))) }) ); // L2OutputOracleImpl @@ -181,7 +181,7 @@ contract Initializer_Test is Bridge_Initializer { bytes32(0), 1, address(0), - ResourceMetering.ResourceConfig({ + IResourceMetering.ResourceConfig({ maxResourceLimit: 1, elasticityMultiplier: 1, baseFeeMaxChangeDenominator: 2, @@ -190,7 +190,7 @@ contract Initializer_Test is Bridge_Initializer { maximumBaseFee: 0 }), address(0), - SystemConfig.Addresses({ + ISystemConfig.Addresses({ l1CrossDomainMessenger: address(0), l1ERC721Bridge: address(0), l1StandardBridge: address(0), @@ -217,7 +217,7 @@ contract Initializer_Test is Bridge_Initializer { bytes32(0), 1, address(0), - ResourceMetering.ResourceConfig({ + IResourceMetering.ResourceConfig({ maxResourceLimit: 1, elasticityMultiplier: 1, baseFeeMaxChangeDenominator: 2, @@ -226,7 +226,7 @@ contract Initializer_Test is Bridge_Initializer { maximumBaseFee: 0 }), address(0), - SystemConfig.Addresses({ + ISystemConfig.Addresses({ l1CrossDomainMessenger: address(0), l1ERC721Bridge: address(0), l1StandardBridge: address(0), @@ -264,7 +264,9 @@ contract Initializer_Test is Bridge_Initializer { InitializeableContract({ name: "L2CrossDomainMessenger", target: address(l2CrossDomainMessenger), - initCalldata: abi.encodeCall(l2CrossDomainMessenger.initialize, (l1CrossDomainMessenger)) + initCalldata: abi.encodeCall( + l2CrossDomainMessenger.initialize, (CrossDomainMessenger(address(l1CrossDomainMessenger))) + ) }) ); // L1StandardBridgeImpl @@ -273,7 +275,8 @@ contract Initializer_Test is Bridge_Initializer { name: "L1StandardBridge", target: deploy.mustGetAddress("L1StandardBridge"), initCalldata: abi.encodeCall( - l1StandardBridge.initialize, (l1CrossDomainMessenger, superchainConfig, systemConfig) + l1StandardBridge.initialize, + (ICrossDomainMessenger(address(l1CrossDomainMessenger)), superchainConfig, systemConfig) ) }) ); @@ -283,7 +286,8 @@ contract Initializer_Test is Bridge_Initializer { name: "L1StandardBridgeProxy", target: address(l1StandardBridge), initCalldata: abi.encodeCall( - l1StandardBridge.initialize, (l1CrossDomainMessenger, superchainConfig, systemConfig) + l1StandardBridge.initialize, + (ICrossDomainMessenger(address(l1CrossDomainMessenger)), superchainConfig, systemConfig) ) }) ); @@ -308,7 +312,9 @@ contract Initializer_Test is Bridge_Initializer { InitializeableContract({ name: "L1ERC721Bridge", target: deploy.mustGetAddress("L1ERC721Bridge"), - initCalldata: abi.encodeCall(l1ERC721Bridge.initialize, (l1CrossDomainMessenger, superchainConfig)) + initCalldata: abi.encodeCall( + l1ERC721Bridge.initialize, (ICrossDomainMessenger(address(l1CrossDomainMessenger)), superchainConfig) + ) }) ); // L1ERC721BridgeProxy @@ -316,7 +322,9 @@ contract Initializer_Test is Bridge_Initializer { InitializeableContract({ name: "L1ERC721BridgeProxy", target: address(l1ERC721Bridge), - initCalldata: abi.encodeCall(l1ERC721Bridge.initialize, (l1CrossDomainMessenger, superchainConfig)) + initCalldata: abi.encodeCall( + l1ERC721Bridge.initialize, (ICrossDomainMessenger(address(l1CrossDomainMessenger)), superchainConfig) + ) }) ); // L2ERC721Bridge @@ -366,7 +374,7 @@ contract Initializer_Test is Bridge_Initializer { target: address(anchorStateRegistry), initCalldata: abi.encodeCall( anchorStateRegistry.initialize, - (new AnchorStateRegistry.StartingAnchorRoot[](1), SuperchainConfig(address(0))) + (new AnchorStateRegistry.StartingAnchorRoot[](1), ISuperchainConfig(address(0))) ) }) ); @@ -377,7 +385,7 @@ contract Initializer_Test is Bridge_Initializer { target: address(anchorStateRegistry), initCalldata: abi.encodeCall( anchorStateRegistry.initialize, - (new AnchorStateRegistry.StartingAnchorRoot[](1), SuperchainConfig(address(0))) + (new AnchorStateRegistry.StartingAnchorRoot[](1), ISuperchainConfig(address(0))) ) }) ); From 707791b431a10d50cb70c9b4f4ce0baf8aa00148 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Wed, 11 Sep 2024 13:48:20 -0400 Subject: [PATCH 094/264] ci: selectively build contracts (#11824) Updates the contracts-bedrock-tests job to only build the specific tests that are being tested as part of the test split for that job. Also merges the other contracts-bedrock-build with build-devnet-allocs since this is a bottleneck now. Overall impact is that CI time is now 7-10 minutes. --- .circleci/config.yml | 117 +++++++++++++++++++++---------------------- 1 file changed, 56 insertions(+), 61 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 08f79a7662ae..2abeb3c0c437 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -189,10 +189,22 @@ jobs: parameters: build_command: type: string - default: just prebuild && forge build --deny-warnings + default: | + just prebuild + forge build --deny-warnings steps: - checkout - install-contracts-dependencies + - restore_cache: + name: Restore Go modules cache + keys: + - gomod-contracts-build-{{ checksum "go.sum" }} + - gomod-contracts-build- + - restore_cache: + name: Restore Go build cache + keys: + - golang-build-cache-contracts-build-{{ checksum "go.sum" }} + - golang-build-cache-contracts-build- - run: name: Print forge version command: forge --version @@ -206,35 +218,6 @@ jobs: environment: FOUNDRY_PROFILE: ci working_directory: packages/contracts-bedrock - - persist_to_workspace: - root: "." - paths: - - ".git" - - "packages/contracts-bedrock/lib" - - "packages/contracts-bedrock/cache" - - "packages/contracts-bedrock/artifacts" - - "packages/contracts-bedrock/forge-artifacts" - - notify-failures-on-develop - - build-devnet-allocs: - docker: - - image: <> - resource_class: xlarge - steps: - - checkout - - attach_workspace: { at: "." } - - install-contracts-dependencies -# - run: # temporarily disabled, to update ci-builder. -# name: "Check L1 geth version" -# command: ./ops/scripts/geth-version-checker.sh || (echo "geth version is wrong, update ci-builder"; false) - - restore_cache: - name: Restore Go modules cache - key: gomod-allocs-{{ checksum "go.sum" }} - - restore_cache: - name: Restore Go build cache - keys: - - golang-build-cache-allocs-{{ checksum "go.sum" }} - - golang-build-cache-allocs- - run: name: Generate L2OO allocs command: DEVNET_L2OO="true" make devnet-allocs @@ -258,17 +241,20 @@ jobs: command: make devnet-allocs - save_cache: name: Save Go modules cache - key: gomod-allocs-{{ checksum "go.sum" }} + key: gomod-contracts-build-{{ checksum "go.sum" }} paths: - "/go/pkg/mod" - save_cache: name: Save Go build cache - key: golang-build-cache-allocs-{{ checksum "go.sum" }} + key: golang-build-cache-contracts-build-{{ checksum "go.sum" }} paths: - "/root/.cache/go-build" - persist_to_workspace: root: "." paths: + - "packages/contracts-bedrock/cache" + - "packages/contracts-bedrock/artifacts" + - "packages/contracts-bedrock/forge-artifacts" - ".devnet/allocs-l1.json" - ".devnet/allocs-l2-delta.json" - ".devnet/allocs-l2-ecotone.json" @@ -565,7 +551,16 @@ jobs: docker: - image: <> resource_class: xlarge - parallelism: 4 + parameters: + test_parallelism: + description: Number of test jobs to run in parallel + type: integer + default: 4 + test_filter: + description: List of test files to run + type: string + default: find ./test -name "*.t.sol" + parallelism: <> steps: - checkout - attach_workspace: { at: "." } @@ -588,6 +583,10 @@ jobs: name: print forge version command: forge --version working_directory: packages/contracts-bedrock + - run: + name: Pull artifacts + command: bash scripts/ops/pull-artifacts.sh + working_directory: packages/contracts-bedrock - run: name: build go-ffi command: just build-go-ffi @@ -596,7 +595,7 @@ jobs: name: run tests command: | # Find all test files - TEST_FILES=$(find ./test -name "*.t.sol") + TEST_FILES=$(<>) # Split the tests by timings TEST_FILES=$(echo "$TEST_FILES" | circleci tests split --split-by=timings) # Strip the leading "./test/" from each file path @@ -621,6 +620,7 @@ jobs: key: golang-build-cache-contracts-bedrock-tests-{{ checksum "go.sum" }} paths: - "/root/.cache/go-build" + - notify-failures-on-develop contracts-bedrock-checks: docker: @@ -1566,25 +1566,26 @@ workflows: equal: [ scheduled_pipeline, << pipeline.trigger_source >> ] jobs: - go-mod-download - - contracts-bedrock-build - contracts-bedrock-build: - name: contracts-bedrock-build-skip-tests - build_command: forge build --skip test + name: contracts-bedrock-build + build_command: | + forge build --skip test --skip scripts + forge build ./scripts/deploy/Deploy.s.sol - contracts-bedrock-tests: - requires: - - contracts-bedrock-build - - go-mod-download + test_filter: find . -name "*.t.sol" -not -name "PreimageOracle.t.sol" + test_parallelism: 4 + - contracts-bedrock-tests: + # PreimageOracle test is slow, run it separately to unblock CI + name: contracts-bedrock-tests-preimage-oracle + test_filter: find . -name "PreimageOracle.t.sol" + test_parallelism: 1 - contracts-bedrock-coverage - contracts-bedrock-checks: requires: - - contracts-bedrock-build-skip-tests + - contracts-bedrock-build - contracts-bedrock-validate-spacers: requires: - - contracts-bedrock-build-skip-tests - - build-devnet-allocs: - requires: - - contracts-bedrock-build-skip-tests - - go-mod-download + - contracts-bedrock-build - semgrep-scan - go-lint: requires: @@ -1614,13 +1615,13 @@ workflows: package_name: cannon on_changes: cannon,packages/contracts-bedrock/src/cannon uses_artifacts: true - requires: ["go-mod-download", "build-devnet-allocs"] + requires: ["go-mod-download", "contracts-bedrock-build"] - fuzz-golang: name: op-e2e-fuzz package_name: op-e2e on_changes: op-e2e,packages/contracts-bedrock/src uses_artifacts: true - requires: ["go-mod-download", "build-devnet-allocs"] + requires: ["go-mod-download", "contracts-bedrock-build"] - go-test: name: op-batcher-tests module: op-batcher @@ -1671,7 +1672,7 @@ workflows: parallelism: 4 requires: - go-mod-download - - build-devnet-allocs + - contracts-bedrock-build - go-e2e-test: name: op-e2e-action-tests<< matrix.variant >> matrix: @@ -1682,14 +1683,14 @@ workflows: parallelism: 1 requires: - go-mod-download - - build-devnet-allocs + - contracts-bedrock-build - go-e2e-test: name: op-e2e-fault-proof-tests module: op-e2e target: test-fault-proofs parallelism: 4 requires: - - build-devnet-allocs + - contracts-bedrock-build - cannon-prestate - op-program-compat: requires: @@ -1770,7 +1771,7 @@ workflows: parameters: variant: ["default", "altda", "altda-generic"] requires: - - build-devnet-allocs + - contracts-bedrock-build - op-batcher-docker-build - op-proposer-docker-build - op-node-docker-build @@ -1781,7 +1782,7 @@ workflows: - check-generated-mocks-op-service - cannon-go-lint-and-test: requires: - - build-devnet-allocs + - contracts-bedrock-build - cannon-build-test-vectors - shellcheck/check: name: shell-check @@ -2049,13 +2050,7 @@ workflows: - cannon-prestate: requires: - go-mod-download - - contracts-bedrock-build: - requires: - - go-mod-download - - build-devnet-allocs: - name: build-devnet-allocs - requires: - - contracts-bedrock-build + - contracts-bedrock-build - go-e2e-test: name: op-e2e-cannon-tests module: op-e2e @@ -2064,7 +2059,7 @@ workflows: notify: true mentions: "@proofs-squad" requires: - - build-devnet-allocs + - contracts-bedrock-build - cannon-prestate context: - slack From 84b1cde384f37b73ad322cc25633ce94bca621e1 Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Wed, 11 Sep 2024 12:14:17 -0600 Subject: [PATCH 095/264] Add entrypoint to deploy against existing Superchain (#11791) * Add entrypoint to deploy against existing Superchain Creates a separate entrypoint in the deploy script to allow an L2 to be deployed against an existing set of Superchain contracts. The deployment assumes that the Superchain contracts have been deployed correctly. The L2 still gets its own ProxyAdmin, AddressManager, and Safe. The API is additive and backwards-compatible. * Update packages/contracts-bedrock/scripts/deploy/Deploy.s.sol Co-authored-by: Maurelian * remove redundant call --------- Co-authored-by: Maurelian --- .../scripts/deploy/Deploy.s.sol | 67 ++++++++++++++++--- 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol b/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol index 71828ebc3ba1..3399ef09da15 100644 --- a/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol @@ -279,6 +279,39 @@ contract Deploy is Deployer { _run(); } + /// @notice Deploy a new OP Chain using an existing SuperchainConfig and ProtocolVersions + /// @param _superchainConfigProxy Address of the existing SuperchainConfig proxy + /// @param _protocolVersionsProxy Address of the existing ProtocolVersions proxy + /// @param includeDump Whether to include a state dump after deployment + function runWithSuperchain( + address payable _superchainConfigProxy, + address payable _protocolVersionsProxy, + bool includeDump + ) + public + { + require(_superchainConfigProxy != address(0), "must specify address for superchain config proxy"); + require(_protocolVersionsProxy != address(0), "must specify address for protocol versions proxy"); + + vm.chainId(cfg.l1ChainID()); + + console.log("Deploying a fresh OP Stack with existing SuperchainConfig and ProtocolVersions"); + + Proxy scProxy = Proxy(_superchainConfigProxy); + save("SuperchainConfig", scProxy.implementation()); + save("SuperchainConfigProxy", _superchainConfigProxy); + + Proxy pvProxy = Proxy(_protocolVersionsProxy); + save("ProtocolVersions", pvProxy.implementation()); + save("ProtocolVersionsProxy", _protocolVersionsProxy); + + _run(false); + + if (includeDump) { + vm.dumpState(Config.stateDumpPath("")); + } + } + function runWithStateDump() public { vm.chainId(cfg.l1ChainID()); _run(); @@ -290,13 +323,27 @@ contract Deploy is Deployer { _run(); } - /// @notice Internal function containing the deploy logic. + /// @notice Compatibility function for tests that override _run(). function _run() internal virtual { + _run(true); + } + + /// @notice Internal function containing the deploy logic. + function _run(bool _needsSuperchain) internal { console.log("start of L1 Deploy!"); deploySafe("SystemOwnerSafe"); console.log("deployed Safe!"); - setupSuperchain(); - console.log("set up superchain!"); + + // Deploy a new ProxyAdmin and AddressManager + // This proxy will be used on the SuperchainConfig and ProtocolVersions contracts, as well as the contracts + // in the OP Chain system. + setupAdmin(); + + if (_needsSuperchain) { + setupSuperchain(); + console.log("set up superchain!"); + } + if (cfg.useAltDA()) { bytes32 typeHash = keccak256(bytes(cfg.daCommitmentType())); bytes32 keccakHash = keccak256(bytes("KeccakCommitment")); @@ -312,6 +359,13 @@ contract Deploy is Deployer { // High Level Deployment Functions // //////////////////////////////////////////////////////////////// + /// @notice Deploy the address manager and proxy admin contracts. + function setupAdmin() public { + deployAddressManager(); + deployProxyAdmin(); + transferProxyAdminOwnership(); + } + /// @notice Deploy a full system with a new SuperchainConfig /// The Superchain system has 2 singleton contracts which lie outside of an OP Chain: /// 1. The SuperchainConfig contract @@ -319,13 +373,6 @@ contract Deploy is Deployer { function setupSuperchain() public { console.log("Setting up Superchain"); - // Deploy a new ProxyAdmin and AddressManager - // This proxy will be used on the SuperchainConfig and ProtocolVersions contracts, as well as the contracts - // in the OP Chain system. - deployAddressManager(); - deployProxyAdmin(); - transferProxyAdminOwnership(); - // Deploy the SuperchainConfigProxy deployERC1967Proxy("SuperchainConfigProxy"); deploySuperchainConfig(); From 144a775072cb35da123d23f97cabc51e6c4d69e4 Mon Sep 17 00:00:00 2001 From: Matt Solomon Date: Wed, 11 Sep 2024 11:53:11 -0700 Subject: [PATCH 096/264] test: fix test and variable naming conventions (#11845) --- .../scripts/DeployImplementations.s.sol | 168 +++++++------- .../scripts/DeployOPChain.s.sol | 92 ++++---- .../scripts/DeploySuperchain.s.sol | 10 +- .../test/DeployImplementations.t.sol | 184 +++++++-------- .../test/DeployOPChain.t.sol | 218 +++++++++--------- .../test/DeploySuperchain.t.sol | 2 +- 6 files changed, 341 insertions(+), 333 deletions(-) diff --git a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol index 3de9f3285ccc..dfe6a61cdaa1 100644 --- a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol +++ b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol @@ -239,11 +239,11 @@ contract DeployImplementations is Script { // -------- Core Deployment Methods -------- function run(string memory _infile) public { - (DeployImplementationsInput dsi, DeployImplementationsOutput dso) = etchIOContracts(); - dsi.loadInputFile(_infile); - run(dsi, dso); + (DeployImplementationsInput dii, DeployImplementationsOutput dio) = etchIOContracts(); + dii.loadInputFile(_infile); + run(dii, dio); string memory outfile = ""; // This will be derived from input file name, e.g. `foo.in.toml` -> `foo.out.toml` - dso.writeOutputFile(outfile); + dio.writeOutputFile(outfile); require(false, "DeployImplementations: run is not implemented"); } @@ -251,31 +251,31 @@ contract DeployImplementations is Script { public returns (DeployImplementationsOutput.Output memory) { - (DeployImplementationsInput dsi, DeployImplementationsOutput dso) = etchIOContracts(); - dsi.loadInput(_input); - run(dsi, dso); - return dso.output(); + (DeployImplementationsInput dii, DeployImplementationsOutput dio) = etchIOContracts(); + dii.loadInput(_input); + run(dii, dio); + return dio.output(); } - function run(DeployImplementationsInput _dsi, DeployImplementationsOutput _dso) public { - require(_dsi.inputSet(), "DeployImplementations: input not set"); + function run(DeployImplementationsInput _dii, DeployImplementationsOutput _dio) public { + require(_dii.inputSet(), "DeployImplementations: input not set"); // Deploy the implementations. - deploySystemConfigImpl(_dsi, _dso); - deployL1CrossDomainMessengerImpl(_dsi, _dso); - deployL1ERC721BridgeImpl(_dsi, _dso); - deployL1StandardBridgeImpl(_dsi, _dso); - deployOptimismMintableERC20FactoryImpl(_dsi, _dso); - deployOptimismPortalImpl(_dsi, _dso); - deployDelayedWETHImpl(_dsi, _dso); - deployPreimageOracleSingleton(_dsi, _dso); - deployMipsSingleton(_dsi, _dso); - deployDisputeGameFactoryImpl(_dsi, _dso); + deploySystemConfigImpl(_dii, _dio); + deployL1CrossDomainMessengerImpl(_dii, _dio); + deployL1ERC721BridgeImpl(_dii, _dio); + deployL1StandardBridgeImpl(_dii, _dio); + deployOptimismMintableERC20FactoryImpl(_dii, _dio); + deployOptimismPortalImpl(_dii, _dio); + deployDelayedWETHImpl(_dii, _dio); + deployPreimageOracleSingleton(_dii, _dio); + deployMipsSingleton(_dii, _dio); + deployDisputeGameFactoryImpl(_dii, _dio); // Deploy the OP Stack Manager with the new implementations set. - deployOPStackManager(_dsi, _dso); + deployOPStackManager(_dii, _dio); - _dso.checkOutput(); + _dio.checkOutput(); } // -------- Deployment Steps -------- @@ -284,7 +284,7 @@ contract DeployImplementations is Script { function opsmSystemConfigSetter( DeployImplementationsInput, - DeployImplementationsOutput _dso + DeployImplementationsOutput _dio ) internal view @@ -293,12 +293,12 @@ contract DeployImplementations is Script { { return OPStackManager.ImplementationSetter({ name: "SystemConfig", - info: OPStackManager.Implementation(address(_dso.systemConfigImpl()), SystemConfig.initialize.selector) + info: OPStackManager.Implementation(address(_dio.systemConfigImpl()), SystemConfig.initialize.selector) }); } function createOPSMContract( - DeployImplementationsInput _dsi, + DeployImplementationsInput _dii, DeployImplementationsOutput, OPStackManager.Blueprints memory blueprints ) @@ -306,8 +306,8 @@ contract DeployImplementations is Script { virtual returns (OPStackManager opsm_) { - SuperchainConfig superchainConfigProxy = _dsi.superchainConfigProxy(); - ProtocolVersions protocolVersionsProxy = _dsi.protocolVersionsProxy(); + SuperchainConfig superchainConfigProxy = _dii.superchainConfigProxy(); + ProtocolVersions protocolVersionsProxy = _dii.protocolVersionsProxy(); vm.broadcast(msg.sender); opsm_ = new OPStackManager({ @@ -317,8 +317,8 @@ contract DeployImplementations is Script { }); } - function deployOPStackManager(DeployImplementationsInput _dsi, DeployImplementationsOutput _dso) public virtual { - string memory release = _dsi.release(); + function deployOPStackManager(DeployImplementationsInput _dii, DeployImplementationsOutput _dio) public virtual { + string memory release = _dii.release(); // First we deploy the blueprints for the singletons deployed by OPSM. // forgefmt: disable-start @@ -335,55 +335,55 @@ contract DeployImplementations is Script { // forgefmt: disable-end // This call contains a broadcast to deploy OPSM. - OPStackManager opsm = createOPSMContract(_dsi, _dso, blueprints); + OPStackManager opsm = createOPSMContract(_dii, _dio, blueprints); OPStackManager.ImplementationSetter[] memory setters = new OPStackManager.ImplementationSetter[](6); setters[0] = OPStackManager.ImplementationSetter({ name: "L1ERC721Bridge", - info: OPStackManager.Implementation(address(_dso.l1ERC721BridgeImpl()), L1ERC721Bridge.initialize.selector) + info: OPStackManager.Implementation(address(_dio.l1ERC721BridgeImpl()), L1ERC721Bridge.initialize.selector) }); setters[1] = OPStackManager.ImplementationSetter({ name: "OptimismPortal", - info: OPStackManager.Implementation(address(_dso.optimismPortalImpl()), OptimismPortal2.initialize.selector) + info: OPStackManager.Implementation(address(_dio.optimismPortalImpl()), OptimismPortal2.initialize.selector) }); - setters[2] = opsmSystemConfigSetter(_dsi, _dso); + setters[2] = opsmSystemConfigSetter(_dii, _dio); setters[3] = OPStackManager.ImplementationSetter({ name: "OptimismMintableERC20Factory", info: OPStackManager.Implementation( - address(_dso.optimismMintableERC20FactoryImpl()), OptimismMintableERC20Factory.initialize.selector + address(_dio.optimismMintableERC20FactoryImpl()), OptimismMintableERC20Factory.initialize.selector ) }); setters[4] = OPStackManager.ImplementationSetter({ name: "L1CrossDomainMessenger", info: OPStackManager.Implementation( - address(_dso.l1CrossDomainMessengerImpl()), L1CrossDomainMessenger.initialize.selector + address(_dio.l1CrossDomainMessengerImpl()), L1CrossDomainMessenger.initialize.selector ) }); setters[5] = OPStackManager.ImplementationSetter({ name: "L1StandardBridge", - info: OPStackManager.Implementation(address(_dso.l1StandardBridgeImpl()), L1StandardBridge.initialize.selector) + info: OPStackManager.Implementation(address(_dio.l1StandardBridgeImpl()), L1StandardBridge.initialize.selector) }); vm.broadcast(msg.sender); opsm.setRelease({ _release: release, _isLatest: true, _setters: setters }); vm.label(address(opsm), "OPStackManager"); - _dso.set(_dso.opsm.selector, address(opsm)); + _dio.set(_dio.opsm.selector, address(opsm)); } // --- Core Contracts --- - function deploySystemConfigImpl(DeployImplementationsInput, DeployImplementationsOutput _dso) public virtual { + function deploySystemConfigImpl(DeployImplementationsInput, DeployImplementationsOutput _dio) public virtual { vm.broadcast(msg.sender); SystemConfig systemConfigImpl = new SystemConfig(); vm.label(address(systemConfigImpl), "systemConfigImpl"); - _dso.set(_dso.systemConfigImpl.selector, address(systemConfigImpl)); + _dio.set(_dio.systemConfigImpl.selector, address(systemConfigImpl)); } function deployL1CrossDomainMessengerImpl( DeployImplementationsInput, - DeployImplementationsOutput _dso + DeployImplementationsOutput _dio ) public virtual @@ -392,28 +392,28 @@ contract DeployImplementations is Script { L1CrossDomainMessenger l1CrossDomainMessengerImpl = new L1CrossDomainMessenger(); vm.label(address(l1CrossDomainMessengerImpl), "L1CrossDomainMessengerImpl"); - _dso.set(_dso.l1CrossDomainMessengerImpl.selector, address(l1CrossDomainMessengerImpl)); + _dio.set(_dio.l1CrossDomainMessengerImpl.selector, address(l1CrossDomainMessengerImpl)); } - function deployL1ERC721BridgeImpl(DeployImplementationsInput, DeployImplementationsOutput _dso) public virtual { + function deployL1ERC721BridgeImpl(DeployImplementationsInput, DeployImplementationsOutput _dio) public virtual { vm.broadcast(msg.sender); L1ERC721Bridge l1ERC721BridgeImpl = new L1ERC721Bridge(); vm.label(address(l1ERC721BridgeImpl), "L1ERC721BridgeImpl"); - _dso.set(_dso.l1ERC721BridgeImpl.selector, address(l1ERC721BridgeImpl)); + _dio.set(_dio.l1ERC721BridgeImpl.selector, address(l1ERC721BridgeImpl)); } - function deployL1StandardBridgeImpl(DeployImplementationsInput, DeployImplementationsOutput _dso) public virtual { + function deployL1StandardBridgeImpl(DeployImplementationsInput, DeployImplementationsOutput _dio) public virtual { vm.broadcast(msg.sender); L1StandardBridge l1StandardBridgeImpl = new L1StandardBridge(); vm.label(address(l1StandardBridgeImpl), "L1StandardBridgeImpl"); - _dso.set(_dso.l1StandardBridgeImpl.selector, address(l1StandardBridgeImpl)); + _dio.set(_dio.l1StandardBridgeImpl.selector, address(l1StandardBridgeImpl)); } function deployOptimismMintableERC20FactoryImpl( DeployImplementationsInput, - DeployImplementationsOutput _dso + DeployImplementationsOutput _dio ) public virtual @@ -422,7 +422,7 @@ contract DeployImplementations is Script { OptimismMintableERC20Factory optimismMintableERC20FactoryImpl = new OptimismMintableERC20Factory(); vm.label(address(optimismMintableERC20FactoryImpl), "OptimismMintableERC20FactoryImpl"); - _dso.set(_dso.optimismMintableERC20FactoryImpl.selector, address(optimismMintableERC20FactoryImpl)); + _dio.set(_dio.optimismMintableERC20FactoryImpl.selector, address(optimismMintableERC20FactoryImpl)); } // --- Fault Proofs Contracts --- @@ -448,14 +448,14 @@ contract DeployImplementations is Script { // - MIPS (singleton) function deployOptimismPortalImpl( - DeployImplementationsInput _dsi, - DeployImplementationsOutput _dso + DeployImplementationsInput _dii, + DeployImplementationsOutput _dio ) public virtual { - uint256 proofMaturityDelaySeconds = _dsi.proofMaturityDelaySeconds(); - uint256 disputeGameFinalityDelaySeconds = _dsi.disputeGameFinalityDelaySeconds(); + uint256 proofMaturityDelaySeconds = _dii.proofMaturityDelaySeconds(); + uint256 disputeGameFinalityDelaySeconds = _dii.disputeGameFinalityDelaySeconds(); vm.broadcast(msg.sender); OptimismPortal2 optimismPortalImpl = new OptimismPortal2({ @@ -464,50 +464,50 @@ contract DeployImplementations is Script { }); vm.label(address(optimismPortalImpl), "OptimismPortalImpl"); - _dso.set(_dso.optimismPortalImpl.selector, address(optimismPortalImpl)); + _dio.set(_dio.optimismPortalImpl.selector, address(optimismPortalImpl)); } - function deployDelayedWETHImpl(DeployImplementationsInput _dsi, DeployImplementationsOutput _dso) public virtual { - uint256 withdrawalDelaySeconds = _dsi.withdrawalDelaySeconds(); + function deployDelayedWETHImpl(DeployImplementationsInput _dii, DeployImplementationsOutput _dio) public virtual { + uint256 withdrawalDelaySeconds = _dii.withdrawalDelaySeconds(); vm.broadcast(msg.sender); DelayedWETH delayedWETHImpl = new DelayedWETH({ _delay: withdrawalDelaySeconds }); vm.label(address(delayedWETHImpl), "DelayedWETHImpl"); - _dso.set(_dso.delayedWETHImpl.selector, address(delayedWETHImpl)); + _dio.set(_dio.delayedWETHImpl.selector, address(delayedWETHImpl)); } function deployPreimageOracleSingleton( - DeployImplementationsInput _dsi, - DeployImplementationsOutput _dso + DeployImplementationsInput _dii, + DeployImplementationsOutput _dio ) public virtual { - uint256 minProposalSizeBytes = _dsi.minProposalSizeBytes(); - uint256 challengePeriodSeconds = _dsi.challengePeriodSeconds(); + uint256 minProposalSizeBytes = _dii.minProposalSizeBytes(); + uint256 challengePeriodSeconds = _dii.challengePeriodSeconds(); vm.broadcast(msg.sender); PreimageOracle preimageOracleSingleton = new PreimageOracle({ _minProposalSize: minProposalSizeBytes, _challengePeriod: challengePeriodSeconds }); vm.label(address(preimageOracleSingleton), "PreimageOracleSingleton"); - _dso.set(_dso.preimageOracleSingleton.selector, address(preimageOracleSingleton)); + _dio.set(_dio.preimageOracleSingleton.selector, address(preimageOracleSingleton)); } - function deployMipsSingleton(DeployImplementationsInput, DeployImplementationsOutput _dso) public virtual { - IPreimageOracle preimageOracle = IPreimageOracle(_dso.preimageOracleSingleton()); + function deployMipsSingleton(DeployImplementationsInput, DeployImplementationsOutput _dio) public virtual { + IPreimageOracle preimageOracle = IPreimageOracle(_dio.preimageOracleSingleton()); vm.broadcast(msg.sender); MIPS mipsSingleton = new MIPS(preimageOracle); vm.label(address(mipsSingleton), "MIPSSingleton"); - _dso.set(_dso.mipsSingleton.selector, address(mipsSingleton)); + _dio.set(_dio.mipsSingleton.selector, address(mipsSingleton)); } function deployDisputeGameFactoryImpl( DeployImplementationsInput, - DeployImplementationsOutput _dso + DeployImplementationsOutput _dio ) public virtual @@ -516,20 +516,20 @@ contract DeployImplementations is Script { DisputeGameFactory disputeGameFactoryImpl = new DisputeGameFactory(); vm.label(address(disputeGameFactoryImpl), "DisputeGameFactoryImpl"); - _dso.set(_dso.disputeGameFactoryImpl.selector, address(disputeGameFactoryImpl)); + _dio.set(_dio.disputeGameFactoryImpl.selector, address(disputeGameFactoryImpl)); } // -------- Utilities -------- - function etchIOContracts() internal returns (DeployImplementationsInput dsi_, DeployImplementationsOutput dso_) { - (dsi_, dso_) = getIOContracts(); - vm.etch(address(dsi_), type(DeployImplementationsInput).runtimeCode); - vm.etch(address(dso_), type(DeployImplementationsOutput).runtimeCode); + function etchIOContracts() internal returns (DeployImplementationsInput dii_, DeployImplementationsOutput dio_) { + (dii_, dio_) = getIOContracts(); + vm.etch(address(dii_), type(DeployImplementationsInput).runtimeCode); + vm.etch(address(dio_), type(DeployImplementationsOutput).runtimeCode); } - function getIOContracts() public view returns (DeployImplementationsInput dsi_, DeployImplementationsOutput dso_) { - dsi_ = DeployImplementationsInput(DeployUtils.toIOAddress(msg.sender, "optimism.DeployImplementationsInput")); - dso_ = DeployImplementationsOutput(DeployUtils.toIOAddress(msg.sender, "optimism.DeployImplementationsOutput")); + function getIOContracts() public view returns (DeployImplementationsInput dii_, DeployImplementationsOutput dio_) { + dii_ = DeployImplementationsInput(DeployUtils.toIOAddress(msg.sender, "optimism.DeployImplementationsInput")); + dio_ = DeployImplementationsOutput(DeployUtils.toIOAddress(msg.sender, "optimism.DeployImplementationsOutput")); } function deployBytecode(bytes memory _bytecode, bytes32 _salt) public returns (address newContract_) { @@ -574,7 +574,7 @@ contract DeployImplementations is Script { // is the same as the proxy admin owner. contract DeployImplementationsInterop is DeployImplementations { function createOPSMContract( - DeployImplementationsInput _dsi, + DeployImplementationsInput _dii, DeployImplementationsOutput, OPStackManager.Blueprints memory blueprints ) @@ -582,8 +582,8 @@ contract DeployImplementationsInterop is DeployImplementations { override returns (OPStackManager opsm_) { - SuperchainConfig superchainConfigProxy = _dsi.superchainConfigProxy(); - ProtocolVersions protocolVersionsProxy = _dsi.protocolVersionsProxy(); + SuperchainConfig superchainConfigProxy = _dii.superchainConfigProxy(); + ProtocolVersions protocolVersionsProxy = _dii.protocolVersionsProxy(); vm.broadcast(msg.sender); opsm_ = new OPStackManagerInterop({ @@ -594,14 +594,14 @@ contract DeployImplementationsInterop is DeployImplementations { } function deployOptimismPortalImpl( - DeployImplementationsInput _dsi, - DeployImplementationsOutput _dso + DeployImplementationsInput _dii, + DeployImplementationsOutput _dio ) public override { - uint256 proofMaturityDelaySeconds = _dsi.proofMaturityDelaySeconds(); - uint256 disputeGameFinalityDelaySeconds = _dsi.disputeGameFinalityDelaySeconds(); + uint256 proofMaturityDelaySeconds = _dii.proofMaturityDelaySeconds(); + uint256 disputeGameFinalityDelaySeconds = _dii.disputeGameFinalityDelaySeconds(); vm.broadcast(msg.sender); OptimismPortalInterop optimismPortalImpl = new OptimismPortalInterop({ @@ -610,20 +610,20 @@ contract DeployImplementationsInterop is DeployImplementations { }); vm.label(address(optimismPortalImpl), "OptimismPortalImpl"); - _dso.set(_dso.optimismPortalImpl.selector, address(optimismPortalImpl)); + _dio.set(_dio.optimismPortalImpl.selector, address(optimismPortalImpl)); } - function deploySystemConfigImpl(DeployImplementationsInput, DeployImplementationsOutput _dso) public override { + function deploySystemConfigImpl(DeployImplementationsInput, DeployImplementationsOutput _dio) public override { vm.broadcast(msg.sender); SystemConfigInterop systemConfigImpl = new SystemConfigInterop(); vm.label(address(systemConfigImpl), "systemConfigImpl"); - _dso.set(_dso.systemConfigImpl.selector, address(systemConfigImpl)); + _dio.set(_dio.systemConfigImpl.selector, address(systemConfigImpl)); } function opsmSystemConfigSetter( DeployImplementationsInput, - DeployImplementationsOutput _dso + DeployImplementationsOutput _dio ) internal view @@ -632,7 +632,7 @@ contract DeployImplementationsInterop is DeployImplementations { { return OPStackManager.ImplementationSetter({ name: "SystemConfig", - info: OPStackManager.Implementation(address(_dso.systemConfigImpl()), SystemConfigInterop.initialize.selector) + info: OPStackManager.Implementation(address(_dio.systemConfigImpl()), SystemConfigInterop.initialize.selector) }); } } diff --git a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol index 17693f010a38..1c0c29c83f83 100644 --- a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol @@ -292,39 +292,39 @@ contract DeployOPChainOutput { contract DeployOPChain is Script { // -------- Core Deployment Methods -------- function run(string memory _infile) public { - (DeployOPChainInput dsi, DeployOPChainOutput dso) = etchIOContracts(); - dsi.loadInputFile(_infile); - run(dsi, dso); + (DeployOPChainInput doi, DeployOPChainOutput doo) = etchIOContracts(); + doi.loadInputFile(_infile); + run(doi, doo); string memory outfile = ""; // This will be derived from input file name, e.g. `foo.in.toml` -> `foo.out.toml` - dso.writeOutputFile(outfile); + doo.writeOutputFile(outfile); require(false, "DeployOPChain: run is not implemented"); } function run(DeployOPChainInput.Input memory _input) public returns (DeployOPChainOutput.Output memory) { - (DeployOPChainInput dsi, DeployOPChainOutput dso) = etchIOContracts(); - dsi.loadInput(_input); - run(dsi, dso); - return dso.output(); + (DeployOPChainInput doi, DeployOPChainOutput doo) = etchIOContracts(); + doi.loadInput(_input); + run(doi, doo); + return doo.output(); } - function run(DeployOPChainInput _dsi, DeployOPChainOutput _dso) public { - require(_dsi.inputSet(), "DeployOPChain: input not set"); + function run(DeployOPChainInput _doi, DeployOPChainOutput _doo) public { + require(_doi.inputSet(), "DeployOPChain: input not set"); - OPStackManager opsm = _dsi.opsm(); + OPStackManager opsm = _doi.opsm(); OPStackManager.Roles memory roles = OPStackManager.Roles({ - opChainProxyAdminOwner: _dsi.opChainProxyAdminOwner(), - systemConfigOwner: _dsi.systemConfigOwner(), - batcher: _dsi.batcher(), - unsafeBlockSigner: _dsi.unsafeBlockSigner(), - proposer: _dsi.proposer(), - challenger: _dsi.challenger() + opChainProxyAdminOwner: _doi.opChainProxyAdminOwner(), + systemConfigOwner: _doi.systemConfigOwner(), + batcher: _doi.batcher(), + unsafeBlockSigner: _doi.unsafeBlockSigner(), + proposer: _doi.proposer(), + challenger: _doi.challenger() }); OPStackManager.DeployInput memory deployInput = OPStackManager.DeployInput({ roles: roles, - basefeeScalar: _dsi.basefeeScalar(), - blobBasefeeScalar: _dsi.blobBaseFeeScalar(), - l2ChainId: _dsi.l2ChainId() + basefeeScalar: _doi.basefeeScalar(), + blobBasefeeScalar: _doi.blobBaseFeeScalar(), + l2ChainId: _doi.l2ChainId() }); vm.broadcast(msg.sender); @@ -347,40 +347,40 @@ contract DeployOPChain is Script { vm.label(address(deployOutput.delayedWETHPermissionedGameProxy), "delayedWETHPermissionedGameProxy"); vm.label(address(deployOutput.delayedWETHPermissionlessGameProxy), "delayedWETHPermissionlessGameProxy"); - _dso.set(_dso.opChainProxyAdmin.selector, address(deployOutput.opChainProxyAdmin)); - _dso.set(_dso.addressManager.selector, address(deployOutput.addressManager)); - _dso.set(_dso.l1ERC721BridgeProxy.selector, address(deployOutput.l1ERC721BridgeProxy)); - _dso.set(_dso.systemConfigProxy.selector, address(deployOutput.systemConfigProxy)); - _dso.set( - _dso.optimismMintableERC20FactoryProxy.selector, address(deployOutput.optimismMintableERC20FactoryProxy) + _doo.set(_doo.opChainProxyAdmin.selector, address(deployOutput.opChainProxyAdmin)); + _doo.set(_doo.addressManager.selector, address(deployOutput.addressManager)); + _doo.set(_doo.l1ERC721BridgeProxy.selector, address(deployOutput.l1ERC721BridgeProxy)); + _doo.set(_doo.systemConfigProxy.selector, address(deployOutput.systemConfigProxy)); + _doo.set( + _doo.optimismMintableERC20FactoryProxy.selector, address(deployOutput.optimismMintableERC20FactoryProxy) ); - _dso.set(_dso.l1StandardBridgeProxy.selector, address(deployOutput.l1StandardBridgeProxy)); - _dso.set(_dso.l1CrossDomainMessengerProxy.selector, address(deployOutput.l1CrossDomainMessengerProxy)); - _dso.set(_dso.optimismPortalProxy.selector, address(deployOutput.optimismPortalProxy)); - _dso.set(_dso.disputeGameFactoryProxy.selector, address(deployOutput.disputeGameFactoryProxy)); - _dso.set(_dso.disputeGameFactoryImpl.selector, address(deployOutput.disputeGameFactoryImpl)); - _dso.set(_dso.anchorStateRegistryProxy.selector, address(deployOutput.anchorStateRegistryProxy)); - _dso.set(_dso.anchorStateRegistryImpl.selector, address(deployOutput.anchorStateRegistryImpl)); - _dso.set(_dso.faultDisputeGame.selector, address(deployOutput.faultDisputeGame)); - _dso.set(_dso.permissionedDisputeGame.selector, address(deployOutput.permissionedDisputeGame)); - _dso.set(_dso.delayedWETHPermissionedGameProxy.selector, address(deployOutput.delayedWETHPermissionedGameProxy)); - _dso.set( - _dso.delayedWETHPermissionlessGameProxy.selector, address(deployOutput.delayedWETHPermissionlessGameProxy) + _doo.set(_doo.l1StandardBridgeProxy.selector, address(deployOutput.l1StandardBridgeProxy)); + _doo.set(_doo.l1CrossDomainMessengerProxy.selector, address(deployOutput.l1CrossDomainMessengerProxy)); + _doo.set(_doo.optimismPortalProxy.selector, address(deployOutput.optimismPortalProxy)); + _doo.set(_doo.disputeGameFactoryProxy.selector, address(deployOutput.disputeGameFactoryProxy)); + _doo.set(_doo.disputeGameFactoryImpl.selector, address(deployOutput.disputeGameFactoryImpl)); + _doo.set(_doo.anchorStateRegistryProxy.selector, address(deployOutput.anchorStateRegistryProxy)); + _doo.set(_doo.anchorStateRegistryImpl.selector, address(deployOutput.anchorStateRegistryImpl)); + _doo.set(_doo.faultDisputeGame.selector, address(deployOutput.faultDisputeGame)); + _doo.set(_doo.permissionedDisputeGame.selector, address(deployOutput.permissionedDisputeGame)); + _doo.set(_doo.delayedWETHPermissionedGameProxy.selector, address(deployOutput.delayedWETHPermissionedGameProxy)); + _doo.set( + _doo.delayedWETHPermissionlessGameProxy.selector, address(deployOutput.delayedWETHPermissionlessGameProxy) ); - _dso.checkOutput(); + _doo.checkOutput(); } // -------- Utilities -------- - function etchIOContracts() internal returns (DeployOPChainInput dsi_, DeployOPChainOutput dso_) { - (dsi_, dso_) = getIOContracts(); - vm.etch(address(dsi_), type(DeployOPChainInput).runtimeCode); - vm.etch(address(dso_), type(DeployOPChainOutput).runtimeCode); + function etchIOContracts() internal returns (DeployOPChainInput doi_, DeployOPChainOutput doo_) { + (doi_, doo_) = getIOContracts(); + vm.etch(address(doi_), type(DeployOPChainInput).runtimeCode); + vm.etch(address(doo_), type(DeployOPChainOutput).runtimeCode); } - function getIOContracts() public view returns (DeployOPChainInput dsi_, DeployOPChainOutput dso_) { - dsi_ = DeployOPChainInput(DeployUtils.toIOAddress(msg.sender, "optimism.DeployOPChainInput")); - dso_ = DeployOPChainOutput(DeployUtils.toIOAddress(msg.sender, "optimism.DeployOPChainOutput")); + function getIOContracts() public view returns (DeployOPChainInput doi_, DeployOPChainOutput doo_) { + doi_ = DeployOPChainInput(DeployUtils.toIOAddress(msg.sender, "optimism.DeployOPChainInput")); + doo_ = DeployOPChainOutput(DeployUtils.toIOAddress(msg.sender, "optimism.DeployOPChainOutput")); } } diff --git a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol index dc0362879664..e735d00f31d3 100644 --- a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol +++ b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol @@ -56,7 +56,15 @@ import { Solarray } from "scripts/libraries/Solarray.sol"; // documentation. // // Additionally, we intentionally use "Input" and "Output" terminology to clearly distinguish these -// scripts from the existing ones that use the "Config" and "Artifacts" terminology. +// scripts from the existing ones that use the "Config" and "Artifacts" terminology. Within scripts +// we use variable names that are shorthand for the full contract names, for example: +// - `dsi` for DeploySuperchainInput +// - `dso` for DeploySuperchainOutput +// - `dio` for DeployImplementationsInput +// - `dio` for DeployImplementationsOutput +// - `doo` for DeployOPChainInput +// - `doo` for DeployOPChainOutput +// - etc. contract DeploySuperchainInput is CommonBase { using stdToml for string; diff --git a/packages/contracts-bedrock/test/DeployImplementations.t.sol b/packages/contracts-bedrock/test/DeployImplementations.t.sol index dc51da5982f1..1acbed7b60e3 100644 --- a/packages/contracts-bedrock/test/DeployImplementations.t.sol +++ b/packages/contracts-bedrock/test/DeployImplementations.t.sol @@ -26,7 +26,7 @@ import { } from "scripts/DeployImplementations.s.sol"; contract DeployImplementationsInput_Test is Test { - DeployImplementationsInput dsi; + DeployImplementationsInput dii; DeployImplementationsInput.Input input = DeployImplementationsInput.Input({ withdrawalDelaySeconds: 100, @@ -40,50 +40,50 @@ contract DeployImplementationsInput_Test is Test { }); function setUp() public { - dsi = new DeployImplementationsInput(); + dii = new DeployImplementationsInput(); } function test_loadInput_succeeds() public { - dsi.loadInput(input); + dii.loadInput(input); - assertTrue(dsi.inputSet(), "100"); + assertTrue(dii.inputSet(), "100"); // Compare the test input struct to the getter methods. - assertEq(input.withdrawalDelaySeconds, dsi.withdrawalDelaySeconds(), "200"); - assertEq(input.minProposalSizeBytes, dsi.minProposalSizeBytes(), "300"); - assertEq(input.challengePeriodSeconds, dsi.challengePeriodSeconds(), "400"); - assertEq(input.proofMaturityDelaySeconds, dsi.proofMaturityDelaySeconds(), "500"); - assertEq(input.disputeGameFinalityDelaySeconds, dsi.disputeGameFinalityDelaySeconds(), "600"); + assertEq(input.withdrawalDelaySeconds, dii.withdrawalDelaySeconds(), "200"); + assertEq(input.minProposalSizeBytes, dii.minProposalSizeBytes(), "300"); + assertEq(input.challengePeriodSeconds, dii.challengePeriodSeconds(), "400"); + assertEq(input.proofMaturityDelaySeconds, dii.proofMaturityDelaySeconds(), "500"); + assertEq(input.disputeGameFinalityDelaySeconds, dii.disputeGameFinalityDelaySeconds(), "600"); // Compare the test input struct to the `input` getter method. - assertEq(keccak256(abi.encode(input)), keccak256(abi.encode(dsi.input())), "800"); + assertEq(keccak256(abi.encode(input)), keccak256(abi.encode(dii.input())), "800"); } function test_getters_whenNotSet_revert() public { bytes memory expectedErr = "DeployImplementationsInput: input not set"; vm.expectRevert(expectedErr); - dsi.withdrawalDelaySeconds(); + dii.withdrawalDelaySeconds(); vm.expectRevert(expectedErr); - dsi.minProposalSizeBytes(); + dii.minProposalSizeBytes(); vm.expectRevert(expectedErr); - dsi.challengePeriodSeconds(); + dii.challengePeriodSeconds(); vm.expectRevert(expectedErr); - dsi.proofMaturityDelaySeconds(); + dii.proofMaturityDelaySeconds(); vm.expectRevert(expectedErr); - dsi.disputeGameFinalityDelaySeconds(); + dii.disputeGameFinalityDelaySeconds(); } } contract DeployImplementationsOutput_Test is Test { - DeployImplementationsOutput dso; + DeployImplementationsOutput dio; function setUp() public { - dso = new DeployImplementationsOutput(); + dio = new DeployImplementationsOutput(); } function test_set_succeeds() public { @@ -112,115 +112,115 @@ contract DeployImplementationsOutput_Test is Test { vm.etch(address(output.l1StandardBridgeImpl), hex"01"); vm.etch(address(output.optimismMintableERC20FactoryImpl), hex"01"); vm.etch(address(output.disputeGameFactoryImpl), hex"01"); - dso.set(dso.opsm.selector, address(output.opsm)); - dso.set(dso.optimismPortalImpl.selector, address(output.optimismPortalImpl)); - dso.set(dso.delayedWETHImpl.selector, address(output.delayedWETHImpl)); - dso.set(dso.preimageOracleSingleton.selector, address(output.preimageOracleSingleton)); - dso.set(dso.mipsSingleton.selector, address(output.mipsSingleton)); - dso.set(dso.systemConfigImpl.selector, address(output.systemConfigImpl)); - dso.set(dso.l1CrossDomainMessengerImpl.selector, address(output.l1CrossDomainMessengerImpl)); - dso.set(dso.l1ERC721BridgeImpl.selector, address(output.l1ERC721BridgeImpl)); - dso.set(dso.l1StandardBridgeImpl.selector, address(output.l1StandardBridgeImpl)); - dso.set(dso.optimismMintableERC20FactoryImpl.selector, address(output.optimismMintableERC20FactoryImpl)); - dso.set(dso.disputeGameFactoryImpl.selector, address(output.disputeGameFactoryImpl)); - - assertEq(address(output.opsm), address(dso.opsm()), "50"); - assertEq(address(output.optimismPortalImpl), address(dso.optimismPortalImpl()), "100"); - assertEq(address(output.delayedWETHImpl), address(dso.delayedWETHImpl()), "200"); - assertEq(address(output.preimageOracleSingleton), address(dso.preimageOracleSingleton()), "300"); - assertEq(address(output.mipsSingleton), address(dso.mipsSingleton()), "400"); - assertEq(address(output.systemConfigImpl), address(dso.systemConfigImpl()), "500"); - assertEq(address(output.l1CrossDomainMessengerImpl), address(dso.l1CrossDomainMessengerImpl()), "600"); - assertEq(address(output.l1ERC721BridgeImpl), address(dso.l1ERC721BridgeImpl()), "700"); - assertEq(address(output.l1StandardBridgeImpl), address(dso.l1StandardBridgeImpl()), "800"); + dio.set(dio.opsm.selector, address(output.opsm)); + dio.set(dio.optimismPortalImpl.selector, address(output.optimismPortalImpl)); + dio.set(dio.delayedWETHImpl.selector, address(output.delayedWETHImpl)); + dio.set(dio.preimageOracleSingleton.selector, address(output.preimageOracleSingleton)); + dio.set(dio.mipsSingleton.selector, address(output.mipsSingleton)); + dio.set(dio.systemConfigImpl.selector, address(output.systemConfigImpl)); + dio.set(dio.l1CrossDomainMessengerImpl.selector, address(output.l1CrossDomainMessengerImpl)); + dio.set(dio.l1ERC721BridgeImpl.selector, address(output.l1ERC721BridgeImpl)); + dio.set(dio.l1StandardBridgeImpl.selector, address(output.l1StandardBridgeImpl)); + dio.set(dio.optimismMintableERC20FactoryImpl.selector, address(output.optimismMintableERC20FactoryImpl)); + dio.set(dio.disputeGameFactoryImpl.selector, address(output.disputeGameFactoryImpl)); + + assertEq(address(output.opsm), address(dio.opsm()), "50"); + assertEq(address(output.optimismPortalImpl), address(dio.optimismPortalImpl()), "100"); + assertEq(address(output.delayedWETHImpl), address(dio.delayedWETHImpl()), "200"); + assertEq(address(output.preimageOracleSingleton), address(dio.preimageOracleSingleton()), "300"); + assertEq(address(output.mipsSingleton), address(dio.mipsSingleton()), "400"); + assertEq(address(output.systemConfigImpl), address(dio.systemConfigImpl()), "500"); + assertEq(address(output.l1CrossDomainMessengerImpl), address(dio.l1CrossDomainMessengerImpl()), "600"); + assertEq(address(output.l1ERC721BridgeImpl), address(dio.l1ERC721BridgeImpl()), "700"); + assertEq(address(output.l1StandardBridgeImpl), address(dio.l1StandardBridgeImpl()), "800"); assertEq( - address(output.optimismMintableERC20FactoryImpl), address(dso.optimismMintableERC20FactoryImpl()), "900" + address(output.optimismMintableERC20FactoryImpl), address(dio.optimismMintableERC20FactoryImpl()), "900" ); - assertEq(address(output.disputeGameFactoryImpl), address(dso.disputeGameFactoryImpl()), "950"); + assertEq(address(output.disputeGameFactoryImpl), address(dio.disputeGameFactoryImpl()), "950"); - assertEq(keccak256(abi.encode(output)), keccak256(abi.encode(dso.output())), "1000"); + assertEq(keccak256(abi.encode(output)), keccak256(abi.encode(dio.output())), "1000"); } function test_getters_whenNotSet_revert() public { bytes memory expectedErr = "DeployUtils: zero address"; vm.expectRevert(expectedErr); - dso.optimismPortalImpl(); + dio.optimismPortalImpl(); vm.expectRevert(expectedErr); - dso.delayedWETHImpl(); + dio.delayedWETHImpl(); vm.expectRevert(expectedErr); - dso.preimageOracleSingleton(); + dio.preimageOracleSingleton(); vm.expectRevert(expectedErr); - dso.mipsSingleton(); + dio.mipsSingleton(); vm.expectRevert(expectedErr); - dso.systemConfigImpl(); + dio.systemConfigImpl(); vm.expectRevert(expectedErr); - dso.l1CrossDomainMessengerImpl(); + dio.l1CrossDomainMessengerImpl(); vm.expectRevert(expectedErr); - dso.l1ERC721BridgeImpl(); + dio.l1ERC721BridgeImpl(); vm.expectRevert(expectedErr); - dso.l1StandardBridgeImpl(); + dio.l1StandardBridgeImpl(); vm.expectRevert(expectedErr); - dso.optimismMintableERC20FactoryImpl(); + dio.optimismMintableERC20FactoryImpl(); vm.expectRevert(expectedErr); - dso.disputeGameFactoryImpl(); + dio.disputeGameFactoryImpl(); } function test_getters_whenAddrHasNoCode_reverts() public { address emptyAddr = makeAddr("emptyAddr"); bytes memory expectedErr = bytes(string.concat("DeployUtils: no code at ", vm.toString(emptyAddr))); - dso.set(dso.optimismPortalImpl.selector, emptyAddr); + dio.set(dio.optimismPortalImpl.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.optimismPortalImpl(); + dio.optimismPortalImpl(); - dso.set(dso.delayedWETHImpl.selector, emptyAddr); + dio.set(dio.delayedWETHImpl.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.delayedWETHImpl(); + dio.delayedWETHImpl(); - dso.set(dso.preimageOracleSingleton.selector, emptyAddr); + dio.set(dio.preimageOracleSingleton.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.preimageOracleSingleton(); + dio.preimageOracleSingleton(); - dso.set(dso.mipsSingleton.selector, emptyAddr); + dio.set(dio.mipsSingleton.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.mipsSingleton(); + dio.mipsSingleton(); - dso.set(dso.systemConfigImpl.selector, emptyAddr); + dio.set(dio.systemConfigImpl.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.systemConfigImpl(); + dio.systemConfigImpl(); - dso.set(dso.l1CrossDomainMessengerImpl.selector, emptyAddr); + dio.set(dio.l1CrossDomainMessengerImpl.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.l1CrossDomainMessengerImpl(); + dio.l1CrossDomainMessengerImpl(); - dso.set(dso.l1ERC721BridgeImpl.selector, emptyAddr); + dio.set(dio.l1ERC721BridgeImpl.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.l1ERC721BridgeImpl(); + dio.l1ERC721BridgeImpl(); - dso.set(dso.l1StandardBridgeImpl.selector, emptyAddr); + dio.set(dio.l1StandardBridgeImpl.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.l1StandardBridgeImpl(); + dio.l1StandardBridgeImpl(); - dso.set(dso.optimismMintableERC20FactoryImpl.selector, emptyAddr); + dio.set(dio.optimismMintableERC20FactoryImpl.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.optimismMintableERC20FactoryImpl(); + dio.optimismMintableERC20FactoryImpl(); } } contract DeployImplementations_Test is Test { DeployImplementations deployImplementations; - DeployImplementationsInput dsi; - DeployImplementationsOutput dso; + DeployImplementationsInput dii; + DeployImplementationsOutput dio; // Define a default input struct for testing. DeployImplementationsInput.Input input = DeployImplementationsInput.Input({ @@ -236,7 +236,7 @@ contract DeployImplementations_Test is Test { function setUp() public virtual { deployImplementations = new DeployImplementations(); - (dsi, dso) = deployImplementations.getIOContracts(); + (dii, dio) = deployImplementations.getIOContracts(); } // By deploying the `DeployImplementations` contract with this virtual function, we provide a @@ -246,37 +246,37 @@ contract DeployImplementations_Test is Test { return new DeployImplementations(); } - function test_run_succeeds(DeployImplementationsInput.Input memory _input) public { + function testFuzz_run_succeeds(DeployImplementationsInput.Input memory _input) public { // This is a requirement in the PreimageOracle contract. _input.challengePeriodSeconds = bound(_input.challengePeriodSeconds, 0, type(uint64).max); DeployImplementationsOutput.Output memory output = deployImplementations.run(_input); // Assert that individual input fields were properly set based on the input struct. - assertEq(_input.withdrawalDelaySeconds, dsi.withdrawalDelaySeconds(), "100"); - assertEq(_input.minProposalSizeBytes, dsi.minProposalSizeBytes(), "200"); - assertEq(_input.challengePeriodSeconds, dsi.challengePeriodSeconds(), "300"); - assertEq(_input.proofMaturityDelaySeconds, dsi.proofMaturityDelaySeconds(), "400"); - assertEq(_input.disputeGameFinalityDelaySeconds, dsi.disputeGameFinalityDelaySeconds(), "500"); + assertEq(_input.withdrawalDelaySeconds, dii.withdrawalDelaySeconds(), "100"); + assertEq(_input.minProposalSizeBytes, dii.minProposalSizeBytes(), "200"); + assertEq(_input.challengePeriodSeconds, dii.challengePeriodSeconds(), "300"); + assertEq(_input.proofMaturityDelaySeconds, dii.proofMaturityDelaySeconds(), "400"); + assertEq(_input.disputeGameFinalityDelaySeconds, dii.disputeGameFinalityDelaySeconds(), "500"); // Assert that individual output fields were properly set based on the output struct. - assertEq(address(output.optimismPortalImpl), address(dso.optimismPortalImpl()), "600"); - assertEq(address(output.delayedWETHImpl), address(dso.delayedWETHImpl()), "700"); - assertEq(address(output.preimageOracleSingleton), address(dso.preimageOracleSingleton()), "800"); - assertEq(address(output.mipsSingleton), address(dso.mipsSingleton()), "900"); - assertEq(address(output.systemConfigImpl), address(dso.systemConfigImpl()), "1000"); - assertEq(address(output.l1CrossDomainMessengerImpl), address(dso.l1CrossDomainMessengerImpl()), "1100"); - assertEq(address(output.l1ERC721BridgeImpl), address(dso.l1ERC721BridgeImpl()), "1200"); - assertEq(address(output.l1StandardBridgeImpl), address(dso.l1StandardBridgeImpl()), "1300"); + assertEq(address(output.optimismPortalImpl), address(dio.optimismPortalImpl()), "600"); + assertEq(address(output.delayedWETHImpl), address(dio.delayedWETHImpl()), "700"); + assertEq(address(output.preimageOracleSingleton), address(dio.preimageOracleSingleton()), "800"); + assertEq(address(output.mipsSingleton), address(dio.mipsSingleton()), "900"); + assertEq(address(output.systemConfigImpl), address(dio.systemConfigImpl()), "1000"); + assertEq(address(output.l1CrossDomainMessengerImpl), address(dio.l1CrossDomainMessengerImpl()), "1100"); + assertEq(address(output.l1ERC721BridgeImpl), address(dio.l1ERC721BridgeImpl()), "1200"); + assertEq(address(output.l1StandardBridgeImpl), address(dio.l1StandardBridgeImpl()), "1300"); assertEq( - address(output.optimismMintableERC20FactoryImpl), address(dso.optimismMintableERC20FactoryImpl()), "1400" + address(output.optimismMintableERC20FactoryImpl), address(dio.optimismMintableERC20FactoryImpl()), "1400" ); - assertEq(address(output.disputeGameFactoryImpl), address(dso.disputeGameFactoryImpl()), "1450"); + assertEq(address(output.disputeGameFactoryImpl), address(dio.disputeGameFactoryImpl()), "1450"); // Assert that the full input and output structs were properly set. - assertEq(keccak256(abi.encode(_input)), keccak256(abi.encode(DeployImplementationsInput(dsi).input())), "1500"); + assertEq(keccak256(abi.encode(_input)), keccak256(abi.encode(DeployImplementationsInput(dii).input())), "1500"); assertEq( - keccak256(abi.encode(output)), keccak256(abi.encode(DeployImplementationsOutput(dso).output())), "1600" + keccak256(abi.encode(output)), keccak256(abi.encode(DeployImplementationsOutput(dio).output())), "1600" ); // Assert inputs were properly passed through to the contract initializers. @@ -293,10 +293,10 @@ contract DeployImplementations_Test is Test { // Ensure that `checkOutput` passes. This is called by the `run` function during execution, // so this just acts as a sanity check. It reverts on failure. - dso.checkOutput(); + dio.checkOutput(); } - function test_run_largeChallengePeriodSeconds_reverts(uint256 _challengePeriodSeconds) public { + function testFuzz_run_largeChallengePeriodSeconds_reverts(uint256 _challengePeriodSeconds) public { input.challengePeriodSeconds = bound(_challengePeriodSeconds, uint256(type(uint64).max) + 1, type(uint256).max); vm.expectRevert("DeployImplementationsInput: challenge period too large"); deployImplementations.run(input); diff --git a/packages/contracts-bedrock/test/DeployOPChain.t.sol b/packages/contracts-bedrock/test/DeployOPChain.t.sol index 7cf975946d28..b2861c2af328 100644 --- a/packages/contracts-bedrock/test/DeployOPChain.t.sol +++ b/packages/contracts-bedrock/test/DeployOPChain.t.sol @@ -32,7 +32,7 @@ import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; contract DeployOPChainInput_Test is Test { - DeployOPChainInput dsi; + DeployOPChainInput doi; DeployOPChainInput.Input input = DeployOPChainInput.Input({ roles: DeployOPChainInput.Roles({ @@ -50,67 +50,67 @@ contract DeployOPChainInput_Test is Test { }); function setUp() public { - dsi = new DeployOPChainInput(); + doi = new DeployOPChainInput(); } function test_loadInput_succeeds() public { - dsi.loadInput(input); + doi.loadInput(input); - assertTrue(dsi.inputSet(), "100"); + assertTrue(doi.inputSet(), "100"); // Compare the test input struct to the getter methods. - assertEq(input.roles.opChainProxyAdminOwner, dsi.opChainProxyAdminOwner(), "200"); - assertEq(input.roles.systemConfigOwner, dsi.systemConfigOwner(), "300"); - assertEq(input.roles.batcher, dsi.batcher(), "400"); - assertEq(input.roles.unsafeBlockSigner, dsi.unsafeBlockSigner(), "500"); - assertEq(input.roles.proposer, dsi.proposer(), "600"); - assertEq(input.roles.challenger, dsi.challenger(), "700"); - assertEq(input.basefeeScalar, dsi.basefeeScalar(), "800"); - assertEq(input.blobBaseFeeScalar, dsi.blobBaseFeeScalar(), "900"); - assertEq(input.l2ChainId, dsi.l2ChainId(), "1000"); - assertEq(address(input.opsm), address(dsi.opsm()), "1100"); + assertEq(input.roles.opChainProxyAdminOwner, doi.opChainProxyAdminOwner(), "200"); + assertEq(input.roles.systemConfigOwner, doi.systemConfigOwner(), "300"); + assertEq(input.roles.batcher, doi.batcher(), "400"); + assertEq(input.roles.unsafeBlockSigner, doi.unsafeBlockSigner(), "500"); + assertEq(input.roles.proposer, doi.proposer(), "600"); + assertEq(input.roles.challenger, doi.challenger(), "700"); + assertEq(input.basefeeScalar, doi.basefeeScalar(), "800"); + assertEq(input.blobBaseFeeScalar, doi.blobBaseFeeScalar(), "900"); + assertEq(input.l2ChainId, doi.l2ChainId(), "1000"); + assertEq(address(input.opsm), address(doi.opsm()), "1100"); // Compare the test input struct to the `input` getter method. - assertEq(keccak256(abi.encode(input)), keccak256(abi.encode(dsi.input())), "1200"); + assertEq(keccak256(abi.encode(input)), keccak256(abi.encode(doi.input())), "1200"); } function test_getters_whenNotSet_revert() public { bytes memory expectedErr = "DeployOPChainInput: input not set"; vm.expectRevert(expectedErr); - dsi.opChainProxyAdminOwner(); + doi.opChainProxyAdminOwner(); vm.expectRevert(expectedErr); - dsi.systemConfigOwner(); + doi.systemConfigOwner(); vm.expectRevert(expectedErr); - dsi.batcher(); + doi.batcher(); vm.expectRevert(expectedErr); - dsi.unsafeBlockSigner(); + doi.unsafeBlockSigner(); vm.expectRevert(expectedErr); - dsi.proposer(); + doi.proposer(); vm.expectRevert(expectedErr); - dsi.challenger(); + doi.challenger(); vm.expectRevert(expectedErr); - dsi.basefeeScalar(); + doi.basefeeScalar(); vm.expectRevert(expectedErr); - dsi.blobBaseFeeScalar(); + doi.blobBaseFeeScalar(); vm.expectRevert(expectedErr); - dsi.l2ChainId(); + doi.l2ChainId(); } } contract DeployOPChainOutput_Test is Test { - DeployOPChainOutput dso; + DeployOPChainOutput doo; function setUp() public { - dso = new DeployOPChainOutput(); + doo = new DeployOPChainOutput(); } function test_set_succeeds() public { @@ -150,170 +150,170 @@ contract DeployOPChainOutput_Test is Test { vm.etch(address(output.delayedWETHPermissionedGameProxy), hex"01"); vm.etch(address(output.delayedWETHPermissionlessGameProxy), hex"01"); - dso.set(dso.opChainProxyAdmin.selector, address(output.opChainProxyAdmin)); - dso.set(dso.addressManager.selector, address(output.addressManager)); - dso.set(dso.l1ERC721BridgeProxy.selector, address(output.l1ERC721BridgeProxy)); - dso.set(dso.systemConfigProxy.selector, address(output.systemConfigProxy)); - dso.set(dso.optimismMintableERC20FactoryProxy.selector, address(output.optimismMintableERC20FactoryProxy)); - dso.set(dso.l1StandardBridgeProxy.selector, address(output.l1StandardBridgeProxy)); - dso.set(dso.l1CrossDomainMessengerProxy.selector, address(output.l1CrossDomainMessengerProxy)); - dso.set(dso.optimismPortalProxy.selector, address(output.optimismPortalProxy)); - dso.set(dso.disputeGameFactoryProxy.selector, address(output.disputeGameFactoryProxy)); - dso.set(dso.disputeGameFactoryImpl.selector, address(output.disputeGameFactoryImpl)); - dso.set(dso.anchorStateRegistryProxy.selector, address(output.anchorStateRegistryProxy)); - dso.set(dso.anchorStateRegistryImpl.selector, address(output.anchorStateRegistryImpl)); - dso.set(dso.faultDisputeGame.selector, address(output.faultDisputeGame)); - dso.set(dso.permissionedDisputeGame.selector, address(output.permissionedDisputeGame)); - dso.set(dso.delayedWETHPermissionedGameProxy.selector, address(output.delayedWETHPermissionedGameProxy)); - dso.set(dso.delayedWETHPermissionlessGameProxy.selector, address(output.delayedWETHPermissionlessGameProxy)); - - assertEq(address(output.opChainProxyAdmin), address(dso.opChainProxyAdmin()), "100"); - assertEq(address(output.addressManager), address(dso.addressManager()), "200"); - assertEq(address(output.l1ERC721BridgeProxy), address(dso.l1ERC721BridgeProxy()), "300"); - assertEq(address(output.systemConfigProxy), address(dso.systemConfigProxy()), "400"); + doo.set(doo.opChainProxyAdmin.selector, address(output.opChainProxyAdmin)); + doo.set(doo.addressManager.selector, address(output.addressManager)); + doo.set(doo.l1ERC721BridgeProxy.selector, address(output.l1ERC721BridgeProxy)); + doo.set(doo.systemConfigProxy.selector, address(output.systemConfigProxy)); + doo.set(doo.optimismMintableERC20FactoryProxy.selector, address(output.optimismMintableERC20FactoryProxy)); + doo.set(doo.l1StandardBridgeProxy.selector, address(output.l1StandardBridgeProxy)); + doo.set(doo.l1CrossDomainMessengerProxy.selector, address(output.l1CrossDomainMessengerProxy)); + doo.set(doo.optimismPortalProxy.selector, address(output.optimismPortalProxy)); + doo.set(doo.disputeGameFactoryProxy.selector, address(output.disputeGameFactoryProxy)); + doo.set(doo.disputeGameFactoryImpl.selector, address(output.disputeGameFactoryImpl)); + doo.set(doo.anchorStateRegistryProxy.selector, address(output.anchorStateRegistryProxy)); + doo.set(doo.anchorStateRegistryImpl.selector, address(output.anchorStateRegistryImpl)); + doo.set(doo.faultDisputeGame.selector, address(output.faultDisputeGame)); + doo.set(doo.permissionedDisputeGame.selector, address(output.permissionedDisputeGame)); + doo.set(doo.delayedWETHPermissionedGameProxy.selector, address(output.delayedWETHPermissionedGameProxy)); + doo.set(doo.delayedWETHPermissionlessGameProxy.selector, address(output.delayedWETHPermissionlessGameProxy)); + + assertEq(address(output.opChainProxyAdmin), address(doo.opChainProxyAdmin()), "100"); + assertEq(address(output.addressManager), address(doo.addressManager()), "200"); + assertEq(address(output.l1ERC721BridgeProxy), address(doo.l1ERC721BridgeProxy()), "300"); + assertEq(address(output.systemConfigProxy), address(doo.systemConfigProxy()), "400"); assertEq( - address(output.optimismMintableERC20FactoryProxy), address(dso.optimismMintableERC20FactoryProxy()), "500" + address(output.optimismMintableERC20FactoryProxy), address(doo.optimismMintableERC20FactoryProxy()), "500" ); - assertEq(address(output.l1StandardBridgeProxy), address(dso.l1StandardBridgeProxy()), "600"); - assertEq(address(output.l1CrossDomainMessengerProxy), address(dso.l1CrossDomainMessengerProxy()), "700"); - assertEq(address(output.optimismPortalProxy), address(dso.optimismPortalProxy()), "800"); - assertEq(address(output.disputeGameFactoryProxy), address(dso.disputeGameFactoryProxy()), "900"); - assertEq(address(output.disputeGameFactoryImpl), address(dso.disputeGameFactoryImpl()), "1000"); - assertEq(address(output.anchorStateRegistryProxy), address(dso.anchorStateRegistryProxy()), "1100"); - assertEq(address(output.anchorStateRegistryImpl), address(dso.anchorStateRegistryImpl()), "1200"); - assertEq(address(output.faultDisputeGame), address(dso.faultDisputeGame()), "1300"); - assertEq(address(output.permissionedDisputeGame), address(dso.permissionedDisputeGame()), "1400"); + assertEq(address(output.l1StandardBridgeProxy), address(doo.l1StandardBridgeProxy()), "600"); + assertEq(address(output.l1CrossDomainMessengerProxy), address(doo.l1CrossDomainMessengerProxy()), "700"); + assertEq(address(output.optimismPortalProxy), address(doo.optimismPortalProxy()), "800"); + assertEq(address(output.disputeGameFactoryProxy), address(doo.disputeGameFactoryProxy()), "900"); + assertEq(address(output.disputeGameFactoryImpl), address(doo.disputeGameFactoryImpl()), "1000"); + assertEq(address(output.anchorStateRegistryProxy), address(doo.anchorStateRegistryProxy()), "1100"); + assertEq(address(output.anchorStateRegistryImpl), address(doo.anchorStateRegistryImpl()), "1200"); + assertEq(address(output.faultDisputeGame), address(doo.faultDisputeGame()), "1300"); + assertEq(address(output.permissionedDisputeGame), address(doo.permissionedDisputeGame()), "1400"); assertEq( - address(output.delayedWETHPermissionedGameProxy), address(dso.delayedWETHPermissionedGameProxy()), "1500" + address(output.delayedWETHPermissionedGameProxy), address(doo.delayedWETHPermissionedGameProxy()), "1500" ); assertEq( address(output.delayedWETHPermissionlessGameProxy), - address(dso.delayedWETHPermissionlessGameProxy()), + address(doo.delayedWETHPermissionlessGameProxy()), "1600" ); - assertEq(keccak256(abi.encode(output)), keccak256(abi.encode(dso.output())), "1700"); + assertEq(keccak256(abi.encode(output)), keccak256(abi.encode(doo.output())), "1700"); } function test_getters_whenNotSet_revert() public { bytes memory expectedErr = "DeployUtils: zero address"; vm.expectRevert(expectedErr); - dso.opChainProxyAdmin(); + doo.opChainProxyAdmin(); vm.expectRevert(expectedErr); - dso.addressManager(); + doo.addressManager(); vm.expectRevert(expectedErr); - dso.l1ERC721BridgeProxy(); + doo.l1ERC721BridgeProxy(); vm.expectRevert(expectedErr); - dso.systemConfigProxy(); + doo.systemConfigProxy(); vm.expectRevert(expectedErr); - dso.optimismMintableERC20FactoryProxy(); + doo.optimismMintableERC20FactoryProxy(); vm.expectRevert(expectedErr); - dso.l1StandardBridgeProxy(); + doo.l1StandardBridgeProxy(); vm.expectRevert(expectedErr); - dso.l1CrossDomainMessengerProxy(); + doo.l1CrossDomainMessengerProxy(); vm.expectRevert(expectedErr); - dso.optimismPortalProxy(); + doo.optimismPortalProxy(); vm.expectRevert(expectedErr); - dso.disputeGameFactoryProxy(); + doo.disputeGameFactoryProxy(); vm.expectRevert(expectedErr); - dso.disputeGameFactoryImpl(); + doo.disputeGameFactoryImpl(); vm.expectRevert(expectedErr); - dso.anchorStateRegistryProxy(); + doo.anchorStateRegistryProxy(); vm.expectRevert(expectedErr); - dso.anchorStateRegistryImpl(); + doo.anchorStateRegistryImpl(); vm.expectRevert(expectedErr); - dso.faultDisputeGame(); + doo.faultDisputeGame(); vm.expectRevert(expectedErr); - dso.permissionedDisputeGame(); + doo.permissionedDisputeGame(); vm.expectRevert(expectedErr); - dso.delayedWETHPermissionedGameProxy(); + doo.delayedWETHPermissionedGameProxy(); vm.expectRevert(expectedErr); - dso.delayedWETHPermissionlessGameProxy(); + doo.delayedWETHPermissionlessGameProxy(); } function test_getters_whenAddrHasNoCode_reverts() public { address emptyAddr = makeAddr("emptyAddr"); bytes memory expectedErr = bytes(string.concat("DeployUtils: no code at ", vm.toString(emptyAddr))); - dso.set(dso.opChainProxyAdmin.selector, emptyAddr); + doo.set(doo.opChainProxyAdmin.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.opChainProxyAdmin(); + doo.opChainProxyAdmin(); - dso.set(dso.addressManager.selector, emptyAddr); + doo.set(doo.addressManager.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.addressManager(); + doo.addressManager(); - dso.set(dso.l1ERC721BridgeProxy.selector, emptyAddr); + doo.set(doo.l1ERC721BridgeProxy.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.l1ERC721BridgeProxy(); + doo.l1ERC721BridgeProxy(); - dso.set(dso.systemConfigProxy.selector, emptyAddr); + doo.set(doo.systemConfigProxy.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.systemConfigProxy(); + doo.systemConfigProxy(); - dso.set(dso.optimismMintableERC20FactoryProxy.selector, emptyAddr); + doo.set(doo.optimismMintableERC20FactoryProxy.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.optimismMintableERC20FactoryProxy(); + doo.optimismMintableERC20FactoryProxy(); - dso.set(dso.l1StandardBridgeProxy.selector, emptyAddr); + doo.set(doo.l1StandardBridgeProxy.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.l1StandardBridgeProxy(); + doo.l1StandardBridgeProxy(); - dso.set(dso.l1CrossDomainMessengerProxy.selector, emptyAddr); + doo.set(doo.l1CrossDomainMessengerProxy.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.l1CrossDomainMessengerProxy(); + doo.l1CrossDomainMessengerProxy(); - dso.set(dso.optimismPortalProxy.selector, emptyAddr); + doo.set(doo.optimismPortalProxy.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.optimismPortalProxy(); + doo.optimismPortalProxy(); - dso.set(dso.disputeGameFactoryProxy.selector, emptyAddr); + doo.set(doo.disputeGameFactoryProxy.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.disputeGameFactoryProxy(); + doo.disputeGameFactoryProxy(); - dso.set(dso.disputeGameFactoryImpl.selector, emptyAddr); + doo.set(doo.disputeGameFactoryImpl.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.disputeGameFactoryImpl(); + doo.disputeGameFactoryImpl(); - dso.set(dso.anchorStateRegistryProxy.selector, emptyAddr); + doo.set(doo.anchorStateRegistryProxy.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.anchorStateRegistryProxy(); + doo.anchorStateRegistryProxy(); - dso.set(dso.anchorStateRegistryImpl.selector, emptyAddr); + doo.set(doo.anchorStateRegistryImpl.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.anchorStateRegistryImpl(); + doo.anchorStateRegistryImpl(); - dso.set(dso.faultDisputeGame.selector, emptyAddr); + doo.set(doo.faultDisputeGame.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.faultDisputeGame(); + doo.faultDisputeGame(); - dso.set(dso.permissionedDisputeGame.selector, emptyAddr); + doo.set(doo.permissionedDisputeGame.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.permissionedDisputeGame(); + doo.permissionedDisputeGame(); - dso.set(dso.delayedWETHPermissionedGameProxy.selector, emptyAddr); + doo.set(doo.delayedWETHPermissionedGameProxy.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.delayedWETHPermissionedGameProxy(); + doo.delayedWETHPermissionedGameProxy(); - dso.set(dso.delayedWETHPermissionlessGameProxy.selector, emptyAddr); + doo.set(doo.delayedWETHPermissionlessGameProxy.selector, emptyAddr); vm.expectRevert(expectedErr); - dso.delayedWETHPermissionlessGameProxy(); + doo.delayedWETHPermissionlessGameProxy(); } } @@ -401,7 +401,7 @@ contract DeployOPChain_TestBase is Test { } contract DeployOPChain_Test is DeployOPChain_TestBase { - function test_run_succeeds(DeployOPChainInput.Input memory _input) public { + function testFuzz_run_succeeds(DeployOPChainInput.Input memory _input) public { vm.assume(_input.roles.opChainProxyAdminOwner != address(0)); vm.assume(_input.roles.systemConfigOwner != address(0)); vm.assume(_input.roles.batcher != address(0)); diff --git a/packages/contracts-bedrock/test/DeploySuperchain.t.sol b/packages/contracts-bedrock/test/DeploySuperchain.t.sol index 62f241d02340..04f712b3b0d8 100644 --- a/packages/contracts-bedrock/test/DeploySuperchain.t.sol +++ b/packages/contracts-bedrock/test/DeploySuperchain.t.sol @@ -206,7 +206,7 @@ contract DeploySuperchain_Test is Test { return keccak256(abi.encode(_seed, _i)); } - function test_run_memory_succeeds(bytes32 _seed) public { + function testFuzz_run_memory_succeeds(bytes32 _seed) public { // Generate random input values from the seed. This doesn't give us the benefit of the forge // fuzzer's dictionary, but that's ok because we are just testing that values are set and // passed correctly. From 88b1a95a5d6732b0103d24808202c35aa199d968 Mon Sep 17 00:00:00 2001 From: Samuel Laferriere Date: Wed, 11 Sep 2024 12:33:43 -0700 Subject: [PATCH 097/264] feat: concurrent alt-da requests (#11698) * feat: initial goroutine blob submission implementation test(batcher): add e2e test for concurrent altda requests doc: add explanation comment for FakeDAServer chore: fix if condition in altda sendTransaction path feat: add maxConcurrentDaRequests config flag + semaphore refactor: batcher to use errgroup for da instead of separate semaphore/waitgroup fix: nil pointer bug after using wrong function after rebase fix: defn of maxConcurrentDaRequests=0 fix: TestBatcherConcurrentAltDARequests chore: remove unneeded if statement around time.Sleep refactor: use TryGo instead of Go to make logic local and easier to read chore: clean up some comments in batcher chore: make batcher shutdown cancel pending altda requests by using shutdownCtx instead of killCtx * chore(batcher): make altda wg wait + log only when useAltDa is true * refactor: batcher altda submission code into its own function * test: refactor batcher e2e test to only count batcher txs * chore: log errors from wait functions * chore: refactor and minimize time that e2e batcher system tests can run * chore: lower timeout duration in test * fix(batcher): maxConcurentDARequests was not being initialized --- op-alt-da/cli.go | 56 ++++++++++---- op-alt-da/daclient.go | 18 ++++- op-alt-da/daclient_test.go | 38 +-------- op-alt-da/damock.go | 85 +++++++++++++++++++++ op-alt-da/daserver.go | 4 +- op-batcher/batcher/driver.go | 106 ++++++++++++++++++++------ op-batcher/batcher/service.go | 3 + op-e2e/e2eutils/transactions/count.go | 21 +++++ op-e2e/setup.go | 67 ++++++++++++---- op-e2e/system_test.go | 81 ++++++++++++++++++-- op-service/txmgr/queue.go | 6 +- op-service/txmgr/queue_test.go | 2 +- 12 files changed, 378 insertions(+), 109 deletions(-) create mode 100644 op-e2e/e2eutils/transactions/count.go diff --git a/op-alt-da/cli.go b/op-alt-da/cli.go index e931707b67f5..30ce2168f570 100644 --- a/op-alt-da/cli.go +++ b/op-alt-da/cli.go @@ -3,15 +3,19 @@ package altda import ( "fmt" "net/url" + "time" "github.com/urfave/cli/v2" ) var ( - EnabledFlagName = altDAFlags("enabled") - DaServerAddressFlagName = altDAFlags("da-server") - VerifyOnReadFlagName = altDAFlags("verify-on-read") - DaServiceFlag = altDAFlags("da-service") + EnabledFlagName = altDAFlags("enabled") + DaServerAddressFlagName = altDAFlags("da-server") + VerifyOnReadFlagName = altDAFlags("verify-on-read") + DaServiceFlagName = altDAFlags("da-service") + PutTimeoutFlagName = altDAFlags("put-timeout") + GetTimeoutFlagName = altDAFlags("get-timeout") + MaxConcurrentRequestsFlagName = altDAFlags("max-concurrent-da-requests") ) // altDAFlags returns the flag names for altDA @@ -46,20 +50,41 @@ func CLIFlags(envPrefix string, category string) []cli.Flag { Category: category, }, &cli.BoolFlag{ - Name: DaServiceFlag, + Name: DaServiceFlagName, Usage: "Use DA service type where commitments are generated by Alt-DA server", Value: false, EnvVars: altDAEnvs(envPrefix, "DA_SERVICE"), Category: category, }, + &cli.DurationFlag{ + Name: PutTimeoutFlagName, + Usage: "Timeout for put requests. 0 means no timeout.", + Value: time.Duration(0), + EnvVars: altDAEnvs(envPrefix, "PUT_TIMEOUT"), + }, + &cli.DurationFlag{ + Name: GetTimeoutFlagName, + Usage: "Timeout for get requests. 0 means no timeout.", + Value: time.Duration(0), + EnvVars: altDAEnvs(envPrefix, "GET_TIMEOUT"), + }, + &cli.Uint64Flag{ + Name: MaxConcurrentRequestsFlagName, + Usage: "Maximum number of concurrent requests to the DA server", + Value: 1, + EnvVars: altDAEnvs(envPrefix, "MAX_CONCURRENT_DA_REQUESTS"), + }, } } type CLIConfig struct { - Enabled bool - DAServerURL string - VerifyOnRead bool - GenericDA bool + Enabled bool + DAServerURL string + VerifyOnRead bool + GenericDA bool + PutTimeout time.Duration + GetTimeout time.Duration + MaxConcurrentRequests uint64 } func (c CLIConfig) Check() error { @@ -75,14 +100,17 @@ func (c CLIConfig) Check() error { } func (c CLIConfig) NewDAClient() *DAClient { - return &DAClient{url: c.DAServerURL, verify: c.VerifyOnRead, precompute: !c.GenericDA} + return &DAClient{url: c.DAServerURL, verify: c.VerifyOnRead, precompute: !c.GenericDA, getTimeout: c.GetTimeout, putTimeout: c.PutTimeout} } func ReadCLIConfig(c *cli.Context) CLIConfig { return CLIConfig{ - Enabled: c.Bool(EnabledFlagName), - DAServerURL: c.String(DaServerAddressFlagName), - VerifyOnRead: c.Bool(VerifyOnReadFlagName), - GenericDA: c.Bool(DaServiceFlag), + Enabled: c.Bool(EnabledFlagName), + DAServerURL: c.String(DaServerAddressFlagName), + VerifyOnRead: c.Bool(VerifyOnReadFlagName), + GenericDA: c.Bool(DaServiceFlagName), + PutTimeout: c.Duration(PutTimeoutFlagName), + GetTimeout: c.Duration(GetTimeoutFlagName), + MaxConcurrentRequests: c.Uint64(MaxConcurrentRequestsFlagName), } } diff --git a/op-alt-da/daclient.go b/op-alt-da/daclient.go index db9c66ce5c21..269b71f3c104 100644 --- a/op-alt-da/daclient.go +++ b/op-alt-da/daclient.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "net/http" + "time" ) // ErrNotFound is returned when the server could not find the input. @@ -23,10 +24,16 @@ type DAClient struct { verify bool // whether commitment is precomputable (only applicable to keccak256) precompute bool + getTimeout time.Duration + putTimeout time.Duration } func NewDAClient(url string, verify bool, pc bool) *DAClient { - return &DAClient{url, verify, pc} + return &DAClient{ + url: url, + verify: verify, + precompute: pc, + } } // GetInput returns the input data for the given encoded commitment bytes. @@ -35,7 +42,8 @@ func (c *DAClient) GetInput(ctx context.Context, comm CommitmentData) ([]byte, e if err != nil { return nil, fmt.Errorf("failed to create HTTP request: %w", err) } - resp, err := http.DefaultClient.Do(req) + client := &http.Client{Timeout: c.getTimeout} + resp, err := client.Do(req) if err != nil { return nil, err } @@ -91,7 +99,8 @@ func (c *DAClient) setInputWithCommit(ctx context.Context, comm CommitmentData, return fmt.Errorf("failed to create HTTP request: %w", err) } req.Header.Set("Content-Type", "application/octet-stream") - resp, err := http.DefaultClient.Do(req) + client := &http.Client{Timeout: c.putTimeout} + resp, err := client.Do(req) if err != nil { return err } @@ -116,7 +125,8 @@ func (c *DAClient) setInput(ctx context.Context, img []byte) (CommitmentData, er return nil, fmt.Errorf("failed to create HTTP request: %w", err) } req.Header.Set("Content-Type", "application/octet-stream") - resp, err := http.DefaultClient.Do(req) + client := &http.Client{Timeout: c.putTimeout} + resp, err := client.Do(req) if err != nil { return nil, err } diff --git a/op-alt-da/daclient_test.go b/op-alt-da/daclient_test.go index 02a9611ae276..d9f7902aadee 100644 --- a/op-alt-da/daclient_test.go +++ b/op-alt-da/daclient_test.go @@ -2,48 +2,14 @@ package altda import ( "context" - "fmt" "math/rand" - "sync" "testing" "github.com/ethereum-optimism/optimism/op-service/testlog" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/require" ) -type MemStore struct { - db map[string][]byte - lock sync.RWMutex -} - -func NewMemStore() *MemStore { - return &MemStore{ - db: make(map[string][]byte), - } -} - -// Get retrieves the given key if it's present in the key-value store. -func (s *MemStore) Get(ctx context.Context, key []byte) ([]byte, error) { - s.lock.RLock() - defer s.lock.RUnlock() - - if entry, ok := s.db[string(key)]; ok { - return common.CopyBytes(entry), nil - } - return nil, ErrNotFound -} - -// Put inserts the given value into the key-value store. -func (s *MemStore) Put(ctx context.Context, key []byte, value []byte) error { - s.lock.Lock() - defer s.lock.Unlock() - - s.db[string(key)] = common.CopyBytes(value) - return nil -} - func TestDAClientPrecomputed(t *testing.T) { store := NewMemStore() logger := testlog.Logger(t, log.LevelDebug) @@ -56,7 +22,7 @@ func TestDAClientPrecomputed(t *testing.T) { cfg := CLIConfig{ Enabled: true, - DAServerURL: fmt.Sprintf("http://%s", server.Endpoint()), + DAServerURL: server.HttpEndpoint(), VerifyOnRead: true, } require.NoError(t, cfg.Check()) @@ -113,7 +79,7 @@ func TestDAClientService(t *testing.T) { cfg := CLIConfig{ Enabled: true, - DAServerURL: fmt.Sprintf("http://%s", server.Endpoint()), + DAServerURL: server.HttpEndpoint(), VerifyOnRead: false, GenericDA: false, } diff --git a/op-alt-da/damock.go b/op-alt-da/damock.go index b56b73fdfcc9..0db129171a82 100644 --- a/op-alt-da/damock.go +++ b/op-alt-da/damock.go @@ -4,8 +4,12 @@ import ( "context" "errors" "io" + "net/http" + "sync" + "time" "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb/memorydb" "github.com/ethereum/go-ethereum/log" @@ -99,3 +103,84 @@ func (d *AltDADisabled) OnFinalizedHeadSignal(f HeadSignalFn) { func (d *AltDADisabled) AdvanceL1Origin(ctx context.Context, l1 L1Fetcher, blockId eth.BlockID) error { return ErrNotEnabled } + +// FakeDAServer is a fake DA server for e2e tests. +// It is a small wrapper around DAServer that allows for setting request latencies, +// to mimic a DA service with slow responses (eg. eigenDA with 10 min batching interval). +type FakeDAServer struct { + *DAServer + putRequestLatency time.Duration + getRequestLatency time.Duration +} + +func NewFakeDAServer(host string, port int, log log.Logger) *FakeDAServer { + store := NewMemStore() + fakeDAServer := &FakeDAServer{ + DAServer: NewDAServer(host, port, store, log, true), + putRequestLatency: 0, + getRequestLatency: 0, + } + return fakeDAServer +} + +func (s *FakeDAServer) HandleGet(w http.ResponseWriter, r *http.Request) { + time.Sleep(s.getRequestLatency) + s.DAServer.HandleGet(w, r) +} + +func (s *FakeDAServer) HandlePut(w http.ResponseWriter, r *http.Request) { + time.Sleep(s.putRequestLatency) + s.DAServer.HandlePut(w, r) +} + +func (s *FakeDAServer) Start() error { + err := s.DAServer.Start() + if err != nil { + return err + } + // Override the HandleGet/Put method registrations + mux := http.NewServeMux() + mux.HandleFunc("/get/", s.HandleGet) + mux.HandleFunc("/put/", s.HandlePut) + s.httpServer.Handler = mux + return nil +} + +func (s *FakeDAServer) SetPutRequestLatency(latency time.Duration) { + s.putRequestLatency = latency +} + +func (s *FakeDAServer) SetGetRequestLatency(latency time.Duration) { + s.getRequestLatency = latency +} + +type MemStore struct { + db map[string][]byte + lock sync.RWMutex +} + +func NewMemStore() *MemStore { + return &MemStore{ + db: make(map[string][]byte), + } +} + +// Get retrieves the given key if it's present in the key-value store. +func (s *MemStore) Get(ctx context.Context, key []byte) ([]byte, error) { + s.lock.RLock() + defer s.lock.RUnlock() + + if entry, ok := s.db[string(key)]; ok { + return common.CopyBytes(entry), nil + } + return nil, ErrNotFound +} + +// Put inserts the given value into the key-value store. +func (s *MemStore) Put(ctx context.Context, key []byte, value []byte) error { + s.lock.Lock() + defer s.lock.Unlock() + + s.db[string(key)] = common.CopyBytes(value) + return nil +} diff --git a/op-alt-da/daserver.go b/op-alt-da/daserver.go index ef43fd27fef3..94446944b543 100644 --- a/op-alt-da/daserver.go +++ b/op-alt-da/daserver.go @@ -187,8 +187,8 @@ func (d *DAServer) HandlePut(w http.ResponseWriter, r *http.Request) { } } -func (b *DAServer) Endpoint() string { - return b.listener.Addr().String() +func (b *DAServer) HttpEndpoint() string { + return fmt.Sprintf("http://%s", b.listener.Addr().String()) } func (b *DAServer) Stop() error { diff --git a/op-batcher/batcher/driver.go b/op-batcher/batcher/driver.go index 0af4c86ca40a..9dbd9e802688 100644 --- a/op-batcher/batcher/driver.go +++ b/op-batcher/batcher/driver.go @@ -22,6 +22,7 @@ import ( "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" + "golang.org/x/sync/errgroup" ) var ( @@ -302,6 +303,12 @@ func (l *BatchSubmitter) loop() { receiptsCh := make(chan txmgr.TxReceipt[txRef]) queue := txmgr.NewQueue[txRef](l.killCtx, l.Txmgr, l.Config.MaxPendingTransactions) + daGroup := &errgroup.Group{} + // errgroup with limit of 0 means no goroutine is able to run concurrently, + // so we only set the limit if it is greater than 0. + if l.Config.MaxConcurrentDARequests > 0 { + daGroup.SetLimit(int(l.Config.MaxConcurrentDARequests)) + } // start the receipt/result processing loop receiptLoopDone := make(chan struct{}) @@ -339,9 +346,20 @@ func (l *BatchSubmitter) loop() { defer ticker.Stop() publishAndWait := func() { - l.publishStateToL1(queue, receiptsCh) + l.publishStateToL1(queue, receiptsCh, daGroup) if !l.Txmgr.IsClosed() { - queue.Wait() + if l.Config.UseAltDA { + l.Log.Info("Waiting for altDA writes to complete...") + err := daGroup.Wait() + if err != nil { + l.Log.Error("Error returned by one of the altda goroutines waited on", "err", err) + } + } + l.Log.Info("Waiting for L1 txs to be confirmed...") + err := queue.Wait() + if err != nil { + l.Log.Error("Error returned by one of the txmgr goroutines waited on", "err", err) + } } else { l.Log.Info("Txmgr is closed, remaining channel data won't be sent") } @@ -368,7 +386,7 @@ func (l *BatchSubmitter) loop() { l.clearState(l.shutdownCtx) continue } - l.publishStateToL1(queue, receiptsCh) + l.publishStateToL1(queue, receiptsCh, daGroup) case <-l.shutdownCtx.Done(): if l.Txmgr.IsClosed() { l.Log.Info("Txmgr is closed, remaining channel data won't be sent") @@ -425,7 +443,7 @@ func (l *BatchSubmitter) waitNodeSync() error { // publishStateToL1 queues up all pending TxData to be published to the L1, returning when there is // no more data to queue for publishing or if there was an error queing the data. -func (l *BatchSubmitter) publishStateToL1(queue *txmgr.Queue[txRef], receiptsCh chan txmgr.TxReceipt[txRef]) { +func (l *BatchSubmitter) publishStateToL1(queue *txmgr.Queue[txRef], receiptsCh chan txmgr.TxReceipt[txRef], daGroup *errgroup.Group) { for { // if the txmgr is closed, we stop the transaction sending if l.Txmgr.IsClosed() { @@ -436,7 +454,7 @@ func (l *BatchSubmitter) publishStateToL1(queue *txmgr.Queue[txRef], receiptsCh l.Log.Info("txpool state is not good, aborting state publishing") return } - err := l.publishTxToL1(l.killCtx, queue, receiptsCh) + err := l.publishTxToL1(l.killCtx, queue, receiptsCh, daGroup) if err != nil { if err != io.EOF { @@ -487,7 +505,7 @@ func (l *BatchSubmitter) clearState(ctx context.Context) { } // publishTxToL1 submits a single state tx to the L1 -func (l *BatchSubmitter) publishTxToL1(ctx context.Context, queue *txmgr.Queue[txRef], receiptsCh chan txmgr.TxReceipt[txRef]) error { +func (l *BatchSubmitter) publishTxToL1(ctx context.Context, queue *txmgr.Queue[txRef], receiptsCh chan txmgr.TxReceipt[txRef], daGroup *errgroup.Group) error { // send all available transactions l1tip, err := l.l1Tip(ctx) if err != nil { @@ -496,7 +514,8 @@ func (l *BatchSubmitter) publishTxToL1(ctx context.Context, queue *txmgr.Queue[t } l.recordL1Tip(l1tip) - // Collect next transaction data + // Collect next transaction data. This pulls data out of the channel, so we need to make sure + // to put it back if ever da or txmgr requests fail, by calling l.recordFailedDARequest/recordFailedTx. txdata, err := l.state.TxData(l1tip.ID()) if err == io.EOF { @@ -507,7 +526,7 @@ func (l *BatchSubmitter) publishTxToL1(ctx context.Context, queue *txmgr.Queue[t return err } - if err = l.sendTransaction(ctx, txdata, queue, receiptsCh); err != nil { + if err = l.sendTransaction(txdata, queue, receiptsCh, daGroup); err != nil { return fmt.Errorf("BatchSubmitter.sendTransaction failed: %w", err) } return nil @@ -552,12 +571,56 @@ func (l *BatchSubmitter) cancelBlockingTx(queue *txmgr.Queue[txRef], receiptsCh l.sendTx(txData{}, true, candidate, queue, receiptsCh) } +// publishToAltDAAndL1 posts the txdata to the DA Provider and then sends the commitment to L1. +func (l *BatchSubmitter) publishToAltDAAndL1(txdata txData, queue *txmgr.Queue[txRef], receiptsCh chan txmgr.TxReceipt[txRef], daGroup *errgroup.Group) { + // sanity checks + if nf := len(txdata.frames); nf != 1 { + l.Log.Crit("Unexpected number of frames in calldata tx", "num_frames", nf) + } + if txdata.asBlob { + l.Log.Crit("Unexpected blob txdata with AltDA enabled") + } + + // when posting txdata to an external DA Provider, we use a goroutine to avoid blocking the main loop + // since it may take a while for the request to return. + goroutineSpawned := daGroup.TryGo(func() error { + // TODO: probably shouldn't be using the global shutdownCtx here, see https://go.dev/blog/context-and-structs + // but sendTransaction receives l.killCtx as an argument, which currently is only canceled after waiting for the main loop + // to exit, which would wait on this DA call to finish, which would take a long time. + // So we prefer to mimic the behavior of txmgr and cancel all pending DA/txmgr requests when the batcher is stopped. + comm, err := l.AltDA.SetInput(l.shutdownCtx, txdata.CallData()) + if err != nil { + l.Log.Error("Failed to post input to Alt DA", "error", err) + // requeue frame if we fail to post to the DA Provider so it can be retried + // note: this assumes that the da server caches requests, otherwise it might lead to resubmissions of the blobs + l.recordFailedDARequest(txdata.ID(), err) + return nil + } + l.Log.Info("Set altda input", "commitment", comm, "tx", txdata.ID()) + candidate := l.calldataTxCandidate(comm.TxData()) + l.sendTx(txdata, false, candidate, queue, receiptsCh) + return nil + }) + if !goroutineSpawned { + // We couldn't start the goroutine because the errgroup.Group limit + // is already reached. Since we can't send the txdata, we have to + // return it for later processing. We use nil error to skip error logging. + l.recordFailedDARequest(txdata.ID(), nil) + } +} + // sendTransaction creates & queues for sending a transaction to the batch inbox address with the given `txData`. // This call will block if the txmgr queue is at the max-pending limit. // The method will block if the queue's MaxPendingTransactions is exceeded. -func (l *BatchSubmitter) sendTransaction(ctx context.Context, txdata txData, queue *txmgr.Queue[txRef], receiptsCh chan txmgr.TxReceipt[txRef]) error { +func (l *BatchSubmitter) sendTransaction(txdata txData, queue *txmgr.Queue[txRef], receiptsCh chan txmgr.TxReceipt[txRef], daGroup *errgroup.Group) error { var err error - // Do the gas estimation offline. A value of 0 will cause the [txmgr] to estimate the gas limit. + + // if Alt DA is enabled we post the txdata to the DA Provider and replace it with the commitment. + if l.Config.UseAltDA { + l.publishToAltDAAndL1(txdata, queue, receiptsCh, daGroup) + // we return nil to allow publishStateToL1 to keep processing the next txdata + return nil + } var candidate *txmgr.TxCandidate if txdata.asBlob { @@ -573,21 +636,7 @@ func (l *BatchSubmitter) sendTransaction(ctx context.Context, txdata txData, que if nf := len(txdata.frames); nf != 1 { l.Log.Crit("Unexpected number of frames in calldata tx", "num_frames", nf) } - data := txdata.CallData() - // if AltDA is enabled we post the txdata to the DA Provider and replace it with the commitment. - if l.Config.UseAltDA { - comm, err := l.AltDA.SetInput(ctx, data) - if err != nil { - l.Log.Error("Failed to post input to Alt DA", "error", err) - // requeue frame if we fail to post to the DA Provider so it can be retried - l.recordFailedTx(txdata.ID(), err) - return nil - } - l.Log.Info("Set AltDA input", "commitment", comm, "tx", txdata.ID()) - // signal AltDA commitment tx with TxDataVersion1 - data = comm.TxData() - } - candidate = l.calldataTxCandidate(data) + candidate = l.calldataTxCandidate(txdata.CallData()) } l.sendTx(txdata, false, candidate, queue, receiptsCh) @@ -649,6 +698,13 @@ func (l *BatchSubmitter) recordL1Tip(l1tip eth.L1BlockRef) { l.Metr.RecordLatestL1Block(l1tip) } +func (l *BatchSubmitter) recordFailedDARequest(id txID, err error) { + if err != nil { + l.Log.Warn("DA request failed", logFields(id, err)...) + } + l.state.TxFailed(id) +} + func (l *BatchSubmitter) recordFailedTx(id txID, err error) { l.Log.Warn("Transaction failed to send", logFields(id, err)...) l.state.TxFailed(id) diff --git a/op-batcher/batcher/service.go b/op-batcher/batcher/service.go index 9b896817f145..edd31f465d16 100644 --- a/op-batcher/batcher/service.go +++ b/op-batcher/batcher/service.go @@ -39,6 +39,8 @@ type BatcherConfig struct { // UseAltDA is true if the rollup config has a DA challenge address so the batcher // will post inputs to the DA server and post commitments to blobs or calldata. UseAltDA bool + // maximum number of concurrent blob put requests to the DA server + MaxConcurrentDARequests uint64 WaitNodeSync bool CheckRecentTxsDepth int @@ -93,6 +95,7 @@ func (bs *BatcherService) initFromCLIConfig(ctx context.Context, version string, bs.PollInterval = cfg.PollInterval bs.MaxPendingTransactions = cfg.MaxPendingTransactions + bs.MaxConcurrentDARequests = cfg.AltDA.MaxConcurrentRequests bs.NetworkTimeout = cfg.TxMgrConfig.NetworkTimeout bs.CheckRecentTxsDepth = cfg.CheckRecentTxsDepth bs.WaitNodeSync = cfg.WaitNodeSync diff --git a/op-e2e/e2eutils/transactions/count.go b/op-e2e/e2eutils/transactions/count.go new file mode 100644 index 000000000000..0f4d41fe0478 --- /dev/null +++ b/op-e2e/e2eutils/transactions/count.go @@ -0,0 +1,21 @@ +package transactions + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +func TransactionsBySender(block *types.Block, sender common.Address) (int64, error) { + txCount := int64(0) + for _, tx := range block.Transactions() { + signer := types.NewCancunSigner(tx.ChainId()) + txSender, err := types.Sender(signer, tx) + if err != nil { + return 0, err + } + if txSender == sender { + txCount++ + } + } + return txCount, nil +} diff --git a/op-e2e/setup.go b/op-e2e/setup.go index cd07e081d0dd..ab2218b097d4 100644 --- a/op-e2e/setup.go +++ b/op-e2e/setup.go @@ -39,6 +39,7 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" + altda "github.com/ethereum-optimism/optimism/op-alt-da" bss "github.com/ethereum-optimism/optimism/op-batcher/batcher" batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" @@ -164,18 +165,19 @@ func DefaultSystemConfig(t testing.TB) SystemConfig { }, }, Loggers: map[string]log.Logger{ - RoleVerif: testlog.Logger(t, log.LevelInfo).New("role", RoleVerif), - RoleSeq: testlog.Logger(t, log.LevelInfo).New("role", RoleSeq), - "batcher": testlog.Logger(t, log.LevelInfo).New("role", "batcher"), - "proposer": testlog.Logger(t, log.LevelInfo).New("role", "proposer"), + RoleVerif: testlog.Logger(t, log.LevelInfo).New("role", RoleVerif), + RoleSeq: testlog.Logger(t, log.LevelInfo).New("role", RoleSeq), + "batcher": testlog.Logger(t, log.LevelInfo).New("role", "batcher"), + "proposer": testlog.Logger(t, log.LevelInfo).New("role", "proposer"), + "da-server": testlog.Logger(t, log.LevelInfo).New("role", "da-server"), }, - GethOptions: map[string][]geth.GethOption{}, - P2PTopology: nil, // no P2P connectivity by default - NonFinalizedProposals: false, - ExternalL2Shim: config.ExternalL2Shim, - DataAvailabilityType: batcherFlags.CalldataType, - MaxPendingTransactions: 1, - BatcherTargetNumFrames: 1, + GethOptions: map[string][]geth.GethOption{}, + P2PTopology: nil, // no P2P connectivity by default + NonFinalizedProposals: false, + ExternalL2Shim: config.ExternalL2Shim, + DataAvailabilityType: batcherFlags.CalldataType, + BatcherMaxPendingTransactions: 1, + BatcherTargetNumFrames: 1, } } @@ -298,12 +300,16 @@ type SystemConfig struct { // If >0, limits the number of blocks per span batch BatcherMaxBlocksPerSpanBatch int + // BatcherMaxPendingTransactions determines how many transactions the batcher will try to send + // concurrently. 0 means unlimited. + BatcherMaxPendingTransactions uint64 + + // BatcherMaxConcurrentDARequest determines how many DAserver requests the batcher is allowed to + // make concurrently. 0 means unlimited. + BatcherMaxConcurrentDARequest uint64 + // SupportL1TimeTravel determines if the L1 node supports quickly skipping forward in time SupportL1TimeTravel bool - - // MaxPendingTransactions determines how many transactions the batcher will try to send - // concurrently. 0 means unlimited. - MaxPendingTransactions uint64 } type System struct { @@ -319,6 +325,7 @@ type System struct { L2OutputSubmitter *l2os.ProposerService BatchSubmitter *bss.BatcherService Mocknet mocknet.Mocknet + FakeAltDAServer *altda.FakeDAServer L1BeaconAPIAddr endpoint.RestHTTP @@ -543,6 +550,16 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste } } + var rollupAltDAConfig *rollup.AltDAConfig + if cfg.DeployConfig.UseAltDA { + rollupAltDAConfig = &rollup.AltDAConfig{ + DAChallengeAddress: cfg.L1Deployments.DataAvailabilityChallengeProxy, + DAChallengeWindow: cfg.DeployConfig.DAChallengeWindow, + DAResolveWindow: cfg.DeployConfig.DAResolveWindow, + CommitmentType: altda.GenericCommitmentString, + } + } + makeRollupConfig := func() rollup.Config { return rollup.Config{ Genesis: rollup.Genesis{ @@ -574,6 +591,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste GraniteTime: cfg.DeployConfig.GraniteTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)), InteropTime: cfg.DeployConfig.InteropTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)), ProtocolVersionsAddress: cfg.L1Deployments.ProtocolVersionsProxy, + AltDAConfig: rollupAltDAConfig, } } defaultConfig := makeRollupConfig() @@ -819,11 +837,27 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste compressionAlgo = derive.Brotli10 } + var batcherAltDACLIConfig altda.CLIConfig + if cfg.DeployConfig.UseAltDA { + fakeAltDAServer := altda.NewFakeDAServer("127.0.0.1", 0, sys.Cfg.Loggers["da-server"]) + if err := fakeAltDAServer.Start(); err != nil { + return nil, fmt.Errorf("failed to start fake altDA server: %w", err) + } + sys.FakeAltDAServer = fakeAltDAServer + + batcherAltDACLIConfig = altda.CLIConfig{ + Enabled: cfg.DeployConfig.UseAltDA, + DAServerURL: fakeAltDAServer.HttpEndpoint(), + VerifyOnRead: true, + GenericDA: true, + MaxConcurrentRequests: cfg.BatcherMaxConcurrentDARequest, + } + } batcherCLIConfig := &bss.CLIConfig{ L1EthRpc: sys.EthInstances[RoleL1].UserRPC().RPC(), L2EthRpc: sys.EthInstances[RoleSeq].UserRPC().RPC(), RollupRpc: sys.RollupNodes[RoleSeq].UserRPC().RPC(), - MaxPendingTransactions: cfg.MaxPendingTransactions, + MaxPendingTransactions: cfg.BatcherMaxPendingTransactions, MaxChannelDuration: 1, MaxL1TxSize: batcherMaxL1TxSizeBytes, TestUseMaxTxSizeForBlobs: cfg.BatcherUseMaxTxSizeForBlobs, @@ -841,6 +875,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste MaxBlocksPerSpanBatch: cfg.BatcherMaxBlocksPerSpanBatch, DataAvailabilityType: sys.Cfg.DataAvailabilityType, CompressionAlgo: compressionAlgo, + AltDA: batcherAltDACLIConfig, } // Batch Submitter batcher, err := bss.BatcherServiceFromCLIConfig(context.Background(), "0.0.1", batcherCLIConfig, sys.Cfg.Loggers["batcher"]) diff --git a/op-e2e/system_test.go b/op-e2e/system_test.go index a168a8c90df6..37fbfe0e7ad8 100644 --- a/op-e2e/system_test.go +++ b/op-e2e/system_test.go @@ -14,6 +14,7 @@ import ( "github.com/libp2p/go-libp2p/core/peer" "github.com/stretchr/testify/require" + "github.com/ethereum-optimism/optimism/op-batcher/flags" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" @@ -1362,7 +1363,7 @@ func TestBatcherMultiTx(t *testing.T) { InitParallel(t) cfg := DefaultSystemConfig(t) - cfg.MaxPendingTransactions = 0 // no limit on parallel txs + cfg.BatcherMaxPendingTransactions = 0 // no limit on parallel txs // ensures that batcher txs are as small as possible cfg.BatcherMaxL1TxSizeBytes = derive.FrameV0OverHeadSize + 1 /*version bytes*/ + 1 cfg.DisableBatcher = true @@ -1375,7 +1376,7 @@ func TestBatcherMultiTx(t *testing.T) { _, err = geth.WaitForBlock(big.NewInt(10), l2Seq, time.Duration(cfg.DeployConfig.L2BlockTime*15)*time.Second) require.NoError(t, err, "Waiting for L2 blocks") - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() l1Number, err := l1Client.BlockNumber(ctx) require.NoError(t, err) @@ -1385,16 +1386,80 @@ func TestBatcherMultiTx(t *testing.T) { err = driver.StartBatchSubmitting() require.NoError(t, err) - totalTxCount := 0 - // wait for up to 10 L1 blocks, usually only 3 is required, but it's + totalBatcherTxsCount := int64(0) + // wait for up to 5 L1 blocks, usually only 3 is required, but it's // possible additional L1 blocks will be created before the batcher starts, // so we wait additional blocks. - for i := int64(0); i < 10; i++ { - block, err := geth.WaitForBlock(big.NewInt(int64(l1Number)+i), l1Client, time.Duration(cfg.DeployConfig.L1BlockTime*5)*time.Second) + for i := int64(0); i < 5; i++ { + block, err := geth.WaitForBlock(big.NewInt(int64(l1Number)+i), l1Client, time.Duration(cfg.DeployConfig.L1BlockTime*2)*time.Second) + require.NoError(t, err, "Waiting for l1 blocks") + // there are possibly other services (proposer/challenger) in the background sending txs + // so we only count the batcher txs + batcherTxCount, err := transactions.TransactionsBySender(block, cfg.DeployConfig.BatchSenderAddress) + require.NoError(t, err) + totalBatcherTxsCount += int64(batcherTxCount) + + if totalBatcherTxsCount >= 10 { + return + } + } + + t.Fatal("Expected at least 10 transactions from the batcher") +} + +func TestBatcherConcurrentAltDARequests(t *testing.T) { + InitParallel(t) + + numL1TxsExpected := int64(10) + + cfg := DefaultSystemConfig(t) + cfg.DeployConfig.UseAltDA = true + cfg.BatcherMaxPendingTransactions = 0 // no limit on parallel txs + // ensures that batcher txs are as small as possible + cfg.BatcherMaxL1TxSizeBytes = derive.FrameV0OverHeadSize + 1 /*version bytes*/ + 1 + cfg.BatcherBatchType = 0 + cfg.DataAvailabilityType = flags.CalldataType + cfg.BatcherMaxConcurrentDARequest = uint64(numL1TxsExpected) + + // disable batcher because we start it manually below + cfg.DisableBatcher = true + sys, err := cfg.Start(t) + require.NoError(t, err, "Error starting up system") + defer sys.Close() + + // make every request take 5 seconds, such that only concurrent requests will be able to make progress fast enough + sys.FakeAltDAServer.SetPutRequestLatency(5 * time.Second) + + l1Client := sys.NodeClient("l1") + l2Seq := sys.NodeClient("sequencer") + + // we wait for numL1TxsExpected L2 blocks to have been produced, just to make sure the sequencer is working properly + _, err = geth.WaitForBlock(big.NewInt(numL1TxsExpected), l2Seq, time.Duration(cfg.DeployConfig.L2BlockTime*uint64(numL1TxsExpected))*time.Second) + require.NoError(t, err, "Waiting for L2 blocks") + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + startingL1BlockNum, err := l1Client.BlockNumber(ctx) + require.NoError(t, err) + + // start batch submission + driver := sys.BatchSubmitter.TestDriver() + err = driver.StartBatchSubmitting() + require.NoError(t, err) + + totalBatcherTxsCount := int64(0) + // wait for up to 5 L1 blocks, expecting 10 L2 batcher txs in them. + // usually only 3 is required, but it's possible additional L1 blocks will be created + // before the batcher starts, so we wait additional blocks. + for i := int64(0); i < 5; i++ { + block, err := geth.WaitForBlock(big.NewInt(int64(startingL1BlockNum)+i), l1Client, time.Duration(cfg.DeployConfig.L1BlockTime*2)*time.Second) require.NoError(t, err, "Waiting for l1 blocks") - totalTxCount += len(block.Transactions()) + // there are possibly other services (proposer/challenger) in the background sending txs + // so we only count the batcher txs + batcherTxCount, err := transactions.TransactionsBySender(block, cfg.DeployConfig.BatchSenderAddress) + require.NoError(t, err) + totalBatcherTxsCount += int64(batcherTxCount) - if totalTxCount >= 10 { + if totalBatcherTxsCount >= numL1TxsExpected { return } } diff --git a/op-service/txmgr/queue.go b/op-service/txmgr/queue.go index cf83b00d5f8a..ee7a03ffa928 100644 --- a/op-service/txmgr/queue.go +++ b/op-service/txmgr/queue.go @@ -44,11 +44,11 @@ func NewQueue[T any](ctx context.Context, txMgr TxManager, maxPending uint64) *Q } // Wait waits for all pending txs to complete (or fail). -func (q *Queue[T]) Wait() { +func (q *Queue[T]) Wait() error { if q.group == nil { - return + return nil } - _ = q.group.Wait() + return q.group.Wait() } // Send will wait until the number of pending txs is below the max pending, diff --git a/op-service/txmgr/queue_test.go b/op-service/txmgr/queue_test.go index 678de8dbb28c..549142c8592a 100644 --- a/op-service/txmgr/queue_test.go +++ b/op-service/txmgr/queue_test.go @@ -222,7 +222,7 @@ func TestQueue_Send(t *testing.T) { require.Equal(t, c.queued, queued, msg) } // wait for the queue to drain (all txs complete or failed) - queue.Wait() + _ = queue.Wait() duration := time.Since(start) // expect the execution time within a certain window now := time.Now() From 9d8c34266c55fd5c7979f497c34f636e06728922 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Wed, 11 Sep 2024 17:18:30 -0400 Subject: [PATCH 098/264] feat: run extra fuzz rounds for new fuzz tests (#11748) Adds a new script that can run extra fuzz test iterations when new fuzz tests are added. Can be used in CI or locally to make sure that new fuzz tests aren't flaky. --- .circleci/config.yml | 33 ++--- packages/contracts-bedrock/justfile | 4 + .../testing/test-heavy-fuzz-modified-tests.sh | 127 ++++++++++++++++++ 3 files changed, 148 insertions(+), 16 deletions(-) create mode 100755 packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 2abeb3c0c437..d34fed3947fe 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -556,10 +556,9 @@ jobs: description: Number of test jobs to run in parallel type: integer default: 4 - test_filter: + test_command: description: List of test files to run type: string - default: find ./test -name "*.t.sol" parallelism: <> steps: - checkout @@ -593,17 +592,7 @@ jobs: working_directory: packages/contracts-bedrock - run: name: run tests - command: | - # Find all test files - TEST_FILES=$(<>) - # Split the tests by timings - TEST_FILES=$(echo "$TEST_FILES" | circleci tests split --split-by=timings) - # Strip the leading "./test/" from each file path - TEST_FILES=$(echo "$TEST_FILES" | sed 's|./test/||') - # Generate the match path - MATCH_PATH="./test/{$(echo "$TEST_FILES" | paste -sd "," -)}" - # Run the tests - forge test --match-path "$MATCH_PATH" + command: <> environment: FOUNDRY_PROFILE: ci working_directory: packages/contracts-bedrock @@ -1572,13 +1561,25 @@ workflows: forge build --skip test --skip scripts forge build ./scripts/deploy/Deploy.s.sol - contracts-bedrock-tests: - test_filter: find . -name "*.t.sol" -not -name "PreimageOracle.t.sol" + # Test everything except PreimageOracle.t.sol since it's slow. + name: contracts-bedrock-tests test_parallelism: 4 + test_command: | + TEST_FILES=$(find . -name "*.t.sol" -not -name "PreimageOracle.t.sol") + TEST_FILES=$(echo "$TEST_FILES" | circleci tests split --split-by=timings) + TEST_FILES=$(echo "$TEST_FILES" | sed 's|./test/||') + MATCH_PATH="./test/{$(echo "$TEST_FILES" | paste -sd "," -)}" + forge test --match-path "$MATCH_PATH" - contracts-bedrock-tests: - # PreimageOracle test is slow, run it separately to unblock CI + # PreimageOracle test is slow, run it separately to unblock CI. name: contracts-bedrock-tests-preimage-oracle - test_filter: find . -name "PreimageOracle.t.sol" test_parallelism: 1 + test_command: forge test --match-path ./test/cannon/PreimageOracle.t.sol + - contracts-bedrock-tests: + # Heavily fuzz any fuzz tests that have been added or modified. + name: contracts-bedrock-tests-heavy-fuzz-modified + test_parallelism: 1 + test_command: just test-heavy-fuzz-modified-tests - contracts-bedrock-coverage - contracts-bedrock-checks: requires: diff --git a/packages/contracts-bedrock/justfile b/packages/contracts-bedrock/justfile index 69a737d4430d..49b39c0c4837 100644 --- a/packages/contracts-bedrock/justfile +++ b/packages/contracts-bedrock/justfile @@ -29,6 +29,10 @@ test-kontrol-no-build: test-rerun: build-go-ffi forge test --rerun -vvv +# Run extra fuzz iterations for modified fuzz tests. +test-heavy-fuzz-modified-tests: build-go-ffi + ./scripts/testing/test-heavy-fuzz-modified-tests.sh + genesis: forge script scripts/L2Genesis.s.sol:L2Genesis --sig 'runWithStateDump()' diff --git a/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh b/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh new file mode 100755 index 000000000000..4974a01dedcd --- /dev/null +++ b/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh @@ -0,0 +1,127 @@ +#!/usr/bin/env bash +set -euo pipefail + +# This script is used to run extra fuzz test iterations on any fuzz tests that +# have been added or modified in a PR. We typically want to run extra fuzz +# iterations when new tests are added to make sure that they are not flaky with +# some small percentage of fuzz runs. +# NOTE: This script is NOT perfect and can only catch changes to fuzz tests +# that are made within the test file itself. It won't catch changes to +# dependencies or other external factors that might impact the behavior of the +# fuzz test. This script may also run fuzz tests that have not actually been +# modified. + +# Set the number of fuzz runs to run. +# 350000 fuzz runs will guarantee that any test that fails 1% of the time with +# the default 512 fuzz runs will fail 99.9% of the time (on average) inside of +# this script. +FUZZ_RUNS=${1:-350000} + +# Set the number of invariant runs to run. +# Invariant runs are generally slower than fuzz runs so we can't afford to run +# as many of them. 25000 is probably good enough for most cases. +INVARIANT_RUNS=${2:-25000} + +# Verify that FUZZ_RUNS is a number. +if ! [[ "$FUZZ_RUNS" =~ ^[0-9]+$ ]]; then + echo "Fuzz runs must be a number" + exit 1 +fi + +# Trap any errors and exit. +trap 'echo "Script failed at line $LINENO"' ERR + +# Get the various base directories. +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +CONTRACTS_BASE=$(dirname "$(dirname "$SCRIPT_DIR")") +ROOT_DIR=$(dirname "$(dirname "$CONTRACTS_BASE")") + +# Change to the root directory. +cd "$ROOT_DIR" + +# Get a list of changed Solidity test files relative to the project root. +CHANGED_FILES=$(git diff origin/develop...HEAD --name-only -- '*.sol') + +# Exit if no changed Solidity files are found. +if [ -z "$CHANGED_FILES" ]; then + echo "No changed Solidity files found" + exit 0 +fi + +# Initialize an array to hold relevant function names. +NEW_OR_MODIFIED_TEST_NAMES="" + +# Process each changed file. +for FILE in $CHANGED_FILES; do + # Get the diff for the file. + DIFF=$(git diff origin/develop...HEAD --unified=0 -- "$FILE") + + # Figure out every modified line. + MODIFIED_LINES=$(echo "$DIFF" | \ + awk '/^@@/ { + split($3, a, ",") + start = substr(a[1], 2) + if (length(a) > 1) + count = a[2] + else + count = 1 + for (i = 0; i < count; i++) + print start + i + }' | sort -n | uniq | xargs) + + # Extract function names and their line numbers from the entire file + FUNCTION_LINES=$(awk '/function testFuzz_|function invariant_/ {print FNR, $0}' "$FILE") + + # Reverse the function lines so we can match the last function modified. + # We'd otherwise end up matching the first function with a line number less + # than the modified line number which is not what we want. + FUNCTION_LINES=$(echo "$FUNCTION_LINES" | sort -r) + + # Process each modified line. + for MODIFIED_LINE_NUM in $MODIFIED_LINES; do + # Check all functions to find the last one where the line number of the + # function is less than or equal to the modified line number. This is + # the function that was most likely modified. + # NOTE: This is not perfect and may accidentally match a function that + # was not actually modified but it works well enough and at least won't + # accidentally miss any modified fuzz tests. + while IFS= read -r func; do + # Get the function line number and name. + FUNC_LINE_NUM=$(echo "$func" | awk '{print $1}') + FUNC_NAME=$(echo "$func" | awk '{print $3}' | sed 's/(.*//') + + # Check if the modified line number is greater than or equal to the + # function line number. If it is, then we've found the closest fuzz + # test that was modified. Again, this is not perfect and may lead + # to false positives but won't lead to false negatives. + if [ "$MODIFIED_LINE_NUM" -ge "$FUNC_LINE_NUM" ]; then + NEW_OR_MODIFIED_TEST_NAMES+="$FUNC_NAME " + break + fi + done <<< "$FUNCTION_LINES" + done +done + +# Remove duplicates and sort. +NEW_OR_MODIFIED_TEST_NAMES=$(echo "$NEW_OR_MODIFIED_TEST_NAMES" | xargs -n1 | sort -u | xargs) + +# Exit if no new or modified fuzz tests are found. +if [ -z "$NEW_OR_MODIFIED_TEST_NAMES" ]; then + echo "No new or modified fuzz tests found" + exit 0 +fi + +# Print the detected tests on different lines. +echo "Detected new or modified fuzz tests:" +for TEST_NAME in $NEW_OR_MODIFIED_TEST_NAMES; do + echo " $TEST_NAME" +done + +# Change to the contracts base directory. +cd "$CONTRACTS_BASE" + +# Set the number of invariant runs. +export FOUNDRY_INVARIANT_RUNS="$INVARIANT_RUNS" + +# Run the detected tests with extra fuzz runs +forge test --match-test "${NEW_OR_MODIFIED_TEST_NAMES// /|}" --fuzz-runs "$FUZZ_RUNS" From c21d0c5fa04faa116ef9572f5f9b36d3e03f3a36 Mon Sep 17 00:00:00 2001 From: Inphi Date: Wed, 11 Sep 2024 17:54:30 -0400 Subject: [PATCH 099/264] Release op-contracts/v1.6.0 (#11760) * op-contracts/v1.6.0-rc.1 release (#11528) * Fix deploy-config absolute prestate * chore: update semver-lock --------- Co-authored-by: smartcontracts Co-authored-by: Kelvin Fichter --- .../deploy-config/mainnet.json | 2 +- packages/contracts-bedrock/semver-lock.json | 24 +++++++++---------- .../src/Safe/DeputyGuardianModule.sol | 4 ++-- .../contracts-bedrock/src/cannon/MIPS.sol | 4 ++-- .../src/cannon/PreimageOracle.sol | 4 ++-- .../src/dispute/AnchorStateRegistry.sol | 4 ++-- .../src/dispute/FaultDisputeGame.sol | 4 ++-- .../src/dispute/weth/DelayedWETH.sol | 4 ++-- .../proofs/utils/DeploymentSummary.sol | 18 +++++++------- .../proofs/utils/DeploymentSummaryCode.sol | 14 +++++------ .../utils/DeploymentSummaryFaultProofs.sol | 18 +++++++------- .../DeploymentSummaryFaultProofsCode.sol | 14 +++++------ 12 files changed, 57 insertions(+), 57 deletions(-) diff --git a/packages/contracts-bedrock/deploy-config/mainnet.json b/packages/contracts-bedrock/deploy-config/mainnet.json index 807c12fe1939..cd217ba11153 100644 --- a/packages/contracts-bedrock/deploy-config/mainnet.json +++ b/packages/contracts-bedrock/deploy-config/mainnet.json @@ -42,7 +42,7 @@ "systemConfigStartBlock": 17422444, "requiredProtocolVersion": "0x0000000000000000000000000000000000000003000000010000000000000000", "recommendedProtocolVersion": "0x0000000000000000000000000000000000000003000000010000000000000000", - "faultGameAbsolutePrestate": "0x03e806a2859a875267a563462a06d4d1d1b455a9efee959a46e21e54b6caf69a", + "faultGameAbsolutePrestate": "0x038512e02c4c3f7bdaec27d00edf55b7155e0905301e1a88083e4e0a6764d54c", "faultGameMaxDepth": 73, "faultGameClockExtension": 10800, "faultGameMaxClockDuration": 302400, diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 8f44a70958a7..82d5b474eea2 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -132,8 +132,8 @@ "sourceCodeHash": "0x3f7bd622a788b8d00fe1631b14b761488eedccf56879f7ea2d610dd5ce81efbe" }, "src/Safe/DeputyGuardianModule.sol": { - "initCodeHash": "0xce6cd0e4f21693a32e7a8ef463b8233b0dde83bdb426f5adc3eef822d4de7bec", - "sourceCodeHash": "0x7b0f24df9af4cf5a52e23b98898b884d8175ad89cc24046d6463c3e9b3599d4d" + "initCodeHash": "0x785cb529957f4d42d1659f2c37967dce7c621f3c6e06550600897205c2551a88", + "sourceCodeHash": "0xc8df2c0ae90cff18ddd4d2b8e2d44689e3c4c98e96c746c4ee9baaebf6a80ec4" }, "src/Safe/LivenessGuard.sol": { "initCodeHash": "0xfd74ff89e7b689b38ab97515d64429ffaf6c0cd1ea6488c6a4743a0665419c85", @@ -144,32 +144,32 @@ "sourceCodeHash": "0x255a3f78036745feb57da2e16a93a83fe3f52944fec42029da9b9eaa147db11c" }, "src/cannon/MIPS.sol": { - "initCodeHash": "0x9a30f51e5516230f8a1a2a757fb992ef3283041f5cc5220dd0891ce815527dfb", - "sourceCodeHash": "0x368963e339be2dbf8f623f9458e870e061725fce20e5a4004e48c03273de7236" + "initCodeHash": "0xd151c45f4b4b2b96d111d37c78290bb461878df4481dbc4bfdd14428e177acc5", + "sourceCodeHash": "0x23543a88057256eb8fd3b4c52d82bb97e359134bd760bdf144e5f697307ce176" }, "src/cannon/MIPS2.sol": { "initCodeHash": "0xf5e2bca4ba0c504ffa68f1ce5fbf4349b1fa892034777d77803d9111aed279fa", "sourceCodeHash": "0x3c3716ac78180fc71d67b0f849b2ec28891b2e065d33d4d70b4b7279a12d4b66" }, "src/cannon/PreimageOracle.sol": { - "initCodeHash": "0xd321f266b19eca87e2f915e4cf1c973ed9beba39d1336df01c4957c72e3783f3", - "sourceCodeHash": "0x050b2f007715f27e9872d1f6dc7bd340cdf08ea11737548c17968ea2e94e75cc" + "initCodeHash": "0x801e52f9c8439fcf7089575fa93272dfb874641dbfc7d82f36d979c987271c0b", + "sourceCodeHash": "0xdb9421a552e6d7581b3db9e4c2a02d8210ad6ca66ba0f8703d77f7cd4b8e132b" }, "src/dispute/AnchorStateRegistry.sol": { - "initCodeHash": "0x6198f305686e6fdfd94db7aeb840a12e263036dcdc234550db49d3f0b87039a8", - "sourceCodeHash": "0x8450bdccf5039bad48284c73c9cfa657cbcc0a435965d9e13ac88f388c591779" + "initCodeHash": "0x73a094f7d00422c8a765a63f4645f9e2fb508655181f227fd9b338c62c26e106", + "sourceCodeHash": "0x7ed9631efb6f5cdec9fb09bc22f0e6248314db6331ed65f0baa462b230733b88" }, "src/dispute/DisputeGameFactory.sol": { "initCodeHash": "0xc1a10f65287c414076b68a7de6c238b91bc6252213187bdef35657d0f00f9382", "sourceCodeHash": "0x3d391c58420abe60d8486136a57d7f9c7137f722c80a8d884305617eb31566ef" }, "src/dispute/FaultDisputeGame.sol": { - "initCodeHash": "0xbeec6747b5d189a75528426ad9e2b329051953f69f2fc86bdad8cae22e33f659", - "sourceCodeHash": "0x6e7aab50fab2d42c7c3f67e4b0f0b74444d29409f275cf758915c7b76d31528f" + "initCodeHash": "0x0084ca38e6ceb3c70ce77ef9769a724e8be5b92457222ef2b09c63bb4b449bf2", + "sourceCodeHash": "0xf199eace79690c010d0f252819e62ef7ad165d9af19c1ee47a6aa451cda259b2" }, "src/dispute/weth/DelayedWETH.sol": { - "initCodeHash": "0x3e687c928b6c890b91c82584ccb1fec47b025b8e58cd9cbfa65229b38b304bae", - "sourceCodeHash": "0x9d6667536161b3fa655dfb3e9a01db070cd0e84d800e34947b10b3b2168a3d56" + "initCodeHash": "0x5e7251e2c638c907c8672166f770cf2bd1fda11eed1d629ceb7568fe2b670006", + "sourceCodeHash": "0x6817260542fe6c2acbc081aad9f4b91c1502e8ae75020197213a8f8d15b6463b" }, "src/legacy/DeployerWhitelist.sol": { "initCodeHash": "0x0b8177ed75b69eddbb9ce6537683f69a9935efed86a1d6faa8feaafbd151c1bd", diff --git a/packages/contracts-bedrock/src/Safe/DeputyGuardianModule.sol b/packages/contracts-bedrock/src/Safe/DeputyGuardianModule.sol index c1ac18fdc0c1..4b80c9da9200 100644 --- a/packages/contracts-bedrock/src/Safe/DeputyGuardianModule.sol +++ b/packages/contracts-bedrock/src/Safe/DeputyGuardianModule.sol @@ -50,8 +50,8 @@ contract DeputyGuardianModule is ISemver { address internal immutable DEPUTY_GUARDIAN; /// @notice Semantic version. - /// @custom:semver 2.0.1-beta.1 - string public constant version = "2.0.1-beta.1"; + /// @custom:semver 2.0.1-beta.2 + string public constant version = "2.0.1-beta.2"; // Constructor to initialize the Safe and baseModule instances constructor(Safe _safe, ISuperchainConfig _superchainConfig, address _deputyGuardian) { diff --git a/packages/contracts-bedrock/src/cannon/MIPS.sol b/packages/contracts-bedrock/src/cannon/MIPS.sol index a81abf5cc734..a1f1113a7aab 100644 --- a/packages/contracts-bedrock/src/cannon/MIPS.sol +++ b/packages/contracts-bedrock/src/cannon/MIPS.sol @@ -44,8 +44,8 @@ contract MIPS is ISemver { } /// @notice The semantic version of the MIPS contract. - /// @custom:semver 1.1.1-beta.1 - string public constant version = "1.1.1-beta.1"; + /// @custom:semver 1.1.1-beta.2 + string public constant version = "1.1.1-beta.2"; /// @notice The preimage oracle contract. IPreimageOracle internal immutable ORACLE; diff --git a/packages/contracts-bedrock/src/cannon/PreimageOracle.sol b/packages/contracts-bedrock/src/cannon/PreimageOracle.sol index c3a43f02c441..c3fbc2b498ad 100644 --- a/packages/contracts-bedrock/src/cannon/PreimageOracle.sol +++ b/packages/contracts-bedrock/src/cannon/PreimageOracle.sol @@ -31,8 +31,8 @@ contract PreimageOracle is IPreimageOracle, ISemver { uint256 public constant PRECOMPILE_CALL_RESERVED_GAS = 100_000; /// @notice The semantic version of the Preimage Oracle contract. - /// @custom:semver 1.1.3-beta.1 - string public constant version = "1.1.3-beta.1"; + /// @custom:semver 1.1.3-beta.2 + string public constant version = "1.1.3-beta.2"; //////////////////////////////////////////////////////////////// // Authorized Preimage Parts // diff --git a/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol b/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol index 3425ec2e394b..1f238e29ac8b 100644 --- a/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol +++ b/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol @@ -28,8 +28,8 @@ contract AnchorStateRegistry is Initializable, IAnchorStateRegistry, ISemver { } /// @notice Semantic version. - /// @custom:semver 2.0.1-beta.1 - string public constant version = "2.0.1-beta.1"; + /// @custom:semver 2.0.1-beta.2 + string public constant version = "2.0.1-beta.2"; /// @notice DisputeGameFactory address. IDisputeGameFactory internal immutable DISPUTE_GAME_FACTORY; diff --git a/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol b/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol index a798df792b4f..d4e668dfb1cc 100644 --- a/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol +++ b/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol @@ -70,8 +70,8 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { uint256 internal constant HEADER_BLOCK_NUMBER_INDEX = 8; /// @notice Semantic version. - /// @custom:semver 1.3.1-beta.1 - string public constant version = "1.3.1-beta.1"; + /// @custom:semver 1.3.1-beta.2 + string public constant version = "1.3.1-beta.2"; /// @notice The starting timestamp of the game Timestamp public createdAt; diff --git a/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol b/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol index 7945c7f51d5d..7acfea9912e3 100644 --- a/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol +++ b/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol @@ -22,8 +22,8 @@ import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; /// Not the prettiest contract in the world, but it gets the job done. contract DelayedWETH is OwnableUpgradeable, WETH98, IDelayedWETH, ISemver { /// @notice Semantic version. - /// @custom:semver 1.1.1-beta.1 - string public constant version = "1.1.1-beta.1"; + /// @custom:semver 1.1.1-beta.2 + string public constant version = "1.1.1-beta.2"; /// @inheritdoc IDelayedWETH mapping(address => mapping(address => WithdrawalRequest)) public withdrawals; diff --git a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummary.sol b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummary.sol index 5c924230ed57..392ba885709b 100644 --- a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummary.sol +++ b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummary.sol @@ -13,9 +13,9 @@ contract DeploymentSummary is DeploymentSummaryCode { Vm private constant vm = Vm(VM_ADDRESS); address internal constant addressManagerAddress = 0x50EEf481cae4250d252Ae577A09bF514f224C6C4; - address internal constant anchorStateRegistryAddress = 0x0C21b289b76ae49983890aed23F78337333F0A5F; + address internal constant anchorStateRegistryAddress = 0xdEC4D949Cf1A2e824eE4F8B12064e166b96171dD; address internal constant anchorStateRegistryProxyAddress = 0x970670459734a83899773A0fd45941B5afC1200e; - address internal constant delayedWETHAddress = 0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05; + address internal constant delayedWETHAddress = 0xe49cED258137CC5E18fB9ABA2Aa14069263D8f49; address internal constant delayedWETHProxyAddress = 0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92; address internal constant disputeGameFactoryAddress = 0x8efDa795511CBBdfFC9eeca1a5bF30f5B1E1ef9E; address internal constant disputeGameFactoryProxyAddress = 0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d; @@ -27,14 +27,14 @@ contract DeploymentSummary is DeploymentSummaryCode { address internal constant l1StandardBridgeProxyAddress = 0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D; address internal constant l2OutputOracleAddress = 0x60d37db59d0D14f7EA5c7425A2C03244E08B162D; address internal constant l2OutputOracleProxyAddress = 0x39Af23E00F1e662025aA01b0cEdA19542B78DF99; - address internal constant mipsAddress = 0x444e09fe6D839273316a87002aB0EFBeA6fe7806; - address internal constant optimismMintableERC20FactoryAddress = 0x47a13af3fB62B24E4914C36aBD9882da23D0e29C; + address internal constant mipsAddress = 0x46cce16e68c41f7EBdf485EF825AB3b46143F738; + address internal constant optimismMintableERC20FactoryAddress = 0x79c3114E5f89266e2C8842871Bce16D4e5076b1e; address internal constant optimismMintableERC20FactoryProxyAddress = 0xc7B87b2b892EA5C3CfF47168881FE168C00377FB; address internal constant optimismPortalAddress = 0xBE8eE5CEA97De55Ae8b020E778A5C93C2Af81Ed4; address internal constant optimismPortal2Address = 0x5506077419b90A12C048500e2eBcafb4fC6Bab61; address internal constant optimismPortalProxyAddress = 0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4; address internal constant permissionedDelayedWETHProxyAddress = 0xd6EAF4c146261653EE059077B78ED088Add54309; - address internal constant preimageOracleAddress = 0x373d916D11cce55b548F7051002e76BCFBD7a85d; + address internal constant preimageOracleAddress = 0x7A9Eab4CE99d157AeE7A02E95b366E972a2D5b0b; address internal constant protocolVersionsAddress = 0xa99F1ab91821747b76Ec0cDFA38368DF4Ba06E84; address internal constant protocolVersionsProxyAddress = 0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1; address internal constant proxyAdminAddress = 0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1; @@ -580,7 +580,7 @@ contract DeploymentSummary is DeploymentSummaryCode { value = hex"0000000000000000000000000000000000000000000000000000000000000008"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"00000000000000000000000047a13af3fb62b24e4914c36abd9882da23d0e29c"; + value = hex"00000000000000000000000079c3114e5f89266e2c8842871bce16d4e5076b1e"; vm.store(optimismMintableERC20FactoryProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -697,7 +697,7 @@ contract DeploymentSummary is DeploymentSummaryCode { value = hex"000000000000000000000000000000000000000000000000000000000000000e"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05"; + value = hex"000000000000000000000000e49ced258137cc5e18fb9aba2aa14069263d8f49"; vm.store(delayedWETHProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -721,7 +721,7 @@ contract DeploymentSummary is DeploymentSummaryCode { value = hex"000000000000000000000000000000000000000000000000000000000000000f"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05"; + value = hex"000000000000000000000000e49ced258137cc5e18fb9aba2aa14069263d8f49"; vm.store(permissionedDelayedWETHProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -745,7 +745,7 @@ contract DeploymentSummary is DeploymentSummaryCode { value = hex"0000000000000000000000000000000000000000000000000000000000000010"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"0000000000000000000000000c21b289b76ae49983890aed23f78337333f0a5f"; + value = hex"000000000000000000000000dec4d949cf1a2e824ee4f8b12064e166b96171dd"; vm.store(anchorStateRegistryProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; diff --git a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryCode.sol b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryCode.sol index e0f719886b0f..272b71f72e59 100644 --- a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryCode.sol +++ b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryCode.sol @@ -47,7 +47,7 @@ contract DeploymentSummaryCode { bytes internal constant l1CrossDomainMessengerCode = hex"60806040526004361061018b5760003560e01c80636425666b116100d6578063b1b1b2091161007f578063d764ad0b11610059578063d764ad0b1461049b578063db505d80146104ae578063ecc70428146104db57600080fd5b8063b1b1b2091461042b578063b28ade251461045b578063c0c53b8b1461047b57600080fd5b80638cbeeef2116100b05780638cbeeef2146102d05780639fce812c146103d0578063a4e7f8bd146103fb57600080fd5b80636425666b146103775780636e296e45146103a457806383a74074146103b957600080fd5b80633dbb202b1161013857806354fd4d501161011257806354fd4d50146102e65780635644cfdf1461033c5780635c975abb1461035257600080fd5b80633dbb202b146102935780633f827a5a146102a85780634c1d6a69146102d057600080fd5b80632828d7e8116101695780632828d7e81461022457806333d7e2bd1461023957806335e80ab31461026657600080fd5b8063028f85f7146101905780630c568498146101c35780630ff754ea146101d8575b600080fd5b34801561019c57600080fd5b506101a5601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101cf57600080fd5b506101a5603f81565b3480156101e457600080fd5b5060fc5473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ba565b34801561023057600080fd5b506101a5604081565b34801561024557600080fd5b5060fd546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561027257600080fd5b5060fb546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b6102a66102a1366004611bdd565b610540565b005b3480156102b457600080fd5b506102bd600181565b60405161ffff90911681526020016101ba565b3480156102dc57600080fd5b506101a5619c4081565b3480156102f257600080fd5b5061032f6040518060400160405280600c81526020017f322e342e312d626574612e31000000000000000000000000000000000000000081525081565b6040516101ba9190611caf565b34801561034857600080fd5b506101a561138881565b34801561035e57600080fd5b5061036761083d565b60405190151581526020016101ba565b34801561038357600080fd5b5060fc546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103b057600080fd5b506101ff6108d6565b3480156103c557600080fd5b506101a562030d4081565b3480156103dc57600080fd5b5060cf5473ffffffffffffffffffffffffffffffffffffffff166101ff565b34801561040757600080fd5b50610367610416366004611cc9565b60ce6020526000908152604090205460ff1681565b34801561043757600080fd5b50610367610446366004611cc9565b60cb6020526000908152604090205460ff1681565b34801561046757600080fd5b506101a5610476366004611ce2565b6109bd565b34801561048757600080fd5b506102a6610496366004611d36565b610a2b565b6102a66104a9366004611d81565b610ca2565b3480156104ba57600080fd5b5060cf546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104e757600080fd5b5061053260cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b6040519081526020016101ba565b6105486115d3565b156105e05734156105e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f642076616c7565207769746820637573746f6d2067617320746f6b656e00000060648201526084015b60405180910390fd5b60cf546107129073ffffffffffffffffffffffffffffffffffffffff166106088585856109bd565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061067460cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016106909796959493929190611e50565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611612565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561079760cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b866040516107a9959493929190611eaf565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60fb54604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156108ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d19190611efd565b905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016109a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084016105d7565b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f6109d9604063ffffffff8816611f4e565b6109e39190611f7e565b6109ee601088611f4e565b6109fb9062030d40611fcc565b610a059190611fcc565b610a0f9190611fcc565b610a199190611fcc565b610a239190611fcc565b949350505050565b6000547501000000000000000000000000000000000000000000900460ff1615808015610a76575060005460017401000000000000000000000000000000000000000090910460ff16105b80610aa85750303b158015610aa8575060005474010000000000000000000000000000000000000000900460ff166001145b610b34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016105d7565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790558015610bba57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b60fb805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560fc805486841690831617905560fd805492851692909116919091179055610c397342000000000000000000000000000000000000076116ab565b8015610c9c57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b610caa61083d565b15610d11576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f43726f7373446f6d61696e4d657373656e6765723a207061757365640000000060448201526064016105d7565b60f087901c60028110610dcc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016105d7565b8061ffff16600003610ec1576000610e1d878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506117e7915050565b600081815260cb602052604090205490915060ff1615610ebf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016105d7565b505b6000610f07898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061180692505050565b9050610f11611829565b15610f4957853414610f2557610f25611ff8565b600081815260ce602052604090205460ff1615610f4457610f44611ff8565b61109b565b3415610ffd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016105d7565b600081815260ce602052604090205460ff1661109b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016105d7565b6110a487611905565b15611157576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016105d7565b600081815260cb602052604090205460ff16156111f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016105d7565b61121785611208611388619c40611fcc565b67ffffffffffffffff1661194b565b158061123d575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561135657600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161134f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016105d7565b50506115ae565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a1617905560006113e788619c405a6113aa9190612027565b8988888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061196992505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801561149d57600082815260cb602052604090205460ff161561143a5761143a611ff8565b600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26115aa565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016115aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016105d7565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6000806115de611981565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b60fc546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c4290849061167390889083908990600090899060040161203e565b6000604051808303818588803b15801561168c57600080fd5b505af11580156116a0573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611756576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105d7565b60cc5473ffffffffffffffffffffffffffffffffffffffff166117a05760cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b60cf80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006117f585858585611a1e565b805190602001209050949350505050565b6000611816878787878787611ab7565b8051906020012090509695505050505050565b60fc5460009073ffffffffffffffffffffffffffffffffffffffff16331480156108d1575060cf5460fc54604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691639bf62d82916004808201926020929091908290030181865afa1580156118c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e99190612096565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff8216301480611945575060fc5473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000806000835160208501868989f195945050505050565b60fd54604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa1580156119f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1591906120b3565b90939092509050565b606084848484604051602401611a3794939291906120f3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b6060868686868686604051602401611ad49695949392919061213d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611b7857600080fd5b50565b60008083601f840112611b8d57600080fd5b50813567ffffffffffffffff811115611ba557600080fd5b602083019150836020828501011115611bbd57600080fd5b9250929050565b803563ffffffff81168114611bd857600080fd5b919050565b60008060008060608587031215611bf357600080fd5b8435611bfe81611b56565b9350602085013567ffffffffffffffff811115611c1a57600080fd5b611c2687828801611b7b565b9094509250611c39905060408601611bc4565b905092959194509250565b6000815180845260005b81811015611c6a57602081850181015186830182015201611c4e565b81811115611c7c576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611cc26020830184611c44565b9392505050565b600060208284031215611cdb57600080fd5b5035919050565b600080600060408486031215611cf757600080fd5b833567ffffffffffffffff811115611d0e57600080fd5b611d1a86828701611b7b565b9094509250611d2d905060208501611bc4565b90509250925092565b600080600060608486031215611d4b57600080fd5b8335611d5681611b56565b92506020840135611d6681611b56565b91506040840135611d7681611b56565b809150509250925092565b600080600080600080600060c0888a031215611d9c57600080fd5b873596506020880135611dae81611b56565b95506040880135611dbe81611b56565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611de857600080fd5b611df48a828b01611b7b565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611ea260c083018486611e07565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611edf608083018688611e07565b905083604083015263ffffffff831660608301529695505050505050565b600060208284031215611f0f57600080fd5b81518015158114611cc257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611f7557611f75611f1f565b02949350505050565b600067ffffffffffffffff80841680611fc0577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611fef57611fef611f1f565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b60008282101561203957612039611f1f565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a06080820152600061208b60a0830184611c44565b979650505050505050565b6000602082840312156120a857600080fd5b8151611cc281611b56565b600080604083850312156120c657600080fd5b82516120d181611b56565b602084015190925060ff811681146120e857600080fd5b809150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152506080604083015261212c6080830185611c44565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261218860c0830184611c44565b9897505050505050505056fea164736f6c634300080f000a"; bytes internal constant optimismMintableERC20FactoryCode = - hex"60806040523480156200001157600080fd5b5060043610620000935760003560e01c8063c4d66de81162000062578063c4d66de81462000175578063ce5ac90f146200018e578063e78cea9214620001a5578063ee9a31a214620001c657600080fd5b8063316b3739146200009857806354fd4d5014620000fb578063896f93d114620001475780638cf0629c146200015e575b600080fd5b620000d1620000a936600462000652565b60026020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b620001386040518060400160405280600d81526020017f312e31302e312d626574612e310000000000000000000000000000000000000081525081565b604051620000f29190620006e5565b620000d162000158366004620007dc565b620001e5565b620000d16200016f36600462000859565b620001fc565b6200018c6200018636600462000652565b6200041b565b005b620000d16200019f366004620007dc565b620005ed565b600154620000d19073ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff16620000d1565b6000620001f4848484620005ed565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff8516620002a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b600085858585604051602001620002c29493929190620008f0565b604051602081830303815290604052805190602001209050600081600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168888888860405162000312906200061a565b620003229594939291906200094a565b8190604051809103906000f590508015801562000343573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff81811660008181526002602052604080822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016948d1694851790555193945090927fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf9190a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054610100900460ff16158080156200043c5750600054600160ff909116105b80620004585750303b15801562000458575060005460ff166001145b620004e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200029e565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156200054557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790558015620005e957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6000620001f48484846012620001fc565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61178a80620009b083390190565b803573ffffffffffffffffffffffffffffffffffffffff811681146200064d57600080fd5b919050565b6000602082840312156200066557600080fd5b620006708262000628565b9392505050565b6000815180845260005b818110156200069f5760208185018101518683018201520162000681565b81811115620006b2576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600062000670602083018462000677565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200073b57600080fd5b813567ffffffffffffffff80821115620007595762000759620006fa565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620007a257620007a2620006fa565b81604052838152866020858801011115620007bc57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215620007f257600080fd5b620007fd8462000628565b9250602084013567ffffffffffffffff808211156200081b57600080fd5b620008298783880162000729565b935060408601359150808211156200084057600080fd5b506200084f8682870162000729565b9150509250925092565b600080600080608085870312156200087057600080fd5b6200087b8562000628565b9350602085013567ffffffffffffffff808211156200089957600080fd5b620008a78883890162000729565b94506040870135915080821115620008be57600080fd5b50620008cd8782880162000729565b925050606085013560ff81168114620008e557600080fd5b939692955090935050565b73ffffffffffffffffffffffffffffffffffffffff8516815260806020820152600062000921608083018662000677565b828103604084015262000935818662000677565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a060408301526200098560a083018662000677565b828103606084015262000999818662000677565b91505060ff83166080830152969550505050505056fe60e06040523480156200001157600080fd5b506040516200178a3803806200178a833981016040819052620000349162000163565b828260036200004483826200029e565b5060046200005382826200029e565b5050506001600160a01b039384166080529390921660a052505060ff1660c0526200036a565b80516001600160a01b03811681146200009157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000be57600080fd5b81516001600160401b0380821115620000db57620000db62000096565b604051601f8301601f19908116603f0116810190828211818310171562000106576200010662000096565b816040528381526020925086838588010111156200012357600080fd5b600091505b8382101562000147578582018301518183018401529082019062000128565b83821115620001595760008385830101525b9695505050505050565b600080600080600060a086880312156200017c57600080fd5b620001878662000079565b9450620001976020870162000079565b60408701519094506001600160401b0380821115620001b557600080fd5b620001c389838a01620000ac565b94506060880151915080821115620001da57600080fd5b50620001e988828901620000ac565b925050608086015160ff811681146200020157600080fd5b809150509295509295909350565b600181811c908216806200022457607f821691505b6020821081036200024557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029957600081815260208120601f850160051c81016020861015620002745750805b601f850160051c820191505b81811015620002955782815560010162000280565b5050505b505050565b81516001600160401b03811115620002ba57620002ba62000096565b620002d281620002cb84546200020f565b846200024b565b602080601f8311600181146200030a5760008415620002f15750858301515b600019600386901b1c1916600185901b17855562000295565b600085815260208120601f198616915b828110156200033b578886015182559484019460019091019084016200031a565b50858210156200035a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c0516113d4620003b6600039600061024401526000818161034b015281816103e001528181610625015261075c0152600081816101a9015261037101526113d46000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610395578063e78cea9214610349578063ee9a31a2146103db57600080fd5b8063ae1f6aaf14610349578063c01e1bd61461036f578063d6c0b2c41461036f57600080fd5b80639dc29fac116100bd5780639dc29fac14610310578063a457c2d714610323578063a9059cbb1461033657600080fd5b806370a08231146102d257806395d89b411461030857600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a36600461117d565b610402565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104f3565b60405161019b91906111c6565b61018f610213366004611262565b610585565b6002545b60405190815260200161019b565b61018f61023836600461128c565b61059d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611262565b6105c1565b61029461028f366004611262565b61060d565b005b6101f86040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61021c6102e03660046112c8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610735565b61029461031e366004611262565b610744565b61018f610331366004611262565b61085b565b61018f610344366004611262565b61092c565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c6103a33660046112e3565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104bb57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104ea57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461050290611316565b80601f016020809104026020016040519081016040528092919081815260200182805461052e90611316565b801561057b5780601f106105505761010080835404028352916020019161057b565b820191906000526020600020905b81548152906001019060200180831161055e57829003601f168201915b5050505050905090565b60003361059381858561093a565b5060019392505050565b6000336105ab858285610aee565b6105b6858585610bc5565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906105939082908690610608908790611398565b61093a565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106e18282610e78565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161072991815260200190565b60405180910390a25050565b60606004805461050290611316565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016106ce565b6108138282610f98565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161072991815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561091f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016106ce565b6105b6828686840361093a565b600033610593818585610bc5565b73ffffffffffffffffffffffffffffffffffffffff83166109dc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bbf5781811015610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106ce565b610bbf848484840361093a565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610d0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e05908490611398565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e6b91815260200190565b60405180910390a3610bbf565b73ffffffffffffffffffffffffffffffffffffffff8216610ef5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106ce565b8060026000828254610f079190611398565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f41908490611398565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff821661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156110f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812083830390556002805484929061112d9084906113b0565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610ae1565b60006020828403121561118f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146111bf57600080fd5b9392505050565b600060208083528351808285015260005b818110156111f3578581018301518582016040015282016111d7565b81811115611205576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461125d57600080fd5b919050565b6000806040838503121561127557600080fd5b61127e83611239565b946020939093013593505050565b6000806000606084860312156112a157600080fd5b6112aa84611239565b92506112b860208501611239565b9150604084013590509250925092565b6000602082840312156112da57600080fd5b6111bf82611239565b600080604083850312156112f657600080fd5b6112ff83611239565b915061130d60208401611239565b90509250929050565b600181811c9082168061132a57607f821691505b602082108103611363577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156113ab576113ab611369565b500190565b6000828210156113c2576113c2611369565b50039056fea164736f6c634300080f000aa164736f6c634300080f000a"; + hex"60806040523480156200001157600080fd5b5060043610620000935760003560e01c8063c4d66de81162000062578063c4d66de81462000175578063ce5ac90f146200018e578063e78cea9214620001a5578063ee9a31a214620001c657600080fd5b8063316b3739146200009857806354fd4d5014620000fb578063896f93d114620001475780638cf0629c146200015e575b600080fd5b620000d1620000a936600462000652565b60026020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b620001386040518060400160405280600d81526020017f312e31302e312d626574612e310000000000000000000000000000000000000081525081565b604051620000f29190620006e5565b620000d162000158366004620007dc565b620001e5565b620000d16200016f36600462000859565b620001fc565b6200018c6200018636600462000652565b6200041b565b005b620000d16200019f366004620007dc565b620005ed565b600154620000d19073ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff16620000d1565b6000620001f4848484620005ed565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff8516620002a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b600085858585604051602001620002c29493929190620008f0565b604051602081830303815290604052805190602001209050600081600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168888888860405162000312906200061a565b620003229594939291906200094a565b8190604051809103906000f590508015801562000343573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff81811660008181526002602052604080822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016948d1694851790555193945090927fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf9190a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054610100900460ff16158080156200043c5750600054600160ff909116105b80620004585750303b15801562000458575060005460ff166001145b620004e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200029e565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156200054557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790558015620005e957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6000620001f48484846012620001fc565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61178a80620009b083390190565b803573ffffffffffffffffffffffffffffffffffffffff811681146200064d57600080fd5b919050565b6000602082840312156200066557600080fd5b620006708262000628565b9392505050565b6000815180845260005b818110156200069f5760208185018101518683018201520162000681565b81811115620006b2576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600062000670602083018462000677565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200073b57600080fd5b813567ffffffffffffffff80821115620007595762000759620006fa565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620007a257620007a2620006fa565b81604052838152866020858801011115620007bc57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215620007f257600080fd5b620007fd8462000628565b9250602084013567ffffffffffffffff808211156200081b57600080fd5b620008298783880162000729565b935060408601359150808211156200084057600080fd5b506200084f8682870162000729565b9150509250925092565b600080600080608085870312156200087057600080fd5b6200087b8562000628565b9350602085013567ffffffffffffffff808211156200089957600080fd5b620008a78883890162000729565b94506040870135915080821115620008be57600080fd5b50620008cd8782880162000729565b925050606085013560ff81168114620008e557600080fd5b939692955090935050565b73ffffffffffffffffffffffffffffffffffffffff8516815260806020820152600062000921608083018662000677565b828103604084015262000935818662000677565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a060408301526200098560a083018662000677565b828103606084015262000999818662000677565b91505060ff83166080830152969550505050505056fe60e06040523480156200001157600080fd5b506040516200178a3803806200178a833981016040819052620000349162000163565b828260036200004483826200029e565b5060046200005382826200029e565b5050506001600160a01b039384166080529390921660a052505060ff1660c0526200036a565b80516001600160a01b03811681146200009157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000be57600080fd5b81516001600160401b0380821115620000db57620000db62000096565b604051601f8301601f19908116603f0116810190828211818310171562000106576200010662000096565b816040528381526020925086838588010111156200012357600080fd5b600091505b8382101562000147578582018301518183018401529082019062000128565b83821115620001595760008385830101525b9695505050505050565b600080600080600060a086880312156200017c57600080fd5b620001878662000079565b9450620001976020870162000079565b60408701519094506001600160401b0380821115620001b557600080fd5b620001c389838a01620000ac565b94506060880151915080821115620001da57600080fd5b50620001e988828901620000ac565b925050608086015160ff811681146200020157600080fd5b809150509295509295909350565b600181811c908216806200022457607f821691505b6020821081036200024557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029957600081815260208120601f850160051c81016020861015620002745750805b601f850160051c820191505b81811015620002955782815560010162000280565b5050505b505050565b81516001600160401b03811115620002ba57620002ba62000096565b620002d281620002cb84546200020f565b846200024b565b602080601f8311600181146200030a5760008415620002f15750858301515b600019600386901b1c1916600185901b17855562000295565b600085815260208120601f198616915b828110156200033b578886015182559484019460019091019084016200031a565b50858210156200035a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c0516113d4620003b6600039600061024401526000818161034b015281816103e001528181610625015261075c0152600081816101a9015261037101526113d46000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610395578063e78cea9214610349578063ee9a31a2146103db57600080fd5b8063ae1f6aaf14610349578063c01e1bd61461036f578063d6c0b2c41461036f57600080fd5b80639dc29fac116100bd5780639dc29fac14610310578063a457c2d714610323578063a9059cbb1461033657600080fd5b806370a08231146102d257806395d89b411461030857600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a36600461117d565b610402565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104f3565b60405161019b91906111c6565b61018f610213366004611262565b610585565b6002545b60405190815260200161019b565b61018f61023836600461128c565b61059d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611262565b6105c1565b61029461028f366004611262565b61060d565b005b6101f86040518060400160405280600c81526020017f312e332e312d626574612e31000000000000000000000000000000000000000081525081565b61021c6102e03660046112c8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610735565b61029461031e366004611262565b610744565b61018f610331366004611262565b61085b565b61018f610344366004611262565b61092c565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c6103a33660046112e3565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104bb57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104ea57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461050290611316565b80601f016020809104026020016040519081016040528092919081815260200182805461052e90611316565b801561057b5780601f106105505761010080835404028352916020019161057b565b820191906000526020600020905b81548152906001019060200180831161055e57829003601f168201915b5050505050905090565b60003361059381858561093a565b5060019392505050565b6000336105ab858285610aee565b6105b6858585610bc5565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906105939082908690610608908790611398565b61093a565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106e18282610e78565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161072991815260200190565b60405180910390a25050565b60606004805461050290611316565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016106ce565b6108138282610f98565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161072991815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561091f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016106ce565b6105b6828686840361093a565b600033610593818585610bc5565b73ffffffffffffffffffffffffffffffffffffffff83166109dc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bbf5781811015610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106ce565b610bbf848484840361093a565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610d0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e05908490611398565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e6b91815260200190565b60405180910390a3610bbf565b73ffffffffffffffffffffffffffffffffffffffff8216610ef5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106ce565b8060026000828254610f079190611398565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f41908490611398565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff821661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156110f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812083830390556002805484929061112d9084906113b0565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610ae1565b60006020828403121561118f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146111bf57600080fd5b9392505050565b600060208083528351808285015260005b818110156111f3578581018301518582016040015282016111d7565b81811115611205576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461125d57600080fd5b919050565b6000806040838503121561127557600080fd5b61127e83611239565b946020939093013593505050565b6000806000606084860312156112a157600080fd5b6112aa84611239565b92506112b860208501611239565b9150604084013590509250925092565b6000602082840312156112da57600080fd5b6111bf82611239565b600080604083850312156112f657600080fd5b6112ff83611239565b915061130d60208401611239565b90509250929050565b600181811c9082168061132a57607f821691505b602082108103611363577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156113ab576113ab611369565b500190565b6000828210156113c2576113c2611369565b50039056fea164736f6c634300080f000aa164736f6c634300080f000a"; bytes internal constant systemConfigCode = hex"608060405234801561001057600080fd5b50600436106102de5760003560e01c8063a711986911610186578063e0e2016d116100e3578063f2fde38b11610097578063f8c68de011610071578063f8c68de0146106e2578063fd32aa0f146106ea578063ffa1ad74146106f257600080fd5b8063f2fde38b146106b2578063f45e65d8146106c5578063f68016b7146106ce57600080fd5b8063e81b2c6d116100c8578063e81b2c6d14610681578063ec7075171461068a578063f2b4e617146106aa57600080fd5b8063e0e2016d14610671578063e2a3285c1461067957600080fd5b8063c9b26f611161013a578063d84447151161011f578063d84447151461064e578063dac6e63a14610656578063db9040fa1461065e57600080fd5b8063c9b26f6114610507578063cc731b021461051a57600080fd5b8063bc49ce5f1161016b578063bc49ce5f146104c6578063bfb14fb7146104ce578063c4e8ddfa146104ff57600080fd5b8063a7119869146104ab578063b40a817c146104b357600080fd5b80634397dfef1161023f578063550fcdc9116101f35780638da5cb5b116101cd5780638da5cb5b14610472578063935f029e146104905780639b7d7f0a146104a357600080fd5b8063550fcdc91461045a5780635d73369c14610462578063715018a61461046a57600080fd5b80634add321d116102245780634add321d146103e95780634f16540b146103f157806354fd4d501461041857600080fd5b80634397dfef146103ab57806348cd4cb1146103e157600080fd5b806318d13918116102965780631fd19ee11161027b5780631fd19ee114610378578063213268491461038057806321d7fde51461039857600080fd5b806318d139181461035b57806319f5cea81461037057600080fd5b80630a49cb03116102c75780630a49cb031461032b5780630ae14b1b146103335780630c18c1621461035257600080fd5b806306c92657146102e3578063078f29cf146102fe575b600080fd5b6102eb6106fa565b6040519081526020015b60405180910390f35b610306610728565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102f5565b610306610761565b630bebc2005b60405167ffffffffffffffff90911681526020016102f5565b6102eb60655481565b61036e610369366004612241565b610791565b005b6102eb6107a5565b6103066107d0565b6103886107fa565b60405190151581526020016102f5565b61036e6103a6366004612277565b610839565b6103b361084f565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835260ff9091166020830152016102f5565b6102eb610863565b610339610893565b6102eb7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b60408051808201909152600c81527f322e332e302d626574612e33000000000000000000000000000000000000000060208201525b6040516102f59190612320565b61044d6108b9565b6102eb6108c3565b61036e6108ee565b60335473ffffffffffffffffffffffffffffffffffffffff16610306565b61036e61049e366004612333565b610902565b610306610914565b610306610944565b61036e6104c136600461236d565b610974565b6102eb610985565b6068546104ea9068010000000000000000900463ffffffff1681565b60405163ffffffff90911681526020016102f5565b6103066109b0565b61036e610515366004612388565b6109e0565b6105de6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b6040516102f59190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b61044d6109f1565b6103066109fb565b61036e61066c3660046124bb565b610a2b565b6102eb610e36565b6102eb610e61565b6102eb60675481565b6068546104ea906c01000000000000000000000000900463ffffffff1681565b610306610e8c565b61036e6106c0366004612241565b610ebc565b6102eb60665481565b6068546103399067ffffffffffffffff1681565b6102eb610f70565b6102eb610f9b565b6102eb600081565b61072560017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b81565b600061075c61075860017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b5490565b905090565b600061075c61075860017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b610799611201565b6107a281611282565b50565b61072560017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b600061075c7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b60008061080561084f565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b610841611201565b61084b828261133f565b5050565b60008061085a611184565b90939092509050565b600061075c61075860017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b60695460009061075c9063ffffffff6a0100000000000000000000820481169116612654565b606061075c61147d565b61072560017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b6108f6611201565b610900600061153e565b565b61090a611201565b61084b82826115b5565b600061075c61075860017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b600061075c61075860017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b61097c611201565b6107a28161168b565b61072560017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b600061075c61075860017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b6109e8611201565b6107a2816117e1565b606061075c611809565b600061075c61075860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b600054610100900460ff1615808015610a4b5750600054600160ff909116105b80610a655750303b158015610a65575060005460ff166001145b610af6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610b5457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b5c6118bf565b610b658a610ebc565b610b6e876117e1565b610b78898961133f565b610b818661168b565b610baa7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08869055565b610bdd610bd860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b849055565b610c11610c0b60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b83519055565b610c48610c3f60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b60208401519055565b610c7f610c7660017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b60408401519055565b610cb6610cad60017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b60608401519055565b610ced610ce460017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b60808401519055565b610d24610d1b60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b60a08401519055565b610d2c61195e565b610d398260c001516119c6565b610d4284611cd0565b610d4a610893565b67ffffffffffffffff168667ffffffffffffffff161015610dc7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b8015610e2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b61072560017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b61072560017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b600061075c61075860017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b610ec4611201565b73ffffffffffffffffffffffffffffffffffffffff8116610f67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610aed565b6107a28161153e565b61072560017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b61072560017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b9055565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600060208251111561107a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f476173506179696e67546f6b656e3a20737472696e672063616e6e6f7420626560448201527f2067726561746572207468616e203332206279746573000000000000000000006064820152608401610aed565b6110838261115b565b92915050565b6110ef6110b760017f04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec61263d565b74ff000000000000000000000000000000000000000060a086901b1673ffffffffffffffffffffffffffffffffffffffff8716179055565b61112261111d60017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d61263d565b839055565b61115561115060017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd0576461263d565b829055565b50505050565b8051602181106111735763ec92f9a36000526004601cfd5b9081015160209190910360031b1b90565b600080806111b661075860017f04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec61263d565b73ffffffffffffffffffffffffffffffffffffffff811693509050826111f5575073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee92601292509050565b60a081901c9150509091565b60335473ffffffffffffffffffffffffffffffffffffffff163314610900576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610aed565b6112ab7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060035b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be836040516113339190612320565b60405180910390a35050565b606880547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000063ffffffff8581169182027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16929092176c0100000000000000000000000092851692909202919091179091557f0100000000000000000000000000000000000000000000000000000000000000602083811b67ffffffff000000001690921717606681905560655460408051938401919091528201526000906060015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be836040516114709190612320565b60405180910390a3505050565b60606000611489611184565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff82160161150257505060408051808201909152600381527f4554480000000000000000000000000000000000000000000000000000000000602082015290565b61153861153361075860017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd0576461263d565b612144565b91505090565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b7fff00000000000000000000000000000000000000000000000000000000000000811615611665576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f53797374656d436f6e6669673a207363616c61722065786365656473206d617860448201527f2e000000000000000000000000000000000000000000000000000000000000006064820152608401610aed565b60658290556066819055604080516020810184905290810182905260009060600161140d565b611693610893565b67ffffffffffffffff168167ffffffffffffffff161015611710576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b630bebc20067ffffffffffffffff82161115611788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f20686967686044820152606401610aed565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002611302565b6067819055604080516020808201849052825180830390910181529082019091526000611302565b60606000611815611184565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff82160161188e57505060408051808201909152600581527f4574686572000000000000000000000000000000000000000000000000000000602082015290565b61153861153361075860017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d61263d565b600054610100900460ff16611956576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610aed565b610900612178565b61198c61075860017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b600003610900576109006119c160017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b439055565b73ffffffffffffffffffffffffffffffffffffffff811615801590611a15575073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14155b8015611a265750611a246107fa565b155b156107a257601260ff168173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a9f9190612680565b60ff1614611b2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f53797374656d436f6e6669673a2062616420646563696d616c73206f6620676160448201527f7320706179696e6720746f6b656e0000000000000000000000000000000000006064820152608401610aed565b6000611bca8273ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015611b7f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611bc5919081019061269d565b610fe6565b90506000611c1c8373ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611b7f573d6000803e3d6000fd5b9050611c2b8360128484611089565b611c33610761565b6040517f71cfaa3f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015260126024830152604482018590526064820184905291909116906371cfaa3f90608401600060405180830381600087803b158015611cb357600080fd5b505af1158015611cc7573d6000803e3d6000fd5b50505050505050565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff161115611d80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d6178206261736500000000000000000000006064820152608401610aed565b6001816040015160ff1611611e17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e203100000000000000000000000000000000006064820152608401610aed565b6068546080820151825167ffffffffffffffff90921691611e389190612768565b63ffffffff161115611ea6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b6000816020015160ff1611611f3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f74206265203000000000000000000000000000000000006064820152608401610aed565b8051602082015163ffffffff82169160ff90911690611f5d908290612787565b611f6791906127d1565b63ffffffff1614611ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d69740000000000000000006064820152608401610aed565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b60405160005b82811a1561215a5760010161214a565b80825260208201838152600082820152505060408101604052919050565b600054610100900460ff1661220f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610aed565b6109003361153e565b803573ffffffffffffffffffffffffffffffffffffffff8116811461223c57600080fd5b919050565b60006020828403121561225357600080fd5b61225c82612218565b9392505050565b803563ffffffff8116811461223c57600080fd5b6000806040838503121561228a57600080fd5b61229383612263565b91506122a160208401612263565b90509250929050565b60005b838110156122c55781810151838201526020016122ad565b838111156111555750506000910152565b600081518084526122ee8160208601602086016122aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061225c60208301846122d6565b6000806040838503121561234657600080fd5b50508035926020909101359150565b803567ffffffffffffffff8116811461223c57600080fd5b60006020828403121561237f57600080fd5b61225c82612355565b60006020828403121561239a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff811182821017156123f3576123f36123a1565b60405290565b60ff811681146107a257600080fd5b600060e0828403121561241a57600080fd5b60405160e0810181811067ffffffffffffffff8211171561243d5761243d6123a1565b60405290508061244c83612218565b815261245a60208401612218565b602082015261246b60408401612218565b604082015261247c60608401612218565b606082015261248d60808401612218565b608082015261249e60a08401612218565b60a08201526124af60c08401612218565b60c08201525092915050565b6000806000806000806000806000898b036102808112156124db57600080fd5b6124e48b612218565b99506124f260208c01612263565b985061250060408c01612263565b975060608b0135965061251560808c01612355565b955061252360a08c01612218565b945060c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff408201121561255557600080fd5b5061255e6123d0565b61256a60c08c01612263565b815260e08b013561257a816123f9565b60208201526101008b013561258e816123f9565b60408201526125a06101208c01612263565b60608201526125b26101408c01612263565b60808201526101608b01356fffffffffffffffffffffffffffffffff811681146125db57600080fd5b60a082015292506125ef6101808b01612218565b91506125ff8b6101a08c01612408565b90509295985092959850929598565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561264f5761264f61260e565b500390565b600067ffffffffffffffff8083168185168083038211156126775761267761260e565b01949350505050565b60006020828403121561269257600080fd5b815161225c816123f9565b6000602082840312156126af57600080fd5b815167ffffffffffffffff808211156126c757600080fd5b818401915084601f8301126126db57600080fd5b8151818111156126ed576126ed6123a1565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612733576127336123a1565b8160405282815287602084870101111561274c57600080fd5b61275d8360208301602088016122aa565b979650505050505050565b600063ffffffff8083168185168083038211156126775761267761260e565b600063ffffffff808416806127c5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff808316818516818304811182151516156127f4576127f461260e565b0294935050505056fea164736f6c634300080f000a"; bytes internal constant l1StandardBridgeCode = @@ -63,15 +63,15 @@ contract DeploymentSummaryCode { bytes internal constant disputeGameFactoryCode = hex"6080604052600436106100e85760003560e01c80636593dc6e1161008a57806396cd97201161005957806396cd972014610313578063bb8aa1fc14610333578063c4d66de814610394578063f2fde38b146103b457600080fd5b80636593dc6e14610293578063715018a6146102c057806382ecf2f6146102d55780638da5cb5b146102e857600080fd5b8063254bd683116100c6578063254bd6831461019c5780634d1975b4146101c957806354fd4d50146101e85780635f0150cb1461023e57600080fd5b806314f6b1a3146100ed5780631b685b9e1461010f5780631e3342401461017c575b600080fd5b3480156100f957600080fd5b5061010d6101083660046110c6565b6103d4565b005b34801561011b57600080fd5b5061015261012a3660046110fd565b60656020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061010d610197366004611118565b61045e565b3480156101a857600080fd5b506101bc6101b7366004611142565b6104aa565b60405161017391906111ef565b3480156101d557600080fd5b506068545b604051908152602001610173565b3480156101f457600080fd5b506102316040518060400160405280600c81526020017f312e302e312d626574612e31000000000000000000000000000000000000000081525081565b60405161017391906112ac565b34801561024a57600080fd5b5061025e6102593660046112bf565b6106ee565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff909116602083015201610173565b34801561029f57600080fd5b506101da6102ae3660046110fd565b60666020526000908152604090205481565b3480156102cc57600080fd5b5061010d610741565b6101526102e33660046112bf565b610755565b3480156102f457600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff16610152565b34801561031f57600080fd5b506101da61032e3660046112bf565b6109ef565b34801561033f57600080fd5b5061035361034e366004611346565b610a28565b6040805163ffffffff909416845267ffffffffffffffff909216602084015273ffffffffffffffffffffffffffffffffffffffff1690820152606001610173565b3480156103a057600080fd5b5061010d6103af36600461135f565b610a91565b3480156103c057600080fd5b5061010d6103cf36600461135f565b610c2d565b6103dc610d00565b63ffffffff821660008181526065602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616908117909155905190917fff513d80e2c7fa487608f70a618dfbc0cf415699dc69588c747e8c71566c88de91a35050565b610466610d00565b63ffffffff8216600081815260666020526040808220849055518392917f74d6665c4b26d5596a5aa13d3014e0c06af4d322075a797f87b03cd4c5bc91ca91a35050565b606854606090831015806104bc575081155b6106e7575060408051600583901b8101602001909152825b8381116106e5576000606882815481106104f0576104f061137c565b600091825260209091200154905060e081901c60a082901c67ffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff831663ffffffff891683036106b6576001865101865260008173ffffffffffffffffffffffffffffffffffffffff1663609d33346040518163ffffffff1660e01b8152600401600060405180830381865afa15801561058a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d091908101906113da565b905060008273ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561061f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064391906114a5565b90506040518060a001604052808881526020018781526020018567ffffffffffffffff168152602001828152602001838152508860018a5161068591906114be565b815181106106955761069561137c565b6020026020010181905250888851106106b3575050505050506106e5565b50505b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191506104d49050565b505b9392505050565b60008060006106ff878787876109ef565b60009081526067602052604090205473ffffffffffffffffffffffffffffffffffffffff81169860a09190911c67ffffffffffffffff16975095505050505050565b610749610d00565b6107536000610d81565b565b63ffffffff841660009081526065602052604081205473ffffffffffffffffffffffffffffffffffffffff16806107c5576040517f031c6de400000000000000000000000000000000000000000000000000000000815263ffffffff871660048201526024015b60405180910390fd5b63ffffffff86166000908152606660205260409020543414610813576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006108206001436114be565b40905061088a338783888860405160200161083f9594939291906114fc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905273ffffffffffffffffffffffffffffffffffffffff841690610df8565b92508273ffffffffffffffffffffffffffffffffffffffff16638129fc1c346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156108d457600080fd5b505af11580156108e8573d6000803e3d6000fd5b505050505060006108fb888888886109ef565b60008181526067602052604090205490915015610947576040517f014f6fe5000000000000000000000000000000000000000000000000000000008152600481018290526024016107bc565b60004260a01b60e08a901b178517600083815260676020526040808220839055606880546001810182559083527fa2153420d844928b4421650203c77babc8b33d7f2e7b450e2966db0c220977530183905551919250899163ffffffff8c169173ffffffffffffffffffffffffffffffffffffffff8916917f5b565efe82411da98814f356d0e7bcb8f0219b8d970307c5afb4a6903a8b2e359190a450505050949350505050565b600084848484604051602001610a089493929190611549565b604051602081830303815290604052805190602001209050949350505050565b600080600080600080610a8160688881548110610a4757610a4761137c565b906000526020600020015460e081901c9160a082901c67ffffffffffffffff169173ffffffffffffffffffffffffffffffffffffffff1690565b9199909850909650945050505050565b600054610100900460ff1615808015610ab15750600054600160ff909116105b80610acb5750303b158015610acb575060005460ff166001145b610b57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107bc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610bb557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610bbd610e06565b610bc682610d81565b8015610c2957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b610c35610d00565b73ffffffffffffffffffffffffffffffffffffffff8116610cd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016107bc565b610ce181610d81565b50565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60335473ffffffffffffffffffffffffffffffffffffffff163314610753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107bc565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006106e760008484610ea5565b600054610100900460ff16610e9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b610753610feb565b600060608203516040830351602084035184518060208701018051600283016c5af43d3d93803e606057fd5bf3895289600d8a035278593da1005b363d3d373d3d3d3d610000806062363936013d738160481b1760218a03527f9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff603a8a035272fd6100003d81600a3d39f336602c57343d527f6062820160781b1761ff9e82106059018a03528060f01b8352606c8101604c8a038cf097505086610f715763301164256000526004601cfd5b905285527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08501527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa09092019190915292915050565b600054610100900460ff16611082576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b61075333610d81565b803563ffffffff8116811461109f57600080fd5b919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610ce157600080fd5b600080604083850312156110d957600080fd5b6110e28361108b565b915060208301356110f2816110a4565b809150509250929050565b60006020828403121561110f57600080fd5b6106e78261108b565b6000806040838503121561112b57600080fd5b6111348361108b565b946020939093013593505050565b60008060006060848603121561115757600080fd5b6111608461108b565b95602085013595506040909401359392505050565b60005b83811015611190578181015183820152602001611178565b8381111561119f576000848401525b50505050565b600081518084526111bd816020860160208601611175565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561129e578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001855281518051845287810151888501528681015167ffffffffffffffff16878501526060808201519085015260809081015160a09185018290529061128a818601836111a5565b968901969450505090860190600101611216565b509098975050505050505050565b6020815260006106e760208301846111a5565b600080600080606085870312156112d557600080fd5b6112de8561108b565b935060208501359250604085013567ffffffffffffffff8082111561130257600080fd5b818701915087601f83011261131657600080fd5b81358181111561132557600080fd5b88602082850101111561133757600080fd5b95989497505060200194505050565b60006020828403121561135857600080fd5b5035919050565b60006020828403121561137157600080fd5b81356106e7816110a4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156113ec57600080fd5b815167ffffffffffffffff8082111561140457600080fd5b818401915084601f83011261141857600080fd5b81518181111561142a5761142a6113ab565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611470576114706113ab565b8160405282815287602084870101111561148957600080fd5b61149a836020830160208801611175565b979650505050505050565b6000602082840312156114b757600080fd5b5051919050565b6000828210156114f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500390565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008660601b1681528460148201528360348201528183605483013760009101605401908152949350505050565b63ffffffff8516815283602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101939250505056fea164736f6c634300080f000a"; bytes internal constant delayedWETHCode = - hex"6080604052600436106101845760003560e01c8063715018a6116100d6578063a9059cbb1161007f578063dd62ed3e11610059578063dd62ed3e1461051c578063f2fde38b14610554578063f3fef3a31461057457610193565b8063a9059cbb146104a8578063cd47bde1146104c8578063d0e30db01461019357610193565b80638da5cb5b116100b05780638da5cb5b1461041757806395d89b4114610442578063977a5ec51461048857610193565b8063715018a61461039057806379502c55146103a55780637eee288d146103f757610193565b80632e1a7d4d1161013857806354fd4d501161011257806354fd4d50146102e75780636a42b8f81461033057806370a082311461036357610193565b80632e1a7d4d14610280578063313ce567146102a0578063485cc955146102c757610193565b80630ca35682116101695780630ca356821461022357806318160ddd1461024357806323b872dd1461026057610193565b806306fdde031461019b578063095ea7b3146101f357610193565b3661019357610191610594565b005b610191610594565b3480156101a757600080fd5b5060408051808201909152600d81527f577261707065642045746865720000000000000000000000000000000000000060208201525b6040516101ea91906113fd565b60405180910390f35b3480156101ff57600080fd5b5061021361020e366004611492565b6105ef565b60405190151581526020016101ea565b34801561022f57600080fd5b5061019161023e3660046114be565b610668565b34801561024f57600080fd5b50475b6040519081526020016101ea565b34801561026c57600080fd5b5061021361027b3660046114d7565b6107b9565b34801561028c57600080fd5b5061019161029b3660046114be565b6109d0565b3480156102ac57600080fd5b506102b5601281565b60405160ff90911681526020016101ea565b3480156102d357600080fd5b506101916102e2366004611518565b6109dd565b3480156102f357600080fd5b506101dd6040518060400160405280600a81526020017f312e312e302d72632e310000000000000000000000000000000000000000000081525081565b34801561033c57600080fd5b507f0000000000000000000000000000000000000000000000000000000000093a80610252565b34801561036f57600080fd5b5061025261037e366004611551565b60656020526000908152604090205481565b34801561039c57600080fd5b50610191610bb9565b3480156103b157600080fd5b506068546103d29073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ea565b34801561040357600080fd5b50610191610412366004611492565b610bcd565b34801561042357600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff166103d2565b34801561044e57600080fd5b5060408051808201909152600481527f574554480000000000000000000000000000000000000000000000000000000060208201526101dd565b34801561049457600080fd5b506101916104a3366004611492565b610c21565b3480156104b457600080fd5b506102136104c3366004611492565b610d0e565b3480156104d457600080fd5b506105076104e3366004611518565b60676020908152600092835260408084209091529082529020805460019091015482565b604080519283526020830191909152016101ea565b34801561052857600080fd5b50610252610537366004611518565b606660209081526000928352604080842090915290825290205481565b34801561056057600080fd5b5061019161056f366004611551565b610d22565b34801561058057600080fd5b5061019161058f366004611492565b610dd6565b33600090815260656020526040812080543492906105b390849061159d565b909155505060405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b33600081815260666020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106579086815260200190565b60405180910390a350600192915050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064015b60405180910390fd5b60004782106106fd57476106ff565b815b604051909150600090339083908381818185875af1925050503d8060008114610744576040519150601f19603f3d011682016040523d82523d6000602084013e610749565b606091505b50509050806107b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f44656c61796564574554483a207265636f766572206661696c6564000000000060448201526064016106e5565b505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152606560205260408120548211156107eb57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610861575073ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156108e95773ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091529020548211156108a357600080fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152606660209081526040808320338452909152812080548492906108e39084906115b5565b90915550505b73ffffffffffffffffffffffffffffffffffffffff84166000908152606560205260408120805484929061091e9084906115b5565b909155505073ffffffffffffffffffffffffffffffffffffffff83166000908152606560205260408120805484929061095890849061159d565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109be91815260200190565b60405180910390a35060019392505050565b6109da3382610dd6565b50565b600054610100900460ff16158080156109fd5750600054600160ff909116105b80610a175750303b158015610a17575060005460ff166001145b610aa3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016106e5565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610b0157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b09611120565b610b12836111bf565b606880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617905580156107b457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b610bc1611236565b610bcb60006111bf565b565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120426001820155805490918391839190610c1790849061159d565b9091555050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610ca2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064016106e5565b73ffffffffffffffffffffffffffffffffffffffff821660008181526066602090815260408083203380855290835292819020859055518481529192917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a35050565b6000610d1b3384846107b9565b9392505050565b610d2a611236565b73ffffffffffffffffffffffffffffffffffffffff8116610dcd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016106e5565b6109da816111bf565b606860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6791906115cc565b15610ece576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f44656c61796564574554483a20636f6e7472616374206973207061757365640060448201526064016106e5565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290208054821115610f8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f44656c61796564574554483a20696e73756666696369656e7420756e6c6f636b60448201527f6564207769746864726177616c0000000000000000000000000000000000000060648201526084016106e5565b6000816001015411611022576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f44656c61796564574554483a207769746864726177616c206e6f7420756e6c6f60448201527f636b65640000000000000000000000000000000000000000000000000000000060648201526084016106e5565b427f0000000000000000000000000000000000000000000000000000000000093a808260010154611053919061159d565b11156110e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f44656c61796564574554483a207769746864726177616c2064656c6179206e6f60448201527f74206d657400000000000000000000000000000000000000000000000000000060648201526084016106e5565b818160000160008282546110f591906115b5565b909155506107b49050826112b7565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff166111b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106e5565b610bcb61135d565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610bcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106e5565b336000908152606560205260409020548111156112d357600080fd5b33600090815260656020526040812080548392906112f29084906115b5565b9091555050604051339082156108fc029083906000818181858888f19350505050158015611324573d6000803e3d6000fd5b5060405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a250565b600054610100900460ff166113f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106e5565b610bcb336111bf565b600060208083528351808285015260005b8181101561142a5785810183015185820160400152820161140e565b8181111561143c576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146109da57600080fd5b600080604083850312156114a557600080fd5b82356114b081611470565b946020939093013593505050565b6000602082840312156114d057600080fd5b5035919050565b6000806000606084860312156114ec57600080fd5b83356114f781611470565b9250602084013561150781611470565b929592945050506040919091013590565b6000806040838503121561152b57600080fd5b823561153681611470565b9150602083013561154681611470565b809150509250929050565b60006020828403121561156357600080fd5b8135610d1b81611470565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115b0576115b061156e565b500190565b6000828210156115c7576115c761156e565b500390565b6000602082840312156115de57600080fd5b81518015158114610d1b57600080fdfea164736f6c634300080f000a"; + hex"6080604052600436106101845760003560e01c8063715018a6116100d6578063a9059cbb1161007f578063dd62ed3e11610059578063dd62ed3e1461051c578063f2fde38b14610554578063f3fef3a31461057457610193565b8063a9059cbb146104a8578063cd47bde1146104c8578063d0e30db01461019357610193565b80638da5cb5b116100b05780638da5cb5b1461041757806395d89b4114610442578063977a5ec51461048857610193565b8063715018a61461039057806379502c55146103a55780637eee288d146103f757610193565b80632e1a7d4d1161013857806354fd4d501161011257806354fd4d50146102e75780636a42b8f81461033057806370a082311461036357610193565b80632e1a7d4d14610280578063313ce567146102a0578063485cc955146102c757610193565b80630ca35682116101695780630ca356821461022357806318160ddd1461024357806323b872dd1461026057610193565b806306fdde031461019b578063095ea7b3146101f357610193565b3661019357610191610594565b005b610191610594565b3480156101a757600080fd5b5060408051808201909152600d81527f577261707065642045746865720000000000000000000000000000000000000060208201525b6040516101ea91906113fd565b60405180910390f35b3480156101ff57600080fd5b5061021361020e366004611492565b6105ef565b60405190151581526020016101ea565b34801561022f57600080fd5b5061019161023e3660046114be565b610668565b34801561024f57600080fd5b50475b6040519081526020016101ea565b34801561026c57600080fd5b5061021361027b3660046114d7565b6107b9565b34801561028c57600080fd5b5061019161029b3660046114be565b6109d0565b3480156102ac57600080fd5b506102b5601281565b60405160ff90911681526020016101ea565b3480156102d357600080fd5b506101916102e2366004611518565b6109dd565b3480156102f357600080fd5b506101dd6040518060400160405280600c81526020017f312e312e312d626574612e32000000000000000000000000000000000000000081525081565b34801561033c57600080fd5b507f0000000000000000000000000000000000000000000000000000000000093a80610252565b34801561036f57600080fd5b5061025261037e366004611551565b60656020526000908152604090205481565b34801561039c57600080fd5b50610191610bb9565b3480156103b157600080fd5b506068546103d29073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ea565b34801561040357600080fd5b50610191610412366004611492565b610bcd565b34801561042357600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff166103d2565b34801561044e57600080fd5b5060408051808201909152600481527f574554480000000000000000000000000000000000000000000000000000000060208201526101dd565b34801561049457600080fd5b506101916104a3366004611492565b610c21565b3480156104b457600080fd5b506102136104c3366004611492565b610d0e565b3480156104d457600080fd5b506105076104e3366004611518565b60676020908152600092835260408084209091529082529020805460019091015482565b604080519283526020830191909152016101ea565b34801561052857600080fd5b50610252610537366004611518565b606660209081526000928352604080842090915290825290205481565b34801561056057600080fd5b5061019161056f366004611551565b610d22565b34801561058057600080fd5b5061019161058f366004611492565b610dd6565b33600090815260656020526040812080543492906105b390849061159d565b909155505060405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b33600081815260666020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106579086815260200190565b60405180910390a350600192915050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064015b60405180910390fd5b60004782106106fd57476106ff565b815b604051909150600090339083908381818185875af1925050503d8060008114610744576040519150601f19603f3d011682016040523d82523d6000602084013e610749565b606091505b50509050806107b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f44656c61796564574554483a207265636f766572206661696c6564000000000060448201526064016106e5565b505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152606560205260408120548211156107eb57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610861575073ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156108e95773ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091529020548211156108a357600080fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152606660209081526040808320338452909152812080548492906108e39084906115b5565b90915550505b73ffffffffffffffffffffffffffffffffffffffff84166000908152606560205260408120805484929061091e9084906115b5565b909155505073ffffffffffffffffffffffffffffffffffffffff83166000908152606560205260408120805484929061095890849061159d565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109be91815260200190565b60405180910390a35060019392505050565b6109da3382610dd6565b50565b600054610100900460ff16158080156109fd5750600054600160ff909116105b80610a175750303b158015610a17575060005460ff166001145b610aa3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016106e5565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610b0157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b09611120565b610b12836111bf565b606880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617905580156107b457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b610bc1611236565b610bcb60006111bf565b565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120426001820155805490918391839190610c1790849061159d565b9091555050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610ca2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064016106e5565b73ffffffffffffffffffffffffffffffffffffffff821660008181526066602090815260408083203380855290835292819020859055518481529192917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a35050565b6000610d1b3384846107b9565b9392505050565b610d2a611236565b73ffffffffffffffffffffffffffffffffffffffff8116610dcd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016106e5565b6109da816111bf565b606860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6791906115cc565b15610ece576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f44656c61796564574554483a20636f6e7472616374206973207061757365640060448201526064016106e5565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290208054821115610f8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f44656c61796564574554483a20696e73756666696369656e7420756e6c6f636b60448201527f6564207769746864726177616c0000000000000000000000000000000000000060648201526084016106e5565b6000816001015411611022576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f44656c61796564574554483a207769746864726177616c206e6f7420756e6c6f60448201527f636b65640000000000000000000000000000000000000000000000000000000060648201526084016106e5565b427f0000000000000000000000000000000000000000000000000000000000093a808260010154611053919061159d565b11156110e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f44656c61796564574554483a207769746864726177616c2064656c6179206e6f60448201527f74206d657400000000000000000000000000000000000000000000000000000060648201526084016106e5565b818160000160008282546110f591906115b5565b909155506107b49050826112b7565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff166111b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106e5565b610bcb61135d565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610bcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106e5565b336000908152606560205260409020548111156112d357600080fd5b33600090815260656020526040812080548392906112f29084906115b5565b9091555050604051339082156108fc029083906000818181858888f19350505050158015611324573d6000803e3d6000fd5b5060405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a250565b600054610100900460ff166113f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106e5565b610bcb336111bf565b600060208083528351808285015260005b8181101561142a5785810183015185820160400152820161140e565b8181111561143c576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146109da57600080fd5b600080604083850312156114a557600080fd5b82356114b081611470565b946020939093013593505050565b6000602082840312156114d057600080fd5b5035919050565b6000806000606084860312156114ec57600080fd5b83356114f781611470565b9250602084013561150781611470565b929592945050506040919091013590565b6000806040838503121561152b57600080fd5b823561153681611470565b9150602083013561154681611470565b809150509250929050565b60006020828403121561156357600080fd5b8135610d1b81611470565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115b0576115b061156e565b500190565b6000828210156115c7576115c761156e565b500390565b6000602082840312156115de57600080fd5b81518015158114610d1b57600080fdfea164736f6c634300080f000a"; bytes internal constant preimageOracleCode = - hex"6080604052600436106101d85760003560e01c80639d53a64811610102578063ddcd58de11610095578063ec5efcbc11610064578063ec5efcbc14610681578063f3f480d9146106a1578063faf37bc7146106d4578063fef2b4ed146106e757600080fd5b8063ddcd58de146105d4578063e03110e11461060c578063e159261114610641578063ea7139501461066157600080fd5b8063b5e7154c116100d1578063b5e7154c14610555578063d18534b51461056c578063da35c6641461058c578063dd24f9bf146105a157600080fd5b80639d53a6481461048e5780639d7e8769146104dd578063b2e67ba8146104fd578063b4801e611461053557600080fd5b806361238bde1161017a5780637ac54767116101495780637ac54767146103ca5780638542cf50146103ea578063882856ef146104355780638dc4be111461046e57600080fd5b806361238bde1461031e5780636551927b146103565780637051472e1461038e5780637917de1d146103aa57600080fd5b80633909af5c116101b65780633909af5c146102715780634d52b4c91461029357806352f0f3ad146102a857806354fd4d50146102c857600080fd5b8063013cf08b146101dd5780630359a5631461022e5780632055b36b1461025c575b600080fd5b3480156101e957600080fd5b506101fd6101f8366004612e29565b610714565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526020830191909152015b60405180910390f35b34801561023a57600080fd5b5061024e610249366004612e6b565b610759565b604051908152602001610225565b34801561026857600080fd5b5061024e601081565b34801561027d57600080fd5b5061029161028c366004613073565b610891565b005b34801561029f57600080fd5b5061024e610ae8565b3480156102b457600080fd5b5061024e6102c336600461315f565b610b03565b3480156102d457600080fd5b506103116040518060400160405280600a81526020017f312e312e322d72632e310000000000000000000000000000000000000000000081525081565b60405161022591906131c6565b34801561032a57600080fd5b5061024e610339366004613217565b600160209081526000928352604080842090915290825290205481565b34801561036257600080fd5b5061024e610371366004612e6b565b601560209081526000928352604080842090915290825290205481565b34801561039a57600080fd5b5061024e6703782dace9d9000081565b3480156103b657600080fd5b506102916103c536600461327b565b610bd9565b3480156103d657600080fd5b5061024e6103e5366004612e29565b6110dc565b3480156103f657600080fd5b50610425610405366004613217565b600260209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610225565b34801561044157600080fd5b50610455610450366004613317565b6110f3565b60405167ffffffffffffffff9091168152602001610225565b34801561047a57600080fd5b5061029161048936600461334a565b61114d565b34801561049a57600080fd5b5061024e6104a9366004612e6b565b73ffffffffffffffffffffffffffffffffffffffff9091166000908152601860209081526040808320938352929052205490565b3480156104e957600080fd5b506102916104f8366004613396565b611248565b34801561050957600080fd5b5061024e610518366004612e6b565b601760209081526000928352604080842090915290825290205481565b34801561054157600080fd5b5061024e610550366004613317565b6113ff565b34801561056157600080fd5b5061024e620186a081565b34801561057857600080fd5b50610291610587366004613073565b611431565b34801561059857600080fd5b5060135461024e565b3480156105ad57600080fd5b507f000000000000000000000000000000000000000000000000000000000000271061024e565b3480156105e057600080fd5b5061024e6105ef366004612e6b565b601660209081526000928352604080842090915290825290205481565b34801561061857600080fd5b5061062c610627366004613217565b611840565b60408051928352602083019190915201610225565b34801561064d57600080fd5b5061029161065c36600461334a565b611931565b34801561066d57600080fd5b5061029161067c366004613422565b611a39565b34801561068d57600080fd5b5061029161069c366004613491565b611b98565b3480156106ad57600080fd5b507f000000000000000000000000000000000000000000000000000000000000007861024e565b6102916106e2366004613519565b611d1e565b3480156106f357600080fd5b5061024e610702366004612e29565b60006020819052908152604090205481565b6013818154811061072457600080fd5b60009182526020909120600290910201805460019091015473ffffffffffffffffffffffffffffffffffffffff909116915082565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601560209081526040808320848452909152812054819061079c9060601c63ffffffff1690565b63ffffffff16905060005b6010811015610889578160011660010361082f5773ffffffffffffffffffffffffffffffffffffffff85166000908152601460209081526040808320878452909152902081601081106107fc576107fc613555565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250610870565b826003826010811061084357610843613555565b01546040805160208101939093528201526060016040516020818303038152906040528051906020012092505b60019190911c9080610881816135b3565b9150506107a7565b505092915050565b600061089d8a8a610759565b90506108c086868360208b01356108bb6108b68d6135eb565b611fea565b61202a565b80156108de57506108de83838360208801356108bb6108b68a6135eb565b610914576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b86604001358860405160200161092a91906136ba565b6040516020818303038152906040528051906020012014610977576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83602001358760200135600161098d91906136f8565b146109c4576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a0c886109d28680613710565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061208b92505050565b610a15886121e6565b836040013588604051602001610a2b91906136ba565b6040516020818303038152906040528051906020012003610a78576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8a1660009081526015602090815260408083208c8452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055610adc8a8a3361298e565b50505050505050505050565b6001610af660106002613897565b610b0091906138a3565b81565b6000610b0f8686612a47565b9050610b1c8360086136f8565b82101580610b2a5750602083115b15610b61576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b60608115610bf257610beb8686612af4565b9050610c2c565b85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050505b3360009081526014602090815260408083208b845290915280822081516102008101928390529160109082845b815481526020019060010190808311610c5957505050505090506000601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b81526020019081526020016000205490506000610cda8260601c63ffffffff1690565b63ffffffff169050333214610d1b576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d2b8260801c63ffffffff1690565b63ffffffff16600003610d6a576040517f87138d5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d748260c01c90565b67ffffffffffffffff1615610db5576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b898114610dee576040517f60f95d5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610dfb89898d8886612b6d565b83516020850160888204881415608883061715610e20576307b1daf16000526004601cfd5b60405160c8810160405260005b83811015610ed0578083018051835260208101516020840152604081015160408401526060810151606084015260808101516080840152508460888301526088810460051b8b013560a883015260c882206001860195508560005b610200811015610ec5576001821615610ea55782818b0152610ec5565b8981015160009081526020938452604090209260019290921c9101610e88565b505050608801610e2d565b50505050600160106002610ee49190613897565b610eee91906138a3565b811115610f27576040517f6229572300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f9c610f3a8360401c63ffffffff1690565b610f4a9063ffffffff168a6136f8565b60401b7fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff606084901b167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff8516171790565b915084156110295777ffffffffffffffffffffffffffffffffffffffffffffffff82164260c01b179150610fd68260801c63ffffffff1690565b63ffffffff16610fec8360401c63ffffffff1690565b63ffffffff1614611029576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526014602090815260408083208e8452909152902061104f90846010612d9f565b503360008181526018602090815260408083208f8452825280832080546001810182559084528284206004820401805460039092166008026101000a67ffffffffffffffff818102199093164390931602919091179055838352601582528083208f8452909152812084905560609190911b81523690601437366014016000a05050505050505050505050565b600381601081106110ec57600080fd5b0154905081565b6018602052826000526040600020602052816000526040600020818154811061111b57600080fd5b906000526020600020906004918282040191900660080292509250509054906101000a900467ffffffffffffffff1681565b60443560008060088301861061116b5763fe2549876000526004601cfd5b60c083901b60805260888386823786600882030151915060206000858360025afa90508061119857600080fd5b50600080517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0400000000000000000000000000000000000000000000000000000000000000178082526002602090815260408084208a8552825280842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558385528252808420998452988152888320939093558152908190529490942055505050565b600080603087600037602060006030600060025afa806112705763f91129696000526004601cfd5b6000517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f010000000000000000000000000000000000000000000000000000000000000017608081815260a08c905260c08b905260308a60e037603088609083013760008060c083600a5afa9250826112f2576309bde3396000526004601cfd5b602886106113085763fe2549876000526004601cfd5b6000602882015278200000000000000000000000000000000000000000000000008152600881018b905285810151935060308a8237603081019b909b52505060509098207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0500000000000000000000000000000000000000000000000000000000000000176000818152600260209081526040808320868452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209583529481528482209a909a559081528089529190912096909655505050505050565b6014602052826000526040600020602052816000526040600020816010811061142757600080fd5b0154925083915050565b73ffffffffffffffffffffffffffffffffffffffff891660009081526015602090815260408083208b845290915290205467ffffffffffffffff8116156114a4576040517fc334f06900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114ae8160c01c90565b67ffffffffffffffff166000036114f1576040517f55d4cbf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000007861151c8260c01c90565b6115309067ffffffffffffffff16426138a3565b11611567576040517f55d4cbf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006115738b8b610759565b905061158c87878360208c01356108bb6108b68e6135eb565b80156115aa57506115aa84848360208901356108bb6108b68b6135eb565b6115e0576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8760400135896040516020016115f691906136ba565b6040516020818303038152906040528051906020012014611643576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84602001358860200135600161165991906136f8565b14158061168b575060016116738360601c63ffffffff1690565b61167d91906138ba565b63ffffffff16856020013514155b156116c2576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116d0896109d28780613710565b6116d9896121e6565b60006116e48a612cc0565b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0200000000000000000000000000000000000000000000000000000000000000179050600061173b8460a01c63ffffffff1690565b67ffffffffffffffff169050600160026000848152602001908152602001600020600083815260200190815260200160002060006101000a81548160ff021916908315150217905550601760008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008d8152602001908152602001600020546001600084815260200190815260200160002060008381526020019081526020016000208190555061180d8460801c63ffffffff1690565b600083815260208190526040902063ffffffff9190911690556118318d8d8161298e565b50505050505050505050505050565b6000828152600260209081526040808320848452909152812054819060ff166118c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546118e58160086136f8565b6118f08560206136f8565b1061190e57836119018260086136f8565b61190b91906138a3565b91505b506000938452600160209081526040808620948652939052919092205492909150565b60443560008060088301861061194f5763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b60008060008060808860601b81528760c01b6014820152858782601c0137601c860181207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0600000000000000000000000000000000000000000000000000000000000000179350604088026260216001603f5a021015611ac35763dd629f866000526004601cfd5b6000808783601c018c5afa94503d6001019150600882018a10611aee5763fe2549876000526004601cfd5b60c082901b81526008018481533d6000600183013e89017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8015160008481526002602090815260408083208d8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915587845282528083209c83529b81528b8220929092559384528390529790912096909655505050505050565b6000611ba48686610759565b9050611bbd83838360208801356108bb6108b68a6135eb565b611bf3576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602084013515611c2f576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c37612ddd565b611c45816109d28780613710565b611c4e816121e6565b846040013581604051602001611c6491906136ba565b6040516020818303038152906040528051906020012003611cb1576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166000908152601560209081526040808320898452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055611d1587873361298e565b50505050505050565b6703782dace9d90000341015611d60576040517fe92c469f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333214611d99576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611da48160086138df565b63ffffffff168263ffffffff1610611de8576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000027108163ffffffff161015611e48576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152601560209081526040808320868452909152902054611e738160801c63ffffffff1690565b63ffffffff1615611eb0576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608082901b7fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff60a085901b167fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff83161717336000818152601560209081526040808320898452825280832094909455835180850185528381528082018981526013805460018101825590855291517f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a090600290930292830180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055517f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0919091015591815260168252828120968152959052909320349055505050565b600081600001518260200151836040015160405160200161200d93929190613907565b604051602081830303815290604052805190602001209050919050565b60008160005b601081101561207e578060051b880135600186831c16600181146120635760008481526020839052604090209350612074565b600082815260208590526040902093505b5050600101612030565b5090931495945050505050565b608881511461209957600080fd5b602081016020830161211a565b8260031b8201518060001a8160011a60081b178160021a60101b8260031a60181b17178160041a60201b8260051a60281b178260061a60301b8360071a60381b1717179050612114816120ff868560059190911b015190565b1867ffffffffffffffff16600586901b840152565b50505050565b612126600083836120a6565b612132600183836120a6565b61213e600283836120a6565b61214a600383836120a6565b612156600483836120a6565b612162600583836120a6565b61216e600683836120a6565b61217a600783836120a6565b612186600883836120a6565b612192600983836120a6565b61219e600a83836120a6565b6121aa600b83836120a6565b6121b6600c83836120a6565b6121c2600d83836120a6565b6121ce600e83836120a6565b6121da600f83836120a6565b612114601083836120a6565b6040805178010000000000008082800000000000808a8000000080008000602082015279808b00000000800000018000000080008081800000000000800991810191909152788a00000000000000880000000080008009000000008000000a60608201527b8000808b800000000000008b8000000000008089800000000000800360808201527f80000000000080028000000000000080000000000000800a800000008000000a60a08201527f800000008000808180000000000080800000000080000001800000008000800860c082015260009060e0016040516020818303038152906040529050602082016020820161286e565b6102808101516101e082015161014083015160a0840151845118189118186102a082015161020083015161016084015160c0850151602086015118189118186102c083015161022084015161018085015160e0860151604087015118189118186102e08401516102408501516101a0860151610100870151606088015118189118186103008501516102608601516101c0870151610120880151608089015118189118188084603f1c6123998660011b67ffffffffffffffff1690565b18188584603f1c6123b48660011b67ffffffffffffffff1690565b18188584603f1c6123cf8660011b67ffffffffffffffff1690565b181895508483603f1c6123ec8560011b67ffffffffffffffff1690565b181894508387603f1c6124098960011b67ffffffffffffffff1690565b60208b01518b51861867ffffffffffffffff168c5291189190911897508118600181901b603f9190911c18935060c08801518118601481901c602c9190911b1867ffffffffffffffff1660208901526101208801518718602c81901c60149190911b1867ffffffffffffffff1660c08901526102c08801518618600381901c603d9190911b1867ffffffffffffffff166101208901526101c08801518718601981901c60279190911b1867ffffffffffffffff166102c08901526102808801518218602e81901c60129190911b1867ffffffffffffffff166101c089015260408801518618600281901c603e9190911b1867ffffffffffffffff166102808901526101808801518618601581901c602b9190911b1867ffffffffffffffff1660408901526101a08801518518602781901c60199190911b1867ffffffffffffffff166101808901526102608801518718603881901c60089190911b1867ffffffffffffffff166101a08901526102e08801518518600881901c60389190911b1867ffffffffffffffff166102608901526101e08801518218601781901c60299190911b1867ffffffffffffffff166102e089015260808801518718602581901c601b9190911b1867ffffffffffffffff166101e08901526103008801518718603281901c600e9190911b1867ffffffffffffffff1660808901526102a08801518118603e81901c60029190911b1867ffffffffffffffff166103008901526101008801518518600981901c60379190911b1867ffffffffffffffff166102a08901526102008801518118601381901c602d9190911b1867ffffffffffffffff1661010089015260a08801518218601c81901c60249190911b1867ffffffffffffffff1661020089015260608801518518602481901c601c9190911b1867ffffffffffffffff1660a08901526102408801518518602b81901c60159190911b1867ffffffffffffffff1660608901526102208801518618603181901c600f9190911b1867ffffffffffffffff166102408901526101608801518118603681901c600a9190911b1867ffffffffffffffff166102208901525060e08701518518603a81901c60069190911b1867ffffffffffffffff166101608801526101408701518118603d81901c60039190911b1867ffffffffffffffff1660e0880152505067ffffffffffffffff81166101408601525b5050505050565b600582811b8201805160018501831b8401805160028701851b8601805160038901871b8801805160048b0190981b8901805167ffffffffffffffff861985168918811690995283198a16861889169096528819861683188816909352841986168818871690528419831684189095169052919391929190611d15565b612808600082612781565b612813600582612781565b61281e600a82612781565b612829600f82612781565b612834601482612781565b50565b612840816122dc565b612849816127fd565b600383901b820151815160c09190911c9061211490821867ffffffffffffffff168352565b61287a60008284612837565b61288660018284612837565b61289260028284612837565b61289e60038284612837565b6128aa60048284612837565b6128b660058284612837565b6128c260068284612837565b6128ce60078284612837565b6128da60088284612837565b6128e660098284612837565b6128f2600a8284612837565b6128fe600b8284612837565b61290a600c8284612837565b612916600d8284612837565b612922600e8284612837565b61292e600f8284612837565b61293a60108284612837565b61294660118284612837565b61295260128284612837565b61295e60138284612837565b61296a60148284612837565b61297660158284612837565b61298260168284612837565b61211460178284612837565b73ffffffffffffffffffffffffffffffffffffffff83811660009081526016602090815260408083208684529091528082208054908390559051909284169083908381818185875af1925050503d8060008114612a07576040519150601f19603f3d011682016040523d82523d6000602084013e612a0c565b606091505b505090508061277a576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831617612aed818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b6060604051905081602082018181018286833760888306808015612b3d5760888290038501848101848103803687375060806001820353506001845160001a1784538652612b54565b608836843760018353608060878401536088850186525b5050505050601f19603f82510116810160405292915050565b6000612b7f8260a01c63ffffffff1690565b67ffffffffffffffff1690506000612b9d8360801c63ffffffff1690565b63ffffffff1690506000612bb78460401c63ffffffff1690565b63ffffffff169050600883108015612bcd575080155b15612c015760c082901b6000908152883560085283513382526017602090815260408084208a855290915290912055612cb6565b60088310158015612c1f575080612c196008856138a3565b93508310155b8015612c335750612c3087826136f8565b83105b15612cb6576000612c4482856138a3565b905087612c528260206136f8565b10158015612c5e575085155b15612c95576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526017602090815260408083208a845290915290209089013590555b5050505050505050565b6000612d43565b66ff00ff00ff00ff8160081c1667ff00ff00ff00ff00612cf18360081b67ffffffffffffffff1690565b1617905065ffff0000ffff8160101c1667ffff0000ffff0000612d1e8360101b67ffffffffffffffff1690565b1617905060008160201c612d3c8360201b67ffffffffffffffff1690565b1792915050565b60808201516020830190612d5b90612cc7565b612cc7565b6040820151612d6990612cc7565b60401b17612d81612d5660018460059190911b015190565b825160809190911b90612d9390612cc7565b60c01b17179392505050565b8260108101928215612dcd579160200282015b82811115612dcd578251825591602001919060010190612db2565b50612dd9929150612df5565b5090565b6040518060200160405280612df0612e0a565b905290565b5b80821115612dd95760008155600101612df6565b6040518061032001604052806019906020820280368337509192915050565b600060208284031215612e3b57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612e6657600080fd5b919050565b60008060408385031215612e7e57600080fd5b612e8783612e42565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610320810167ffffffffffffffff81118282101715612ee857612ee8612e95565b60405290565b6040516060810167ffffffffffffffff81118282101715612ee857612ee8612e95565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612f5857612f58612e95565b604052919050565b803567ffffffffffffffff81168114612e6657600080fd5b6000610320808385031215612f8c57600080fd5b604051602080820182811067ffffffffffffffff82111715612fb057612fb0612e95565b806040525081935085601f860112612fc757600080fd5b612fcf612ec4565b928501928087851115612fe157600080fd5b865b8581101561300157612ff481612f60565b8352918301918301612fe3565b509092525091949350505050565b60006060828403121561302157600080fd5b50919050565b60008083601f84011261303957600080fd5b50813567ffffffffffffffff81111561305157600080fd5b6020830191508360208260051b850101111561306c57600080fd5b9250929050565b60008060008060008060008060006103e08a8c03121561309257600080fd5b61309b8a612e42565b985060208a013597506130b18b60408c01612f78565b96506103608a013567ffffffffffffffff808211156130cf57600080fd5b6130db8d838e0161300f565b97506103808c01359150808211156130f257600080fd5b6130fe8d838e01613027565b90975095506103a08c013591508082111561311857600080fd5b6131248d838e0161300f565b94506103c08c013591508082111561313b57600080fd5b506131488c828d01613027565b915080935050809150509295985092959850929598565b600080600080600060a0868803121561317757600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60005b838110156131b557818101518382015260200161319d565b838111156121145750506000910152565b60208152600082518060208401526131e581604085016020870161319a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000806040838503121561322a57600080fd5b50508035926020909101359150565b60008083601f84011261324b57600080fd5b50813567ffffffffffffffff81111561326357600080fd5b60208301915083602082850101111561306c57600080fd5b600080600080600080600060a0888a03121561329657600080fd5b8735965060208801359550604088013567ffffffffffffffff808211156132bc57600080fd5b6132c88b838c01613239565b909750955060608a01359150808211156132e157600080fd5b506132ee8a828b01613027565b9094509250506080880135801515811461330757600080fd5b8091505092959891949750929550565b60008060006060848603121561332c57600080fd5b61333584612e42565b95602085013595506040909401359392505050565b60008060006040848603121561335f57600080fd5b83359250602084013567ffffffffffffffff81111561337d57600080fd5b61338986828701613239565b9497909650939450505050565b600080600080600080600060a0888a0312156133b157600080fd5b8735965060208801359550604088013567ffffffffffffffff808211156133d757600080fd5b6133e38b838c01613239565b909750955060608a01359150808211156133fc57600080fd5b506134098a828b01613239565b989b979a50959894979596608090950135949350505050565b60008060008060006080868803121561343a57600080fd5b8535945061344a60208701612e42565b935061345860408701612f60565b9250606086013567ffffffffffffffff81111561347457600080fd5b61348088828901613239565b969995985093965092949392505050565b6000806000806000608086880312156134a957600080fd5b6134b286612e42565b945060208601359350604086013567ffffffffffffffff808211156134d657600080fd5b6134e289838a0161300f565b945060608801359150808211156134f857600080fd5b5061348088828901613027565b803563ffffffff81168114612e6657600080fd5b60008060006060848603121561352e57600080fd5b8335925061353e60208501613505565b915061354c60408501613505565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135e4576135e4613584565b5060010190565b6000606082360312156135fd57600080fd5b613605612eee565b823567ffffffffffffffff8082111561361d57600080fd5b9084019036601f83011261363057600080fd5b813560208282111561364457613644612e95565b613674817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011601612f11565b9250818352368183860101111561368a57600080fd5b81818501828501376000918301810191909152908352848101359083015250604092830135928101929092525090565b81516103208201908260005b60198110156136ef57825167ffffffffffffffff168252602092830192909101906001016136c6565b50505092915050565b6000821982111561370b5761370b613584565b500190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261374557600080fd5b83018035915067ffffffffffffffff82111561376057600080fd5b60200191503681900382131561306c57600080fd5b600181815b808511156137ce57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156137b4576137b4613584565b808516156137c157918102915b93841c939080029061377a565b509250929050565b6000826137e557506001613891565b816137f257506000613891565b816001811461380857600281146138125761382e565b6001915050613891565b60ff84111561382357613823613584565b50506001821b613891565b5060208310610133831016604e8410600b8410161715613851575081810a613891565b61385b8383613775565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561388d5761388d613584565b0290505b92915050565b6000612aed83836137d6565b6000828210156138b5576138b5613584565b500390565b600063ffffffff838116908316818110156138d7576138d7613584565b039392505050565b600063ffffffff8083168185168083038211156138fe576138fe613584565b01949350505050565b6000845161391981846020890161319a565b9190910192835250602082015260400191905056fea164736f6c634300080f000a"; + hex"6080604052600436106101d85760003560e01c80639d53a64811610102578063ddcd58de11610095578063ec5efcbc11610064578063ec5efcbc14610681578063f3f480d9146106a1578063faf37bc7146106d4578063fef2b4ed146106e757600080fd5b8063ddcd58de146105d4578063e03110e11461060c578063e159261114610641578063ea7139501461066157600080fd5b8063b5e7154c116100d1578063b5e7154c14610555578063d18534b51461056c578063da35c6641461058c578063dd24f9bf146105a157600080fd5b80639d53a6481461048e5780639d7e8769146104dd578063b2e67ba8146104fd578063b4801e611461053557600080fd5b806361238bde1161017a5780637ac54767116101495780637ac54767146103ca5780638542cf50146103ea578063882856ef146104355780638dc4be111461046e57600080fd5b806361238bde1461031e5780636551927b146103565780637051472e1461038e5780637917de1d146103aa57600080fd5b80633909af5c116101b65780633909af5c146102715780634d52b4c91461029357806352f0f3ad146102a857806354fd4d50146102c857600080fd5b8063013cf08b146101dd5780630359a5631461022e5780632055b36b1461025c575b600080fd5b3480156101e957600080fd5b506101fd6101f8366004612e29565b610714565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526020830191909152015b60405180910390f35b34801561023a57600080fd5b5061024e610249366004612e6b565b610759565b604051908152602001610225565b34801561026857600080fd5b5061024e601081565b34801561027d57600080fd5b5061029161028c366004613073565b610891565b005b34801561029f57600080fd5b5061024e610ae8565b3480156102b457600080fd5b5061024e6102c336600461315f565b610b03565b3480156102d457600080fd5b506103116040518060400160405280600c81526020017f312e312e332d626574612e32000000000000000000000000000000000000000081525081565b60405161022591906131c6565b34801561032a57600080fd5b5061024e610339366004613217565b600160209081526000928352604080842090915290825290205481565b34801561036257600080fd5b5061024e610371366004612e6b565b601560209081526000928352604080842090915290825290205481565b34801561039a57600080fd5b5061024e6703782dace9d9000081565b3480156103b657600080fd5b506102916103c536600461327b565b610bd9565b3480156103d657600080fd5b5061024e6103e5366004612e29565b6110dc565b3480156103f657600080fd5b50610425610405366004613217565b600260209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610225565b34801561044157600080fd5b50610455610450366004613317565b6110f3565b60405167ffffffffffffffff9091168152602001610225565b34801561047a57600080fd5b5061029161048936600461334a565b61114d565b34801561049a57600080fd5b5061024e6104a9366004612e6b565b73ffffffffffffffffffffffffffffffffffffffff9091166000908152601860209081526040808320938352929052205490565b3480156104e957600080fd5b506102916104f8366004613396565b611248565b34801561050957600080fd5b5061024e610518366004612e6b565b601760209081526000928352604080842090915290825290205481565b34801561054157600080fd5b5061024e610550366004613317565b6113ff565b34801561056157600080fd5b5061024e620186a081565b34801561057857600080fd5b50610291610587366004613073565b611431565b34801561059857600080fd5b5060135461024e565b3480156105ad57600080fd5b507f000000000000000000000000000000000000000000000000000000000000271061024e565b3480156105e057600080fd5b5061024e6105ef366004612e6b565b601660209081526000928352604080842090915290825290205481565b34801561061857600080fd5b5061062c610627366004613217565b611840565b60408051928352602083019190915201610225565b34801561064d57600080fd5b5061029161065c36600461334a565b611931565b34801561066d57600080fd5b5061029161067c366004613422565b611a39565b34801561068d57600080fd5b5061029161069c366004613491565b611b98565b3480156106ad57600080fd5b507f000000000000000000000000000000000000000000000000000000000000007861024e565b6102916106e2366004613519565b611d1e565b3480156106f357600080fd5b5061024e610702366004612e29565b60006020819052908152604090205481565b6013818154811061072457600080fd5b60009182526020909120600290910201805460019091015473ffffffffffffffffffffffffffffffffffffffff909116915082565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601560209081526040808320848452909152812054819061079c9060601c63ffffffff1690565b63ffffffff16905060005b6010811015610889578160011660010361082f5773ffffffffffffffffffffffffffffffffffffffff85166000908152601460209081526040808320878452909152902081601081106107fc576107fc613555565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250610870565b826003826010811061084357610843613555565b01546040805160208101939093528201526060016040516020818303038152906040528051906020012092505b60019190911c9080610881816135b3565b9150506107a7565b505092915050565b600061089d8a8a610759565b90506108c086868360208b01356108bb6108b68d6135eb565b611fea565b61202a565b80156108de57506108de83838360208801356108bb6108b68a6135eb565b610914576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b86604001358860405160200161092a91906136ba565b6040516020818303038152906040528051906020012014610977576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83602001358760200135600161098d91906136f8565b146109c4576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a0c886109d28680613710565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061208b92505050565b610a15886121e6565b836040013588604051602001610a2b91906136ba565b6040516020818303038152906040528051906020012003610a78576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8a1660009081526015602090815260408083208c8452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055610adc8a8a3361298e565b50505050505050505050565b6001610af660106002613897565b610b0091906138a3565b81565b6000610b0f8686612a47565b9050610b1c8360086136f8565b82101580610b2a5750602083115b15610b61576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b60608115610bf257610beb8686612af4565b9050610c2c565b85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050505b3360009081526014602090815260408083208b845290915280822081516102008101928390529160109082845b815481526020019060010190808311610c5957505050505090506000601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b81526020019081526020016000205490506000610cda8260601c63ffffffff1690565b63ffffffff169050333214610d1b576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d2b8260801c63ffffffff1690565b63ffffffff16600003610d6a576040517f87138d5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d748260c01c90565b67ffffffffffffffff1615610db5576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b898114610dee576040517f60f95d5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610dfb89898d8886612b6d565b83516020850160888204881415608883061715610e20576307b1daf16000526004601cfd5b60405160c8810160405260005b83811015610ed0578083018051835260208101516020840152604081015160408401526060810151606084015260808101516080840152508460888301526088810460051b8b013560a883015260c882206001860195508560005b610200811015610ec5576001821615610ea55782818b0152610ec5565b8981015160009081526020938452604090209260019290921c9101610e88565b505050608801610e2d565b50505050600160106002610ee49190613897565b610eee91906138a3565b811115610f27576040517f6229572300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f9c610f3a8360401c63ffffffff1690565b610f4a9063ffffffff168a6136f8565b60401b7fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff606084901b167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff8516171790565b915084156110295777ffffffffffffffffffffffffffffffffffffffffffffffff82164260c01b179150610fd68260801c63ffffffff1690565b63ffffffff16610fec8360401c63ffffffff1690565b63ffffffff1614611029576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526014602090815260408083208e8452909152902061104f90846010612d9f565b503360008181526018602090815260408083208f8452825280832080546001810182559084528284206004820401805460039092166008026101000a67ffffffffffffffff818102199093164390931602919091179055838352601582528083208f8452909152812084905560609190911b81523690601437366014016000a05050505050505050505050565b600381601081106110ec57600080fd5b0154905081565b6018602052826000526040600020602052816000526040600020818154811061111b57600080fd5b906000526020600020906004918282040191900660080292509250509054906101000a900467ffffffffffffffff1681565b60443560008060088301861061116b5763fe2549876000526004601cfd5b60c083901b60805260888386823786600882030151915060206000858360025afa90508061119857600080fd5b50600080517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0400000000000000000000000000000000000000000000000000000000000000178082526002602090815260408084208a8552825280842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558385528252808420998452988152888320939093558152908190529490942055505050565b600080603087600037602060006030600060025afa806112705763f91129696000526004601cfd5b6000517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f010000000000000000000000000000000000000000000000000000000000000017608081815260a08c905260c08b905260308a60e037603088609083013760008060c083600a5afa9250826112f2576309bde3396000526004601cfd5b602886106113085763fe2549876000526004601cfd5b6000602882015278200000000000000000000000000000000000000000000000008152600881018b905285810151935060308a8237603081019b909b52505060509098207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0500000000000000000000000000000000000000000000000000000000000000176000818152600260209081526040808320868452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209583529481528482209a909a559081528089529190912096909655505050505050565b6014602052826000526040600020602052816000526040600020816010811061142757600080fd5b0154925083915050565b73ffffffffffffffffffffffffffffffffffffffff891660009081526015602090815260408083208b845290915290205467ffffffffffffffff8116156114a4576040517fc334f06900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114ae8160c01c90565b67ffffffffffffffff166000036114f1576040517f55d4cbf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000007861151c8260c01c90565b6115309067ffffffffffffffff16426138a3565b11611567576040517f55d4cbf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006115738b8b610759565b905061158c87878360208c01356108bb6108b68e6135eb565b80156115aa57506115aa84848360208901356108bb6108b68b6135eb565b6115e0576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8760400135896040516020016115f691906136ba565b6040516020818303038152906040528051906020012014611643576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84602001358860200135600161165991906136f8565b14158061168b575060016116738360601c63ffffffff1690565b61167d91906138ba565b63ffffffff16856020013514155b156116c2576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116d0896109d28780613710565b6116d9896121e6565b60006116e48a612cc0565b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0200000000000000000000000000000000000000000000000000000000000000179050600061173b8460a01c63ffffffff1690565b67ffffffffffffffff169050600160026000848152602001908152602001600020600083815260200190815260200160002060006101000a81548160ff021916908315150217905550601760008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008d8152602001908152602001600020546001600084815260200190815260200160002060008381526020019081526020016000208190555061180d8460801c63ffffffff1690565b600083815260208190526040902063ffffffff9190911690556118318d8d8161298e565b50505050505050505050505050565b6000828152600260209081526040808320848452909152812054819060ff166118c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546118e58160086136f8565b6118f08560206136f8565b1061190e57836119018260086136f8565b61190b91906138a3565b91505b506000938452600160209081526040808620948652939052919092205492909150565b60443560008060088301861061194f5763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b60008060008060808860601b81528760c01b6014820152858782601c0137601c860181207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0600000000000000000000000000000000000000000000000000000000000000179350604088026260216001603f5a021015611ac35763dd629f866000526004601cfd5b6000808783601c018c5afa94503d6001019150600882018a10611aee5763fe2549876000526004601cfd5b60c082901b81526008018481533d6000600183013e89017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8015160008481526002602090815260408083208d8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915587845282528083209c83529b81528b8220929092559384528390529790912096909655505050505050565b6000611ba48686610759565b9050611bbd83838360208801356108bb6108b68a6135eb565b611bf3576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602084013515611c2f576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c37612ddd565b611c45816109d28780613710565b611c4e816121e6565b846040013581604051602001611c6491906136ba565b6040516020818303038152906040528051906020012003611cb1576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166000908152601560209081526040808320898452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055611d1587873361298e565b50505050505050565b6703782dace9d90000341015611d60576040517fe92c469f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333214611d99576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611da48160086138df565b63ffffffff168263ffffffff1610611de8576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000027108163ffffffff161015611e48576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152601560209081526040808320868452909152902054611e738160801c63ffffffff1690565b63ffffffff1615611eb0576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608082901b7fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff60a085901b167fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff83161717336000818152601560209081526040808320898452825280832094909455835180850185528381528082018981526013805460018101825590855291517f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a090600290930292830180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055517f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0919091015591815260168252828120968152959052909320349055505050565b600081600001518260200151836040015160405160200161200d93929190613907565b604051602081830303815290604052805190602001209050919050565b60008160005b601081101561207e578060051b880135600186831c16600181146120635760008481526020839052604090209350612074565b600082815260208590526040902093505b5050600101612030565b5090931495945050505050565b608881511461209957600080fd5b602081016020830161211a565b8260031b8201518060001a8160011a60081b178160021a60101b8260031a60181b17178160041a60201b8260051a60281b178260061a60301b8360071a60381b1717179050612114816120ff868560059190911b015190565b1867ffffffffffffffff16600586901b840152565b50505050565b612126600083836120a6565b612132600183836120a6565b61213e600283836120a6565b61214a600383836120a6565b612156600483836120a6565b612162600583836120a6565b61216e600683836120a6565b61217a600783836120a6565b612186600883836120a6565b612192600983836120a6565b61219e600a83836120a6565b6121aa600b83836120a6565b6121b6600c83836120a6565b6121c2600d83836120a6565b6121ce600e83836120a6565b6121da600f83836120a6565b612114601083836120a6565b6040805178010000000000008082800000000000808a8000000080008000602082015279808b00000000800000018000000080008081800000000000800991810191909152788a00000000000000880000000080008009000000008000000a60608201527b8000808b800000000000008b8000000000008089800000000000800360808201527f80000000000080028000000000000080000000000000800a800000008000000a60a08201527f800000008000808180000000000080800000000080000001800000008000800860c082015260009060e0016040516020818303038152906040529050602082016020820161286e565b6102808101516101e082015161014083015160a0840151845118189118186102a082015161020083015161016084015160c0850151602086015118189118186102c083015161022084015161018085015160e0860151604087015118189118186102e08401516102408501516101a0860151610100870151606088015118189118186103008501516102608601516101c0870151610120880151608089015118189118188084603f1c6123998660011b67ffffffffffffffff1690565b18188584603f1c6123b48660011b67ffffffffffffffff1690565b18188584603f1c6123cf8660011b67ffffffffffffffff1690565b181895508483603f1c6123ec8560011b67ffffffffffffffff1690565b181894508387603f1c6124098960011b67ffffffffffffffff1690565b60208b01518b51861867ffffffffffffffff168c5291189190911897508118600181901b603f9190911c18935060c08801518118601481901c602c9190911b1867ffffffffffffffff1660208901526101208801518718602c81901c60149190911b1867ffffffffffffffff1660c08901526102c08801518618600381901c603d9190911b1867ffffffffffffffff166101208901526101c08801518718601981901c60279190911b1867ffffffffffffffff166102c08901526102808801518218602e81901c60129190911b1867ffffffffffffffff166101c089015260408801518618600281901c603e9190911b1867ffffffffffffffff166102808901526101808801518618601581901c602b9190911b1867ffffffffffffffff1660408901526101a08801518518602781901c60199190911b1867ffffffffffffffff166101808901526102608801518718603881901c60089190911b1867ffffffffffffffff166101a08901526102e08801518518600881901c60389190911b1867ffffffffffffffff166102608901526101e08801518218601781901c60299190911b1867ffffffffffffffff166102e089015260808801518718602581901c601b9190911b1867ffffffffffffffff166101e08901526103008801518718603281901c600e9190911b1867ffffffffffffffff1660808901526102a08801518118603e81901c60029190911b1867ffffffffffffffff166103008901526101008801518518600981901c60379190911b1867ffffffffffffffff166102a08901526102008801518118601381901c602d9190911b1867ffffffffffffffff1661010089015260a08801518218601c81901c60249190911b1867ffffffffffffffff1661020089015260608801518518602481901c601c9190911b1867ffffffffffffffff1660a08901526102408801518518602b81901c60159190911b1867ffffffffffffffff1660608901526102208801518618603181901c600f9190911b1867ffffffffffffffff166102408901526101608801518118603681901c600a9190911b1867ffffffffffffffff166102208901525060e08701518518603a81901c60069190911b1867ffffffffffffffff166101608801526101408701518118603d81901c60039190911b1867ffffffffffffffff1660e0880152505067ffffffffffffffff81166101408601525b5050505050565b600582811b8201805160018501831b8401805160028701851b8601805160038901871b8801805160048b0190981b8901805167ffffffffffffffff861985168918811690995283198a16861889169096528819861683188816909352841986168818871690528419831684189095169052919391929190611d15565b612808600082612781565b612813600582612781565b61281e600a82612781565b612829600f82612781565b612834601482612781565b50565b612840816122dc565b612849816127fd565b600383901b820151815160c09190911c9061211490821867ffffffffffffffff168352565b61287a60008284612837565b61288660018284612837565b61289260028284612837565b61289e60038284612837565b6128aa60048284612837565b6128b660058284612837565b6128c260068284612837565b6128ce60078284612837565b6128da60088284612837565b6128e660098284612837565b6128f2600a8284612837565b6128fe600b8284612837565b61290a600c8284612837565b612916600d8284612837565b612922600e8284612837565b61292e600f8284612837565b61293a60108284612837565b61294660118284612837565b61295260128284612837565b61295e60138284612837565b61296a60148284612837565b61297660158284612837565b61298260168284612837565b61211460178284612837565b73ffffffffffffffffffffffffffffffffffffffff83811660009081526016602090815260408083208684529091528082208054908390559051909284169083908381818185875af1925050503d8060008114612a07576040519150601f19603f3d011682016040523d82523d6000602084013e612a0c565b606091505b505090508061277a576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831617612aed818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b6060604051905081602082018181018286833760888306808015612b3d5760888290038501848101848103803687375060806001820353506001845160001a1784538652612b54565b608836843760018353608060878401536088850186525b5050505050601f19603f82510116810160405292915050565b6000612b7f8260a01c63ffffffff1690565b67ffffffffffffffff1690506000612b9d8360801c63ffffffff1690565b63ffffffff1690506000612bb78460401c63ffffffff1690565b63ffffffff169050600883108015612bcd575080155b15612c015760c082901b6000908152883560085283513382526017602090815260408084208a855290915290912055612cb6565b60088310158015612c1f575080612c196008856138a3565b93508310155b8015612c335750612c3087826136f8565b83105b15612cb6576000612c4482856138a3565b905087612c528260206136f8565b10158015612c5e575085155b15612c95576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526017602090815260408083208a845290915290209089013590555b5050505050505050565b6000612d43565b66ff00ff00ff00ff8160081c1667ff00ff00ff00ff00612cf18360081b67ffffffffffffffff1690565b1617905065ffff0000ffff8160101c1667ffff0000ffff0000612d1e8360101b67ffffffffffffffff1690565b1617905060008160201c612d3c8360201b67ffffffffffffffff1690565b1792915050565b60808201516020830190612d5b90612cc7565b612cc7565b6040820151612d6990612cc7565b60401b17612d81612d5660018460059190911b015190565b825160809190911b90612d9390612cc7565b60c01b17179392505050565b8260108101928215612dcd579160200282015b82811115612dcd578251825591602001919060010190612db2565b50612dd9929150612df5565b5090565b6040518060200160405280612df0612e0a565b905290565b5b80821115612dd95760008155600101612df6565b6040518061032001604052806019906020820280368337509192915050565b600060208284031215612e3b57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612e6657600080fd5b919050565b60008060408385031215612e7e57600080fd5b612e8783612e42565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610320810167ffffffffffffffff81118282101715612ee857612ee8612e95565b60405290565b6040516060810167ffffffffffffffff81118282101715612ee857612ee8612e95565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612f5857612f58612e95565b604052919050565b803567ffffffffffffffff81168114612e6657600080fd5b6000610320808385031215612f8c57600080fd5b604051602080820182811067ffffffffffffffff82111715612fb057612fb0612e95565b806040525081935085601f860112612fc757600080fd5b612fcf612ec4565b928501928087851115612fe157600080fd5b865b8581101561300157612ff481612f60565b8352918301918301612fe3565b509092525091949350505050565b60006060828403121561302157600080fd5b50919050565b60008083601f84011261303957600080fd5b50813567ffffffffffffffff81111561305157600080fd5b6020830191508360208260051b850101111561306c57600080fd5b9250929050565b60008060008060008060008060006103e08a8c03121561309257600080fd5b61309b8a612e42565b985060208a013597506130b18b60408c01612f78565b96506103608a013567ffffffffffffffff808211156130cf57600080fd5b6130db8d838e0161300f565b97506103808c01359150808211156130f257600080fd5b6130fe8d838e01613027565b90975095506103a08c013591508082111561311857600080fd5b6131248d838e0161300f565b94506103c08c013591508082111561313b57600080fd5b506131488c828d01613027565b915080935050809150509295985092959850929598565b600080600080600060a0868803121561317757600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60005b838110156131b557818101518382015260200161319d565b838111156121145750506000910152565b60208152600082518060208401526131e581604085016020870161319a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000806040838503121561322a57600080fd5b50508035926020909101359150565b60008083601f84011261324b57600080fd5b50813567ffffffffffffffff81111561326357600080fd5b60208301915083602082850101111561306c57600080fd5b600080600080600080600060a0888a03121561329657600080fd5b8735965060208801359550604088013567ffffffffffffffff808211156132bc57600080fd5b6132c88b838c01613239565b909750955060608a01359150808211156132e157600080fd5b506132ee8a828b01613027565b9094509250506080880135801515811461330757600080fd5b8091505092959891949750929550565b60008060006060848603121561332c57600080fd5b61333584612e42565b95602085013595506040909401359392505050565b60008060006040848603121561335f57600080fd5b83359250602084013567ffffffffffffffff81111561337d57600080fd5b61338986828701613239565b9497909650939450505050565b600080600080600080600060a0888a0312156133b157600080fd5b8735965060208801359550604088013567ffffffffffffffff808211156133d757600080fd5b6133e38b838c01613239565b909750955060608a01359150808211156133fc57600080fd5b506134098a828b01613239565b989b979a50959894979596608090950135949350505050565b60008060008060006080868803121561343a57600080fd5b8535945061344a60208701612e42565b935061345860408701612f60565b9250606086013567ffffffffffffffff81111561347457600080fd5b61348088828901613239565b969995985093965092949392505050565b6000806000806000608086880312156134a957600080fd5b6134b286612e42565b945060208601359350604086013567ffffffffffffffff808211156134d657600080fd5b6134e289838a0161300f565b945060608801359150808211156134f857600080fd5b5061348088828901613027565b803563ffffffff81168114612e6657600080fd5b60008060006060848603121561352e57600080fd5b8335925061353e60208501613505565b915061354c60408501613505565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135e4576135e4613584565b5060010190565b6000606082360312156135fd57600080fd5b613605612eee565b823567ffffffffffffffff8082111561361d57600080fd5b9084019036601f83011261363057600080fd5b813560208282111561364457613644612e95565b613674817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011601612f11565b9250818352368183860101111561368a57600080fd5b81818501828501376000918301810191909152908352848101359083015250604092830135928101929092525090565b81516103208201908260005b60198110156136ef57825167ffffffffffffffff168252602092830192909101906001016136c6565b50505092915050565b6000821982111561370b5761370b613584565b500190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261374557600080fd5b83018035915067ffffffffffffffff82111561376057600080fd5b60200191503681900382131561306c57600080fd5b600181815b808511156137ce57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156137b4576137b4613584565b808516156137c157918102915b93841c939080029061377a565b509250929050565b6000826137e557506001613891565b816137f257506000613891565b816001811461380857600281146138125761382e565b6001915050613891565b60ff84111561382357613823613584565b50506001821b613891565b5060208310610133831016604e8410600b8410161715613851575081810a613891565b61385b8383613775565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561388d5761388d613584565b0290505b92915050565b6000612aed83836137d6565b6000828210156138b5576138b5613584565b500390565b600063ffffffff838116908316818110156138d7576138d7613584565b039392505050565b600063ffffffff8083168185168083038211156138fe576138fe613584565b01949350505050565b6000845161391981846020890161319a565b9190910192835250602082015260400191905056fea164736f6c634300080f000a"; bytes internal constant mipsCode = - hex"608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d50146100465780637dc0d1d014610098578063e14ced32146100dc575b600080fd5b6100826040518060400160405280600a81526020017f312e312e302d72632e310000000000000000000000000000000000000000000081525081565b60405161008f91906121ee565b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000373d916d11cce55b548f7051002e76bcfbd7a85d16815260200161008f565b6100ef6100ea3660046122a3565b6100fd565b60405190815260200161008f565b6000610107612164565b6080811461011457600080fd5b6040516106001461012457600080fd5b6084871461013157600080fd5b6101a4851461013f57600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a0819052605a89013590911c6101c05260628801906101e09060018111156101f5576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b506020810181511461020657600080fd5b60200160005b602081101561023057823560e01c825260049092019160209091019060010161020c565b5050508061012001511561024e576102466103a6565b91505061039d565b6101408101805160010167ffffffffffffffff16905260006101a49050600080600061028385606001518660000151866104f7565b9250925092508163ffffffff1660001480156102a557508063ffffffff16600c145b156102bf576102b387610521565b9550505050505061039d565b6000610339866040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b6101608701518751919250610356918391906105248888886108f9565b8652805163ffffffff9081166060808901919091526020830151821660808901526040830151821660a08901528201511660c08701526103946103a6565b96505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a8401526000926102009290916062830191906001811115610453576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b60005b602081101561047a57601c8601518452602090950194600490930192600101610456565b506000835283830384a060009450806001811461049a57600395506104c2565b8280156104b257600181146104bb57600296506104c0565b600096506104c0565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b6000806000610507858786610cdf565b925050603f601a83901c8116915082165b93509350939050565b600061052b612164565b608090506000806000806105628561016001516040810151608082015160a083015160c084015160e0909401519294919390929091565b509350935093509350600080610ffa63ffffffff168663ffffffff16036105a75761059285858960e00151610d93565b63ffffffff1660e08a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03363ffffffff8716016105e05763400000009150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefe863ffffffff8716016106165760019150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef6a63ffffffff87160161066a57600161012088015260ff851661010088015261065d6103a6565b9998505050505050505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05d63ffffffff8716016107665760006040518061012001604052808763ffffffff1681526020018663ffffffff1681526020018563ffffffff16815260200189602001518152602001896040015163ffffffff1681526020018b81526020017f000000000000000000000000373d916d11cce55b548f7051002e76bcfbd7a85d73ffffffffffffffffffffffffffffffffffffffff1681526020016107386101a4600160ff16610380020190565b81528951602090910152905061074d81610e27565b8b5263ffffffff1660408b015290935091506108089050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05c63ffffffff8716016107cb57602087015160408801516107b1918791879187916105248d5161109f565b63ffffffff1660408b015260208a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff02963ffffffff871601610808576108028585611195565b90925090505b6000610882886040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b61016089015163ffffffff85811660408084019190915285821660e0909301929092526020830180518083168086526004909101831682526060808e01919091529051821660808d015291830151811660a08c0152908201511660c08a015290506108eb6103a6565b9a9950505050505050505050565b84600263ffffffff8416148061091557508263ffffffff166003145b156109675760006002856303ffffff1663ffffffff16901b896020015163f00000001617905061096189898663ffffffff1660021461095557601f610958565b60005b60ff168461124a565b50610cd4565b600080601f601087901c8116908a90601589901c166020811061098c5761098c612317565b602002015192508063ffffffff871615806109ad57508663ffffffff16601c145b156109df578a8263ffffffff16602081106109ca576109ca612317565b6020020151925050601f600b88901c16610a96565b60208763ffffffff161015610a41578663ffffffff16600c1480610a0957508663ffffffff16600d145b80610a1a57508663ffffffff16600e145b15610a2b578761ffff169250610a96565b610a3a8861ffff166010611322565b9250610a96565b60288763ffffffff16101580610a5d57508663ffffffff166022145b80610a6e57508663ffffffff166026145b15610a96578a8263ffffffff1660208110610a8b57610a8b612317565b602002015192508190505b60048763ffffffff1610158015610ab3575060088763ffffffff16105b80610ac457508663ffffffff166001145b15610ae057610ad78c8c898b8689611395565b50505050610cd4565b63ffffffff6000602089831610610b4557610b008a61ffff166010611322565b9095019463fffffffc8616610b168d828e610cdf565b915060288a63ffffffff1610158015610b3657508963ffffffff16603014155b15610b4357809250600093505b505b6000610b558b8b8b8a8a87611583565b63ffffffff1690508963ffffffff166000148015610b7a575060088963ffffffff1610155b8015610b8c5750601c8963ffffffff16105b15610c54578863ffffffff1660081480610bac57508863ffffffff166009145b15610bdf57610bd38f8f8b63ffffffff16600814610bca5786610bcd565b60005b8a61124a565b50505050505050610cd4565b8863ffffffff16600a03610c0157610bd38f8f868a63ffffffff8b1615611ca0565b8863ffffffff16600b03610c2457610bd38f8f868a63ffffffff8b161515611ca0565b60108963ffffffff1610158015610c415750601c8963ffffffff16105b15610c5457610bd38f8f8b8a8a89611d70565b8963ffffffff166038148015610c6f575063ffffffff851615155b15610c9f5760018e8663ffffffff1660208110610c8e57610c8e612317565b63ffffffff90921660209290920201525b8263ffffffff1663ffffffff14610cbe57610cbb838d83612029565b97505b610ccc8f8f86846001611ca0565b505050505050505b979650505050505050565b6000610cea826120cb565b6003831615610cf857600080fd5b6020820191358360051c8160005b601b811015610d5e5760208601953583821c6001168015610d2e5760018114610d4357610d54565b60008481526020839052604090209350610d54565b600082815260208590526040902093505b5050600101610d06565b50868114610d7457630badf00d60005260206000fd5b5050601f93909316601c0360031b9290921c63ffffffff169392505050565b6000808284610fff811615610dad57610fff811661100003015b8663ffffffff16600003610e195784935090810190636000000063ffffffff83161180610de557508463ffffffff168263ffffffff16105b80610dfb57508563ffffffff168163ffffffff16105b15610e14575063ffffffff925060169150839050610518565b610e1d565b8693505b5093509350939050565b6101008101516080820151825160009283929163ffffffff161561109857845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb01611052576000610e93866101000151876020015163fffffffc168860e00151610cdf565b606087015190915060001a600103610f1557610f0f86606001518760a0015160408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b60608701525b6000808760c0015173ffffffffffffffffffffffffffffffffffffffff1663e03110e189606001518a608001516040518363ffffffff1660e01b8152600401610f6e92919091825263ffffffff16602082015260400190565b6040805180830381865afa158015610f8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fae9190612346565b60208a015160408b01519294509092509060038216600481900384811015610fd4578094505b5083821015610fe1578193505b8460088502610100031c9450846008828660040303021b9450600180600883600403021b036001806008878560040303021b0391508119811690508581198816179650505061103f8a6020015163fffffffc168b60e0015187612029565b9298505050938601939250611098915050565b845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0161108c5784604001519350611098565b63ffffffff9350600992505b9193509193565b600080858563ffffffff8b16600114806110bf575063ffffffff8b166002145b806110d0575063ffffffff8b166004145b156110dd57889350611187565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8c160161117b57600061111d868c63fffffffc1689610cdf565b90508860038c166004038b81101561113357809b505b8b965086900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193880293841b0116911b17915060009050611187565b63ffffffff9350600992505b975097509750979350505050565b60008063ffffffff83166003036112385763ffffffff841615806111bf575063ffffffff84166005145b806111d0575063ffffffff84166003145b156111de5760009150611243565b63ffffffff8416600114806111f9575063ffffffff84166002145b8061120a575063ffffffff84166006145b8061121b575063ffffffff84166004145b156112295760019150611243565b5063ffffffff90506009611243565b5063ffffffff905060165b9250929050565b836000015160040163ffffffff16846020015163ffffffff16146112cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b835160208501805163ffffffff908116875283811690915283161561131b5780600801848463ffffffff166020811061130a5761130a612317565b63ffffffff90921660209290920201525b5050505050565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b018261137f576000611381565b815b90861663ffffffff16179250505092915050565b6000866000015160040163ffffffff16876020015163ffffffff1614611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f7400000000000000000000000060448201526064016112c6565b8463ffffffff166004148061143257508463ffffffff166005145b156114a9576000868463ffffffff166020811061145157611451612317565b602002015190508063ffffffff168363ffffffff1614801561147957508563ffffffff166004145b806114a157508063ffffffff168363ffffffff16141580156114a157508563ffffffff166005145b915050611526565b8463ffffffff166006036114c65760008260030b13159050611526565b8463ffffffff166007036114e25760008260030b139050611526565b8463ffffffff1660010361152657601f601085901c16600081900361150b5760008360030b1291505b8063ffffffff166001036115245760008360030b121591505b505b8651602088015163ffffffff168852811561156757600261154c8661ffff166010611322565b63ffffffff90811690911b8201600401166020890152611579565b60208801805160040163ffffffff1690525b5050505050505050565b600063ffffffff861615806115b0575060088663ffffffff16101580156115b05750600f8663ffffffff16105b156119b05785600881146115f357600981146115fc57600a811461160557600b811461160e57600c811461161757600d811461162057600e81146116295761162e565b6020955061162e565b6021955061162e565b602a955061162e565b602b955061162e565b6024955061162e565b6025955061162e565b602695505b508463ffffffff16600003611653575063ffffffff8216601f600688901c161b611c96565b8463ffffffff16600203611677575063ffffffff8216601f600688901c161c611c96565b8463ffffffff166003036116ab57601f600688901c166116a363ffffffff8516821c6020839003611322565b915050611c96565b8463ffffffff166004036116cb575063ffffffff8216601f84161b611c96565b8463ffffffff166006036116eb575063ffffffff8216601f84161c611c96565b8463ffffffff1660070361171357601f84166116a363ffffffff8516821c6020839003611322565b8463ffffffff16600803611728575082611c96565b8463ffffffff1660090361173d575082611c96565b8463ffffffff16600a03611752575082611c96565b8463ffffffff16600b03611767575082611c96565b8463ffffffff16600c0361177c575082611c96565b8463ffffffff16600f03611791575082611c96565b8463ffffffff166010036117a6575082611c96565b8463ffffffff166011036117bb575082611c96565b8463ffffffff166012036117d0575082611c96565b8463ffffffff166013036117e5575082611c96565b8463ffffffff166018036117fa575082611c96565b8463ffffffff1660190361180f575082611c96565b8463ffffffff16601a03611824575082611c96565b8463ffffffff16601b03611839575082611c96565b8463ffffffff166020036118505750828201611c96565b8463ffffffff166021036118675750828201611c96565b8463ffffffff1660220361187e5750818303611c96565b8463ffffffff166023036118955750818303611c96565b8463ffffffff166024036118ac5750828216611c96565b8463ffffffff166025036118c35750828217611c96565b8463ffffffff166026036118da5750828218611c96565b8463ffffffff166027036118f2575082821719611c96565b8463ffffffff16602a03611921578260030b8460030b12611914576000611917565b60015b60ff169050611c96565b8463ffffffff16602b03611949578263ffffffff168463ffffffff1610611914576000611917565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e0000000000000000000000000060448201526064016112c6565b611949565b8563ffffffff16601c03611a30578463ffffffff166002036119d55750828202611c96565b8463ffffffff16602014806119f057508463ffffffff166021145b156119ab578463ffffffff16602003611a07579219925b60005b6380000000851615611a29576401fffffffe600195861b169401611a0a565b9050611c96565b8563ffffffff16600f03611a51575065ffffffff0000601083901b16611c96565b8563ffffffff16602003611a8557611a298460031660080260180363ffffffff168363ffffffff16901c60ff166008611322565b8563ffffffff16602103611aba57611a298460021660080260100363ffffffff168363ffffffff16901c61ffff166010611322565b8563ffffffff16602203611ae8575063ffffffff60086003851602811681811b198416918316901b17611c96565b8563ffffffff16602303611afd575080611c96565b8563ffffffff16602403611b2e578360031660080260180363ffffffff168263ffffffff16901c60ff169050611c96565b8563ffffffff16602503611b60578360021660080260100363ffffffff168263ffffffff16901c61ffff169050611c96565b8563ffffffff16602603611b91575063ffffffff60086003851602601803811681811c198416918316901c17611c96565b8563ffffffff16602803611bc6575060ff63ffffffff60086003861602601803811682811b9091188316918416901b17611c96565b8563ffffffff16602903611bfc575061ffff63ffffffff60086002861602601003811682811b9091188316918416901b17611c96565b8563ffffffff16602a03611c2a575063ffffffff60086003851602811681811c198316918416901c17611c96565b8563ffffffff16602b03611c3f575081611c96565b8563ffffffff16602e03611c70575063ffffffff60086003851602601803811681811b198316918416901b17611c96565b8563ffffffff16603003611c85575080611c96565b8563ffffffff166038036119495750815b9695505050505050565b60208363ffffffff1610611d10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c696420726567697374657200000000000000000000000000000000000060448201526064016112c6565b63ffffffff831615801590611d225750805b15611d515781848463ffffffff1660208110611d4057611d40612317565b63ffffffff90921660209290920201525b5050505060208101805163ffffffff8082169093526004019091169052565b60008463ffffffff16601003611d8b57506060860151611fd1565b8463ffffffff16601103611daa5763ffffffff84166060880152611fd1565b8463ffffffff16601203611dc357506040860151611fd1565b8463ffffffff16601303611de25763ffffffff84166040880152611fd1565b8463ffffffff16601803611e165763ffffffff600385810b9085900b02602081901c821660608a0152166040880152611fd1565b8463ffffffff16601903611e475763ffffffff84811681851602602081901c821660608a0152166040880152611fd1565b8463ffffffff16601a03611f0a578260030b600003611ec2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8260030b8460030b81611ed757611ed761236a565b0763ffffffff166060880152600383810b9085900b81611ef957611ef961236a565b0563ffffffff166040880152611fd1565b8463ffffffff16601b03611fd1578263ffffffff16600003611f88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8263ffffffff168463ffffffff1681611fa357611fa361236a565b0663ffffffff908116606089015283811690851681611fc457611fc461236a565b0463ffffffff1660408801525b63ffffffff8216156120075780868363ffffffff1660208110611ff657611ff6612317565b63ffffffff90921660209290920201525b50505060208401805163ffffffff808216909652600401909416909352505050565b6000612034836120cb565b600384161561204257600080fd5b6020830192601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b8110156120c05760208601953582821c600116801561209057600181146120a5576120b6565b600085815260208390526040902094506120b6565b600082815260208690526040902094505b5050600101612068565b509095945050505050565b366103808201811015612160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f617461000000000000000000000000000000000000000000000000000000000060648201526084016112c6565b5050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915261016081016121ca6121cf565b905290565b6040518061040001604052806020906020820280368337509192915050565b600060208083528351808285015260005b8181101561221b578581018301518582016040015282016121ff565b8181111561222d576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60008083601f84011261227357600080fd5b50813567ffffffffffffffff81111561228b57600080fd5b60208301915083602082850101111561124357600080fd5b6000806000806000606086880312156122bb57600080fd5b853567ffffffffffffffff808211156122d357600080fd5b6122df89838a01612261565b909750955060208801359150808211156122f857600080fd5b5061230588828901612261565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561235957600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a"; + hex"608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d50146100465780637dc0d1d014610098578063e14ced32146100dc575b600080fd5b6100826040518060400160405280600c81526020017f312e312e312d626574612e32000000000000000000000000000000000000000081525081565b60405161008f91906121ee565b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007a9eab4ce99d157aee7a02e95b366e972a2d5b0b16815260200161008f565b6100ef6100ea3660046122a3565b6100fd565b60405190815260200161008f565b6000610107612164565b6080811461011457600080fd5b6040516106001461012457600080fd5b6084871461013157600080fd5b6101a4851461013f57600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a0819052605a89013590911c6101c05260628801906101e09060018111156101f5576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b506020810181511461020657600080fd5b60200160005b602081101561023057823560e01c825260049092019160209091019060010161020c565b5050508061012001511561024e576102466103a6565b91505061039d565b6101408101805160010167ffffffffffffffff16905260006101a49050600080600061028385606001518660000151866104f7565b9250925092508163ffffffff1660001480156102a557508063ffffffff16600c145b156102bf576102b387610521565b9550505050505061039d565b6000610339866040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b6101608701518751919250610356918391906105248888886108f9565b8652805163ffffffff9081166060808901919091526020830151821660808901526040830151821660a08901528201511660c08701526103946103a6565b96505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a8401526000926102009290916062830191906001811115610453576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b60005b602081101561047a57601c8601518452602090950194600490930192600101610456565b506000835283830384a060009450806001811461049a57600395506104c2565b8280156104b257600181146104bb57600296506104c0565b600096506104c0565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b6000806000610507858786610cdf565b925050603f601a83901c8116915082165b93509350939050565b600061052b612164565b608090506000806000806105628561016001516040810151608082015160a083015160c084015160e0909401519294919390929091565b509350935093509350600080610ffa63ffffffff168663ffffffff16036105a75761059285858960e00151610d93565b63ffffffff1660e08a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03363ffffffff8716016105e05763400000009150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefe863ffffffff8716016106165760019150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef6a63ffffffff87160161066a57600161012088015260ff851661010088015261065d6103a6565b9998505050505050505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05d63ffffffff8716016107665760006040518061012001604052808763ffffffff1681526020018663ffffffff1681526020018563ffffffff16815260200189602001518152602001896040015163ffffffff1681526020018b81526020017f0000000000000000000000007a9eab4ce99d157aee7a02e95b366e972a2d5b0b73ffffffffffffffffffffffffffffffffffffffff1681526020016107386101a4600160ff16610380020190565b81528951602090910152905061074d81610e27565b8b5263ffffffff1660408b015290935091506108089050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05c63ffffffff8716016107cb57602087015160408801516107b1918791879187916105248d5161109f565b63ffffffff1660408b015260208a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff02963ffffffff871601610808576108028585611195565b90925090505b6000610882886040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b61016089015163ffffffff85811660408084019190915285821660e0909301929092526020830180518083168086526004909101831682526060808e01919091529051821660808d015291830151811660a08c0152908201511660c08a015290506108eb6103a6565b9a9950505050505050505050565b84600263ffffffff8416148061091557508263ffffffff166003145b156109675760006002856303ffffff1663ffffffff16901b896020015163f00000001617905061096189898663ffffffff1660021461095557601f610958565b60005b60ff168461124a565b50610cd4565b600080601f601087901c8116908a90601589901c166020811061098c5761098c612317565b602002015192508063ffffffff871615806109ad57508663ffffffff16601c145b156109df578a8263ffffffff16602081106109ca576109ca612317565b6020020151925050601f600b88901c16610a96565b60208763ffffffff161015610a41578663ffffffff16600c1480610a0957508663ffffffff16600d145b80610a1a57508663ffffffff16600e145b15610a2b578761ffff169250610a96565b610a3a8861ffff166010611322565b9250610a96565b60288763ffffffff16101580610a5d57508663ffffffff166022145b80610a6e57508663ffffffff166026145b15610a96578a8263ffffffff1660208110610a8b57610a8b612317565b602002015192508190505b60048763ffffffff1610158015610ab3575060088763ffffffff16105b80610ac457508663ffffffff166001145b15610ae057610ad78c8c898b8689611395565b50505050610cd4565b63ffffffff6000602089831610610b4557610b008a61ffff166010611322565b9095019463fffffffc8616610b168d828e610cdf565b915060288a63ffffffff1610158015610b3657508963ffffffff16603014155b15610b4357809250600093505b505b6000610b558b8b8b8a8a87611583565b63ffffffff1690508963ffffffff166000148015610b7a575060088963ffffffff1610155b8015610b8c5750601c8963ffffffff16105b15610c54578863ffffffff1660081480610bac57508863ffffffff166009145b15610bdf57610bd38f8f8b63ffffffff16600814610bca5786610bcd565b60005b8a61124a565b50505050505050610cd4565b8863ffffffff16600a03610c0157610bd38f8f868a63ffffffff8b1615611ca0565b8863ffffffff16600b03610c2457610bd38f8f868a63ffffffff8b161515611ca0565b60108963ffffffff1610158015610c415750601c8963ffffffff16105b15610c5457610bd38f8f8b8a8a89611d70565b8963ffffffff166038148015610c6f575063ffffffff851615155b15610c9f5760018e8663ffffffff1660208110610c8e57610c8e612317565b63ffffffff90921660209290920201525b8263ffffffff1663ffffffff14610cbe57610cbb838d83612029565b97505b610ccc8f8f86846001611ca0565b505050505050505b979650505050505050565b6000610cea826120cb565b6003831615610cf857600080fd5b6020820191358360051c8160005b601b811015610d5e5760208601953583821c6001168015610d2e5760018114610d4357610d54565b60008481526020839052604090209350610d54565b600082815260208590526040902093505b5050600101610d06565b50868114610d7457630badf00d60005260206000fd5b5050601f93909316601c0360031b9290921c63ffffffff169392505050565b6000808284610fff811615610dad57610fff811661100003015b8663ffffffff16600003610e195784935090810190636000000063ffffffff83161180610de557508463ffffffff168263ffffffff16105b80610dfb57508563ffffffff168163ffffffff16105b15610e14575063ffffffff925060169150839050610518565b610e1d565b8693505b5093509350939050565b6101008101516080820151825160009283929163ffffffff161561109857845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb01611052576000610e93866101000151876020015163fffffffc168860e00151610cdf565b606087015190915060001a600103610f1557610f0f86606001518760a0015160408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b60608701525b6000808760c0015173ffffffffffffffffffffffffffffffffffffffff1663e03110e189606001518a608001516040518363ffffffff1660e01b8152600401610f6e92919091825263ffffffff16602082015260400190565b6040805180830381865afa158015610f8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fae9190612346565b60208a015160408b01519294509092509060038216600481900384811015610fd4578094505b5083821015610fe1578193505b8460088502610100031c9450846008828660040303021b9450600180600883600403021b036001806008878560040303021b0391508119811690508581198816179650505061103f8a6020015163fffffffc168b60e0015187612029565b9298505050938601939250611098915050565b845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0161108c5784604001519350611098565b63ffffffff9350600992505b9193509193565b600080858563ffffffff8b16600114806110bf575063ffffffff8b166002145b806110d0575063ffffffff8b166004145b156110dd57889350611187565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8c160161117b57600061111d868c63fffffffc1689610cdf565b90508860038c166004038b81101561113357809b505b8b965086900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193880293841b0116911b17915060009050611187565b63ffffffff9350600992505b975097509750979350505050565b60008063ffffffff83166003036112385763ffffffff841615806111bf575063ffffffff84166005145b806111d0575063ffffffff84166003145b156111de5760009150611243565b63ffffffff8416600114806111f9575063ffffffff84166002145b8061120a575063ffffffff84166006145b8061121b575063ffffffff84166004145b156112295760019150611243565b5063ffffffff90506009611243565b5063ffffffff905060165b9250929050565b836000015160040163ffffffff16846020015163ffffffff16146112cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b835160208501805163ffffffff908116875283811690915283161561131b5780600801848463ffffffff166020811061130a5761130a612317565b63ffffffff90921660209290920201525b5050505050565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b018261137f576000611381565b815b90861663ffffffff16179250505092915050565b6000866000015160040163ffffffff16876020015163ffffffff1614611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f7400000000000000000000000060448201526064016112c6565b8463ffffffff166004148061143257508463ffffffff166005145b156114a9576000868463ffffffff166020811061145157611451612317565b602002015190508063ffffffff168363ffffffff1614801561147957508563ffffffff166004145b806114a157508063ffffffff168363ffffffff16141580156114a157508563ffffffff166005145b915050611526565b8463ffffffff166006036114c65760008260030b13159050611526565b8463ffffffff166007036114e25760008260030b139050611526565b8463ffffffff1660010361152657601f601085901c16600081900361150b5760008360030b1291505b8063ffffffff166001036115245760008360030b121591505b505b8651602088015163ffffffff168852811561156757600261154c8661ffff166010611322565b63ffffffff90811690911b8201600401166020890152611579565b60208801805160040163ffffffff1690525b5050505050505050565b600063ffffffff861615806115b0575060088663ffffffff16101580156115b05750600f8663ffffffff16105b156119b05785600881146115f357600981146115fc57600a811461160557600b811461160e57600c811461161757600d811461162057600e81146116295761162e565b6020955061162e565b6021955061162e565b602a955061162e565b602b955061162e565b6024955061162e565b6025955061162e565b602695505b508463ffffffff16600003611653575063ffffffff8216601f600688901c161b611c96565b8463ffffffff16600203611677575063ffffffff8216601f600688901c161c611c96565b8463ffffffff166003036116ab57601f600688901c166116a363ffffffff8516821c6020839003611322565b915050611c96565b8463ffffffff166004036116cb575063ffffffff8216601f84161b611c96565b8463ffffffff166006036116eb575063ffffffff8216601f84161c611c96565b8463ffffffff1660070361171357601f84166116a363ffffffff8516821c6020839003611322565b8463ffffffff16600803611728575082611c96565b8463ffffffff1660090361173d575082611c96565b8463ffffffff16600a03611752575082611c96565b8463ffffffff16600b03611767575082611c96565b8463ffffffff16600c0361177c575082611c96565b8463ffffffff16600f03611791575082611c96565b8463ffffffff166010036117a6575082611c96565b8463ffffffff166011036117bb575082611c96565b8463ffffffff166012036117d0575082611c96565b8463ffffffff166013036117e5575082611c96565b8463ffffffff166018036117fa575082611c96565b8463ffffffff1660190361180f575082611c96565b8463ffffffff16601a03611824575082611c96565b8463ffffffff16601b03611839575082611c96565b8463ffffffff166020036118505750828201611c96565b8463ffffffff166021036118675750828201611c96565b8463ffffffff1660220361187e5750818303611c96565b8463ffffffff166023036118955750818303611c96565b8463ffffffff166024036118ac5750828216611c96565b8463ffffffff166025036118c35750828217611c96565b8463ffffffff166026036118da5750828218611c96565b8463ffffffff166027036118f2575082821719611c96565b8463ffffffff16602a03611921578260030b8460030b12611914576000611917565b60015b60ff169050611c96565b8463ffffffff16602b03611949578263ffffffff168463ffffffff1610611914576000611917565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e0000000000000000000000000060448201526064016112c6565b611949565b8563ffffffff16601c03611a30578463ffffffff166002036119d55750828202611c96565b8463ffffffff16602014806119f057508463ffffffff166021145b156119ab578463ffffffff16602003611a07579219925b60005b6380000000851615611a29576401fffffffe600195861b169401611a0a565b9050611c96565b8563ffffffff16600f03611a51575065ffffffff0000601083901b16611c96565b8563ffffffff16602003611a8557611a298460031660080260180363ffffffff168363ffffffff16901c60ff166008611322565b8563ffffffff16602103611aba57611a298460021660080260100363ffffffff168363ffffffff16901c61ffff166010611322565b8563ffffffff16602203611ae8575063ffffffff60086003851602811681811b198416918316901b17611c96565b8563ffffffff16602303611afd575080611c96565b8563ffffffff16602403611b2e578360031660080260180363ffffffff168263ffffffff16901c60ff169050611c96565b8563ffffffff16602503611b60578360021660080260100363ffffffff168263ffffffff16901c61ffff169050611c96565b8563ffffffff16602603611b91575063ffffffff60086003851602601803811681811c198416918316901c17611c96565b8563ffffffff16602803611bc6575060ff63ffffffff60086003861602601803811682811b9091188316918416901b17611c96565b8563ffffffff16602903611bfc575061ffff63ffffffff60086002861602601003811682811b9091188316918416901b17611c96565b8563ffffffff16602a03611c2a575063ffffffff60086003851602811681811c198316918416901c17611c96565b8563ffffffff16602b03611c3f575081611c96565b8563ffffffff16602e03611c70575063ffffffff60086003851602601803811681811b198316918416901b17611c96565b8563ffffffff16603003611c85575080611c96565b8563ffffffff166038036119495750815b9695505050505050565b60208363ffffffff1610611d10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c696420726567697374657200000000000000000000000000000000000060448201526064016112c6565b63ffffffff831615801590611d225750805b15611d515781848463ffffffff1660208110611d4057611d40612317565b63ffffffff90921660209290920201525b5050505060208101805163ffffffff8082169093526004019091169052565b60008463ffffffff16601003611d8b57506060860151611fd1565b8463ffffffff16601103611daa5763ffffffff84166060880152611fd1565b8463ffffffff16601203611dc357506040860151611fd1565b8463ffffffff16601303611de25763ffffffff84166040880152611fd1565b8463ffffffff16601803611e165763ffffffff600385810b9085900b02602081901c821660608a0152166040880152611fd1565b8463ffffffff16601903611e475763ffffffff84811681851602602081901c821660608a0152166040880152611fd1565b8463ffffffff16601a03611f0a578260030b600003611ec2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8260030b8460030b81611ed757611ed761236a565b0763ffffffff166060880152600383810b9085900b81611ef957611ef961236a565b0563ffffffff166040880152611fd1565b8463ffffffff16601b03611fd1578263ffffffff16600003611f88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8263ffffffff168463ffffffff1681611fa357611fa361236a565b0663ffffffff908116606089015283811690851681611fc457611fc461236a565b0463ffffffff1660408801525b63ffffffff8216156120075780868363ffffffff1660208110611ff657611ff6612317565b63ffffffff90921660209290920201525b50505060208401805163ffffffff808216909652600401909416909352505050565b6000612034836120cb565b600384161561204257600080fd5b6020830192601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b8110156120c05760208601953582821c600116801561209057600181146120a5576120b6565b600085815260208390526040902094506120b6565b600082815260208690526040902094505b5050600101612068565b509095945050505050565b366103808201811015612160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f617461000000000000000000000000000000000000000000000000000000000060648201526084016112c6565b5050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915261016081016121ca6121cf565b905290565b6040518061040001604052806020906020820280368337509192915050565b600060208083528351808285015260005b8181101561221b578581018301518582016040015282016121ff565b8181111561222d576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60008083601f84011261227357600080fd5b50813567ffffffffffffffff81111561228b57600080fd5b60208301915083602082850101111561124357600080fd5b6000806000806000606086880312156122bb57600080fd5b853567ffffffffffffffff808211156122d357600080fd5b6122df89838a01612261565b909750955060208801359150808211156122f857600080fd5b5061230588828901612261565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561235957600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a"; bytes internal constant anchorStateRegistryCode = - hex"608060405234801561001057600080fd5b506004361061007d5760003560e01c80635e05fbd01161005b5780635e05fbd01461012a5780637258a8071461013d578063838c2d1e14610179578063f2b4e6171461018157600080fd5b806317cf21a91461008257806335e80ab31461009757806354fd4d50146100e1575b600080fd5b610095610090366004610b4c565b6101a7565b005b6002546100b79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61011d6040518060400160405280600c81526020017f322e302e312d626574612e31000000000000000000000000000000000000000081525081565b6040516100d89190610bea565b610095610138366004610cc6565b61061c565b61016461014b366004610df0565b6001602081905260009182526040909120805491015482565b604080519283526020830191909152016100d8565b610095610853565b7f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d6100b7565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610214573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102389190610e0d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461029c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156102ec573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526103329190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161039793929190610efb565b6040805180830381865afa1580156103b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d79190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043f576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561048c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b09190610f9f565b60028111156104c1576104c1610f70565b146104f8576040517f8f8af25f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806105788773ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610551573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105759190610fc0565b90565b81526020018673ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ec9190610fc0565b905263ffffffff909416600090815260016020818152604090922086518155959091015194019390935550505050565b600054610100900460ff161580801561063c5750600054600160ff909116105b806106565750303b158015610656575060005460ff166001145b6106e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561074457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60005b83518110156107aa57600084828151811061076457610764610fd9565b60209081029190910181015180820151905163ffffffff1660009081526001808452604090912082518155919092015191015550806107a281611008565b915050610747565b50600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055801561084e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600033905060008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108a8573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526108ee9190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161095393929190610efb565b6040805180830381865afa15801561096f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109939190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109fb576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160008563ffffffff1663ffffffff168152602001908152602001600020600101548573ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8d9190610fc0565b11610a99575050505050565b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ae6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0a9190610f9f565b6002811115610b1b57610b1b610f70565b146104f8575050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4957600080fd5b50565b600060208284031215610b5e57600080fd5b8135610b6981610b27565b9392505050565b60005b83811015610b8b578181015183820152602001610b73565b83811115610b9a576000848401525b50505050565b60008151808452610bb8816020860160208601610b70565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610b696020830184610ba0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610c4f57610c4f610bfd565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610c9c57610c9c610bfd565b604052919050565b63ffffffff81168114610b4957600080fd5b8035610cc181610b27565b919050565b6000806040808486031215610cda57600080fd5b833567ffffffffffffffff80821115610cf257600080fd5b818601915086601f830112610d0657600080fd5b8135602082821115610d1a57610d1a610bfd565b610d28818360051b01610c55565b8281528181019350606092830285018201928a841115610d4757600080fd5b948201945b83861015610dd457858b0381811215610d655760008081fd5b610d6d610c2c565b8735610d7881610ca4565b81527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201891315610daa5760008081fd5b610db2610c2c565b8886013581528989013586820152818601528652509485019493820193610d4c565b509650610de2888201610cb6565b955050505050509250929050565b600060208284031215610e0257600080fd5b8135610b6981610ca4565b600060208284031215610e1f57600080fd5b8151610b6981610b27565b600080600060608486031215610e3f57600080fd5b8351610e4a81610ca4565b60208501516040860151919450925067ffffffffffffffff80821115610e6f57600080fd5b818601915086601f830112610e8357600080fd5b815181811115610e9557610e95610bfd565b610ec660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610c55565b9150808252876020828501011115610edd57600080fd5b610eee816020840160208601610b70565b5080925050509250925092565b63ffffffff84168152826020820152606060408201526000610f206060830184610ba0565b95945050505050565b60008060408385031215610f3c57600080fd5b8251610f4781610b27565b602084015190925067ffffffffffffffff81168114610f6557600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060208284031215610fb157600080fd5b815160038110610b6957600080fd5b600060208284031215610fd257600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611060577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea164736f6c634300080f000a"; + hex"608060405234801561001057600080fd5b506004361061007d5760003560e01c80635e05fbd01161005b5780635e05fbd01461012a5780637258a8071461013d578063838c2d1e14610179578063f2b4e6171461018157600080fd5b806317cf21a91461008257806335e80ab31461009757806354fd4d50146100e1575b600080fd5b610095610090366004610b4c565b6101a7565b005b6002546100b79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61011d6040518060400160405280600c81526020017f322e302e312d626574612e32000000000000000000000000000000000000000081525081565b6040516100d89190610bea565b610095610138366004610cc6565b61061c565b61016461014b366004610df0565b6001602081905260009182526040909120805491015482565b604080519283526020830191909152016100d8565b610095610853565b7f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d6100b7565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610214573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102389190610e0d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461029c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156102ec573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526103329190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161039793929190610efb565b6040805180830381865afa1580156103b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d79190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043f576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561048c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b09190610f9f565b60028111156104c1576104c1610f70565b146104f8576040517f8f8af25f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806105788773ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610551573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105759190610fc0565b90565b81526020018673ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ec9190610fc0565b905263ffffffff909416600090815260016020818152604090922086518155959091015194019390935550505050565b600054610100900460ff161580801561063c5750600054600160ff909116105b806106565750303b158015610656575060005460ff166001145b6106e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561074457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60005b83518110156107aa57600084828151811061076457610764610fd9565b60209081029190910181015180820151905163ffffffff1660009081526001808452604090912082518155919092015191015550806107a281611008565b915050610747565b50600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055801561084e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600033905060008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108a8573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526108ee9190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161095393929190610efb565b6040805180830381865afa15801561096f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109939190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109fb576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160008563ffffffff1663ffffffff168152602001908152602001600020600101548573ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8d9190610fc0565b11610a99575050505050565b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ae6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0a9190610f9f565b6002811115610b1b57610b1b610f70565b146104f8575050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4957600080fd5b50565b600060208284031215610b5e57600080fd5b8135610b6981610b27565b9392505050565b60005b83811015610b8b578181015183820152602001610b73565b83811115610b9a576000848401525b50505050565b60008151808452610bb8816020860160208601610b70565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610b696020830184610ba0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610c4f57610c4f610bfd565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610c9c57610c9c610bfd565b604052919050565b63ffffffff81168114610b4957600080fd5b8035610cc181610b27565b919050565b6000806040808486031215610cda57600080fd5b833567ffffffffffffffff80821115610cf257600080fd5b818601915086601f830112610d0657600080fd5b8135602082821115610d1a57610d1a610bfd565b610d28818360051b01610c55565b8281528181019350606092830285018201928a841115610d4757600080fd5b948201945b83861015610dd457858b0381811215610d655760008081fd5b610d6d610c2c565b8735610d7881610ca4565b81527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201891315610daa5760008081fd5b610db2610c2c565b8886013581528989013586820152818601528652509485019493820193610d4c565b509650610de2888201610cb6565b955050505050509250929050565b600060208284031215610e0257600080fd5b8135610b6981610ca4565b600060208284031215610e1f57600080fd5b8151610b6981610b27565b600080600060608486031215610e3f57600080fd5b8351610e4a81610ca4565b60208501516040860151919450925067ffffffffffffffff80821115610e6f57600080fd5b818601915086601f830112610e8357600080fd5b815181811115610e9557610e95610bfd565b610ec660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610c55565b9150808252876020828501011115610edd57600080fd5b610eee816020840160208601610b70565b5080925050509250925092565b63ffffffff84168152826020820152606060408201526000610f206060830184610ba0565b95945050505050565b60008060408385031215610f3c57600080fd5b8251610f4781610b27565b602084015190925067ffffffffffffffff81168114610f6557600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060208284031215610fb157600080fd5b815160038110610b6957600080fd5b600060208284031215610fd257600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611060577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea164736f6c634300080f000a"; bytes internal constant acc33Code = - hex"6080604052600436106102f25760003560e01c806370872aa51161018f578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b18578063fa315aa914610b3c578063fe2bbeb214610b6f57600080fd5b8063ec5e630814610a95578063eff0f59214610ac8578063f8f43ff614610af857600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a0f578063d8cc1a3c14610a42578063dabd396d14610a6257600080fd5b8063c6f0308c14610937578063cf09e0d0146109c1578063d5d44d80146109e257600080fd5b80638d450a9511610143578063bcef3b551161011d578063bcef3b55146108b7578063bd8da956146108f7578063c395e1ca1461091757600080fd5b80638d450a9514610777578063a445ece6146107aa578063bbdc02db1461087657600080fd5b80638129fc1c116101745780638129fc1c1461071a5780638980e0cc146107225780638b85902b1461073757600080fd5b806370872aa5146106f25780637b0f0adc1461070757600080fd5b80633fc8cef3116102485780635c0cba33116101fc5780636361506d116101d65780636361506d1461066c5780636b6716c0146106ac5780636f034409146106df57600080fd5b80635c0cba3314610604578063609d33341461063757806360e274641461064c57600080fd5b806354fd4d501161022d57806354fd4d501461055e57806357da950e146105b45780635a5fa2d9146105e457600080fd5b80633fc8cef314610518578063472777c61461054b57600080fd5b80632810e1d6116102aa57806337b1b2291161028457806337b1b229146104655780633a768463146104a55780633e3ac912146104d857600080fd5b80632810e1d6146103de5780632ad69aeb146103f357806330dbe5701461041357600080fd5b806319effeb4116102db57806319effeb414610339578063200d2ed21461038457806325fc2ace146103bf57600080fd5b806301935130146102f757806303c2924d14610319575b600080fd5b34801561030357600080fd5b506103176103123660046154e2565b610b9f565b005b34801561032557600080fd5b5061031761033436600461553d565b610ec0565b34801561034557600080fd5b506000546103669068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561039057600080fd5b506000546103b290700100000000000000000000000000000000900460ff1681565b60405161037b919061558e565b3480156103cb57600080fd5b506008545b60405190815260200161037b565b3480156103ea57600080fd5b506103b2611566565b3480156103ff57600080fd5b506103d061040e36600461553d565b61180b565b34801561041f57600080fd5b506001546104409073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161037b565b34801561047157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610440565b3480156104b157600080fd5b507f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe7806610440565b3480156104e457600080fd5b50600054610508907201000000000000000000000000000000000000900460ff1681565b604051901515815260200161037b565b34801561052457600080fd5b507f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92610440565b6103176105593660046155cf565b611841565b34801561056a57600080fd5b506105a76040518060400160405280600a81526020017f312e332e302d72632e310000000000000000000000000000000000000000000081525081565b60405161037b9190615666565b3480156105c057600080fd5b506008546009546105cf919082565b6040805192835260208301919091520161037b565b3480156105f057600080fd5b506103d06105ff366004615679565b611853565b34801561061057600080fd5b507f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e610440565b34801561064357600080fd5b506105a761188d565b34801561065857600080fd5b506103176106673660046156b7565b61189b565b34801561067857600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103d0565b3480156106b857600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610366565b6103176106ed3660046156e9565b611a42565b3480156106fe57600080fd5b506009546103d0565b6103176107153660046155cf565b61251b565b610317612528565b34801561072e57600080fd5b506002546103d0565b34801561074357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103d0565b34801561078357600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103d0565b3480156107b657600080fd5b506108226107c5366004615679565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff16606082015260800161037b565b34801561088257600080fd5b5060405163ffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260200161037b565b3480156108c357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103d0565b34801561090357600080fd5b50610366610912366004615679565b612a81565b34801561092357600080fd5b506103d0610932366004615728565b612c60565b34801561094357600080fd5b50610957610952366004615679565b612e43565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e00161037b565b3480156109cd57600080fd5b506000546103669067ffffffffffffffff1681565b3480156109ee57600080fd5b506103d06109fd3660046156b7565b60036020526000908152604090205481565b348015610a1b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000003856103d0565b348015610a4e57600080fd5b50610317610a5d36600461575a565b612eda565b348015610a6e57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b0610366565b348015610aa157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000046103d0565b348015610ad457600080fd5b50610508610ae3366004615679565b60046020526000908152604090205460ff1681565b348015610b0457600080fd5b50610317610b133660046155cf565b613509565b348015610b2457600080fd5b50610b2d6139c6565b60405161037b939291906157e4565b348015610b4857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000086103d0565b348015610b7b57600080fd5b50610508610b8a366004615679565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610bcb57610bcb61555f565b14610c02576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610c55576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610ca3610c9e36869003860186615838565b613a41565b14610cda576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610cef9291906158c5565b604051809103902014610d2e576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d77610d7284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613a9d92505050565b613b0a565b90506000610d9e82600881518110610d9157610d916158d5565b6020026020010151613cc0565b9050602081511115610ddc576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610e51576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610eec57610eec61555f565b14610f23576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610f3857610f386158d5565b906000526020600020906005020190506000610f5384612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b081169082161015610fbc576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611005576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561102257508515155b156110bd578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110555781611071565b600186015473ffffffffffffffffffffffffffffffffffffffff165b905061107d8187613d74565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff166060830152611160576fffffffffffffffffffffffffffffffff6040820152600181526000869003611160578195505b600086826020015163ffffffff166111789190615933565b90506000838211611189578161118b565b835b602084015190915063ffffffff165b818110156112d75760008682815481106111b6576111b66158d5565b6000918252602080832090910154808352600690915260409091205490915060ff1661120e576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611223576112236158d5565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112805750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b156112c257600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b505080806112cf9061594b565b91505061119a565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921790915584900361155b57606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558915801561145757506000547201000000000000000000000000000000000000900460ff165b156114cc5760015473ffffffffffffffffffffffffffffffffffffffff1661147f818a613d74565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff909116178855611559565b61151373ffffffffffffffffffffffffffffffffffffffff8216156114f1578161150d565b600189015473ffffffffffffffffffffffffffffffffffffffff165b89613d74565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff1660028111156115945761159461555f565b146115cb576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff1661162f576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008154811061165b5761165b6158d5565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611696576001611699565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff9091161770010000000000000000000000000000000083600281111561174a5761174a61555f565b02179055600281111561175f5761175f61555f565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e73ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156117f057600080fd5b505af1158015611804573d6000803e3d6000fd5b5050505090565b6005602052816000526040600020818154811061182757600080fd5b90600052602060002001600091509150505481565b905090565b61184e8383836001611a42565b505050565b6000818152600760209081526040808320600590925282208054825461188490610100900463ffffffff1682615983565b95945050505050565b606061183c60546020613e75565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260036020526040812080549082905590819003611900576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169063f3fef3a390604401600060405180830381600087803b15801561199057600080fd5b505af11580156119a4573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a02576040519150601f19603f3d011682016040523d82523d6000602084013e611a07565b606091505b505090508061184e576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008054700100000000000000000000000000000000900460ff166002811115611a6e57611a6e61555f565b14611aa5576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110611aba57611aba6158d5565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514611ba1576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000611c61826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580611c9c5750611c997f00000000000000000000000000000000000000000000000000000000000000046002615933565b81145b8015611ca6575084155b15611cdd576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015611d03575086155b15611d3a576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000008811115611d94576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dbf7f00000000000000000000000000000000000000000000000000000000000000046001615933565b8103611dd157611dd186888588613ec7565b34611ddb83612c60565b14611e12576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611e1d88612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b0811690821603611e85576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611eb260017f0000000000000000000000000000000000000000000000000000000000000008615983565b8303611ff0577f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f47919061599a565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb591906159b7565b611fe9907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166159d0565b9050612083565b61201b60017f0000000000000000000000000000000000000000000000000000000000000004615983565b830361205657611fe97f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1660026159fc565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b6120b7817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b67ffffffffffffffff166120d28367ffffffffffffffff1690565b67ffffffffffffffff16111561211957612116817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615612197576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c8152602001908152602001600020600160028054905061242d9190615983565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169263d0e30db09234926004808301939282900301818588803b1580156124c557600080fd5b505af11580156124d9573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b61184e8383836000611a42565b60005471010000000000000000000000000000000000900460ff161561257a576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e1690637258a807906024016040805180830381865afa15801561262e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126529190615a55565b90925090508161268e576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a146126c157639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401351161275b576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd929092169363d0e30db093926004828101939282900301818588803b158015612a3057600080fd5b505af1158015612a44573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b600080600054700100000000000000000000000000000000900460ff166002811115612aaf57612aaf61555f565b14612ae6576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110612afb57612afb6158d5565b600091825260208220600590910201805490925063ffffffff90811614612b6a57815460028054909163ffffffff16908110612b3957612b396158d5565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090612ba290700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b612bb69067ffffffffffffffff1642615983565b612bd5612b95846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16612be99190615933565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b01667ffffffffffffffff168167ffffffffffffffff1611612c365780611884565b7f00000000000000000000000000000000000000000000000000000000000004b095945050505050565b600080612cff836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000008811115612d5e576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000612d798383615aa8565b9050670de0b6b3a76400006000612db0827f0000000000000000000000000000000000000000000000000000000000000008615abc565b90506000612dce612dc9670de0b6b3a764000086615abc565b614078565b90506000612ddc84846142d3565b90506000612dea8383614322565b90506000612df782614350565b90506000612e1682612e11670de0b6b3a76400008f615abc565b614538565b90506000612e248b83614322565b9050612e30818d615abc565b9f9e505050505050505050505050505050565b60028181548110612e5357600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b60008054700100000000000000000000000000000000900460ff166002811115612f0657612f0661555f565b14612f3d576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028781548110612f5257612f526158d5565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b9050612fb17f00000000000000000000000000000000000000000000000000000000000000086001615933565b61304d826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1614613087576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561317e576130da7f00000000000000000000000000000000000000000000000000000000000000047f0000000000000000000000000000000000000000000000000000000000000008615983565b6001901b6130f9846fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff166131159190615af9565b156131525761314961313a60016fffffffffffffffffffffffffffffffff8716615b0d565b865463ffffffff166000614608565b60030154613174565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506131a8565b600385015491506131a561313a6fffffffffffffffffffffffffffffffff86166001615b36565b90505b600882901b60088a8a6040516131bf9291906158c5565b6040518091039020901b14613200576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061320b8c6146ec565b9050600061321a836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff169063e14ced3290613294908f908f908f908f908a90600401615baa565b6020604051808303816000875af11580156132b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d791906159b7565b600485015491149150600090600290613382906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b61341e896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6134289190615be4565b6134329190615c07565b60ff161590508115158103613473576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156134ca576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff1660028111156135355761353561555f565b1461356c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061357b8661471b565b9350935093509350600061359185858585614b24565b905060007f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015613600573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613624919061599a565b90506001890361371c5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a84613680367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af11580156136f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061371691906159b7565b5061155b565b600289036137485773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8489613680565b600389036137745773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8487613680565b600489036138fb5760006137ba6fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000004614bde565b6009546137c79190615933565b6137d2906001615933565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061383b57367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036054013561383d565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156138d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f491906159b7565b505061155b565b60058903613994576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000038560c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016136d3565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060613a1f61188d565b9050909192565b600081831015613a365781613a38565b825b90505b92915050565b60008160000151826020015183604001518460600151604051602001613a80949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003613aec576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000613b1a85614c8c565b919450925090506001816001811115613b3557613b3561555f565b14613b6c576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451613b788385615933565b14613baf576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081613bc65790505093506000835b8651811015613cb457600080613c396040518060400160405280858c60000151613c1d9190615983565b8152602001858c60200151613c329190615933565b9052614c8c565b509150915060405180604001604052808383613c559190615933565b8152602001848b60200151613c6a9190615933565b815250888581518110613c7f57613c7f6158d5565b6020908102919091010152613c95600185615933565b9350613ca18183615933565b613cab9084615933565b92505050613bf3565b50845250919392505050565b60606000806000613cd085614c8c565b919450925090506000816001811115613ceb57613ceb61555f565b14613d22576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613d2c8284615933565b855114613d65576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118848560200151848461512a565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff90931692839290613dc3908490615933565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd921690637eee288d90604401600060405180830381600087803b158015613e5857600080fd5b505af1158015613e6c573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b6000613ee66fffffffffffffffffffffffffffffffff84166001615b36565b90506000613ef682866001614608565b9050600086901a8380613fe25750613f2f60027f0000000000000000000000000000000000000000000000000000000000000004615af9565b6004830154600290613fd3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b613fdd9190615c07565b60ff16145b1561403a5760ff811660011480613ffc575060ff81166002145b614035576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b613e6c565b60ff811615613e6c576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b17600082136140d757631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a76400000215820261431057637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b6000816000190483118202156143405763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d7821361437e57919050565b680755bf798b4a1bf1e5821261439c5763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000613a38670de0b6b3a76400008361455086614078565b61455a9190615c29565b6145649190615ce5565b614350565b6000806145f6837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826146515761464c6fffffffffffffffffffffffffffffffff86167f00000000000000000000000000000000000000000000000000000000000000046151bf565b61466c565b61466c856fffffffffffffffffffffffffffffffff1661534b565b905060028481548110614681576146816158d5565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff8281169116146146e457815460028054909163ffffffff169081106146cf576146cf6158d5565b90600052602060002090600502019150614692565b509392505050565b60008060008060006146fd8661471b565b935093509350935061471184848484614b24565b9695505050505050565b600080600080600085905060006002828154811061473b5761473b6158d5565b600091825260209091206004600590920201908101549091507f000000000000000000000000000000000000000000000000000000000000000490614812906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff161161484c576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f000000000000000000000000000000000000000000000000000000000000000490614913906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16925082111561498857825463ffffffff166149527f00000000000000000000000000000000000000000000000000000000000000046001615933565b830361495c578391505b6002818154811061496f5761496f6158d5565b9060005260206000209060050201935080945050614850565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149f16149dc856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff161490508015614ac0576000614a29836fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff161115614a94576000614a6b614a6360016fffffffffffffffffffffffffffffffff8616615b0d565b896001614608565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a50614a9a9050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614b16565b6000614ae2614a636fffffffffffffffffffffffffffffffff85166001615b36565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614b915760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611884565b8282604051602001614bbf9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614c6b847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614ccf576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614cf4576000600160009450945094505050615123565b60b78111614e0a576000614d09608083615983565b905080876000015111614d48576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614dc057507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614df7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060019550935060009250615123915050565b60bf8111614f68576000614e1f60b783615983565b905080876000015111614e5e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614ec0576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614f08576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f128184615933565b895111614f4b576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f56836001615933565b97509550600094506151239350505050565b60f78111614fcd576000614f7d60c083615983565b905080876000015111614fbc576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600195509350849250615123915050565b6000614fda60f783615983565b905080876000015111615019576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361507b576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116150c3576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6150cd8184615933565b895111615106576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615111836001615933565b97509550600194506151239350505050565b9193909250565b60608167ffffffffffffffff81111561514557615145615809565b6040519080825280601f01601f19166020018201604052801561516f576020820181803683370190505b50905081156151b85760006151848486615933565b90506020820160005b848110156151a557828101518282015260200161518d565b848111156151b4576000858301525b5050505b9392505050565b60008161525e846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116152745763b34b5c226000526004601cfd5b61527d8361534b565b90508161531c826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611613a3b57613a38615332836001615933565b6fffffffffffffffffffffffffffffffff8316906153f0565b600081196001830116816153df827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b60008061547d847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f8401126154ab57600080fd5b50813567ffffffffffffffff8111156154c357600080fd5b6020830191508360208285010111156154db57600080fd5b9250929050565b600080600083850360a08112156154f857600080fd5b608081121561550657600080fd5b50839250608084013567ffffffffffffffff81111561552457600080fd5b61553086828701615499565b9497909650939450505050565b6000806040838503121561555057600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106155c9577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806000606084860312156155e457600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561562157602081850181015186830182015201615605565b81811115615633576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000613a3860208301846155fb565b60006020828403121561568b57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146156b457600080fd5b50565b6000602082840312156156c957600080fd5b81356151b881615692565b803580151581146156e457600080fd5b919050565b600080600080608085870312156156ff57600080fd5b84359350602085013592506040850135915061571d606086016156d4565b905092959194509250565b60006020828403121561573a57600080fd5b81356fffffffffffffffffffffffffffffffff811681146151b857600080fd5b6000806000806000806080878903121561577357600080fd5b86359550615783602088016156d4565b9450604087013567ffffffffffffffff808211156157a057600080fd5b6157ac8a838b01615499565b909650945060608901359150808211156157c557600080fd5b506157d289828a01615499565b979a9699509497509295939492505050565b63ffffffff8416815282602082015260606040820152600061188460608301846155fb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006080828403121561584a57600080fd5b6040516080810181811067ffffffffffffffff82111715615894577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561594657615946615904565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361597c5761597c615904565b5060010190565b60008282101561599557615995615904565b500390565b6000602082840312156159ac57600080fd5b81516151b881615692565b6000602082840312156159c957600080fd5b5051919050565b600067ffffffffffffffff8083168185168083038211156159f3576159f3615904565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615a2357615a23615904565b02949350505050565b600067ffffffffffffffff83811690831681811015615a4d57615a4d615904565b039392505050565b60008060408385031215615a6857600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615ab757615ab7615a79565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615af457615af4615904565b500290565b600082615b0857615b08615a79565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615a4d57615a4d615904565b60006fffffffffffffffffffffffffffffffff8083168185168083038211156159f3576159f3615904565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615bbe606083018789615b61565b8281036020840152615bd1818688615b61565b9150508260408301529695505050505050565b600060ff821660ff841680821015615bfe57615bfe615904565b90039392505050565b600060ff831680615c1a57615c1a615a79565b8060ff84160691505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615c6a57615c6a615904565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615ca557615ca5615904565b60008712925087820587128484161615615cc157615cc1615904565b87850587128184161615615cd757615cd7615904565b505050929093029392505050565b600082615cf457615cf4615a79565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615d4857615d48615904565b50059056fea164736f6c634300080f000a"; + hex"6080604052600436106102f25760003560e01c806370872aa51161018f578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b18578063fa315aa914610b3c578063fe2bbeb214610b6f57600080fd5b8063ec5e630814610a95578063eff0f59214610ac8578063f8f43ff614610af857600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a0f578063d8cc1a3c14610a42578063dabd396d14610a6257600080fd5b8063c6f0308c14610937578063cf09e0d0146109c1578063d5d44d80146109e257600080fd5b80638d450a9511610143578063bcef3b551161011d578063bcef3b55146108b7578063bd8da956146108f7578063c395e1ca1461091757600080fd5b80638d450a9514610777578063a445ece6146107aa578063bbdc02db1461087657600080fd5b80638129fc1c116101745780638129fc1c1461071a5780638980e0cc146107225780638b85902b1461073757600080fd5b806370872aa5146106f25780637b0f0adc1461070757600080fd5b80633fc8cef3116102485780635c0cba33116101fc5780636361506d116101d65780636361506d1461066c5780636b6716c0146106ac5780636f034409146106df57600080fd5b80635c0cba3314610604578063609d33341461063757806360e274641461064c57600080fd5b806354fd4d501161022d57806354fd4d501461055e57806357da950e146105b45780635a5fa2d9146105e457600080fd5b80633fc8cef314610518578063472777c61461054b57600080fd5b80632810e1d6116102aa57806337b1b2291161028457806337b1b229146104655780633a768463146104a55780633e3ac912146104d857600080fd5b80632810e1d6146103de5780632ad69aeb146103f357806330dbe5701461041357600080fd5b806319effeb4116102db57806319effeb414610339578063200d2ed21461038457806325fc2ace146103bf57600080fd5b806301935130146102f757806303c2924d14610319575b600080fd5b34801561030357600080fd5b506103176103123660046154e2565b610b9f565b005b34801561032557600080fd5b5061031761033436600461553d565b610ec0565b34801561034557600080fd5b506000546103669068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561039057600080fd5b506000546103b290700100000000000000000000000000000000900460ff1681565b60405161037b919061558e565b3480156103cb57600080fd5b506008545b60405190815260200161037b565b3480156103ea57600080fd5b506103b2611566565b3480156103ff57600080fd5b506103d061040e36600461553d565b61180b565b34801561041f57600080fd5b506001546104409073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161037b565b34801561047157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610440565b3480156104b157600080fd5b507f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f738610440565b3480156104e457600080fd5b50600054610508907201000000000000000000000000000000000000900460ff1681565b604051901515815260200161037b565b34801561052457600080fd5b507f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92610440565b6103176105593660046155cf565b611841565b34801561056a57600080fd5b506105a76040518060400160405280600c81526020017f312e332e312d626574612e32000000000000000000000000000000000000000081525081565b60405161037b9190615666565b3480156105c057600080fd5b506008546009546105cf919082565b6040805192835260208301919091520161037b565b3480156105f057600080fd5b506103d06105ff366004615679565b611853565b34801561061057600080fd5b507f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e610440565b34801561064357600080fd5b506105a761188d565b34801561065857600080fd5b506103176106673660046156b7565b61189b565b34801561067857600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103d0565b3480156106b857600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610366565b6103176106ed3660046156e9565b611a42565b3480156106fe57600080fd5b506009546103d0565b6103176107153660046155cf565b61251b565b610317612528565b34801561072e57600080fd5b506002546103d0565b34801561074357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103d0565b34801561078357600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103d0565b3480156107b657600080fd5b506108226107c5366004615679565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff16606082015260800161037b565b34801561088257600080fd5b5060405163ffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260200161037b565b3480156108c357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103d0565b34801561090357600080fd5b50610366610912366004615679565b612a81565b34801561092357600080fd5b506103d0610932366004615728565b612c60565b34801561094357600080fd5b50610957610952366004615679565b612e43565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e00161037b565b3480156109cd57600080fd5b506000546103669067ffffffffffffffff1681565b3480156109ee57600080fd5b506103d06109fd3660046156b7565b60036020526000908152604090205481565b348015610a1b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000003856103d0565b348015610a4e57600080fd5b50610317610a5d36600461575a565b612eda565b348015610a6e57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b0610366565b348015610aa157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000046103d0565b348015610ad457600080fd5b50610508610ae3366004615679565b60046020526000908152604090205460ff1681565b348015610b0457600080fd5b50610317610b133660046155cf565b613509565b348015610b2457600080fd5b50610b2d6139c6565b60405161037b939291906157e4565b348015610b4857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000086103d0565b348015610b7b57600080fd5b50610508610b8a366004615679565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610bcb57610bcb61555f565b14610c02576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610c55576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610ca3610c9e36869003860186615838565b613a41565b14610cda576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610cef9291906158c5565b604051809103902014610d2e576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d77610d7284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613a9d92505050565b613b0a565b90506000610d9e82600881518110610d9157610d916158d5565b6020026020010151613cc0565b9050602081511115610ddc576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610e51576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610eec57610eec61555f565b14610f23576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610f3857610f386158d5565b906000526020600020906005020190506000610f5384612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b081169082161015610fbc576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611005576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561102257508515155b156110bd578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110555781611071565b600186015473ffffffffffffffffffffffffffffffffffffffff165b905061107d8187613d74565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff166060830152611160576fffffffffffffffffffffffffffffffff6040820152600181526000869003611160578195505b600086826020015163ffffffff166111789190615933565b90506000838211611189578161118b565b835b602084015190915063ffffffff165b818110156112d75760008682815481106111b6576111b66158d5565b6000918252602080832090910154808352600690915260409091205490915060ff1661120e576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611223576112236158d5565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112805750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b156112c257600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b505080806112cf9061594b565b91505061119a565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921790915584900361155b57606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558915801561145757506000547201000000000000000000000000000000000000900460ff165b156114cc5760015473ffffffffffffffffffffffffffffffffffffffff1661147f818a613d74565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff909116178855611559565b61151373ffffffffffffffffffffffffffffffffffffffff8216156114f1578161150d565b600189015473ffffffffffffffffffffffffffffffffffffffff165b89613d74565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff1660028111156115945761159461555f565b146115cb576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff1661162f576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008154811061165b5761165b6158d5565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611696576001611699565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff9091161770010000000000000000000000000000000083600281111561174a5761174a61555f565b02179055600281111561175f5761175f61555f565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e73ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156117f057600080fd5b505af1158015611804573d6000803e3d6000fd5b5050505090565b6005602052816000526040600020818154811061182757600080fd5b90600052602060002001600091509150505481565b905090565b61184e8383836001611a42565b505050565b6000818152600760209081526040808320600590925282208054825461188490610100900463ffffffff1682615983565b95945050505050565b606061183c60546020613e75565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260036020526040812080549082905590819003611900576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169063f3fef3a390604401600060405180830381600087803b15801561199057600080fd5b505af11580156119a4573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a02576040519150601f19603f3d011682016040523d82523d6000602084013e611a07565b606091505b505090508061184e576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008054700100000000000000000000000000000000900460ff166002811115611a6e57611a6e61555f565b14611aa5576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110611aba57611aba6158d5565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514611ba1576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000611c61826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580611c9c5750611c997f00000000000000000000000000000000000000000000000000000000000000046002615933565b81145b8015611ca6575084155b15611cdd576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015611d03575086155b15611d3a576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000008811115611d94576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dbf7f00000000000000000000000000000000000000000000000000000000000000046001615933565b8103611dd157611dd186888588613ec7565b34611ddb83612c60565b14611e12576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611e1d88612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b0811690821603611e85576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611eb260017f0000000000000000000000000000000000000000000000000000000000000008615983565b8303611ff0577f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f47919061599a565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb591906159b7565b611fe9907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166159d0565b9050612083565b61201b60017f0000000000000000000000000000000000000000000000000000000000000004615983565b830361205657611fe97f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1660026159fc565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b6120b7817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b67ffffffffffffffff166120d28367ffffffffffffffff1690565b67ffffffffffffffff16111561211957612116817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615612197576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c8152602001908152602001600020600160028054905061242d9190615983565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169263d0e30db09234926004808301939282900301818588803b1580156124c557600080fd5b505af11580156124d9573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b61184e8383836000611a42565b60005471010000000000000000000000000000000000900460ff161561257a576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e1690637258a807906024016040805180830381865afa15801561262e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126529190615a55565b90925090508161268e576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a146126c157639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401351161275b576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd929092169363d0e30db093926004828101939282900301818588803b158015612a3057600080fd5b505af1158015612a44573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b600080600054700100000000000000000000000000000000900460ff166002811115612aaf57612aaf61555f565b14612ae6576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110612afb57612afb6158d5565b600091825260208220600590910201805490925063ffffffff90811614612b6a57815460028054909163ffffffff16908110612b3957612b396158d5565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090612ba290700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b612bb69067ffffffffffffffff1642615983565b612bd5612b95846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16612be99190615933565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b01667ffffffffffffffff168167ffffffffffffffff1611612c365780611884565b7f00000000000000000000000000000000000000000000000000000000000004b095945050505050565b600080612cff836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000008811115612d5e576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000612d798383615aa8565b9050670de0b6b3a76400006000612db0827f0000000000000000000000000000000000000000000000000000000000000008615abc565b90506000612dce612dc9670de0b6b3a764000086615abc565b614078565b90506000612ddc84846142d3565b90506000612dea8383614322565b90506000612df782614350565b90506000612e1682612e11670de0b6b3a76400008f615abc565b614538565b90506000612e248b83614322565b9050612e30818d615abc565b9f9e505050505050505050505050505050565b60028181548110612e5357600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b60008054700100000000000000000000000000000000900460ff166002811115612f0657612f0661555f565b14612f3d576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028781548110612f5257612f526158d5565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b9050612fb17f00000000000000000000000000000000000000000000000000000000000000086001615933565b61304d826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1614613087576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561317e576130da7f00000000000000000000000000000000000000000000000000000000000000047f0000000000000000000000000000000000000000000000000000000000000008615983565b6001901b6130f9846fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff166131159190615af9565b156131525761314961313a60016fffffffffffffffffffffffffffffffff8716615b0d565b865463ffffffff166000614608565b60030154613174565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506131a8565b600385015491506131a561313a6fffffffffffffffffffffffffffffffff86166001615b36565b90505b600882901b60088a8a6040516131bf9291906158c5565b6040518091039020901b14613200576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061320b8c6146ec565b9050600061321a836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff169063e14ced3290613294908f908f908f908f908a90600401615baa565b6020604051808303816000875af11580156132b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d791906159b7565b600485015491149150600090600290613382906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b61341e896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6134289190615be4565b6134329190615c07565b60ff161590508115158103613473576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156134ca576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff1660028111156135355761353561555f565b1461356c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061357b8661471b565b9350935093509350600061359185858585614b24565b905060007f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015613600573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613624919061599a565b90506001890361371c5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a84613680367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af11580156136f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061371691906159b7565b5061155b565b600289036137485773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8489613680565b600389036137745773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8487613680565b600489036138fb5760006137ba6fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000004614bde565b6009546137c79190615933565b6137d2906001615933565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061383b57367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036054013561383d565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156138d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f491906159b7565b505061155b565b60058903613994576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000038560c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016136d3565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060613a1f61188d565b9050909192565b600081831015613a365781613a38565b825b90505b92915050565b60008160000151826020015183604001518460600151604051602001613a80949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003613aec576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000613b1a85614c8c565b919450925090506001816001811115613b3557613b3561555f565b14613b6c576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451613b788385615933565b14613baf576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081613bc65790505093506000835b8651811015613cb457600080613c396040518060400160405280858c60000151613c1d9190615983565b8152602001858c60200151613c329190615933565b9052614c8c565b509150915060405180604001604052808383613c559190615933565b8152602001848b60200151613c6a9190615933565b815250888581518110613c7f57613c7f6158d5565b6020908102919091010152613c95600185615933565b9350613ca18183615933565b613cab9084615933565b92505050613bf3565b50845250919392505050565b60606000806000613cd085614c8c565b919450925090506000816001811115613ceb57613ceb61555f565b14613d22576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613d2c8284615933565b855114613d65576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118848560200151848461512a565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff90931692839290613dc3908490615933565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd921690637eee288d90604401600060405180830381600087803b158015613e5857600080fd5b505af1158015613e6c573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b6000613ee66fffffffffffffffffffffffffffffffff84166001615b36565b90506000613ef682866001614608565b9050600086901a8380613fe25750613f2f60027f0000000000000000000000000000000000000000000000000000000000000004615af9565b6004830154600290613fd3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b613fdd9190615c07565b60ff16145b1561403a5760ff811660011480613ffc575060ff81166002145b614035576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b613e6c565b60ff811615613e6c576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b17600082136140d757631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a76400000215820261431057637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b6000816000190483118202156143405763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d7821361437e57919050565b680755bf798b4a1bf1e5821261439c5763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000613a38670de0b6b3a76400008361455086614078565b61455a9190615c29565b6145649190615ce5565b614350565b6000806145f6837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826146515761464c6fffffffffffffffffffffffffffffffff86167f00000000000000000000000000000000000000000000000000000000000000046151bf565b61466c565b61466c856fffffffffffffffffffffffffffffffff1661534b565b905060028481548110614681576146816158d5565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff8281169116146146e457815460028054909163ffffffff169081106146cf576146cf6158d5565b90600052602060002090600502019150614692565b509392505050565b60008060008060006146fd8661471b565b935093509350935061471184848484614b24565b9695505050505050565b600080600080600085905060006002828154811061473b5761473b6158d5565b600091825260209091206004600590920201908101549091507f000000000000000000000000000000000000000000000000000000000000000490614812906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff161161484c576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f000000000000000000000000000000000000000000000000000000000000000490614913906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16925082111561498857825463ffffffff166149527f00000000000000000000000000000000000000000000000000000000000000046001615933565b830361495c578391505b6002818154811061496f5761496f6158d5565b9060005260206000209060050201935080945050614850565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149f16149dc856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff161490508015614ac0576000614a29836fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff161115614a94576000614a6b614a6360016fffffffffffffffffffffffffffffffff8616615b0d565b896001614608565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a50614a9a9050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614b16565b6000614ae2614a636fffffffffffffffffffffffffffffffff85166001615b36565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614b915760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611884565b8282604051602001614bbf9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614c6b847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614ccf576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614cf4576000600160009450945094505050615123565b60b78111614e0a576000614d09608083615983565b905080876000015111614d48576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614dc057507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614df7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060019550935060009250615123915050565b60bf8111614f68576000614e1f60b783615983565b905080876000015111614e5e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614ec0576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614f08576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f128184615933565b895111614f4b576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f56836001615933565b97509550600094506151239350505050565b60f78111614fcd576000614f7d60c083615983565b905080876000015111614fbc576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600195509350849250615123915050565b6000614fda60f783615983565b905080876000015111615019576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361507b576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116150c3576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6150cd8184615933565b895111615106576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615111836001615933565b97509550600194506151239350505050565b9193909250565b60608167ffffffffffffffff81111561514557615145615809565b6040519080825280601f01601f19166020018201604052801561516f576020820181803683370190505b50905081156151b85760006151848486615933565b90506020820160005b848110156151a557828101518282015260200161518d565b848111156151b4576000858301525b5050505b9392505050565b60008161525e846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116152745763b34b5c226000526004601cfd5b61527d8361534b565b90508161531c826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611613a3b57613a38615332836001615933565b6fffffffffffffffffffffffffffffffff8316906153f0565b600081196001830116816153df827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b60008061547d847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f8401126154ab57600080fd5b50813567ffffffffffffffff8111156154c357600080fd5b6020830191508360208285010111156154db57600080fd5b9250929050565b600080600083850360a08112156154f857600080fd5b608081121561550657600080fd5b50839250608084013567ffffffffffffffff81111561552457600080fd5b61553086828701615499565b9497909650939450505050565b6000806040838503121561555057600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106155c9577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806000606084860312156155e457600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561562157602081850181015186830182015201615605565b81811115615633576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000613a3860208301846155fb565b60006020828403121561568b57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146156b457600080fd5b50565b6000602082840312156156c957600080fd5b81356151b881615692565b803580151581146156e457600080fd5b919050565b600080600080608085870312156156ff57600080fd5b84359350602085013592506040850135915061571d606086016156d4565b905092959194509250565b60006020828403121561573a57600080fd5b81356fffffffffffffffffffffffffffffffff811681146151b857600080fd5b6000806000806000806080878903121561577357600080fd5b86359550615783602088016156d4565b9450604087013567ffffffffffffffff808211156157a057600080fd5b6157ac8a838b01615499565b909650945060608901359150808211156157c557600080fd5b506157d289828a01615499565b979a9699509497509295939492505050565b63ffffffff8416815282602082015260606040820152600061188460608301846155fb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006080828403121561584a57600080fd5b6040516080810181811067ffffffffffffffff82111715615894577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561594657615946615904565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361597c5761597c615904565b5060010190565b60008282101561599557615995615904565b500390565b6000602082840312156159ac57600080fd5b81516151b881615692565b6000602082840312156159c957600080fd5b5051919050565b600067ffffffffffffffff8083168185168083038211156159f3576159f3615904565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615a2357615a23615904565b02949350505050565b600067ffffffffffffffff83811690831681811015615a4d57615a4d615904565b039392505050565b60008060408385031215615a6857600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615ab757615ab7615a79565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615af457615af4615904565b500290565b600082615b0857615b08615a79565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615a4d57615a4d615904565b60006fffffffffffffffffffffffffffffffff8083168185168083038211156159f3576159f3615904565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615bbe606083018789615b61565b8281036020840152615bd1818688615b61565b9150508260408301529695505050505050565b600060ff821660ff841680821015615bfe57615bfe615904565b90039392505050565b600060ff831680615c1a57615c1a615a79565b8060ff84160691505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615c6a57615c6a615904565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615ca557615ca5615904565b60008712925087820587128484161615615cc157615cc1615904565b87850587128184161615615cd757615cd7615904565b505050929093029392505050565b600082615cf457615cf4615a79565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615d4857615d48615904565b50059056fea164736f6c634300080f000a"; bytes internal constant acc34Code = - hex"6080604052600436106103085760003560e01c806370872aa51161019a578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b94578063fa315aa914610bb8578063fe2bbeb214610beb57600080fd5b8063ec5e630814610b11578063eff0f59214610b44578063f8f43ff614610b7457600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a8b578063d8cc1a3c14610abe578063dabd396d14610ade57600080fd5b8063c6f0308c146109b3578063cf09e0d014610a3d578063d5d44d8014610a5e57600080fd5b8063a445ece611610143578063bcef3b551161011d578063bcef3b5514610933578063bd8da95614610973578063c395e1ca1461099357600080fd5b8063a445ece6146107f3578063a8e4fb90146108bf578063bbdc02db146108f257600080fd5b80638980e0cc116101745780638980e0cc1461076b5780638b85902b146107805780638d450a95146107c057600080fd5b806370872aa51461073b5780637b0f0adc146107505780638129fc1c1461076357600080fd5b80633fc8cef31161025e5780635c0cba33116102075780636361506d116101e15780636361506d146106b55780636b6716c0146106f55780636f0344091461072857600080fd5b80635c0cba331461064d578063609d33341461068057806360e274641461069557600080fd5b806354fd4d501161023857806354fd4d50146105a757806357da950e146105fd5780635a5fa2d91461062d57600080fd5b80633fc8cef31461052e578063472777c614610561578063534db0e21461057457600080fd5b80632810e1d6116102c057806337b1b2291161029a57806337b1b2291461047b5780633a768463146104bb5780633e3ac912146104ee57600080fd5b80632810e1d6146103f45780632ad69aeb1461040957806330dbe5701461042957600080fd5b806319effeb4116102f157806319effeb41461034f578063200d2ed21461039a57806325fc2ace146103d557600080fd5b8063019351301461030d57806303c2924d1461032f575b600080fd5b34801561031957600080fd5b5061032d61032836600461575d565b610c1b565b005b34801561033b57600080fd5b5061032d61034a3660046157b8565b610f3c565b34801561035b57600080fd5b5060005461037c9068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156103a657600080fd5b506000546103c890700100000000000000000000000000000000900460ff1681565b6040516103919190615809565b3480156103e157600080fd5b506008545b604051908152602001610391565b34801561040057600080fd5b506103c86115e2565b34801561041557600080fd5b506103e66104243660046157b8565b611887565b34801561043557600080fd5b506001546104569073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610391565b34801561048757600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610456565b3480156104c757600080fd5b507f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe7806610456565b3480156104fa57600080fd5b5060005461051e907201000000000000000000000000000000000000900460ff1681565b6040519015158152602001610391565b34801561053a57600080fd5b507f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309610456565b61032d61056f36600461584a565b6118bd565b34801561058057600080fd5b507f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63610456565b3480156105b357600080fd5b506105f06040518060400160405280600a81526020017f312e332e302d72632e310000000000000000000000000000000000000000000081525081565b60405161039191906158e1565b34801561060957600080fd5b50600854600954610618919082565b60408051928352602083019190915201610391565b34801561063957600080fd5b506103e66106483660046158f4565b6118cf565b34801561065957600080fd5b507f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e610456565b34801561068c57600080fd5b506105f0611909565b3480156106a157600080fd5b5061032d6106b0366004615932565b611917565b3480156106c157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103e6565b34801561070157600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061037c565b61032d610736366004615964565b611abe565b34801561074757600080fd5b506009546103e6565b61032d61075e36600461584a565b611b7f565b61032d611b8c565b34801561077757600080fd5b506002546103e6565b34801561078c57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103e6565b3480156107cc57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103e6565b3480156107ff57600080fd5b5061086b61080e3660046158f4565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff166060820152608001610391565b3480156108cb57600080fd5b507f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8610456565b3480156108fe57600080fd5b5060405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000001168152602001610391565b34801561093f57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103e6565b34801561097f57600080fd5b5061037c61098e3660046158f4565b611c05565b34801561099f57600080fd5b506103e66109ae3660046159a3565b611de4565b3480156109bf57600080fd5b506109d36109ce3660046158f4565b611fc7565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e001610391565b348015610a4957600080fd5b5060005461037c9067ffffffffffffffff1681565b348015610a6a57600080fd5b506103e6610a79366004615932565b60036020526000908152604090205481565b348015610a9757600080fd5b507f00000000000000000000000000000000000000000000000000000000000003856103e6565b348015610aca57600080fd5b5061032d610ad93660046159d5565b61205e565b348015610aea57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b061037c565b348015610b1d57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000046103e6565b348015610b5057600080fd5b5061051e610b5f3660046158f4565b60046020526000908152604090205460ff1681565b348015610b8057600080fd5b5061032d610b8f36600461584a565b612123565b348015610ba057600080fd5b50610ba96125e0565b60405161039193929190615a5f565b348015610bc457600080fd5b507f00000000000000000000000000000000000000000000000000000000000000086103e6565b348015610bf757600080fd5b5061051e610c063660046158f4565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610c4757610c476157da565b14610c7e576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610cd1576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d08367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610d1f610d1a36869003860186615ab3565b61265b565b14610d56576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610d6b929190615b40565b604051809103902014610daa576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610df3610dee84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506126b792505050565b612724565b90506000610e1a82600881518110610e0d57610e0d615b50565b60200260200101516128da565b9050602081511115610e58576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610ecd576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610f6857610f686157da565b14610f9f576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610fb457610fb4615b50565b906000526020600020906005020190506000610fcf84611c05565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b081169082161015611038576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611081576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561109e57508515155b15611139578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110d157816110ed565b600186015473ffffffffffffffffffffffffffffffffffffffff165b90506110f9818761298e565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff1660608301526111dc576fffffffffffffffffffffffffffffffff60408201526001815260008690036111dc578195505b600086826020015163ffffffff166111f49190615bae565b905060008382116112055781611207565b835b602084015190915063ffffffff165b8181101561135357600086828154811061123257611232615b50565b6000918252602080832090910154808352600690915260409091205490915060ff1661128a576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002828154811061129f5761129f615b50565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112fc5750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b1561133e57600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b5050808061134b90615bc6565b915050611216565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909316929092179091558490036115d757606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055891580156114d357506000547201000000000000000000000000000000000000900460ff165b156115485760015473ffffffffffffffffffffffffffffffffffffffff166114fb818a61298e565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff9091161788556115d5565b61158f73ffffffffffffffffffffffffffffffffffffffff82161561156d5781611589565b600189015473ffffffffffffffffffffffffffffffffffffffff165b8961298e565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff166002811115611610576116106157da565b14611647576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff166116ab576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660026000815481106116d7576116d7615b50565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611712576001611715565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff909116177001000000000000000000000000000000008360028111156117c6576117c66157da565b0217905560028111156117db576117db6157da565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e73ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561186c57600080fd5b505af1158015611880573d6000803e3d6000fd5b5050505090565b600560205281600052604060002081815481106118a357600080fd5b90600052602060002001600091509150505481565b905090565b6118ca8383836001611abe565b505050565b6000818152600760209081526040808320600590925282208054825461190090610100900463ffffffff1682615bfe565b95945050505050565b60606118b860546020612a8f565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604081208054908290559081900361197c576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309169063f3fef3a390604401600060405180830381600087803b158015611a0c57600080fd5b505af1158015611a20573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a7e576040519150601f19603f3d011682016040523d82523d6000602084013e611a83565b606091505b50509050806118ca576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8161480611b3757503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b6316145b611b6d576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b7984848484612ae1565b50505050565b6118ca8383836000611abe565b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c81614611bfb576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c036135ba565b565b600080600054700100000000000000000000000000000000900460ff166002811115611c3357611c336157da565b14611c6a576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110611c7f57611c7f615b50565b600091825260208220600590910201805490925063ffffffff90811614611cee57815460028054909163ffffffff16908110611cbd57611cbd615b50565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090611d2690700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b611d3a9067ffffffffffffffff1642615bfe565b611d59611d19846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16611d6d9190615bae565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b01667ffffffffffffffff168167ffffffffffffffff1611611dba5780611900565b7f00000000000000000000000000000000000000000000000000000000000004b095945050505050565b600080611e83836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000008811115611ee2576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000611efd8383615c44565b9050670de0b6b3a76400006000611f34827f0000000000000000000000000000000000000000000000000000000000000008615c58565b90506000611f52611f4d670de0b6b3a764000086615c58565b613b13565b90506000611f608484613d6e565b90506000611f6e8383613dbd565b90506000611f7b82613deb565b90506000611f9a82611f95670de0b6b3a76400008f615c58565b613fd3565b90506000611fa88b83613dbd565b9050611fb4818d615c58565b9f9e505050505050505050505050505050565b60028181548110611fd757600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c81614806120d757503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b6316145b61210d576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61211b868686868686614004565b505050505050565b60008054700100000000000000000000000000000000900460ff16600281111561214f5761214f6157da565b14612186576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061219586614633565b935093509350935060006121ab85858585614a3c565b905060007f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561221a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223e9190615c95565b9050600189036123365773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8461229a367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af115801561230c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123309190615cb2565b506115d7565b600289036123625773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848961229a565b6003890361238e5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848761229a565b600489036125155760006123d46fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000004614af6565b6009546123e19190615bae565b6123ec906001615bae565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061245557367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135612457565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156124ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250e9190615cb2565b50506115d7565b600589036125ae576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000038560c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016122ed565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000001367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060612639611909565b9050909192565b6000818310156126505781612652565b825b90505b92915050565b6000816000015182602001518360400151846060015160405160200161269a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003612706576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b6060600080600061273485614ba4565b91945092509050600181600181111561274f5761274f6157da565b14612786576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516127928385615bae565b146127c9576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816127e05790505093506000835b86518110156128ce576000806128536040518060400160405280858c600001516128379190615bfe565b8152602001858c6020015161284c9190615bae565b9052614ba4565b50915091506040518060400160405280838361286f9190615bae565b8152602001848b602001516128849190615bae565b81525088858151811061289957612899615b50565b60209081029190910101526128af600185615bae565b93506128bb8183615bae565b6128c59084615bae565b9250505061280d565b50845250919392505050565b606060008060006128ea85614ba4565b919450925090506000816001811115612905576129056157da565b1461293c576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129468284615bae565b85511461297f576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61190085602001518484615042565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff909316928392906129dd908490615bae565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f000000000000000000000000d6eaf4c146261653ee059077b78ed088add543091690637eee288d90604401600060405180830381600087803b158015612a7257600080fd5b505af1158015612a86573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b60008054700100000000000000000000000000000000900460ff166002811115612b0d57612b0d6157da565b14612b44576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110612b5957612b59615b50565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514612c40576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000612d00826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580612d3b5750612d387f00000000000000000000000000000000000000000000000000000000000000046002615bae565b81145b8015612d45575084155b15612d7c576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015612da2575086155b15612dd9576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000008811115612e33576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e5e7f00000000000000000000000000000000000000000000000000000000000000046001615bae565b8103612e7057612e70868885886150d7565b34612e7a83611de4565b14612eb1576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612ebc88611c05565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b0811690821603612f24576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612f5160017f0000000000000000000000000000000000000000000000000000000000000008615bfe565b830361308f577f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fe69190615c95565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015613030573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130549190615cb2565b613088907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16615ccb565b9050613122565b6130ba60017f0000000000000000000000000000000000000000000000000000000000000004615bfe565b83036130f5576130887f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166002615cf7565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b613156817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615d27565b67ffffffffffffffff166131718367ffffffffffffffff1690565b67ffffffffffffffff1611156131b8576131b5817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615d27565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615613236576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c815260200190815260200160002060016002805490506134cc9190615bfe565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309169263d0e30db09234926004808301939282900301818588803b15801561356457600080fd5b505af1158015613578573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b60005471010000000000000000000000000000000000900460ff161561360c576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000001166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e1690637258a807906024016040805180830381865afa1580156136c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136e49190615d50565b909250905081613720576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a1461375357639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135116137ed576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f000000000000000000000000d6eaf4c146261653ee059077b78ed088add543099092169363d0e30db093926004828101939282900301818588803b158015613ac257600080fd5b505af1158015613ad6573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b1760008213613b7257631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a764000002158202613dab57637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b600081600019048311820215613ddb5763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d78213613e1957919050565b680755bf798b4a1bf1e58212613e375763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000612652670de0b6b3a764000083613feb86613b13565b613ff59190615d74565b613fff9190615e30565b613deb565b60008054700100000000000000000000000000000000900460ff166002811115614030576140306157da565b14614067576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002878154811061407c5761407c615b50565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506140db7f00000000000000000000000000000000000000000000000000000000000000086001615bae565b614177826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16146141b1576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008089156142a8576142047f00000000000000000000000000000000000000000000000000000000000000047f0000000000000000000000000000000000000000000000000000000000000008615bfe565b6001901b614223846fffffffffffffffffffffffffffffffff16615288565b6fffffffffffffffffffffffffffffffff1661423f9190615e98565b1561427c5761427361426460016fffffffffffffffffffffffffffffffff8716615eac565b865463ffffffff166000615327565b6003015461429e565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506142d2565b600385015491506142cf6142646fffffffffffffffffffffffffffffffff86166001615ed5565b90505b600882901b60088a8a6040516142e9929190615b40565b6040518091039020901b1461432a576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006143358c61540b565b90506000614344836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff169063e14ced32906143be908f908f908f908f908a90600401615f49565b6020604051808303816000875af11580156143dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144019190615cb2565b6004850154911491506000906002906144ac906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b614548896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6145529190615f83565b61455c9190615fa6565b60ff16159050811515810361459d576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156145f4576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b600080600080600085905060006002828154811061465357614653615b50565b600091825260209091206004600590920201908101549091507f00000000000000000000000000000000000000000000000000000000000000049061472a906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611614764576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f00000000000000000000000000000000000000000000000000000000000000049061482b906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1692508211156148a057825463ffffffff1661486a7f00000000000000000000000000000000000000000000000000000000000000046001615bae565b8303614874578391505b6002818154811061488757614887615b50565b9060005260206000209060050201935080945050614768565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149096148f4856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff1614905080156149d8576000614941836fffffffffffffffffffffffffffffffff16615288565b6fffffffffffffffffffffffffffffffff1611156149ac57600061498361497b60016fffffffffffffffffffffffffffffffff8616615eac565b896001615327565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a506149b29050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614a2e565b60006149fa61497b6fffffffffffffffffffffffffffffffff85166001615ed5565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614aa95760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611900565b8282604051602001614ad79291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614b83847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614be7576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614c0c57600060016000945094509450505061503b565b60b78111614d22576000614c21608083615bfe565b905080876000015111614c60576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614cd857507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614d0f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061503b915050565b60bf8111614e80576000614d3760b783615bfe565b905080876000015111614d76576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614dd8576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614e20576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614e2a8184615bae565b895111614e63576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614e6e836001615bae565b975095506000945061503b9350505050565b60f78111614ee5576000614e9560c083615bfe565b905080876000015111614ed4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061503b915050565b6000614ef260f783615bfe565b905080876000015111614f31576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614f93576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614fdb576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614fe58184615bae565b89511161501e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615029836001615bae565b975095506001945061503b9350505050565b9193909250565b60608167ffffffffffffffff81111561505d5761505d615a84565b6040519080825280601f01601f191660200182016040528015615087576020820181803683370190505b50905081156150d057600061509c8486615bae565b90506020820160005b848110156150bd5782810151828201526020016150a5565b848111156150cc576000858301525b5050505b9392505050565b60006150f66fffffffffffffffffffffffffffffffff84166001615ed5565b9050600061510682866001615327565b9050600086901a83806151f2575061513f60027f0000000000000000000000000000000000000000000000000000000000000004615e98565b60048301546002906151e3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6151ed9190615fa6565b60ff16145b1561524a5760ff81166001148061520c575060ff81166002145b615245576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016137e4565b612a86565b60ff811615612a86576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016137e4565b600080615315837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826153705761536b6fffffffffffffffffffffffffffffffff86167f000000000000000000000000000000000000000000000000000000000000000461543a565b61538b565b61538b856fffffffffffffffffffffffffffffffff166155c6565b9050600284815481106153a0576153a0615b50565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff82811691161461540357815460028054909163ffffffff169081106153ee576153ee615b50565b906000526020600020906005020191506153b1565b509392505050565b600080600080600061541c86614633565b935093509350935061543084848484614a3c565b9695505050505050565b6000816154d9846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116154ef5763b34b5c226000526004601cfd5b6154f8836155c6565b905081615597826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611612655576126526155ad836001615bae565b6fffffffffffffffffffffffffffffffff83169061566b565b6000811960018301168161565a827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b6000806156f8847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f84011261572657600080fd5b50813567ffffffffffffffff81111561573e57600080fd5b60208301915083602082850101111561575657600080fd5b9250929050565b600080600083850360a081121561577357600080fd5b608081121561578157600080fd5b50839250608084013567ffffffffffffffff81111561579f57600080fd5b6157ab86828701615714565b9497909650939450505050565b600080604083850312156157cb57600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310615844577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060006060848603121561585f57600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561589c57602081850181015186830182015201615880565b818111156158ae576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006126526020830184615876565b60006020828403121561590657600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461592f57600080fd5b50565b60006020828403121561594457600080fd5b81356150d08161590d565b8035801515811461595f57600080fd5b919050565b6000806000806080858703121561597a57600080fd5b8435935060208501359250604085013591506159986060860161594f565b905092959194509250565b6000602082840312156159b557600080fd5b81356fffffffffffffffffffffffffffffffff811681146150d057600080fd5b600080600080600080608087890312156159ee57600080fd5b863595506159fe6020880161594f565b9450604087013567ffffffffffffffff80821115615a1b57600080fd5b615a278a838b01615714565b90965094506060890135915080821115615a4057600080fd5b50615a4d89828a01615714565b979a9699509497509295939492505050565b63ffffffff841681528260208201526060604082015260006119006060830184615876565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060808284031215615ac557600080fd5b6040516080810181811067ffffffffffffffff82111715615b0f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115615bc157615bc1615b7f565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615bf757615bf7615b7f565b5060010190565b600082821015615c1057615c10615b7f565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615c5357615c53615c15565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615c9057615c90615b7f565b500290565b600060208284031215615ca757600080fd5b81516150d08161590d565b600060208284031215615cc457600080fd5b5051919050565b600067ffffffffffffffff808316818516808303821115615cee57615cee615b7f565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615d1e57615d1e615b7f565b02949350505050565b600067ffffffffffffffff83811690831681811015615d4857615d48615b7f565b039392505050565b60008060408385031215615d6357600080fd5b505080516020909101519092909150565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615db557615db5615b7f565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615df057615df0615b7f565b60008712925087820587128484161615615e0c57615e0c615b7f565b87850587128184161615615e2257615e22615b7f565b505050929093029392505050565b600082615e3f57615e3f615c15565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615e9357615e93615b7f565b500590565b600082615ea757615ea7615c15565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615d4857615d48615b7f565b60006fffffffffffffffffffffffffffffffff808316818516808303821115615cee57615cee615b7f565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615f5d606083018789615f00565b8281036020840152615f70818688615f00565b9150508260408301529695505050505050565b600060ff821660ff841680821015615f9d57615f9d615b7f565b90039392505050565b600060ff831680615fb957615fb9615c15565b8060ff8416069150509291505056fea164736f6c634300080f000a"; + hex"6080604052600436106103085760003560e01c806370872aa51161019a578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b94578063fa315aa914610bb8578063fe2bbeb214610beb57600080fd5b8063ec5e630814610b11578063eff0f59214610b44578063f8f43ff614610b7457600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a8b578063d8cc1a3c14610abe578063dabd396d14610ade57600080fd5b8063c6f0308c146109b3578063cf09e0d014610a3d578063d5d44d8014610a5e57600080fd5b8063a445ece611610143578063bcef3b551161011d578063bcef3b5514610933578063bd8da95614610973578063c395e1ca1461099357600080fd5b8063a445ece6146107f3578063a8e4fb90146108bf578063bbdc02db146108f257600080fd5b80638980e0cc116101745780638980e0cc1461076b5780638b85902b146107805780638d450a95146107c057600080fd5b806370872aa51461073b5780637b0f0adc146107505780638129fc1c1461076357600080fd5b80633fc8cef31161025e5780635c0cba33116102075780636361506d116101e15780636361506d146106b55780636b6716c0146106f55780636f0344091461072857600080fd5b80635c0cba331461064d578063609d33341461068057806360e274641461069557600080fd5b806354fd4d501161023857806354fd4d50146105a757806357da950e146105fd5780635a5fa2d91461062d57600080fd5b80633fc8cef31461052e578063472777c614610561578063534db0e21461057457600080fd5b80632810e1d6116102c057806337b1b2291161029a57806337b1b2291461047b5780633a768463146104bb5780633e3ac912146104ee57600080fd5b80632810e1d6146103f45780632ad69aeb1461040957806330dbe5701461042957600080fd5b806319effeb4116102f157806319effeb41461034f578063200d2ed21461039a57806325fc2ace146103d557600080fd5b8063019351301461030d57806303c2924d1461032f575b600080fd5b34801561031957600080fd5b5061032d61032836600461575d565b610c1b565b005b34801561033b57600080fd5b5061032d61034a3660046157b8565b610f3c565b34801561035b57600080fd5b5060005461037c9068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156103a657600080fd5b506000546103c890700100000000000000000000000000000000900460ff1681565b6040516103919190615809565b3480156103e157600080fd5b506008545b604051908152602001610391565b34801561040057600080fd5b506103c86115e2565b34801561041557600080fd5b506103e66104243660046157b8565b611887565b34801561043557600080fd5b506001546104569073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610391565b34801561048757600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610456565b3480156104c757600080fd5b507f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f738610456565b3480156104fa57600080fd5b5060005461051e907201000000000000000000000000000000000000900460ff1681565b6040519015158152602001610391565b34801561053a57600080fd5b507f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309610456565b61032d61056f36600461584a565b6118bd565b34801561058057600080fd5b507f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63610456565b3480156105b357600080fd5b506105f06040518060400160405280600c81526020017f312e332e312d626574612e32000000000000000000000000000000000000000081525081565b60405161039191906158e1565b34801561060957600080fd5b50600854600954610618919082565b60408051928352602083019190915201610391565b34801561063957600080fd5b506103e66106483660046158f4565b6118cf565b34801561065957600080fd5b507f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e610456565b34801561068c57600080fd5b506105f0611909565b3480156106a157600080fd5b5061032d6106b0366004615932565b611917565b3480156106c157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103e6565b34801561070157600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061037c565b61032d610736366004615964565b611abe565b34801561074757600080fd5b506009546103e6565b61032d61075e36600461584a565b611b7f565b61032d611b8c565b34801561077757600080fd5b506002546103e6565b34801561078c57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103e6565b3480156107cc57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103e6565b3480156107ff57600080fd5b5061086b61080e3660046158f4565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff166060820152608001610391565b3480156108cb57600080fd5b507f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8610456565b3480156108fe57600080fd5b5060405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000001168152602001610391565b34801561093f57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103e6565b34801561097f57600080fd5b5061037c61098e3660046158f4565b611c05565b34801561099f57600080fd5b506103e66109ae3660046159a3565b611de4565b3480156109bf57600080fd5b506109d36109ce3660046158f4565b611fc7565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e001610391565b348015610a4957600080fd5b5060005461037c9067ffffffffffffffff1681565b348015610a6a57600080fd5b506103e6610a79366004615932565b60036020526000908152604090205481565b348015610a9757600080fd5b507f00000000000000000000000000000000000000000000000000000000000003856103e6565b348015610aca57600080fd5b5061032d610ad93660046159d5565b61205e565b348015610aea57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b061037c565b348015610b1d57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000046103e6565b348015610b5057600080fd5b5061051e610b5f3660046158f4565b60046020526000908152604090205460ff1681565b348015610b8057600080fd5b5061032d610b8f36600461584a565b612123565b348015610ba057600080fd5b50610ba96125e0565b60405161039193929190615a5f565b348015610bc457600080fd5b507f00000000000000000000000000000000000000000000000000000000000000086103e6565b348015610bf757600080fd5b5061051e610c063660046158f4565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610c4757610c476157da565b14610c7e576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610cd1576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d08367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610d1f610d1a36869003860186615ab3565b61265b565b14610d56576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610d6b929190615b40565b604051809103902014610daa576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610df3610dee84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506126b792505050565b612724565b90506000610e1a82600881518110610e0d57610e0d615b50565b60200260200101516128da565b9050602081511115610e58576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610ecd576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610f6857610f686157da565b14610f9f576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610fb457610fb4615b50565b906000526020600020906005020190506000610fcf84611c05565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b081169082161015611038576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611081576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561109e57508515155b15611139578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110d157816110ed565b600186015473ffffffffffffffffffffffffffffffffffffffff165b90506110f9818761298e565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff1660608301526111dc576fffffffffffffffffffffffffffffffff60408201526001815260008690036111dc578195505b600086826020015163ffffffff166111f49190615bae565b905060008382116112055781611207565b835b602084015190915063ffffffff165b8181101561135357600086828154811061123257611232615b50565b6000918252602080832090910154808352600690915260409091205490915060ff1661128a576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002828154811061129f5761129f615b50565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112fc5750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b1561133e57600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b5050808061134b90615bc6565b915050611216565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909316929092179091558490036115d757606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055891580156114d357506000547201000000000000000000000000000000000000900460ff165b156115485760015473ffffffffffffffffffffffffffffffffffffffff166114fb818a61298e565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff9091161788556115d5565b61158f73ffffffffffffffffffffffffffffffffffffffff82161561156d5781611589565b600189015473ffffffffffffffffffffffffffffffffffffffff165b8961298e565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff166002811115611610576116106157da565b14611647576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff166116ab576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660026000815481106116d7576116d7615b50565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611712576001611715565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff909116177001000000000000000000000000000000008360028111156117c6576117c66157da565b0217905560028111156117db576117db6157da565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e73ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561186c57600080fd5b505af1158015611880573d6000803e3d6000fd5b5050505090565b600560205281600052604060002081815481106118a357600080fd5b90600052602060002001600091509150505481565b905090565b6118ca8383836001611abe565b505050565b6000818152600760209081526040808320600590925282208054825461190090610100900463ffffffff1682615bfe565b95945050505050565b60606118b860546020612a8f565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604081208054908290559081900361197c576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309169063f3fef3a390604401600060405180830381600087803b158015611a0c57600080fd5b505af1158015611a20573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a7e576040519150601f19603f3d011682016040523d82523d6000602084013e611a83565b606091505b50509050806118ca576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8161480611b3757503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b6316145b611b6d576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b7984848484612ae1565b50505050565b6118ca8383836000611abe565b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c81614611bfb576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c036135ba565b565b600080600054700100000000000000000000000000000000900460ff166002811115611c3357611c336157da565b14611c6a576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110611c7f57611c7f615b50565b600091825260208220600590910201805490925063ffffffff90811614611cee57815460028054909163ffffffff16908110611cbd57611cbd615b50565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090611d2690700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b611d3a9067ffffffffffffffff1642615bfe565b611d59611d19846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16611d6d9190615bae565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b01667ffffffffffffffff168167ffffffffffffffff1611611dba5780611900565b7f00000000000000000000000000000000000000000000000000000000000004b095945050505050565b600080611e83836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000008811115611ee2576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000611efd8383615c44565b9050670de0b6b3a76400006000611f34827f0000000000000000000000000000000000000000000000000000000000000008615c58565b90506000611f52611f4d670de0b6b3a764000086615c58565b613b13565b90506000611f608484613d6e565b90506000611f6e8383613dbd565b90506000611f7b82613deb565b90506000611f9a82611f95670de0b6b3a76400008f615c58565b613fd3565b90506000611fa88b83613dbd565b9050611fb4818d615c58565b9f9e505050505050505050505050505050565b60028181548110611fd757600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c81614806120d757503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b6316145b61210d576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61211b868686868686614004565b505050505050565b60008054700100000000000000000000000000000000900460ff16600281111561214f5761214f6157da565b14612186576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061219586614633565b935093509350935060006121ab85858585614a3c565b905060007f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561221a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223e9190615c95565b9050600189036123365773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8461229a367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af115801561230c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123309190615cb2565b506115d7565b600289036123625773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848961229a565b6003890361238e5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848761229a565b600489036125155760006123d46fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000004614af6565b6009546123e19190615bae565b6123ec906001615bae565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061245557367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135612457565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156124ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250e9190615cb2565b50506115d7565b600589036125ae576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000038560c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016122ed565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000001367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060612639611909565b9050909192565b6000818310156126505781612652565b825b90505b92915050565b6000816000015182602001518360400151846060015160405160200161269a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003612706576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b6060600080600061273485614ba4565b91945092509050600181600181111561274f5761274f6157da565b14612786576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516127928385615bae565b146127c9576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816127e05790505093506000835b86518110156128ce576000806128536040518060400160405280858c600001516128379190615bfe565b8152602001858c6020015161284c9190615bae565b9052614ba4565b50915091506040518060400160405280838361286f9190615bae565b8152602001848b602001516128849190615bae565b81525088858151811061289957612899615b50565b60209081029190910101526128af600185615bae565b93506128bb8183615bae565b6128c59084615bae565b9250505061280d565b50845250919392505050565b606060008060006128ea85614ba4565b919450925090506000816001811115612905576129056157da565b1461293c576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129468284615bae565b85511461297f576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61190085602001518484615042565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff909316928392906129dd908490615bae565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f000000000000000000000000d6eaf4c146261653ee059077b78ed088add543091690637eee288d90604401600060405180830381600087803b158015612a7257600080fd5b505af1158015612a86573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b60008054700100000000000000000000000000000000900460ff166002811115612b0d57612b0d6157da565b14612b44576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110612b5957612b59615b50565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514612c40576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000612d00826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580612d3b5750612d387f00000000000000000000000000000000000000000000000000000000000000046002615bae565b81145b8015612d45575084155b15612d7c576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015612da2575086155b15612dd9576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000008811115612e33576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e5e7f00000000000000000000000000000000000000000000000000000000000000046001615bae565b8103612e7057612e70868885886150d7565b34612e7a83611de4565b14612eb1576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612ebc88611c05565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b0811690821603612f24576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612f5160017f0000000000000000000000000000000000000000000000000000000000000008615bfe565b830361308f577f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fe69190615c95565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015613030573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130549190615cb2565b613088907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16615ccb565b9050613122565b6130ba60017f0000000000000000000000000000000000000000000000000000000000000004615bfe565b83036130f5576130887f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166002615cf7565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b613156817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615d27565b67ffffffffffffffff166131718367ffffffffffffffff1690565b67ffffffffffffffff1611156131b8576131b5817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615d27565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615613236576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c815260200190815260200160002060016002805490506134cc9190615bfe565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309169263d0e30db09234926004808301939282900301818588803b15801561356457600080fd5b505af1158015613578573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b60005471010000000000000000000000000000000000900460ff161561360c576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000001166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e1690637258a807906024016040805180830381865afa1580156136c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136e49190615d50565b909250905081613720576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a1461375357639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135116137ed576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f000000000000000000000000d6eaf4c146261653ee059077b78ed088add543099092169363d0e30db093926004828101939282900301818588803b158015613ac257600080fd5b505af1158015613ad6573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b1760008213613b7257631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a764000002158202613dab57637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b600081600019048311820215613ddb5763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d78213613e1957919050565b680755bf798b4a1bf1e58212613e375763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000612652670de0b6b3a764000083613feb86613b13565b613ff59190615d74565b613fff9190615e30565b613deb565b60008054700100000000000000000000000000000000900460ff166002811115614030576140306157da565b14614067576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002878154811061407c5761407c615b50565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506140db7f00000000000000000000000000000000000000000000000000000000000000086001615bae565b614177826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16146141b1576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008089156142a8576142047f00000000000000000000000000000000000000000000000000000000000000047f0000000000000000000000000000000000000000000000000000000000000008615bfe565b6001901b614223846fffffffffffffffffffffffffffffffff16615288565b6fffffffffffffffffffffffffffffffff1661423f9190615e98565b1561427c5761427361426460016fffffffffffffffffffffffffffffffff8716615eac565b865463ffffffff166000615327565b6003015461429e565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506142d2565b600385015491506142cf6142646fffffffffffffffffffffffffffffffff86166001615ed5565b90505b600882901b60088a8a6040516142e9929190615b40565b6040518091039020901b1461432a576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006143358c61540b565b90506000614344836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff169063e14ced32906143be908f908f908f908f908a90600401615f49565b6020604051808303816000875af11580156143dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144019190615cb2565b6004850154911491506000906002906144ac906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b614548896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6145529190615f83565b61455c9190615fa6565b60ff16159050811515810361459d576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156145f4576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b600080600080600085905060006002828154811061465357614653615b50565b600091825260209091206004600590920201908101549091507f00000000000000000000000000000000000000000000000000000000000000049061472a906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611614764576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f00000000000000000000000000000000000000000000000000000000000000049061482b906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1692508211156148a057825463ffffffff1661486a7f00000000000000000000000000000000000000000000000000000000000000046001615bae565b8303614874578391505b6002818154811061488757614887615b50565b9060005260206000209060050201935080945050614768565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149096148f4856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff1614905080156149d8576000614941836fffffffffffffffffffffffffffffffff16615288565b6fffffffffffffffffffffffffffffffff1611156149ac57600061498361497b60016fffffffffffffffffffffffffffffffff8616615eac565b896001615327565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a506149b29050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614a2e565b60006149fa61497b6fffffffffffffffffffffffffffffffff85166001615ed5565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614aa95760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611900565b8282604051602001614ad79291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614b83847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614be7576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614c0c57600060016000945094509450505061503b565b60b78111614d22576000614c21608083615bfe565b905080876000015111614c60576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614cd857507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614d0f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061503b915050565b60bf8111614e80576000614d3760b783615bfe565b905080876000015111614d76576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614dd8576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614e20576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614e2a8184615bae565b895111614e63576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614e6e836001615bae565b975095506000945061503b9350505050565b60f78111614ee5576000614e9560c083615bfe565b905080876000015111614ed4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061503b915050565b6000614ef260f783615bfe565b905080876000015111614f31576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614f93576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614fdb576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614fe58184615bae565b89511161501e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615029836001615bae565b975095506001945061503b9350505050565b9193909250565b60608167ffffffffffffffff81111561505d5761505d615a84565b6040519080825280601f01601f191660200182016040528015615087576020820181803683370190505b50905081156150d057600061509c8486615bae565b90506020820160005b848110156150bd5782810151828201526020016150a5565b848111156150cc576000858301525b5050505b9392505050565b60006150f66fffffffffffffffffffffffffffffffff84166001615ed5565b9050600061510682866001615327565b9050600086901a83806151f2575061513f60027f0000000000000000000000000000000000000000000000000000000000000004615e98565b60048301546002906151e3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6151ed9190615fa6565b60ff16145b1561524a5760ff81166001148061520c575060ff81166002145b615245576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016137e4565b612a86565b60ff811615612a86576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016137e4565b600080615315837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826153705761536b6fffffffffffffffffffffffffffffffff86167f000000000000000000000000000000000000000000000000000000000000000461543a565b61538b565b61538b856fffffffffffffffffffffffffffffffff166155c6565b9050600284815481106153a0576153a0615b50565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff82811691161461540357815460028054909163ffffffff169081106153ee576153ee615b50565b906000526020600020906005020191506153b1565b509392505050565b600080600080600061541c86614633565b935093509350935061543084848484614a3c565b9695505050505050565b6000816154d9846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116154ef5763b34b5c226000526004601cfd5b6154f8836155c6565b905081615597826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611612655576126526155ad836001615bae565b6fffffffffffffffffffffffffffffffff83169061566b565b6000811960018301168161565a827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b6000806156f8847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f84011261572657600080fd5b50813567ffffffffffffffff81111561573e57600080fd5b60208301915083602082850101111561575657600080fd5b9250929050565b600080600083850360a081121561577357600080fd5b608081121561578157600080fd5b50839250608084013567ffffffffffffffff81111561579f57600080fd5b6157ab86828701615714565b9497909650939450505050565b600080604083850312156157cb57600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310615844577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060006060848603121561585f57600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561589c57602081850181015186830182015201615880565b818111156158ae576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006126526020830184615876565b60006020828403121561590657600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461592f57600080fd5b50565b60006020828403121561594457600080fd5b81356150d08161590d565b8035801515811461595f57600080fd5b919050565b6000806000806080858703121561597a57600080fd5b8435935060208501359250604085013591506159986060860161594f565b905092959194509250565b6000602082840312156159b557600080fd5b81356fffffffffffffffffffffffffffffffff811681146150d057600080fd5b600080600080600080608087890312156159ee57600080fd5b863595506159fe6020880161594f565b9450604087013567ffffffffffffffff80821115615a1b57600080fd5b615a278a838b01615714565b90965094506060890135915080821115615a4057600080fd5b50615a4d89828a01615714565b979a9699509497509295939492505050565b63ffffffff841681528260208201526060604082015260006119006060830184615876565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060808284031215615ac557600080fd5b6040516080810181811067ffffffffffffffff82111715615b0f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115615bc157615bc1615b7f565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615bf757615bf7615b7f565b5060010190565b600082821015615c1057615c10615b7f565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615c5357615c53615c15565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615c9057615c90615b7f565b500290565b600060208284031215615ca757600080fd5b81516150d08161590d565b600060208284031215615cc457600080fd5b5051919050565b600067ffffffffffffffff808316818516808303821115615cee57615cee615b7f565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615d1e57615d1e615b7f565b02949350505050565b600067ffffffffffffffff83811690831681811015615d4857615d48615b7f565b039392505050565b60008060408385031215615d6357600080fd5b505080516020909101519092909150565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615db557615db5615b7f565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615df057615df0615b7f565b60008712925087820587128484161615615e0c57615e0c615b7f565b87850587128184161615615e2257615e22615b7f565b505050929093029392505050565b600082615e3f57615e3f615c15565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615e9357615e93615b7f565b500590565b600082615ea757615ea7615c15565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615d4857615d48615b7f565b60006fffffffffffffffffffffffffffffffff808316818516808303821115615cee57615cee615b7f565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615f5d606083018789615f00565b8281036020840152615f70818688615f00565b9150508260408301529695505050505050565b600060ff821660ff841680821015615f9d57615f9d615b7f565b90039392505050565b600060ff831680615fb957615fb9615c15565b8060ff8416069150509291505056fea164736f6c634300080f000a"; } diff --git a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofs.sol b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofs.sol index 7f3e459b481e..9750b8deb973 100644 --- a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofs.sol +++ b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofs.sol @@ -13,9 +13,9 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { Vm private constant vm = Vm(VM_ADDRESS); address internal constant addressManagerAddress = 0x50EEf481cae4250d252Ae577A09bF514f224C6C4; - address internal constant anchorStateRegistryAddress = 0x0C21b289b76ae49983890aed23F78337333F0A5F; + address internal constant anchorStateRegistryAddress = 0xdEC4D949Cf1A2e824eE4F8B12064e166b96171dD; address internal constant anchorStateRegistryProxyAddress = 0x970670459734a83899773A0fd45941B5afC1200e; - address internal constant delayedWETHAddress = 0x2A6347EDD3C7813CDE46DD7eA61FF1Cf2290BC05; + address internal constant delayedWETHAddress = 0xe49cED258137CC5E18fB9ABA2Aa14069263D8f49; address internal constant delayedWETHProxyAddress = 0xEF179756ea6525AFade217cA5aB0b1b5CfE0fd92; address internal constant disputeGameFactoryAddress = 0x8efDa795511CBBdfFC9eeca1a5bF30f5B1E1ef9E; address internal constant disputeGameFactoryProxyAddress = 0x5207CfA0166E8de0FCdFd78B4d17b68587bE306d; @@ -27,14 +27,14 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { address internal constant l1StandardBridgeProxyAddress = 0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D; address internal constant l2OutputOracleAddress = 0x60d37db59d0D14f7EA5c7425A2C03244E08B162D; address internal constant l2OutputOracleProxyAddress = 0x39Af23E00F1e662025aA01b0cEdA19542B78DF99; - address internal constant mipsAddress = 0x444e09fe6D839273316a87002aB0EFBeA6fe7806; - address internal constant optimismMintableERC20FactoryAddress = 0x47a13af3fB62B24E4914C36aBD9882da23D0e29C; + address internal constant mipsAddress = 0x46cce16e68c41f7EBdf485EF825AB3b46143F738; + address internal constant optimismMintableERC20FactoryAddress = 0x79c3114E5f89266e2C8842871Bce16D4e5076b1e; address internal constant optimismMintableERC20FactoryProxyAddress = 0xc7B87b2b892EA5C3CfF47168881FE168C00377FB; address internal constant optimismPortalAddress = 0xBE8eE5CEA97De55Ae8b020E778A5C93C2Af81Ed4; address internal constant optimismPortal2Address = 0x5506077419b90A12C048500e2eBcafb4fC6Bab61; address internal constant optimismPortalProxyAddress = 0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4; address internal constant permissionedDelayedWETHProxyAddress = 0xd6EAF4c146261653EE059077B78ED088Add54309; - address internal constant preimageOracleAddress = 0x373d916D11cce55b548F7051002e76BCFBD7a85d; + address internal constant preimageOracleAddress = 0x7A9Eab4CE99d157AeE7A02E95b366E972a2D5b0b; address internal constant protocolVersionsAddress = 0xa99F1ab91821747b76Ec0cDFA38368DF4Ba06E84; address internal constant protocolVersionsProxyAddress = 0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1; address internal constant proxyAdminAddress = 0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1; @@ -583,7 +583,7 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { value = hex"0000000000000000000000000000000000000000000000000000000000000008"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"00000000000000000000000047a13af3fb62b24e4914c36abd9882da23d0e29c"; + value = hex"00000000000000000000000079c3114e5f89266e2c8842871bce16d4e5076b1e"; vm.store(optimismMintableERC20FactoryProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -700,7 +700,7 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { value = hex"000000000000000000000000000000000000000000000000000000000000000e"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05"; + value = hex"000000000000000000000000e49ced258137cc5e18fb9aba2aa14069263d8f49"; vm.store(delayedWETHProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -724,7 +724,7 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { value = hex"000000000000000000000000000000000000000000000000000000000000000f"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"0000000000000000000000002a6347edd3c7813cde46dd7ea61ff1cf2290bc05"; + value = hex"000000000000000000000000e49ced258137cc5e18fb9aba2aa14069263d8f49"; vm.store(permissionedDelayedWETHProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; @@ -748,7 +748,7 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { value = hex"0000000000000000000000000000000000000000000000000000000000000010"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"0000000000000000000000000c21b289b76ae49983890aed23f78337333f0a5f"; + value = hex"000000000000000000000000dec4d949cf1a2e824ee4f8b12064e166b96171dd"; vm.store(anchorStateRegistryProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; diff --git a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofsCode.sol b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofsCode.sol index a980e26c22f2..e68d91067864 100644 --- a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofsCode.sol +++ b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofsCode.sol @@ -47,7 +47,7 @@ contract DeploymentSummaryFaultProofsCode { bytes internal constant l1CrossDomainMessengerCode = hex"60806040526004361061018b5760003560e01c80636425666b116100d6578063b1b1b2091161007f578063d764ad0b11610059578063d764ad0b1461049b578063db505d80146104ae578063ecc70428146104db57600080fd5b8063b1b1b2091461042b578063b28ade251461045b578063c0c53b8b1461047b57600080fd5b80638cbeeef2116100b05780638cbeeef2146102d05780639fce812c146103d0578063a4e7f8bd146103fb57600080fd5b80636425666b146103775780636e296e45146103a457806383a74074146103b957600080fd5b80633dbb202b1161013857806354fd4d501161011257806354fd4d50146102e65780635644cfdf1461033c5780635c975abb1461035257600080fd5b80633dbb202b146102935780633f827a5a146102a85780634c1d6a69146102d057600080fd5b80632828d7e8116101695780632828d7e81461022457806333d7e2bd1461023957806335e80ab31461026657600080fd5b8063028f85f7146101905780630c568498146101c35780630ff754ea146101d8575b600080fd5b34801561019c57600080fd5b506101a5601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101cf57600080fd5b506101a5603f81565b3480156101e457600080fd5b5060fc5473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ba565b34801561023057600080fd5b506101a5604081565b34801561024557600080fd5b5060fd546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561027257600080fd5b5060fb546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b6102a66102a1366004611bdd565b610540565b005b3480156102b457600080fd5b506102bd600181565b60405161ffff90911681526020016101ba565b3480156102dc57600080fd5b506101a5619c4081565b3480156102f257600080fd5b5061032f6040518060400160405280600c81526020017f322e342e312d626574612e31000000000000000000000000000000000000000081525081565b6040516101ba9190611caf565b34801561034857600080fd5b506101a561138881565b34801561035e57600080fd5b5061036761083d565b60405190151581526020016101ba565b34801561038357600080fd5b5060fc546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103b057600080fd5b506101ff6108d6565b3480156103c557600080fd5b506101a562030d4081565b3480156103dc57600080fd5b5060cf5473ffffffffffffffffffffffffffffffffffffffff166101ff565b34801561040757600080fd5b50610367610416366004611cc9565b60ce6020526000908152604090205460ff1681565b34801561043757600080fd5b50610367610446366004611cc9565b60cb6020526000908152604090205460ff1681565b34801561046757600080fd5b506101a5610476366004611ce2565b6109bd565b34801561048757600080fd5b506102a6610496366004611d36565b610a2b565b6102a66104a9366004611d81565b610ca2565b3480156104ba57600080fd5b5060cf546101ff9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104e757600080fd5b5061053260cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b6040519081526020016101ba565b6105486115d3565b156105e05734156105e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f642076616c7565207769746820637573746f6d2067617320746f6b656e00000060648201526084015b60405180910390fd5b60cf546107129073ffffffffffffffffffffffffffffffffffffffff166106088585856109bd565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061067460cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016106909796959493929190611e50565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611612565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561079760cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b866040516107a9959493929190611eaf565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60fb54604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156108ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d19190611efd565b905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016109a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084016105d7565b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f6109d9604063ffffffff8816611f4e565b6109e39190611f7e565b6109ee601088611f4e565b6109fb9062030d40611fcc565b610a059190611fcc565b610a0f9190611fcc565b610a199190611fcc565b610a239190611fcc565b949350505050565b6000547501000000000000000000000000000000000000000000900460ff1615808015610a76575060005460017401000000000000000000000000000000000000000090910460ff16105b80610aa85750303b158015610aa8575060005474010000000000000000000000000000000000000000900460ff166001145b610b34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016105d7565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790558015610bba57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b60fb805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560fc805486841690831617905560fd805492851692909116919091179055610c397342000000000000000000000000000000000000076116ab565b8015610c9c57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b610caa61083d565b15610d11576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f43726f7373446f6d61696e4d657373656e6765723a207061757365640000000060448201526064016105d7565b60f087901c60028110610dcc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016105d7565b8061ffff16600003610ec1576000610e1d878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506117e7915050565b600081815260cb602052604090205490915060ff1615610ebf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016105d7565b505b6000610f07898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061180692505050565b9050610f11611829565b15610f4957853414610f2557610f25611ff8565b600081815260ce602052604090205460ff1615610f4457610f44611ff8565b61109b565b3415610ffd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016105d7565b600081815260ce602052604090205460ff1661109b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016105d7565b6110a487611905565b15611157576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016105d7565b600081815260cb602052604090205460ff16156111f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016105d7565b61121785611208611388619c40611fcc565b67ffffffffffffffff1661194b565b158061123d575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561135657600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161134f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016105d7565b50506115ae565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a1617905560006113e788619c405a6113aa9190612027565b8988888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061196992505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801561149d57600082815260cb602052604090205460ff161561143a5761143a611ff8565b600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26115aa565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016115aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016105d7565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6000806115de611981565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b60fc546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c4290849061167390889083908990600090899060040161203e565b6000604051808303818588803b15801561168c57600080fd5b505af11580156116a0573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611756576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105d7565b60cc5473ffffffffffffffffffffffffffffffffffffffff166117a05760cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b60cf80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006117f585858585611a1e565b805190602001209050949350505050565b6000611816878787878787611ab7565b8051906020012090509695505050505050565b60fc5460009073ffffffffffffffffffffffffffffffffffffffff16331480156108d1575060cf5460fc54604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691639bf62d82916004808201926020929091908290030181865afa1580156118c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e99190612096565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff8216301480611945575060fc5473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000806000835160208501868989f195945050505050565b60fd54604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa1580156119f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1591906120b3565b90939092509050565b606084848484604051602401611a3794939291906120f3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b6060868686868686604051602401611ad49695949392919061213d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611b7857600080fd5b50565b60008083601f840112611b8d57600080fd5b50813567ffffffffffffffff811115611ba557600080fd5b602083019150836020828501011115611bbd57600080fd5b9250929050565b803563ffffffff81168114611bd857600080fd5b919050565b60008060008060608587031215611bf357600080fd5b8435611bfe81611b56565b9350602085013567ffffffffffffffff811115611c1a57600080fd5b611c2687828801611b7b565b9094509250611c39905060408601611bc4565b905092959194509250565b6000815180845260005b81811015611c6a57602081850181015186830182015201611c4e565b81811115611c7c576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611cc26020830184611c44565b9392505050565b600060208284031215611cdb57600080fd5b5035919050565b600080600060408486031215611cf757600080fd5b833567ffffffffffffffff811115611d0e57600080fd5b611d1a86828701611b7b565b9094509250611d2d905060208501611bc4565b90509250925092565b600080600060608486031215611d4b57600080fd5b8335611d5681611b56565b92506020840135611d6681611b56565b91506040840135611d7681611b56565b809150509250925092565b600080600080600080600060c0888a031215611d9c57600080fd5b873596506020880135611dae81611b56565b95506040880135611dbe81611b56565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611de857600080fd5b611df48a828b01611b7b565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611ea260c083018486611e07565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611edf608083018688611e07565b905083604083015263ffffffff831660608301529695505050505050565b600060208284031215611f0f57600080fd5b81518015158114611cc257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611f7557611f75611f1f565b02949350505050565b600067ffffffffffffffff80841680611fc0577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611fef57611fef611f1f565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b60008282101561203957612039611f1f565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a06080820152600061208b60a0830184611c44565b979650505050505050565b6000602082840312156120a857600080fd5b8151611cc281611b56565b600080604083850312156120c657600080fd5b82516120d181611b56565b602084015190925060ff811681146120e857600080fd5b809150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152506080604083015261212c6080830185611c44565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261218860c0830184611c44565b9897505050505050505056fea164736f6c634300080f000a"; bytes internal constant optimismMintableERC20FactoryCode = - hex"60806040523480156200001157600080fd5b5060043610620000935760003560e01c8063c4d66de81162000062578063c4d66de81462000175578063ce5ac90f146200018e578063e78cea9214620001a5578063ee9a31a214620001c657600080fd5b8063316b3739146200009857806354fd4d5014620000fb578063896f93d114620001475780638cf0629c146200015e575b600080fd5b620000d1620000a936600462000652565b60026020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b620001386040518060400160405280600d81526020017f312e31302e312d626574612e310000000000000000000000000000000000000081525081565b604051620000f29190620006e5565b620000d162000158366004620007dc565b620001e5565b620000d16200016f36600462000859565b620001fc565b6200018c6200018636600462000652565b6200041b565b005b620000d16200019f366004620007dc565b620005ed565b600154620000d19073ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff16620000d1565b6000620001f4848484620005ed565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff8516620002a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b600085858585604051602001620002c29493929190620008f0565b604051602081830303815290604052805190602001209050600081600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168888888860405162000312906200061a565b620003229594939291906200094a565b8190604051809103906000f590508015801562000343573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff81811660008181526002602052604080822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016948d1694851790555193945090927fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf9190a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054610100900460ff16158080156200043c5750600054600160ff909116105b80620004585750303b15801562000458575060005460ff166001145b620004e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200029e565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156200054557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790558015620005e957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6000620001f48484846012620001fc565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61178a80620009b083390190565b803573ffffffffffffffffffffffffffffffffffffffff811681146200064d57600080fd5b919050565b6000602082840312156200066557600080fd5b620006708262000628565b9392505050565b6000815180845260005b818110156200069f5760208185018101518683018201520162000681565b81811115620006b2576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600062000670602083018462000677565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200073b57600080fd5b813567ffffffffffffffff80821115620007595762000759620006fa565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620007a257620007a2620006fa565b81604052838152866020858801011115620007bc57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215620007f257600080fd5b620007fd8462000628565b9250602084013567ffffffffffffffff808211156200081b57600080fd5b620008298783880162000729565b935060408601359150808211156200084057600080fd5b506200084f8682870162000729565b9150509250925092565b600080600080608085870312156200087057600080fd5b6200087b8562000628565b9350602085013567ffffffffffffffff808211156200089957600080fd5b620008a78883890162000729565b94506040870135915080821115620008be57600080fd5b50620008cd8782880162000729565b925050606085013560ff81168114620008e557600080fd5b939692955090935050565b73ffffffffffffffffffffffffffffffffffffffff8516815260806020820152600062000921608083018662000677565b828103604084015262000935818662000677565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a060408301526200098560a083018662000677565b828103606084015262000999818662000677565b91505060ff83166080830152969550505050505056fe60e06040523480156200001157600080fd5b506040516200178a3803806200178a833981016040819052620000349162000163565b828260036200004483826200029e565b5060046200005382826200029e565b5050506001600160a01b039384166080529390921660a052505060ff1660c0526200036a565b80516001600160a01b03811681146200009157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000be57600080fd5b81516001600160401b0380821115620000db57620000db62000096565b604051601f8301601f19908116603f0116810190828211818310171562000106576200010662000096565b816040528381526020925086838588010111156200012357600080fd5b600091505b8382101562000147578582018301518183018401529082019062000128565b83821115620001595760008385830101525b9695505050505050565b600080600080600060a086880312156200017c57600080fd5b620001878662000079565b9450620001976020870162000079565b60408701519094506001600160401b0380821115620001b557600080fd5b620001c389838a01620000ac565b94506060880151915080821115620001da57600080fd5b50620001e988828901620000ac565b925050608086015160ff811681146200020157600080fd5b809150509295509295909350565b600181811c908216806200022457607f821691505b6020821081036200024557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029957600081815260208120601f850160051c81016020861015620002745750805b601f850160051c820191505b81811015620002955782815560010162000280565b5050505b505050565b81516001600160401b03811115620002ba57620002ba62000096565b620002d281620002cb84546200020f565b846200024b565b602080601f8311600181146200030a5760008415620002f15750858301515b600019600386901b1c1916600185901b17855562000295565b600085815260208120601f198616915b828110156200033b578886015182559484019460019091019084016200031a565b50858210156200035a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c0516113d4620003b6600039600061024401526000818161034b015281816103e001528181610625015261075c0152600081816101a9015261037101526113d46000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610395578063e78cea9214610349578063ee9a31a2146103db57600080fd5b8063ae1f6aaf14610349578063c01e1bd61461036f578063d6c0b2c41461036f57600080fd5b80639dc29fac116100bd5780639dc29fac14610310578063a457c2d714610323578063a9059cbb1461033657600080fd5b806370a08231146102d257806395d89b411461030857600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a36600461117d565b610402565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104f3565b60405161019b91906111c6565b61018f610213366004611262565b610585565b6002545b60405190815260200161019b565b61018f61023836600461128c565b61059d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611262565b6105c1565b61029461028f366004611262565b61060d565b005b6101f86040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61021c6102e03660046112c8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610735565b61029461031e366004611262565b610744565b61018f610331366004611262565b61085b565b61018f610344366004611262565b61092c565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c6103a33660046112e3565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104bb57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104ea57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461050290611316565b80601f016020809104026020016040519081016040528092919081815260200182805461052e90611316565b801561057b5780601f106105505761010080835404028352916020019161057b565b820191906000526020600020905b81548152906001019060200180831161055e57829003601f168201915b5050505050905090565b60003361059381858561093a565b5060019392505050565b6000336105ab858285610aee565b6105b6858585610bc5565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906105939082908690610608908790611398565b61093a565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106e18282610e78565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161072991815260200190565b60405180910390a25050565b60606004805461050290611316565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016106ce565b6108138282610f98565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161072991815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561091f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016106ce565b6105b6828686840361093a565b600033610593818585610bc5565b73ffffffffffffffffffffffffffffffffffffffff83166109dc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bbf5781811015610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106ce565b610bbf848484840361093a565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610d0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e05908490611398565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e6b91815260200190565b60405180910390a3610bbf565b73ffffffffffffffffffffffffffffffffffffffff8216610ef5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106ce565b8060026000828254610f079190611398565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f41908490611398565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff821661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156110f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812083830390556002805484929061112d9084906113b0565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610ae1565b60006020828403121561118f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146111bf57600080fd5b9392505050565b600060208083528351808285015260005b818110156111f3578581018301518582016040015282016111d7565b81811115611205576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461125d57600080fd5b919050565b6000806040838503121561127557600080fd5b61127e83611239565b946020939093013593505050565b6000806000606084860312156112a157600080fd5b6112aa84611239565b92506112b860208501611239565b9150604084013590509250925092565b6000602082840312156112da57600080fd5b6111bf82611239565b600080604083850312156112f657600080fd5b6112ff83611239565b915061130d60208401611239565b90509250929050565b600181811c9082168061132a57607f821691505b602082108103611363577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156113ab576113ab611369565b500190565b6000828210156113c2576113c2611369565b50039056fea164736f6c634300080f000aa164736f6c634300080f000a"; + hex"60806040523480156200001157600080fd5b5060043610620000935760003560e01c8063c4d66de81162000062578063c4d66de81462000175578063ce5ac90f146200018e578063e78cea9214620001a5578063ee9a31a214620001c657600080fd5b8063316b3739146200009857806354fd4d5014620000fb578063896f93d114620001475780638cf0629c146200015e575b600080fd5b620000d1620000a936600462000652565b60026020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b620001386040518060400160405280600d81526020017f312e31302e312d626574612e310000000000000000000000000000000000000081525081565b604051620000f29190620006e5565b620000d162000158366004620007dc565b620001e5565b620000d16200016f36600462000859565b620001fc565b6200018c6200018636600462000652565b6200041b565b005b620000d16200019f366004620007dc565b620005ed565b600154620000d19073ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff16620000d1565b6000620001f4848484620005ed565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff8516620002a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b600085858585604051602001620002c29493929190620008f0565b604051602081830303815290604052805190602001209050600081600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168888888860405162000312906200061a565b620003229594939291906200094a565b8190604051809103906000f590508015801562000343573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff81811660008181526002602052604080822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016948d1694851790555193945090927fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf9190a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054610100900460ff16158080156200043c5750600054600160ff909116105b80620004585750303b15801562000458575060005460ff166001145b620004e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200029e565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156200054557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790558015620005e957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6000620001f48484846012620001fc565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61178a80620009b083390190565b803573ffffffffffffffffffffffffffffffffffffffff811681146200064d57600080fd5b919050565b6000602082840312156200066557600080fd5b620006708262000628565b9392505050565b6000815180845260005b818110156200069f5760208185018101518683018201520162000681565b81811115620006b2576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600062000670602083018462000677565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200073b57600080fd5b813567ffffffffffffffff80821115620007595762000759620006fa565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620007a257620007a2620006fa565b81604052838152866020858801011115620007bc57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215620007f257600080fd5b620007fd8462000628565b9250602084013567ffffffffffffffff808211156200081b57600080fd5b620008298783880162000729565b935060408601359150808211156200084057600080fd5b506200084f8682870162000729565b9150509250925092565b600080600080608085870312156200087057600080fd5b6200087b8562000628565b9350602085013567ffffffffffffffff808211156200089957600080fd5b620008a78883890162000729565b94506040870135915080821115620008be57600080fd5b50620008cd8782880162000729565b925050606085013560ff81168114620008e557600080fd5b939692955090935050565b73ffffffffffffffffffffffffffffffffffffffff8516815260806020820152600062000921608083018662000677565b828103604084015262000935818662000677565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a060408301526200098560a083018662000677565b828103606084015262000999818662000677565b91505060ff83166080830152969550505050505056fe60e06040523480156200001157600080fd5b506040516200178a3803806200178a833981016040819052620000349162000163565b828260036200004483826200029e565b5060046200005382826200029e565b5050506001600160a01b039384166080529390921660a052505060ff1660c0526200036a565b80516001600160a01b03811681146200009157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000be57600080fd5b81516001600160401b0380821115620000db57620000db62000096565b604051601f8301601f19908116603f0116810190828211818310171562000106576200010662000096565b816040528381526020925086838588010111156200012357600080fd5b600091505b8382101562000147578582018301518183018401529082019062000128565b83821115620001595760008385830101525b9695505050505050565b600080600080600060a086880312156200017c57600080fd5b620001878662000079565b9450620001976020870162000079565b60408701519094506001600160401b0380821115620001b557600080fd5b620001c389838a01620000ac565b94506060880151915080821115620001da57600080fd5b50620001e988828901620000ac565b925050608086015160ff811681146200020157600080fd5b809150509295509295909350565b600181811c908216806200022457607f821691505b6020821081036200024557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029957600081815260208120601f850160051c81016020861015620002745750805b601f850160051c820191505b81811015620002955782815560010162000280565b5050505b505050565b81516001600160401b03811115620002ba57620002ba62000096565b620002d281620002cb84546200020f565b846200024b565b602080601f8311600181146200030a5760008415620002f15750858301515b600019600386901b1c1916600185901b17855562000295565b600085815260208120601f198616915b828110156200033b578886015182559484019460019091019084016200031a565b50858210156200035a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c0516113d4620003b6600039600061024401526000818161034b015281816103e001528181610625015261075c0152600081816101a9015261037101526113d46000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610395578063e78cea9214610349578063ee9a31a2146103db57600080fd5b8063ae1f6aaf14610349578063c01e1bd61461036f578063d6c0b2c41461036f57600080fd5b80639dc29fac116100bd5780639dc29fac14610310578063a457c2d714610323578063a9059cbb1461033657600080fd5b806370a08231146102d257806395d89b411461030857600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a36600461117d565b610402565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104f3565b60405161019b91906111c6565b61018f610213366004611262565b610585565b6002545b60405190815260200161019b565b61018f61023836600461128c565b61059d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611262565b6105c1565b61029461028f366004611262565b61060d565b005b6101f86040518060400160405280600c81526020017f312e332e312d626574612e31000000000000000000000000000000000000000081525081565b61021c6102e03660046112c8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610735565b61029461031e366004611262565b610744565b61018f610331366004611262565b61085b565b61018f610344366004611262565b61092c565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c6103a33660046112e3565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104bb57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104ea57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461050290611316565b80601f016020809104026020016040519081016040528092919081815260200182805461052e90611316565b801561057b5780601f106105505761010080835404028352916020019161057b565b820191906000526020600020905b81548152906001019060200180831161055e57829003601f168201915b5050505050905090565b60003361059381858561093a565b5060019392505050565b6000336105ab858285610aee565b6105b6858585610bc5565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906105939082908690610608908790611398565b61093a565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106e18282610e78565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161072991815260200190565b60405180910390a25050565b60606004805461050290611316565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016106ce565b6108138282610f98565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161072991815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561091f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016106ce565b6105b6828686840361093a565b600033610593818585610bc5565b73ffffffffffffffffffffffffffffffffffffffff83166109dc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bbf5781811015610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106ce565b610bbf848484840361093a565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610d0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e05908490611398565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e6b91815260200190565b60405180910390a3610bbf565b73ffffffffffffffffffffffffffffffffffffffff8216610ef5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106ce565b8060026000828254610f079190611398565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f41908490611398565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff821661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156110f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812083830390556002805484929061112d9084906113b0565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610ae1565b60006020828403121561118f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146111bf57600080fd5b9392505050565b600060208083528351808285015260005b818110156111f3578581018301518582016040015282016111d7565b81811115611205576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461125d57600080fd5b919050565b6000806040838503121561127557600080fd5b61127e83611239565b946020939093013593505050565b6000806000606084860312156112a157600080fd5b6112aa84611239565b92506112b860208501611239565b9150604084013590509250925092565b6000602082840312156112da57600080fd5b6111bf82611239565b600080604083850312156112f657600080fd5b6112ff83611239565b915061130d60208401611239565b90509250929050565b600181811c9082168061132a57607f821691505b602082108103611363577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156113ab576113ab611369565b500190565b6000828210156113c2576113c2611369565b50039056fea164736f6c634300080f000aa164736f6c634300080f000a"; bytes internal constant systemConfigCode = hex"608060405234801561001057600080fd5b50600436106102de5760003560e01c8063a711986911610186578063e0e2016d116100e3578063f2fde38b11610097578063f8c68de011610071578063f8c68de0146106e2578063fd32aa0f146106ea578063ffa1ad74146106f257600080fd5b8063f2fde38b146106b2578063f45e65d8146106c5578063f68016b7146106ce57600080fd5b8063e81b2c6d116100c8578063e81b2c6d14610681578063ec7075171461068a578063f2b4e617146106aa57600080fd5b8063e0e2016d14610671578063e2a3285c1461067957600080fd5b8063c9b26f611161013a578063d84447151161011f578063d84447151461064e578063dac6e63a14610656578063db9040fa1461065e57600080fd5b8063c9b26f6114610507578063cc731b021461051a57600080fd5b8063bc49ce5f1161016b578063bc49ce5f146104c6578063bfb14fb7146104ce578063c4e8ddfa146104ff57600080fd5b8063a7119869146104ab578063b40a817c146104b357600080fd5b80634397dfef1161023f578063550fcdc9116101f35780638da5cb5b116101cd5780638da5cb5b14610472578063935f029e146104905780639b7d7f0a146104a357600080fd5b8063550fcdc91461045a5780635d73369c14610462578063715018a61461046a57600080fd5b80634add321d116102245780634add321d146103e95780634f16540b146103f157806354fd4d501461041857600080fd5b80634397dfef146103ab57806348cd4cb1146103e157600080fd5b806318d13918116102965780631fd19ee11161027b5780631fd19ee114610378578063213268491461038057806321d7fde51461039857600080fd5b806318d139181461035b57806319f5cea81461037057600080fd5b80630a49cb03116102c75780630a49cb031461032b5780630ae14b1b146103335780630c18c1621461035257600080fd5b806306c92657146102e3578063078f29cf146102fe575b600080fd5b6102eb6106fa565b6040519081526020015b60405180910390f35b610306610728565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102f5565b610306610761565b630bebc2005b60405167ffffffffffffffff90911681526020016102f5565b6102eb60655481565b61036e610369366004612241565b610791565b005b6102eb6107a5565b6103066107d0565b6103886107fa565b60405190151581526020016102f5565b61036e6103a6366004612277565b610839565b6103b361084f565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835260ff9091166020830152016102f5565b6102eb610863565b610339610893565b6102eb7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b60408051808201909152600c81527f322e332e302d626574612e33000000000000000000000000000000000000000060208201525b6040516102f59190612320565b61044d6108b9565b6102eb6108c3565b61036e6108ee565b60335473ffffffffffffffffffffffffffffffffffffffff16610306565b61036e61049e366004612333565b610902565b610306610914565b610306610944565b61036e6104c136600461236d565b610974565b6102eb610985565b6068546104ea9068010000000000000000900463ffffffff1681565b60405163ffffffff90911681526020016102f5565b6103066109b0565b61036e610515366004612388565b6109e0565b6105de6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b6040516102f59190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b61044d6109f1565b6103066109fb565b61036e61066c3660046124bb565b610a2b565b6102eb610e36565b6102eb610e61565b6102eb60675481565b6068546104ea906c01000000000000000000000000900463ffffffff1681565b610306610e8c565b61036e6106c0366004612241565b610ebc565b6102eb60665481565b6068546103399067ffffffffffffffff1681565b6102eb610f70565b6102eb610f9b565b6102eb600081565b61072560017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b81565b600061075c61075860017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b5490565b905090565b600061075c61075860017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b610799611201565b6107a281611282565b50565b61072560017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b600061075c7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b60008061080561084f565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b610841611201565b61084b828261133f565b5050565b60008061085a611184565b90939092509050565b600061075c61075860017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b60695460009061075c9063ffffffff6a0100000000000000000000820481169116612654565b606061075c61147d565b61072560017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b6108f6611201565b610900600061153e565b565b61090a611201565b61084b82826115b5565b600061075c61075860017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b600061075c61075860017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b61097c611201565b6107a28161168b565b61072560017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b600061075c61075860017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b6109e8611201565b6107a2816117e1565b606061075c611809565b600061075c61075860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b600054610100900460ff1615808015610a4b5750600054600160ff909116105b80610a655750303b158015610a65575060005460ff166001145b610af6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610b5457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b5c6118bf565b610b658a610ebc565b610b6e876117e1565b610b78898961133f565b610b818661168b565b610baa7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08869055565b610bdd610bd860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59861263d565b849055565b610c11610c0b60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063761263d565b83519055565b610c48610c3f60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a861263d565b60208401519055565b610c7f610c7660017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b60408401519055565b610cb6610cad60017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b60608401519055565b610ced610ce460017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b60808401519055565b610d24610d1b60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d61263d565b60a08401519055565b610d2c61195e565b610d398260c001516119c6565b610d4284611cd0565b610d4a610893565b67ffffffffffffffff168667ffffffffffffffff161015610dc7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b8015610e2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b61072560017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b61072560017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b600061075c61075860017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa90761263d565b610ec4611201565b73ffffffffffffffffffffffffffffffffffffffff8116610f67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610aed565b6107a28161153e565b61072560017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637761263d565b61072560017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad61263d565b9055565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600060208251111561107a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f476173506179696e67546f6b656e3a20737472696e672063616e6e6f7420626560448201527f2067726561746572207468616e203332206279746573000000000000000000006064820152608401610aed565b6110838261115b565b92915050565b6110ef6110b760017f04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec61263d565b74ff000000000000000000000000000000000000000060a086901b1673ffffffffffffffffffffffffffffffffffffffff8716179055565b61112261111d60017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d61263d565b839055565b61115561115060017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd0576461263d565b829055565b50505050565b8051602181106111735763ec92f9a36000526004601cfd5b9081015160209190910360031b1b90565b600080806111b661075860017f04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec61263d565b73ffffffffffffffffffffffffffffffffffffffff811693509050826111f5575073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee92601292509050565b60a081901c9150509091565b60335473ffffffffffffffffffffffffffffffffffffffff163314610900576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610aed565b6112ab7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060035b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be836040516113339190612320565b60405180910390a35050565b606880547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000063ffffffff8581169182027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16929092176c0100000000000000000000000092851692909202919091179091557f0100000000000000000000000000000000000000000000000000000000000000602083811b67ffffffff000000001690921717606681905560655460408051938401919091528201526000906060015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be836040516114709190612320565b60405180910390a3505050565b60606000611489611184565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff82160161150257505060408051808201909152600381527f4554480000000000000000000000000000000000000000000000000000000000602082015290565b61153861153361075860017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd0576461263d565b612144565b91505090565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b7fff00000000000000000000000000000000000000000000000000000000000000811615611665576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f53797374656d436f6e6669673a207363616c61722065786365656473206d617860448201527f2e000000000000000000000000000000000000000000000000000000000000006064820152608401610aed565b60658290556066819055604080516020810184905290810182905260009060600161140d565b611693610893565b67ffffffffffffffff168167ffffffffffffffff161015611710576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b630bebc20067ffffffffffffffff82161115611788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f20686967686044820152606401610aed565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002611302565b6067819055604080516020808201849052825180830390910181529082019091526000611302565b60606000611815611184565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff82160161188e57505060408051808201909152600581527f4574686572000000000000000000000000000000000000000000000000000000602082015290565b61153861153361075860017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d61263d565b600054610100900460ff16611956576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610aed565b610900612178565b61198c61075860017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b600003610900576109006119c160017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a061263d565b439055565b73ffffffffffffffffffffffffffffffffffffffff811615801590611a15575073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14155b8015611a265750611a246107fa565b155b156107a257601260ff168173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a9f9190612680565b60ff1614611b2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f53797374656d436f6e6669673a2062616420646563696d616c73206f6620676160448201527f7320706179696e6720746f6b656e0000000000000000000000000000000000006064820152608401610aed565b6000611bca8273ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015611b7f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611bc5919081019061269d565b610fe6565b90506000611c1c8373ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611b7f573d6000803e3d6000fd5b9050611c2b8360128484611089565b611c33610761565b6040517f71cfaa3f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015260126024830152604482018590526064820184905291909116906371cfaa3f90608401600060405180830381600087803b158015611cb357600080fd5b505af1158015611cc7573d6000803e3d6000fd5b50505050505050565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff161115611d80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d6178206261736500000000000000000000006064820152608401610aed565b6001816040015160ff1611611e17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e203100000000000000000000000000000000006064820152608401610aed565b6068546080820151825167ffffffffffffffff90921691611e389190612768565b63ffffffff161115611ea6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610aed565b6000816020015160ff1611611f3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f74206265203000000000000000000000000000000000006064820152608401610aed565b8051602082015163ffffffff82169160ff90911690611f5d908290612787565b611f6791906127d1565b63ffffffff1614611ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d69740000000000000000006064820152608401610aed565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b60405160005b82811a1561215a5760010161214a565b80825260208201838152600082820152505060408101604052919050565b600054610100900460ff1661220f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610aed565b6109003361153e565b803573ffffffffffffffffffffffffffffffffffffffff8116811461223c57600080fd5b919050565b60006020828403121561225357600080fd5b61225c82612218565b9392505050565b803563ffffffff8116811461223c57600080fd5b6000806040838503121561228a57600080fd5b61229383612263565b91506122a160208401612263565b90509250929050565b60005b838110156122c55781810151838201526020016122ad565b838111156111555750506000910152565b600081518084526122ee8160208601602086016122aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061225c60208301846122d6565b6000806040838503121561234657600080fd5b50508035926020909101359150565b803567ffffffffffffffff8116811461223c57600080fd5b60006020828403121561237f57600080fd5b61225c82612355565b60006020828403121561239a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff811182821017156123f3576123f36123a1565b60405290565b60ff811681146107a257600080fd5b600060e0828403121561241a57600080fd5b60405160e0810181811067ffffffffffffffff8211171561243d5761243d6123a1565b60405290508061244c83612218565b815261245a60208401612218565b602082015261246b60408401612218565b604082015261247c60608401612218565b606082015261248d60808401612218565b608082015261249e60a08401612218565b60a08201526124af60c08401612218565b60c08201525092915050565b6000806000806000806000806000898b036102808112156124db57600080fd5b6124e48b612218565b99506124f260208c01612263565b985061250060408c01612263565b975060608b0135965061251560808c01612355565b955061252360a08c01612218565b945060c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff408201121561255557600080fd5b5061255e6123d0565b61256a60c08c01612263565b815260e08b013561257a816123f9565b60208201526101008b013561258e816123f9565b60408201526125a06101208c01612263565b60608201526125b26101408c01612263565b60808201526101608b01356fffffffffffffffffffffffffffffffff811681146125db57600080fd5b60a082015292506125ef6101808b01612218565b91506125ff8b6101a08c01612408565b90509295985092959850929598565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561264f5761264f61260e565b500390565b600067ffffffffffffffff8083168185168083038211156126775761267761260e565b01949350505050565b60006020828403121561269257600080fd5b815161225c816123f9565b6000602082840312156126af57600080fd5b815167ffffffffffffffff808211156126c757600080fd5b818401915084601f8301126126db57600080fd5b8151818111156126ed576126ed6123a1565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612733576127336123a1565b8160405282815287602084870101111561274c57600080fd5b61275d8360208301602088016122aa565b979650505050505050565b600063ffffffff8083168185168083038211156126775761267761260e565b600063ffffffff808416806127c5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff808316818516818304811182151516156127f4576127f461260e565b0294935050505056fea164736f6c634300080f000a"; bytes internal constant l1StandardBridgeCode = @@ -63,15 +63,15 @@ contract DeploymentSummaryFaultProofsCode { bytes internal constant disputeGameFactoryCode = hex"6080604052600436106100e85760003560e01c80636593dc6e1161008a57806396cd97201161005957806396cd972014610313578063bb8aa1fc14610333578063c4d66de814610394578063f2fde38b146103b457600080fd5b80636593dc6e14610293578063715018a6146102c057806382ecf2f6146102d55780638da5cb5b146102e857600080fd5b8063254bd683116100c6578063254bd6831461019c5780634d1975b4146101c957806354fd4d50146101e85780635f0150cb1461023e57600080fd5b806314f6b1a3146100ed5780631b685b9e1461010f5780631e3342401461017c575b600080fd5b3480156100f957600080fd5b5061010d6101083660046110c6565b6103d4565b005b34801561011b57600080fd5b5061015261012a3660046110fd565b60656020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061010d610197366004611118565b61045e565b3480156101a857600080fd5b506101bc6101b7366004611142565b6104aa565b60405161017391906111ef565b3480156101d557600080fd5b506068545b604051908152602001610173565b3480156101f457600080fd5b506102316040518060400160405280600c81526020017f312e302e312d626574612e31000000000000000000000000000000000000000081525081565b60405161017391906112ac565b34801561024a57600080fd5b5061025e6102593660046112bf565b6106ee565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff909116602083015201610173565b34801561029f57600080fd5b506101da6102ae3660046110fd565b60666020526000908152604090205481565b3480156102cc57600080fd5b5061010d610741565b6101526102e33660046112bf565b610755565b3480156102f457600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff16610152565b34801561031f57600080fd5b506101da61032e3660046112bf565b6109ef565b34801561033f57600080fd5b5061035361034e366004611346565b610a28565b6040805163ffffffff909416845267ffffffffffffffff909216602084015273ffffffffffffffffffffffffffffffffffffffff1690820152606001610173565b3480156103a057600080fd5b5061010d6103af36600461135f565b610a91565b3480156103c057600080fd5b5061010d6103cf36600461135f565b610c2d565b6103dc610d00565b63ffffffff821660008181526065602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616908117909155905190917fff513d80e2c7fa487608f70a618dfbc0cf415699dc69588c747e8c71566c88de91a35050565b610466610d00565b63ffffffff8216600081815260666020526040808220849055518392917f74d6665c4b26d5596a5aa13d3014e0c06af4d322075a797f87b03cd4c5bc91ca91a35050565b606854606090831015806104bc575081155b6106e7575060408051600583901b8101602001909152825b8381116106e5576000606882815481106104f0576104f061137c565b600091825260209091200154905060e081901c60a082901c67ffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff831663ffffffff891683036106b6576001865101865260008173ffffffffffffffffffffffffffffffffffffffff1663609d33346040518163ffffffff1660e01b8152600401600060405180830381865afa15801561058a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d091908101906113da565b905060008273ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561061f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064391906114a5565b90506040518060a001604052808881526020018781526020018567ffffffffffffffff168152602001828152602001838152508860018a5161068591906114be565b815181106106955761069561137c565b6020026020010181905250888851106106b3575050505050506106e5565b50505b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191506104d49050565b505b9392505050565b60008060006106ff878787876109ef565b60009081526067602052604090205473ffffffffffffffffffffffffffffffffffffffff81169860a09190911c67ffffffffffffffff16975095505050505050565b610749610d00565b6107536000610d81565b565b63ffffffff841660009081526065602052604081205473ffffffffffffffffffffffffffffffffffffffff16806107c5576040517f031c6de400000000000000000000000000000000000000000000000000000000815263ffffffff871660048201526024015b60405180910390fd5b63ffffffff86166000908152606660205260409020543414610813576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006108206001436114be565b40905061088a338783888860405160200161083f9594939291906114fc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905273ffffffffffffffffffffffffffffffffffffffff841690610df8565b92508273ffffffffffffffffffffffffffffffffffffffff16638129fc1c346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156108d457600080fd5b505af11580156108e8573d6000803e3d6000fd5b505050505060006108fb888888886109ef565b60008181526067602052604090205490915015610947576040517f014f6fe5000000000000000000000000000000000000000000000000000000008152600481018290526024016107bc565b60004260a01b60e08a901b178517600083815260676020526040808220839055606880546001810182559083527fa2153420d844928b4421650203c77babc8b33d7f2e7b450e2966db0c220977530183905551919250899163ffffffff8c169173ffffffffffffffffffffffffffffffffffffffff8916917f5b565efe82411da98814f356d0e7bcb8f0219b8d970307c5afb4a6903a8b2e359190a450505050949350505050565b600084848484604051602001610a089493929190611549565b604051602081830303815290604052805190602001209050949350505050565b600080600080600080610a8160688881548110610a4757610a4761137c565b906000526020600020015460e081901c9160a082901c67ffffffffffffffff169173ffffffffffffffffffffffffffffffffffffffff1690565b9199909850909650945050505050565b600054610100900460ff1615808015610ab15750600054600160ff909116105b80610acb5750303b158015610acb575060005460ff166001145b610b57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107bc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610bb557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610bbd610e06565b610bc682610d81565b8015610c2957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b610c35610d00565b73ffffffffffffffffffffffffffffffffffffffff8116610cd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016107bc565b610ce181610d81565b50565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60335473ffffffffffffffffffffffffffffffffffffffff163314610753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107bc565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006106e760008484610ea5565b600054610100900460ff16610e9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b610753610feb565b600060608203516040830351602084035184518060208701018051600283016c5af43d3d93803e606057fd5bf3895289600d8a035278593da1005b363d3d373d3d3d3d610000806062363936013d738160481b1760218a03527f9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff603a8a035272fd6100003d81600a3d39f336602c57343d527f6062820160781b1761ff9e82106059018a03528060f01b8352606c8101604c8a038cf097505086610f715763301164256000526004601cfd5b905285527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08501527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa09092019190915292915050565b600054610100900460ff16611082576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b61075333610d81565b803563ffffffff8116811461109f57600080fd5b919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610ce157600080fd5b600080604083850312156110d957600080fd5b6110e28361108b565b915060208301356110f2816110a4565b809150509250929050565b60006020828403121561110f57600080fd5b6106e78261108b565b6000806040838503121561112b57600080fd5b6111348361108b565b946020939093013593505050565b60008060006060848603121561115757600080fd5b6111608461108b565b95602085013595506040909401359392505050565b60005b83811015611190578181015183820152602001611178565b8381111561119f576000848401525b50505050565b600081518084526111bd816020860160208601611175565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561129e578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001855281518051845287810151888501528681015167ffffffffffffffff16878501526060808201519085015260809081015160a09185018290529061128a818601836111a5565b968901969450505090860190600101611216565b509098975050505050505050565b6020815260006106e760208301846111a5565b600080600080606085870312156112d557600080fd5b6112de8561108b565b935060208501359250604085013567ffffffffffffffff8082111561130257600080fd5b818701915087601f83011261131657600080fd5b81358181111561132557600080fd5b88602082850101111561133757600080fd5b95989497505060200194505050565b60006020828403121561135857600080fd5b5035919050565b60006020828403121561137157600080fd5b81356106e7816110a4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156113ec57600080fd5b815167ffffffffffffffff8082111561140457600080fd5b818401915084601f83011261141857600080fd5b81518181111561142a5761142a6113ab565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611470576114706113ab565b8160405282815287602084870101111561148957600080fd5b61149a836020830160208801611175565b979650505050505050565b6000602082840312156114b757600080fd5b5051919050565b6000828210156114f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500390565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008660601b1681528460148201528360348201528183605483013760009101605401908152949350505050565b63ffffffff8516815283602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101939250505056fea164736f6c634300080f000a"; bytes internal constant delayedWETHCode = - hex"6080604052600436106101845760003560e01c8063715018a6116100d6578063a9059cbb1161007f578063dd62ed3e11610059578063dd62ed3e1461051c578063f2fde38b14610554578063f3fef3a31461057457610193565b8063a9059cbb146104a8578063cd47bde1146104c8578063d0e30db01461019357610193565b80638da5cb5b116100b05780638da5cb5b1461041757806395d89b4114610442578063977a5ec51461048857610193565b8063715018a61461039057806379502c55146103a55780637eee288d146103f757610193565b80632e1a7d4d1161013857806354fd4d501161011257806354fd4d50146102e75780636a42b8f81461033057806370a082311461036357610193565b80632e1a7d4d14610280578063313ce567146102a0578063485cc955146102c757610193565b80630ca35682116101695780630ca356821461022357806318160ddd1461024357806323b872dd1461026057610193565b806306fdde031461019b578063095ea7b3146101f357610193565b3661019357610191610594565b005b610191610594565b3480156101a757600080fd5b5060408051808201909152600d81527f577261707065642045746865720000000000000000000000000000000000000060208201525b6040516101ea91906113fd565b60405180910390f35b3480156101ff57600080fd5b5061021361020e366004611492565b6105ef565b60405190151581526020016101ea565b34801561022f57600080fd5b5061019161023e3660046114be565b610668565b34801561024f57600080fd5b50475b6040519081526020016101ea565b34801561026c57600080fd5b5061021361027b3660046114d7565b6107b9565b34801561028c57600080fd5b5061019161029b3660046114be565b6109d0565b3480156102ac57600080fd5b506102b5601281565b60405160ff90911681526020016101ea565b3480156102d357600080fd5b506101916102e2366004611518565b6109dd565b3480156102f357600080fd5b506101dd6040518060400160405280600a81526020017f312e312e302d72632e310000000000000000000000000000000000000000000081525081565b34801561033c57600080fd5b507f0000000000000000000000000000000000000000000000000000000000093a80610252565b34801561036f57600080fd5b5061025261037e366004611551565b60656020526000908152604090205481565b34801561039c57600080fd5b50610191610bb9565b3480156103b157600080fd5b506068546103d29073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ea565b34801561040357600080fd5b50610191610412366004611492565b610bcd565b34801561042357600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff166103d2565b34801561044e57600080fd5b5060408051808201909152600481527f574554480000000000000000000000000000000000000000000000000000000060208201526101dd565b34801561049457600080fd5b506101916104a3366004611492565b610c21565b3480156104b457600080fd5b506102136104c3366004611492565b610d0e565b3480156104d457600080fd5b506105076104e3366004611518565b60676020908152600092835260408084209091529082529020805460019091015482565b604080519283526020830191909152016101ea565b34801561052857600080fd5b50610252610537366004611518565b606660209081526000928352604080842090915290825290205481565b34801561056057600080fd5b5061019161056f366004611551565b610d22565b34801561058057600080fd5b5061019161058f366004611492565b610dd6565b33600090815260656020526040812080543492906105b390849061159d565b909155505060405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b33600081815260666020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106579086815260200190565b60405180910390a350600192915050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064015b60405180910390fd5b60004782106106fd57476106ff565b815b604051909150600090339083908381818185875af1925050503d8060008114610744576040519150601f19603f3d011682016040523d82523d6000602084013e610749565b606091505b50509050806107b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f44656c61796564574554483a207265636f766572206661696c6564000000000060448201526064016106e5565b505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152606560205260408120548211156107eb57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610861575073ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156108e95773ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091529020548211156108a357600080fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152606660209081526040808320338452909152812080548492906108e39084906115b5565b90915550505b73ffffffffffffffffffffffffffffffffffffffff84166000908152606560205260408120805484929061091e9084906115b5565b909155505073ffffffffffffffffffffffffffffffffffffffff83166000908152606560205260408120805484929061095890849061159d565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109be91815260200190565b60405180910390a35060019392505050565b6109da3382610dd6565b50565b600054610100900460ff16158080156109fd5750600054600160ff909116105b80610a175750303b158015610a17575060005460ff166001145b610aa3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016106e5565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610b0157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b09611120565b610b12836111bf565b606880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617905580156107b457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b610bc1611236565b610bcb60006111bf565b565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120426001820155805490918391839190610c1790849061159d565b9091555050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610ca2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064016106e5565b73ffffffffffffffffffffffffffffffffffffffff821660008181526066602090815260408083203380855290835292819020859055518481529192917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a35050565b6000610d1b3384846107b9565b9392505050565b610d2a611236565b73ffffffffffffffffffffffffffffffffffffffff8116610dcd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016106e5565b6109da816111bf565b606860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6791906115cc565b15610ece576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f44656c61796564574554483a20636f6e7472616374206973207061757365640060448201526064016106e5565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290208054821115610f8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f44656c61796564574554483a20696e73756666696369656e7420756e6c6f636b60448201527f6564207769746864726177616c0000000000000000000000000000000000000060648201526084016106e5565b6000816001015411611022576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f44656c61796564574554483a207769746864726177616c206e6f7420756e6c6f60448201527f636b65640000000000000000000000000000000000000000000000000000000060648201526084016106e5565b427f0000000000000000000000000000000000000000000000000000000000093a808260010154611053919061159d565b11156110e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f44656c61796564574554483a207769746864726177616c2064656c6179206e6f60448201527f74206d657400000000000000000000000000000000000000000000000000000060648201526084016106e5565b818160000160008282546110f591906115b5565b909155506107b49050826112b7565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff166111b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106e5565b610bcb61135d565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610bcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106e5565b336000908152606560205260409020548111156112d357600080fd5b33600090815260656020526040812080548392906112f29084906115b5565b9091555050604051339082156108fc029083906000818181858888f19350505050158015611324573d6000803e3d6000fd5b5060405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a250565b600054610100900460ff166113f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106e5565b610bcb336111bf565b600060208083528351808285015260005b8181101561142a5785810183015185820160400152820161140e565b8181111561143c576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146109da57600080fd5b600080604083850312156114a557600080fd5b82356114b081611470565b946020939093013593505050565b6000602082840312156114d057600080fd5b5035919050565b6000806000606084860312156114ec57600080fd5b83356114f781611470565b9250602084013561150781611470565b929592945050506040919091013590565b6000806040838503121561152b57600080fd5b823561153681611470565b9150602083013561154681611470565b809150509250929050565b60006020828403121561156357600080fd5b8135610d1b81611470565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115b0576115b061156e565b500190565b6000828210156115c7576115c761156e565b500390565b6000602082840312156115de57600080fd5b81518015158114610d1b57600080fdfea164736f6c634300080f000a"; + hex"6080604052600436106101845760003560e01c8063715018a6116100d6578063a9059cbb1161007f578063dd62ed3e11610059578063dd62ed3e1461051c578063f2fde38b14610554578063f3fef3a31461057457610193565b8063a9059cbb146104a8578063cd47bde1146104c8578063d0e30db01461019357610193565b80638da5cb5b116100b05780638da5cb5b1461041757806395d89b4114610442578063977a5ec51461048857610193565b8063715018a61461039057806379502c55146103a55780637eee288d146103f757610193565b80632e1a7d4d1161013857806354fd4d501161011257806354fd4d50146102e75780636a42b8f81461033057806370a082311461036357610193565b80632e1a7d4d14610280578063313ce567146102a0578063485cc955146102c757610193565b80630ca35682116101695780630ca356821461022357806318160ddd1461024357806323b872dd1461026057610193565b806306fdde031461019b578063095ea7b3146101f357610193565b3661019357610191610594565b005b610191610594565b3480156101a757600080fd5b5060408051808201909152600d81527f577261707065642045746865720000000000000000000000000000000000000060208201525b6040516101ea91906113fd565b60405180910390f35b3480156101ff57600080fd5b5061021361020e366004611492565b6105ef565b60405190151581526020016101ea565b34801561022f57600080fd5b5061019161023e3660046114be565b610668565b34801561024f57600080fd5b50475b6040519081526020016101ea565b34801561026c57600080fd5b5061021361027b3660046114d7565b6107b9565b34801561028c57600080fd5b5061019161029b3660046114be565b6109d0565b3480156102ac57600080fd5b506102b5601281565b60405160ff90911681526020016101ea565b3480156102d357600080fd5b506101916102e2366004611518565b6109dd565b3480156102f357600080fd5b506101dd6040518060400160405280600c81526020017f312e312e312d626574612e32000000000000000000000000000000000000000081525081565b34801561033c57600080fd5b507f0000000000000000000000000000000000000000000000000000000000093a80610252565b34801561036f57600080fd5b5061025261037e366004611551565b60656020526000908152604090205481565b34801561039c57600080fd5b50610191610bb9565b3480156103b157600080fd5b506068546103d29073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ea565b34801561040357600080fd5b50610191610412366004611492565b610bcd565b34801561042357600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff166103d2565b34801561044e57600080fd5b5060408051808201909152600481527f574554480000000000000000000000000000000000000000000000000000000060208201526101dd565b34801561049457600080fd5b506101916104a3366004611492565b610c21565b3480156104b457600080fd5b506102136104c3366004611492565b610d0e565b3480156104d457600080fd5b506105076104e3366004611518565b60676020908152600092835260408084209091529082529020805460019091015482565b604080519283526020830191909152016101ea565b34801561052857600080fd5b50610252610537366004611518565b606660209081526000928352604080842090915290825290205481565b34801561056057600080fd5b5061019161056f366004611551565b610d22565b34801561058057600080fd5b5061019161058f366004611492565b610dd6565b33600090815260656020526040812080543492906105b390849061159d565b909155505060405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b33600081815260666020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106579086815260200190565b60405180910390a350600192915050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064015b60405180910390fd5b60004782106106fd57476106ff565b815b604051909150600090339083908381818185875af1925050503d8060008114610744576040519150601f19603f3d011682016040523d82523d6000602084013e610749565b606091505b50509050806107b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f44656c61796564574554483a207265636f766572206661696c6564000000000060448201526064016106e5565b505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152606560205260408120548211156107eb57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610861575073ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156108e95773ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091529020548211156108a357600080fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152606660209081526040808320338452909152812080548492906108e39084906115b5565b90915550505b73ffffffffffffffffffffffffffffffffffffffff84166000908152606560205260408120805484929061091e9084906115b5565b909155505073ffffffffffffffffffffffffffffffffffffffff83166000908152606560205260408120805484929061095890849061159d565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109be91815260200190565b60405180910390a35060019392505050565b6109da3382610dd6565b50565b600054610100900460ff16158080156109fd5750600054600160ff909116105b80610a175750303b158015610a17575060005460ff166001145b610aa3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016106e5565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610b0157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b09611120565b610b12836111bf565b606880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617905580156107b457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b610bc1611236565b610bcb60006111bf565b565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120426001820155805490918391839190610c1790849061159d565b9091555050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610ca2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064016106e5565b73ffffffffffffffffffffffffffffffffffffffff821660008181526066602090815260408083203380855290835292819020859055518481529192917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a35050565b6000610d1b3384846107b9565b9392505050565b610d2a611236565b73ffffffffffffffffffffffffffffffffffffffff8116610dcd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016106e5565b6109da816111bf565b606860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6791906115cc565b15610ece576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f44656c61796564574554483a20636f6e7472616374206973207061757365640060448201526064016106e5565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290208054821115610f8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f44656c61796564574554483a20696e73756666696369656e7420756e6c6f636b60448201527f6564207769746864726177616c0000000000000000000000000000000000000060648201526084016106e5565b6000816001015411611022576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f44656c61796564574554483a207769746864726177616c206e6f7420756e6c6f60448201527f636b65640000000000000000000000000000000000000000000000000000000060648201526084016106e5565b427f0000000000000000000000000000000000000000000000000000000000093a808260010154611053919061159d565b11156110e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f44656c61796564574554483a207769746864726177616c2064656c6179206e6f60448201527f74206d657400000000000000000000000000000000000000000000000000000060648201526084016106e5565b818160000160008282546110f591906115b5565b909155506107b49050826112b7565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff166111b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106e5565b610bcb61135d565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610bcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106e5565b336000908152606560205260409020548111156112d357600080fd5b33600090815260656020526040812080548392906112f29084906115b5565b9091555050604051339082156108fc029083906000818181858888f19350505050158015611324573d6000803e3d6000fd5b5060405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a250565b600054610100900460ff166113f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106e5565b610bcb336111bf565b600060208083528351808285015260005b8181101561142a5785810183015185820160400152820161140e565b8181111561143c576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146109da57600080fd5b600080604083850312156114a557600080fd5b82356114b081611470565b946020939093013593505050565b6000602082840312156114d057600080fd5b5035919050565b6000806000606084860312156114ec57600080fd5b83356114f781611470565b9250602084013561150781611470565b929592945050506040919091013590565b6000806040838503121561152b57600080fd5b823561153681611470565b9150602083013561154681611470565b809150509250929050565b60006020828403121561156357600080fd5b8135610d1b81611470565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115b0576115b061156e565b500190565b6000828210156115c7576115c761156e565b500390565b6000602082840312156115de57600080fd5b81518015158114610d1b57600080fdfea164736f6c634300080f000a"; bytes internal constant preimageOracleCode = - hex"6080604052600436106101d85760003560e01c80639d53a64811610102578063ddcd58de11610095578063ec5efcbc11610064578063ec5efcbc14610681578063f3f480d9146106a1578063faf37bc7146106d4578063fef2b4ed146106e757600080fd5b8063ddcd58de146105d4578063e03110e11461060c578063e159261114610641578063ea7139501461066157600080fd5b8063b5e7154c116100d1578063b5e7154c14610555578063d18534b51461056c578063da35c6641461058c578063dd24f9bf146105a157600080fd5b80639d53a6481461048e5780639d7e8769146104dd578063b2e67ba8146104fd578063b4801e611461053557600080fd5b806361238bde1161017a5780637ac54767116101495780637ac54767146103ca5780638542cf50146103ea578063882856ef146104355780638dc4be111461046e57600080fd5b806361238bde1461031e5780636551927b146103565780637051472e1461038e5780637917de1d146103aa57600080fd5b80633909af5c116101b65780633909af5c146102715780634d52b4c91461029357806352f0f3ad146102a857806354fd4d50146102c857600080fd5b8063013cf08b146101dd5780630359a5631461022e5780632055b36b1461025c575b600080fd5b3480156101e957600080fd5b506101fd6101f8366004612e29565b610714565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526020830191909152015b60405180910390f35b34801561023a57600080fd5b5061024e610249366004612e6b565b610759565b604051908152602001610225565b34801561026857600080fd5b5061024e601081565b34801561027d57600080fd5b5061029161028c366004613073565b610891565b005b34801561029f57600080fd5b5061024e610ae8565b3480156102b457600080fd5b5061024e6102c336600461315f565b610b03565b3480156102d457600080fd5b506103116040518060400160405280600a81526020017f312e312e322d72632e310000000000000000000000000000000000000000000081525081565b60405161022591906131c6565b34801561032a57600080fd5b5061024e610339366004613217565b600160209081526000928352604080842090915290825290205481565b34801561036257600080fd5b5061024e610371366004612e6b565b601560209081526000928352604080842090915290825290205481565b34801561039a57600080fd5b5061024e6703782dace9d9000081565b3480156103b657600080fd5b506102916103c536600461327b565b610bd9565b3480156103d657600080fd5b5061024e6103e5366004612e29565b6110dc565b3480156103f657600080fd5b50610425610405366004613217565b600260209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610225565b34801561044157600080fd5b50610455610450366004613317565b6110f3565b60405167ffffffffffffffff9091168152602001610225565b34801561047a57600080fd5b5061029161048936600461334a565b61114d565b34801561049a57600080fd5b5061024e6104a9366004612e6b565b73ffffffffffffffffffffffffffffffffffffffff9091166000908152601860209081526040808320938352929052205490565b3480156104e957600080fd5b506102916104f8366004613396565b611248565b34801561050957600080fd5b5061024e610518366004612e6b565b601760209081526000928352604080842090915290825290205481565b34801561054157600080fd5b5061024e610550366004613317565b6113ff565b34801561056157600080fd5b5061024e620186a081565b34801561057857600080fd5b50610291610587366004613073565b611431565b34801561059857600080fd5b5060135461024e565b3480156105ad57600080fd5b507f000000000000000000000000000000000000000000000000000000000000271061024e565b3480156105e057600080fd5b5061024e6105ef366004612e6b565b601660209081526000928352604080842090915290825290205481565b34801561061857600080fd5b5061062c610627366004613217565b611840565b60408051928352602083019190915201610225565b34801561064d57600080fd5b5061029161065c36600461334a565b611931565b34801561066d57600080fd5b5061029161067c366004613422565b611a39565b34801561068d57600080fd5b5061029161069c366004613491565b611b98565b3480156106ad57600080fd5b507f000000000000000000000000000000000000000000000000000000000000007861024e565b6102916106e2366004613519565b611d1e565b3480156106f357600080fd5b5061024e610702366004612e29565b60006020819052908152604090205481565b6013818154811061072457600080fd5b60009182526020909120600290910201805460019091015473ffffffffffffffffffffffffffffffffffffffff909116915082565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601560209081526040808320848452909152812054819061079c9060601c63ffffffff1690565b63ffffffff16905060005b6010811015610889578160011660010361082f5773ffffffffffffffffffffffffffffffffffffffff85166000908152601460209081526040808320878452909152902081601081106107fc576107fc613555565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250610870565b826003826010811061084357610843613555565b01546040805160208101939093528201526060016040516020818303038152906040528051906020012092505b60019190911c9080610881816135b3565b9150506107a7565b505092915050565b600061089d8a8a610759565b90506108c086868360208b01356108bb6108b68d6135eb565b611fea565b61202a565b80156108de57506108de83838360208801356108bb6108b68a6135eb565b610914576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b86604001358860405160200161092a91906136ba565b6040516020818303038152906040528051906020012014610977576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83602001358760200135600161098d91906136f8565b146109c4576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a0c886109d28680613710565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061208b92505050565b610a15886121e6565b836040013588604051602001610a2b91906136ba565b6040516020818303038152906040528051906020012003610a78576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8a1660009081526015602090815260408083208c8452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055610adc8a8a3361298e565b50505050505050505050565b6001610af660106002613897565b610b0091906138a3565b81565b6000610b0f8686612a47565b9050610b1c8360086136f8565b82101580610b2a5750602083115b15610b61576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b60608115610bf257610beb8686612af4565b9050610c2c565b85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050505b3360009081526014602090815260408083208b845290915280822081516102008101928390529160109082845b815481526020019060010190808311610c5957505050505090506000601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b81526020019081526020016000205490506000610cda8260601c63ffffffff1690565b63ffffffff169050333214610d1b576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d2b8260801c63ffffffff1690565b63ffffffff16600003610d6a576040517f87138d5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d748260c01c90565b67ffffffffffffffff1615610db5576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b898114610dee576040517f60f95d5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610dfb89898d8886612b6d565b83516020850160888204881415608883061715610e20576307b1daf16000526004601cfd5b60405160c8810160405260005b83811015610ed0578083018051835260208101516020840152604081015160408401526060810151606084015260808101516080840152508460888301526088810460051b8b013560a883015260c882206001860195508560005b610200811015610ec5576001821615610ea55782818b0152610ec5565b8981015160009081526020938452604090209260019290921c9101610e88565b505050608801610e2d565b50505050600160106002610ee49190613897565b610eee91906138a3565b811115610f27576040517f6229572300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f9c610f3a8360401c63ffffffff1690565b610f4a9063ffffffff168a6136f8565b60401b7fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff606084901b167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff8516171790565b915084156110295777ffffffffffffffffffffffffffffffffffffffffffffffff82164260c01b179150610fd68260801c63ffffffff1690565b63ffffffff16610fec8360401c63ffffffff1690565b63ffffffff1614611029576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526014602090815260408083208e8452909152902061104f90846010612d9f565b503360008181526018602090815260408083208f8452825280832080546001810182559084528284206004820401805460039092166008026101000a67ffffffffffffffff818102199093164390931602919091179055838352601582528083208f8452909152812084905560609190911b81523690601437366014016000a05050505050505050505050565b600381601081106110ec57600080fd5b0154905081565b6018602052826000526040600020602052816000526040600020818154811061111b57600080fd5b906000526020600020906004918282040191900660080292509250509054906101000a900467ffffffffffffffff1681565b60443560008060088301861061116b5763fe2549876000526004601cfd5b60c083901b60805260888386823786600882030151915060206000858360025afa90508061119857600080fd5b50600080517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0400000000000000000000000000000000000000000000000000000000000000178082526002602090815260408084208a8552825280842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558385528252808420998452988152888320939093558152908190529490942055505050565b600080603087600037602060006030600060025afa806112705763f91129696000526004601cfd5b6000517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f010000000000000000000000000000000000000000000000000000000000000017608081815260a08c905260c08b905260308a60e037603088609083013760008060c083600a5afa9250826112f2576309bde3396000526004601cfd5b602886106113085763fe2549876000526004601cfd5b6000602882015278200000000000000000000000000000000000000000000000008152600881018b905285810151935060308a8237603081019b909b52505060509098207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0500000000000000000000000000000000000000000000000000000000000000176000818152600260209081526040808320868452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209583529481528482209a909a559081528089529190912096909655505050505050565b6014602052826000526040600020602052816000526040600020816010811061142757600080fd5b0154925083915050565b73ffffffffffffffffffffffffffffffffffffffff891660009081526015602090815260408083208b845290915290205467ffffffffffffffff8116156114a4576040517fc334f06900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114ae8160c01c90565b67ffffffffffffffff166000036114f1576040517f55d4cbf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000007861151c8260c01c90565b6115309067ffffffffffffffff16426138a3565b11611567576040517f55d4cbf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006115738b8b610759565b905061158c87878360208c01356108bb6108b68e6135eb565b80156115aa57506115aa84848360208901356108bb6108b68b6135eb565b6115e0576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8760400135896040516020016115f691906136ba565b6040516020818303038152906040528051906020012014611643576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84602001358860200135600161165991906136f8565b14158061168b575060016116738360601c63ffffffff1690565b61167d91906138ba565b63ffffffff16856020013514155b156116c2576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116d0896109d28780613710565b6116d9896121e6565b60006116e48a612cc0565b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0200000000000000000000000000000000000000000000000000000000000000179050600061173b8460a01c63ffffffff1690565b67ffffffffffffffff169050600160026000848152602001908152602001600020600083815260200190815260200160002060006101000a81548160ff021916908315150217905550601760008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008d8152602001908152602001600020546001600084815260200190815260200160002060008381526020019081526020016000208190555061180d8460801c63ffffffff1690565b600083815260208190526040902063ffffffff9190911690556118318d8d8161298e565b50505050505050505050505050565b6000828152600260209081526040808320848452909152812054819060ff166118c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546118e58160086136f8565b6118f08560206136f8565b1061190e57836119018260086136f8565b61190b91906138a3565b91505b506000938452600160209081526040808620948652939052919092205492909150565b60443560008060088301861061194f5763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b60008060008060808860601b81528760c01b6014820152858782601c0137601c860181207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0600000000000000000000000000000000000000000000000000000000000000179350604088026260216001603f5a021015611ac35763dd629f866000526004601cfd5b6000808783601c018c5afa94503d6001019150600882018a10611aee5763fe2549876000526004601cfd5b60c082901b81526008018481533d6000600183013e89017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8015160008481526002602090815260408083208d8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915587845282528083209c83529b81528b8220929092559384528390529790912096909655505050505050565b6000611ba48686610759565b9050611bbd83838360208801356108bb6108b68a6135eb565b611bf3576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602084013515611c2f576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c37612ddd565b611c45816109d28780613710565b611c4e816121e6565b846040013581604051602001611c6491906136ba565b6040516020818303038152906040528051906020012003611cb1576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166000908152601560209081526040808320898452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055611d1587873361298e565b50505050505050565b6703782dace9d90000341015611d60576040517fe92c469f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333214611d99576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611da48160086138df565b63ffffffff168263ffffffff1610611de8576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000027108163ffffffff161015611e48576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152601560209081526040808320868452909152902054611e738160801c63ffffffff1690565b63ffffffff1615611eb0576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608082901b7fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff60a085901b167fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff83161717336000818152601560209081526040808320898452825280832094909455835180850185528381528082018981526013805460018101825590855291517f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a090600290930292830180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055517f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0919091015591815260168252828120968152959052909320349055505050565b600081600001518260200151836040015160405160200161200d93929190613907565b604051602081830303815290604052805190602001209050919050565b60008160005b601081101561207e578060051b880135600186831c16600181146120635760008481526020839052604090209350612074565b600082815260208590526040902093505b5050600101612030565b5090931495945050505050565b608881511461209957600080fd5b602081016020830161211a565b8260031b8201518060001a8160011a60081b178160021a60101b8260031a60181b17178160041a60201b8260051a60281b178260061a60301b8360071a60381b1717179050612114816120ff868560059190911b015190565b1867ffffffffffffffff16600586901b840152565b50505050565b612126600083836120a6565b612132600183836120a6565b61213e600283836120a6565b61214a600383836120a6565b612156600483836120a6565b612162600583836120a6565b61216e600683836120a6565b61217a600783836120a6565b612186600883836120a6565b612192600983836120a6565b61219e600a83836120a6565b6121aa600b83836120a6565b6121b6600c83836120a6565b6121c2600d83836120a6565b6121ce600e83836120a6565b6121da600f83836120a6565b612114601083836120a6565b6040805178010000000000008082800000000000808a8000000080008000602082015279808b00000000800000018000000080008081800000000000800991810191909152788a00000000000000880000000080008009000000008000000a60608201527b8000808b800000000000008b8000000000008089800000000000800360808201527f80000000000080028000000000000080000000000000800a800000008000000a60a08201527f800000008000808180000000000080800000000080000001800000008000800860c082015260009060e0016040516020818303038152906040529050602082016020820161286e565b6102808101516101e082015161014083015160a0840151845118189118186102a082015161020083015161016084015160c0850151602086015118189118186102c083015161022084015161018085015160e0860151604087015118189118186102e08401516102408501516101a0860151610100870151606088015118189118186103008501516102608601516101c0870151610120880151608089015118189118188084603f1c6123998660011b67ffffffffffffffff1690565b18188584603f1c6123b48660011b67ffffffffffffffff1690565b18188584603f1c6123cf8660011b67ffffffffffffffff1690565b181895508483603f1c6123ec8560011b67ffffffffffffffff1690565b181894508387603f1c6124098960011b67ffffffffffffffff1690565b60208b01518b51861867ffffffffffffffff168c5291189190911897508118600181901b603f9190911c18935060c08801518118601481901c602c9190911b1867ffffffffffffffff1660208901526101208801518718602c81901c60149190911b1867ffffffffffffffff1660c08901526102c08801518618600381901c603d9190911b1867ffffffffffffffff166101208901526101c08801518718601981901c60279190911b1867ffffffffffffffff166102c08901526102808801518218602e81901c60129190911b1867ffffffffffffffff166101c089015260408801518618600281901c603e9190911b1867ffffffffffffffff166102808901526101808801518618601581901c602b9190911b1867ffffffffffffffff1660408901526101a08801518518602781901c60199190911b1867ffffffffffffffff166101808901526102608801518718603881901c60089190911b1867ffffffffffffffff166101a08901526102e08801518518600881901c60389190911b1867ffffffffffffffff166102608901526101e08801518218601781901c60299190911b1867ffffffffffffffff166102e089015260808801518718602581901c601b9190911b1867ffffffffffffffff166101e08901526103008801518718603281901c600e9190911b1867ffffffffffffffff1660808901526102a08801518118603e81901c60029190911b1867ffffffffffffffff166103008901526101008801518518600981901c60379190911b1867ffffffffffffffff166102a08901526102008801518118601381901c602d9190911b1867ffffffffffffffff1661010089015260a08801518218601c81901c60249190911b1867ffffffffffffffff1661020089015260608801518518602481901c601c9190911b1867ffffffffffffffff1660a08901526102408801518518602b81901c60159190911b1867ffffffffffffffff1660608901526102208801518618603181901c600f9190911b1867ffffffffffffffff166102408901526101608801518118603681901c600a9190911b1867ffffffffffffffff166102208901525060e08701518518603a81901c60069190911b1867ffffffffffffffff166101608801526101408701518118603d81901c60039190911b1867ffffffffffffffff1660e0880152505067ffffffffffffffff81166101408601525b5050505050565b600582811b8201805160018501831b8401805160028701851b8601805160038901871b8801805160048b0190981b8901805167ffffffffffffffff861985168918811690995283198a16861889169096528819861683188816909352841986168818871690528419831684189095169052919391929190611d15565b612808600082612781565b612813600582612781565b61281e600a82612781565b612829600f82612781565b612834601482612781565b50565b612840816122dc565b612849816127fd565b600383901b820151815160c09190911c9061211490821867ffffffffffffffff168352565b61287a60008284612837565b61288660018284612837565b61289260028284612837565b61289e60038284612837565b6128aa60048284612837565b6128b660058284612837565b6128c260068284612837565b6128ce60078284612837565b6128da60088284612837565b6128e660098284612837565b6128f2600a8284612837565b6128fe600b8284612837565b61290a600c8284612837565b612916600d8284612837565b612922600e8284612837565b61292e600f8284612837565b61293a60108284612837565b61294660118284612837565b61295260128284612837565b61295e60138284612837565b61296a60148284612837565b61297660158284612837565b61298260168284612837565b61211460178284612837565b73ffffffffffffffffffffffffffffffffffffffff83811660009081526016602090815260408083208684529091528082208054908390559051909284169083908381818185875af1925050503d8060008114612a07576040519150601f19603f3d011682016040523d82523d6000602084013e612a0c565b606091505b505090508061277a576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831617612aed818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b6060604051905081602082018181018286833760888306808015612b3d5760888290038501848101848103803687375060806001820353506001845160001a1784538652612b54565b608836843760018353608060878401536088850186525b5050505050601f19603f82510116810160405292915050565b6000612b7f8260a01c63ffffffff1690565b67ffffffffffffffff1690506000612b9d8360801c63ffffffff1690565b63ffffffff1690506000612bb78460401c63ffffffff1690565b63ffffffff169050600883108015612bcd575080155b15612c015760c082901b6000908152883560085283513382526017602090815260408084208a855290915290912055612cb6565b60088310158015612c1f575080612c196008856138a3565b93508310155b8015612c335750612c3087826136f8565b83105b15612cb6576000612c4482856138a3565b905087612c528260206136f8565b10158015612c5e575085155b15612c95576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526017602090815260408083208a845290915290209089013590555b5050505050505050565b6000612d43565b66ff00ff00ff00ff8160081c1667ff00ff00ff00ff00612cf18360081b67ffffffffffffffff1690565b1617905065ffff0000ffff8160101c1667ffff0000ffff0000612d1e8360101b67ffffffffffffffff1690565b1617905060008160201c612d3c8360201b67ffffffffffffffff1690565b1792915050565b60808201516020830190612d5b90612cc7565b612cc7565b6040820151612d6990612cc7565b60401b17612d81612d5660018460059190911b015190565b825160809190911b90612d9390612cc7565b60c01b17179392505050565b8260108101928215612dcd579160200282015b82811115612dcd578251825591602001919060010190612db2565b50612dd9929150612df5565b5090565b6040518060200160405280612df0612e0a565b905290565b5b80821115612dd95760008155600101612df6565b6040518061032001604052806019906020820280368337509192915050565b600060208284031215612e3b57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612e6657600080fd5b919050565b60008060408385031215612e7e57600080fd5b612e8783612e42565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610320810167ffffffffffffffff81118282101715612ee857612ee8612e95565b60405290565b6040516060810167ffffffffffffffff81118282101715612ee857612ee8612e95565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612f5857612f58612e95565b604052919050565b803567ffffffffffffffff81168114612e6657600080fd5b6000610320808385031215612f8c57600080fd5b604051602080820182811067ffffffffffffffff82111715612fb057612fb0612e95565b806040525081935085601f860112612fc757600080fd5b612fcf612ec4565b928501928087851115612fe157600080fd5b865b8581101561300157612ff481612f60565b8352918301918301612fe3565b509092525091949350505050565b60006060828403121561302157600080fd5b50919050565b60008083601f84011261303957600080fd5b50813567ffffffffffffffff81111561305157600080fd5b6020830191508360208260051b850101111561306c57600080fd5b9250929050565b60008060008060008060008060006103e08a8c03121561309257600080fd5b61309b8a612e42565b985060208a013597506130b18b60408c01612f78565b96506103608a013567ffffffffffffffff808211156130cf57600080fd5b6130db8d838e0161300f565b97506103808c01359150808211156130f257600080fd5b6130fe8d838e01613027565b90975095506103a08c013591508082111561311857600080fd5b6131248d838e0161300f565b94506103c08c013591508082111561313b57600080fd5b506131488c828d01613027565b915080935050809150509295985092959850929598565b600080600080600060a0868803121561317757600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60005b838110156131b557818101518382015260200161319d565b838111156121145750506000910152565b60208152600082518060208401526131e581604085016020870161319a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000806040838503121561322a57600080fd5b50508035926020909101359150565b60008083601f84011261324b57600080fd5b50813567ffffffffffffffff81111561326357600080fd5b60208301915083602082850101111561306c57600080fd5b600080600080600080600060a0888a03121561329657600080fd5b8735965060208801359550604088013567ffffffffffffffff808211156132bc57600080fd5b6132c88b838c01613239565b909750955060608a01359150808211156132e157600080fd5b506132ee8a828b01613027565b9094509250506080880135801515811461330757600080fd5b8091505092959891949750929550565b60008060006060848603121561332c57600080fd5b61333584612e42565b95602085013595506040909401359392505050565b60008060006040848603121561335f57600080fd5b83359250602084013567ffffffffffffffff81111561337d57600080fd5b61338986828701613239565b9497909650939450505050565b600080600080600080600060a0888a0312156133b157600080fd5b8735965060208801359550604088013567ffffffffffffffff808211156133d757600080fd5b6133e38b838c01613239565b909750955060608a01359150808211156133fc57600080fd5b506134098a828b01613239565b989b979a50959894979596608090950135949350505050565b60008060008060006080868803121561343a57600080fd5b8535945061344a60208701612e42565b935061345860408701612f60565b9250606086013567ffffffffffffffff81111561347457600080fd5b61348088828901613239565b969995985093965092949392505050565b6000806000806000608086880312156134a957600080fd5b6134b286612e42565b945060208601359350604086013567ffffffffffffffff808211156134d657600080fd5b6134e289838a0161300f565b945060608801359150808211156134f857600080fd5b5061348088828901613027565b803563ffffffff81168114612e6657600080fd5b60008060006060848603121561352e57600080fd5b8335925061353e60208501613505565b915061354c60408501613505565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135e4576135e4613584565b5060010190565b6000606082360312156135fd57600080fd5b613605612eee565b823567ffffffffffffffff8082111561361d57600080fd5b9084019036601f83011261363057600080fd5b813560208282111561364457613644612e95565b613674817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011601612f11565b9250818352368183860101111561368a57600080fd5b81818501828501376000918301810191909152908352848101359083015250604092830135928101929092525090565b81516103208201908260005b60198110156136ef57825167ffffffffffffffff168252602092830192909101906001016136c6565b50505092915050565b6000821982111561370b5761370b613584565b500190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261374557600080fd5b83018035915067ffffffffffffffff82111561376057600080fd5b60200191503681900382131561306c57600080fd5b600181815b808511156137ce57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156137b4576137b4613584565b808516156137c157918102915b93841c939080029061377a565b509250929050565b6000826137e557506001613891565b816137f257506000613891565b816001811461380857600281146138125761382e565b6001915050613891565b60ff84111561382357613823613584565b50506001821b613891565b5060208310610133831016604e8410600b8410161715613851575081810a613891565b61385b8383613775565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561388d5761388d613584565b0290505b92915050565b6000612aed83836137d6565b6000828210156138b5576138b5613584565b500390565b600063ffffffff838116908316818110156138d7576138d7613584565b039392505050565b600063ffffffff8083168185168083038211156138fe576138fe613584565b01949350505050565b6000845161391981846020890161319a565b9190910192835250602082015260400191905056fea164736f6c634300080f000a"; + hex"6080604052600436106101d85760003560e01c80639d53a64811610102578063ddcd58de11610095578063ec5efcbc11610064578063ec5efcbc14610681578063f3f480d9146106a1578063faf37bc7146106d4578063fef2b4ed146106e757600080fd5b8063ddcd58de146105d4578063e03110e11461060c578063e159261114610641578063ea7139501461066157600080fd5b8063b5e7154c116100d1578063b5e7154c14610555578063d18534b51461056c578063da35c6641461058c578063dd24f9bf146105a157600080fd5b80639d53a6481461048e5780639d7e8769146104dd578063b2e67ba8146104fd578063b4801e611461053557600080fd5b806361238bde1161017a5780637ac54767116101495780637ac54767146103ca5780638542cf50146103ea578063882856ef146104355780638dc4be111461046e57600080fd5b806361238bde1461031e5780636551927b146103565780637051472e1461038e5780637917de1d146103aa57600080fd5b80633909af5c116101b65780633909af5c146102715780634d52b4c91461029357806352f0f3ad146102a857806354fd4d50146102c857600080fd5b8063013cf08b146101dd5780630359a5631461022e5780632055b36b1461025c575b600080fd5b3480156101e957600080fd5b506101fd6101f8366004612e29565b610714565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526020830191909152015b60405180910390f35b34801561023a57600080fd5b5061024e610249366004612e6b565b610759565b604051908152602001610225565b34801561026857600080fd5b5061024e601081565b34801561027d57600080fd5b5061029161028c366004613073565b610891565b005b34801561029f57600080fd5b5061024e610ae8565b3480156102b457600080fd5b5061024e6102c336600461315f565b610b03565b3480156102d457600080fd5b506103116040518060400160405280600c81526020017f312e312e332d626574612e32000000000000000000000000000000000000000081525081565b60405161022591906131c6565b34801561032a57600080fd5b5061024e610339366004613217565b600160209081526000928352604080842090915290825290205481565b34801561036257600080fd5b5061024e610371366004612e6b565b601560209081526000928352604080842090915290825290205481565b34801561039a57600080fd5b5061024e6703782dace9d9000081565b3480156103b657600080fd5b506102916103c536600461327b565b610bd9565b3480156103d657600080fd5b5061024e6103e5366004612e29565b6110dc565b3480156103f657600080fd5b50610425610405366004613217565b600260209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610225565b34801561044157600080fd5b50610455610450366004613317565b6110f3565b60405167ffffffffffffffff9091168152602001610225565b34801561047a57600080fd5b5061029161048936600461334a565b61114d565b34801561049a57600080fd5b5061024e6104a9366004612e6b565b73ffffffffffffffffffffffffffffffffffffffff9091166000908152601860209081526040808320938352929052205490565b3480156104e957600080fd5b506102916104f8366004613396565b611248565b34801561050957600080fd5b5061024e610518366004612e6b565b601760209081526000928352604080842090915290825290205481565b34801561054157600080fd5b5061024e610550366004613317565b6113ff565b34801561056157600080fd5b5061024e620186a081565b34801561057857600080fd5b50610291610587366004613073565b611431565b34801561059857600080fd5b5060135461024e565b3480156105ad57600080fd5b507f000000000000000000000000000000000000000000000000000000000000271061024e565b3480156105e057600080fd5b5061024e6105ef366004612e6b565b601660209081526000928352604080842090915290825290205481565b34801561061857600080fd5b5061062c610627366004613217565b611840565b60408051928352602083019190915201610225565b34801561064d57600080fd5b5061029161065c36600461334a565b611931565b34801561066d57600080fd5b5061029161067c366004613422565b611a39565b34801561068d57600080fd5b5061029161069c366004613491565b611b98565b3480156106ad57600080fd5b507f000000000000000000000000000000000000000000000000000000000000007861024e565b6102916106e2366004613519565b611d1e565b3480156106f357600080fd5b5061024e610702366004612e29565b60006020819052908152604090205481565b6013818154811061072457600080fd5b60009182526020909120600290910201805460019091015473ffffffffffffffffffffffffffffffffffffffff909116915082565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601560209081526040808320848452909152812054819061079c9060601c63ffffffff1690565b63ffffffff16905060005b6010811015610889578160011660010361082f5773ffffffffffffffffffffffffffffffffffffffff85166000908152601460209081526040808320878452909152902081601081106107fc576107fc613555565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250610870565b826003826010811061084357610843613555565b01546040805160208101939093528201526060016040516020818303038152906040528051906020012092505b60019190911c9080610881816135b3565b9150506107a7565b505092915050565b600061089d8a8a610759565b90506108c086868360208b01356108bb6108b68d6135eb565b611fea565b61202a565b80156108de57506108de83838360208801356108bb6108b68a6135eb565b610914576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b86604001358860405160200161092a91906136ba565b6040516020818303038152906040528051906020012014610977576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83602001358760200135600161098d91906136f8565b146109c4576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a0c886109d28680613710565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061208b92505050565b610a15886121e6565b836040013588604051602001610a2b91906136ba565b6040516020818303038152906040528051906020012003610a78576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8a1660009081526015602090815260408083208c8452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055610adc8a8a3361298e565b50505050505050505050565b6001610af660106002613897565b610b0091906138a3565b81565b6000610b0f8686612a47565b9050610b1c8360086136f8565b82101580610b2a5750602083115b15610b61576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b60608115610bf257610beb8686612af4565b9050610c2c565b85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050505b3360009081526014602090815260408083208b845290915280822081516102008101928390529160109082845b815481526020019060010190808311610c5957505050505090506000601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b81526020019081526020016000205490506000610cda8260601c63ffffffff1690565b63ffffffff169050333214610d1b576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d2b8260801c63ffffffff1690565b63ffffffff16600003610d6a576040517f87138d5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d748260c01c90565b67ffffffffffffffff1615610db5576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b898114610dee576040517f60f95d5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610dfb89898d8886612b6d565b83516020850160888204881415608883061715610e20576307b1daf16000526004601cfd5b60405160c8810160405260005b83811015610ed0578083018051835260208101516020840152604081015160408401526060810151606084015260808101516080840152508460888301526088810460051b8b013560a883015260c882206001860195508560005b610200811015610ec5576001821615610ea55782818b0152610ec5565b8981015160009081526020938452604090209260019290921c9101610e88565b505050608801610e2d565b50505050600160106002610ee49190613897565b610eee91906138a3565b811115610f27576040517f6229572300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f9c610f3a8360401c63ffffffff1690565b610f4a9063ffffffff168a6136f8565b60401b7fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff606084901b167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff8516171790565b915084156110295777ffffffffffffffffffffffffffffffffffffffffffffffff82164260c01b179150610fd68260801c63ffffffff1690565b63ffffffff16610fec8360401c63ffffffff1690565b63ffffffff1614611029576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526014602090815260408083208e8452909152902061104f90846010612d9f565b503360008181526018602090815260408083208f8452825280832080546001810182559084528284206004820401805460039092166008026101000a67ffffffffffffffff818102199093164390931602919091179055838352601582528083208f8452909152812084905560609190911b81523690601437366014016000a05050505050505050505050565b600381601081106110ec57600080fd5b0154905081565b6018602052826000526040600020602052816000526040600020818154811061111b57600080fd5b906000526020600020906004918282040191900660080292509250509054906101000a900467ffffffffffffffff1681565b60443560008060088301861061116b5763fe2549876000526004601cfd5b60c083901b60805260888386823786600882030151915060206000858360025afa90508061119857600080fd5b50600080517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0400000000000000000000000000000000000000000000000000000000000000178082526002602090815260408084208a8552825280842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558385528252808420998452988152888320939093558152908190529490942055505050565b600080603087600037602060006030600060025afa806112705763f91129696000526004601cfd5b6000517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f010000000000000000000000000000000000000000000000000000000000000017608081815260a08c905260c08b905260308a60e037603088609083013760008060c083600a5afa9250826112f2576309bde3396000526004601cfd5b602886106113085763fe2549876000526004601cfd5b6000602882015278200000000000000000000000000000000000000000000000008152600881018b905285810151935060308a8237603081019b909b52505060509098207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0500000000000000000000000000000000000000000000000000000000000000176000818152600260209081526040808320868452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209583529481528482209a909a559081528089529190912096909655505050505050565b6014602052826000526040600020602052816000526040600020816010811061142757600080fd5b0154925083915050565b73ffffffffffffffffffffffffffffffffffffffff891660009081526015602090815260408083208b845290915290205467ffffffffffffffff8116156114a4576040517fc334f06900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114ae8160c01c90565b67ffffffffffffffff166000036114f1576040517f55d4cbf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000007861151c8260c01c90565b6115309067ffffffffffffffff16426138a3565b11611567576040517f55d4cbf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006115738b8b610759565b905061158c87878360208c01356108bb6108b68e6135eb565b80156115aa57506115aa84848360208901356108bb6108b68b6135eb565b6115e0576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8760400135896040516020016115f691906136ba565b6040516020818303038152906040528051906020012014611643576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84602001358860200135600161165991906136f8565b14158061168b575060016116738360601c63ffffffff1690565b61167d91906138ba565b63ffffffff16856020013514155b156116c2576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116d0896109d28780613710565b6116d9896121e6565b60006116e48a612cc0565b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0200000000000000000000000000000000000000000000000000000000000000179050600061173b8460a01c63ffffffff1690565b67ffffffffffffffff169050600160026000848152602001908152602001600020600083815260200190815260200160002060006101000a81548160ff021916908315150217905550601760008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008d8152602001908152602001600020546001600084815260200190815260200160002060008381526020019081526020016000208190555061180d8460801c63ffffffff1690565b600083815260208190526040902063ffffffff9190911690556118318d8d8161298e565b50505050505050505050505050565b6000828152600260209081526040808320848452909152812054819060ff166118c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546118e58160086136f8565b6118f08560206136f8565b1061190e57836119018260086136f8565b61190b91906138a3565b91505b506000938452600160209081526040808620948652939052919092205492909150565b60443560008060088301861061194f5763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b60008060008060808860601b81528760c01b6014820152858782601c0137601c860181207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0600000000000000000000000000000000000000000000000000000000000000179350604088026260216001603f5a021015611ac35763dd629f866000526004601cfd5b6000808783601c018c5afa94503d6001019150600882018a10611aee5763fe2549876000526004601cfd5b60c082901b81526008018481533d6000600183013e89017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8015160008481526002602090815260408083208d8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915587845282528083209c83529b81528b8220929092559384528390529790912096909655505050505050565b6000611ba48686610759565b9050611bbd83838360208801356108bb6108b68a6135eb565b611bf3576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602084013515611c2f576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c37612ddd565b611c45816109d28780613710565b611c4e816121e6565b846040013581604051602001611c6491906136ba565b6040516020818303038152906040528051906020012003611cb1576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166000908152601560209081526040808320898452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055611d1587873361298e565b50505050505050565b6703782dace9d90000341015611d60576040517fe92c469f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333214611d99576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611da48160086138df565b63ffffffff168263ffffffff1610611de8576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000027108163ffffffff161015611e48576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152601560209081526040808320868452909152902054611e738160801c63ffffffff1690565b63ffffffff1615611eb0576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608082901b7fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff60a085901b167fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff83161717336000818152601560209081526040808320898452825280832094909455835180850185528381528082018981526013805460018101825590855291517f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a090600290930292830180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055517f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0919091015591815260168252828120968152959052909320349055505050565b600081600001518260200151836040015160405160200161200d93929190613907565b604051602081830303815290604052805190602001209050919050565b60008160005b601081101561207e578060051b880135600186831c16600181146120635760008481526020839052604090209350612074565b600082815260208590526040902093505b5050600101612030565b5090931495945050505050565b608881511461209957600080fd5b602081016020830161211a565b8260031b8201518060001a8160011a60081b178160021a60101b8260031a60181b17178160041a60201b8260051a60281b178260061a60301b8360071a60381b1717179050612114816120ff868560059190911b015190565b1867ffffffffffffffff16600586901b840152565b50505050565b612126600083836120a6565b612132600183836120a6565b61213e600283836120a6565b61214a600383836120a6565b612156600483836120a6565b612162600583836120a6565b61216e600683836120a6565b61217a600783836120a6565b612186600883836120a6565b612192600983836120a6565b61219e600a83836120a6565b6121aa600b83836120a6565b6121b6600c83836120a6565b6121c2600d83836120a6565b6121ce600e83836120a6565b6121da600f83836120a6565b612114601083836120a6565b6040805178010000000000008082800000000000808a8000000080008000602082015279808b00000000800000018000000080008081800000000000800991810191909152788a00000000000000880000000080008009000000008000000a60608201527b8000808b800000000000008b8000000000008089800000000000800360808201527f80000000000080028000000000000080000000000000800a800000008000000a60a08201527f800000008000808180000000000080800000000080000001800000008000800860c082015260009060e0016040516020818303038152906040529050602082016020820161286e565b6102808101516101e082015161014083015160a0840151845118189118186102a082015161020083015161016084015160c0850151602086015118189118186102c083015161022084015161018085015160e0860151604087015118189118186102e08401516102408501516101a0860151610100870151606088015118189118186103008501516102608601516101c0870151610120880151608089015118189118188084603f1c6123998660011b67ffffffffffffffff1690565b18188584603f1c6123b48660011b67ffffffffffffffff1690565b18188584603f1c6123cf8660011b67ffffffffffffffff1690565b181895508483603f1c6123ec8560011b67ffffffffffffffff1690565b181894508387603f1c6124098960011b67ffffffffffffffff1690565b60208b01518b51861867ffffffffffffffff168c5291189190911897508118600181901b603f9190911c18935060c08801518118601481901c602c9190911b1867ffffffffffffffff1660208901526101208801518718602c81901c60149190911b1867ffffffffffffffff1660c08901526102c08801518618600381901c603d9190911b1867ffffffffffffffff166101208901526101c08801518718601981901c60279190911b1867ffffffffffffffff166102c08901526102808801518218602e81901c60129190911b1867ffffffffffffffff166101c089015260408801518618600281901c603e9190911b1867ffffffffffffffff166102808901526101808801518618601581901c602b9190911b1867ffffffffffffffff1660408901526101a08801518518602781901c60199190911b1867ffffffffffffffff166101808901526102608801518718603881901c60089190911b1867ffffffffffffffff166101a08901526102e08801518518600881901c60389190911b1867ffffffffffffffff166102608901526101e08801518218601781901c60299190911b1867ffffffffffffffff166102e089015260808801518718602581901c601b9190911b1867ffffffffffffffff166101e08901526103008801518718603281901c600e9190911b1867ffffffffffffffff1660808901526102a08801518118603e81901c60029190911b1867ffffffffffffffff166103008901526101008801518518600981901c60379190911b1867ffffffffffffffff166102a08901526102008801518118601381901c602d9190911b1867ffffffffffffffff1661010089015260a08801518218601c81901c60249190911b1867ffffffffffffffff1661020089015260608801518518602481901c601c9190911b1867ffffffffffffffff1660a08901526102408801518518602b81901c60159190911b1867ffffffffffffffff1660608901526102208801518618603181901c600f9190911b1867ffffffffffffffff166102408901526101608801518118603681901c600a9190911b1867ffffffffffffffff166102208901525060e08701518518603a81901c60069190911b1867ffffffffffffffff166101608801526101408701518118603d81901c60039190911b1867ffffffffffffffff1660e0880152505067ffffffffffffffff81166101408601525b5050505050565b600582811b8201805160018501831b8401805160028701851b8601805160038901871b8801805160048b0190981b8901805167ffffffffffffffff861985168918811690995283198a16861889169096528819861683188816909352841986168818871690528419831684189095169052919391929190611d15565b612808600082612781565b612813600582612781565b61281e600a82612781565b612829600f82612781565b612834601482612781565b50565b612840816122dc565b612849816127fd565b600383901b820151815160c09190911c9061211490821867ffffffffffffffff168352565b61287a60008284612837565b61288660018284612837565b61289260028284612837565b61289e60038284612837565b6128aa60048284612837565b6128b660058284612837565b6128c260068284612837565b6128ce60078284612837565b6128da60088284612837565b6128e660098284612837565b6128f2600a8284612837565b6128fe600b8284612837565b61290a600c8284612837565b612916600d8284612837565b612922600e8284612837565b61292e600f8284612837565b61293a60108284612837565b61294660118284612837565b61295260128284612837565b61295e60138284612837565b61296a60148284612837565b61297660158284612837565b61298260168284612837565b61211460178284612837565b73ffffffffffffffffffffffffffffffffffffffff83811660009081526016602090815260408083208684529091528082208054908390559051909284169083908381818185875af1925050503d8060008114612a07576040519150601f19603f3d011682016040523d82523d6000602084013e612a0c565b606091505b505090508061277a576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831617612aed818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b6060604051905081602082018181018286833760888306808015612b3d5760888290038501848101848103803687375060806001820353506001845160001a1784538652612b54565b608836843760018353608060878401536088850186525b5050505050601f19603f82510116810160405292915050565b6000612b7f8260a01c63ffffffff1690565b67ffffffffffffffff1690506000612b9d8360801c63ffffffff1690565b63ffffffff1690506000612bb78460401c63ffffffff1690565b63ffffffff169050600883108015612bcd575080155b15612c015760c082901b6000908152883560085283513382526017602090815260408084208a855290915290912055612cb6565b60088310158015612c1f575080612c196008856138a3565b93508310155b8015612c335750612c3087826136f8565b83105b15612cb6576000612c4482856138a3565b905087612c528260206136f8565b10158015612c5e575085155b15612c95576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526017602090815260408083208a845290915290209089013590555b5050505050505050565b6000612d43565b66ff00ff00ff00ff8160081c1667ff00ff00ff00ff00612cf18360081b67ffffffffffffffff1690565b1617905065ffff0000ffff8160101c1667ffff0000ffff0000612d1e8360101b67ffffffffffffffff1690565b1617905060008160201c612d3c8360201b67ffffffffffffffff1690565b1792915050565b60808201516020830190612d5b90612cc7565b612cc7565b6040820151612d6990612cc7565b60401b17612d81612d5660018460059190911b015190565b825160809190911b90612d9390612cc7565b60c01b17179392505050565b8260108101928215612dcd579160200282015b82811115612dcd578251825591602001919060010190612db2565b50612dd9929150612df5565b5090565b6040518060200160405280612df0612e0a565b905290565b5b80821115612dd95760008155600101612df6565b6040518061032001604052806019906020820280368337509192915050565b600060208284031215612e3b57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612e6657600080fd5b919050565b60008060408385031215612e7e57600080fd5b612e8783612e42565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610320810167ffffffffffffffff81118282101715612ee857612ee8612e95565b60405290565b6040516060810167ffffffffffffffff81118282101715612ee857612ee8612e95565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612f5857612f58612e95565b604052919050565b803567ffffffffffffffff81168114612e6657600080fd5b6000610320808385031215612f8c57600080fd5b604051602080820182811067ffffffffffffffff82111715612fb057612fb0612e95565b806040525081935085601f860112612fc757600080fd5b612fcf612ec4565b928501928087851115612fe157600080fd5b865b8581101561300157612ff481612f60565b8352918301918301612fe3565b509092525091949350505050565b60006060828403121561302157600080fd5b50919050565b60008083601f84011261303957600080fd5b50813567ffffffffffffffff81111561305157600080fd5b6020830191508360208260051b850101111561306c57600080fd5b9250929050565b60008060008060008060008060006103e08a8c03121561309257600080fd5b61309b8a612e42565b985060208a013597506130b18b60408c01612f78565b96506103608a013567ffffffffffffffff808211156130cf57600080fd5b6130db8d838e0161300f565b97506103808c01359150808211156130f257600080fd5b6130fe8d838e01613027565b90975095506103a08c013591508082111561311857600080fd5b6131248d838e0161300f565b94506103c08c013591508082111561313b57600080fd5b506131488c828d01613027565b915080935050809150509295985092959850929598565b600080600080600060a0868803121561317757600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60005b838110156131b557818101518382015260200161319d565b838111156121145750506000910152565b60208152600082518060208401526131e581604085016020870161319a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000806040838503121561322a57600080fd5b50508035926020909101359150565b60008083601f84011261324b57600080fd5b50813567ffffffffffffffff81111561326357600080fd5b60208301915083602082850101111561306c57600080fd5b600080600080600080600060a0888a03121561329657600080fd5b8735965060208801359550604088013567ffffffffffffffff808211156132bc57600080fd5b6132c88b838c01613239565b909750955060608a01359150808211156132e157600080fd5b506132ee8a828b01613027565b9094509250506080880135801515811461330757600080fd5b8091505092959891949750929550565b60008060006060848603121561332c57600080fd5b61333584612e42565b95602085013595506040909401359392505050565b60008060006040848603121561335f57600080fd5b83359250602084013567ffffffffffffffff81111561337d57600080fd5b61338986828701613239565b9497909650939450505050565b600080600080600080600060a0888a0312156133b157600080fd5b8735965060208801359550604088013567ffffffffffffffff808211156133d757600080fd5b6133e38b838c01613239565b909750955060608a01359150808211156133fc57600080fd5b506134098a828b01613239565b989b979a50959894979596608090950135949350505050565b60008060008060006080868803121561343a57600080fd5b8535945061344a60208701612e42565b935061345860408701612f60565b9250606086013567ffffffffffffffff81111561347457600080fd5b61348088828901613239565b969995985093965092949392505050565b6000806000806000608086880312156134a957600080fd5b6134b286612e42565b945060208601359350604086013567ffffffffffffffff808211156134d657600080fd5b6134e289838a0161300f565b945060608801359150808211156134f857600080fd5b5061348088828901613027565b803563ffffffff81168114612e6657600080fd5b60008060006060848603121561352e57600080fd5b8335925061353e60208501613505565b915061354c60408501613505565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135e4576135e4613584565b5060010190565b6000606082360312156135fd57600080fd5b613605612eee565b823567ffffffffffffffff8082111561361d57600080fd5b9084019036601f83011261363057600080fd5b813560208282111561364457613644612e95565b613674817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011601612f11565b9250818352368183860101111561368a57600080fd5b81818501828501376000918301810191909152908352848101359083015250604092830135928101929092525090565b81516103208201908260005b60198110156136ef57825167ffffffffffffffff168252602092830192909101906001016136c6565b50505092915050565b6000821982111561370b5761370b613584565b500190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261374557600080fd5b83018035915067ffffffffffffffff82111561376057600080fd5b60200191503681900382131561306c57600080fd5b600181815b808511156137ce57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156137b4576137b4613584565b808516156137c157918102915b93841c939080029061377a565b509250929050565b6000826137e557506001613891565b816137f257506000613891565b816001811461380857600281146138125761382e565b6001915050613891565b60ff84111561382357613823613584565b50506001821b613891565b5060208310610133831016604e8410600b8410161715613851575081810a613891565b61385b8383613775565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561388d5761388d613584565b0290505b92915050565b6000612aed83836137d6565b6000828210156138b5576138b5613584565b500390565b600063ffffffff838116908316818110156138d7576138d7613584565b039392505050565b600063ffffffff8083168185168083038211156138fe576138fe613584565b01949350505050565b6000845161391981846020890161319a565b9190910192835250602082015260400191905056fea164736f6c634300080f000a"; bytes internal constant mipsCode = - hex"608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d50146100465780637dc0d1d014610098578063e14ced32146100dc575b600080fd5b6100826040518060400160405280600a81526020017f312e312e302d72632e310000000000000000000000000000000000000000000081525081565b60405161008f91906121ee565b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000373d916d11cce55b548f7051002e76bcfbd7a85d16815260200161008f565b6100ef6100ea3660046122a3565b6100fd565b60405190815260200161008f565b6000610107612164565b6080811461011457600080fd5b6040516106001461012457600080fd5b6084871461013157600080fd5b6101a4851461013f57600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a0819052605a89013590911c6101c05260628801906101e09060018111156101f5576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b506020810181511461020657600080fd5b60200160005b602081101561023057823560e01c825260049092019160209091019060010161020c565b5050508061012001511561024e576102466103a6565b91505061039d565b6101408101805160010167ffffffffffffffff16905260006101a49050600080600061028385606001518660000151866104f7565b9250925092508163ffffffff1660001480156102a557508063ffffffff16600c145b156102bf576102b387610521565b9550505050505061039d565b6000610339866040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b6101608701518751919250610356918391906105248888886108f9565b8652805163ffffffff9081166060808901919091526020830151821660808901526040830151821660a08901528201511660c08701526103946103a6565b96505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a8401526000926102009290916062830191906001811115610453576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b60005b602081101561047a57601c8601518452602090950194600490930192600101610456565b506000835283830384a060009450806001811461049a57600395506104c2565b8280156104b257600181146104bb57600296506104c0565b600096506104c0565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b6000806000610507858786610cdf565b925050603f601a83901c8116915082165b93509350939050565b600061052b612164565b608090506000806000806105628561016001516040810151608082015160a083015160c084015160e0909401519294919390929091565b509350935093509350600080610ffa63ffffffff168663ffffffff16036105a75761059285858960e00151610d93565b63ffffffff1660e08a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03363ffffffff8716016105e05763400000009150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefe863ffffffff8716016106165760019150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef6a63ffffffff87160161066a57600161012088015260ff851661010088015261065d6103a6565b9998505050505050505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05d63ffffffff8716016107665760006040518061012001604052808763ffffffff1681526020018663ffffffff1681526020018563ffffffff16815260200189602001518152602001896040015163ffffffff1681526020018b81526020017f000000000000000000000000373d916d11cce55b548f7051002e76bcfbd7a85d73ffffffffffffffffffffffffffffffffffffffff1681526020016107386101a4600160ff16610380020190565b81528951602090910152905061074d81610e27565b8b5263ffffffff1660408b015290935091506108089050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05c63ffffffff8716016107cb57602087015160408801516107b1918791879187916105248d5161109f565b63ffffffff1660408b015260208a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff02963ffffffff871601610808576108028585611195565b90925090505b6000610882886040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b61016089015163ffffffff85811660408084019190915285821660e0909301929092526020830180518083168086526004909101831682526060808e01919091529051821660808d015291830151811660a08c0152908201511660c08a015290506108eb6103a6565b9a9950505050505050505050565b84600263ffffffff8416148061091557508263ffffffff166003145b156109675760006002856303ffffff1663ffffffff16901b896020015163f00000001617905061096189898663ffffffff1660021461095557601f610958565b60005b60ff168461124a565b50610cd4565b600080601f601087901c8116908a90601589901c166020811061098c5761098c612317565b602002015192508063ffffffff871615806109ad57508663ffffffff16601c145b156109df578a8263ffffffff16602081106109ca576109ca612317565b6020020151925050601f600b88901c16610a96565b60208763ffffffff161015610a41578663ffffffff16600c1480610a0957508663ffffffff16600d145b80610a1a57508663ffffffff16600e145b15610a2b578761ffff169250610a96565b610a3a8861ffff166010611322565b9250610a96565b60288763ffffffff16101580610a5d57508663ffffffff166022145b80610a6e57508663ffffffff166026145b15610a96578a8263ffffffff1660208110610a8b57610a8b612317565b602002015192508190505b60048763ffffffff1610158015610ab3575060088763ffffffff16105b80610ac457508663ffffffff166001145b15610ae057610ad78c8c898b8689611395565b50505050610cd4565b63ffffffff6000602089831610610b4557610b008a61ffff166010611322565b9095019463fffffffc8616610b168d828e610cdf565b915060288a63ffffffff1610158015610b3657508963ffffffff16603014155b15610b4357809250600093505b505b6000610b558b8b8b8a8a87611583565b63ffffffff1690508963ffffffff166000148015610b7a575060088963ffffffff1610155b8015610b8c5750601c8963ffffffff16105b15610c54578863ffffffff1660081480610bac57508863ffffffff166009145b15610bdf57610bd38f8f8b63ffffffff16600814610bca5786610bcd565b60005b8a61124a565b50505050505050610cd4565b8863ffffffff16600a03610c0157610bd38f8f868a63ffffffff8b1615611ca0565b8863ffffffff16600b03610c2457610bd38f8f868a63ffffffff8b161515611ca0565b60108963ffffffff1610158015610c415750601c8963ffffffff16105b15610c5457610bd38f8f8b8a8a89611d70565b8963ffffffff166038148015610c6f575063ffffffff851615155b15610c9f5760018e8663ffffffff1660208110610c8e57610c8e612317565b63ffffffff90921660209290920201525b8263ffffffff1663ffffffff14610cbe57610cbb838d83612029565b97505b610ccc8f8f86846001611ca0565b505050505050505b979650505050505050565b6000610cea826120cb565b6003831615610cf857600080fd5b6020820191358360051c8160005b601b811015610d5e5760208601953583821c6001168015610d2e5760018114610d4357610d54565b60008481526020839052604090209350610d54565b600082815260208590526040902093505b5050600101610d06565b50868114610d7457630badf00d60005260206000fd5b5050601f93909316601c0360031b9290921c63ffffffff169392505050565b6000808284610fff811615610dad57610fff811661100003015b8663ffffffff16600003610e195784935090810190636000000063ffffffff83161180610de557508463ffffffff168263ffffffff16105b80610dfb57508563ffffffff168163ffffffff16105b15610e14575063ffffffff925060169150839050610518565b610e1d565b8693505b5093509350939050565b6101008101516080820151825160009283929163ffffffff161561109857845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb01611052576000610e93866101000151876020015163fffffffc168860e00151610cdf565b606087015190915060001a600103610f1557610f0f86606001518760a0015160408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b60608701525b6000808760c0015173ffffffffffffffffffffffffffffffffffffffff1663e03110e189606001518a608001516040518363ffffffff1660e01b8152600401610f6e92919091825263ffffffff16602082015260400190565b6040805180830381865afa158015610f8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fae9190612346565b60208a015160408b01519294509092509060038216600481900384811015610fd4578094505b5083821015610fe1578193505b8460088502610100031c9450846008828660040303021b9450600180600883600403021b036001806008878560040303021b0391508119811690508581198816179650505061103f8a6020015163fffffffc168b60e0015187612029565b9298505050938601939250611098915050565b845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0161108c5784604001519350611098565b63ffffffff9350600992505b9193509193565b600080858563ffffffff8b16600114806110bf575063ffffffff8b166002145b806110d0575063ffffffff8b166004145b156110dd57889350611187565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8c160161117b57600061111d868c63fffffffc1689610cdf565b90508860038c166004038b81101561113357809b505b8b965086900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193880293841b0116911b17915060009050611187565b63ffffffff9350600992505b975097509750979350505050565b60008063ffffffff83166003036112385763ffffffff841615806111bf575063ffffffff84166005145b806111d0575063ffffffff84166003145b156111de5760009150611243565b63ffffffff8416600114806111f9575063ffffffff84166002145b8061120a575063ffffffff84166006145b8061121b575063ffffffff84166004145b156112295760019150611243565b5063ffffffff90506009611243565b5063ffffffff905060165b9250929050565b836000015160040163ffffffff16846020015163ffffffff16146112cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b835160208501805163ffffffff908116875283811690915283161561131b5780600801848463ffffffff166020811061130a5761130a612317565b63ffffffff90921660209290920201525b5050505050565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b018261137f576000611381565b815b90861663ffffffff16179250505092915050565b6000866000015160040163ffffffff16876020015163ffffffff1614611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f7400000000000000000000000060448201526064016112c6565b8463ffffffff166004148061143257508463ffffffff166005145b156114a9576000868463ffffffff166020811061145157611451612317565b602002015190508063ffffffff168363ffffffff1614801561147957508563ffffffff166004145b806114a157508063ffffffff168363ffffffff16141580156114a157508563ffffffff166005145b915050611526565b8463ffffffff166006036114c65760008260030b13159050611526565b8463ffffffff166007036114e25760008260030b139050611526565b8463ffffffff1660010361152657601f601085901c16600081900361150b5760008360030b1291505b8063ffffffff166001036115245760008360030b121591505b505b8651602088015163ffffffff168852811561156757600261154c8661ffff166010611322565b63ffffffff90811690911b8201600401166020890152611579565b60208801805160040163ffffffff1690525b5050505050505050565b600063ffffffff861615806115b0575060088663ffffffff16101580156115b05750600f8663ffffffff16105b156119b05785600881146115f357600981146115fc57600a811461160557600b811461160e57600c811461161757600d811461162057600e81146116295761162e565b6020955061162e565b6021955061162e565b602a955061162e565b602b955061162e565b6024955061162e565b6025955061162e565b602695505b508463ffffffff16600003611653575063ffffffff8216601f600688901c161b611c96565b8463ffffffff16600203611677575063ffffffff8216601f600688901c161c611c96565b8463ffffffff166003036116ab57601f600688901c166116a363ffffffff8516821c6020839003611322565b915050611c96565b8463ffffffff166004036116cb575063ffffffff8216601f84161b611c96565b8463ffffffff166006036116eb575063ffffffff8216601f84161c611c96565b8463ffffffff1660070361171357601f84166116a363ffffffff8516821c6020839003611322565b8463ffffffff16600803611728575082611c96565b8463ffffffff1660090361173d575082611c96565b8463ffffffff16600a03611752575082611c96565b8463ffffffff16600b03611767575082611c96565b8463ffffffff16600c0361177c575082611c96565b8463ffffffff16600f03611791575082611c96565b8463ffffffff166010036117a6575082611c96565b8463ffffffff166011036117bb575082611c96565b8463ffffffff166012036117d0575082611c96565b8463ffffffff166013036117e5575082611c96565b8463ffffffff166018036117fa575082611c96565b8463ffffffff1660190361180f575082611c96565b8463ffffffff16601a03611824575082611c96565b8463ffffffff16601b03611839575082611c96565b8463ffffffff166020036118505750828201611c96565b8463ffffffff166021036118675750828201611c96565b8463ffffffff1660220361187e5750818303611c96565b8463ffffffff166023036118955750818303611c96565b8463ffffffff166024036118ac5750828216611c96565b8463ffffffff166025036118c35750828217611c96565b8463ffffffff166026036118da5750828218611c96565b8463ffffffff166027036118f2575082821719611c96565b8463ffffffff16602a03611921578260030b8460030b12611914576000611917565b60015b60ff169050611c96565b8463ffffffff16602b03611949578263ffffffff168463ffffffff1610611914576000611917565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e0000000000000000000000000060448201526064016112c6565b611949565b8563ffffffff16601c03611a30578463ffffffff166002036119d55750828202611c96565b8463ffffffff16602014806119f057508463ffffffff166021145b156119ab578463ffffffff16602003611a07579219925b60005b6380000000851615611a29576401fffffffe600195861b169401611a0a565b9050611c96565b8563ffffffff16600f03611a51575065ffffffff0000601083901b16611c96565b8563ffffffff16602003611a8557611a298460031660080260180363ffffffff168363ffffffff16901c60ff166008611322565b8563ffffffff16602103611aba57611a298460021660080260100363ffffffff168363ffffffff16901c61ffff166010611322565b8563ffffffff16602203611ae8575063ffffffff60086003851602811681811b198416918316901b17611c96565b8563ffffffff16602303611afd575080611c96565b8563ffffffff16602403611b2e578360031660080260180363ffffffff168263ffffffff16901c60ff169050611c96565b8563ffffffff16602503611b60578360021660080260100363ffffffff168263ffffffff16901c61ffff169050611c96565b8563ffffffff16602603611b91575063ffffffff60086003851602601803811681811c198416918316901c17611c96565b8563ffffffff16602803611bc6575060ff63ffffffff60086003861602601803811682811b9091188316918416901b17611c96565b8563ffffffff16602903611bfc575061ffff63ffffffff60086002861602601003811682811b9091188316918416901b17611c96565b8563ffffffff16602a03611c2a575063ffffffff60086003851602811681811c198316918416901c17611c96565b8563ffffffff16602b03611c3f575081611c96565b8563ffffffff16602e03611c70575063ffffffff60086003851602601803811681811b198316918416901b17611c96565b8563ffffffff16603003611c85575080611c96565b8563ffffffff166038036119495750815b9695505050505050565b60208363ffffffff1610611d10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c696420726567697374657200000000000000000000000000000000000060448201526064016112c6565b63ffffffff831615801590611d225750805b15611d515781848463ffffffff1660208110611d4057611d40612317565b63ffffffff90921660209290920201525b5050505060208101805163ffffffff8082169093526004019091169052565b60008463ffffffff16601003611d8b57506060860151611fd1565b8463ffffffff16601103611daa5763ffffffff84166060880152611fd1565b8463ffffffff16601203611dc357506040860151611fd1565b8463ffffffff16601303611de25763ffffffff84166040880152611fd1565b8463ffffffff16601803611e165763ffffffff600385810b9085900b02602081901c821660608a0152166040880152611fd1565b8463ffffffff16601903611e475763ffffffff84811681851602602081901c821660608a0152166040880152611fd1565b8463ffffffff16601a03611f0a578260030b600003611ec2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8260030b8460030b81611ed757611ed761236a565b0763ffffffff166060880152600383810b9085900b81611ef957611ef961236a565b0563ffffffff166040880152611fd1565b8463ffffffff16601b03611fd1578263ffffffff16600003611f88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8263ffffffff168463ffffffff1681611fa357611fa361236a565b0663ffffffff908116606089015283811690851681611fc457611fc461236a565b0463ffffffff1660408801525b63ffffffff8216156120075780868363ffffffff1660208110611ff657611ff6612317565b63ffffffff90921660209290920201525b50505060208401805163ffffffff808216909652600401909416909352505050565b6000612034836120cb565b600384161561204257600080fd5b6020830192601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b8110156120c05760208601953582821c600116801561209057600181146120a5576120b6565b600085815260208390526040902094506120b6565b600082815260208690526040902094505b5050600101612068565b509095945050505050565b366103808201811015612160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f617461000000000000000000000000000000000000000000000000000000000060648201526084016112c6565b5050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915261016081016121ca6121cf565b905290565b6040518061040001604052806020906020820280368337509192915050565b600060208083528351808285015260005b8181101561221b578581018301518582016040015282016121ff565b8181111561222d576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60008083601f84011261227357600080fd5b50813567ffffffffffffffff81111561228b57600080fd5b60208301915083602082850101111561124357600080fd5b6000806000806000606086880312156122bb57600080fd5b853567ffffffffffffffff808211156122d357600080fd5b6122df89838a01612261565b909750955060208801359150808211156122f857600080fd5b5061230588828901612261565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561235957600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a"; + hex"608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d50146100465780637dc0d1d014610098578063e14ced32146100dc575b600080fd5b6100826040518060400160405280600c81526020017f312e312e312d626574612e32000000000000000000000000000000000000000081525081565b60405161008f91906121ee565b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007a9eab4ce99d157aee7a02e95b366e972a2d5b0b16815260200161008f565b6100ef6100ea3660046122a3565b6100fd565b60405190815260200161008f565b6000610107612164565b6080811461011457600080fd5b6040516106001461012457600080fd5b6084871461013157600080fd5b6101a4851461013f57600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a0819052605a89013590911c6101c05260628801906101e09060018111156101f5576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b506020810181511461020657600080fd5b60200160005b602081101561023057823560e01c825260049092019160209091019060010161020c565b5050508061012001511561024e576102466103a6565b91505061039d565b6101408101805160010167ffffffffffffffff16905260006101a49050600080600061028385606001518660000151866104f7565b9250925092508163ffffffff1660001480156102a557508063ffffffff16600c145b156102bf576102b387610521565b9550505050505061039d565b6000610339866040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b6101608701518751919250610356918391906105248888886108f9565b8652805163ffffffff9081166060808901919091526020830151821660808901526040830151821660a08901528201511660c08701526103946103a6565b96505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a8401526000926102009290916062830191906001811115610453576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b60005b602081101561047a57601c8601518452602090950194600490930192600101610456565b506000835283830384a060009450806001811461049a57600395506104c2565b8280156104b257600181146104bb57600296506104c0565b600096506104c0565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b6000806000610507858786610cdf565b925050603f601a83901c8116915082165b93509350939050565b600061052b612164565b608090506000806000806105628561016001516040810151608082015160a083015160c084015160e0909401519294919390929091565b509350935093509350600080610ffa63ffffffff168663ffffffff16036105a75761059285858960e00151610d93565b63ffffffff1660e08a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03363ffffffff8716016105e05763400000009150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefe863ffffffff8716016106165760019150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef6a63ffffffff87160161066a57600161012088015260ff851661010088015261065d6103a6565b9998505050505050505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05d63ffffffff8716016107665760006040518061012001604052808763ffffffff1681526020018663ffffffff1681526020018563ffffffff16815260200189602001518152602001896040015163ffffffff1681526020018b81526020017f0000000000000000000000007a9eab4ce99d157aee7a02e95b366e972a2d5b0b73ffffffffffffffffffffffffffffffffffffffff1681526020016107386101a4600160ff16610380020190565b81528951602090910152905061074d81610e27565b8b5263ffffffff1660408b015290935091506108089050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05c63ffffffff8716016107cb57602087015160408801516107b1918791879187916105248d5161109f565b63ffffffff1660408b015260208a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff02963ffffffff871601610808576108028585611195565b90925090505b6000610882886040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b61016089015163ffffffff85811660408084019190915285821660e0909301929092526020830180518083168086526004909101831682526060808e01919091529051821660808d015291830151811660a08c0152908201511660c08a015290506108eb6103a6565b9a9950505050505050505050565b84600263ffffffff8416148061091557508263ffffffff166003145b156109675760006002856303ffffff1663ffffffff16901b896020015163f00000001617905061096189898663ffffffff1660021461095557601f610958565b60005b60ff168461124a565b50610cd4565b600080601f601087901c8116908a90601589901c166020811061098c5761098c612317565b602002015192508063ffffffff871615806109ad57508663ffffffff16601c145b156109df578a8263ffffffff16602081106109ca576109ca612317565b6020020151925050601f600b88901c16610a96565b60208763ffffffff161015610a41578663ffffffff16600c1480610a0957508663ffffffff16600d145b80610a1a57508663ffffffff16600e145b15610a2b578761ffff169250610a96565b610a3a8861ffff166010611322565b9250610a96565b60288763ffffffff16101580610a5d57508663ffffffff166022145b80610a6e57508663ffffffff166026145b15610a96578a8263ffffffff1660208110610a8b57610a8b612317565b602002015192508190505b60048763ffffffff1610158015610ab3575060088763ffffffff16105b80610ac457508663ffffffff166001145b15610ae057610ad78c8c898b8689611395565b50505050610cd4565b63ffffffff6000602089831610610b4557610b008a61ffff166010611322565b9095019463fffffffc8616610b168d828e610cdf565b915060288a63ffffffff1610158015610b3657508963ffffffff16603014155b15610b4357809250600093505b505b6000610b558b8b8b8a8a87611583565b63ffffffff1690508963ffffffff166000148015610b7a575060088963ffffffff1610155b8015610b8c5750601c8963ffffffff16105b15610c54578863ffffffff1660081480610bac57508863ffffffff166009145b15610bdf57610bd38f8f8b63ffffffff16600814610bca5786610bcd565b60005b8a61124a565b50505050505050610cd4565b8863ffffffff16600a03610c0157610bd38f8f868a63ffffffff8b1615611ca0565b8863ffffffff16600b03610c2457610bd38f8f868a63ffffffff8b161515611ca0565b60108963ffffffff1610158015610c415750601c8963ffffffff16105b15610c5457610bd38f8f8b8a8a89611d70565b8963ffffffff166038148015610c6f575063ffffffff851615155b15610c9f5760018e8663ffffffff1660208110610c8e57610c8e612317565b63ffffffff90921660209290920201525b8263ffffffff1663ffffffff14610cbe57610cbb838d83612029565b97505b610ccc8f8f86846001611ca0565b505050505050505b979650505050505050565b6000610cea826120cb565b6003831615610cf857600080fd5b6020820191358360051c8160005b601b811015610d5e5760208601953583821c6001168015610d2e5760018114610d4357610d54565b60008481526020839052604090209350610d54565b600082815260208590526040902093505b5050600101610d06565b50868114610d7457630badf00d60005260206000fd5b5050601f93909316601c0360031b9290921c63ffffffff169392505050565b6000808284610fff811615610dad57610fff811661100003015b8663ffffffff16600003610e195784935090810190636000000063ffffffff83161180610de557508463ffffffff168263ffffffff16105b80610dfb57508563ffffffff168163ffffffff16105b15610e14575063ffffffff925060169150839050610518565b610e1d565b8693505b5093509350939050565b6101008101516080820151825160009283929163ffffffff161561109857845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb01611052576000610e93866101000151876020015163fffffffc168860e00151610cdf565b606087015190915060001a600103610f1557610f0f86606001518760a0015160408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b60608701525b6000808760c0015173ffffffffffffffffffffffffffffffffffffffff1663e03110e189606001518a608001516040518363ffffffff1660e01b8152600401610f6e92919091825263ffffffff16602082015260400190565b6040805180830381865afa158015610f8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fae9190612346565b60208a015160408b01519294509092509060038216600481900384811015610fd4578094505b5083821015610fe1578193505b8460088502610100031c9450846008828660040303021b9450600180600883600403021b036001806008878560040303021b0391508119811690508581198816179650505061103f8a6020015163fffffffc168b60e0015187612029565b9298505050938601939250611098915050565b845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0161108c5784604001519350611098565b63ffffffff9350600992505b9193509193565b600080858563ffffffff8b16600114806110bf575063ffffffff8b166002145b806110d0575063ffffffff8b166004145b156110dd57889350611187565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8c160161117b57600061111d868c63fffffffc1689610cdf565b90508860038c166004038b81101561113357809b505b8b965086900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193880293841b0116911b17915060009050611187565b63ffffffff9350600992505b975097509750979350505050565b60008063ffffffff83166003036112385763ffffffff841615806111bf575063ffffffff84166005145b806111d0575063ffffffff84166003145b156111de5760009150611243565b63ffffffff8416600114806111f9575063ffffffff84166002145b8061120a575063ffffffff84166006145b8061121b575063ffffffff84166004145b156112295760019150611243565b5063ffffffff90506009611243565b5063ffffffff905060165b9250929050565b836000015160040163ffffffff16846020015163ffffffff16146112cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b835160208501805163ffffffff908116875283811690915283161561131b5780600801848463ffffffff166020811061130a5761130a612317565b63ffffffff90921660209290920201525b5050505050565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b018261137f576000611381565b815b90861663ffffffff16179250505092915050565b6000866000015160040163ffffffff16876020015163ffffffff1614611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f7400000000000000000000000060448201526064016112c6565b8463ffffffff166004148061143257508463ffffffff166005145b156114a9576000868463ffffffff166020811061145157611451612317565b602002015190508063ffffffff168363ffffffff1614801561147957508563ffffffff166004145b806114a157508063ffffffff168363ffffffff16141580156114a157508563ffffffff166005145b915050611526565b8463ffffffff166006036114c65760008260030b13159050611526565b8463ffffffff166007036114e25760008260030b139050611526565b8463ffffffff1660010361152657601f601085901c16600081900361150b5760008360030b1291505b8063ffffffff166001036115245760008360030b121591505b505b8651602088015163ffffffff168852811561156757600261154c8661ffff166010611322565b63ffffffff90811690911b8201600401166020890152611579565b60208801805160040163ffffffff1690525b5050505050505050565b600063ffffffff861615806115b0575060088663ffffffff16101580156115b05750600f8663ffffffff16105b156119b05785600881146115f357600981146115fc57600a811461160557600b811461160e57600c811461161757600d811461162057600e81146116295761162e565b6020955061162e565b6021955061162e565b602a955061162e565b602b955061162e565b6024955061162e565b6025955061162e565b602695505b508463ffffffff16600003611653575063ffffffff8216601f600688901c161b611c96565b8463ffffffff16600203611677575063ffffffff8216601f600688901c161c611c96565b8463ffffffff166003036116ab57601f600688901c166116a363ffffffff8516821c6020839003611322565b915050611c96565b8463ffffffff166004036116cb575063ffffffff8216601f84161b611c96565b8463ffffffff166006036116eb575063ffffffff8216601f84161c611c96565b8463ffffffff1660070361171357601f84166116a363ffffffff8516821c6020839003611322565b8463ffffffff16600803611728575082611c96565b8463ffffffff1660090361173d575082611c96565b8463ffffffff16600a03611752575082611c96565b8463ffffffff16600b03611767575082611c96565b8463ffffffff16600c0361177c575082611c96565b8463ffffffff16600f03611791575082611c96565b8463ffffffff166010036117a6575082611c96565b8463ffffffff166011036117bb575082611c96565b8463ffffffff166012036117d0575082611c96565b8463ffffffff166013036117e5575082611c96565b8463ffffffff166018036117fa575082611c96565b8463ffffffff1660190361180f575082611c96565b8463ffffffff16601a03611824575082611c96565b8463ffffffff16601b03611839575082611c96565b8463ffffffff166020036118505750828201611c96565b8463ffffffff166021036118675750828201611c96565b8463ffffffff1660220361187e5750818303611c96565b8463ffffffff166023036118955750818303611c96565b8463ffffffff166024036118ac5750828216611c96565b8463ffffffff166025036118c35750828217611c96565b8463ffffffff166026036118da5750828218611c96565b8463ffffffff166027036118f2575082821719611c96565b8463ffffffff16602a03611921578260030b8460030b12611914576000611917565b60015b60ff169050611c96565b8463ffffffff16602b03611949578263ffffffff168463ffffffff1610611914576000611917565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e0000000000000000000000000060448201526064016112c6565b611949565b8563ffffffff16601c03611a30578463ffffffff166002036119d55750828202611c96565b8463ffffffff16602014806119f057508463ffffffff166021145b156119ab578463ffffffff16602003611a07579219925b60005b6380000000851615611a29576401fffffffe600195861b169401611a0a565b9050611c96565b8563ffffffff16600f03611a51575065ffffffff0000601083901b16611c96565b8563ffffffff16602003611a8557611a298460031660080260180363ffffffff168363ffffffff16901c60ff166008611322565b8563ffffffff16602103611aba57611a298460021660080260100363ffffffff168363ffffffff16901c61ffff166010611322565b8563ffffffff16602203611ae8575063ffffffff60086003851602811681811b198416918316901b17611c96565b8563ffffffff16602303611afd575080611c96565b8563ffffffff16602403611b2e578360031660080260180363ffffffff168263ffffffff16901c60ff169050611c96565b8563ffffffff16602503611b60578360021660080260100363ffffffff168263ffffffff16901c61ffff169050611c96565b8563ffffffff16602603611b91575063ffffffff60086003851602601803811681811c198416918316901c17611c96565b8563ffffffff16602803611bc6575060ff63ffffffff60086003861602601803811682811b9091188316918416901b17611c96565b8563ffffffff16602903611bfc575061ffff63ffffffff60086002861602601003811682811b9091188316918416901b17611c96565b8563ffffffff16602a03611c2a575063ffffffff60086003851602811681811c198316918416901c17611c96565b8563ffffffff16602b03611c3f575081611c96565b8563ffffffff16602e03611c70575063ffffffff60086003851602601803811681811b198316918416901b17611c96565b8563ffffffff16603003611c85575080611c96565b8563ffffffff166038036119495750815b9695505050505050565b60208363ffffffff1610611d10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c696420726567697374657200000000000000000000000000000000000060448201526064016112c6565b63ffffffff831615801590611d225750805b15611d515781848463ffffffff1660208110611d4057611d40612317565b63ffffffff90921660209290920201525b5050505060208101805163ffffffff8082169093526004019091169052565b60008463ffffffff16601003611d8b57506060860151611fd1565b8463ffffffff16601103611daa5763ffffffff84166060880152611fd1565b8463ffffffff16601203611dc357506040860151611fd1565b8463ffffffff16601303611de25763ffffffff84166040880152611fd1565b8463ffffffff16601803611e165763ffffffff600385810b9085900b02602081901c821660608a0152166040880152611fd1565b8463ffffffff16601903611e475763ffffffff84811681851602602081901c821660608a0152166040880152611fd1565b8463ffffffff16601a03611f0a578260030b600003611ec2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8260030b8460030b81611ed757611ed761236a565b0763ffffffff166060880152600383810b9085900b81611ef957611ef961236a565b0563ffffffff166040880152611fd1565b8463ffffffff16601b03611fd1578263ffffffff16600003611f88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8263ffffffff168463ffffffff1681611fa357611fa361236a565b0663ffffffff908116606089015283811690851681611fc457611fc461236a565b0463ffffffff1660408801525b63ffffffff8216156120075780868363ffffffff1660208110611ff657611ff6612317565b63ffffffff90921660209290920201525b50505060208401805163ffffffff808216909652600401909416909352505050565b6000612034836120cb565b600384161561204257600080fd5b6020830192601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b8110156120c05760208601953582821c600116801561209057600181146120a5576120b6565b600085815260208390526040902094506120b6565b600082815260208690526040902094505b5050600101612068565b509095945050505050565b366103808201811015612160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f617461000000000000000000000000000000000000000000000000000000000060648201526084016112c6565b5050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915261016081016121ca6121cf565b905290565b6040518061040001604052806020906020820280368337509192915050565b600060208083528351808285015260005b8181101561221b578581018301518582016040015282016121ff565b8181111561222d576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60008083601f84011261227357600080fd5b50813567ffffffffffffffff81111561228b57600080fd5b60208301915083602082850101111561124357600080fd5b6000806000806000606086880312156122bb57600080fd5b853567ffffffffffffffff808211156122d357600080fd5b6122df89838a01612261565b909750955060208801359150808211156122f857600080fd5b5061230588828901612261565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561235957600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a"; bytes internal constant anchorStateRegistryCode = - hex"608060405234801561001057600080fd5b506004361061007d5760003560e01c80635e05fbd01161005b5780635e05fbd01461012a5780637258a8071461013d578063838c2d1e14610179578063f2b4e6171461018157600080fd5b806317cf21a91461008257806335e80ab31461009757806354fd4d50146100e1575b600080fd5b610095610090366004610b4c565b6101a7565b005b6002546100b79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61011d6040518060400160405280600c81526020017f322e302e312d626574612e31000000000000000000000000000000000000000081525081565b6040516100d89190610bea565b610095610138366004610cc6565b61061c565b61016461014b366004610df0565b6001602081905260009182526040909120805491015482565b604080519283526020830191909152016100d8565b610095610853565b7f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d6100b7565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610214573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102389190610e0d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461029c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156102ec573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526103329190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161039793929190610efb565b6040805180830381865afa1580156103b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d79190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043f576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561048c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b09190610f9f565b60028111156104c1576104c1610f70565b146104f8576040517f8f8af25f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806105788773ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610551573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105759190610fc0565b90565b81526020018673ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ec9190610fc0565b905263ffffffff909416600090815260016020818152604090922086518155959091015194019390935550505050565b600054610100900460ff161580801561063c5750600054600160ff909116105b806106565750303b158015610656575060005460ff166001145b6106e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561074457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60005b83518110156107aa57600084828151811061076457610764610fd9565b60209081029190910181015180820151905163ffffffff1660009081526001808452604090912082518155919092015191015550806107a281611008565b915050610747565b50600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055801561084e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600033905060008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108a8573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526108ee9190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161095393929190610efb565b6040805180830381865afa15801561096f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109939190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109fb576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160008563ffffffff1663ffffffff168152602001908152602001600020600101548573ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8d9190610fc0565b11610a99575050505050565b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ae6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0a9190610f9f565b6002811115610b1b57610b1b610f70565b146104f8575050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4957600080fd5b50565b600060208284031215610b5e57600080fd5b8135610b6981610b27565b9392505050565b60005b83811015610b8b578181015183820152602001610b73565b83811115610b9a576000848401525b50505050565b60008151808452610bb8816020860160208601610b70565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610b696020830184610ba0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610c4f57610c4f610bfd565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610c9c57610c9c610bfd565b604052919050565b63ffffffff81168114610b4957600080fd5b8035610cc181610b27565b919050565b6000806040808486031215610cda57600080fd5b833567ffffffffffffffff80821115610cf257600080fd5b818601915086601f830112610d0657600080fd5b8135602082821115610d1a57610d1a610bfd565b610d28818360051b01610c55565b8281528181019350606092830285018201928a841115610d4757600080fd5b948201945b83861015610dd457858b0381811215610d655760008081fd5b610d6d610c2c565b8735610d7881610ca4565b81527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201891315610daa5760008081fd5b610db2610c2c565b8886013581528989013586820152818601528652509485019493820193610d4c565b509650610de2888201610cb6565b955050505050509250929050565b600060208284031215610e0257600080fd5b8135610b6981610ca4565b600060208284031215610e1f57600080fd5b8151610b6981610b27565b600080600060608486031215610e3f57600080fd5b8351610e4a81610ca4565b60208501516040860151919450925067ffffffffffffffff80821115610e6f57600080fd5b818601915086601f830112610e8357600080fd5b815181811115610e9557610e95610bfd565b610ec660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610c55565b9150808252876020828501011115610edd57600080fd5b610eee816020840160208601610b70565b5080925050509250925092565b63ffffffff84168152826020820152606060408201526000610f206060830184610ba0565b95945050505050565b60008060408385031215610f3c57600080fd5b8251610f4781610b27565b602084015190925067ffffffffffffffff81168114610f6557600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060208284031215610fb157600080fd5b815160038110610b6957600080fd5b600060208284031215610fd257600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611060577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea164736f6c634300080f000a"; + hex"608060405234801561001057600080fd5b506004361061007d5760003560e01c80635e05fbd01161005b5780635e05fbd01461012a5780637258a8071461013d578063838c2d1e14610179578063f2b4e6171461018157600080fd5b806317cf21a91461008257806335e80ab31461009757806354fd4d50146100e1575b600080fd5b610095610090366004610b4c565b6101a7565b005b6002546100b79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61011d6040518060400160405280600c81526020017f322e302e312d626574612e32000000000000000000000000000000000000000081525081565b6040516100d89190610bea565b610095610138366004610cc6565b61061c565b61016461014b366004610df0565b6001602081905260009182526040909120805491015482565b604080519283526020830191909152016100d8565b610095610853565b7f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d6100b7565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610214573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102389190610e0d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461029c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156102ec573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526103329190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161039793929190610efb565b6040805180830381865afa1580156103b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d79190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043f576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561048c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b09190610f9f565b60028111156104c1576104c1610f70565b146104f8576040517f8f8af25f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806105788773ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610551573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105759190610fc0565b90565b81526020018673ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ec9190610fc0565b905263ffffffff909416600090815260016020818152604090922086518155959091015194019390935550505050565b600054610100900460ff161580801561063c5750600054600160ff909116105b806106565750303b158015610656575060005460ff166001145b6106e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561074457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60005b83518110156107aa57600084828151811061076457610764610fd9565b60209081029190910181015180820151905163ffffffff1660009081526001808452604090912082518155919092015191015550806107a281611008565b915050610747565b50600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055801561084e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600033905060008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108a8573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526108ee9190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161095393929190610efb565b6040805180830381865afa15801561096f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109939190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109fb576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160008563ffffffff1663ffffffff168152602001908152602001600020600101548573ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8d9190610fc0565b11610a99575050505050565b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ae6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0a9190610f9f565b6002811115610b1b57610b1b610f70565b146104f8575050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4957600080fd5b50565b600060208284031215610b5e57600080fd5b8135610b6981610b27565b9392505050565b60005b83811015610b8b578181015183820152602001610b73565b83811115610b9a576000848401525b50505050565b60008151808452610bb8816020860160208601610b70565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610b696020830184610ba0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610c4f57610c4f610bfd565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610c9c57610c9c610bfd565b604052919050565b63ffffffff81168114610b4957600080fd5b8035610cc181610b27565b919050565b6000806040808486031215610cda57600080fd5b833567ffffffffffffffff80821115610cf257600080fd5b818601915086601f830112610d0657600080fd5b8135602082821115610d1a57610d1a610bfd565b610d28818360051b01610c55565b8281528181019350606092830285018201928a841115610d4757600080fd5b948201945b83861015610dd457858b0381811215610d655760008081fd5b610d6d610c2c565b8735610d7881610ca4565b81527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201891315610daa5760008081fd5b610db2610c2c565b8886013581528989013586820152818601528652509485019493820193610d4c565b509650610de2888201610cb6565b955050505050509250929050565b600060208284031215610e0257600080fd5b8135610b6981610ca4565b600060208284031215610e1f57600080fd5b8151610b6981610b27565b600080600060608486031215610e3f57600080fd5b8351610e4a81610ca4565b60208501516040860151919450925067ffffffffffffffff80821115610e6f57600080fd5b818601915086601f830112610e8357600080fd5b815181811115610e9557610e95610bfd565b610ec660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610c55565b9150808252876020828501011115610edd57600080fd5b610eee816020840160208601610b70565b5080925050509250925092565b63ffffffff84168152826020820152606060408201526000610f206060830184610ba0565b95945050505050565b60008060408385031215610f3c57600080fd5b8251610f4781610b27565b602084015190925067ffffffffffffffff81168114610f6557600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060208284031215610fb157600080fd5b815160038110610b6957600080fd5b600060208284031215610fd257600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611060577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea164736f6c634300080f000a"; bytes internal constant acc33Code = - hex"6080604052600436106102f25760003560e01c806370872aa51161018f578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b18578063fa315aa914610b3c578063fe2bbeb214610b6f57600080fd5b8063ec5e630814610a95578063eff0f59214610ac8578063f8f43ff614610af857600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a0f578063d8cc1a3c14610a42578063dabd396d14610a6257600080fd5b8063c6f0308c14610937578063cf09e0d0146109c1578063d5d44d80146109e257600080fd5b80638d450a9511610143578063bcef3b551161011d578063bcef3b55146108b7578063bd8da956146108f7578063c395e1ca1461091757600080fd5b80638d450a9514610777578063a445ece6146107aa578063bbdc02db1461087657600080fd5b80638129fc1c116101745780638129fc1c1461071a5780638980e0cc146107225780638b85902b1461073757600080fd5b806370872aa5146106f25780637b0f0adc1461070757600080fd5b80633fc8cef3116102485780635c0cba33116101fc5780636361506d116101d65780636361506d1461066c5780636b6716c0146106ac5780636f034409146106df57600080fd5b80635c0cba3314610604578063609d33341461063757806360e274641461064c57600080fd5b806354fd4d501161022d57806354fd4d501461055e57806357da950e146105b45780635a5fa2d9146105e457600080fd5b80633fc8cef314610518578063472777c61461054b57600080fd5b80632810e1d6116102aa57806337b1b2291161028457806337b1b229146104655780633a768463146104a55780633e3ac912146104d857600080fd5b80632810e1d6146103de5780632ad69aeb146103f357806330dbe5701461041357600080fd5b806319effeb4116102db57806319effeb414610339578063200d2ed21461038457806325fc2ace146103bf57600080fd5b806301935130146102f757806303c2924d14610319575b600080fd5b34801561030357600080fd5b506103176103123660046154e2565b610b9f565b005b34801561032557600080fd5b5061031761033436600461553d565b610ec0565b34801561034557600080fd5b506000546103669068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561039057600080fd5b506000546103b290700100000000000000000000000000000000900460ff1681565b60405161037b919061558e565b3480156103cb57600080fd5b506008545b60405190815260200161037b565b3480156103ea57600080fd5b506103b2611566565b3480156103ff57600080fd5b506103d061040e36600461553d565b61180b565b34801561041f57600080fd5b506001546104409073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161037b565b34801561047157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610440565b3480156104b157600080fd5b507f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe7806610440565b3480156104e457600080fd5b50600054610508907201000000000000000000000000000000000000900460ff1681565b604051901515815260200161037b565b34801561052457600080fd5b507f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92610440565b6103176105593660046155cf565b611841565b34801561056a57600080fd5b506105a76040518060400160405280600a81526020017f312e332e302d72632e310000000000000000000000000000000000000000000081525081565b60405161037b9190615666565b3480156105c057600080fd5b506008546009546105cf919082565b6040805192835260208301919091520161037b565b3480156105f057600080fd5b506103d06105ff366004615679565b611853565b34801561061057600080fd5b507f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e610440565b34801561064357600080fd5b506105a761188d565b34801561065857600080fd5b506103176106673660046156b7565b61189b565b34801561067857600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103d0565b3480156106b857600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610366565b6103176106ed3660046156e9565b611a42565b3480156106fe57600080fd5b506009546103d0565b6103176107153660046155cf565b61251b565b610317612528565b34801561072e57600080fd5b506002546103d0565b34801561074357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103d0565b34801561078357600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103d0565b3480156107b657600080fd5b506108226107c5366004615679565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff16606082015260800161037b565b34801561088257600080fd5b5060405163ffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260200161037b565b3480156108c357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103d0565b34801561090357600080fd5b50610366610912366004615679565b612a81565b34801561092357600080fd5b506103d0610932366004615728565b612c60565b34801561094357600080fd5b50610957610952366004615679565b612e43565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e00161037b565b3480156109cd57600080fd5b506000546103669067ffffffffffffffff1681565b3480156109ee57600080fd5b506103d06109fd3660046156b7565b60036020526000908152604090205481565b348015610a1b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000003856103d0565b348015610a4e57600080fd5b50610317610a5d36600461575a565b612eda565b348015610a6e57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b0610366565b348015610aa157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000046103d0565b348015610ad457600080fd5b50610508610ae3366004615679565b60046020526000908152604090205460ff1681565b348015610b0457600080fd5b50610317610b133660046155cf565b613509565b348015610b2457600080fd5b50610b2d6139c6565b60405161037b939291906157e4565b348015610b4857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000086103d0565b348015610b7b57600080fd5b50610508610b8a366004615679565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610bcb57610bcb61555f565b14610c02576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610c55576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610ca3610c9e36869003860186615838565b613a41565b14610cda576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610cef9291906158c5565b604051809103902014610d2e576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d77610d7284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613a9d92505050565b613b0a565b90506000610d9e82600881518110610d9157610d916158d5565b6020026020010151613cc0565b9050602081511115610ddc576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610e51576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610eec57610eec61555f565b14610f23576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610f3857610f386158d5565b906000526020600020906005020190506000610f5384612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b081169082161015610fbc576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611005576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561102257508515155b156110bd578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110555781611071565b600186015473ffffffffffffffffffffffffffffffffffffffff165b905061107d8187613d74565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff166060830152611160576fffffffffffffffffffffffffffffffff6040820152600181526000869003611160578195505b600086826020015163ffffffff166111789190615933565b90506000838211611189578161118b565b835b602084015190915063ffffffff165b818110156112d75760008682815481106111b6576111b66158d5565b6000918252602080832090910154808352600690915260409091205490915060ff1661120e576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611223576112236158d5565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112805750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b156112c257600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b505080806112cf9061594b565b91505061119a565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921790915584900361155b57606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558915801561145757506000547201000000000000000000000000000000000000900460ff165b156114cc5760015473ffffffffffffffffffffffffffffffffffffffff1661147f818a613d74565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff909116178855611559565b61151373ffffffffffffffffffffffffffffffffffffffff8216156114f1578161150d565b600189015473ffffffffffffffffffffffffffffffffffffffff165b89613d74565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff1660028111156115945761159461555f565b146115cb576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff1661162f576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008154811061165b5761165b6158d5565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611696576001611699565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff9091161770010000000000000000000000000000000083600281111561174a5761174a61555f565b02179055600281111561175f5761175f61555f565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e73ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156117f057600080fd5b505af1158015611804573d6000803e3d6000fd5b5050505090565b6005602052816000526040600020818154811061182757600080fd5b90600052602060002001600091509150505481565b905090565b61184e8383836001611a42565b505050565b6000818152600760209081526040808320600590925282208054825461188490610100900463ffffffff1682615983565b95945050505050565b606061183c60546020613e75565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260036020526040812080549082905590819003611900576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169063f3fef3a390604401600060405180830381600087803b15801561199057600080fd5b505af11580156119a4573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a02576040519150601f19603f3d011682016040523d82523d6000602084013e611a07565b606091505b505090508061184e576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008054700100000000000000000000000000000000900460ff166002811115611a6e57611a6e61555f565b14611aa5576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110611aba57611aba6158d5565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514611ba1576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000611c61826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580611c9c5750611c997f00000000000000000000000000000000000000000000000000000000000000046002615933565b81145b8015611ca6575084155b15611cdd576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015611d03575086155b15611d3a576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000008811115611d94576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dbf7f00000000000000000000000000000000000000000000000000000000000000046001615933565b8103611dd157611dd186888588613ec7565b34611ddb83612c60565b14611e12576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611e1d88612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b0811690821603611e85576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611eb260017f0000000000000000000000000000000000000000000000000000000000000008615983565b8303611ff0577f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f47919061599a565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb591906159b7565b611fe9907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166159d0565b9050612083565b61201b60017f0000000000000000000000000000000000000000000000000000000000000004615983565b830361205657611fe97f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1660026159fc565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b6120b7817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b67ffffffffffffffff166120d28367ffffffffffffffff1690565b67ffffffffffffffff16111561211957612116817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615612197576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c8152602001908152602001600020600160028054905061242d9190615983565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169263d0e30db09234926004808301939282900301818588803b1580156124c557600080fd5b505af11580156124d9573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b61184e8383836000611a42565b60005471010000000000000000000000000000000000900460ff161561257a576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e1690637258a807906024016040805180830381865afa15801561262e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126529190615a55565b90925090508161268e576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a146126c157639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401351161275b576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd929092169363d0e30db093926004828101939282900301818588803b158015612a3057600080fd5b505af1158015612a44573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b600080600054700100000000000000000000000000000000900460ff166002811115612aaf57612aaf61555f565b14612ae6576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110612afb57612afb6158d5565b600091825260208220600590910201805490925063ffffffff90811614612b6a57815460028054909163ffffffff16908110612b3957612b396158d5565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090612ba290700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b612bb69067ffffffffffffffff1642615983565b612bd5612b95846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16612be99190615933565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b01667ffffffffffffffff168167ffffffffffffffff1611612c365780611884565b7f00000000000000000000000000000000000000000000000000000000000004b095945050505050565b600080612cff836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000008811115612d5e576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000612d798383615aa8565b9050670de0b6b3a76400006000612db0827f0000000000000000000000000000000000000000000000000000000000000008615abc565b90506000612dce612dc9670de0b6b3a764000086615abc565b614078565b90506000612ddc84846142d3565b90506000612dea8383614322565b90506000612df782614350565b90506000612e1682612e11670de0b6b3a76400008f615abc565b614538565b90506000612e248b83614322565b9050612e30818d615abc565b9f9e505050505050505050505050505050565b60028181548110612e5357600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b60008054700100000000000000000000000000000000900460ff166002811115612f0657612f0661555f565b14612f3d576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028781548110612f5257612f526158d5565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b9050612fb17f00000000000000000000000000000000000000000000000000000000000000086001615933565b61304d826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1614613087576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561317e576130da7f00000000000000000000000000000000000000000000000000000000000000047f0000000000000000000000000000000000000000000000000000000000000008615983565b6001901b6130f9846fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff166131159190615af9565b156131525761314961313a60016fffffffffffffffffffffffffffffffff8716615b0d565b865463ffffffff166000614608565b60030154613174565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506131a8565b600385015491506131a561313a6fffffffffffffffffffffffffffffffff86166001615b36565b90505b600882901b60088a8a6040516131bf9291906158c5565b6040518091039020901b14613200576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061320b8c6146ec565b9050600061321a836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff169063e14ced3290613294908f908f908f908f908a90600401615baa565b6020604051808303816000875af11580156132b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d791906159b7565b600485015491149150600090600290613382906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b61341e896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6134289190615be4565b6134329190615c07565b60ff161590508115158103613473576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156134ca576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff1660028111156135355761353561555f565b1461356c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061357b8661471b565b9350935093509350600061359185858585614b24565b905060007f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015613600573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613624919061599a565b90506001890361371c5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a84613680367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af11580156136f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061371691906159b7565b5061155b565b600289036137485773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8489613680565b600389036137745773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8487613680565b600489036138fb5760006137ba6fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000004614bde565b6009546137c79190615933565b6137d2906001615933565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061383b57367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036054013561383d565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156138d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f491906159b7565b505061155b565b60058903613994576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000038560c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016136d3565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060613a1f61188d565b9050909192565b600081831015613a365781613a38565b825b90505b92915050565b60008160000151826020015183604001518460600151604051602001613a80949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003613aec576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000613b1a85614c8c565b919450925090506001816001811115613b3557613b3561555f565b14613b6c576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451613b788385615933565b14613baf576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081613bc65790505093506000835b8651811015613cb457600080613c396040518060400160405280858c60000151613c1d9190615983565b8152602001858c60200151613c329190615933565b9052614c8c565b509150915060405180604001604052808383613c559190615933565b8152602001848b60200151613c6a9190615933565b815250888581518110613c7f57613c7f6158d5565b6020908102919091010152613c95600185615933565b9350613ca18183615933565b613cab9084615933565b92505050613bf3565b50845250919392505050565b60606000806000613cd085614c8c565b919450925090506000816001811115613ceb57613ceb61555f565b14613d22576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613d2c8284615933565b855114613d65576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118848560200151848461512a565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff90931692839290613dc3908490615933565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd921690637eee288d90604401600060405180830381600087803b158015613e5857600080fd5b505af1158015613e6c573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b6000613ee66fffffffffffffffffffffffffffffffff84166001615b36565b90506000613ef682866001614608565b9050600086901a8380613fe25750613f2f60027f0000000000000000000000000000000000000000000000000000000000000004615af9565b6004830154600290613fd3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b613fdd9190615c07565b60ff16145b1561403a5760ff811660011480613ffc575060ff81166002145b614035576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b613e6c565b60ff811615613e6c576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b17600082136140d757631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a76400000215820261431057637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b6000816000190483118202156143405763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d7821361437e57919050565b680755bf798b4a1bf1e5821261439c5763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000613a38670de0b6b3a76400008361455086614078565b61455a9190615c29565b6145649190615ce5565b614350565b6000806145f6837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826146515761464c6fffffffffffffffffffffffffffffffff86167f00000000000000000000000000000000000000000000000000000000000000046151bf565b61466c565b61466c856fffffffffffffffffffffffffffffffff1661534b565b905060028481548110614681576146816158d5565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff8281169116146146e457815460028054909163ffffffff169081106146cf576146cf6158d5565b90600052602060002090600502019150614692565b509392505050565b60008060008060006146fd8661471b565b935093509350935061471184848484614b24565b9695505050505050565b600080600080600085905060006002828154811061473b5761473b6158d5565b600091825260209091206004600590920201908101549091507f000000000000000000000000000000000000000000000000000000000000000490614812906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff161161484c576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f000000000000000000000000000000000000000000000000000000000000000490614913906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16925082111561498857825463ffffffff166149527f00000000000000000000000000000000000000000000000000000000000000046001615933565b830361495c578391505b6002818154811061496f5761496f6158d5565b9060005260206000209060050201935080945050614850565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149f16149dc856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff161490508015614ac0576000614a29836fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff161115614a94576000614a6b614a6360016fffffffffffffffffffffffffffffffff8616615b0d565b896001614608565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a50614a9a9050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614b16565b6000614ae2614a636fffffffffffffffffffffffffffffffff85166001615b36565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614b915760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611884565b8282604051602001614bbf9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614c6b847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614ccf576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614cf4576000600160009450945094505050615123565b60b78111614e0a576000614d09608083615983565b905080876000015111614d48576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614dc057507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614df7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060019550935060009250615123915050565b60bf8111614f68576000614e1f60b783615983565b905080876000015111614e5e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614ec0576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614f08576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f128184615933565b895111614f4b576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f56836001615933565b97509550600094506151239350505050565b60f78111614fcd576000614f7d60c083615983565b905080876000015111614fbc576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600195509350849250615123915050565b6000614fda60f783615983565b905080876000015111615019576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361507b576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116150c3576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6150cd8184615933565b895111615106576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615111836001615933565b97509550600194506151239350505050565b9193909250565b60608167ffffffffffffffff81111561514557615145615809565b6040519080825280601f01601f19166020018201604052801561516f576020820181803683370190505b50905081156151b85760006151848486615933565b90506020820160005b848110156151a557828101518282015260200161518d565b848111156151b4576000858301525b5050505b9392505050565b60008161525e846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116152745763b34b5c226000526004601cfd5b61527d8361534b565b90508161531c826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611613a3b57613a38615332836001615933565b6fffffffffffffffffffffffffffffffff8316906153f0565b600081196001830116816153df827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b60008061547d847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f8401126154ab57600080fd5b50813567ffffffffffffffff8111156154c357600080fd5b6020830191508360208285010111156154db57600080fd5b9250929050565b600080600083850360a08112156154f857600080fd5b608081121561550657600080fd5b50839250608084013567ffffffffffffffff81111561552457600080fd5b61553086828701615499565b9497909650939450505050565b6000806040838503121561555057600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106155c9577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806000606084860312156155e457600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561562157602081850181015186830182015201615605565b81811115615633576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000613a3860208301846155fb565b60006020828403121561568b57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146156b457600080fd5b50565b6000602082840312156156c957600080fd5b81356151b881615692565b803580151581146156e457600080fd5b919050565b600080600080608085870312156156ff57600080fd5b84359350602085013592506040850135915061571d606086016156d4565b905092959194509250565b60006020828403121561573a57600080fd5b81356fffffffffffffffffffffffffffffffff811681146151b857600080fd5b6000806000806000806080878903121561577357600080fd5b86359550615783602088016156d4565b9450604087013567ffffffffffffffff808211156157a057600080fd5b6157ac8a838b01615499565b909650945060608901359150808211156157c557600080fd5b506157d289828a01615499565b979a9699509497509295939492505050565b63ffffffff8416815282602082015260606040820152600061188460608301846155fb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006080828403121561584a57600080fd5b6040516080810181811067ffffffffffffffff82111715615894577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561594657615946615904565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361597c5761597c615904565b5060010190565b60008282101561599557615995615904565b500390565b6000602082840312156159ac57600080fd5b81516151b881615692565b6000602082840312156159c957600080fd5b5051919050565b600067ffffffffffffffff8083168185168083038211156159f3576159f3615904565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615a2357615a23615904565b02949350505050565b600067ffffffffffffffff83811690831681811015615a4d57615a4d615904565b039392505050565b60008060408385031215615a6857600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615ab757615ab7615a79565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615af457615af4615904565b500290565b600082615b0857615b08615a79565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615a4d57615a4d615904565b60006fffffffffffffffffffffffffffffffff8083168185168083038211156159f3576159f3615904565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615bbe606083018789615b61565b8281036020840152615bd1818688615b61565b9150508260408301529695505050505050565b600060ff821660ff841680821015615bfe57615bfe615904565b90039392505050565b600060ff831680615c1a57615c1a615a79565b8060ff84160691505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615c6a57615c6a615904565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615ca557615ca5615904565b60008712925087820587128484161615615cc157615cc1615904565b87850587128184161615615cd757615cd7615904565b505050929093029392505050565b600082615cf457615cf4615a79565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615d4857615d48615904565b50059056fea164736f6c634300080f000a"; + hex"6080604052600436106102f25760003560e01c806370872aa51161018f578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b18578063fa315aa914610b3c578063fe2bbeb214610b6f57600080fd5b8063ec5e630814610a95578063eff0f59214610ac8578063f8f43ff614610af857600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a0f578063d8cc1a3c14610a42578063dabd396d14610a6257600080fd5b8063c6f0308c14610937578063cf09e0d0146109c1578063d5d44d80146109e257600080fd5b80638d450a9511610143578063bcef3b551161011d578063bcef3b55146108b7578063bd8da956146108f7578063c395e1ca1461091757600080fd5b80638d450a9514610777578063a445ece6146107aa578063bbdc02db1461087657600080fd5b80638129fc1c116101745780638129fc1c1461071a5780638980e0cc146107225780638b85902b1461073757600080fd5b806370872aa5146106f25780637b0f0adc1461070757600080fd5b80633fc8cef3116102485780635c0cba33116101fc5780636361506d116101d65780636361506d1461066c5780636b6716c0146106ac5780636f034409146106df57600080fd5b80635c0cba3314610604578063609d33341461063757806360e274641461064c57600080fd5b806354fd4d501161022d57806354fd4d501461055e57806357da950e146105b45780635a5fa2d9146105e457600080fd5b80633fc8cef314610518578063472777c61461054b57600080fd5b80632810e1d6116102aa57806337b1b2291161028457806337b1b229146104655780633a768463146104a55780633e3ac912146104d857600080fd5b80632810e1d6146103de5780632ad69aeb146103f357806330dbe5701461041357600080fd5b806319effeb4116102db57806319effeb414610339578063200d2ed21461038457806325fc2ace146103bf57600080fd5b806301935130146102f757806303c2924d14610319575b600080fd5b34801561030357600080fd5b506103176103123660046154e2565b610b9f565b005b34801561032557600080fd5b5061031761033436600461553d565b610ec0565b34801561034557600080fd5b506000546103669068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561039057600080fd5b506000546103b290700100000000000000000000000000000000900460ff1681565b60405161037b919061558e565b3480156103cb57600080fd5b506008545b60405190815260200161037b565b3480156103ea57600080fd5b506103b2611566565b3480156103ff57600080fd5b506103d061040e36600461553d565b61180b565b34801561041f57600080fd5b506001546104409073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161037b565b34801561047157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610440565b3480156104b157600080fd5b507f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f738610440565b3480156104e457600080fd5b50600054610508907201000000000000000000000000000000000000900460ff1681565b604051901515815260200161037b565b34801561052457600080fd5b507f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92610440565b6103176105593660046155cf565b611841565b34801561056a57600080fd5b506105a76040518060400160405280600c81526020017f312e332e312d626574612e32000000000000000000000000000000000000000081525081565b60405161037b9190615666565b3480156105c057600080fd5b506008546009546105cf919082565b6040805192835260208301919091520161037b565b3480156105f057600080fd5b506103d06105ff366004615679565b611853565b34801561061057600080fd5b507f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e610440565b34801561064357600080fd5b506105a761188d565b34801561065857600080fd5b506103176106673660046156b7565b61189b565b34801561067857600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103d0565b3480156106b857600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610366565b6103176106ed3660046156e9565b611a42565b3480156106fe57600080fd5b506009546103d0565b6103176107153660046155cf565b61251b565b610317612528565b34801561072e57600080fd5b506002546103d0565b34801561074357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103d0565b34801561078357600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103d0565b3480156107b657600080fd5b506108226107c5366004615679565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff16606082015260800161037b565b34801561088257600080fd5b5060405163ffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260200161037b565b3480156108c357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103d0565b34801561090357600080fd5b50610366610912366004615679565b612a81565b34801561092357600080fd5b506103d0610932366004615728565b612c60565b34801561094357600080fd5b50610957610952366004615679565b612e43565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e00161037b565b3480156109cd57600080fd5b506000546103669067ffffffffffffffff1681565b3480156109ee57600080fd5b506103d06109fd3660046156b7565b60036020526000908152604090205481565b348015610a1b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000003856103d0565b348015610a4e57600080fd5b50610317610a5d36600461575a565b612eda565b348015610a6e57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b0610366565b348015610aa157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000046103d0565b348015610ad457600080fd5b50610508610ae3366004615679565b60046020526000908152604090205460ff1681565b348015610b0457600080fd5b50610317610b133660046155cf565b613509565b348015610b2457600080fd5b50610b2d6139c6565b60405161037b939291906157e4565b348015610b4857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000086103d0565b348015610b7b57600080fd5b50610508610b8a366004615679565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610bcb57610bcb61555f565b14610c02576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610c55576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610ca3610c9e36869003860186615838565b613a41565b14610cda576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610cef9291906158c5565b604051809103902014610d2e576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d77610d7284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613a9d92505050565b613b0a565b90506000610d9e82600881518110610d9157610d916158d5565b6020026020010151613cc0565b9050602081511115610ddc576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610e51576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610eec57610eec61555f565b14610f23576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610f3857610f386158d5565b906000526020600020906005020190506000610f5384612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b081169082161015610fbc576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611005576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561102257508515155b156110bd578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110555781611071565b600186015473ffffffffffffffffffffffffffffffffffffffff165b905061107d8187613d74565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff166060830152611160576fffffffffffffffffffffffffffffffff6040820152600181526000869003611160578195505b600086826020015163ffffffff166111789190615933565b90506000838211611189578161118b565b835b602084015190915063ffffffff165b818110156112d75760008682815481106111b6576111b66158d5565b6000918252602080832090910154808352600690915260409091205490915060ff1661120e576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611223576112236158d5565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112805750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b156112c257600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b505080806112cf9061594b565b91505061119a565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921790915584900361155b57606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558915801561145757506000547201000000000000000000000000000000000000900460ff165b156114cc5760015473ffffffffffffffffffffffffffffffffffffffff1661147f818a613d74565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff909116178855611559565b61151373ffffffffffffffffffffffffffffffffffffffff8216156114f1578161150d565b600189015473ffffffffffffffffffffffffffffffffffffffff165b89613d74565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff1660028111156115945761159461555f565b146115cb576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff1661162f576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008154811061165b5761165b6158d5565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611696576001611699565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff9091161770010000000000000000000000000000000083600281111561174a5761174a61555f565b02179055600281111561175f5761175f61555f565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e73ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156117f057600080fd5b505af1158015611804573d6000803e3d6000fd5b5050505090565b6005602052816000526040600020818154811061182757600080fd5b90600052602060002001600091509150505481565b905090565b61184e8383836001611a42565b505050565b6000818152600760209081526040808320600590925282208054825461188490610100900463ffffffff1682615983565b95945050505050565b606061183c60546020613e75565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260036020526040812080549082905590819003611900576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169063f3fef3a390604401600060405180830381600087803b15801561199057600080fd5b505af11580156119a4573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a02576040519150601f19603f3d011682016040523d82523d6000602084013e611a07565b606091505b505090508061184e576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008054700100000000000000000000000000000000900460ff166002811115611a6e57611a6e61555f565b14611aa5576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110611aba57611aba6158d5565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514611ba1576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000611c61826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580611c9c5750611c997f00000000000000000000000000000000000000000000000000000000000000046002615933565b81145b8015611ca6575084155b15611cdd576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015611d03575086155b15611d3a576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000008811115611d94576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dbf7f00000000000000000000000000000000000000000000000000000000000000046001615933565b8103611dd157611dd186888588613ec7565b34611ddb83612c60565b14611e12576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611e1d88612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b0811690821603611e85576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611eb260017f0000000000000000000000000000000000000000000000000000000000000008615983565b8303611ff0577f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f47919061599a565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb591906159b7565b611fe9907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166159d0565b9050612083565b61201b60017f0000000000000000000000000000000000000000000000000000000000000004615983565b830361205657611fe97f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1660026159fc565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b6120b7817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b67ffffffffffffffff166120d28367ffffffffffffffff1690565b67ffffffffffffffff16111561211957612116817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615612197576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c8152602001908152602001600020600160028054905061242d9190615983565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169263d0e30db09234926004808301939282900301818588803b1580156124c557600080fd5b505af11580156124d9573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b61184e8383836000611a42565b60005471010000000000000000000000000000000000900460ff161561257a576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e1690637258a807906024016040805180830381865afa15801561262e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126529190615a55565b90925090508161268e576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a146126c157639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401351161275b576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd929092169363d0e30db093926004828101939282900301818588803b158015612a3057600080fd5b505af1158015612a44573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b600080600054700100000000000000000000000000000000900460ff166002811115612aaf57612aaf61555f565b14612ae6576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110612afb57612afb6158d5565b600091825260208220600590910201805490925063ffffffff90811614612b6a57815460028054909163ffffffff16908110612b3957612b396158d5565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090612ba290700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b612bb69067ffffffffffffffff1642615983565b612bd5612b95846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16612be99190615933565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b01667ffffffffffffffff168167ffffffffffffffff1611612c365780611884565b7f00000000000000000000000000000000000000000000000000000000000004b095945050505050565b600080612cff836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000008811115612d5e576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000612d798383615aa8565b9050670de0b6b3a76400006000612db0827f0000000000000000000000000000000000000000000000000000000000000008615abc565b90506000612dce612dc9670de0b6b3a764000086615abc565b614078565b90506000612ddc84846142d3565b90506000612dea8383614322565b90506000612df782614350565b90506000612e1682612e11670de0b6b3a76400008f615abc565b614538565b90506000612e248b83614322565b9050612e30818d615abc565b9f9e505050505050505050505050505050565b60028181548110612e5357600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b60008054700100000000000000000000000000000000900460ff166002811115612f0657612f0661555f565b14612f3d576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028781548110612f5257612f526158d5565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b9050612fb17f00000000000000000000000000000000000000000000000000000000000000086001615933565b61304d826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1614613087576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561317e576130da7f00000000000000000000000000000000000000000000000000000000000000047f0000000000000000000000000000000000000000000000000000000000000008615983565b6001901b6130f9846fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff166131159190615af9565b156131525761314961313a60016fffffffffffffffffffffffffffffffff8716615b0d565b865463ffffffff166000614608565b60030154613174565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506131a8565b600385015491506131a561313a6fffffffffffffffffffffffffffffffff86166001615b36565b90505b600882901b60088a8a6040516131bf9291906158c5565b6040518091039020901b14613200576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061320b8c6146ec565b9050600061321a836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff169063e14ced3290613294908f908f908f908f908a90600401615baa565b6020604051808303816000875af11580156132b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d791906159b7565b600485015491149150600090600290613382906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b61341e896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6134289190615be4565b6134329190615c07565b60ff161590508115158103613473576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156134ca576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff1660028111156135355761353561555f565b1461356c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061357b8661471b565b9350935093509350600061359185858585614b24565b905060007f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015613600573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613624919061599a565b90506001890361371c5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a84613680367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af11580156136f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061371691906159b7565b5061155b565b600289036137485773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8489613680565b600389036137745773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8487613680565b600489036138fb5760006137ba6fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000004614bde565b6009546137c79190615933565b6137d2906001615933565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061383b57367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036054013561383d565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156138d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f491906159b7565b505061155b565b60058903613994576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000038560c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016136d3565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060613a1f61188d565b9050909192565b600081831015613a365781613a38565b825b90505b92915050565b60008160000151826020015183604001518460600151604051602001613a80949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003613aec576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000613b1a85614c8c565b919450925090506001816001811115613b3557613b3561555f565b14613b6c576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451613b788385615933565b14613baf576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081613bc65790505093506000835b8651811015613cb457600080613c396040518060400160405280858c60000151613c1d9190615983565b8152602001858c60200151613c329190615933565b9052614c8c565b509150915060405180604001604052808383613c559190615933565b8152602001848b60200151613c6a9190615933565b815250888581518110613c7f57613c7f6158d5565b6020908102919091010152613c95600185615933565b9350613ca18183615933565b613cab9084615933565b92505050613bf3565b50845250919392505050565b60606000806000613cd085614c8c565b919450925090506000816001811115613ceb57613ceb61555f565b14613d22576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613d2c8284615933565b855114613d65576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118848560200151848461512a565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff90931692839290613dc3908490615933565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd921690637eee288d90604401600060405180830381600087803b158015613e5857600080fd5b505af1158015613e6c573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b6000613ee66fffffffffffffffffffffffffffffffff84166001615b36565b90506000613ef682866001614608565b9050600086901a8380613fe25750613f2f60027f0000000000000000000000000000000000000000000000000000000000000004615af9565b6004830154600290613fd3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b613fdd9190615c07565b60ff16145b1561403a5760ff811660011480613ffc575060ff81166002145b614035576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b613e6c565b60ff811615613e6c576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b17600082136140d757631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a76400000215820261431057637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b6000816000190483118202156143405763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d7821361437e57919050565b680755bf798b4a1bf1e5821261439c5763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000613a38670de0b6b3a76400008361455086614078565b61455a9190615c29565b6145649190615ce5565b614350565b6000806145f6837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826146515761464c6fffffffffffffffffffffffffffffffff86167f00000000000000000000000000000000000000000000000000000000000000046151bf565b61466c565b61466c856fffffffffffffffffffffffffffffffff1661534b565b905060028481548110614681576146816158d5565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff8281169116146146e457815460028054909163ffffffff169081106146cf576146cf6158d5565b90600052602060002090600502019150614692565b509392505050565b60008060008060006146fd8661471b565b935093509350935061471184848484614b24565b9695505050505050565b600080600080600085905060006002828154811061473b5761473b6158d5565b600091825260209091206004600590920201908101549091507f000000000000000000000000000000000000000000000000000000000000000490614812906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff161161484c576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f000000000000000000000000000000000000000000000000000000000000000490614913906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16925082111561498857825463ffffffff166149527f00000000000000000000000000000000000000000000000000000000000000046001615933565b830361495c578391505b6002818154811061496f5761496f6158d5565b9060005260206000209060050201935080945050614850565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149f16149dc856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff161490508015614ac0576000614a29836fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff161115614a94576000614a6b614a6360016fffffffffffffffffffffffffffffffff8616615b0d565b896001614608565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a50614a9a9050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614b16565b6000614ae2614a636fffffffffffffffffffffffffffffffff85166001615b36565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614b915760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611884565b8282604051602001614bbf9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614c6b847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614ccf576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614cf4576000600160009450945094505050615123565b60b78111614e0a576000614d09608083615983565b905080876000015111614d48576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614dc057507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614df7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060019550935060009250615123915050565b60bf8111614f68576000614e1f60b783615983565b905080876000015111614e5e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614ec0576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614f08576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f128184615933565b895111614f4b576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f56836001615933565b97509550600094506151239350505050565b60f78111614fcd576000614f7d60c083615983565b905080876000015111614fbc576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600195509350849250615123915050565b6000614fda60f783615983565b905080876000015111615019576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361507b576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116150c3576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6150cd8184615933565b895111615106576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615111836001615933565b97509550600194506151239350505050565b9193909250565b60608167ffffffffffffffff81111561514557615145615809565b6040519080825280601f01601f19166020018201604052801561516f576020820181803683370190505b50905081156151b85760006151848486615933565b90506020820160005b848110156151a557828101518282015260200161518d565b848111156151b4576000858301525b5050505b9392505050565b60008161525e846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116152745763b34b5c226000526004601cfd5b61527d8361534b565b90508161531c826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611613a3b57613a38615332836001615933565b6fffffffffffffffffffffffffffffffff8316906153f0565b600081196001830116816153df827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b60008061547d847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f8401126154ab57600080fd5b50813567ffffffffffffffff8111156154c357600080fd5b6020830191508360208285010111156154db57600080fd5b9250929050565b600080600083850360a08112156154f857600080fd5b608081121561550657600080fd5b50839250608084013567ffffffffffffffff81111561552457600080fd5b61553086828701615499565b9497909650939450505050565b6000806040838503121561555057600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106155c9577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806000606084860312156155e457600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561562157602081850181015186830182015201615605565b81811115615633576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000613a3860208301846155fb565b60006020828403121561568b57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146156b457600080fd5b50565b6000602082840312156156c957600080fd5b81356151b881615692565b803580151581146156e457600080fd5b919050565b600080600080608085870312156156ff57600080fd5b84359350602085013592506040850135915061571d606086016156d4565b905092959194509250565b60006020828403121561573a57600080fd5b81356fffffffffffffffffffffffffffffffff811681146151b857600080fd5b6000806000806000806080878903121561577357600080fd5b86359550615783602088016156d4565b9450604087013567ffffffffffffffff808211156157a057600080fd5b6157ac8a838b01615499565b909650945060608901359150808211156157c557600080fd5b506157d289828a01615499565b979a9699509497509295939492505050565b63ffffffff8416815282602082015260606040820152600061188460608301846155fb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006080828403121561584a57600080fd5b6040516080810181811067ffffffffffffffff82111715615894577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561594657615946615904565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361597c5761597c615904565b5060010190565b60008282101561599557615995615904565b500390565b6000602082840312156159ac57600080fd5b81516151b881615692565b6000602082840312156159c957600080fd5b5051919050565b600067ffffffffffffffff8083168185168083038211156159f3576159f3615904565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615a2357615a23615904565b02949350505050565b600067ffffffffffffffff83811690831681811015615a4d57615a4d615904565b039392505050565b60008060408385031215615a6857600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615ab757615ab7615a79565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615af457615af4615904565b500290565b600082615b0857615b08615a79565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615a4d57615a4d615904565b60006fffffffffffffffffffffffffffffffff8083168185168083038211156159f3576159f3615904565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615bbe606083018789615b61565b8281036020840152615bd1818688615b61565b9150508260408301529695505050505050565b600060ff821660ff841680821015615bfe57615bfe615904565b90039392505050565b600060ff831680615c1a57615c1a615a79565b8060ff84160691505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615c6a57615c6a615904565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615ca557615ca5615904565b60008712925087820587128484161615615cc157615cc1615904565b87850587128184161615615cd757615cd7615904565b505050929093029392505050565b600082615cf457615cf4615a79565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615d4857615d48615904565b50059056fea164736f6c634300080f000a"; bytes internal constant acc34Code = - hex"6080604052600436106103085760003560e01c806370872aa51161019a578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b94578063fa315aa914610bb8578063fe2bbeb214610beb57600080fd5b8063ec5e630814610b11578063eff0f59214610b44578063f8f43ff614610b7457600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a8b578063d8cc1a3c14610abe578063dabd396d14610ade57600080fd5b8063c6f0308c146109b3578063cf09e0d014610a3d578063d5d44d8014610a5e57600080fd5b8063a445ece611610143578063bcef3b551161011d578063bcef3b5514610933578063bd8da95614610973578063c395e1ca1461099357600080fd5b8063a445ece6146107f3578063a8e4fb90146108bf578063bbdc02db146108f257600080fd5b80638980e0cc116101745780638980e0cc1461076b5780638b85902b146107805780638d450a95146107c057600080fd5b806370872aa51461073b5780637b0f0adc146107505780638129fc1c1461076357600080fd5b80633fc8cef31161025e5780635c0cba33116102075780636361506d116101e15780636361506d146106b55780636b6716c0146106f55780636f0344091461072857600080fd5b80635c0cba331461064d578063609d33341461068057806360e274641461069557600080fd5b806354fd4d501161023857806354fd4d50146105a757806357da950e146105fd5780635a5fa2d91461062d57600080fd5b80633fc8cef31461052e578063472777c614610561578063534db0e21461057457600080fd5b80632810e1d6116102c057806337b1b2291161029a57806337b1b2291461047b5780633a768463146104bb5780633e3ac912146104ee57600080fd5b80632810e1d6146103f45780632ad69aeb1461040957806330dbe5701461042957600080fd5b806319effeb4116102f157806319effeb41461034f578063200d2ed21461039a57806325fc2ace146103d557600080fd5b8063019351301461030d57806303c2924d1461032f575b600080fd5b34801561031957600080fd5b5061032d61032836600461575d565b610c1b565b005b34801561033b57600080fd5b5061032d61034a3660046157b8565b610f3c565b34801561035b57600080fd5b5060005461037c9068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156103a657600080fd5b506000546103c890700100000000000000000000000000000000900460ff1681565b6040516103919190615809565b3480156103e157600080fd5b506008545b604051908152602001610391565b34801561040057600080fd5b506103c86115e2565b34801561041557600080fd5b506103e66104243660046157b8565b611887565b34801561043557600080fd5b506001546104569073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610391565b34801561048757600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610456565b3480156104c757600080fd5b507f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe7806610456565b3480156104fa57600080fd5b5060005461051e907201000000000000000000000000000000000000900460ff1681565b6040519015158152602001610391565b34801561053a57600080fd5b507f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309610456565b61032d61056f36600461584a565b6118bd565b34801561058057600080fd5b507f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63610456565b3480156105b357600080fd5b506105f06040518060400160405280600a81526020017f312e332e302d72632e310000000000000000000000000000000000000000000081525081565b60405161039191906158e1565b34801561060957600080fd5b50600854600954610618919082565b60408051928352602083019190915201610391565b34801561063957600080fd5b506103e66106483660046158f4565b6118cf565b34801561065957600080fd5b507f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e610456565b34801561068c57600080fd5b506105f0611909565b3480156106a157600080fd5b5061032d6106b0366004615932565b611917565b3480156106c157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103e6565b34801561070157600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061037c565b61032d610736366004615964565b611abe565b34801561074757600080fd5b506009546103e6565b61032d61075e36600461584a565b611b7f565b61032d611b8c565b34801561077757600080fd5b506002546103e6565b34801561078c57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103e6565b3480156107cc57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103e6565b3480156107ff57600080fd5b5061086b61080e3660046158f4565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff166060820152608001610391565b3480156108cb57600080fd5b507f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8610456565b3480156108fe57600080fd5b5060405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000001168152602001610391565b34801561093f57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103e6565b34801561097f57600080fd5b5061037c61098e3660046158f4565b611c05565b34801561099f57600080fd5b506103e66109ae3660046159a3565b611de4565b3480156109bf57600080fd5b506109d36109ce3660046158f4565b611fc7565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e001610391565b348015610a4957600080fd5b5060005461037c9067ffffffffffffffff1681565b348015610a6a57600080fd5b506103e6610a79366004615932565b60036020526000908152604090205481565b348015610a9757600080fd5b507f00000000000000000000000000000000000000000000000000000000000003856103e6565b348015610aca57600080fd5b5061032d610ad93660046159d5565b61205e565b348015610aea57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b061037c565b348015610b1d57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000046103e6565b348015610b5057600080fd5b5061051e610b5f3660046158f4565b60046020526000908152604090205460ff1681565b348015610b8057600080fd5b5061032d610b8f36600461584a565b612123565b348015610ba057600080fd5b50610ba96125e0565b60405161039193929190615a5f565b348015610bc457600080fd5b507f00000000000000000000000000000000000000000000000000000000000000086103e6565b348015610bf757600080fd5b5061051e610c063660046158f4565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610c4757610c476157da565b14610c7e576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610cd1576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d08367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610d1f610d1a36869003860186615ab3565b61265b565b14610d56576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610d6b929190615b40565b604051809103902014610daa576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610df3610dee84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506126b792505050565b612724565b90506000610e1a82600881518110610e0d57610e0d615b50565b60200260200101516128da565b9050602081511115610e58576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610ecd576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610f6857610f686157da565b14610f9f576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610fb457610fb4615b50565b906000526020600020906005020190506000610fcf84611c05565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b081169082161015611038576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611081576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561109e57508515155b15611139578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110d157816110ed565b600186015473ffffffffffffffffffffffffffffffffffffffff165b90506110f9818761298e565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff1660608301526111dc576fffffffffffffffffffffffffffffffff60408201526001815260008690036111dc578195505b600086826020015163ffffffff166111f49190615bae565b905060008382116112055781611207565b835b602084015190915063ffffffff165b8181101561135357600086828154811061123257611232615b50565b6000918252602080832090910154808352600690915260409091205490915060ff1661128a576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002828154811061129f5761129f615b50565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112fc5750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b1561133e57600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b5050808061134b90615bc6565b915050611216565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909316929092179091558490036115d757606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055891580156114d357506000547201000000000000000000000000000000000000900460ff165b156115485760015473ffffffffffffffffffffffffffffffffffffffff166114fb818a61298e565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff9091161788556115d5565b61158f73ffffffffffffffffffffffffffffffffffffffff82161561156d5781611589565b600189015473ffffffffffffffffffffffffffffffffffffffff165b8961298e565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff166002811115611610576116106157da565b14611647576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff166116ab576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660026000815481106116d7576116d7615b50565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611712576001611715565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff909116177001000000000000000000000000000000008360028111156117c6576117c66157da565b0217905560028111156117db576117db6157da565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e73ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561186c57600080fd5b505af1158015611880573d6000803e3d6000fd5b5050505090565b600560205281600052604060002081815481106118a357600080fd5b90600052602060002001600091509150505481565b905090565b6118ca8383836001611abe565b505050565b6000818152600760209081526040808320600590925282208054825461190090610100900463ffffffff1682615bfe565b95945050505050565b60606118b860546020612a8f565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604081208054908290559081900361197c576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309169063f3fef3a390604401600060405180830381600087803b158015611a0c57600080fd5b505af1158015611a20573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a7e576040519150601f19603f3d011682016040523d82523d6000602084013e611a83565b606091505b50509050806118ca576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8161480611b3757503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b6316145b611b6d576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b7984848484612ae1565b50505050565b6118ca8383836000611abe565b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c81614611bfb576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c036135ba565b565b600080600054700100000000000000000000000000000000900460ff166002811115611c3357611c336157da565b14611c6a576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110611c7f57611c7f615b50565b600091825260208220600590910201805490925063ffffffff90811614611cee57815460028054909163ffffffff16908110611cbd57611cbd615b50565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090611d2690700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b611d3a9067ffffffffffffffff1642615bfe565b611d59611d19846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16611d6d9190615bae565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b01667ffffffffffffffff168167ffffffffffffffff1611611dba5780611900565b7f00000000000000000000000000000000000000000000000000000000000004b095945050505050565b600080611e83836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000008811115611ee2576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000611efd8383615c44565b9050670de0b6b3a76400006000611f34827f0000000000000000000000000000000000000000000000000000000000000008615c58565b90506000611f52611f4d670de0b6b3a764000086615c58565b613b13565b90506000611f608484613d6e565b90506000611f6e8383613dbd565b90506000611f7b82613deb565b90506000611f9a82611f95670de0b6b3a76400008f615c58565b613fd3565b90506000611fa88b83613dbd565b9050611fb4818d615c58565b9f9e505050505050505050505050505050565b60028181548110611fd757600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c81614806120d757503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b6316145b61210d576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61211b868686868686614004565b505050505050565b60008054700100000000000000000000000000000000900460ff16600281111561214f5761214f6157da565b14612186576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061219586614633565b935093509350935060006121ab85858585614a3c565b905060007f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561221a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223e9190615c95565b9050600189036123365773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8461229a367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af115801561230c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123309190615cb2565b506115d7565b600289036123625773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848961229a565b6003890361238e5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848761229a565b600489036125155760006123d46fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000004614af6565b6009546123e19190615bae565b6123ec906001615bae565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061245557367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135612457565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156124ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250e9190615cb2565b50506115d7565b600589036125ae576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000038560c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016122ed565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000001367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060612639611909565b9050909192565b6000818310156126505781612652565b825b90505b92915050565b6000816000015182602001518360400151846060015160405160200161269a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003612706576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b6060600080600061273485614ba4565b91945092509050600181600181111561274f5761274f6157da565b14612786576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516127928385615bae565b146127c9576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816127e05790505093506000835b86518110156128ce576000806128536040518060400160405280858c600001516128379190615bfe565b8152602001858c6020015161284c9190615bae565b9052614ba4565b50915091506040518060400160405280838361286f9190615bae565b8152602001848b602001516128849190615bae565b81525088858151811061289957612899615b50565b60209081029190910101526128af600185615bae565b93506128bb8183615bae565b6128c59084615bae565b9250505061280d565b50845250919392505050565b606060008060006128ea85614ba4565b919450925090506000816001811115612905576129056157da565b1461293c576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129468284615bae565b85511461297f576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61190085602001518484615042565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff909316928392906129dd908490615bae565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f000000000000000000000000d6eaf4c146261653ee059077b78ed088add543091690637eee288d90604401600060405180830381600087803b158015612a7257600080fd5b505af1158015612a86573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b60008054700100000000000000000000000000000000900460ff166002811115612b0d57612b0d6157da565b14612b44576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110612b5957612b59615b50565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514612c40576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000612d00826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580612d3b5750612d387f00000000000000000000000000000000000000000000000000000000000000046002615bae565b81145b8015612d45575084155b15612d7c576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015612da2575086155b15612dd9576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000008811115612e33576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e5e7f00000000000000000000000000000000000000000000000000000000000000046001615bae565b8103612e7057612e70868885886150d7565b34612e7a83611de4565b14612eb1576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612ebc88611c05565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b0811690821603612f24576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612f5160017f0000000000000000000000000000000000000000000000000000000000000008615bfe565b830361308f577f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fe69190615c95565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015613030573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130549190615cb2565b613088907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16615ccb565b9050613122565b6130ba60017f0000000000000000000000000000000000000000000000000000000000000004615bfe565b83036130f5576130887f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166002615cf7565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b613156817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615d27565b67ffffffffffffffff166131718367ffffffffffffffff1690565b67ffffffffffffffff1611156131b8576131b5817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615d27565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615613236576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c815260200190815260200160002060016002805490506134cc9190615bfe565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309169263d0e30db09234926004808301939282900301818588803b15801561356457600080fd5b505af1158015613578573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b60005471010000000000000000000000000000000000900460ff161561360c576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000001166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e1690637258a807906024016040805180830381865afa1580156136c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136e49190615d50565b909250905081613720576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a1461375357639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135116137ed576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f000000000000000000000000d6eaf4c146261653ee059077b78ed088add543099092169363d0e30db093926004828101939282900301818588803b158015613ac257600080fd5b505af1158015613ad6573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b1760008213613b7257631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a764000002158202613dab57637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b600081600019048311820215613ddb5763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d78213613e1957919050565b680755bf798b4a1bf1e58212613e375763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000612652670de0b6b3a764000083613feb86613b13565b613ff59190615d74565b613fff9190615e30565b613deb565b60008054700100000000000000000000000000000000900460ff166002811115614030576140306157da565b14614067576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002878154811061407c5761407c615b50565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506140db7f00000000000000000000000000000000000000000000000000000000000000086001615bae565b614177826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16146141b1576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008089156142a8576142047f00000000000000000000000000000000000000000000000000000000000000047f0000000000000000000000000000000000000000000000000000000000000008615bfe565b6001901b614223846fffffffffffffffffffffffffffffffff16615288565b6fffffffffffffffffffffffffffffffff1661423f9190615e98565b1561427c5761427361426460016fffffffffffffffffffffffffffffffff8716615eac565b865463ffffffff166000615327565b6003015461429e565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506142d2565b600385015491506142cf6142646fffffffffffffffffffffffffffffffff86166001615ed5565b90505b600882901b60088a8a6040516142e9929190615b40565b6040518091039020901b1461432a576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006143358c61540b565b90506000614344836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000444e09fe6d839273316a87002ab0efbea6fe780673ffffffffffffffffffffffffffffffffffffffff169063e14ced32906143be908f908f908f908f908a90600401615f49565b6020604051808303816000875af11580156143dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144019190615cb2565b6004850154911491506000906002906144ac906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b614548896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6145529190615f83565b61455c9190615fa6565b60ff16159050811515810361459d576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156145f4576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b600080600080600085905060006002828154811061465357614653615b50565b600091825260209091206004600590920201908101549091507f00000000000000000000000000000000000000000000000000000000000000049061472a906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611614764576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f00000000000000000000000000000000000000000000000000000000000000049061482b906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1692508211156148a057825463ffffffff1661486a7f00000000000000000000000000000000000000000000000000000000000000046001615bae565b8303614874578391505b6002818154811061488757614887615b50565b9060005260206000209060050201935080945050614768565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149096148f4856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff1614905080156149d8576000614941836fffffffffffffffffffffffffffffffff16615288565b6fffffffffffffffffffffffffffffffff1611156149ac57600061498361497b60016fffffffffffffffffffffffffffffffff8616615eac565b896001615327565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a506149b29050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614a2e565b60006149fa61497b6fffffffffffffffffffffffffffffffff85166001615ed5565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614aa95760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611900565b8282604051602001614ad79291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614b83847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614be7576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614c0c57600060016000945094509450505061503b565b60b78111614d22576000614c21608083615bfe565b905080876000015111614c60576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614cd857507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614d0f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061503b915050565b60bf8111614e80576000614d3760b783615bfe565b905080876000015111614d76576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614dd8576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614e20576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614e2a8184615bae565b895111614e63576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614e6e836001615bae565b975095506000945061503b9350505050565b60f78111614ee5576000614e9560c083615bfe565b905080876000015111614ed4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061503b915050565b6000614ef260f783615bfe565b905080876000015111614f31576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614f93576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614fdb576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614fe58184615bae565b89511161501e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615029836001615bae565b975095506001945061503b9350505050565b9193909250565b60608167ffffffffffffffff81111561505d5761505d615a84565b6040519080825280601f01601f191660200182016040528015615087576020820181803683370190505b50905081156150d057600061509c8486615bae565b90506020820160005b848110156150bd5782810151828201526020016150a5565b848111156150cc576000858301525b5050505b9392505050565b60006150f66fffffffffffffffffffffffffffffffff84166001615ed5565b9050600061510682866001615327565b9050600086901a83806151f2575061513f60027f0000000000000000000000000000000000000000000000000000000000000004615e98565b60048301546002906151e3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6151ed9190615fa6565b60ff16145b1561524a5760ff81166001148061520c575060ff81166002145b615245576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016137e4565b612a86565b60ff811615612a86576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016137e4565b600080615315837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826153705761536b6fffffffffffffffffffffffffffffffff86167f000000000000000000000000000000000000000000000000000000000000000461543a565b61538b565b61538b856fffffffffffffffffffffffffffffffff166155c6565b9050600284815481106153a0576153a0615b50565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff82811691161461540357815460028054909163ffffffff169081106153ee576153ee615b50565b906000526020600020906005020191506153b1565b509392505050565b600080600080600061541c86614633565b935093509350935061543084848484614a3c565b9695505050505050565b6000816154d9846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116154ef5763b34b5c226000526004601cfd5b6154f8836155c6565b905081615597826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611612655576126526155ad836001615bae565b6fffffffffffffffffffffffffffffffff83169061566b565b6000811960018301168161565a827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b6000806156f8847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f84011261572657600080fd5b50813567ffffffffffffffff81111561573e57600080fd5b60208301915083602082850101111561575657600080fd5b9250929050565b600080600083850360a081121561577357600080fd5b608081121561578157600080fd5b50839250608084013567ffffffffffffffff81111561579f57600080fd5b6157ab86828701615714565b9497909650939450505050565b600080604083850312156157cb57600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310615844577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060006060848603121561585f57600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561589c57602081850181015186830182015201615880565b818111156158ae576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006126526020830184615876565b60006020828403121561590657600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461592f57600080fd5b50565b60006020828403121561594457600080fd5b81356150d08161590d565b8035801515811461595f57600080fd5b919050565b6000806000806080858703121561597a57600080fd5b8435935060208501359250604085013591506159986060860161594f565b905092959194509250565b6000602082840312156159b557600080fd5b81356fffffffffffffffffffffffffffffffff811681146150d057600080fd5b600080600080600080608087890312156159ee57600080fd5b863595506159fe6020880161594f565b9450604087013567ffffffffffffffff80821115615a1b57600080fd5b615a278a838b01615714565b90965094506060890135915080821115615a4057600080fd5b50615a4d89828a01615714565b979a9699509497509295939492505050565b63ffffffff841681528260208201526060604082015260006119006060830184615876565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060808284031215615ac557600080fd5b6040516080810181811067ffffffffffffffff82111715615b0f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115615bc157615bc1615b7f565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615bf757615bf7615b7f565b5060010190565b600082821015615c1057615c10615b7f565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615c5357615c53615c15565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615c9057615c90615b7f565b500290565b600060208284031215615ca757600080fd5b81516150d08161590d565b600060208284031215615cc457600080fd5b5051919050565b600067ffffffffffffffff808316818516808303821115615cee57615cee615b7f565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615d1e57615d1e615b7f565b02949350505050565b600067ffffffffffffffff83811690831681811015615d4857615d48615b7f565b039392505050565b60008060408385031215615d6357600080fd5b505080516020909101519092909150565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615db557615db5615b7f565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615df057615df0615b7f565b60008712925087820587128484161615615e0c57615e0c615b7f565b87850587128184161615615e2257615e22615b7f565b505050929093029392505050565b600082615e3f57615e3f615c15565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615e9357615e93615b7f565b500590565b600082615ea757615ea7615c15565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615d4857615d48615b7f565b60006fffffffffffffffffffffffffffffffff808316818516808303821115615cee57615cee615b7f565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615f5d606083018789615f00565b8281036020840152615f70818688615f00565b9150508260408301529695505050505050565b600060ff821660ff841680821015615f9d57615f9d615b7f565b90039392505050565b600060ff831680615fb957615fb9615c15565b8060ff8416069150509291505056fea164736f6c634300080f000a"; + hex"6080604052600436106103085760003560e01c806370872aa51161019a578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b94578063fa315aa914610bb8578063fe2bbeb214610beb57600080fd5b8063ec5e630814610b11578063eff0f59214610b44578063f8f43ff614610b7457600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a8b578063d8cc1a3c14610abe578063dabd396d14610ade57600080fd5b8063c6f0308c146109b3578063cf09e0d014610a3d578063d5d44d8014610a5e57600080fd5b8063a445ece611610143578063bcef3b551161011d578063bcef3b5514610933578063bd8da95614610973578063c395e1ca1461099357600080fd5b8063a445ece6146107f3578063a8e4fb90146108bf578063bbdc02db146108f257600080fd5b80638980e0cc116101745780638980e0cc1461076b5780638b85902b146107805780638d450a95146107c057600080fd5b806370872aa51461073b5780637b0f0adc146107505780638129fc1c1461076357600080fd5b80633fc8cef31161025e5780635c0cba33116102075780636361506d116101e15780636361506d146106b55780636b6716c0146106f55780636f0344091461072857600080fd5b80635c0cba331461064d578063609d33341461068057806360e274641461069557600080fd5b806354fd4d501161023857806354fd4d50146105a757806357da950e146105fd5780635a5fa2d91461062d57600080fd5b80633fc8cef31461052e578063472777c614610561578063534db0e21461057457600080fd5b80632810e1d6116102c057806337b1b2291161029a57806337b1b2291461047b5780633a768463146104bb5780633e3ac912146104ee57600080fd5b80632810e1d6146103f45780632ad69aeb1461040957806330dbe5701461042957600080fd5b806319effeb4116102f157806319effeb41461034f578063200d2ed21461039a57806325fc2ace146103d557600080fd5b8063019351301461030d57806303c2924d1461032f575b600080fd5b34801561031957600080fd5b5061032d61032836600461575d565b610c1b565b005b34801561033b57600080fd5b5061032d61034a3660046157b8565b610f3c565b34801561035b57600080fd5b5060005461037c9068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156103a657600080fd5b506000546103c890700100000000000000000000000000000000900460ff1681565b6040516103919190615809565b3480156103e157600080fd5b506008545b604051908152602001610391565b34801561040057600080fd5b506103c86115e2565b34801561041557600080fd5b506103e66104243660046157b8565b611887565b34801561043557600080fd5b506001546104569073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610391565b34801561048757600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610456565b3480156104c757600080fd5b507f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f738610456565b3480156104fa57600080fd5b5060005461051e907201000000000000000000000000000000000000900460ff1681565b6040519015158152602001610391565b34801561053a57600080fd5b507f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309610456565b61032d61056f36600461584a565b6118bd565b34801561058057600080fd5b507f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63610456565b3480156105b357600080fd5b506105f06040518060400160405280600c81526020017f312e332e312d626574612e32000000000000000000000000000000000000000081525081565b60405161039191906158e1565b34801561060957600080fd5b50600854600954610618919082565b60408051928352602083019190915201610391565b34801561063957600080fd5b506103e66106483660046158f4565b6118cf565b34801561065957600080fd5b507f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e610456565b34801561068c57600080fd5b506105f0611909565b3480156106a157600080fd5b5061032d6106b0366004615932565b611917565b3480156106c157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103e6565b34801561070157600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061037c565b61032d610736366004615964565b611abe565b34801561074757600080fd5b506009546103e6565b61032d61075e36600461584a565b611b7f565b61032d611b8c565b34801561077757600080fd5b506002546103e6565b34801561078c57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103e6565b3480156107cc57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103e6565b3480156107ff57600080fd5b5061086b61080e3660046158f4565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff166060820152608001610391565b3480156108cb57600080fd5b507f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8610456565b3480156108fe57600080fd5b5060405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000001168152602001610391565b34801561093f57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103e6565b34801561097f57600080fd5b5061037c61098e3660046158f4565b611c05565b34801561099f57600080fd5b506103e66109ae3660046159a3565b611de4565b3480156109bf57600080fd5b506109d36109ce3660046158f4565b611fc7565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e001610391565b348015610a4957600080fd5b5060005461037c9067ffffffffffffffff1681565b348015610a6a57600080fd5b506103e6610a79366004615932565b60036020526000908152604090205481565b348015610a9757600080fd5b507f00000000000000000000000000000000000000000000000000000000000003856103e6565b348015610aca57600080fd5b5061032d610ad93660046159d5565b61205e565b348015610aea57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b061037c565b348015610b1d57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000046103e6565b348015610b5057600080fd5b5061051e610b5f3660046158f4565b60046020526000908152604090205460ff1681565b348015610b8057600080fd5b5061032d610b8f36600461584a565b612123565b348015610ba057600080fd5b50610ba96125e0565b60405161039193929190615a5f565b348015610bc457600080fd5b507f00000000000000000000000000000000000000000000000000000000000000086103e6565b348015610bf757600080fd5b5061051e610c063660046158f4565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610c4757610c476157da565b14610c7e576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610cd1576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d08367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610d1f610d1a36869003860186615ab3565b61265b565b14610d56576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610d6b929190615b40565b604051809103902014610daa576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610df3610dee84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506126b792505050565b612724565b90506000610e1a82600881518110610e0d57610e0d615b50565b60200260200101516128da565b9050602081511115610e58576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610ecd576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610f6857610f686157da565b14610f9f576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610fb457610fb4615b50565b906000526020600020906005020190506000610fcf84611c05565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b081169082161015611038576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611081576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561109e57508515155b15611139578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110d157816110ed565b600186015473ffffffffffffffffffffffffffffffffffffffff165b90506110f9818761298e565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff1660608301526111dc576fffffffffffffffffffffffffffffffff60408201526001815260008690036111dc578195505b600086826020015163ffffffff166111f49190615bae565b905060008382116112055781611207565b835b602084015190915063ffffffff165b8181101561135357600086828154811061123257611232615b50565b6000918252602080832090910154808352600690915260409091205490915060ff1661128a576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002828154811061129f5761129f615b50565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112fc5750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b1561133e57600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b5050808061134b90615bc6565b915050611216565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909316929092179091558490036115d757606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055891580156114d357506000547201000000000000000000000000000000000000900460ff165b156115485760015473ffffffffffffffffffffffffffffffffffffffff166114fb818a61298e565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff9091161788556115d5565b61158f73ffffffffffffffffffffffffffffffffffffffff82161561156d5781611589565b600189015473ffffffffffffffffffffffffffffffffffffffff165b8961298e565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff166002811115611610576116106157da565b14611647576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff166116ab576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660026000815481106116d7576116d7615b50565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611712576001611715565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff909116177001000000000000000000000000000000008360028111156117c6576117c66157da565b0217905560028111156117db576117db6157da565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e73ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561186c57600080fd5b505af1158015611880573d6000803e3d6000fd5b5050505090565b600560205281600052604060002081815481106118a357600080fd5b90600052602060002001600091509150505481565b905090565b6118ca8383836001611abe565b505050565b6000818152600760209081526040808320600590925282208054825461190090610100900463ffffffff1682615bfe565b95945050505050565b60606118b860546020612a8f565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604081208054908290559081900361197c576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309169063f3fef3a390604401600060405180830381600087803b158015611a0c57600080fd5b505af1158015611a20573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a7e576040519150601f19603f3d011682016040523d82523d6000602084013e611a83565b606091505b50509050806118ca576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8161480611b3757503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b6316145b611b6d576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b7984848484612ae1565b50505050565b6118ca8383836000611abe565b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c81614611bfb576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c036135ba565b565b600080600054700100000000000000000000000000000000900460ff166002811115611c3357611c336157da565b14611c6a576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110611c7f57611c7f615b50565b600091825260208220600590910201805490925063ffffffff90811614611cee57815460028054909163ffffffff16908110611cbd57611cbd615b50565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090611d2690700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b611d3a9067ffffffffffffffff1642615bfe565b611d59611d19846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16611d6d9190615bae565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b01667ffffffffffffffff168167ffffffffffffffff1611611dba5780611900565b7f00000000000000000000000000000000000000000000000000000000000004b095945050505050565b600080611e83836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000008811115611ee2576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000611efd8383615c44565b9050670de0b6b3a76400006000611f34827f0000000000000000000000000000000000000000000000000000000000000008615c58565b90506000611f52611f4d670de0b6b3a764000086615c58565b613b13565b90506000611f608484613d6e565b90506000611f6e8383613dbd565b90506000611f7b82613deb565b90506000611f9a82611f95670de0b6b3a76400008f615c58565b613fd3565b90506000611fa88b83613dbd565b9050611fb4818d615c58565b9f9e505050505050505050505050505050565b60028181548110611fd757600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c81614806120d757503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b6316145b61210d576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61211b868686868686614004565b505050505050565b60008054700100000000000000000000000000000000900460ff16600281111561214f5761214f6157da565b14612186576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061219586614633565b935093509350935060006121ab85858585614a3c565b905060007f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561221a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223e9190615c95565b9050600189036123365773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8461229a367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af115801561230c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123309190615cb2565b506115d7565b600289036123625773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848961229a565b6003890361238e5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848761229a565b600489036125155760006123d46fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000004614af6565b6009546123e19190615bae565b6123ec906001615bae565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061245557367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135612457565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156124ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250e9190615cb2565b50506115d7565b600589036125ae576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000038560c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016122ed565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000001367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060612639611909565b9050909192565b6000818310156126505781612652565b825b90505b92915050565b6000816000015182602001518360400151846060015160405160200161269a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003612706576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b6060600080600061273485614ba4565b91945092509050600181600181111561274f5761274f6157da565b14612786576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516127928385615bae565b146127c9576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816127e05790505093506000835b86518110156128ce576000806128536040518060400160405280858c600001516128379190615bfe565b8152602001858c6020015161284c9190615bae565b9052614ba4565b50915091506040518060400160405280838361286f9190615bae565b8152602001848b602001516128849190615bae565b81525088858151811061289957612899615b50565b60209081029190910101526128af600185615bae565b93506128bb8183615bae565b6128c59084615bae565b9250505061280d565b50845250919392505050565b606060008060006128ea85614ba4565b919450925090506000816001811115612905576129056157da565b1461293c576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129468284615bae565b85511461297f576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61190085602001518484615042565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff909316928392906129dd908490615bae565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f000000000000000000000000d6eaf4c146261653ee059077b78ed088add543091690637eee288d90604401600060405180830381600087803b158015612a7257600080fd5b505af1158015612a86573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b60008054700100000000000000000000000000000000900460ff166002811115612b0d57612b0d6157da565b14612b44576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110612b5957612b59615b50565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514612c40576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000612d00826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580612d3b5750612d387f00000000000000000000000000000000000000000000000000000000000000046002615bae565b81145b8015612d45575084155b15612d7c576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015612da2575086155b15612dd9576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000008811115612e33576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e5e7f00000000000000000000000000000000000000000000000000000000000000046001615bae565b8103612e7057612e70868885886150d7565b34612e7a83611de4565b14612eb1576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612ebc88611c05565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b0811690821603612f24576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612f5160017f0000000000000000000000000000000000000000000000000000000000000008615bfe565b830361308f577f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fe69190615c95565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015613030573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130549190615cb2565b613088907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16615ccb565b9050613122565b6130ba60017f0000000000000000000000000000000000000000000000000000000000000004615bfe565b83036130f5576130887f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166002615cf7565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b613156817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615d27565b67ffffffffffffffff166131718367ffffffffffffffff1690565b67ffffffffffffffff1611156131b8576131b5817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615d27565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615613236576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c815260200190815260200160002060016002805490506134cc9190615bfe565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309169263d0e30db09234926004808301939282900301818588803b15801561356457600080fd5b505af1158015613578573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b60005471010000000000000000000000000000000000900460ff161561360c576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000001166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e1690637258a807906024016040805180830381865afa1580156136c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136e49190615d50565b909250905081613720576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a1461375357639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135116137ed576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f000000000000000000000000d6eaf4c146261653ee059077b78ed088add543099092169363d0e30db093926004828101939282900301818588803b158015613ac257600080fd5b505af1158015613ad6573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b1760008213613b7257631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a764000002158202613dab57637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b600081600019048311820215613ddb5763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d78213613e1957919050565b680755bf798b4a1bf1e58212613e375763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000612652670de0b6b3a764000083613feb86613b13565b613ff59190615d74565b613fff9190615e30565b613deb565b60008054700100000000000000000000000000000000900460ff166002811115614030576140306157da565b14614067576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002878154811061407c5761407c615b50565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506140db7f00000000000000000000000000000000000000000000000000000000000000086001615bae565b614177826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16146141b1576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008089156142a8576142047f00000000000000000000000000000000000000000000000000000000000000047f0000000000000000000000000000000000000000000000000000000000000008615bfe565b6001901b614223846fffffffffffffffffffffffffffffffff16615288565b6fffffffffffffffffffffffffffffffff1661423f9190615e98565b1561427c5761427361426460016fffffffffffffffffffffffffffffffff8716615eac565b865463ffffffff166000615327565b6003015461429e565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506142d2565b600385015491506142cf6142646fffffffffffffffffffffffffffffffff86166001615ed5565b90505b600882901b60088a8a6040516142e9929190615b40565b6040518091039020901b1461432a576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006143358c61540b565b90506000614344836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff169063e14ced32906143be908f908f908f908f908a90600401615f49565b6020604051808303816000875af11580156143dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144019190615cb2565b6004850154911491506000906002906144ac906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b614548896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6145529190615f83565b61455c9190615fa6565b60ff16159050811515810361459d576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156145f4576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b600080600080600085905060006002828154811061465357614653615b50565b600091825260209091206004600590920201908101549091507f00000000000000000000000000000000000000000000000000000000000000049061472a906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611614764576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f00000000000000000000000000000000000000000000000000000000000000049061482b906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1692508211156148a057825463ffffffff1661486a7f00000000000000000000000000000000000000000000000000000000000000046001615bae565b8303614874578391505b6002818154811061488757614887615b50565b9060005260206000209060050201935080945050614768565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149096148f4856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff1614905080156149d8576000614941836fffffffffffffffffffffffffffffffff16615288565b6fffffffffffffffffffffffffffffffff1611156149ac57600061498361497b60016fffffffffffffffffffffffffffffffff8616615eac565b896001615327565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a506149b29050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614a2e565b60006149fa61497b6fffffffffffffffffffffffffffffffff85166001615ed5565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614aa95760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611900565b8282604051602001614ad79291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614b83847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614be7576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614c0c57600060016000945094509450505061503b565b60b78111614d22576000614c21608083615bfe565b905080876000015111614c60576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614cd857507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614d0f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061503b915050565b60bf8111614e80576000614d3760b783615bfe565b905080876000015111614d76576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614dd8576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614e20576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614e2a8184615bae565b895111614e63576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614e6e836001615bae565b975095506000945061503b9350505050565b60f78111614ee5576000614e9560c083615bfe565b905080876000015111614ed4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061503b915050565b6000614ef260f783615bfe565b905080876000015111614f31576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614f93576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614fdb576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614fe58184615bae565b89511161501e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615029836001615bae565b975095506001945061503b9350505050565b9193909250565b60608167ffffffffffffffff81111561505d5761505d615a84565b6040519080825280601f01601f191660200182016040528015615087576020820181803683370190505b50905081156150d057600061509c8486615bae565b90506020820160005b848110156150bd5782810151828201526020016150a5565b848111156150cc576000858301525b5050505b9392505050565b60006150f66fffffffffffffffffffffffffffffffff84166001615ed5565b9050600061510682866001615327565b9050600086901a83806151f2575061513f60027f0000000000000000000000000000000000000000000000000000000000000004615e98565b60048301546002906151e3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6151ed9190615fa6565b60ff16145b1561524a5760ff81166001148061520c575060ff81166002145b615245576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016137e4565b612a86565b60ff811615612a86576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016137e4565b600080615315837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826153705761536b6fffffffffffffffffffffffffffffffff86167f000000000000000000000000000000000000000000000000000000000000000461543a565b61538b565b61538b856fffffffffffffffffffffffffffffffff166155c6565b9050600284815481106153a0576153a0615b50565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff82811691161461540357815460028054909163ffffffff169081106153ee576153ee615b50565b906000526020600020906005020191506153b1565b509392505050565b600080600080600061541c86614633565b935093509350935061543084848484614a3c565b9695505050505050565b6000816154d9846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116154ef5763b34b5c226000526004601cfd5b6154f8836155c6565b905081615597826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611612655576126526155ad836001615bae565b6fffffffffffffffffffffffffffffffff83169061566b565b6000811960018301168161565a827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b6000806156f8847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f84011261572657600080fd5b50813567ffffffffffffffff81111561573e57600080fd5b60208301915083602082850101111561575657600080fd5b9250929050565b600080600083850360a081121561577357600080fd5b608081121561578157600080fd5b50839250608084013567ffffffffffffffff81111561579f57600080fd5b6157ab86828701615714565b9497909650939450505050565b600080604083850312156157cb57600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310615844577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060006060848603121561585f57600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561589c57602081850181015186830182015201615880565b818111156158ae576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006126526020830184615876565b60006020828403121561590657600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461592f57600080fd5b50565b60006020828403121561594457600080fd5b81356150d08161590d565b8035801515811461595f57600080fd5b919050565b6000806000806080858703121561597a57600080fd5b8435935060208501359250604085013591506159986060860161594f565b905092959194509250565b6000602082840312156159b557600080fd5b81356fffffffffffffffffffffffffffffffff811681146150d057600080fd5b600080600080600080608087890312156159ee57600080fd5b863595506159fe6020880161594f565b9450604087013567ffffffffffffffff80821115615a1b57600080fd5b615a278a838b01615714565b90965094506060890135915080821115615a4057600080fd5b50615a4d89828a01615714565b979a9699509497509295939492505050565b63ffffffff841681528260208201526060604082015260006119006060830184615876565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060808284031215615ac557600080fd5b6040516080810181811067ffffffffffffffff82111715615b0f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115615bc157615bc1615b7f565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615bf757615bf7615b7f565b5060010190565b600082821015615c1057615c10615b7f565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615c5357615c53615c15565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615c9057615c90615b7f565b500290565b600060208284031215615ca757600080fd5b81516150d08161590d565b600060208284031215615cc457600080fd5b5051919050565b600067ffffffffffffffff808316818516808303821115615cee57615cee615b7f565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615d1e57615d1e615b7f565b02949350505050565b600067ffffffffffffffff83811690831681811015615d4857615d48615b7f565b039392505050565b60008060408385031215615d6357600080fd5b505080516020909101519092909150565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615db557615db5615b7f565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615df057615df0615b7f565b60008712925087820587128484161615615e0c57615e0c615b7f565b87850587128184161615615e2257615e22615b7f565b505050929093029392505050565b600082615e3f57615e3f615c15565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615e9357615e93615b7f565b500590565b600082615ea757615ea7615c15565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615d4857615d48615b7f565b60006fffffffffffffffffffffffffffffffff808316818516808303821115615cee57615cee615b7f565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615f5d606083018789615f00565b8281036020840152615f70818688615f00565b9150508260408301529695505050505050565b600060ff821660ff841680821015615f9d57615f9d615b7f565b90039392505050565b600060ff831680615fb957615fb9615c15565b8060ff8416069150509291505056fea164736f6c634300080f000a"; } From 327e6e68c70c9d5ba83e4a754d6da18da6445fa9 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Thu, 12 Sep 2024 08:46:06 +1000 Subject: [PATCH 100/264] proofs Add a proofs-tools docker image (#11825) * op-challenger: Add a "big" op-challenger docker image including asterisc and kona * proofs-tools: Rename op-challenger-deps to proofs-tools and use tagged asterisc and kona sources. * proofs-tools: Use more recent version of challenger for testing * proofs-tools: Remove TODO * proofs-tools: Only build for amd64 - kona doesn't support arm64. * proofs-tools: Add README * proofs-tools: Use challenger v1.1.0 --- .circleci/config.yml | 24 ++++++++++++++++++++++-- docker-bake.hcl | 13 +++++++++++++ ops/docker/proofs-tools/Dockerfile | 26 ++++++++++++++++++++++++++ ops/docker/proofs-tools/README.md | 8 ++++++++ 4 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 ops/docker/proofs-tools/Dockerfile create mode 100644 ops/docker/proofs-tools/README.md diff --git a/.circleci/config.yml b/.circleci/config.yml index d34fed3947fe..ec5d8887b6dc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1744,6 +1744,10 @@ workflows: docker_name: op-challenger docker_tags: <>,<> save_image_tag: <> # for devnet later + - docker-build: + name: proofs-tools-docker-build + docker_name: proofs-tools + docker_tags: <>,<> - docker-build: name: op-dispute-mon-docker-build docker_name: op-dispute-mon @@ -1980,10 +1984,10 @@ workflows: requires: - op-supervisor-docker-release - docker-build: - name: ci-builder-docker-release + name: op-challenger-big-docker-release filters: tags: - only: /^ci-builder\/v.*/ + only: /^op-challenger\/v.*/ branches: ignore: /.*/ docker_name: ci-builder @@ -1995,6 +1999,22 @@ workflows: - oplabs-gcr requires: - hold + - docker-build: + name: proofs-tools-docker-release + filters: + tags: + only: /^proofs-tools\/v.*/ + branches: + ignore: /.*/ + docker_name: proofs-tools + docker_tags: <>,latest + publish: true + release: true + resource_class: xlarge + context: + - oplabs-gcr + requires: + - hold - docker-build: name: ci-builder-rust-docker-release filters: diff --git a/docker-bake.hcl b/docker-bake.hcl index 47509616416a..cd5d83b7d1b7 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -199,6 +199,19 @@ target "cannon" { tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/cannon:${tag}"] } +target "proofs-tools" { + dockerfile = "./ops/docker/proofs-tools/Dockerfile" + context = "." + args = { + CHALLENGER_VERSION="v1.1.0" + KONA_VERSION="kona-client-v0.1.0-alpha.3" + ASTERISC_VERSION="v1.0.2" + } + target="proofs-tools" + platforms = split(",", PLATFORMS) + tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/proofs-tools:${tag}"] +} + target "ci-builder" { dockerfile = "./ops/docker/ci-builder/Dockerfile" context = "." diff --git a/ops/docker/proofs-tools/Dockerfile b/ops/docker/proofs-tools/Dockerfile new file mode 100644 index 000000000000..884c3a5927b8 --- /dev/null +++ b/ops/docker/proofs-tools/Dockerfile @@ -0,0 +1,26 @@ +ARG GIT_COMMIT +ARG GIT_DATE + +ARG CHALLENGER_VERSION +ARG KONA_VERSION +ARG ASTERISC_VERSION + +FROM --platform=$BUILDPLATFORM us-docker.pkg.dev/oplabs-tools-artifacts/images/op-challenger:$CHALLENGER_VERSION AS challenger +FROM --platform=$BUILDPLATFORM ghcr.io/anton-rs/kona/kona-fpp-asterisc:$KONA_VERSION AS kona +FROM --platform=$BUILDPLATFORM ghcr.io/ethereum-optimism/asterisc/asterisc:$ASTERISC_VERSION AS asterisc + +FROM --platform=$BUILDPLATFORM ubuntu:22.04 AS proofs-tools +RUN apt-get update && apt-get install -y --no-install-recommends musl +COPY --from=challenger /usr/local/bin/op-challenger /usr/local/bin/ +COPY --from=challenger /usr/local/bin/cannon /usr/local/bin/ +ENV OP_CHALLENGER_CANNON_BIN /usr/local/bin/cannon +COPY --from=challenger /usr/local/bin/op-program /usr/local/bin/ +ENV OP_CHALLENGER_CANNON_SERVER=/usr/local/bin/op-program + +COPY --from=kona /kona-host /usr/local/bin/ +ENV OP_CHALLENGER_ASTERISC_KONA_SERVER=/usr/local/bin/kona-host + +COPY --from=asterisc /usr/local/bin/asterisc /usr/local/bin/ +ENV OP_CHALLENGER_ASTERISC_BIN=/usr/local/bin/asterisc + +CMD /usr/local/bin/op-challenger diff --git a/ops/docker/proofs-tools/README.md b/ops/docker/proofs-tools/README.md new file mode 100644 index 000000000000..faa47f8d4ad3 --- /dev/null +++ b/ops/docker/proofs-tools/README.md @@ -0,0 +1,8 @@ +## Proofs Tools + +The proofs-tools docker image provides a collection of useful fault proofs related tools in a single docker image. +In particular it provides op-challenger with cannon, asterisc, op-program and kona-host ready to participate in +cannon, asterisc or asterisc-kona game types. + +The version of each tool used in the image is specified +in [docker-bake.hcl](https://github.com/ethereum-optimism/optimism/blob/develop/docker-bake.hcl). From 06a62ea816f3de6695215ee97c3e8f87f4b2acf3 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Wed, 11 Sep 2024 18:47:24 -0400 Subject: [PATCH 101/264] maint: add remaining L1 contract interfaces (#11848) Adds interfaces for all remaining L1 contracts. L2 contracts are next! --- packages/contracts-bedrock/.gas-snapshot | 16 ++-- .../contracts-bedrock/scripts/L2Genesis.s.sol | 34 +++++---- .../scripts/checks/check-interfaces.sh | 4 +- .../scripts/deploy/ChainAssertions.sol | 18 ++--- .../scripts/deploy/Deploy.s.sol | 50 +++++-------- .../periphery/deploy/DeployPeriphery.s.sol | 1 - packages/contracts-bedrock/semver-lock.json | 6 +- .../src/L1/interfaces/IL1ERC721Bridge.sol | 40 ++++++++++ .../src/L1/interfaces/IL1StandardBridge.sol | 75 +++++++++++++++++++ .../src/L1/interfaces/IProtocolVersions.sol | 28 +++++++ .../L1/interfaces/ISystemConfigInterop.sol | 24 ++++++ .../src/L2/L2ERC721Bridge.sol | 13 +++- .../src/L2/L2StandardBridge.sol | 11 ++- .../src/L2/L2StandardBridgeInterop.sol | 7 +- .../universal/interfaces/IERC721Bridge.sol | 47 ++++++++++++ .../IOptimismMintableERC20Factory.sol | 36 +++++++++ .../universal/interfaces/IStandardBridge.sol | 64 ++++++++++++++++ .../test/L1/L1ERC721Bridge.t.sol | 16 ++-- .../test/L1/L1StandardBridge.t.sol | 22 +++--- .../test/L1/ProtocolVersions.t.sol | 18 ++--- .../test/L1/SystemConfigInterop.t.sol | 16 ++-- .../test/L2/L2ERC721Bridge.t.sol | 13 ++-- packages/contracts-bedrock/test/Specs.t.sol | 12 +-- .../contracts-bedrock/test/setup/Setup.sol | 49 ++++++------ .../OptimismMintableERC20Factory.t.sol | 11 +-- .../test/vendor/Initializable.t.sol | 8 +- 26 files changed, 483 insertions(+), 156 deletions(-) create mode 100644 packages/contracts-bedrock/src/L1/interfaces/IL1ERC721Bridge.sol create mode 100644 packages/contracts-bedrock/src/L1/interfaces/IL1StandardBridge.sol create mode 100644 packages/contracts-bedrock/src/L1/interfaces/IProtocolVersions.sol create mode 100644 packages/contracts-bedrock/src/L1/interfaces/ISystemConfigInterop.sol create mode 100644 packages/contracts-bedrock/src/universal/interfaces/IERC721Bridge.sol create mode 100644 packages/contracts-bedrock/src/universal/interfaces/IOptimismMintableERC20Factory.sol create mode 100644 packages/contracts-bedrock/src/universal/interfaces/IStandardBridge.sol diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index af4acca99719..f42bdc83dcb7 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -6,12 +6,12 @@ GasBenchMark_L1Block_SetValuesEcotone:test_setL1BlockValuesEcotone_benchmark() ( GasBenchMark_L1Block_SetValuesEcotone_Warm:test_setL1BlockValuesEcotone_benchmark() (gas: 7597) GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 369242) GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2967382) -GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 564365) -GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4076580) -GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 467007) -GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3512689) -GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 72624) +GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 564356) +GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4076571) +GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 467019) +GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3512701) +GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 72618) GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 92973) -GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68320) -GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68962) -GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 155618) \ No newline at end of file +GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68312) +GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68943) +GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 155610) \ No newline at end of file diff --git a/packages/contracts-bedrock/scripts/L2Genesis.s.sol b/packages/contracts-bedrock/scripts/L2Genesis.s.sol index e6040f4eec2f..1ab494b052f8 100644 --- a/packages/contracts-bedrock/scripts/L2Genesis.s.sol +++ b/packages/contracts-bedrock/scripts/L2Genesis.s.sol @@ -1,31 +1,39 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Testing import { Script } from "forge-std/Script.sol"; import { console2 as console } from "forge-std/console2.sol"; -import { Deployer } from "scripts/deploy/Deployer.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; +// Scripts +import { Deployer } from "scripts/deploy/Deployer.sol"; import { Config, OutputMode, OutputModeUtils, Fork, ForkUtils, LATEST_FORK } from "scripts/libraries/Config.sol"; import { Artifacts } from "scripts/Artifacts.s.sol"; import { DeployConfig } from "scripts/deploy/DeployConfig.s.sol"; -import { Predeploys } from "src/libraries/Predeploys.sol"; -import { Preinstalls } from "src/libraries/Preinstalls.sol"; +import { Process } from "scripts/libraries/Process.sol"; + +// Contracts import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol"; import { L1Block } from "src/L2/L1Block.sol"; import { GasPriceOracle } from "src/L2/GasPriceOracle.sol"; import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol"; -import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; -import { OptimismMintableERC721Factory } from "src/universal/OptimismMintableERC721Factory.sol"; import { BaseFeeVault } from "src/L2/BaseFeeVault.sol"; import { L1FeeVault } from "src/L2/L1FeeVault.sol"; -import { GovernanceToken } from "src/governance/GovernanceToken.sol"; +import { OptimismMintableERC721Factory } from "src/universal/OptimismMintableERC721Factory.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; +import { StandardBridge } from "src/universal/StandardBridge.sol"; import { FeeVault } from "src/universal/FeeVault.sol"; -import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; -import { Process } from "scripts/libraries/Process.sol"; +import { GovernanceToken } from "src/governance/GovernanceToken.sol"; + +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { Preinstalls } from "src/libraries/Preinstalls.sol"; + +// Interfaces +import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol"; interface IInitializable { function initialize(address _addr) external; @@ -296,10 +304,10 @@ contract L2Genesis is Deployer { impl = _setImplementationCode(Predeploys.L2_STANDARD_BRIDGE); } - L2StandardBridge(payable(impl)).initialize({ _otherBridge: L1StandardBridge(payable(address(0))) }); + L2StandardBridge(payable(impl)).initialize({ _otherBridge: StandardBridge(payable(address(0))) }); L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).initialize({ - _otherBridge: L1StandardBridge(_l1StandardBridgeProxy) + _otherBridge: StandardBridge(_l1StandardBridgeProxy) }); } @@ -333,9 +341,9 @@ contract L2Genesis is Deployer { function setOptimismMintableERC20Factory() public { address impl = _setImplementationCode(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); - OptimismMintableERC20Factory(impl).initialize({ _bridge: address(0) }); + IOptimismMintableERC20Factory(impl).initialize({ _bridge: address(0) }); - OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY).initialize({ + IOptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY).initialize({ _bridge: Predeploys.L2_STANDARD_BRIDGE }); } diff --git a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh index 89a62e3c4ce0..df8c10238ca4 100755 --- a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh +++ b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh @@ -35,7 +35,6 @@ EXCLUDE_CONTRACTS=( "Vm" "VmSafe" "IMulticall3" - "IBeacon" "IERC721TokenReceiver" "IProxyCreationCallback" @@ -68,6 +67,9 @@ EXCLUDE_CONTRACTS=( "ISuperchainConfig" "IOptimismPortal" "IL1BlockIsthmus" + + # Need to make complex tweaks to the check script for this one + "ISystemConfigInterop" ) # Find all JSON files in the forge-artifacts folder diff --git a/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol b/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol index 0ebb848f23a3..efe20eb7343e 100644 --- a/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol +++ b/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol @@ -8,15 +8,12 @@ import { console2 as console } from "forge-std/console2.sol"; // Scripts import { DeployConfig } from "scripts/deploy/DeployConfig.s.sol"; import { Deployer } from "scripts/deploy/Deployer.sol"; +import { ISystemConfigV0 } from "scripts/interfaces/ISystemConfigV0.sol"; // Contracts import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; -import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; -import { ProtocolVersion, ProtocolVersions } from "src/L1/ProtocolVersions.sol"; -import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; -import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; // Libraries import { Constants } from "src/libraries/Constants.sol"; @@ -31,7 +28,10 @@ import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { IL1CrossDomainMessenger } from "src/L1/interfaces/IL1CrossDomainMessenger.sol"; import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; -import { ISystemConfigV0 } from "scripts/interfaces/ISystemConfigV0.sol"; +import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; +import { IL1StandardBridge } from "src/L1/interfaces/IL1StandardBridge.sol"; +import { ProtocolVersion, IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol"; +import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol"; library ChainAssertions { Vm internal constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); @@ -160,7 +160,7 @@ library ChainAssertions { /// @notice Asserts that the L1StandardBridge is setup correctly function checkL1StandardBridge(Types.ContractSet memory _contracts, bool _isProxy) internal view { console.log("Running chain assertions on the L1StandardBridge"); - L1StandardBridge bridge = L1StandardBridge(payable(_contracts.L1StandardBridge)); + IL1StandardBridge bridge = IL1StandardBridge(payable(_contracts.L1StandardBridge)); // Check that the contract is initialized assertSlotValueIsOne({ _contractAddress: address(bridge), _slot: 0, _offset: 0 }); @@ -291,7 +291,7 @@ library ChainAssertions { /// @notice Asserts that the OptimismMintableERC20Factory is setup correctly function checkOptimismMintableERC20Factory(Types.ContractSet memory _contracts, bool _isProxy) internal view { console.log("Running chain assertions on the OptimismMintableERC20Factory"); - OptimismMintableERC20Factory factory = OptimismMintableERC20Factory(_contracts.OptimismMintableERC20Factory); + IOptimismMintableERC20Factory factory = IOptimismMintableERC20Factory(_contracts.OptimismMintableERC20Factory); // Check that the contract is initialized assertSlotValueIsOne({ _contractAddress: address(factory), _slot: 0, _offset: 0 }); @@ -308,7 +308,7 @@ library ChainAssertions { /// @notice Asserts that the L1ERC721Bridge is setup correctly function checkL1ERC721Bridge(Types.ContractSet memory _contracts, bool _isProxy) internal view { console.log("Running chain assertions on the L1ERC721Bridge"); - L1ERC721Bridge bridge = L1ERC721Bridge(_contracts.L1ERC721Bridge); + IL1ERC721Bridge bridge = IL1ERC721Bridge(_contracts.L1ERC721Bridge); // Check that the contract is initialized assertSlotValueIsOne({ _contractAddress: address(bridge), _slot: 0, _offset: 0 }); @@ -405,7 +405,7 @@ library ChainAssertions { view { console.log("Running chain assertions on the ProtocolVersions"); - ProtocolVersions versions = ProtocolVersions(_contracts.ProtocolVersions); + IProtocolVersions versions = IProtocolVersions(_contracts.ProtocolVersions); // Check that the contract is initialized assertSlotValueIsOne({ _contractAddress: address(versions), _slot: 0, _offset: 0 }); diff --git a/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol b/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol index 3399ef09da15..b0cdcc4dcfe3 100644 --- a/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol @@ -28,12 +28,9 @@ import { ChainAssertions } from "scripts/deploy/ChainAssertions.sol"; import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { AddressManager } from "src/legacy/AddressManager.sol"; import { Proxy } from "src/universal/Proxy.sol"; -import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol"; import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol"; import { ResolvedDelegateProxy } from "src/legacy/ResolvedDelegateProxy.sol"; -import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; -import { SystemConfigInterop } from "src/L1/SystemConfigInterop.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; @@ -41,8 +38,6 @@ import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { MIPS } from "src/cannon/MIPS.sol"; -import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; -import { ProtocolVersions, ProtocolVersion } from "src/L1/ProtocolVersions.sol"; import { StorageSetter } from "src/universal/StorageSetter.sol"; // Libraries @@ -61,8 +56,12 @@ import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { IDataAvailabilityChallenge } from "src/L1/interfaces/IDataAvailabilityChallenge.sol"; +import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; +import { IL1StandardBridge } from "src/L1/interfaces/IL1StandardBridge.sol"; +import { IProtocolVersions, ProtocolVersion } from "src/L1/interfaces/IProtocolVersions.sol"; import { IBigStepper } from "src/dispute/interfaces/IBigStepper.sol"; import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol"; +import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol"; /// @title Deploy /// @notice Script used to deploy a bedrock system. The entire system is deployed within the `run` function. @@ -751,11 +750,8 @@ contract Deploy is Deployer { /// @notice Deploy the OptimismMintableERC20Factory function deployOptimismMintableERC20Factory() public broadcast returns (address addr_) { - console.log("Deploying OptimismMintableERC20Factory implementation"); - OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory{ salt: _implSalt() }(); - - save("OptimismMintableERC20Factory", address(factory)); - console.log("OptimismMintableERC20Factory deployed at %s", address(factory)); + IOptimismMintableERC20Factory factory = + IOptimismMintableERC20Factory(_deploy("OptimismMintableERC20Factory", hex"")); // Override the `OptimismMintableERC20Factory` contract to the deployed implementation. This is necessary // to check the `OptimismMintableERC20Factory` implementation alongside dependent contracts, which @@ -806,10 +802,7 @@ contract Deploy is Deployer { /// @notice Deploy the ProtocolVersions function deployProtocolVersions() public broadcast returns (address addr_) { - console.log("Deploying ProtocolVersions implementation"); - ProtocolVersions versions = new ProtocolVersions{ salt: _implSalt() }(); - save("ProtocolVersions", address(versions)); - console.log("ProtocolVersions deployed at %s", address(versions)); + IProtocolVersions versions = IProtocolVersions(_deploy("ProtocolVersions", hex"")); // Override the `ProtocolVersions` contract to the deployed implementation. This is necessary // to check the `ProtocolVersions` implementation alongside dependent contracts, which @@ -874,12 +867,7 @@ contract Deploy is Deployer { /// @notice Deploy the L1StandardBridge function deployL1StandardBridge() public broadcast returns (address addr_) { - console.log("Deploying L1StandardBridge implementation"); - - L1StandardBridge bridge = new L1StandardBridge{ salt: _implSalt() }(); - - save("L1StandardBridge", address(bridge)); - console.log("L1StandardBridge deployed at %s", address(bridge)); + IL1StandardBridge bridge = IL1StandardBridge(payable(_deploy("L1StandardBridge", hex""))); // Override the `L1StandardBridge` contract to the deployed implementation. This is necessary // to check the `L1StandardBridge` implementation alongside dependent contracts, which @@ -893,11 +881,7 @@ contract Deploy is Deployer { /// @notice Deploy the L1ERC721Bridge function deployL1ERC721Bridge() public broadcast returns (address addr_) { - console.log("Deploying L1ERC721Bridge implementation"); - L1ERC721Bridge bridge = new L1ERC721Bridge{ salt: _implSalt() }(); - - save("L1ERC721Bridge", address(bridge)); - console.log("L1ERC721Bridge deployed at %s", address(bridge)); + IL1ERC721Bridge bridge = IL1ERC721Bridge(_deploy("L1ERC721Bridge", hex"")); // Override the `L1ERC721Bridge` contract to the deployed implementation. This is necessary // to check the `L1ERC721Bridge` implementation alongside dependent contracts, which @@ -1137,7 +1121,7 @@ contract Deploy is Deployer { _proxy: payable(l1StandardBridgeProxy), _implementation: l1StandardBridge, _innerCallData: abi.encodeCall( - L1StandardBridge.initialize, + IL1StandardBridge.initialize, ( ICrossDomainMessenger(l1CrossDomainMessengerProxy), ISuperchainConfig(superchainConfigProxy), @@ -1146,7 +1130,7 @@ contract Deploy is Deployer { ) }); - string memory version = L1StandardBridge(payable(l1StandardBridgeProxy)).version(); + string memory version = IL1StandardBridge(payable(l1StandardBridgeProxy)).version(); console.log("L1StandardBridge version: %s", version); ChainAssertions.checkL1StandardBridge({ _contracts: _proxies(), _isProxy: true }); @@ -1164,12 +1148,12 @@ contract Deploy is Deployer { _proxy: payable(l1ERC721BridgeProxy), _implementation: l1ERC721Bridge, _innerCallData: abi.encodeCall( - L1ERC721Bridge.initialize, + IL1ERC721Bridge.initialize, (ICrossDomainMessenger(payable(l1CrossDomainMessengerProxy)), ISuperchainConfig(superchainConfigProxy)) ) }); - L1ERC721Bridge bridge = L1ERC721Bridge(l1ERC721BridgeProxy); + IL1ERC721Bridge bridge = IL1ERC721Bridge(l1ERC721BridgeProxy); string memory version = bridge.version(); console.log("L1ERC721Bridge version: %s", version); @@ -1186,10 +1170,10 @@ contract Deploy is Deployer { _upgradeAndCallViaSafe({ _proxy: payable(optimismMintableERC20FactoryProxy), _implementation: optimismMintableERC20Factory, - _innerCallData: abi.encodeCall(OptimismMintableERC20Factory.initialize, (l1StandardBridgeProxy)) + _innerCallData: abi.encodeCall(IOptimismMintableERC20Factory.initialize, (l1StandardBridgeProxy)) }); - OptimismMintableERC20Factory factory = OptimismMintableERC20Factory(optimismMintableERC20FactoryProxy); + IOptimismMintableERC20Factory factory = IOptimismMintableERC20Factory(optimismMintableERC20FactoryProxy); string memory version = factory.version(); console.log("OptimismMintableERC20Factory version: %s", version); @@ -1358,7 +1342,7 @@ contract Deploy is Deployer { _proxy: payable(protocolVersionsProxy), _implementation: protocolVersions, _innerCallData: abi.encodeCall( - ProtocolVersions.initialize, + IProtocolVersions.initialize, ( finalSystemOwner, ProtocolVersion.wrap(requiredProtocolVersion), @@ -1367,7 +1351,7 @@ contract Deploy is Deployer { ) }); - ProtocolVersions versions = ProtocolVersions(protocolVersionsProxy); + IProtocolVersions versions = IProtocolVersions(protocolVersionsProxy); string memory version = versions.version(); console.log("ProtocolVersions version: %s", version); diff --git a/packages/contracts-bedrock/scripts/periphery/deploy/DeployPeriphery.s.sol b/packages/contracts-bedrock/scripts/periphery/deploy/DeployPeriphery.s.sol index 856104eb2734..8f4b86b95d62 100644 --- a/packages/contracts-bedrock/scripts/periphery/deploy/DeployPeriphery.s.sol +++ b/packages/contracts-bedrock/scripts/periphery/deploy/DeployPeriphery.s.sol @@ -10,7 +10,6 @@ import { PeripheryDeployConfig } from "scripts/periphery/deploy/PeripheryDeployC import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { Proxy } from "src/universal/Proxy.sol"; -import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { Faucet } from "src/periphery/faucet/Faucet.sol"; import { Drippie } from "src/periphery/drippie/Drippie.sol"; import { CheckGelatoLow } from "src/periphery/drippie/dripchecks/CheckGelatoLow.sol"; diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 82d5b474eea2..809345a37f8f 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -97,15 +97,15 @@ }, "src/L2/L2ERC721Bridge.sol": { "initCodeHash": "0x827077e1a0ce6c8f9ee1196c409ea77d831efd440992b3969b05259083cdf0bd", - "sourceCodeHash": "0xdc5e08a5a9ee8d61e843ac630126629ccfedb49a3b0dd167863dd48d75629a95" + "sourceCodeHash": "0x51a44e1fcef9483cc58ba0c9895cb3eec675785145428ece9aa7acd1a1a5b57c" }, "src/L2/L2StandardBridge.sol": { "initCodeHash": "0x01692b613e3d4e649d877a0fd8f0798a26401ba8ccc4cda0e61f1f9079729320", - "sourceCodeHash": "0x5c8e8ba3ecdae116f98caf67cca5fb3594bf7085e186f0a14bad1d6f143b6bc8" + "sourceCodeHash": "0xca7d45b137fb66a941cbfe97a914c8bda78462c86ddd90085b6e2275cfb6da92" }, "src/L2/L2StandardBridgeInterop.sol": { "initCodeHash": "0x5c9ef6b0817f715d1b8b097f3fc19e33bc54453426ca12bb48e4cea143076339", - "sourceCodeHash": "0x5a2d206477d6ba84e93bf0e1545a5cf2c93a6bb80529c07927f53915bde298bf" + "sourceCodeHash": "0x6c814f4536d9fb8f384ed2195957f868abd15252e36d6dd243f3d60349a61994" }, "src/L2/L2ToL1MessagePasser.sol": { "initCodeHash": "0x13fe3729beb9ed966c97bef09acb9fe5043fe651d453145073d05f2567fa988d", diff --git a/packages/contracts-bedrock/src/L1/interfaces/IL1ERC721Bridge.sol b/packages/contracts-bedrock/src/L1/interfaces/IL1ERC721Bridge.sol new file mode 100644 index 000000000000..fd64f40fe5ac --- /dev/null +++ b/packages/contracts-bedrock/src/L1/interfaces/IL1ERC721Bridge.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { IERC721Bridge } from "src/universal/interfaces/IERC721Bridge.sol"; +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; + +interface IL1ERC721Bridge is IERC721Bridge { + function bridgeERC721( + address _localToken, + address _remoteToken, + uint256 _tokenId, + uint32 _minGasLimit, + bytes memory _extraData + ) + external; + function bridgeERC721To( + address _localToken, + address _remoteToken, + address _to, + uint256 _tokenId, + uint32 _minGasLimit, + bytes memory _extraData + ) + external; + function deposits(address, address, uint256) external view returns (bool); + function finalizeBridgeERC721( + address _localToken, + address _remoteToken, + address _from, + address _to, + uint256 _tokenId, + bytes memory _extraData + ) + external; + function initialize(ICrossDomainMessenger _messenger, ISuperchainConfig _superchainConfig) external; + function paused() external view returns (bool); + function superchainConfig() external view returns (ISuperchainConfig); + function version() external view returns (string memory); +} diff --git a/packages/contracts-bedrock/src/L1/interfaces/IL1StandardBridge.sol b/packages/contracts-bedrock/src/L1/interfaces/IL1StandardBridge.sol new file mode 100644 index 000000000000..119c8c1f1d8e --- /dev/null +++ b/packages/contracts-bedrock/src/L1/interfaces/IL1StandardBridge.sol @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { IStandardBridge } from "src/universal/interfaces/IStandardBridge.sol"; +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; + +interface IL1StandardBridge is IStandardBridge { + event ERC20DepositInitiated( + address indexed l1Token, + address indexed l2Token, + address indexed from, + address to, + uint256 amount, + bytes extraData + ); + event ERC20WithdrawalFinalized( + address indexed l1Token, + address indexed l2Token, + address indexed from, + address to, + uint256 amount, + bytes extraData + ); + event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes extraData); + event ETHWithdrawalFinalized(address indexed from, address indexed to, uint256 amount, bytes extraData); + + function depositERC20( + address _l1Token, + address _l2Token, + uint256 _amount, + uint32 _minGasLimit, + bytes memory _extraData + ) + external; + function depositERC20To( + address _l1Token, + address _l2Token, + address _to, + uint256 _amount, + uint32 _minGasLimit, + bytes memory _extraData + ) + external; + function depositETH(uint32 _minGasLimit, bytes memory _extraData) external payable; + function depositETHTo(address _to, uint32 _minGasLimit, bytes memory _extraData) external payable; + function finalizeERC20Withdrawal( + address _l1Token, + address _l2Token, + address _from, + address _to, + uint256 _amount, + bytes memory _extraData + ) + external; + function finalizeETHWithdrawal( + address _from, + address _to, + uint256 _amount, + bytes memory _extraData + ) + external + payable; + function initialize( + ICrossDomainMessenger _messenger, + ISuperchainConfig _superchainConfig, + ISystemConfig _systemConfig + ) + external; + function l2TokenBridge() external view returns (address); + function superchainConfig() external view returns (ISuperchainConfig); + function systemConfig() external view returns (ISystemConfig); + function version() external view returns (string memory); +} diff --git a/packages/contracts-bedrock/src/L1/interfaces/IProtocolVersions.sol b/packages/contracts-bedrock/src/L1/interfaces/IProtocolVersions.sol new file mode 100644 index 000000000000..0fbd8d1f2de6 --- /dev/null +++ b/packages/contracts-bedrock/src/L1/interfaces/IProtocolVersions.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +type ProtocolVersion is uint256; + +interface IProtocolVersions { + enum UpdateType { + REQUIRED_PROTOCOL_VERSION, + RECOMMENDED_PROTOCOL_VERSION + } + + event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data); + event Initialized(uint8 version); + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + function RECOMMENDED_SLOT() external view returns (bytes32); + function REQUIRED_SLOT() external view returns (bytes32); + function VERSION() external view returns (uint256); + function initialize(address _owner, ProtocolVersion _required, ProtocolVersion _recommended) external; + function owner() external view returns (address); + function recommended() external view returns (ProtocolVersion out_); + function renounceOwnership() external; + function required() external view returns (ProtocolVersion out_); + function setRecommended(ProtocolVersion _recommended) external; + function setRequired(ProtocolVersion _required) external; + function transferOwnership(address newOwner) external; + function version() external view returns (string memory); +} diff --git a/packages/contracts-bedrock/src/L1/interfaces/ISystemConfigInterop.sol b/packages/contracts-bedrock/src/L1/interfaces/ISystemConfigInterop.sol new file mode 100644 index 000000000000..3f6e6f723650 --- /dev/null +++ b/packages/contracts-bedrock/src/L1/interfaces/ISystemConfigInterop.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; + +interface ISystemConfigInterop is ISystemConfig { + function addDependency(uint256 _chainId) external; + function dependencyManager() external view returns (address); + function initialize( + address _owner, + uint32 _basefeeScalar, + uint32 _blobbasefeeScalar, + bytes32 _batcherHash, + uint64 _gasLimit, + address _unsafeBlockSigner, + IResourceMetering.ResourceConfig memory _config, + address _batchInbox, + Addresses memory _addresses, + address _dependencyManager + ) + external; + function removeDependency(uint256 _chainId) external; +} diff --git a/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol b/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol index 3ff30e8b7272..4f3231c677f0 100644 --- a/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol +++ b/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol @@ -1,14 +1,19 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Contracts import { ERC721Bridge } from "src/universal/ERC721Bridge.sol"; + +// Libraries import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; -import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; +import { Constants } from "src/libraries/Constants.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Interfaces +import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; import { IOptimismMintableERC721 } from "src/universal/interfaces/IOptimismMintableERC721.sol"; import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol"; -import { Constants } from "src/libraries/Constants.sol"; -import { Predeploys } from "src/libraries/Predeploys.sol"; /// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000014 @@ -114,7 +119,7 @@ contract L2ERC721Bridge is ERC721Bridge, ISemver { IOptimismMintableERC721(_localToken).burn(_from, _tokenId); bytes memory message = abi.encodeWithSelector( - L1ERC721Bridge.finalizeBridgeERC721.selector, remoteToken, _localToken, _from, _to, _tokenId, _extraData + IL1ERC721Bridge.finalizeBridgeERC721.selector, remoteToken, _localToken, _from, _to, _tokenId, _extraData ); // Send message to L1 bridge diff --git a/packages/contracts-bedrock/src/L2/L2StandardBridge.sol b/packages/contracts-bedrock/src/L2/L2StandardBridge.sol index 063ee398f770..5cf6ebecfb5d 100644 --- a/packages/contracts-bedrock/src/L2/L2StandardBridge.sol +++ b/packages/contracts-bedrock/src/L2/L2StandardBridge.sol @@ -1,13 +1,18 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Predeploys } from "src/libraries/Predeploys.sol"; +// Contracts import { StandardBridge } from "src/universal/StandardBridge.sol"; -import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; -import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; import { L1Block } from "src/L2/L1Block.sol"; +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Interfaces +import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; + /// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000010 /// @title L2StandardBridge diff --git a/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol b/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol index f7a82fc2af3f..be6c9e4c878d 100644 --- a/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol +++ b/packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol @@ -1,8 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Predeploys } from "src/libraries/Predeploys.sol"; +// Contracts import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; + +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Interfaces import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import { IOptimismERC20Factory } from "src/L2/interfaces/IOptimismERC20Factory.sol"; diff --git a/packages/contracts-bedrock/src/universal/interfaces/IERC721Bridge.sol b/packages/contracts-bedrock/src/universal/interfaces/IERC721Bridge.sol new file mode 100644 index 000000000000..ccb2d5f0a483 --- /dev/null +++ b/packages/contracts-bedrock/src/universal/interfaces/IERC721Bridge.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; + +interface IERC721Bridge { + event ERC721BridgeFinalized( + address indexed localToken, + address indexed remoteToken, + address indexed from, + address to, + uint256 tokenId, + bytes extraData + ); + event ERC721BridgeInitiated( + address indexed localToken, + address indexed remoteToken, + address indexed from, + address to, + uint256 tokenId, + bytes extraData + ); + event Initialized(uint8 version); + + function MESSENGER() external view returns (ICrossDomainMessenger); + function OTHER_BRIDGE() external view returns (IERC721Bridge); + function bridgeERC721( + address _localToken, + address _remoteToken, + uint256 _tokenId, + uint32 _minGasLimit, + bytes memory _extraData + ) + external; + function bridgeERC721To( + address _localToken, + address _remoteToken, + address _to, + uint256 _tokenId, + uint32 _minGasLimit, + bytes memory _extraData + ) + external; + function messenger() external view returns (ICrossDomainMessenger); + function otherBridge() external view returns (IERC721Bridge); + function paused() external view returns (bool); +} diff --git a/packages/contracts-bedrock/src/universal/interfaces/IOptimismMintableERC20Factory.sol b/packages/contracts-bedrock/src/universal/interfaces/IOptimismMintableERC20Factory.sol new file mode 100644 index 000000000000..ecb52c94cada --- /dev/null +++ b/packages/contracts-bedrock/src/universal/interfaces/IOptimismMintableERC20Factory.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IOptimismMintableERC20Factory { + event Initialized(uint8 version); + event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer); + event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken); + + function BRIDGE() external view returns (address); + function bridge() external view returns (address); + function createOptimismMintableERC20( + address _remoteToken, + string memory _name, + string memory _symbol + ) + external + returns (address); + function createOptimismMintableERC20WithDecimals( + address _remoteToken, + string memory _name, + string memory _symbol, + uint8 _decimals + ) + external + returns (address); + function createStandardL2Token( + address _remoteToken, + string memory _name, + string memory _symbol + ) + external + returns (address); + function deployments(address) external view returns (address); + function initialize(address _bridge) external; + function version() external view returns (string memory); +} diff --git a/packages/contracts-bedrock/src/universal/interfaces/IStandardBridge.sol b/packages/contracts-bedrock/src/universal/interfaces/IStandardBridge.sol new file mode 100644 index 000000000000..b92aae27503b --- /dev/null +++ b/packages/contracts-bedrock/src/universal/interfaces/IStandardBridge.sol @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; + +interface IStandardBridge { + event ERC20BridgeFinalized( + address indexed localToken, + address indexed remoteToken, + address indexed from, + address to, + uint256 amount, + bytes extraData + ); + event ERC20BridgeInitiated( + address indexed localToken, + address indexed remoteToken, + address indexed from, + address to, + uint256 amount, + bytes extraData + ); + event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes extraData); + event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes extraData); + event Initialized(uint8 version); + + receive() external payable; + + function MESSENGER() external view returns (ICrossDomainMessenger); + function OTHER_BRIDGE() external view returns (IStandardBridge); + function bridgeERC20( + address _localToken, + address _remoteToken, + uint256 _amount, + uint32 _minGasLimit, + bytes memory _extraData + ) + external; + function bridgeERC20To( + address _localToken, + address _remoteToken, + address _to, + uint256 _amount, + uint32 _minGasLimit, + bytes memory _extraData + ) + external; + function bridgeETH(uint32 _minGasLimit, bytes memory _extraData) external payable; + function bridgeETHTo(address _to, uint32 _minGasLimit, bytes memory _extraData) external payable; + function deposits(address, address) external view returns (uint256); + function finalizeBridgeERC20( + address _localToken, + address _remoteToken, + address _from, + address _to, + uint256 _amount, + bytes memory _extraData + ) + external; + function finalizeBridgeETH(address _from, address _to, uint256 _amount, bytes memory _extraData) external payable; + function messenger() external view returns (ICrossDomainMessenger); + function otherBridge() external view returns (IStandardBridge); + function paused() external view returns (bool); +} diff --git a/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol b/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol index ce3d949e333e..f69b73e1fd5e 100644 --- a/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol +++ b/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol @@ -1,18 +1,20 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Testing utilities +// Testing import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; -import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -// Target contract dependencies +// Contracts +import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; + +// Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Interfaces import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; - -// Target contract -import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; +import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; /// @dev Test ERC721 contract. contract TestERC721 is ERC721 { @@ -67,7 +69,7 @@ contract L1ERC721Bridge_Test is Bridge_Initializer { /// @notice Marked virtual to be overridden in /// test/kontrol/deployment/DeploymentSummary.t.sol function test_constructor_succeeds() public virtual { - L1ERC721Bridge impl = L1ERC721Bridge(deploy.mustGetAddress("L1ERC721Bridge")); + IL1ERC721Bridge impl = IL1ERC721Bridge(deploy.mustGetAddress("L1ERC721Bridge")); assertEq(address(impl.MESSENGER()), address(0)); assertEq(address(impl.messenger()), address(0)); assertEq(address(impl.OTHER_BRIDGE()), Predeploys.L2_ERC721_BRIDGE); diff --git a/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol b/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol index bcba92adf6ba..afc97afd0b43 100644 --- a/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol +++ b/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol @@ -1,31 +1,31 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Testing utilities +// Testing import { stdStorage, StdStorage } from "forge-std/Test.sol"; -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; +// Contracts +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { StandardBridge } from "src/universal/StandardBridge.sol"; +import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; + // Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; import { Constants } from "src/libraries/Constants.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; -// Target contract dependencies -import { StandardBridge } from "src/universal/StandardBridge.sol"; -import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; -import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; +// Interfaces import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; -import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; - -// Target contract import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; +import { IL1StandardBridge } from "src/L1/interfaces/IL1StandardBridge.sol"; contract L1StandardBridge_Getter_Test is Bridge_Initializer { /// @dev Test that the accessors return the correct initialized values. function test_getters_succeeds() external view { assert(l1StandardBridge.l2TokenBridge() == address(l2StandardBridge)); - assert(l1StandardBridge.OTHER_BRIDGE() == l2StandardBridge); + assert(address(l1StandardBridge.OTHER_BRIDGE()) == address(l2StandardBridge)); assert(address(l1StandardBridge.messenger()) == address(l1CrossDomainMessenger)); assert(address(l1StandardBridge.MESSENGER()) == address(l1CrossDomainMessenger)); assert(l1StandardBridge.superchainConfig() == superchainConfig); @@ -38,7 +38,7 @@ contract L1StandardBridge_Initialize_Test is Bridge_Initializer { /// @notice Marked virtual to be overridden in /// test/kontrol/deployment/DeploymentSummary.t.sol function test_constructor_succeeds() external virtual { - L1StandardBridge impl = L1StandardBridge(deploy.mustGetAddress("L1StandardBridge")); + IL1StandardBridge impl = IL1StandardBridge(deploy.mustGetAddress("L1StandardBridge")); assertEq(address(impl.superchainConfig()), address(0)); assertEq(address(impl.MESSENGER()), address(0)); assertEq(address(impl.messenger()), address(0)); diff --git a/packages/contracts-bedrock/test/L1/ProtocolVersions.t.sol b/packages/contracts-bedrock/test/L1/ProtocolVersions.t.sol index 235654d38af6..957d2b914f38 100644 --- a/packages/contracts-bedrock/test/L1/ProtocolVersions.t.sol +++ b/packages/contracts-bedrock/test/L1/ProtocolVersions.t.sol @@ -12,10 +12,10 @@ import { Constants } from "src/libraries/Constants.sol"; import { Proxy } from "src/universal/Proxy.sol"; // Target contract -import { ProtocolVersions, ProtocolVersion } from "src/L1/ProtocolVersions.sol"; +import { IProtocolVersions, ProtocolVersion } from "src/L1/interfaces/IProtocolVersions.sol"; contract ProtocolVersions_Init is CommonTest { - event ConfigUpdate(uint256 indexed version, ProtocolVersions.UpdateType indexed updateType, bytes data); + event ConfigUpdate(uint256 indexed version, IProtocolVersions.UpdateType indexed updateType, bytes data); ProtocolVersion required; ProtocolVersion recommended; @@ -30,7 +30,7 @@ contract ProtocolVersions_Init is CommonTest { contract ProtocolVersions_Initialize_Test is ProtocolVersions_Init { /// @dev Tests that initialization sets the correct values. function test_initialize_values_succeeds() external view { - ProtocolVersions protocolVersionsImpl = ProtocolVersions(deploy.mustGetAddress("ProtocolVersions")); + IProtocolVersions protocolVersionsImpl = IProtocolVersions(deploy.mustGetAddress("ProtocolVersions")); address owner = deploy.cfg().finalSystemOwner(); assertEq(ProtocolVersion.unwrap(protocolVersions.required()), ProtocolVersion.unwrap(required)); @@ -44,7 +44,7 @@ contract ProtocolVersions_Initialize_Test is ProtocolVersions_Init { /// @dev Ensures that the events are emitted during initialization. function test_initialize_events_succeeds() external { - ProtocolVersions protocolVersionsImpl = ProtocolVersions(deploy.mustGetAddress("ProtocolVersions")); + IProtocolVersions protocolVersionsImpl = IProtocolVersions(deploy.mustGetAddress("ProtocolVersions")); assertEq(protocolVersionsImpl.owner(), address(0xdEad)); // Wipe out the initialized slot so the proxy can be initialized again @@ -52,15 +52,15 @@ contract ProtocolVersions_Initialize_Test is ProtocolVersions_Init { // The order depends here vm.expectEmit(true, true, true, true, address(protocolVersions)); - emit ConfigUpdate(0, ProtocolVersions.UpdateType.REQUIRED_PROTOCOL_VERSION, abi.encode(required)); + emit ConfigUpdate(0, IProtocolVersions.UpdateType.REQUIRED_PROTOCOL_VERSION, abi.encode(required)); vm.expectEmit(true, true, true, true, address(protocolVersions)); - emit ConfigUpdate(0, ProtocolVersions.UpdateType.RECOMMENDED_PROTOCOL_VERSION, abi.encode(recommended)); + emit ConfigUpdate(0, IProtocolVersions.UpdateType.RECOMMENDED_PROTOCOL_VERSION, abi.encode(recommended)); vm.prank(EIP1967Helper.getAdmin(address(protocolVersions))); Proxy(payable(address(protocolVersions))).upgradeToAndCall( address(protocolVersionsImpl), abi.encodeCall( - ProtocolVersions.initialize, + IProtocolVersions.initialize, ( alice, // _owner required, // _required @@ -89,7 +89,7 @@ contract ProtocolVersions_Setters_Test is ProtocolVersions_Init { /// @dev Tests that `setRequired` updates the required protocol version successfully. function testFuzz_setRequired_succeeds(uint256 _version) external { vm.expectEmit(true, true, true, true); - emit ConfigUpdate(0, ProtocolVersions.UpdateType.REQUIRED_PROTOCOL_VERSION, abi.encode(_version)); + emit ConfigUpdate(0, IProtocolVersions.UpdateType.REQUIRED_PROTOCOL_VERSION, abi.encode(_version)); vm.prank(protocolVersions.owner()); protocolVersions.setRequired(ProtocolVersion.wrap(_version)); @@ -99,7 +99,7 @@ contract ProtocolVersions_Setters_Test is ProtocolVersions_Init { /// @dev Tests that `setRecommended` updates the recommended protocol version successfully. function testFuzz_setRecommended_succeeds(uint256 _version) external { vm.expectEmit(true, true, true, true); - emit ConfigUpdate(0, ProtocolVersions.UpdateType.RECOMMENDED_PROTOCOL_VERSION, abi.encode(_version)); + emit ConfigUpdate(0, IProtocolVersions.UpdateType.RECOMMENDED_PROTOCOL_VERSION, abi.encode(_version)); vm.prank(protocolVersions.owner()); protocolVersions.setRecommended(ProtocolVersion.wrap(_version)); diff --git a/packages/contracts-bedrock/test/L1/SystemConfigInterop.t.sol b/packages/contracts-bedrock/test/L1/SystemConfigInterop.t.sol index 191949e29f6f..6cd3c8b3145c 100644 --- a/packages/contracts-bedrock/test/L1/SystemConfigInterop.t.sol +++ b/packages/contracts-bedrock/test/L1/SystemConfigInterop.t.sol @@ -1,20 +1,22 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Testing utilities +// Testing import { CommonTest } from "test/setup/CommonTest.sol"; +// Contracts +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { ConfigType } from "src/L2/L1BlockIsthmus.sol"; + // Libraries import { Constants } from "src/libraries/Constants.sol"; import { StaticConfig } from "src/libraries/StaticConfig.sol"; import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; -// Target contract dependencies +// Interfaces import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; -import { SystemConfigInterop } from "src/L1/SystemConfigInterop.sol"; +import { ISystemConfigInterop } from "src/L1/interfaces/ISystemConfigInterop.sol"; import { IOptimismPortalInterop } from "src/L1/interfaces/IOptimismPortalInterop.sol"; -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import { ConfigType } from "src/L2/L1BlockIsthmus.sol"; contract SystemConfigInterop_Test is CommonTest { /// @notice Marked virtual to be overridden in @@ -132,7 +134,7 @@ contract SystemConfigInterop_Test is CommonTest { } /// @dev Returns the SystemConfigInterop instance. - function _systemConfigInterop() internal view returns (SystemConfigInterop) { - return SystemConfigInterop(address(systemConfig)); + function _systemConfigInterop() internal view returns (ISystemConfigInterop) { + return ISystemConfigInterop(address(systemConfig)); } } diff --git a/packages/contracts-bedrock/test/L2/L2ERC721Bridge.t.sol b/packages/contracts-bedrock/test/L2/L2ERC721Bridge.t.sol index b7a3e96bc44b..dc7490bd8136 100644 --- a/packages/contracts-bedrock/test/L2/L2ERC721Bridge.t.sol +++ b/packages/contracts-bedrock/test/L2/L2ERC721Bridge.t.sol @@ -1,18 +1,17 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Testing import { console } from "forge-std/console.sol"; - -// Testing utilities import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; -// Target contract dependencies +// Contracts import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; +import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; import { OptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol"; -// Target contract -import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; +// Interfaces +import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; contract TestERC721 is ERC721 { constructor() ERC721("Test", "TST") { } @@ -175,7 +174,7 @@ contract L2ERC721Bridge_Test is Bridge_Initializer { ( address(l1ERC721Bridge), abi.encodeCall( - L1ERC721Bridge.finalizeBridgeERC721, + IL1ERC721Bridge.finalizeBridgeERC721, (address(remoteToken), address(localToken), alice, bob, tokenId, hex"5678") ), 1234 diff --git a/packages/contracts-bedrock/test/Specs.t.sol b/packages/contracts-bedrock/test/Specs.t.sol index d8b918acf8bc..419ffa69ece3 100644 --- a/packages/contracts-bedrock/test/Specs.t.sol +++ b/packages/contracts-bedrock/test/Specs.t.sol @@ -10,7 +10,6 @@ import { Executables } from "scripts/libraries/Executables.sol"; import { ForgeArtifacts, Abi, AbiEntry } from "scripts/libraries/ForgeArtifacts.sol"; // Contracts -import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; import { OPStackManager } from "src/L1/OPStackManager.sol"; // Interfaces @@ -19,6 +18,7 @@ import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; import { IOptimismPortalInterop } from "src/L1/interfaces/IOptimismPortalInterop.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { IDataAvailabilityChallenge } from "src/L1/interfaces/IDataAvailabilityChallenge.sol"; +import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol"; /// @title Specification_Test /// @dev Specifies common security properties of entrypoints to L1 contracts, including authorization and @@ -394,19 +394,19 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "ProtocolVersions", _sel: _getSel("RECOMMENDED_SLOT()") }); _addSpec({ _name: "ProtocolVersions", _sel: _getSel("REQUIRED_SLOT()") }); _addSpec({ _name: "ProtocolVersions", _sel: _getSel("VERSION()") }); - _addSpec({ _name: "ProtocolVersions", _sel: ProtocolVersions.initialize.selector }); + _addSpec({ _name: "ProtocolVersions", _sel: IProtocolVersions.initialize.selector }); _addSpec({ _name: "ProtocolVersions", _sel: _getSel("owner()") }); - _addSpec({ _name: "ProtocolVersions", _sel: ProtocolVersions.recommended.selector }); + _addSpec({ _name: "ProtocolVersions", _sel: IProtocolVersions.recommended.selector }); _addSpec({ _name: "ProtocolVersions", _sel: _getSel("renounceOwnership()"), _auth: Role.SYSTEMCONFIGOWNER }); - _addSpec({ _name: "ProtocolVersions", _sel: ProtocolVersions.required.selector }); + _addSpec({ _name: "ProtocolVersions", _sel: IProtocolVersions.required.selector }); _addSpec({ _name: "ProtocolVersions", - _sel: ProtocolVersions.setRequired.selector, + _sel: IProtocolVersions.setRequired.selector, _auth: Role.SYSTEMCONFIGOWNER }); _addSpec({ _name: "ProtocolVersions", - _sel: ProtocolVersions.setRecommended.selector, + _sel: IProtocolVersions.setRecommended.selector, _auth: Role.SYSTEMCONFIGOWNER }); _addSpec({ _name: "ProtocolVersions", _sel: _getSel("transferOwnership(address)") }); diff --git a/packages/contracts-bedrock/test/setup/Setup.sol b/packages/contracts-bedrock/test/setup/Setup.sol index 0d8db00009cb..5bfd5328144c 100644 --- a/packages/contracts-bedrock/test/setup/Setup.sol +++ b/packages/contracts-bedrock/test/setup/Setup.sol @@ -25,19 +25,13 @@ import { GasPriceOracle } from "src/L2/GasPriceOracle.sol"; import { L1Block } from "src/L2/L1Block.sol"; import { LegacyMessagePasser } from "src/legacy/LegacyMessagePasser.sol"; import { GovernanceToken } from "src/governance/GovernanceToken.sol"; -import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; -import { StandardBridge } from "src/universal/StandardBridge.sol"; import { FeeVault } from "src/universal/FeeVault.sol"; -import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; -import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; -import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; -import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; -import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; -import { AddressManager } from "src/legacy/AddressManager.sol"; import { WETH } from "src/L2/WETH.sol"; import { SuperchainWETH } from "src/L2/SuperchainWETH.sol"; import { ETHLiquidity } from "src/L2/ETHLiquidity.sol"; -import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; +import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; +import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; +import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; // Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; @@ -52,6 +46,11 @@ import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { IDataAvailabilityChallenge } from "src/L1/interfaces/IDataAvailabilityChallenge.sol"; +import { IL1StandardBridge } from "src/L1/interfaces/IL1StandardBridge.sol"; +import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol"; +import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; +import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol"; +import { IAddressManager } from "src/legacy/interfaces/IAddressManager.sol"; /// @title Setup /// @dev This contact is responsible for setting up the contracts in state. It currently @@ -74,28 +73,30 @@ contract Setup { // @notice Allows users of Setup to override what L2 genesis is being created. Fork l2Fork = LATEST_FORK; - IOptimismPortal optimismPortal; - IOptimismPortal2 optimismPortal2; + // L1 contracts DisputeGameFactory disputeGameFactory; + AnchorStateRegistry anchorStateRegistry; DelayedWETH delayedWeth; + IOptimismPortal optimismPortal; + IOptimismPortal2 optimismPortal2; IL2OutputOracle l2OutputOracle; ISystemConfig systemConfig; - L1StandardBridge l1StandardBridge; + IL1StandardBridge l1StandardBridge; IL1CrossDomainMessenger l1CrossDomainMessenger; - AddressManager addressManager; - L1ERC721Bridge l1ERC721Bridge; - OptimismMintableERC20Factory l1OptimismMintableERC20Factory; - ProtocolVersions protocolVersions; + IAddressManager addressManager; + IL1ERC721Bridge l1ERC721Bridge; + IOptimismMintableERC20Factory l1OptimismMintableERC20Factory; + IProtocolVersions protocolVersions; ISuperchainConfig superchainConfig; IDataAvailabilityChallenge dataAvailabilityChallenge; - AnchorStateRegistry anchorStateRegistry; + // L2 contracts L2CrossDomainMessenger l2CrossDomainMessenger = L2CrossDomainMessenger(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER)); L2StandardBridgeInterop l2StandardBridge = L2StandardBridgeInterop(payable(Predeploys.L2_STANDARD_BRIDGE)); L2ToL1MessagePasser l2ToL1MessagePasser = L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)); - OptimismMintableERC20Factory l2OptimismMintableERC20Factory = - OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); + IOptimismMintableERC20Factory l2OptimismMintableERC20Factory = + IOptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); L2ERC721Bridge l2ERC721Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE); BaseFeeVault baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT)); SequencerFeeVault sequencerFeeVault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET)); @@ -146,13 +147,13 @@ contract Setup { delayedWeth = DelayedWETH(deploy.mustGetAddress("DelayedWETHProxy")); l2OutputOracle = IL2OutputOracle(deploy.mustGetAddress("L2OutputOracleProxy")); systemConfig = ISystemConfig(deploy.mustGetAddress("SystemConfigProxy")); - l1StandardBridge = L1StandardBridge(deploy.mustGetAddress("L1StandardBridgeProxy")); + l1StandardBridge = IL1StandardBridge(deploy.mustGetAddress("L1StandardBridgeProxy")); l1CrossDomainMessenger = IL1CrossDomainMessenger(deploy.mustGetAddress("L1CrossDomainMessengerProxy")); - addressManager = AddressManager(deploy.mustGetAddress("AddressManager")); - l1ERC721Bridge = L1ERC721Bridge(deploy.mustGetAddress("L1ERC721BridgeProxy")); + addressManager = IAddressManager(deploy.mustGetAddress("AddressManager")); + l1ERC721Bridge = IL1ERC721Bridge(deploy.mustGetAddress("L1ERC721BridgeProxy")); l1OptimismMintableERC20Factory = - OptimismMintableERC20Factory(deploy.mustGetAddress("OptimismMintableERC20FactoryProxy")); - protocolVersions = ProtocolVersions(deploy.mustGetAddress("ProtocolVersionsProxy")); + IOptimismMintableERC20Factory(deploy.mustGetAddress("OptimismMintableERC20FactoryProxy")); + protocolVersions = IProtocolVersions(deploy.mustGetAddress("ProtocolVersionsProxy")); superchainConfig = ISuperchainConfig(deploy.mustGetAddress("SuperchainConfigProxy")); anchorStateRegistry = AnchorStateRegistry(deploy.mustGetAddress("AnchorStateRegistryProxy")); diff --git a/packages/contracts-bedrock/test/universal/OptimismMintableERC20Factory.t.sol b/packages/contracts-bedrock/test/universal/OptimismMintableERC20Factory.t.sol index 85dc4e0d3e9b..07aa2c61958d 100644 --- a/packages/contracts-bedrock/test/universal/OptimismMintableERC20Factory.t.sol +++ b/packages/contracts-bedrock/test/universal/OptimismMintableERC20Factory.t.sol @@ -1,17 +1,18 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Testing utilities +// Testing import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { NextImpl } from "test/mocks/NextImpl.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; -// Target contract dependencies +// Contracts import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; +import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; import { Proxy } from "src/universal/Proxy.sol"; -// Target contract -import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; +// Interfaces +import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol"; contract OptimismMintableTokenFactory_Test is Bridge_Initializer { event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken); @@ -19,7 +20,7 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer { /// @notice Tests that the constructor is initialized correctly. function test_constructor_succeeds() external { - OptimismMintableERC20Factory impl = new OptimismMintableERC20Factory(); + IOptimismMintableERC20Factory impl = IOptimismMintableERC20Factory(address(new OptimismMintableERC20Factory())); assertEq(address(impl.BRIDGE()), address(0)); assertEq(address(impl.bridge()), address(0)); } diff --git a/packages/contracts-bedrock/test/vendor/Initializable.t.sol b/packages/contracts-bedrock/test/vendor/Initializable.t.sol index 52566f95ec1b..df9231a27627 100644 --- a/packages/contracts-bedrock/test/vendor/Initializable.t.sol +++ b/packages/contracts-bedrock/test/vendor/Initializable.t.sol @@ -7,9 +7,9 @@ import { Executables } from "scripts/libraries/Executables.sol"; import { Constants } from "src/libraries/Constants.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; +import { StandardBridge } from "src/universal/StandardBridge.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; -import { SystemConfigInterop } from "src/L1/SystemConfigInterop.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; @@ -17,7 +17,7 @@ import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol import { GameTypes } from "src/dispute/lib/Types.sol"; import { ForgeArtifacts, StorageSlot } from "scripts/libraries/ForgeArtifacts.sol"; import { Process } from "scripts/libraries/Process.sol"; -import "src/L1/ProtocolVersions.sol"; +import { ProtocolVersion } from "src/L1/interfaces/IProtocolVersions.sol"; import "src/dispute/lib/Types.sol"; import "scripts/deploy/Deployer.sol"; @@ -296,7 +296,7 @@ contract Initializer_Test is Bridge_Initializer { InitializeableContract({ name: "L2StandardBridge", target: address(l2StandardBridge), - initCalldata: abi.encodeCall(l2StandardBridge.initialize, (l1StandardBridge)) + initCalldata: abi.encodeCall(l2StandardBridge.initialize, (StandardBridge(payable(l1StandardBridge)))) }) ); // L2StandardBridgeInterop @@ -304,7 +304,7 @@ contract Initializer_Test is Bridge_Initializer { InitializeableContract({ name: "L2StandardBridgeInterop", target: address(l2StandardBridge), - initCalldata: abi.encodeCall(l2StandardBridge.initialize, (l1StandardBridge)) + initCalldata: abi.encodeCall(l2StandardBridge.initialize, (StandardBridge(payable(l1StandardBridge)))) }) ); // L1ERC721BridgeImpl From 89c9fef18638bcc239c7b5dea7cfa4484aa6ed52 Mon Sep 17 00:00:00 2001 From: clabby Date: Wed, 11 Sep 2024 19:59:40 -0400 Subject: [PATCH 102/264] feat: Run `op-program` in `op-e2e` action tests (#11846) * feat: Run `op-program` in `op-e2e` action tests * configurable forks * golint / op-program test * use correct endpoint --- op-e2e/actions/l1_miner.go | 2 +- op-e2e/actions/op_program_test.go | 270 +++++++++++++++++++++++ op-e2e/e2eutils/blobs.go | 49 +++- op-e2e/system_fpp_test.go | 1 + op-program/host/config/config.go | 13 +- op-program/host/config/config_test.go | 3 +- op-program/host/host.go | 56 +++-- op-program/host/prefetcher/prefetcher.go | 27 +-- op-program/host/prefetcher/retry.go | 19 +- op-program/host/prefetcher/retry_test.go | 3 +- op-program/host/sources/sources.go | 27 +++ 11 files changed, 404 insertions(+), 66 deletions(-) create mode 100644 op-e2e/actions/op_program_test.go create mode 100644 op-program/host/sources/sources.go diff --git a/op-e2e/actions/l1_miner.go b/op-e2e/actions/l1_miner.go index 9026d74db178..d14eab394131 100644 --- a/op-e2e/actions/l1_miner.go +++ b/op-e2e/actions/l1_miner.go @@ -240,7 +240,7 @@ func (s *L1Miner) ActL1EndBlock(t Testing) { for _, sidecar := range s.l1BuildingBlobSidecars { for i, h := range sidecar.BlobHashes() { blob := (*eth.Blob)(&sidecar.Blobs[i]) - s.blobStore.StoreBlob(block.Hash(), h, blob) + s.blobStore.StoreBlob(block.Time(), h, blob) } } _, err = s.l1Chain.InsertChain(types.Blocks{block}) diff --git a/op-e2e/actions/op_program_test.go b/op-e2e/actions/op_program_test.go new file mode 100644 index 000000000000..81bb337b381f --- /dev/null +++ b/op-e2e/actions/op_program_test.go @@ -0,0 +1,270 @@ +package actions + +import ( + "context" + "math/rand" + "os" + "testing" + + batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-program/host" + "github.com/ethereum-optimism/optimism/op-program/host/config" + "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +var dumpFixtures = false + +func init() { + if os.Getenv("OP_E2E_DUMP_FIXTURES") == "1" { + dumpFixtures = true + } +} + +// L2FaultProofEnv is a test harness for a fault provable L2 chain. +type L2FaultProofEnv struct { + log log.Logger + batcher *L2Batcher + sequencer *L2Sequencer + engine *L2Engine + engCl *sources.EngineClient + sd *e2eutils.SetupData + dp *e2eutils.DeployParams + miner *L1Miner + alice *CrossLayerUser +} + +func NewL2FaultProofEnv(t Testing, tp *e2eutils.TestParams, dp *e2eutils.DeployParams, batcherCfg *BatcherCfg) *L2FaultProofEnv { + log := testlog.Logger(t, log.LvlDebug) + sd := e2eutils.Setup(t, dp, defaultAlloc) + + miner, engine, sequencer := setupSequencerTest(t, sd, log) + miner.ActL1SetFeeRecipient(common.Address{0xCA, 0xFE, 0xBA, 0xBE}) + sequencer.ActL2PipelineFull(t) + engCl := engine.EngineClient(t, sd.RollupCfg) + + // Set the batcher key to the secret key of the batcher + batcherCfg.BatcherKey = dp.Secrets.Batcher + batcher := NewL2Batcher(log, sd.RollupCfg, batcherCfg, sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engCl) + + addresses := e2eutils.CollectAddresses(sd, dp) + cl := engine.EthClient() + l2UserEnv := &BasicUserEnv[*L2Bindings]{ + EthCl: cl, + Signer: types.LatestSigner(sd.L2Cfg.Config), + AddressCorpora: addresses, + Bindings: NewL2Bindings(t, cl, engine.GethClient()), + } + alice := NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b))) + alice.L2.SetUserEnv(l2UserEnv) + + return &L2FaultProofEnv{ + log: log, + batcher: batcher, + sequencer: sequencer, + engine: engine, + engCl: engCl, + sd: sd, + dp: dp, + miner: miner, + alice: alice, + } +} + +type TestParam func(p *e2eutils.TestParams) + +func NewTestParams(params ...TestParam) *e2eutils.TestParams { + dfault := defaultRollupTestParams + for _, apply := range params { + apply(dfault) + } + return dfault +} + +type DeployParam func(p *e2eutils.DeployParams) + +func NewDeployParams(t Testing, params ...DeployParam) *e2eutils.DeployParams { + dfault := e2eutils.MakeDeployParams(t, NewTestParams()) + for _, apply := range params { + apply(dfault) + } + return dfault +} + +type BatcherCfgParam func(c *BatcherCfg) + +func NewBatcherCfg(params ...BatcherCfgParam) *BatcherCfg { + dfault := &BatcherCfg{ + MinL1TxSize: 0, + MaxL1TxSize: 128_000, + DataAvailabilityType: batcherFlags.BlobsType, + } + for _, apply := range params { + apply(dfault) + } + return dfault +} + +type OpProgramCfgParam func(p *config.Config) + +func NewOpProgramCfg( + t Testing, + env *L2FaultProofEnv, + l1Head common.Hash, + l2Head common.Hash, + l2OutputRoot common.Hash, + l2Claim common.Hash, + l2ClaimBlockNum uint64, + params ...OpProgramCfgParam, +) *config.Config { + dfault := config.NewConfig(env.sd.RollupCfg, env.sd.L2Cfg.Config, l1Head, l2Head, l2OutputRoot, l2Claim, l2ClaimBlockNum) + + // Set up in-process L1 sources + dfault.L1ProcessSource = env.miner.L1Client(t, env.sd.RollupCfg) + dfault.L1BeaconProcessSource = env.miner.blobStore + + // Set up in-process L2 source + l2ClCfg := sources.L2ClientDefaultConfig(env.sd.RollupCfg, true) + l2RPC := env.engine.RPCClient() + l2Client, err := host.NewL2Client(l2RPC, env.log, nil, &host.L2ClientConfig{L2ClientConfig: l2ClCfg, L2Head: l2Head}) + require.NoError(t, err, "failed to create L2 client") + l2DebugCl := &host.L2Source{L2Client: l2Client, DebugClient: sources.NewDebugClient(l2RPC.CallContext)} + dfault.L2ProcessSource = l2DebugCl + + for _, apply := range params { + apply(dfault) + } + return dfault +} + +func Test_ProgramAction_SimpleEmptyChain_HonestClaim_Granite(gt *testing.T) { + t := NewDefaultTesting(gt) + tp := NewTestParams() + dp := NewDeployParams(t, func(dp *e2eutils.DeployParams) { + genesisBlock := hexutil.Uint64(0) + + // Enable Cancun on L1 & Granite on L2 at genesis + dp.DeployConfig.L1CancunTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisRegolithTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisFjordTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisGraniteTimeOffset = &genesisBlock + }) + bCfg := NewBatcherCfg() + env := NewL2FaultProofEnv(t, tp, dp, bCfg) + + // Build an empty block on L2 + env.sequencer.ActL2StartBlock(t) + env.sequencer.ActL2EndBlock(t) + + // Instruct the batcher to submit the block to L1, and include the transaction. + env.batcher.ActSubmitAll(t) + env.miner.ActL1StartBlock(12)(t) + env.miner.ActL1IncludeTxByHash(env.batcher.LastSubmitted.Hash())(t) + env.miner.ActL1EndBlock(t) + + // Finalize the block with the batch on L1. + env.miner.ActL1SafeNext(t) + env.miner.ActL1FinalizeNext(t) + + // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. + env.sequencer.ActL1HeadSignal(t) + env.sequencer.ActL2PipelineFull(t) + + l1Head := env.miner.l1Chain.CurrentBlock() + l2SafeHead := env.engine.l2Chain.CurrentSafeBlock() + + // Ensure there is only 1 block on L1. + require.Equal(t, uint64(1), l1Head.Number.Uint64()) + // Ensure the block is marked as safe before we attempt to fault prove it. + require.Equal(t, uint64(1), l2SafeHead.Number.Uint64()) + + // Fetch the pre and post output roots for the fault proof. + preRoot, err := env.sequencer.RollupClient().OutputAtBlock(context.Background(), l2SafeHead.Number.Uint64()-1) + require.NoError(t, err) + claimRoot, err := env.sequencer.RollupClient().OutputAtBlock(context.Background(), l2SafeHead.Number.Uint64()) + require.NoError(t, err) + + // Run the fault proof program from the state transition from L2 block 0 -> 1. + programCfg := NewOpProgramCfg( + t, + env, + l1Head.Hash(), + preRoot.BlockRef.Hash, + common.Hash(preRoot.OutputRoot), + common.Hash(claimRoot.OutputRoot), + l2SafeHead.Number.Uint64(), + ) + err = host.FaultProofProgram(context.Background(), env.log, programCfg) + require.NoError(t, err) +} + +func Test_ProgramAction_SimpleEmptyChain_JunkClaim_Granite(gt *testing.T) { + t := NewDefaultTesting(gt) + tp := NewTestParams() + dp := NewDeployParams(t, func(dp *e2eutils.DeployParams) { + genesisBlock := hexutil.Uint64(0) + + // Enable Cancun on L1 & Granite on L2 at genesis + dp.DeployConfig.L1CancunTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisRegolithTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisFjordTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisGraniteTimeOffset = &genesisBlock + }) + bCfg := NewBatcherCfg() + env := NewL2FaultProofEnv(t, tp, dp, bCfg) + + // Build an empty block on L2 + env.sequencer.ActL2StartBlock(t) + env.sequencer.ActL2EndBlock(t) + + // Instruct the batcher to submit the block to L1, and include the transaction. + env.batcher.ActSubmitAll(t) + env.miner.ActL1StartBlock(12)(t) + env.miner.ActL1IncludeTxByHash(env.batcher.LastSubmitted.Hash())(t) + env.miner.ActL1EndBlock(t) + + // Finalize the block with the batch on L1. + env.miner.ActL1SafeNext(t) + env.miner.ActL1FinalizeNext(t) + + // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. + env.sequencer.ActL1HeadSignal(t) + env.sequencer.ActL2PipelineFull(t) + + l1Head := env.miner.l1Chain.CurrentBlock() + l2SafeHead := env.engine.l2Chain.CurrentSafeBlock() + + // Ensure there is only 1 block on L1. + require.Equal(t, uint64(1), l1Head.Number.Uint64()) + // Ensure the block is marked as safe before we attempt to fault prove it. + require.Equal(t, uint64(1), l2SafeHead.Number.Uint64()) + + // Fetch the pre and post output roots for the fault proof. + preRoot, err := env.sequencer.RollupClient().OutputAtBlock(context.Background(), l2SafeHead.Number.Uint64()-1) + require.NoError(t, err) + + // Run the fault proof program from the state transition from L2 block 0 -> 1, with a junk claim. + programCfg := NewOpProgramCfg( + t, + env, + l1Head.Hash(), + preRoot.BlockRef.Hash, + common.Hash(preRoot.OutputRoot), + common.HexToHash("0xdeadbeef"), + l2SafeHead.Number.Uint64(), + ) + err = host.FaultProofProgram(context.Background(), env.log, programCfg) + require.Error(t, err) +} diff --git a/op-e2e/e2eutils/blobs.go b/op-e2e/e2eutils/blobs.go index 730aae1d94c5..01256a355a92 100644 --- a/op-e2e/e2eutils/blobs.go +++ b/op-e2e/e2eutils/blobs.go @@ -6,33 +6,35 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/ethereum-optimism/optimism/op-program/host/sources" "github.com/ethereum-optimism/optimism/op-service/eth" ) // BlobsStore is a simple in-memory store of blobs, for testing purposes type BlobsStore struct { - // blockhash -> blob versioned hash -> blob - blobs map[common.Hash]map[common.Hash]*eth.Blob + // block timestamp -> blob versioned hash -> blob + blobs map[uint64]map[common.Hash]*eth.Blob } func NewBlobStore() *BlobsStore { - return &BlobsStore{blobs: make(map[common.Hash]map[common.Hash]*eth.Blob)} + return &BlobsStore{blobs: make(map[uint64]map[common.Hash]*eth.Blob)} } -func (store *BlobsStore) StoreBlob(blockHash common.Hash, versionedHash common.Hash, blob *eth.Blob) { - m, ok := store.blobs[blockHash] +func (store *BlobsStore) StoreBlob(blockTime uint64, versionedHash common.Hash, blob *eth.Blob) { + m, ok := store.blobs[blockTime] if !ok { m = make(map[common.Hash]*eth.Blob) - store.blobs[blockHash] = m + store.blobs[blockTime] = m } m[versionedHash] = blob } func (store *BlobsStore) GetBlobs(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.Blob, error) { out := make([]*eth.Blob, 0, len(hashes)) - m, ok := store.blobs[ref.Hash] + m, ok := store.blobs[ref.Time] if !ok { return nil, fmt.Errorf("no blobs known with given time: %w", ethereum.NotFound) } @@ -46,4 +48,35 @@ func (store *BlobsStore) GetBlobs(ctx context.Context, ref eth.L1BlockRef, hashe return out, nil } -var _ derive.L1BlobsFetcher = (*BlobsStore)(nil) +func (store *BlobsStore) GetBlobSidecars(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.BlobSidecar, error) { + out := make([]*eth.BlobSidecar, 0, len(hashes)) + m, ok := store.blobs[ref.Time] + if !ok { + return nil, fmt.Errorf("no blobs known with given time: %w", ethereum.NotFound) + } + for _, h := range hashes { + b, ok := m[h.Hash] + if !ok { + return nil, fmt.Errorf("blob %d %s is not in store: %w", h.Index, h.Hash, ethereum.NotFound) + } + if b == nil { + return nil, fmt.Errorf("blob %d %s is nil, cannot copy: %w", h.Index, h.Hash, ethereum.NotFound) + } + + commitment, err := kzg4844.BlobToCommitment(b.KZGBlob()) + if err != nil { + return nil, fmt.Errorf("failed to convert blob to commitment: %w", err) + } + out = append(out, ð.BlobSidecar{ + Index: eth.Uint64String(h.Index), + Blob: *b, + KZGCommitment: eth.Bytes48(commitment), + }) + } + return out, nil +} + +var ( + _ derive.L1BlobsFetcher = (*BlobsStore)(nil) + _ sources.L1BlobSource = (*BlobsStore)(nil) +) diff --git a/op-e2e/system_fpp_test.go b/op-e2e/system_fpp_test.go index c3598880b0cf..fab62fce2ce0 100644 --- a/op-e2e/system_fpp_test.go +++ b/op-e2e/system_fpp_test.go @@ -281,6 +281,7 @@ func testFaultProofProgramScenario(t *testing.T, ctx context.Context, sys *Syste fppConfig := oppconf.NewConfig(sys.RollupConfig, sys.L2GenesisCfg.Config, s.L1Head, s.L2Head, s.L2OutputRoot, common.Hash(s.L2Claim), s.L2ClaimBlockNumber) fppConfig.L1URL = sys.NodeEndpoint("l1").RPC() fppConfig.L2URL = sys.NodeEndpoint("sequencer").RPC() + fppConfig.L1BeaconURL = sys.L1BeaconEndpoint().RestHTTP() fppConfig.DataDir = preimageDir if s.Detached { // When running in detached mode we need to compile the client executable since it will be called directly. diff --git a/op-program/host/config/config.go b/op-program/host/config/config.go index dd9a2dff15ca..4ef56070c6ac 100644 --- a/op-program/host/config/config.go +++ b/op-program/host/config/config.go @@ -13,6 +13,7 @@ import ( opnode "github.com/ethereum-optimism/optimism/op-node" "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-program/host/flags" + hostSources "github.com/ethereum-optimism/optimism/op-program/host/sources" "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" @@ -73,6 +74,11 @@ type Config struct { // IsCustomChainConfig indicates that the program uses a custom chain configuration IsCustomChainConfig bool + + // Optional process sources. Will be favored over the RPC sources if set. + L1ProcessSource hostSources.L1Source + L1BeaconProcessSource hostSources.L1BlobSource + L2ProcessSource hostSources.L2Source } func (c *Config) Check() error { @@ -113,8 +119,11 @@ func (c *Config) Check() error { } func (c *Config) FetchingEnabled() bool { - // TODO: Include Beacon URL once cancun is active on all chains we fault prove. - return c.L1URL != "" && c.L2URL != "" + return (c.L1URL != "" && c.L2URL != "" && c.L1BeaconURL != "") || c.InProcessSourcesEnabled() +} + +func (c *Config) InProcessSourcesEnabled() bool { + return c.L1ProcessSource != nil && c.L1BeaconProcessSource != nil && c.L2ProcessSource != nil } // NewConfig creates a Config with all optional values set to the CLI default value diff --git a/op-program/host/config/config_test.go b/op-program/host/config/config_test.go index b9aaccc65416..e9cc54edd6a6 100644 --- a/op-program/host/config/config_test.go +++ b/op-program/host/config/config_test.go @@ -140,7 +140,8 @@ func TestFetchingEnabled(t *testing.T) { t.Run("FetchingEnabledWhenBothFetcherUrlsSpecified", func(t *testing.T) { cfg := validConfig() cfg.L1URL = "https://example.com:1234" - cfg.L2URL = "https://example.com:5678" + cfg.L1BeaconURL = "https://example.com:5678" + cfg.L2URL = "https://example.com:91011" require.True(t, cfg.FetchingEnabled(), "Should enable fetching when node URL supplied") }) } diff --git a/op-program/host/host.go b/op-program/host/host.go index 886205aca396..5cce95d0250c 100644 --- a/op-program/host/host.go +++ b/op-program/host/host.go @@ -16,6 +16,7 @@ import ( "github.com/ethereum-optimism/optimism/op-program/host/flags" "github.com/ethereum-optimism/optimism/op-program/host/kvstore" "github.com/ethereum-optimism/optimism/op-program/host/prefetcher" + hostSources "github.com/ethereum-optimism/optimism/op-program/host/sources" "github.com/ethereum-optimism/optimism/op-program/host/types" opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/client" @@ -205,31 +206,42 @@ func PreimageServer(ctx context.Context, logger log.Logger, cfg *config.Config, } func makePrefetcher(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *config.Config) (*prefetcher.Prefetcher, error) { - logger.Info("Connecting to L1 node", "l1", cfg.L1URL) - l1RPC, err := client.NewRPC(ctx, logger, cfg.L1URL, client.WithDialBackoff(10)) - if err != nil { - return nil, fmt.Errorf("failed to setup L1 RPC: %w", err) - } + var l1Cl hostSources.L1Source + var l1BlobFetcher hostSources.L1BlobSource + var l2DebugCl hostSources.L2Source - logger.Info("Connecting to L2 node", "l2", cfg.L2URL) - l2RPC, err := client.NewRPC(ctx, logger, cfg.L2URL, client.WithDialBackoff(10)) - if err != nil { - return nil, fmt.Errorf("failed to setup L2 RPC: %w", err) - } + if cfg.InProcessSourcesEnabled() { + logger.Debug("Using in-process sources for preimage fetching.") + l1Cl = cfg.L1ProcessSource + l1BlobFetcher = cfg.L1BeaconProcessSource + l2DebugCl = cfg.L2ProcessSource + } else { + logger.Info("Connecting to L1 node", "l1", cfg.L1URL) + l1RPC, err := client.NewRPC(ctx, logger, cfg.L1URL, client.WithDialBackoff(10)) + if err != nil { + return nil, fmt.Errorf("failed to setup L1 RPC: %w", err) + } - l1ClCfg := sources.L1ClientDefaultConfig(cfg.Rollup, cfg.L1TrustRPC, cfg.L1RPCKind) - l2ClCfg := sources.L2ClientDefaultConfig(cfg.Rollup, true) - l1Cl, err := sources.NewL1Client(l1RPC, logger, nil, l1ClCfg) - if err != nil { - return nil, fmt.Errorf("failed to create L1 client: %w", err) - } - l1Beacon := sources.NewBeaconHTTPClient(client.NewBasicHTTPClient(cfg.L1BeaconURL, logger)) - l1BlobFetcher := sources.NewL1BeaconClient(l1Beacon, sources.L1BeaconClientConfig{FetchAllSidecars: false}) - l2Cl, err := NewL2Client(l2RPC, logger, nil, &L2ClientConfig{L2ClientConfig: l2ClCfg, L2Head: cfg.L2Head}) - if err != nil { - return nil, fmt.Errorf("failed to create L2 client: %w", err) + logger.Info("Connecting to L2 node", "l2", cfg.L2URL) + l2RPC, err := client.NewRPC(ctx, logger, cfg.L2URL, client.WithDialBackoff(10)) + if err != nil { + return nil, fmt.Errorf("failed to setup L2 RPC: %w", err) + } + + l1ClCfg := sources.L1ClientDefaultConfig(cfg.Rollup, cfg.L1TrustRPC, cfg.L1RPCKind) + l2ClCfg := sources.L2ClientDefaultConfig(cfg.Rollup, true) + l1Cl, err = sources.NewL1Client(l1RPC, logger, nil, l1ClCfg) + if err != nil { + return nil, fmt.Errorf("failed to create L1 client: %w", err) + } + l1Beacon := sources.NewBeaconHTTPClient(client.NewBasicHTTPClient(cfg.L1BeaconURL, logger)) + l1BlobFetcher = sources.NewL1BeaconClient(l1Beacon, sources.L1BeaconClientConfig{FetchAllSidecars: false}) + l2Cl, err := NewL2Client(l2RPC, logger, nil, &L2ClientConfig{L2ClientConfig: l2ClCfg, L2Head: cfg.L2Head}) + if err != nil { + return nil, fmt.Errorf("failed to create L2 client: %w", err) + } + l2DebugCl = &L2Source{L2Client: l2Cl, DebugClient: sources.NewDebugClient(l2RPC.CallContext)} } - l2DebugCl := &L2Source{L2Client: l2Cl, DebugClient: sources.NewDebugClient(l2RPC.CallContext)} return prefetcher.NewPrefetcher(logger, l1Cl, l1BlobFetcher, l2DebugCl, kv), nil } diff --git a/op-program/host/prefetcher/prefetcher.go b/op-program/host/prefetcher/prefetcher.go index cb5a52fa88ce..d381e6be2385 100644 --- a/op-program/host/prefetcher/prefetcher.go +++ b/op-program/host/prefetcher/prefetcher.go @@ -13,6 +13,7 @@ import ( "github.com/ethereum-optimism/optimism/op-program/client/l2" "github.com/ethereum-optimism/optimism/op-program/client/mpt" "github.com/ethereum-optimism/optimism/op-program/host/kvstore" + "github.com/ethereum-optimism/optimism/op-program/host/sources" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -34,34 +35,16 @@ var acceleratedPrecompiles = []common.Address{ common.BytesToAddress([]byte{0x0a}), // KZG Point Evaluation } -type L1Source interface { - InfoByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, error) - InfoAndTxsByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Transactions, error) - FetchReceipts(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Receipts, error) -} - -type L1BlobSource interface { - GetBlobSidecars(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.BlobSidecar, error) - GetBlobs(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.Blob, error) -} - -type L2Source interface { - InfoAndTxsByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Transactions, error) - NodeByHash(ctx context.Context, hash common.Hash) ([]byte, error) - CodeByHash(ctx context.Context, hash common.Hash) ([]byte, error) - OutputByRoot(ctx context.Context, root common.Hash) (eth.Output, error) -} - type Prefetcher struct { logger log.Logger - l1Fetcher L1Source - l1BlobFetcher L1BlobSource - l2Fetcher L2Source + l1Fetcher sources.L1Source + l1BlobFetcher sources.L1BlobSource + l2Fetcher sources.L2Source lastHint string kvStore kvstore.KV } -func NewPrefetcher(logger log.Logger, l1Fetcher L1Source, l1BlobFetcher L1BlobSource, l2Fetcher L2Source, kvStore kvstore.KV) *Prefetcher { +func NewPrefetcher(logger log.Logger, l1Fetcher sources.L1Source, l1BlobFetcher sources.L1BlobSource, l2Fetcher sources.L2Source, kvStore kvstore.KV) *Prefetcher { return &Prefetcher{ logger: logger, l1Fetcher: NewRetryingL1Source(logger, l1Fetcher), diff --git a/op-program/host/prefetcher/retry.go b/op-program/host/prefetcher/retry.go index da9a588d8c3a..98941f710f54 100644 --- a/op-program/host/prefetcher/retry.go +++ b/op-program/host/prefetcher/retry.go @@ -4,6 +4,7 @@ import ( "context" "math" + "github.com/ethereum-optimism/optimism/op-program/host/sources" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/retry" "github.com/ethereum/go-ethereum/common" @@ -15,11 +16,11 @@ const maxAttempts = math.MaxInt // Succeed or die trying type RetryingL1Source struct { logger log.Logger - source L1Source + source sources.L1Source strategy retry.Strategy } -func NewRetryingL1Source(logger log.Logger, source L1Source) *RetryingL1Source { +func NewRetryingL1Source(logger log.Logger, source sources.L1Source) *RetryingL1Source { return &RetryingL1Source{ logger: logger, source: source, @@ -57,15 +58,15 @@ func (s *RetryingL1Source) FetchReceipts(ctx context.Context, blockHash common.H }) } -var _ L1Source = (*RetryingL1Source)(nil) +var _ sources.L1Source = (*RetryingL1Source)(nil) type RetryingL1BlobSource struct { logger log.Logger - source L1BlobSource + source sources.L1BlobSource strategy retry.Strategy } -func NewRetryingL1BlobSource(logger log.Logger, source L1BlobSource) *RetryingL1BlobSource { +func NewRetryingL1BlobSource(logger log.Logger, source sources.L1BlobSource) *RetryingL1BlobSource { return &RetryingL1BlobSource{ logger: logger, source: source, @@ -93,11 +94,11 @@ func (s *RetryingL1BlobSource) GetBlobs(ctx context.Context, ref eth.L1BlockRef, }) } -var _ L1BlobSource = (*RetryingL1BlobSource)(nil) +var _ sources.L1BlobSource = (*RetryingL1BlobSource)(nil) type RetryingL2Source struct { logger log.Logger - source L2Source + source sources.L2Source strategy retry.Strategy } @@ -142,7 +143,7 @@ func (s *RetryingL2Source) OutputByRoot(ctx context.Context, root common.Hash) ( }) } -func NewRetryingL2Source(logger log.Logger, source L2Source) *RetryingL2Source { +func NewRetryingL2Source(logger log.Logger, source sources.L2Source) *RetryingL2Source { return &RetryingL2Source{ logger: logger, source: source, @@ -150,4 +151,4 @@ func NewRetryingL2Source(logger log.Logger, source L2Source) *RetryingL2Source { } } -var _ L2Source = (*RetryingL2Source)(nil) +var _ sources.L2Source = (*RetryingL2Source)(nil) diff --git a/op-program/host/prefetcher/retry_test.go b/op-program/host/prefetcher/retry_test.go index 737635b57d95..dec179fc6276 100644 --- a/op-program/host/prefetcher/retry_test.go +++ b/op-program/host/prefetcher/retry_test.go @@ -12,6 +12,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/op-program/host/sources" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/retry" "github.com/ethereum-optimism/optimism/op-service/testlog" @@ -374,4 +375,4 @@ func (m *MockL2Source) ExpectOutputByRoot(root common.Hash, output eth.Output, e m.Mock.On("OutputByRoot", root).Once().Return(output, &err) } -var _ L2Source = (*MockL2Source)(nil) +var _ sources.L2Source = (*MockL2Source)(nil) diff --git a/op-program/host/sources/sources.go b/op-program/host/sources/sources.go new file mode 100644 index 000000000000..4b6570553c58 --- /dev/null +++ b/op-program/host/sources/sources.go @@ -0,0 +1,27 @@ +package sources + +import ( + "context" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +type L1Source interface { + InfoByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, error) + InfoAndTxsByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Transactions, error) + FetchReceipts(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Receipts, error) +} + +type L1BlobSource interface { + GetBlobSidecars(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.BlobSidecar, error) + GetBlobs(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.Blob, error) +} + +type L2Source interface { + InfoAndTxsByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Transactions, error) + NodeByHash(ctx context.Context, hash common.Hash) ([]byte, error) + CodeByHash(ctx context.Context, hash common.Hash) ([]byte, error) + OutputByRoot(ctx context.Context, root common.Hash) (eth.Output, error) +} From 489d93c77266f0ac367e89682fca6b10d93a75f6 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Wed, 11 Sep 2024 20:02:12 -0400 Subject: [PATCH 103/264] fix: add IBeacon to interface check ignore (#11860) IBeacon should've thrown an error but didn't, need to investigate why that was the case. For now I've added it to the ignore list. --- packages/contracts-bedrock/scripts/checks/check-interfaces.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh index df8c10238ca4..30dcaca3610d 100755 --- a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh +++ b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh @@ -37,6 +37,7 @@ EXCLUDE_CONTRACTS=( "IMulticall3" "IERC721TokenReceiver" "IProxyCreationCallback" + "IBeacon" # EAS "IEAS" From d91f92a2057ff0da00e3ef0b23c8240df9f2c6ae Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Thu, 12 Sep 2024 10:21:41 +1000 Subject: [PATCH 104/264] proofs-tools: Fix circleci config to run hold job on proofs-tools release tags (#11856) --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ec5d8887b6dc..8afcb1af6df4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1805,7 +1805,7 @@ workflows: type: approval filters: tags: - only: /^(da-server|ci-builder(-rust)?|ufm-[a-z0-9\-]*|op-[a-z0-9\-]*)\/v.*/ + only: /^(da-server|ci-builder(-rust)?|proofs-tools|ufm-[a-z0-9\-]*|op-[a-z0-9\-]*)\/v.*/ branches: ignore: /.*/ - docker-build: From 820636fb00d32f6153a836af30e9c1430241e6e0 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Wed, 11 Sep 2024 20:27:35 -0400 Subject: [PATCH 105/264] maint: add comment to OptimismPortal2 proof submitters mapping (#11853) Adds a comment to OptimismPortal2 that further explains the proofSubmitters mapping. --- packages/contracts-bedrock/semver-lock.json | 6 +++--- .../contracts-bedrock/src/L1/OptimismPortal2.sol | 12 +++++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 809345a37f8f..255c6cc3d07d 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -40,11 +40,11 @@ "sourceCodeHash": "0x17404b6cc3f62f66786c314e2abdf021a19c00845e2cbb2ec7796f2fa469991c" }, "src/L1/OptimismPortal2.sol": { - "initCodeHash": "0x6c1168834a0d2a23d9bfb995dd458ef5c2fd059c874d453988ef648de8300730", - "sourceCodeHash": "0xa8053edf2ddd421615c7570e5dbb435980b88e0f08e3189e2fc69b7a476e80a2" + "initCodeHash": "0xa5e9f45888a4a7cd6bf50c63bd6414181dd6ffdfc2afbcbe31046c0abc199a28", + "sourceCodeHash": "0xdcecbbd01e867f6b93b3d57f22de946237d56341606bdabb53257e017117f10a" }, "src/L1/OptimismPortalInterop.sol": { - "initCodeHash": "0xc95dd89962e301ce1fe773337463ea6e3b32b362971e5ad4f69e0881af7f4b7d", + "initCodeHash": "0x8bac6679aaf2c593d22fbe6b558509eef004959846e842181e5cc55e14b36ada", "sourceCodeHash": "0xe6a7794799915f408cb57c73af266670de8a3f02408d3dbc2c97db25d3e42635" }, "src/L1/ProtocolVersions.sol": { diff --git a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol index ad47652919c2..526c699f5256 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol @@ -106,7 +106,13 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { /// @notice The timestamp at which the respected game type was last updated. uint64 public respectedGameTypeUpdatedAt; - /// @notice Mapping of withdrawal hashes to addresses that have submitted a proof for the withdrawal. + /// @notice Mapping of withdrawal hashes to addresses that have submitted a proof for the + /// withdrawal. Original OptimismPortal contract only allowed one proof to be submitted + /// for any given withdrawal hash. Fault Proofs version of this contract must allow + /// multiple proofs for the same withdrawal hash to prevent a malicious user from + /// blocking other withdrawals by proving them against invalid proposals. Submitters + /// are tracked in an array to simplify the off-chain process of determining which + /// proof submission should be used when finalizing a withdrawal. mapping(bytes32 => address[]) public proofSubmitters; /// @notice Represents the amount of native asset minted in L2. This may not @@ -158,9 +164,9 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { } /// @notice Semantic version. - /// @custom:semver 3.11.0-beta.3 + /// @custom:semver 3.11.0-beta.4 function version() public pure virtual returns (string memory) { - return "3.11.0-beta.3"; + return "3.11.0-beta.4"; } /// @notice Constructs the OptimismPortal contract. From bd3955a62127f5a31ddd86a0f4cf69bc17855f7f Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Wed, 11 Sep 2024 20:36:56 -0400 Subject: [PATCH 106/264] fix: add extra context to check interfaces script logs (#11861) Updates the output of the check-interfaces script to be more clear about cases when removing items from the EXCLUDE_CONTRACTS list is acceptable and how to verify that an item is unnecessary. --- .../contracts-bedrock/scripts/checks/check-interfaces.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh index 30dcaca3610d..435034a3b06d 100755 --- a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh +++ b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh @@ -219,8 +219,9 @@ done # Check for unnecessary exclusions for exclude_item in "${EXCLUDE_CONTRACTS[@]}"; do if ! grep -q "^$exclude_item$" "$REPORTED_INTERFACES_FILE"; then - echo "Warning: $exclude_item is in the exclude list but was not reported as an issue." - echo "Consider removing it from the EXCLUDE_CONTRACTS list in the script." + echo "Warning: $exclude_item is in the exclude list but WAS NOT reported as an issue. It" + echo "may be unnecessary in the EXCLUDE_CONTRACTS list, but you MUST verify this before" + echo "removing it by performing a clean and full build before re-running this script." fi done From 320e11db7fc287a27dc02b5bc4946fe907eb2bdf Mon Sep 17 00:00:00 2001 From: clabby Date: Wed, 11 Sep 2024 20:41:04 -0400 Subject: [PATCH 107/264] feat: Helper for dumping `fp-tests` fixtures in `op-program` action tests (#11855) * feat: Helper for dumping `fp-tests` fixtures in `op-program` action tests * adrian review --- op-e2e/actions/op_program_test.go | 119 +++++++++++++++++++++++++++++- 1 file changed, 117 insertions(+), 2 deletions(-) diff --git a/op-e2e/actions/op_program_test.go b/op-e2e/actions/op_program_test.go index 81bb337b381f..e642d447c506 100644 --- a/op-e2e/actions/op_program_test.go +++ b/op-e2e/actions/op_program_test.go @@ -2,14 +2,22 @@ package actions import ( "context" + "encoding/json" + "errors" + "io/fs" "math/rand" "os" + "os/exec" + "path/filepath" "testing" + "github.com/BurntSushi/toml" batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-program/client/claim" "github.com/ethereum-optimism/optimism/op-program/host" "github.com/ethereum-optimism/optimism/op-program/host/config" + hostTypes "github.com/ethereum-optimism/optimism/op-program/host/types" "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum/go-ethereum/common" @@ -19,10 +27,14 @@ import ( "github.com/stretchr/testify/require" ) -var dumpFixtures = false +var ( + dumpFixtures = false + fixtureDir string +) func init() { - if os.Getenv("OP_E2E_DUMP_FIXTURES") == "1" { + fixtureDir = os.Getenv("OP_E2E_FPP_FIXTURE_DIR") + if fixtureDir != "" { dumpFixtures = true } } @@ -137,6 +149,11 @@ func NewOpProgramCfg( l2DebugCl := &host.L2Source{L2Client: l2Client, DebugClient: sources.NewDebugClient(l2RPC.CallContext)} dfault.L2ProcessSource = l2DebugCl + if dumpFixtures { + dfault.DataDir = t.TempDir() + dfault.DataFormat = hostTypes.DataFormatPebble + } + for _, apply := range params { apply(dfault) } @@ -205,6 +222,8 @@ func Test_ProgramAction_SimpleEmptyChain_HonestClaim_Granite(gt *testing.T) { ) err = host.FaultProofProgram(context.Background(), env.log, programCfg) require.NoError(t, err) + + tryDumpTestFixture(gt, err, "simple-empty-chain-honest-claim-granite", env, programCfg) } func Test_ProgramAction_SimpleEmptyChain_JunkClaim_Granite(gt *testing.T) { @@ -267,4 +286,100 @@ func Test_ProgramAction_SimpleEmptyChain_JunkClaim_Granite(gt *testing.T) { ) err = host.FaultProofProgram(context.Background(), env.log, programCfg) require.Error(t, err) + + tryDumpTestFixture(gt, err, "simple-empty-chain-junk-claim-granite", env, programCfg) +} + +//////////////////////////////////////////////////////////////// +// Fixture Generation utils // +//////////////////////////////////////////////////////////////// + +type TestFixture struct { + Name string `toml:"name"` + ExpectedStatus uint8 `toml:"expected-status"` + Inputs FixtureInputs `toml:"inputs"` +} + +type FixtureInputs struct { + L2BlockNumber uint64 `toml:"l2-block-number"` + L2Claim common.Hash `toml:"l2-claim"` + L2Head common.Hash `toml:"l2-head"` + L2OutputRoot common.Hash `toml:"l2-output-root"` + L2ChainID uint64 `toml:"l2-chain-id"` + L1Head common.Hash `toml:"l1-head"` +} + +// Dumps a `fp-tests` test fixture to disk if the `OP_E2E_DUMP_FIXTURES` environment variable is set. +// +// [fp-tests]: https://github.com/ethereum-optimism/fp-tests +func tryDumpTestFixture(t *testing.T, result error, name string, env *L2FaultProofEnv, programCfg *config.Config) { + if !dumpFixtures { + return + } + + rollupCfg := env.sequencer.rollupCfg + l2Genesis := env.sd.L2Cfg + + var expectedStatus uint8 + if result == nil { + expectedStatus = 0 + } else if errors.Is(result, claim.ErrClaimNotValid) { + expectedStatus = 1 + } else { + expectedStatus = 2 + } + + fixture := TestFixture{ + Name: name, + ExpectedStatus: expectedStatus, + Inputs: FixtureInputs{ + L2BlockNumber: programCfg.L2ClaimBlockNumber, + L2Claim: programCfg.L2Claim, + L2Head: programCfg.L2Head, + L2OutputRoot: programCfg.L2OutputRoot, + L2ChainID: env.sd.RollupCfg.L2ChainID.Uint64(), + L1Head: programCfg.L1Head, + }, + } + + fixturePath := filepath.Join(fixtureDir, name) + + err := os.MkdirAll(filepath.Join(fixturePath), fs.ModePerm) + require.NoError(t, err, "failed to create fixture dir") + + fixtureFilePath := filepath.Join(fixturePath, "fixture.toml") + serFixture, err := toml.Marshal(fixture) + require.NoError(t, err, "failed to serialize fixture") + require.NoError(t, os.WriteFile(fixtureFilePath, serFixture, fs.ModePerm), "failed to write fixture") + + genesisPath := filepath.Join(fixturePath, "genesis.json") + serGenesis, err := l2Genesis.MarshalJSON() + require.NoError(t, err, "failed to serialize genesis") + require.NoError(t, os.WriteFile(genesisPath, serGenesis, fs.ModePerm), "failed to write genesis") + + rollupPath := filepath.Join(fixturePath, "rollup.json") + serRollup, err := json.Marshal(rollupCfg) + require.NoError(t, err, "failed to serialize rollup") + require.NoError(t, os.WriteFile(rollupPath, serRollup, fs.ModePerm), "failed to write rollup") + + // Copy the witness database into the fixture directory. + cmd := exec.Command("cp", "-r", programCfg.DataDir, filepath.Join(fixturePath, "witness-db")) + require.NoError(t, cmd.Run(), "Failed to copy witness DB") + + // Compress the genesis file. + cmd = exec.Command("zstd", genesisPath) + _ = cmd.Run() + require.NoError(t, os.Remove(genesisPath), "Failed to remove uncompressed genesis file") + + // Compress the witness database. + cmd = exec.Command( + "tar", + "--zstd", + "-cf", + filepath.Join(fixturePath, "witness-db.tar.zst"), + filepath.Join(fixturePath, "witness-db"), + ) + cmd.Dir = filepath.Join(fixturePath) + require.NoError(t, cmd.Run(), "Failed to compress witness DB") + require.NoError(t, os.RemoveAll(filepath.Join(fixturePath, "witness-db")), "Failed to remove uncompressed witness DB") } From 5cdcfd46f0f309e9901dafd8f4c47357c8320c34 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Thu, 12 Sep 2024 10:44:08 +1000 Subject: [PATCH 108/264] proofs-tools: Update ci-docker-tag-op-stack-release.sh regex (#11862) --- ops/scripts/ci-docker-tag-op-stack-release.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ops/scripts/ci-docker-tag-op-stack-release.sh b/ops/scripts/ci-docker-tag-op-stack-release.sh index 49904d7cce9a..09ae8ad81df3 100755 --- a/ops/scripts/ci-docker-tag-op-stack-release.sh +++ b/ops/scripts/ci-docker-tag-op-stack-release.sh @@ -6,7 +6,7 @@ DOCKER_REPO=$1 GIT_TAG=$2 GIT_SHA=$3 -IMAGE_NAME=$(echo "$GIT_TAG" | grep -Eow '^(ci-builder(-rust)?|da-server|ufm-[a-z0-9\-]*|op-[a-z0-9\-]*)' || true) +IMAGE_NAME=$(echo "$GIT_TAG" | grep -Eow '^(ci-builder(-rust)?|da-server|proofs-tools|ufm-[a-z0-9\-]*|op-[a-z0-9\-]*)' || true) if [ -z "$IMAGE_NAME" ]; then echo "image name could not be parsed from git tag '$GIT_TAG'" exit 1 From 4656d49ac32e7cfecb3fb29e79e39f641defa198 Mon Sep 17 00:00:00 2001 From: Ratan Kaliani Date: Wed, 11 Sep 2024 18:18:26 -0700 Subject: [PATCH 109/264] chore: export process frames (#11864) --- op-node/cmd/batch_decoder/reassemble/reassemble.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/op-node/cmd/batch_decoder/reassemble/reassemble.go b/op-node/cmd/batch_decoder/reassemble/reassemble.go index 8844b2ab8fba..d8fc136b5043 100644 --- a/op-node/cmd/batch_decoder/reassemble/reassemble.go +++ b/op-node/cmd/batch_decoder/reassemble/reassemble.go @@ -72,7 +72,7 @@ func Channels(config Config, rollupCfg *rollup.Config) { framesByChannel[frame.Frame.ID] = append(framesByChannel[frame.Frame.ID], frame) } for id, frames := range framesByChannel { - ch := processFrames(config, rollupCfg, id, frames) + ch := ProcessFrames(config, rollupCfg, id, frames) filename := path.Join(config.OutDirectory, fmt.Sprintf("%s.json", id.String())) if err := writeChannel(ch, filename); err != nil { log.Fatal(err) @@ -90,7 +90,9 @@ func writeChannel(ch ChannelWithMetadata, filename string) error { return enc.Encode(ch) } -func processFrames(cfg Config, rollupCfg *rollup.Config, id derive.ChannelID, frames []FrameWithMetadata) ChannelWithMetadata { +// ProcessFrames processes the frames for a given channel and reads batches and other relevant metadata +// from the channel. Returns a ChannelWithMetadata struct containing all the relevant data. +func ProcessFrames(cfg Config, rollupCfg *rollup.Config, id derive.ChannelID, frames []FrameWithMetadata) ChannelWithMetadata { spec := rollup.NewChainSpec(rollupCfg) ch := derive.NewChannel(id, eth.L1BlockRef{Number: frames[0].InclusionBlock}) invalidFrame := false From 77f726874a2f961a4a17f816c099c390b0f7a53b Mon Sep 17 00:00:00 2001 From: clabby Date: Wed, 11 Sep 2024 21:45:54 -0400 Subject: [PATCH 110/264] chore: Cleanup proofs actions (#11858) * chore: Cleanup proofs actions * tidy * lint * adrian review * move `RunFaultProofProgram` onto the `L2FaultProofEnv` type --- go.mod | 2 +- op-e2e/actions/altda_test.go | 2 +- op-e2e/actions/batch_queue_test.go | 2 +- op-e2e/actions/blocktime_test.go | 8 +- op-e2e/actions/dencun_fork_test.go | 28 +- op-e2e/actions/ecotone_fork_test.go | 8 +- op-e2e/actions/eip4844_test.go | 4 +- op-e2e/actions/fjord_fork_test.go | 4 +- op-e2e/actions/interop_test.go | 4 +- op-e2e/actions/l1_miner.go | 4 +- op-e2e/actions/l1_miner_test.go | 4 +- op-e2e/actions/l1_replica.go | 4 + op-e2e/actions/l1_replica_test.go | 17 +- op-e2e/actions/l2_batcher_test.go | 18 +- op-e2e/actions/l2_engine.go | 4 + op-e2e/actions/l2_engine_test.go | 16 +- op-e2e/actions/l2_proposer_test.go | 4 +- op-e2e/actions/l2_sequencer_test.go | 48 +-- op-e2e/actions/l2_verifier_test.go | 33 +- op-e2e/actions/op_program_test.go | 385 ------------------- op-e2e/actions/proofs/env.go | 181 +++++++++ op-e2e/actions/proofs/fixture.go | 119 ++++++ op-e2e/actions/proofs/simple_program_test.go | 109 ++++++ op-e2e/actions/reorg_test.go | 14 +- op-e2e/actions/safedb_test.go | 4 +- op-e2e/actions/span_batch_test.go | 14 +- op-e2e/actions/sync_test.go | 56 +-- op-e2e/actions/system_config_test.go | 12 +- op-e2e/actions/user_test.go | 4 +- op-e2e/actions/utils.go | 79 ++++ 30 files changed, 614 insertions(+), 577 deletions(-) delete mode 100644 op-e2e/actions/op_program_test.go create mode 100644 op-e2e/actions/proofs/env.go create mode 100644 op-e2e/actions/proofs/fixture.go create mode 100644 op-e2e/actions/proofs/simple_program_test.go create mode 100644 op-e2e/actions/utils.go diff --git a/go.mod b/go.mod index 5ab245ccf283..e1b4e14530a1 100644 --- a/go.mod +++ b/go.mod @@ -35,6 +35,7 @@ require ( github.com/multiformats/go-base32 v0.1.0 github.com/multiformats/go-multiaddr v0.13.0 github.com/multiformats/go-multiaddr-dns v0.3.1 + github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 github.com/olekukonko/tablewriter v0.0.5 github.com/onsi/gomega v1.34.1 github.com/pkg/errors v0.9.1 @@ -165,7 +166,6 @@ require ( github.com/multiformats/go-varint v0.0.7 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/naoina/go-stringutil v0.1.0 // indirect - github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 // indirect github.com/onsi/ginkgo/v2 v2.20.0 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect diff --git a/op-e2e/actions/altda_test.go b/op-e2e/actions/altda_test.go index ab18ff77e098..ed6068c141ae 100644 --- a/op-e2e/actions/altda_test.go +++ b/op-e2e/actions/altda_test.go @@ -60,7 +60,7 @@ func NewL2AltDA(t Testing, params ...AltDAParam) *L2AltDA { log := testlog.Logger(t, log.LvlDebug) dp := e2eutils.MakeDeployParams(t, p) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) require.True(t, sd.RollupCfg.AltDAEnabled()) diff --git a/op-e2e/actions/batch_queue_test.go b/op-e2e/actions/batch_queue_test.go index 69c9957d134b..e5132a85ac94 100644 --- a/op-e2e/actions/batch_queue_test.go +++ b/op-e2e/actions/batch_queue_test.go @@ -30,7 +30,7 @@ func TestDeriveChainFromNearL1Genesis(gt *testing.T) { dp := e2eutils.MakeDeployParams(t, p) // do not activate Delta hardfork for verifier applyDeltaTimeOffset(dp, nil) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) logger := testlog.Logger(t, log.LevelInfo) miner, seqEngine, sequencer := setupSequencerTest(t, sd, logger) diff --git a/op-e2e/actions/blocktime_test.go b/op-e2e/actions/blocktime_test.go index 7bf34e103cc7..20f644887697 100644 --- a/op-e2e/actions/blocktime_test.go +++ b/op-e2e/actions/blocktime_test.go @@ -45,12 +45,12 @@ func TestBlockTimeBatchType(t *testing.T) { // This is a regression test against the bug fixed in PR #4566 func BatchInLastPossibleBlocks(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) applyDeltaTimeOffset(dp, deltaTimeOffset) dp.DeployConfig.SequencerWindowSize = 4 dp.DeployConfig.L2BlockTime = 2 - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) sd, _, miner, sequencer, sequencerEngine, _, _, batcher := setupReorgTestActors(t, dp, sd, log) @@ -156,7 +156,7 @@ func BatchInLastPossibleBlocks(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // Note: It batches submits when possible. func LargeL1Gaps(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) dp.DeployConfig.L1BlockTime = 4 dp.DeployConfig.L2BlockTime = 2 dp.DeployConfig.SequencerWindowSize = 4 @@ -166,7 +166,7 @@ func LargeL1Gaps(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // TODO(client-pod#831): The Ecotone (and Fjord) activation blocks don't include user txs, // so disabling these forks for now. applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) sd, _, miner, sequencer, sequencerEngine, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) diff --git a/op-e2e/actions/dencun_fork_test.go b/op-e2e/actions/dencun_fork_test.go index 9b411e28f1e7..ac0484c800b0 100644 --- a/op-e2e/actions/dencun_fork_test.go +++ b/op-e2e/actions/dencun_fork_test.go @@ -18,10 +18,10 @@ import ( func TestDencunL1ForkAfterGenesis(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) offset := hexutil.Uint64(24) dp.DeployConfig.L1CancunTimeOffset = &offset - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) @@ -61,9 +61,9 @@ func TestDencunL1ForkAfterGenesis(gt *testing.T) { func TestDencunL1ForkAtGenesis(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) require.Zero(t, *dp.DeployConfig.L1CancunTimeOffset) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) @@ -118,7 +118,7 @@ func verifyEcotoneBlock(gt *testing.T, header *types.Header) { func TestDencunL2ForkAfterGenesis(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) require.Zero(t, *dp.DeployConfig.L1CancunTimeOffset) // This test wil fork on the second block offset := hexutil.Uint64(dp.DeployConfig.L2BlockTime * 2) @@ -127,7 +127,7 @@ func TestDencunL2ForkAfterGenesis(gt *testing.T) { dp.DeployConfig.L2GenesisGraniteTimeOffset = nil // New forks have to be added here, after changing the default deploy config! - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) _, _, _, sequencer, engine, verifier, _, _ := setupReorgTestActors(t, dp, sd, log) @@ -156,10 +156,10 @@ func TestDencunL2ForkAfterGenesis(gt *testing.T) { func TestDencunL2ForkAtGenesis(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) require.Zero(t, *dp.DeployConfig.L2GenesisEcotoneTimeOffset) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) _, _, _, sequencer, engine, verifier, _, _ := setupReorgTestActors(t, dp, sd, log) @@ -194,9 +194,9 @@ func newEngine(t Testing, sd *e2eutils.SetupData, log log.Logger) *L2Engine { // TestDencunBlobTxRPC tries to send a Blob tx to the L2 engine via RPC, it should not be accepted. func TestDencunBlobTxRPC(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) engine := newEngine(t, sd, log) cl := engine.EthClient() @@ -208,9 +208,9 @@ func TestDencunBlobTxRPC(gt *testing.T) { // TestDencunBlobTxInTxPool tries to insert a blob tx directly into the tx pool, it should not be accepted. func TestDencunBlobTxInTxPool(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) engine := newEngine(t, sd, log) tx := aliceSimpleBlobTx(t, dp) @@ -221,9 +221,9 @@ func TestDencunBlobTxInTxPool(gt *testing.T) { // TestDencunBlobTxInclusion tries to send a Blob tx to the L2 engine, it should not be accepted. func TestDencunBlobTxInclusion(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) _, engine, sequencer := setupSequencerTest(t, sd, log) diff --git a/op-e2e/actions/ecotone_fork_test.go b/op-e2e/actions/ecotone_fork_test.go index 260a7960089a..3237915d6e00 100644 --- a/op-e2e/actions/ecotone_fork_test.go +++ b/op-e2e/actions/ecotone_fork_test.go @@ -41,7 +41,7 @@ func verifyCodeHashMatches(t Testing, client *ethclient.Client, address common.A func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) ecotoneOffset := hexutil.Uint64(4) log := testlog.Logger(t, log.LevelDebug) @@ -54,7 +54,7 @@ func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) { // New forks have to be added here... require.NoError(t, dp.DeployConfig.Check(log), "must have valid config") - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) _, _, miner, sequencer, engine, verifier, _, _ := setupReorgTestActors(t, dp, sd, log) ethCl := engine.EthClient() @@ -239,7 +239,7 @@ func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) { // TestEcotoneBeforeL1 tests that the L2 Ecotone fork can activate before L1 Dencun does func TestEcotoneBeforeL1(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) offset := hexutil.Uint64(0) farOffset := hexutil.Uint64(10000) dp.DeployConfig.L2GenesisRegolithTimeOffset = &offset @@ -248,7 +248,7 @@ func TestEcotoneBeforeL1(gt *testing.T) { dp.DeployConfig.L2GenesisDeltaTimeOffset = &offset dp.DeployConfig.L2GenesisEcotoneTimeOffset = &offset - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) _, _, _, sequencer, engine, verifier, _, _ := setupReorgTestActors(t, dp, sd, log) diff --git a/op-e2e/actions/eip4844_test.go b/op-e2e/actions/eip4844_test.go index ddab21d48b47..8b287250bb0e 100644 --- a/op-e2e/actions/eip4844_test.go +++ b/op-e2e/actions/eip4844_test.go @@ -17,14 +17,14 @@ import ( ) func setupEIP4844Test(t Testing, log log.Logger) (*e2eutils.SetupData, *e2eutils.DeployParams, *L1Miner, *L2Sequencer, *L2Engine, *L2Verifier, *L2Engine) { - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) genesisActivation := hexutil.Uint64(0) dp.DeployConfig.L1CancunTimeOffset = &genesisActivation dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisActivation dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisActivation dp.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisActivation - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) miner.ActL1SetFeeRecipient(common.Address{'A'}) sequencer.ActL2PipelineFull(t) diff --git a/op-e2e/actions/fjord_fork_test.go b/op-e2e/actions/fjord_fork_test.go index 517ec5cd2618..d003c69af394 100644 --- a/op-e2e/actions/fjord_fork_test.go +++ b/op-e2e/actions/fjord_fork_test.go @@ -30,7 +30,7 @@ var ( func TestFjordNetworkUpgradeTransactions(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) genesisBlock := hexutil.Uint64(0) fjordOffset := hexutil.Uint64(2) @@ -46,7 +46,7 @@ func TestFjordNetworkUpgradeTransactions(gt *testing.T) { dp.DeployConfig.L2GenesisFjordTimeOffset = &fjordOffset require.NoError(t, dp.DeployConfig.Check(log), "must have valid config") - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) _, _, _, sequencer, engine, verifier, _, _ := setupReorgTestActors(t, dp, sd, log) ethCl := engine.EthClient() diff --git a/op-e2e/actions/interop_test.go b/op-e2e/actions/interop_test.go index 8890f86a0067..614ab05f65a7 100644 --- a/op-e2e/actions/interop_test.go +++ b/op-e2e/actions/interop_test.go @@ -19,8 +19,8 @@ var _ interop.InteropBackend = (*testutils.MockInteropBackend)(nil) func TestInteropVerifier(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) - sd := e2eutils.Setup(t, dp, defaultAlloc) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + sd := e2eutils.Setup(t, dp, DefaultAlloc) // Temporary work-around: interop needs to be active, for cross-safety to not be instant. // The state genesis in this test is pre-interop however. sd.RollupCfg.InteropTime = new(uint64) diff --git a/op-e2e/actions/l1_miner.go b/op-e2e/actions/l1_miner.go index d14eab394131..46c9045961bb 100644 --- a/op-e2e/actions/l1_miner.go +++ b/op-e2e/actions/l1_miner.go @@ -17,7 +17,7 @@ import ( "github.com/ethereum/go-ethereum/trie" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" - "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/ethereum-optimism/optimism/op-program/host/sources" "github.com/ethereum-optimism/optimism/op-service/eth" ) @@ -52,7 +52,7 @@ func NewL1Miner(t Testing, log log.Logger, genesis *core.Genesis) *L1Miner { } } -func (s *L1Miner) BlobStore() derive.L1BlobsFetcher { +func (s *L1Miner) BlobStore() sources.L1BlobSource { return s.blobStore } diff --git a/op-e2e/actions/l1_miner_test.go b/op-e2e/actions/l1_miner_test.go index 10e4c0c5498c..a56fc06c235b 100644 --- a/op-e2e/actions/l1_miner_test.go +++ b/op-e2e/actions/l1_miner_test.go @@ -15,8 +15,8 @@ import ( func TestL1Miner_BuildBlock(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) - sd := e2eutils.Setup(t, dp, defaultAlloc) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) miner := NewL1Miner(t, log, sd.L1Cfg) t.Cleanup(func() { diff --git a/op-e2e/actions/l1_replica.go b/op-e2e/actions/l1_replica.go index fb042757065e..83120203ee7b 100644 --- a/op-e2e/actions/l1_replica.go +++ b/op-e2e/actions/l1_replica.go @@ -192,6 +192,10 @@ func (s *L1Replica) L1Client(t Testing, cfg *rollup.Config) *sources.L1Client { return l1F } +func (s *L1Replica) L1Chain() *core.BlockChain { + return s.l1Chain +} + func (s *L1Replica) UnsafeNum() uint64 { head := s.l1Chain.CurrentBlock() headNum := uint64(0) diff --git a/op-e2e/actions/l1_replica_test.go b/op-e2e/actions/l1_replica_test.go index ab918a619644..1d342a86e81f 100644 --- a/op-e2e/actions/l1_replica_test.go +++ b/op-e2e/actions/l1_replica_test.go @@ -21,20 +21,11 @@ import ( "github.com/ethereum-optimism/optimism/op-service/testlog" ) -var defaultRollupTestParams = &e2eutils.TestParams{ - MaxSequencerDrift: 40, - SequencerWindowSize: 120, - ChannelTimeout: 120, - L1BlockTime: 15, -} - -var defaultAlloc = &e2eutils.AllocParams{PrefundTestUsers: true} - // Test if we can mock an RPC failure func TestL1Replica_ActL1RPCFail(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) - sd := e2eutils.Setup(t, dp, defaultAlloc) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) replica := NewL1Replica(t, log, sd.L1Cfg) t.Cleanup(func() { @@ -55,9 +46,9 @@ func TestL1Replica_ActL1RPCFail(gt *testing.T) { // Test if we can make the replica sync an artificial L1 chain, rewind it, and reorg it func TestL1Replica_ActL1Sync(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) dp.DeployConfig.L1CancunTimeOffset = nil - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) genesisBlock := sd.L1Cfg.ToBlock() consensus := beacon.New(ethash.NewFaker()) diff --git a/op-e2e/actions/l2_batcher_test.go b/op-e2e/actions/l2_batcher_test.go index 6235c7482326..88dd393a38df 100644 --- a/op-e2e/actions/l2_batcher_test.go +++ b/op-e2e/actions/l2_batcher_test.go @@ -81,7 +81,7 @@ func NormalBatcher(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { } dp := e2eutils.MakeDeployParams(t, p) applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) @@ -148,9 +148,9 @@ func NormalBatcher(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { func L2Finalization(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) miner, engine, sequencer := setupSequencerTest(t, sd, log) @@ -245,9 +245,9 @@ func L2Finalization(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // L2FinalizationWithSparseL1 tests that safe L2 blocks can be finalized even if we do not regularly get a L1 finalization signal func L2FinalizationWithSparseL1(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) miner, engine, sequencer := setupSequencerTest(t, sd, log) @@ -301,11 +301,11 @@ func L2FinalizationWithSparseL1(gt *testing.T, deltaTimeOffset *hexutil.Uint64) // and the safe L2 head should remain unaltered. func GarbageBatch(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) - p := defaultRollupTestParams + p := DefaultRollupTestParams dp := e2eutils.MakeDeployParams(t, p) applyDeltaTimeOffset(dp, deltaTimeOffset) for _, garbageKind := range GarbageKinds { - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelError) miner, engine, sequencer := setupSequencerTest(t, sd, log) @@ -385,7 +385,7 @@ func ExtendedTimeWithoutL1Batches(gt *testing.T, deltaTimeOffset *hexutil.Uint64 } dp := e2eutils.MakeDeployParams(t, p) applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelError) miner, engine, sequencer := setupSequencerTest(t, sd, log) @@ -441,7 +441,7 @@ func BigL2Txs(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { } dp := e2eutils.MakeDeployParams(t, p) applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelInfo) miner, engine, sequencer := setupSequencerTest(t, sd, log) diff --git a/op-e2e/actions/l2_engine.go b/op-e2e/actions/l2_engine.go index 54267ee9da58..828ede53cade 100644 --- a/op-e2e/actions/l2_engine.go +++ b/op-e2e/actions/l2_engine.go @@ -135,6 +135,10 @@ func (e *engineApiBackend) Genesis() *core.Genesis { return e.genesis } +func (s *L2Engine) L2Chain() *core.BlockChain { + return s.l2Chain +} + func (s *L2Engine) Enode() *enode.Node { return s.node.Server().LocalNode().Node() } diff --git a/op-e2e/actions/l2_engine_test.go b/op-e2e/actions/l2_engine_test.go index 5d7a537b5d03..2ea335ec855e 100644 --- a/op-e2e/actions/l2_engine_test.go +++ b/op-e2e/actions/l2_engine_test.go @@ -31,8 +31,8 @@ import ( func TestL2EngineAPI(gt *testing.T) { t := NewDefaultTesting(gt) jwtPath := e2eutils.WriteDefaultJWT(t) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) - sd := e2eutils.Setup(t, dp, defaultAlloc) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) genesisBlock := sd.L2Cfg.ToBlock() consensus := beacon.New(ethash.NewFaker()) @@ -107,8 +107,8 @@ func TestL2EngineAPI(gt *testing.T) { func TestL2EngineAPIBlockBuilding(gt *testing.T) { t := NewDefaultTesting(gt) jwtPath := e2eutils.WriteDefaultJWT(t) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) - sd := e2eutils.Setup(t, dp, defaultAlloc) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) genesisBlock := sd.L2Cfg.ToBlock() db := rawdb.NewMemoryDatabase() @@ -208,8 +208,8 @@ func TestL2EngineAPIBlockBuilding(gt *testing.T) { func TestL2EngineAPIFail(gt *testing.T) { t := NewDefaultTesting(gt) jwtPath := e2eutils.WriteDefaultJWT(t) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) - sd := e2eutils.Setup(t, dp, defaultAlloc) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) engine := NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath) // mock an RPC failure @@ -228,8 +228,8 @@ func TestL2EngineAPIFail(gt *testing.T) { func TestEngineAPITests(t *testing.T) { test.RunEngineAPITests(t, func(t *testing.T) engineapi.EngineBackend { jwtPath := e2eutils.WriteDefaultJWT(t) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) - sd := e2eutils.Setup(t, dp, defaultAlloc) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + sd := e2eutils.Setup(t, dp, DefaultAlloc) n, _, apiBackend := newBackend(t, sd.L2Cfg, jwtPath, nil) err := n.Start() require.NoError(t, err) diff --git a/op-e2e/actions/l2_proposer_test.go b/op-e2e/actions/l2_proposer_test.go index bed138cdb3a7..a8fe25816a0c 100644 --- a/op-e2e/actions/l2_proposer_test.go +++ b/op-e2e/actions/l2_proposer_test.go @@ -45,9 +45,9 @@ func TestProposerBatchType(t *testing.T) { func RunProposerTest(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) diff --git a/op-e2e/actions/l2_sequencer_test.go b/op-e2e/actions/l2_sequencer_test.go index 87cf95eaa425..8872da6481d1 100644 --- a/op-e2e/actions/l2_sequencer_test.go +++ b/op-e2e/actions/l2_sequencer_test.go @@ -5,10 +5,6 @@ import ( "testing" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/eth/ethconfig" - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/common" @@ -21,43 +17,9 @@ import ( "github.com/ethereum-optimism/optimism/op-service/testlog" ) -func EngineWithP2P() EngineOption { - return func(ethCfg *ethconfig.Config, nodeCfg *node.Config) error { - p2pKey, err := crypto.GenerateKey() - if err != nil { - return err - } - nodeCfg.P2P = p2p.Config{ - MaxPeers: 100, - NoDiscovery: true, - ListenAddr: "127.0.0.1:0", - PrivateKey: p2pKey, - } - return nil - } -} - -type sequencerCfg struct { - verifierCfg -} - -func defaultSequencerConfig() *sequencerCfg { - return &sequencerCfg{verifierCfg: *defaultVerifierCfg()} -} - -type SequencerOpt func(opts *sequencerCfg) - -func WithVerifierOpts(opts ...VerifierOpt) SequencerOpt { - return func(cfg *sequencerCfg) { - for _, opt := range opts { - opt(&cfg.verifierCfg) - } - } -} - func setupSequencerTest(t Testing, sd *e2eutils.SetupData, log log.Logger, opts ...SequencerOpt) (*L1Miner, *L2Engine, *L2Sequencer) { jwtPath := e2eutils.WriteDefaultJWT(t) - cfg := defaultSequencerConfig() + cfg := DefaultSequencerConfig() for _, opt := range opts { opt(cfg) } @@ -70,7 +32,7 @@ func setupSequencerTest(t Testing, sd *e2eutils.SetupData, log log.Logger, opts l2Cl, err := sources.NewEngineClient(engine.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(t, err) - sequencer := NewL2Sequencer(t, log.New("role", "sequencer"), l1F, miner.BlobStore(), altda.Disabled, l2Cl, sd.RollupCfg, 0, cfg.interopBackend) + sequencer := NewL2Sequencer(t, log.New("role", "sequencer"), l1F, miner.BlobStore(), altda.Disabled, l2Cl, sd.RollupCfg, 0, cfg.InteropBackend) return miner, engine, sequencer } @@ -83,7 +45,7 @@ func TestL2Sequencer_SequencerDrift(gt *testing.T) { L1BlockTime: 12, } dp := e2eutils.MakeDeployParams(t, p) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) miner, engine, sequencer := setupSequencerTest(t, sd, log) miner.ActL1SetFeeRecipient(common.Address{'A'}) @@ -150,8 +112,8 @@ func TestL2Sequencer_SequencerDrift(gt *testing.T) { // while the verifier-codepath only ever sees the valid post-reorg L1 chain. func TestL2Sequencer_SequencerOnlyReorg(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) - sd := e2eutils.Setup(t, dp, defaultAlloc) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) miner, _, sequencer := setupSequencerTest(t, sd, log) diff --git a/op-e2e/actions/l2_verifier_test.go b/op-e2e/actions/l2_verifier_test.go index f8f751ca6b7a..75c1efbc176c 100644 --- a/op-e2e/actions/l2_verifier_test.go +++ b/op-e2e/actions/l2_verifier_test.go @@ -9,48 +9,21 @@ import ( altda "github.com/ethereum-optimism/optimism/op-alt-da" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" - "github.com/ethereum-optimism/optimism/op-node/node/safedb" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" - "github.com/ethereum-optimism/optimism/op-node/rollup/interop" "github.com/ethereum-optimism/optimism/op-node/rollup/sync" "github.com/ethereum-optimism/optimism/op-service/testlog" ) -type verifierCfg struct { - safeHeadListener safeDB - interopBackend interop.InteropBackend -} - -type VerifierOpt func(opts *verifierCfg) - -func WithSafeHeadListener(l safeDB) VerifierOpt { - return func(opts *verifierCfg) { - opts.safeHeadListener = l - } -} - -func WithInteropBackend(b interop.InteropBackend) VerifierOpt { - return func(opts *verifierCfg) { - opts.interopBackend = b - } -} - -func defaultVerifierCfg() *verifierCfg { - return &verifierCfg{ - safeHeadListener: safedb.Disabled, - } -} - func setupVerifier(t Testing, sd *e2eutils.SetupData, log log.Logger, l1F derive.L1Fetcher, blobSrc derive.L1BlobsFetcher, syncCfg *sync.Config, opts ...VerifierOpt) (*L2Engine, *L2Verifier) { - cfg := defaultVerifierCfg() + cfg := DefaultVerifierCfg() for _, opt := range opts { opt(cfg) } jwtPath := e2eutils.WriteDefaultJWT(t) engine := NewL2Engine(t, log.New("role", "verifier-engine"), sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath, EngineWithP2P()) engCl := engine.EngineClient(t, sd.RollupCfg) - verifier := NewL2Verifier(t, log.New("role", "verifier"), l1F, blobSrc, altda.Disabled, engCl, sd.RollupCfg, syncCfg, cfg.safeHeadListener, cfg.interopBackend) + verifier := NewL2Verifier(t, log.New("role", "verifier"), l1F, blobSrc, altda.Disabled, engCl, sd.RollupCfg, syncCfg, cfg.SafeHeadListener, cfg.InteropBackend) return engine, verifier } @@ -70,7 +43,7 @@ func TestL2Verifier_SequenceWindow(gt *testing.T) { L1BlockTime: 15, } dp := e2eutils.MakeDeployParams(t, p) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) miner, engine, verifier := setupVerifierOnlyTest(t, sd, log) miner.ActL1SetFeeRecipient(common.Address{'A'}) diff --git a/op-e2e/actions/op_program_test.go b/op-e2e/actions/op_program_test.go deleted file mode 100644 index e642d447c506..000000000000 --- a/op-e2e/actions/op_program_test.go +++ /dev/null @@ -1,385 +0,0 @@ -package actions - -import ( - "context" - "encoding/json" - "errors" - "io/fs" - "math/rand" - "os" - "os/exec" - "path/filepath" - "testing" - - "github.com/BurntSushi/toml" - batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" - "github.com/ethereum-optimism/optimism/op-program/client/claim" - "github.com/ethereum-optimism/optimism/op-program/host" - "github.com/ethereum-optimism/optimism/op-program/host/config" - hostTypes "github.com/ethereum-optimism/optimism/op-program/host/types" - "github.com/ethereum-optimism/optimism/op-service/sources" - "github.com/ethereum-optimism/optimism/op-service/testlog" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" - "github.com/stretchr/testify/require" -) - -var ( - dumpFixtures = false - fixtureDir string -) - -func init() { - fixtureDir = os.Getenv("OP_E2E_FPP_FIXTURE_DIR") - if fixtureDir != "" { - dumpFixtures = true - } -} - -// L2FaultProofEnv is a test harness for a fault provable L2 chain. -type L2FaultProofEnv struct { - log log.Logger - batcher *L2Batcher - sequencer *L2Sequencer - engine *L2Engine - engCl *sources.EngineClient - sd *e2eutils.SetupData - dp *e2eutils.DeployParams - miner *L1Miner - alice *CrossLayerUser -} - -func NewL2FaultProofEnv(t Testing, tp *e2eutils.TestParams, dp *e2eutils.DeployParams, batcherCfg *BatcherCfg) *L2FaultProofEnv { - log := testlog.Logger(t, log.LvlDebug) - sd := e2eutils.Setup(t, dp, defaultAlloc) - - miner, engine, sequencer := setupSequencerTest(t, sd, log) - miner.ActL1SetFeeRecipient(common.Address{0xCA, 0xFE, 0xBA, 0xBE}) - sequencer.ActL2PipelineFull(t) - engCl := engine.EngineClient(t, sd.RollupCfg) - - // Set the batcher key to the secret key of the batcher - batcherCfg.BatcherKey = dp.Secrets.Batcher - batcher := NewL2Batcher(log, sd.RollupCfg, batcherCfg, sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engCl) - - addresses := e2eutils.CollectAddresses(sd, dp) - cl := engine.EthClient() - l2UserEnv := &BasicUserEnv[*L2Bindings]{ - EthCl: cl, - Signer: types.LatestSigner(sd.L2Cfg.Config), - AddressCorpora: addresses, - Bindings: NewL2Bindings(t, cl, engine.GethClient()), - } - alice := NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b))) - alice.L2.SetUserEnv(l2UserEnv) - - return &L2FaultProofEnv{ - log: log, - batcher: batcher, - sequencer: sequencer, - engine: engine, - engCl: engCl, - sd: sd, - dp: dp, - miner: miner, - alice: alice, - } -} - -type TestParam func(p *e2eutils.TestParams) - -func NewTestParams(params ...TestParam) *e2eutils.TestParams { - dfault := defaultRollupTestParams - for _, apply := range params { - apply(dfault) - } - return dfault -} - -type DeployParam func(p *e2eutils.DeployParams) - -func NewDeployParams(t Testing, params ...DeployParam) *e2eutils.DeployParams { - dfault := e2eutils.MakeDeployParams(t, NewTestParams()) - for _, apply := range params { - apply(dfault) - } - return dfault -} - -type BatcherCfgParam func(c *BatcherCfg) - -func NewBatcherCfg(params ...BatcherCfgParam) *BatcherCfg { - dfault := &BatcherCfg{ - MinL1TxSize: 0, - MaxL1TxSize: 128_000, - DataAvailabilityType: batcherFlags.BlobsType, - } - for _, apply := range params { - apply(dfault) - } - return dfault -} - -type OpProgramCfgParam func(p *config.Config) - -func NewOpProgramCfg( - t Testing, - env *L2FaultProofEnv, - l1Head common.Hash, - l2Head common.Hash, - l2OutputRoot common.Hash, - l2Claim common.Hash, - l2ClaimBlockNum uint64, - params ...OpProgramCfgParam, -) *config.Config { - dfault := config.NewConfig(env.sd.RollupCfg, env.sd.L2Cfg.Config, l1Head, l2Head, l2OutputRoot, l2Claim, l2ClaimBlockNum) - - // Set up in-process L1 sources - dfault.L1ProcessSource = env.miner.L1Client(t, env.sd.RollupCfg) - dfault.L1BeaconProcessSource = env.miner.blobStore - - // Set up in-process L2 source - l2ClCfg := sources.L2ClientDefaultConfig(env.sd.RollupCfg, true) - l2RPC := env.engine.RPCClient() - l2Client, err := host.NewL2Client(l2RPC, env.log, nil, &host.L2ClientConfig{L2ClientConfig: l2ClCfg, L2Head: l2Head}) - require.NoError(t, err, "failed to create L2 client") - l2DebugCl := &host.L2Source{L2Client: l2Client, DebugClient: sources.NewDebugClient(l2RPC.CallContext)} - dfault.L2ProcessSource = l2DebugCl - - if dumpFixtures { - dfault.DataDir = t.TempDir() - dfault.DataFormat = hostTypes.DataFormatPebble - } - - for _, apply := range params { - apply(dfault) - } - return dfault -} - -func Test_ProgramAction_SimpleEmptyChain_HonestClaim_Granite(gt *testing.T) { - t := NewDefaultTesting(gt) - tp := NewTestParams() - dp := NewDeployParams(t, func(dp *e2eutils.DeployParams) { - genesisBlock := hexutil.Uint64(0) - - // Enable Cancun on L1 & Granite on L2 at genesis - dp.DeployConfig.L1CancunTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisRegolithTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisFjordTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisGraniteTimeOffset = &genesisBlock - }) - bCfg := NewBatcherCfg() - env := NewL2FaultProofEnv(t, tp, dp, bCfg) - - // Build an empty block on L2 - env.sequencer.ActL2StartBlock(t) - env.sequencer.ActL2EndBlock(t) - - // Instruct the batcher to submit the block to L1, and include the transaction. - env.batcher.ActSubmitAll(t) - env.miner.ActL1StartBlock(12)(t) - env.miner.ActL1IncludeTxByHash(env.batcher.LastSubmitted.Hash())(t) - env.miner.ActL1EndBlock(t) - - // Finalize the block with the batch on L1. - env.miner.ActL1SafeNext(t) - env.miner.ActL1FinalizeNext(t) - - // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. - env.sequencer.ActL1HeadSignal(t) - env.sequencer.ActL2PipelineFull(t) - - l1Head := env.miner.l1Chain.CurrentBlock() - l2SafeHead := env.engine.l2Chain.CurrentSafeBlock() - - // Ensure there is only 1 block on L1. - require.Equal(t, uint64(1), l1Head.Number.Uint64()) - // Ensure the block is marked as safe before we attempt to fault prove it. - require.Equal(t, uint64(1), l2SafeHead.Number.Uint64()) - - // Fetch the pre and post output roots for the fault proof. - preRoot, err := env.sequencer.RollupClient().OutputAtBlock(context.Background(), l2SafeHead.Number.Uint64()-1) - require.NoError(t, err) - claimRoot, err := env.sequencer.RollupClient().OutputAtBlock(context.Background(), l2SafeHead.Number.Uint64()) - require.NoError(t, err) - - // Run the fault proof program from the state transition from L2 block 0 -> 1. - programCfg := NewOpProgramCfg( - t, - env, - l1Head.Hash(), - preRoot.BlockRef.Hash, - common.Hash(preRoot.OutputRoot), - common.Hash(claimRoot.OutputRoot), - l2SafeHead.Number.Uint64(), - ) - err = host.FaultProofProgram(context.Background(), env.log, programCfg) - require.NoError(t, err) - - tryDumpTestFixture(gt, err, "simple-empty-chain-honest-claim-granite", env, programCfg) -} - -func Test_ProgramAction_SimpleEmptyChain_JunkClaim_Granite(gt *testing.T) { - t := NewDefaultTesting(gt) - tp := NewTestParams() - dp := NewDeployParams(t, func(dp *e2eutils.DeployParams) { - genesisBlock := hexutil.Uint64(0) - - // Enable Cancun on L1 & Granite on L2 at genesis - dp.DeployConfig.L1CancunTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisRegolithTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisFjordTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisGraniteTimeOffset = &genesisBlock - }) - bCfg := NewBatcherCfg() - env := NewL2FaultProofEnv(t, tp, dp, bCfg) - - // Build an empty block on L2 - env.sequencer.ActL2StartBlock(t) - env.sequencer.ActL2EndBlock(t) - - // Instruct the batcher to submit the block to L1, and include the transaction. - env.batcher.ActSubmitAll(t) - env.miner.ActL1StartBlock(12)(t) - env.miner.ActL1IncludeTxByHash(env.batcher.LastSubmitted.Hash())(t) - env.miner.ActL1EndBlock(t) - - // Finalize the block with the batch on L1. - env.miner.ActL1SafeNext(t) - env.miner.ActL1FinalizeNext(t) - - // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. - env.sequencer.ActL1HeadSignal(t) - env.sequencer.ActL2PipelineFull(t) - - l1Head := env.miner.l1Chain.CurrentBlock() - l2SafeHead := env.engine.l2Chain.CurrentSafeBlock() - - // Ensure there is only 1 block on L1. - require.Equal(t, uint64(1), l1Head.Number.Uint64()) - // Ensure the block is marked as safe before we attempt to fault prove it. - require.Equal(t, uint64(1), l2SafeHead.Number.Uint64()) - - // Fetch the pre and post output roots for the fault proof. - preRoot, err := env.sequencer.RollupClient().OutputAtBlock(context.Background(), l2SafeHead.Number.Uint64()-1) - require.NoError(t, err) - - // Run the fault proof program from the state transition from L2 block 0 -> 1, with a junk claim. - programCfg := NewOpProgramCfg( - t, - env, - l1Head.Hash(), - preRoot.BlockRef.Hash, - common.Hash(preRoot.OutputRoot), - common.HexToHash("0xdeadbeef"), - l2SafeHead.Number.Uint64(), - ) - err = host.FaultProofProgram(context.Background(), env.log, programCfg) - require.Error(t, err) - - tryDumpTestFixture(gt, err, "simple-empty-chain-junk-claim-granite", env, programCfg) -} - -//////////////////////////////////////////////////////////////// -// Fixture Generation utils // -//////////////////////////////////////////////////////////////// - -type TestFixture struct { - Name string `toml:"name"` - ExpectedStatus uint8 `toml:"expected-status"` - Inputs FixtureInputs `toml:"inputs"` -} - -type FixtureInputs struct { - L2BlockNumber uint64 `toml:"l2-block-number"` - L2Claim common.Hash `toml:"l2-claim"` - L2Head common.Hash `toml:"l2-head"` - L2OutputRoot common.Hash `toml:"l2-output-root"` - L2ChainID uint64 `toml:"l2-chain-id"` - L1Head common.Hash `toml:"l1-head"` -} - -// Dumps a `fp-tests` test fixture to disk if the `OP_E2E_DUMP_FIXTURES` environment variable is set. -// -// [fp-tests]: https://github.com/ethereum-optimism/fp-tests -func tryDumpTestFixture(t *testing.T, result error, name string, env *L2FaultProofEnv, programCfg *config.Config) { - if !dumpFixtures { - return - } - - rollupCfg := env.sequencer.rollupCfg - l2Genesis := env.sd.L2Cfg - - var expectedStatus uint8 - if result == nil { - expectedStatus = 0 - } else if errors.Is(result, claim.ErrClaimNotValid) { - expectedStatus = 1 - } else { - expectedStatus = 2 - } - - fixture := TestFixture{ - Name: name, - ExpectedStatus: expectedStatus, - Inputs: FixtureInputs{ - L2BlockNumber: programCfg.L2ClaimBlockNumber, - L2Claim: programCfg.L2Claim, - L2Head: programCfg.L2Head, - L2OutputRoot: programCfg.L2OutputRoot, - L2ChainID: env.sd.RollupCfg.L2ChainID.Uint64(), - L1Head: programCfg.L1Head, - }, - } - - fixturePath := filepath.Join(fixtureDir, name) - - err := os.MkdirAll(filepath.Join(fixturePath), fs.ModePerm) - require.NoError(t, err, "failed to create fixture dir") - - fixtureFilePath := filepath.Join(fixturePath, "fixture.toml") - serFixture, err := toml.Marshal(fixture) - require.NoError(t, err, "failed to serialize fixture") - require.NoError(t, os.WriteFile(fixtureFilePath, serFixture, fs.ModePerm), "failed to write fixture") - - genesisPath := filepath.Join(fixturePath, "genesis.json") - serGenesis, err := l2Genesis.MarshalJSON() - require.NoError(t, err, "failed to serialize genesis") - require.NoError(t, os.WriteFile(genesisPath, serGenesis, fs.ModePerm), "failed to write genesis") - - rollupPath := filepath.Join(fixturePath, "rollup.json") - serRollup, err := json.Marshal(rollupCfg) - require.NoError(t, err, "failed to serialize rollup") - require.NoError(t, os.WriteFile(rollupPath, serRollup, fs.ModePerm), "failed to write rollup") - - // Copy the witness database into the fixture directory. - cmd := exec.Command("cp", "-r", programCfg.DataDir, filepath.Join(fixturePath, "witness-db")) - require.NoError(t, cmd.Run(), "Failed to copy witness DB") - - // Compress the genesis file. - cmd = exec.Command("zstd", genesisPath) - _ = cmd.Run() - require.NoError(t, os.Remove(genesisPath), "Failed to remove uncompressed genesis file") - - // Compress the witness database. - cmd = exec.Command( - "tar", - "--zstd", - "-cf", - filepath.Join(fixturePath, "witness-db.tar.zst"), - filepath.Join(fixturePath, "witness-db"), - ) - cmd.Dir = filepath.Join(fixturePath) - require.NoError(t, cmd.Run(), "Failed to compress witness DB") - require.NoError(t, os.RemoveAll(filepath.Join(fixturePath, "witness-db")), "Failed to remove uncompressed witness DB") -} diff --git a/op-e2e/actions/proofs/env.go b/op-e2e/actions/proofs/env.go new file mode 100644 index 000000000000..59fc51fdf452 --- /dev/null +++ b/op-e2e/actions/proofs/env.go @@ -0,0 +1,181 @@ +package proofs + +import ( + "math/rand" + "testing" + + altda "github.com/ethereum-optimism/optimism/op-alt-da" + batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" + "github.com/ethereum-optimism/optimism/op-e2e/actions" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-program/host" + "github.com/ethereum-optimism/optimism/op-program/host/config" + hostTypes "github.com/ethereum-optimism/optimism/op-program/host/types" + "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +// L2FaultProofEnv is a test harness for a fault provable L2 chain. +type L2FaultProofEnv struct { + log log.Logger + batcher *actions.L2Batcher + sequencer *actions.L2Sequencer + engine *actions.L2Engine + engCl *sources.EngineClient + sd *e2eutils.SetupData + dp *e2eutils.DeployParams + miner *actions.L1Miner + alice *actions.CrossLayerUser +} + +func NewL2FaultProofEnv(t actions.Testing, tp *e2eutils.TestParams, dp *e2eutils.DeployParams, batcherCfg *actions.BatcherCfg) *L2FaultProofEnv { + log := testlog.Logger(t, log.LvlDebug) + sd := e2eutils.Setup(t, dp, actions.DefaultAlloc) + + jwtPath := e2eutils.WriteDefaultJWT(t) + cfg := &actions.SequencerCfg{VerifierCfg: *actions.DefaultVerifierCfg()} + + miner := actions.NewL1Miner(t, log.New("role", "l1-miner"), sd.L1Cfg) + + l1F, err := sources.NewL1Client(miner.RPCClient(), log, nil, sources.L1ClientDefaultConfig(sd.RollupCfg, false, sources.RPCKindStandard)) + require.NoError(t, err) + engine := actions.NewL2Engine(t, log.New("role", "sequencer-engine"), sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath, actions.EngineWithP2P()) + l2Cl, err := sources.NewEngineClient(engine.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) + require.NoError(t, err) + + sequencer := actions.NewL2Sequencer(t, log.New("role", "sequencer"), l1F, miner.BlobStore(), altda.Disabled, l2Cl, sd.RollupCfg, 0, cfg.InteropBackend) + miner.ActL1SetFeeRecipient(common.Address{0xCA, 0xFE, 0xBA, 0xBE}) + sequencer.ActL2PipelineFull(t) + engCl := engine.EngineClient(t, sd.RollupCfg) + + // Set the batcher key to the secret key of the batcher + batcherCfg.BatcherKey = dp.Secrets.Batcher + batcher := actions.NewL2Batcher(log, sd.RollupCfg, batcherCfg, sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engCl) + + addresses := e2eutils.CollectAddresses(sd, dp) + cl := engine.EthClient() + l2UserEnv := &actions.BasicUserEnv[*actions.L2Bindings]{ + EthCl: cl, + Signer: types.LatestSigner(sd.L2Cfg.Config), + AddressCorpora: addresses, + Bindings: actions.NewL2Bindings(t, cl, engine.GethClient()), + } + alice := actions.NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b))) + alice.L2.SetUserEnv(l2UserEnv) + + return &L2FaultProofEnv{ + log: log, + batcher: batcher, + sequencer: sequencer, + engine: engine, + engCl: engCl, + sd: sd, + dp: dp, + miner: miner, + alice: alice, + } +} + +type FixtureInputParam func(f *FixtureInputs) + +func (env *L2FaultProofEnv) RunFaultProofProgram(t actions.Testing, gt *testing.T, l2ClaimBlockNum uint64, fixtureInputParams ...FixtureInputParam) error { + // Fetch the pre and post output roots for the fault proof. + preRoot, err := env.sequencer.RollupClient().OutputAtBlock(t.Ctx(), l2ClaimBlockNum-1) + require.NoError(t, err) + claimRoot, err := env.sequencer.RollupClient().OutputAtBlock(t.Ctx(), l2ClaimBlockNum) + require.NoError(t, err) + l1Head := env.miner.L1Chain().CurrentBlock() + + fixtureInputs := &FixtureInputs{ + L2BlockNumber: l2ClaimBlockNum, + L2Claim: common.Hash(claimRoot.OutputRoot), + L2Head: preRoot.BlockRef.Hash, + L2OutputRoot: common.Hash(preRoot.OutputRoot), + L2ChainID: env.sd.RollupCfg.L2ChainID.Uint64(), + L1Head: l1Head.Hash(), + } + for _, apply := range fixtureInputParams { + apply(fixtureInputs) + } + + // Run the fault proof program from the state transition from L2 block 0 -> 1. + programCfg := NewOpProgramCfg( + t, + env, + fixtureInputs, + ) + err = host.FaultProofProgram(t.Ctx(), env.log, programCfg) + tryDumpTestFixture(gt, err, t.Name(), env, programCfg) + return err +} + +type TestParam func(p *e2eutils.TestParams) + +func NewTestParams(params ...TestParam) *e2eutils.TestParams { + dfault := actions.DefaultRollupTestParams + for _, apply := range params { + apply(dfault) + } + return dfault +} + +type DeployParam func(p *e2eutils.DeployParams) + +func NewDeployParams(t actions.Testing, params ...DeployParam) *e2eutils.DeployParams { + dfault := e2eutils.MakeDeployParams(t, NewTestParams()) + for _, apply := range params { + apply(dfault) + } + return dfault +} + +type BatcherCfgParam func(c *actions.BatcherCfg) + +func NewBatcherCfg(params ...BatcherCfgParam) *actions.BatcherCfg { + dfault := &actions.BatcherCfg{ + MinL1TxSize: 0, + MaxL1TxSize: 128_000, + DataAvailabilityType: batcherFlags.BlobsType, + } + for _, apply := range params { + apply(dfault) + } + return dfault +} + +type OpProgramCfgParam func(p *config.Config) + +func NewOpProgramCfg( + t actions.Testing, + env *L2FaultProofEnv, + fi *FixtureInputs, + params ...OpProgramCfgParam, +) *config.Config { + dfault := config.NewConfig(env.sd.RollupCfg, env.sd.L2Cfg.Config, fi.L1Head, fi.L2Head, fi.L2OutputRoot, fi.L2Claim, fi.L2BlockNumber) + + // Set up in-process L1 sources + dfault.L1ProcessSource = env.miner.L1Client(t, env.sd.RollupCfg) + dfault.L1BeaconProcessSource = env.miner.BlobStore() + + // Set up in-process L2 source + l2ClCfg := sources.L2ClientDefaultConfig(env.sd.RollupCfg, true) + l2RPC := env.engine.RPCClient() + l2Client, err := host.NewL2Client(l2RPC, env.log, nil, &host.L2ClientConfig{L2ClientConfig: l2ClCfg, L2Head: fi.L2Head}) + require.NoError(t, err, "failed to create L2 client") + l2DebugCl := &host.L2Source{L2Client: l2Client, DebugClient: sources.NewDebugClient(l2RPC.CallContext)} + dfault.L2ProcessSource = l2DebugCl + + if dumpFixtures { + dfault.DataDir = t.TempDir() + dfault.DataFormat = hostTypes.DataFormatPebble + } + + for _, apply := range params { + apply(dfault) + } + return dfault +} diff --git a/op-e2e/actions/proofs/fixture.go b/op-e2e/actions/proofs/fixture.go new file mode 100644 index 000000000000..8bc4a875a4c3 --- /dev/null +++ b/op-e2e/actions/proofs/fixture.go @@ -0,0 +1,119 @@ +package proofs + +import ( + "encoding/json" + "errors" + "io/fs" + "os" + "os/exec" + "path/filepath" + "testing" + + "github.com/ethereum-optimism/optimism/op-program/client/claim" + "github.com/ethereum-optimism/optimism/op-program/host/config" + "github.com/ethereum/go-ethereum/common" + "github.com/naoina/toml" + "github.com/stretchr/testify/require" +) + +var ( + dumpFixtures = false + fixtureDir string +) + +func init() { + fixtureDir = os.Getenv("OP_E2E_FPP_FIXTURE_DIR") + if fixtureDir != "" { + dumpFixtures = true + } +} + +type TestFixture struct { + Name string `toml:"name"` + ExpectedStatus uint8 `toml:"expected-status"` + Inputs FixtureInputs `toml:"inputs"` +} + +type FixtureInputs struct { + L2BlockNumber uint64 `toml:"l2-block-number"` + L2Claim common.Hash `toml:"l2-claim"` + L2Head common.Hash `toml:"l2-head"` + L2OutputRoot common.Hash `toml:"l2-output-root"` + L2ChainID uint64 `toml:"l2-chain-id"` + L1Head common.Hash `toml:"l1-head"` +} + +// Dumps a `fp-tests` test fixture to disk if the `OP_E2E_DUMP_FIXTURES` environment variable is set. +// +// [fp-tests]: https://github.com/ethereum-optimism/fp-tests +func tryDumpTestFixture(t *testing.T, result error, name string, env *L2FaultProofEnv, programCfg *config.Config) { + if !dumpFixtures { + return + } + + rollupCfg := env.sd.RollupCfg + l2Genesis := env.sd.L2Cfg + + var expectedStatus uint8 + if result == nil { + expectedStatus = 0 + } else if errors.Is(result, claim.ErrClaimNotValid) { + expectedStatus = 1 + } else { + expectedStatus = 2 + } + + fixture := TestFixture{ + Name: name, + ExpectedStatus: expectedStatus, + Inputs: FixtureInputs{ + L2BlockNumber: programCfg.L2ClaimBlockNumber, + L2Claim: programCfg.L2Claim, + L2Head: programCfg.L2Head, + L2OutputRoot: programCfg.L2OutputRoot, + L2ChainID: env.sd.RollupCfg.L2ChainID.Uint64(), + L1Head: programCfg.L1Head, + }, + } + + fixturePath := filepath.Join(fixtureDir, name) + + err := os.MkdirAll(filepath.Join(fixturePath), fs.ModePerm) + require.NoError(t, err, "failed to create fixture dir") + + fixtureFilePath := filepath.Join(fixturePath, "fixture.toml") + serFixture, err := toml.Marshal(fixture) + require.NoError(t, err, "failed to serialize fixture") + require.NoError(t, os.WriteFile(fixtureFilePath, serFixture, fs.ModePerm), "failed to write fixture") + + genesisPath := filepath.Join(fixturePath, "genesis.json") + serGenesis, err := l2Genesis.MarshalJSON() + require.NoError(t, err, "failed to serialize genesis") + require.NoError(t, os.WriteFile(genesisPath, serGenesis, fs.ModePerm), "failed to write genesis") + + rollupPath := filepath.Join(fixturePath, "rollup.json") + serRollup, err := json.Marshal(rollupCfg) + require.NoError(t, err, "failed to serialize rollup") + require.NoError(t, os.WriteFile(rollupPath, serRollup, fs.ModePerm), "failed to write rollup") + + // Copy the witness database into the fixture directory. + cmd := exec.Command("cp", "-r", programCfg.DataDir, filepath.Join(fixturePath, "witness-db")) + require.NoError(t, cmd.Run(), "Failed to copy witness DB") + + // Compress the genesis file. + cmd = exec.Command("zstd", genesisPath) + _ = cmd.Run() + require.NoError(t, os.Remove(genesisPath), "Failed to remove uncompressed genesis file") + + // Compress the witness database. + cmd = exec.Command( + "tar", + "--zstd", + "-cf", + filepath.Join(fixturePath, "witness-db.tar.zst"), + filepath.Join(fixturePath, "witness-db"), + ) + cmd.Dir = filepath.Join(fixturePath) + require.NoError(t, cmd.Run(), "Failed to compress witness DB") + require.NoError(t, os.RemoveAll(filepath.Join(fixturePath, "witness-db")), "Failed to remove uncompressed witness DB") +} diff --git a/op-e2e/actions/proofs/simple_program_test.go b/op-e2e/actions/proofs/simple_program_test.go new file mode 100644 index 000000000000..b160045210d5 --- /dev/null +++ b/op-e2e/actions/proofs/simple_program_test.go @@ -0,0 +1,109 @@ +package proofs + +import ( + "testing" + + "github.com/ethereum-optimism/optimism/op-e2e/actions" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/stretchr/testify/require" +) + +func Test_ProgramAction_SimpleEmptyChain_HonestClaim_Granite(gt *testing.T) { + t := actions.NewDefaultTesting(gt) + tp := NewTestParams() + dp := NewDeployParams(t, func(dp *e2eutils.DeployParams) { + genesisBlock := hexutil.Uint64(0) + + // Enable Cancun on L1 & Granite on L2 at genesis + dp.DeployConfig.L1CancunTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisRegolithTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisFjordTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisGraniteTimeOffset = &genesisBlock + }) + bCfg := NewBatcherCfg() + env := NewL2FaultProofEnv(t, tp, dp, bCfg) + + // Build an empty block on L2 + env.sequencer.ActL2StartBlock(t) + env.sequencer.ActL2EndBlock(t) + + // Instruct the batcher to submit the block to L1, and include the transaction. + env.batcher.ActSubmitAll(t) + env.miner.ActL1StartBlock(12)(t) + env.miner.ActL1IncludeTxByHash(env.batcher.LastSubmitted.Hash())(t) + env.miner.ActL1EndBlock(t) + + // Finalize the block with the batch on L1. + env.miner.ActL1SafeNext(t) + env.miner.ActL1FinalizeNext(t) + + // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. + env.sequencer.ActL1HeadSignal(t) + env.sequencer.ActL2PipelineFull(t) + + l1Head := env.miner.L1Chain().CurrentBlock() + l2SafeHead := env.engine.L2Chain().CurrentSafeBlock() + + // Ensure there is only 1 block on L1. + require.Equal(t, uint64(1), l1Head.Number.Uint64()) + // Ensure the block is marked as safe before we attempt to fault prove it. + require.Equal(t, uint64(1), l2SafeHead.Number.Uint64()) + + err := env.RunFaultProofProgram(t, gt, l2SafeHead.Number.Uint64()) + require.NoError(t, err, "fault proof program failed") +} + +func Test_ProgramAction_SimpleEmptyChain_JunkClaim_Granite(gt *testing.T) { + t := actions.NewDefaultTesting(gt) + tp := NewTestParams() + dp := NewDeployParams(t, func(dp *e2eutils.DeployParams) { + genesisBlock := hexutil.Uint64(0) + + // Enable Cancun on L1 & Granite on L2 at genesis + dp.DeployConfig.L1CancunTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisRegolithTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisFjordTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisGraniteTimeOffset = &genesisBlock + }) + bCfg := NewBatcherCfg() + env := NewL2FaultProofEnv(t, tp, dp, bCfg) + + // Build an empty block on L2 + env.sequencer.ActL2StartBlock(t) + env.sequencer.ActL2EndBlock(t) + + // Instruct the batcher to submit the block to L1, and include the transaction. + env.batcher.ActSubmitAll(t) + env.miner.ActL1StartBlock(12)(t) + env.miner.ActL1IncludeTxByHash(env.batcher.LastSubmitted.Hash())(t) + env.miner.ActL1EndBlock(t) + + // Finalize the block with the batch on L1. + env.miner.ActL1SafeNext(t) + env.miner.ActL1FinalizeNext(t) + + // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. + env.sequencer.ActL1HeadSignal(t) + env.sequencer.ActL2PipelineFull(t) + + l1Head := env.miner.L1Chain().CurrentBlock() + l2SafeHead := env.engine.L2Chain().CurrentSafeBlock() + + // Ensure there is only 1 block on L1. + require.Equal(t, uint64(1), l1Head.Number.Uint64()) + // Ensure the block is marked as safe before we attempt to fault prove it. + require.Equal(t, uint64(1), l2SafeHead.Number.Uint64()) + + err := env.RunFaultProofProgram(t, gt, l2SafeHead.Number.Uint64(), func(f *FixtureInputs) { + f.L2Claim = common.HexToHash("0xdeadbeef") + }) + require.Error(t, err, "fault proof program should have failed") +} diff --git a/op-e2e/actions/reorg_test.go b/op-e2e/actions/reorg_test.go index 271b69cb1b29..1ffd512d328f 100644 --- a/op-e2e/actions/reorg_test.go +++ b/op-e2e/actions/reorg_test.go @@ -27,7 +27,7 @@ func setupReorgTest(t Testing, config *e2eutils.TestParams, deltaTimeOffset *hex dp := e2eutils.MakeDeployParams(t, config) applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) return setupReorgTestActors(t, dp, sd, log) @@ -75,7 +75,7 @@ func TestReorgBatchType(t *testing.T) { func ReorgOrphanBlock(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) - sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, defaultRollupTestParams, deltaTimeOffset) + sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, DefaultRollupTestParams, deltaTimeOffset) verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg) sequencer.ActL2PipelineFull(t) @@ -143,7 +143,7 @@ func ReorgOrphanBlock(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { func ReorgFlipFlop(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) - sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, defaultRollupTestParams, deltaTimeOffset) + sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, DefaultRollupTestParams, deltaTimeOffset) minerCl := miner.L1Client(t, sd.RollupCfg) verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg) checkVerifEngine := func() { @@ -599,9 +599,9 @@ func RestartOpGeth(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { nodeCfg.DataDir = dbPath return nil } - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) jwtPath := e2eutils.WriteDefaultJWT(t) // L1 @@ -687,9 +687,9 @@ func RestartOpGeth(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // the alt block is not synced by the verifier, in unsafe and safe sync modes. func ConflictingL2Blocks(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) sd, _, miner, sequencer, seqEng, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) diff --git a/op-e2e/actions/safedb_test.go b/op-e2e/actions/safedb_test.go index 9fd570fa79f5..d7baeeb3715c 100644 --- a/op-e2e/actions/safedb_test.go +++ b/op-e2e/actions/safedb_test.go @@ -17,7 +17,7 @@ import ( func TestRecordSafeHeadUpdates(gt *testing.T) { t := NewDefaultTesting(gt) - sd, miner, sequencer, verifier, verifierEng, batcher := setupSafeDBTest(t, defaultRollupTestParams) + sd, miner, sequencer, verifier, verifierEng, batcher := setupSafeDBTest(t, DefaultRollupTestParams) verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg) sequencer.ActL2PipelineFull(t) @@ -116,7 +116,7 @@ func TestRecordSafeHeadUpdates(gt *testing.T) { func setupSafeDBTest(t Testing, config *e2eutils.TestParams) (*e2eutils.SetupData, *L1Miner, *L2Sequencer, *L2Verifier, *L2Engine, *L2Batcher) { dp := e2eutils.MakeDeployParams(t, config) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) logger := testlog.Logger(t, log.LevelDebug) return setupSafeDBTestActors(t, dp, sd, logger) diff --git a/op-e2e/actions/span_batch_test.go b/op-e2e/actions/span_batch_test.go index 23f5963fa97a..7eb551c521c7 100644 --- a/op-e2e/actions/span_batch_test.go +++ b/op-e2e/actions/span_batch_test.go @@ -41,7 +41,7 @@ func TestDropSpanBatchBeforeHardfork(gt *testing.T) { dp := e2eutils.MakeDeployParams(t, p) // do not activate Delta hardfork for verifier applyDeltaTimeOffset(dp, nil) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelError) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) @@ -137,7 +137,7 @@ func TestHardforkMiddleOfSpanBatch(gt *testing.T) { dp.DeployConfig.L2GenesisFjordTimeOffset = nil dp.DeployConfig.L2GenesisGraniteTimeOffset = nil - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelError) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) @@ -245,7 +245,7 @@ func TestAcceptSingularBatchAfterHardfork(gt *testing.T) { // activate Delta hardfork for verifier. applyDeltaTimeOffset(dp, &minTs) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelError) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) @@ -331,7 +331,7 @@ func TestMixOfBatchesAfterHardfork(gt *testing.T) { // Activate Delta hardfork for verifier. applyDeltaTimeOffset(dp, &minTs) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelError) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) @@ -421,7 +421,7 @@ func TestSpanBatchEmptyChain(gt *testing.T) { minTs := hexutil.Uint64(0) // Activate Delta hardfork applyDeltaTimeOffset(dp, &minTs) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelError) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) @@ -484,7 +484,7 @@ func TestSpanBatchLowThroughputChain(gt *testing.T) { minTs := hexutil.Uint64(0) // Activate Delta hardfork applyDeltaTimeOffset(dp, &minTs) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelError) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) @@ -598,7 +598,7 @@ func TestBatchEquivalence(gt *testing.T) { dp := e2eutils.MakeDeployParams(t, p) minTs := hexutil.Uint64(0) applyDeltaTimeOffset(dp, &minTs) - sdDeltaActivated := e2eutils.Setup(t, dp, defaultAlloc) + sdDeltaActivated := e2eutils.Setup(t, dp, DefaultAlloc) // Delta deactivated deploy config rcfg := *sdDeltaActivated.RollupCfg diff --git a/op-e2e/actions/sync_test.go b/op-e2e/actions/sync_test.go index 5f78739631cc..d2b34b1f06fa 100644 --- a/op-e2e/actions/sync_test.go +++ b/op-e2e/actions/sync_test.go @@ -65,9 +65,9 @@ func TestSyncBatchType(t *testing.T) { func DerivationWithFlakyL1RPC(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelError) // mute all the temporary derivation errors that we forcefully create _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) @@ -105,9 +105,9 @@ func DerivationWithFlakyL1RPC(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { func FinalizeWhileSyncing(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelError) // mute all the temporary derivation errors that we forcefully create _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) @@ -151,8 +151,8 @@ func FinalizeWhileSyncing(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // TestUnsafeSync tests that a verifier properly imports unsafe blocks via gossip. func TestUnsafeSync(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) - sd := e2eutils.Setup(t, dp, defaultAlloc) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelInfo) sd, _, _, sequencer, seqEng, verifier, _, _ := setupReorgTestActors(t, dp, sd, log) @@ -179,12 +179,12 @@ func TestUnsafeSync(gt *testing.T) { func TestBackupUnsafe(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) minTs := hexutil.Uint64(0) // Activate Delta hardfork applyDeltaTimeOffset(dp, &minTs) dp.DeployConfig.L2BlockTime = 2 - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LvlInfo) _, dp, miner, sequencer, seqEng, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) l2Cl := seqEng.EthClient() @@ -340,12 +340,12 @@ func TestBackupUnsafe(gt *testing.T) { func TestBackupUnsafeReorgForkChoiceInputError(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) minTs := hexutil.Uint64(0) // Activate Delta hardfork applyDeltaTimeOffset(dp, &minTs) dp.DeployConfig.L2BlockTime = 2 - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LvlInfo) _, dp, miner, sequencer, seqEng, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) l2Cl := seqEng.EthClient() @@ -473,12 +473,12 @@ func TestBackupUnsafeReorgForkChoiceInputError(gt *testing.T) { func TestBackupUnsafeReorgForkChoiceNotInputError(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) minTs := hexutil.Uint64(0) // Activate Delta hardfork applyDeltaTimeOffset(dp, &minTs) dp.DeployConfig.L2BlockTime = 2 - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LvlInfo) _, dp, miner, sequencer, seqEng, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) l2Cl := seqEng.EthClient() @@ -692,8 +692,8 @@ func BatchSubmitBlock(t Testing, miner *L1Miner, sequencer *L2Sequencer, verifie // when passed a single unsafe block. op-geth can either snap sync or full sync here. func TestELSync(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) - sd := e2eutils.Setup(t, dp, defaultAlloc) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelInfo) miner, seqEng, sequencer := setupSequencerTest(t, sd, log) @@ -745,8 +745,8 @@ func PrepareELSyncedNode(t Testing, miner *L1Miner, sequencer *L2Sequencer, seqE // 8. Create 1 more block & batch submit everything & assert that the verifier picked up those blocks func TestELSyncTransitionstoCL(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) - sd := e2eutils.Setup(t, dp, defaultAlloc) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + sd := e2eutils.Setup(t, dp, DefaultAlloc) logger := testlog.Logger(t, log.LevelInfo) captureLog, captureLogHandler := testlog.CaptureLogger(t, log.LevelInfo) @@ -802,8 +802,8 @@ func TestELSyncTransitionstoCL(gt *testing.T) { func TestELSyncTransitionsToCLSyncAfterNodeRestart(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) - sd := e2eutils.Setup(t, dp, defaultAlloc) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + sd := e2eutils.Setup(t, dp, DefaultAlloc) logger := testlog.Logger(t, log.LevelInfo) captureLog, captureLogHandler := testlog.CaptureLogger(t, log.LevelInfo) @@ -819,7 +819,7 @@ func TestELSyncTransitionsToCLSyncAfterNodeRestart(gt *testing.T) { PrepareELSyncedNode(t, miner, sequencer, seqEng, verifier, verEng, seqEngCl, batcher, dp) // Create a new verifier which is essentially a new op-node with the sync mode of ELSync and default geth engine kind. - verifier = NewL2Verifier(t, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), altda.Disabled, verifier.eng, sd.RollupCfg, &sync.Config{SyncMode: sync.ELSync}, defaultVerifierCfg().safeHeadListener, nil) + verifier = NewL2Verifier(t, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), altda.Disabled, verifier.eng, sd.RollupCfg, &sync.Config{SyncMode: sync.ELSync}, DefaultVerifierCfg().SafeHeadListener, nil) // Build another 10 L1 blocks on the sequencer for i := 0; i < 10; i++ { @@ -844,8 +844,8 @@ func TestELSyncTransitionsToCLSyncAfterNodeRestart(gt *testing.T) { func TestForcedELSyncCLAfterNodeRestart(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) - sd := e2eutils.Setup(t, dp, defaultAlloc) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + sd := e2eutils.Setup(t, dp, DefaultAlloc) logger := testlog.Logger(t, log.LevelInfo) captureLog, captureLogHandler := testlog.CaptureLogger(t, log.LevelInfo) @@ -861,7 +861,7 @@ func TestForcedELSyncCLAfterNodeRestart(gt *testing.T) { PrepareELSyncedNode(t, miner, sequencer, seqEng, verifier, verEng, seqEngCl, batcher, dp) // Create a new verifier which is essentially a new op-node with the sync mode of ELSync and erigon engine kind. - verifier2 := NewL2Verifier(t, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), altda.Disabled, verifier.eng, sd.RollupCfg, &sync.Config{SyncMode: sync.ELSync, SupportsPostFinalizationELSync: true}, defaultVerifierCfg().safeHeadListener, nil) + verifier2 := NewL2Verifier(t, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), altda.Disabled, verifier.eng, sd.RollupCfg, &sync.Config{SyncMode: sync.ELSync, SupportsPostFinalizationELSync: true}, DefaultVerifierCfg().SafeHeadListener, nil) // Build another 10 L1 blocks on the sequencer for i := 0; i < 10; i++ { @@ -890,12 +890,12 @@ func TestForcedELSyncCLAfterNodeRestart(gt *testing.T) { func TestInvalidPayloadInSpanBatch(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) minTs := hexutil.Uint64(0) // Activate Delta hardfork applyDeltaTimeOffset(dp, &minTs) dp.DeployConfig.L2BlockTime = 2 - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelInfo) _, _, miner, sequencer, seqEng, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) l2Cl := seqEng.EthClient() @@ -995,12 +995,12 @@ func TestInvalidPayloadInSpanBatch(gt *testing.T) { func TestSpanBatchAtomicity_Consolidation(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) minTs := hexutil.Uint64(0) // Activate Delta hardfork applyDeltaTimeOffset(dp, &minTs) dp.DeployConfig.L2BlockTime = 2 - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelInfo) _, _, miner, sequencer, seqEng, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) seqEngCl, err := sources.NewEngineClient(seqEng.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) @@ -1063,12 +1063,12 @@ func TestSpanBatchAtomicity_Consolidation(gt *testing.T) { func TestSpanBatchAtomicity_ForceAdvance(gt *testing.T) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) minTs := hexutil.Uint64(0) // Activate Delta hardfork applyDeltaTimeOffset(dp, &minTs) dp.DeployConfig.L2BlockTime = 2 - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelInfo) _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) diff --git a/op-e2e/actions/system_config_test.go b/op-e2e/actions/system_config_test.go index 452d5dbc300b..406ca0a16983 100644 --- a/op-e2e/actions/system_config_test.go +++ b/op-e2e/actions/system_config_test.go @@ -51,10 +51,10 @@ func TestSystemConfigBatchType(t *testing.T) { func BatcherKeyRotation(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) dp.DeployConfig.L2BlockTime = 2 applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) miner.ActL1SetFeeRecipient(common.Address{'A'}) @@ -226,7 +226,7 @@ func BatcherKeyRotation(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // and that the L1 data fees to the L2 transaction are applied correctly before, during and after the GPO update in L2. func GPOParamsChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) applyDeltaTimeOffset(dp, deltaTimeOffset) // activating Delta only, not Ecotone and further: @@ -236,7 +236,7 @@ func GPOParamsChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { dp.DeployConfig.L2GenesisFjordTimeOffset = nil dp.DeployConfig.L2GenesisGraniteTimeOffset = nil - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), @@ -361,9 +361,9 @@ func GPOParamsChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // the gas limit change event. And checks if a verifier node can reproduce the same gas limit change. func GasLimitChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), diff --git a/op-e2e/actions/user_test.go b/op-e2e/actions/user_test.go index 3a0b079cb3e4..8bb1b042c9a3 100644 --- a/op-e2e/actions/user_test.go +++ b/op-e2e/actions/user_test.go @@ -109,7 +109,7 @@ func TestCrossLayerUser(t *testing.T) { func runCrossLayerUserTest(gt *testing.T, test hardforkScheduledTest) { t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) // This overwrites all deploy-config settings, // so even when the deploy-config defaults change, we test the right transitions. dp.DeployConfig.L2GenesisRegolithTimeOffset = test.regolithTime @@ -125,7 +125,7 @@ func runCrossLayerUserTest(gt *testing.T, test hardforkScheduledTest) { require.Zero(t, uint64(*test.ecotoneTime)%uint64(dp.DeployConfig.L2BlockTime), "ecotone fork must be aligned") } - sd := e2eutils.Setup(t, dp, defaultAlloc) + sd := e2eutils.Setup(t, dp, DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) require.Equal(t, dp.Secrets.Addresses().Batcher, dp.DeployConfig.BatchSenderAddress) diff --git a/op-e2e/actions/utils.go b/op-e2e/actions/utils.go new file mode 100644 index 000000000000..aa03db3e29b5 --- /dev/null +++ b/op-e2e/actions/utils.go @@ -0,0 +1,79 @@ +package actions + +import ( + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-node/node/safedb" + "github.com/ethereum-optimism/optimism/op-node/rollup/interop" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" +) + +var DefaultRollupTestParams = &e2eutils.TestParams{ + MaxSequencerDrift: 40, + SequencerWindowSize: 120, + ChannelTimeout: 120, + L1BlockTime: 15, +} + +var DefaultAlloc = &e2eutils.AllocParams{PrefundTestUsers: true} + +type VerifierCfg struct { + SafeHeadListener safeDB + InteropBackend interop.InteropBackend +} + +type VerifierOpt func(opts *VerifierCfg) + +func WithSafeHeadListener(l safeDB) VerifierOpt { + return func(opts *VerifierCfg) { + opts.SafeHeadListener = l + } +} + +func WithInteropBackend(b interop.InteropBackend) VerifierOpt { + return func(opts *VerifierCfg) { + opts.InteropBackend = b + } +} + +func DefaultVerifierCfg() *VerifierCfg { + return &VerifierCfg{ + SafeHeadListener: safedb.Disabled, + } +} + +func EngineWithP2P() EngineOption { + return func(ethCfg *ethconfig.Config, nodeCfg *node.Config) error { + p2pKey, err := crypto.GenerateKey() + if err != nil { + return err + } + nodeCfg.P2P = p2p.Config{ + MaxPeers: 100, + NoDiscovery: true, + ListenAddr: "127.0.0.1:0", + PrivateKey: p2pKey, + } + return nil + } +} + +type SequencerCfg struct { + VerifierCfg +} + +func DefaultSequencerConfig() *SequencerCfg { + return &SequencerCfg{VerifierCfg: *DefaultVerifierCfg()} +} + +type SequencerOpt func(opts *SequencerCfg) + +func WithVerifierOpts(opts ...VerifierOpt) SequencerOpt { + return func(cfg *SequencerCfg) { + for _, opt := range opts { + opt(&cfg.VerifierCfg) + } + } +} From e9337dbb4fd6deae6bdbda94f5178f4bad0c0f40 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Thu, 12 Sep 2024 11:46:29 +1000 Subject: [PATCH 111/264] proofs-tools: Include openssl and certs (#11865) --- ops/docker/proofs-tools/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ops/docker/proofs-tools/Dockerfile b/ops/docker/proofs-tools/Dockerfile index 884c3a5927b8..61f39c8af705 100644 --- a/ops/docker/proofs-tools/Dockerfile +++ b/ops/docker/proofs-tools/Dockerfile @@ -10,7 +10,7 @@ FROM --platform=$BUILDPLATFORM ghcr.io/anton-rs/kona/kona-fpp-asterisc:$KONA_VER FROM --platform=$BUILDPLATFORM ghcr.io/ethereum-optimism/asterisc/asterisc:$ASTERISC_VERSION AS asterisc FROM --platform=$BUILDPLATFORM ubuntu:22.04 AS proofs-tools -RUN apt-get update && apt-get install -y --no-install-recommends musl +RUN apt-get update && apt-get install -y --no-install-recommends musl openssl ca-certificates COPY --from=challenger /usr/local/bin/op-challenger /usr/local/bin/ COPY --from=challenger /usr/local/bin/cannon /usr/local/bin/ ENV OP_CHALLENGER_CANNON_BIN /usr/local/bin/cannon From 7ff5e6edb7b1c53dc2d6fc417e6fcd3fa4d1f9c4 Mon Sep 17 00:00:00 2001 From: Inphi Date: Wed, 11 Sep 2024 22:24:38 -0400 Subject: [PATCH 112/264] cannon: Fix GC emulation of Go programs (#11704) * cannon: Fix GC emulation of Go programs Improves Linux/MIPS32 emulation for Go programs that utilize the garbage collector and goroutine scheduling. This adds support for the following syscalls: - getpid - used by the go scheduler - clock_gettime - used by the go scheduler and for GC assists and to properly emulate time related operations such as `time.Sleep`. Note on GC assists: The Go GC relies on `clock_gettime` for GC "assists", whereby a mutator can perform a little bit of GC without waiting for the scheduler to do so. A monotonic clock (runtime.nanotime) is used to compute the current goroutine's compute budget. By modeling a MIPS32 CPU that runs at some clock speed (ex: 10 MHz), we can provide a consistent emulation of monotonic time needed by the Go runtime. All other clock_gettime flags are handled as unimplemented syscalls. * fix unsupported syscalls test * fix some review comments * address review comments * update snapshots * fuzz invalid memory proof * reduce test runtime * tweak realtime emulation * reduce test runtime * set a high timeout for heavy fuzz tests * simplify fuzz * fix heavy tests --- cannon/mipsevm/exec/memory.go | 19 +- cannon/mipsevm/exec/mips_syscalls.go | 43 ++- cannon/mipsevm/memory/memory.go | 14 + cannon/mipsevm/memory/memory_test.go | 8 + cannon/mipsevm/multithreaded/instrumented.go | 2 + .../multithreaded/instrumented_test.go | 59 ++-- cannon/mipsevm/multithreaded/mips.go | 25 +- .../multithreaded/testutil/expectations.go | 14 + cannon/mipsevm/tests/evm_common_test.go | 4 +- .../mipsevm/tests/evm_multithreaded_test.go | 108 +++++++- cannon/mipsevm/testutil/oracle.go | 11 +- cannon/testdata/example/alloc/main.go | 15 +- op-chain-ops/srcmap/solutil.go | 11 +- .../scripts/go-ffi/differential-testing.go | 51 +++- .../testing/test-heavy-fuzz-modified-tests.sh | 16 ++ packages/contracts-bedrock/semver-lock.json | 8 +- .../contracts-bedrock/snapshots/abi/MIPS.json | 5 + .../snapshots/abi/MIPS2.json | 10 + .../contracts-bedrock/src/cannon/MIPS.sol | 4 +- .../contracts-bedrock/src/cannon/MIPS2.sol | 46 +++- .../src/cannon/interfaces/IMIPS.sol | 2 + .../src/cannon/interfaces/IMIPS2.sol | 2 + .../src/cannon/libraries/CannonErrors.sol | 6 + .../src/cannon/libraries/MIPSMemory.sol | 45 +++- .../src/cannon/libraries/MIPSSyscalls.sol | 6 +- .../contracts-bedrock/test/cannon/MIPS.t.sol | 46 ++-- .../contracts-bedrock/test/cannon/MIPS2.t.sol | 253 ++++++++++++++++-- .../proofs/utils/DeploymentSummary.sol | 8 +- .../proofs/utils/DeploymentSummaryCode.sol | 10 +- .../utils/DeploymentSummaryFaultProofs.sol | 8 +- .../DeploymentSummaryFaultProofsCode.sol | 10 +- .../test/setup/FFIInterface.sol | 50 ++++ 32 files changed, 786 insertions(+), 133 deletions(-) diff --git a/cannon/mipsevm/exec/memory.go b/cannon/mipsevm/exec/memory.go index d006a6f90560..3dea28dce29b 100644 --- a/cannon/mipsevm/exec/memory.go +++ b/cannon/mipsevm/exec/memory.go @@ -14,7 +14,10 @@ type MemoryTrackerImpl struct { memory *memory.Memory lastMemAccess uint32 memProofEnabled bool - memProof [memory.MEM_PROOF_SIZE]byte + // proof of first unique memory access + memProof [memory.MEM_PROOF_SIZE]byte + // proof of second unique memory access + memProof2 [memory.MEM_PROOF_SIZE]byte } func NewMemoryTracker(memory *memory.Memory) *MemoryTrackerImpl { @@ -31,6 +34,16 @@ func (m *MemoryTrackerImpl) TrackMemAccess(effAddr uint32) { } } +// TrackMemAccess2 creates a proof for a memory access following a call to TrackMemAccess +// This is used to generate proofs for contiguous memory accesses within the same step +func (m *MemoryTrackerImpl) TrackMemAccess2(effAddr uint32) { + if m.memProofEnabled && m.lastMemAccess+4 != effAddr { + panic(fmt.Errorf("unexpected disjointed mem access at %08x, last memory access is at %08x buffered", effAddr, m.lastMemAccess)) + } + m.lastMemAccess = effAddr + m.memProof2 = m.memory.MerkleProof(effAddr) +} + func (m *MemoryTrackerImpl) Reset(enableProof bool) { m.memProofEnabled = enableProof m.lastMemAccess = ^uint32(0) @@ -39,3 +52,7 @@ func (m *MemoryTrackerImpl) Reset(enableProof bool) { func (m *MemoryTrackerImpl) MemProof() [memory.MEM_PROOF_SIZE]byte { return m.memProof } + +func (m *MemoryTrackerImpl) MemProof2() [memory.MEM_PROOF_SIZE]byte { + return m.memProof2 +} diff --git a/cannon/mipsevm/exec/mips_syscalls.go b/cannon/mipsevm/exec/mips_syscalls.go index d2f49f279573..33a8e489bdb7 100644 --- a/cannon/mipsevm/exec/mips_syscalls.go +++ b/cannon/mipsevm/exec/mips_syscalls.go @@ -14,19 +14,21 @@ import ( // Syscall codes const ( - SysMmap = 4090 - SysBrk = 4045 - SysClone = 4120 - SysExitGroup = 4246 - SysRead = 4003 - SysWrite = 4004 - SysFcntl = 4055 - SysExit = 4001 - SysSchedYield = 4162 - SysGetTID = 4222 - SysFutex = 4238 - SysOpen = 4005 - SysNanosleep = 4166 + SysMmap = 4090 + SysBrk = 4045 + SysClone = 4120 + SysExitGroup = 4246 + SysRead = 4003 + SysWrite = 4004 + SysFcntl = 4055 + SysExit = 4001 + SysSchedYield = 4162 + SysGetTID = 4222 + SysFutex = 4238 + SysOpen = 4005 + SysNanosleep = 4166 + SysClockGetTime = 4263 + SysGetpid = 4020 ) // Noop Syscall codes @@ -67,7 +69,6 @@ const ( SysTimerCreate = 4257 SysTimerSetTime = 4258 SysTimerDelete = 4261 - SysClockGetTime = 4263 ) // File descriptors @@ -132,7 +133,21 @@ const ( // Other constants const ( + // SchedQuantum is the number of steps dedicated for a thread before it's preempted. Effectively used to emulate thread "time slices" SchedQuantum = 100_000 + + // HZ is the assumed clock rate of an emulated MIPS32 CPU. + // The value of HZ is a rough estimate of the Cannon instruction count / second on a typical machine. + // HZ is used to emulate the clock_gettime syscall used by guest programs that have a Go runtime. + // The Go runtime consumes the system time to determine when to initiate gc assists and for goroutine scheduling. + // A HZ value that is too low (i.e. lower than the emulation speed) results in the main goroutine attempting to assist with GC more often. + // Adjust this value accordingly as the emulation speed changes. The HZ value should be within the same order of magnitude as the emulation speed. + HZ = 10_000_000 + + // ClockGettimeRealtimeFlag is the clock_gettime clock id for Linux's realtime clock: https://github.com/torvalds/linux/blob/ad618736883b8970f66af799e34007475fe33a68/include/uapi/linux/time.h#L49 + ClockGettimeRealtimeFlag = 0 + // ClockGettimeMonotonicFlag is the clock_gettime clock id for Linux's monotonic clock: https://github.com/torvalds/linux/blob/ad618736883b8970f66af799e34007475fe33a68/include/uapi/linux/time.h#L50 + ClockGettimeMonotonicFlag = 1 ) func GetSyscallArgs(registers *[32]uint32) (syscallNum, a0, a1, a2, a3 uint32) { diff --git a/cannon/mipsevm/memory/memory.go b/cannon/mipsevm/memory/memory.go index c7100ea22b53..392a0482c48e 100644 --- a/cannon/mipsevm/memory/memory.go +++ b/cannon/mipsevm/memory/memory.go @@ -328,6 +328,20 @@ func (m *Memory) Deserialize(in io.Reader) error { return nil } +func (m *Memory) Copy() *Memory { + out := NewMemory() + out.nodes = make(map[uint64]*[32]byte) + out.pages = make(map[uint32]*CachedPage) + out.lastPageKeys = [2]uint32{^uint32(0), ^uint32(0)} + out.lastPage = [2]*CachedPage{nil, nil} + for k, page := range m.pages { + data := new(Page) + *data = *page.Data + out.AllocPage(k).Data = data + } + return out +} + type memReader struct { m *Memory addr uint32 diff --git a/cannon/mipsevm/memory/memory_test.go b/cannon/mipsevm/memory/memory_test.go index a2b0e745562b..5f3f9301e552 100644 --- a/cannon/mipsevm/memory/memory_test.go +++ b/cannon/mipsevm/memory/memory_test.go @@ -187,3 +187,11 @@ func TestMemoryJSON(t *testing.T) { require.NoError(t, json.Unmarshal(dat, &res)) require.Equal(t, uint32(123), res.GetMemory(8)) } + +func TestMemoryCopy(t *testing.T) { + m := NewMemory() + m.SetMemory(0x8000, 123) + mcpy := m.Copy() + require.Equal(t, uint32(123), mcpy.GetMemory(0x8000)) + require.Equal(t, m.MerkleRoot(), mcpy.MerkleRoot()) +} diff --git a/cannon/mipsevm/multithreaded/instrumented.go b/cannon/mipsevm/multithreaded/instrumented.go index 1928e26004b1..ac76d6cdb532 100644 --- a/cannon/mipsevm/multithreaded/instrumented.go +++ b/cannon/mipsevm/multithreaded/instrumented.go @@ -73,7 +73,9 @@ func (m *InstrumentedState) Step(proof bool) (wit *mipsevm.StepWitness, err erro if proof { memProof := m.memoryTracker.MemProof() + memProof2 := m.memoryTracker.MemProof2() wit.ProofData = append(wit.ProofData, memProof[:]...) + wit.ProofData = append(wit.ProofData, memProof2[:]...) lastPreimageKey, lastPreimage, lastPreimageOffset := m.preimageOracle.LastPreimage() if lastPreimageOffset != ^uint32(0) { wit.PreimageOffset = lastPreimageOffset diff --git a/cannon/mipsevm/multithreaded/instrumented_test.go b/cannon/mipsevm/multithreaded/instrumented_test.go index 800bdf836c63..403897a9723d 100644 --- a/cannon/mipsevm/multithreaded/instrumented_test.go +++ b/cannon/mipsevm/multithreaded/instrumented_test.go @@ -19,19 +19,23 @@ func vmFactory(state *State, po mipsevm.PreimageOracle, stdOut, stdErr io.Writer } func TestInstrumentedState_OpenMips(t *testing.T) { + t.Parallel() // TODO(cp-903): Add mt-specific tests here testutil.RunVMTests_OpenMips(t, CreateEmptyState, vmFactory, "clone.bin") } func TestInstrumentedState_Hello(t *testing.T) { + t.Parallel() testutil.RunVMTest_Hello(t, CreateInitialState, vmFactory, false) } func TestInstrumentedState_Claim(t *testing.T) { + t.Parallel() testutil.RunVMTest_Claim(t, CreateInitialState, vmFactory, false) } func TestInstrumentedState_MultithreadedProgram(t *testing.T) { + t.Parallel() state, _ := testutil.LoadELFProgram(t, "../../testdata/example/bin/multithreaded.elf", CreateInitialState, false) oracle := testutil.StaticOracle(t, []byte{}) @@ -54,26 +58,43 @@ func TestInstrumentedState_MultithreadedProgram(t *testing.T) { } func TestInstrumentedState_Alloc(t *testing.T) { - t.Skip("TODO(client-pod#906): Currently failing - need to debug.") + const MiB = 1024 * 1024 - state, _ := testutil.LoadELFProgram(t, "../../testdata/example/bin/alloc.elf", CreateInitialState, false) - const numAllocs = 100 // where each alloc is a 32 MiB chunk - oracle := testutil.AllocOracle(t, numAllocs) + cases := []struct { + name string + numAllocs int + allocSize int + maxMemoryUsageCheck int + }{ + {name: "10 32MiB allocations", numAllocs: 10, allocSize: 32 * MiB, maxMemoryUsageCheck: 256 * MiB}, + {name: "5 64MiB allocations", numAllocs: 5, allocSize: 64 * MiB, maxMemoryUsageCheck: 256 * MiB}, + {name: "5 128MiB allocations", numAllocs: 5, allocSize: 128 * MiB, maxMemoryUsageCheck: 128 * 3 * MiB}, + } - // completes in ~870 M steps - us := NewInstrumentedState(state, oracle, os.Stdout, os.Stderr, testutil.CreateLogger(), nil) - for i := 0; i < 20_000_000_000; i++ { - if us.GetState().GetExited() { - break - } - _, err := us.Step(false) - require.NoError(t, err) - if state.Step%10_000_000 == 0 { - t.Logf("Completed %d steps", state.Step) - } + for _, test := range cases { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + state, _ := testutil.LoadELFProgram(t, "../../testdata/example/bin/alloc.elf", CreateInitialState, false) + oracle := testutil.AllocOracle(t, test.numAllocs, test.allocSize) + + us := NewInstrumentedState(state, oracle, os.Stdout, os.Stderr, testutil.CreateLogger(), nil) + // emulation shouldn't take more than 20 B steps + for i := 0; i < 20_000_000_000; i++ { + if us.GetState().GetExited() { + break + } + _, err := us.Step(false) + require.NoError(t, err) + if state.Step%10_000_000 == 0 { + t.Logf("Completed %d steps", state.Step) + } + } + memUsage := state.Memory.PageCount() * memory.PageSize + t.Logf("Completed in %d steps. cannon memory usage: %d KiB", state.Step, memUsage/1024/1024.0) + require.True(t, state.Exited, "must complete program") + require.Equal(t, uint8(0), state.ExitCode, "exit with 0") + require.Less(t, memUsage, test.maxMemoryUsageCheck, "memory allocation is too large") + }) } - t.Logf("Completed in %d steps", state.Step) - require.True(t, state.Exited, "must complete program") - require.Equal(t, uint8(0), state.ExitCode, "exit with 0") - require.Less(t, state.Memory.PageCount()*memory.PageSize, 1*1024*1024*1024, "must not allocate more than 1 GiB") } diff --git a/cannon/mipsevm/multithreaded/mips.go b/cannon/mipsevm/multithreaded/mips.go index 8f7b594fcab8..73eb33c03a81 100644 --- a/cannon/mipsevm/multithreaded/mips.go +++ b/cannon/mipsevm/multithreaded/mips.go @@ -143,6 +143,30 @@ func (m *InstrumentedState) handleSyscall() error { case exec.SysOpen: v0 = exec.SysErrorSignal v1 = exec.MipsEBADF + case exec.SysClockGetTime: + switch a0 { + case exec.ClockGettimeRealtimeFlag, exec.ClockGettimeMonotonicFlag: + v0, v1 = 0, 0 + var secs, nsecs uint32 + if a0 == exec.ClockGettimeMonotonicFlag { + // monotonic clock_gettime is used by Go guest programs for goroutine scheduling and to implement + // `time.Sleep` (and other sleep related operations). + secs = uint32(m.state.Step / exec.HZ) + nsecs = uint32((m.state.Step % exec.HZ) * (1_000_000_000 / exec.HZ)) + } // else realtime set to Unix Epoch + + effAddr := a1 & 0xFFffFFfc + m.memoryTracker.TrackMemAccess(effAddr) + m.state.Memory.SetMemory(effAddr, secs) + m.memoryTracker.TrackMemAccess2(effAddr + 4) + m.state.Memory.SetMemory(effAddr+4, nsecs) + default: + v0 = exec.SysErrorSignal + v1 = exec.MipsEINVAL + } + case exec.SysGetpid: + v0 = 0 + v1 = 0 case exec.SysMunmap: case exec.SysGetAffinity: case exec.SysMadvise: @@ -173,7 +197,6 @@ func (m *InstrumentedState) handleSyscall() error { case exec.SysTimerCreate: case exec.SysTimerSetTime: case exec.SysTimerDelete: - case exec.SysClockGetTime: default: m.Traceback() panic(fmt.Sprintf("unrecognized syscall: %d", syscallNum)) diff --git a/cannon/mipsevm/multithreaded/testutil/expectations.go b/cannon/mipsevm/multithreaded/testutil/expectations.go index f2e1bbb200f0..56b5ee747c76 100644 --- a/cannon/mipsevm/multithreaded/testutil/expectations.go +++ b/cannon/mipsevm/multithreaded/testutil/expectations.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/stretchr/testify/require" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/memory" "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" ) @@ -33,6 +34,7 @@ type ExpectedMTState struct { prestateActiveThreadOrig ExpectedThreadState // Cached for internal use ActiveThreadId uint32 threadExpectations map[uint32]*ExpectedThreadState + memoryExpectations *memory.Memory } type ExpectedThreadState struct { @@ -81,6 +83,7 @@ func NewExpectedMTState(fromState *multithreaded.State) *ExpectedMTState { prestateActiveThreadOrig: *newExpectedThreadState(currentThread), // Cache prestate thread for internal use ActiveThreadId: currentThread.ThreadId, threadExpectations: expectedThreads, + memoryExpectations: fromState.Memory.Copy(), } } @@ -109,6 +112,17 @@ func (e *ExpectedMTState) ExpectStep() { e.StepsSinceLastContextSwitch += 1 } +func (e *ExpectedMTState) ExpectMemoryWrite(addr uint32, val uint32) { + e.memoryExpectations.SetMemory(addr, val) + e.MemoryRoot = e.memoryExpectations.MerkleRoot() +} + +func (e *ExpectedMTState) ExpectMemoryWriteMultiple(addr uint32, val uint32, addr2 uint32, val2 uint32) { + e.memoryExpectations.SetMemory(addr, val) + e.memoryExpectations.SetMemory(addr2, val) + e.MemoryRoot = e.memoryExpectations.MerkleRoot() +} + func (e *ExpectedMTState) ExpectPreemption(preState *multithreaded.State) { e.ActiveThreadId = FindNextThread(preState).ThreadId e.StepsSinceLastContextSwitch = 0 diff --git a/cannon/mipsevm/tests/evm_common_test.go b/cannon/mipsevm/tests/evm_common_test.go index 437501140f25..ea6c7b2de957 100644 --- a/cannon/mipsevm/tests/evm_common_test.go +++ b/cannon/mipsevm/tests/evm_common_test.go @@ -488,8 +488,8 @@ func TestHelloEVM(t *testing.T) { // verify the post-state matches. // TODO: maybe more readable to decode the evmPost state, and do attribute-wise comparison. goPost, _ := goVm.GetState().EncodeWitness() - require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), - "mipsevm produced different state than EVM") + require.Equalf(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), + "mipsevm produced different state than EVM. insn: %x", insn) } end := time.Now() delta := end.Sub(start) diff --git a/cannon/mipsevm/tests/evm_multithreaded_test.go b/cannon/mipsevm/tests/evm_multithreaded_test.go index 2730e8294a88..480dee57dfbb 100644 --- a/cannon/mipsevm/tests/evm_multithreaded_test.go +++ b/cannon/mipsevm/tests/evm_multithreaded_test.go @@ -558,6 +558,111 @@ func TestEVM_SysOpen(t *testing.T) { testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) } +func TestEVM_SysGetPID(t *testing.T) { + var tracer *tracing.Hooks + goVm, state, contracts := setup(t, 1929) + + state.Memory.SetMemory(state.GetPC(), syscallInsn) + state.GetRegistersRef()[2] = exec.SysGetpid // Set syscall number + step := state.Step + + // Set up post-state expectations + expected := mttestutil.NewExpectedMTState(state) + expected.ExpectStep() + expected.ActiveThread().Registers[2] = 0 + expected.ActiveThread().Registers[7] = 0 + + // State transition + var err error + var stepWitness *mipsevm.StepWitness + stepWitness, err = goVm.Step(true) + require.NoError(t, err) + + // Validate post-state + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) +} + +func TestEVM_SysClockGettimeMonotonic(t *testing.T) { + testEVM_SysClockGettime(t, exec.ClockGettimeMonotonicFlag) +} + +func TestEVM_SysClockGettimeRealtime(t *testing.T) { + testEVM_SysClockGettime(t, exec.ClockGettimeRealtimeFlag) +} + +func testEVM_SysClockGettime(t *testing.T, clkid uint32) { + var tracer *tracing.Hooks + + cases := []struct { + name string + timespecAddr uint32 + }{ + {"aligned timespec address", 0x1000}, + {"unaligned timespec address", 0x1003}, + } + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + goVm, state, contracts := setup(t, 2101) + + state.Memory.SetMemory(state.GetPC(), syscallInsn) + state.GetRegistersRef()[2] = exec.SysClockGetTime // Set syscall number + state.GetRegistersRef()[4] = clkid // a0 + state.GetRegistersRef()[5] = c.timespecAddr // a1 + step := state.Step + + expected := mttestutil.NewExpectedMTState(state) + expected.ExpectStep() + expected.ActiveThread().Registers[2] = 0 + expected.ActiveThread().Registers[7] = 0 + next := state.Step + 1 + var secs, nsecs uint32 + if clkid == exec.ClockGettimeMonotonicFlag { + secs = uint32(next / exec.HZ) + nsecs = uint32((next % exec.HZ) * (1_000_000_000 / exec.HZ)) + } + effAddr := c.timespecAddr & 0xFFffFFfc + expected.ExpectMemoryWrite(effAddr, secs) + expected.ExpectMemoryWrite(effAddr+4, nsecs) + + var err error + var stepWitness *mipsevm.StepWitness + stepWitness, err = goVm.Step(true) + require.NoError(t, err) + + // Validate post-state + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) + }) + } +} + +func TestEVM_SysClockGettimeNonMonotonic(t *testing.T) { + var tracer *tracing.Hooks + goVm, state, contracts := setup(t, 2101) + + timespecAddr := uint32(0x1000) + state.Memory.SetMemory(state.GetPC(), syscallInsn) + state.GetRegistersRef()[2] = exec.SysClockGetTime // Set syscall number + state.GetRegistersRef()[4] = 0xDEAD // a0 - invalid clockid + state.GetRegistersRef()[5] = timespecAddr // a1 + step := state.Step + + expected := mttestutil.NewExpectedMTState(state) + expected.ExpectStep() + expected.ActiveThread().Registers[2] = exec.SysErrorSignal + expected.ActiveThread().Registers[7] = exec.MipsEINVAL + + var err error + var stepWitness *mipsevm.StepWitness + stepWitness, err = goVm.Step(true) + require.NoError(t, err) + + // Validate post-state + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) +} + var NoopSyscalls = map[string]uint32{ "SysGetAffinity": 4240, "SysMadvise": 4218, @@ -589,7 +694,6 @@ var NoopSyscalls = map[string]uint32{ "SysTimerCreate": 4257, "SysTimerSetTime": 4258, "SysTimerDelete": 4261, - "SysClockGetTime": 4263, } func TestEVM_NoopSyscall(t *testing.T) { @@ -627,7 +731,7 @@ func TestEVM_UnsupportedSyscall(t *testing.T) { var tracer *tracing.Hooks var NoopSyscallNums = maps.Values(NoopSyscalls) - var SupportedSyscalls = []uint32{exec.SysMmap, exec.SysBrk, exec.SysClone, exec.SysExitGroup, exec.SysRead, exec.SysWrite, exec.SysFcntl, exec.SysExit, exec.SysSchedYield, exec.SysGetTID, exec.SysFutex, exec.SysOpen, exec.SysNanosleep} + var SupportedSyscalls = []uint32{exec.SysMmap, exec.SysBrk, exec.SysClone, exec.SysExitGroup, exec.SysRead, exec.SysWrite, exec.SysFcntl, exec.SysExit, exec.SysSchedYield, exec.SysGetTID, exec.SysFutex, exec.SysOpen, exec.SysNanosleep, exec.SysClockGetTime, exec.SysGetpid} unsupportedSyscalls := make([]uint32, 0, 400) for i := 4000; i < 4400; i++ { candidate := uint32(i) diff --git a/cannon/mipsevm/testutil/oracle.go b/cannon/mipsevm/testutil/oracle.go index e0cd9baf6dff..64b0f31a897c 100644 --- a/cannon/mipsevm/testutil/oracle.go +++ b/cannon/mipsevm/testutil/oracle.go @@ -120,14 +120,19 @@ func ClaimTestOracle(t *testing.T) (po mipsevm.PreimageOracle, stdOut string, st return oracle, fmt.Sprintf("computing %d * %d + %d\nclaim %d is good!\n", s, a, b, s*a+b), "started!" } -func AllocOracle(t *testing.T, numAllocs int) *TestOracle { +func AllocOracle(t *testing.T, numAllocs int, allocSize int) *TestOracle { return &TestOracle{ hint: func(v []byte) {}, getPreimage: func(k [32]byte) []byte { - if k != preimage.LocalIndexKey(0).PreimageKey() { + switch k { + case preimage.LocalIndexKey(0).PreimageKey(): + return binary.LittleEndian.AppendUint64(nil, uint64(numAllocs)) + case preimage.LocalIndexKey(1).PreimageKey(): + return binary.LittleEndian.AppendUint64(nil, uint64(allocSize)) + default: t.Fatalf("invalid preimage request for %x", k) } - return binary.LittleEndian.AppendUint64(nil, uint64(numAllocs)) + panic("unreachable") }, } } diff --git a/cannon/testdata/example/alloc/main.go b/cannon/testdata/example/alloc/main.go index 41bc67000d2b..3c7af2f165f5 100644 --- a/cannon/testdata/example/alloc/main.go +++ b/cannon/testdata/example/alloc/main.go @@ -12,20 +12,27 @@ func main() { var mem []byte po := preimage.NewOracleClient(preimage.ClientPreimageChannel()) numAllocs := binary.LittleEndian.Uint64(po.Get(preimage.LocalIndexKey(0))) + allocSize := binary.LittleEndian.Uint64(po.Get(preimage.LocalIndexKey(1))) - fmt.Printf("alloc program. numAllocs=%d\n", numAllocs) + fmt.Printf("alloc program. numAllocs=%d allocSize=%d\n", numAllocs, allocSize) var alloc int for i := 0; i < int(numAllocs); i++ { - mem = make([]byte, 32*1024*1024) + mem = make([]byte, allocSize) alloc += len(mem) // touch a couple pages to prevent the runtime from overcommitting memory for j := 0; j < len(mem); j += 1024 { mem[j] = 0xFF } - fmt.Printf("allocated %d bytes\n", alloc) + printGCStats(alloc) } + fmt.Println("alloc program exit") + printGCStats(alloc) +} + +func printGCStats(alloc int) { var m runtime.MemStats runtime.ReadMemStats(&m) - fmt.Printf("alloc program exit. memstats: heap_alloc=%d frees=%d mallocs=%d\n", m.HeapAlloc, m.Frees, m.Mallocs) + fmt.Printf("allocated %d bytes. memstats: heap_alloc=%d next_gc=%d frees=%d mallocs=%d num_gc=%d\n", + alloc, m.HeapAlloc, m.NextGC, m.Frees, m.Mallocs, m.NumGC) } diff --git a/op-chain-ops/srcmap/solutil.go b/op-chain-ops/srcmap/solutil.go index 6566144a819b..6d1aa4c64a3e 100644 --- a/op-chain-ops/srcmap/solutil.go +++ b/op-chain-ops/srcmap/solutil.go @@ -239,8 +239,15 @@ func (s *SourceMapTracer) info(codeAddr common.Address, pc uint64) string { func (s *SourceMapTracer) OnOpCode(pc uint64, opcode byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) { op := vm.OpCode(opcode) if op.IsPush() { - start := uint64(op) - uint64(vm.PUSH1) + 1 - val := scope.StackData()[:start] + var val []byte + sc, ok := scope.(*vm.ScopeContext) + if ok { + start := pc + 1 + end := uint64(op) - uint64(vm.PUSH1) + 1 + val = sc.Contract.Code[start : start+end] + } else { + val = []byte("N/A") + } fmt.Fprintf(s.out, "%-40s : pc %x opcode %s (%x)\n", s.info(scope.Address(), pc), pc, op.String(), val) return } diff --git a/packages/contracts-bedrock/scripts/go-ffi/differential-testing.go b/packages/contracts-bedrock/scripts/go-ffi/differential-testing.go index 3186c88b0cba..af4deae5c09c 100644 --- a/packages/contracts-bedrock/scripts/go-ffi/differential-testing.go +++ b/packages/contracts-bedrock/scripts/go-ffi/differential-testing.go @@ -359,10 +359,11 @@ func DiffTestUtils() { // Print the output fmt.Print(hexutil.Encode(packed[32:])) case "cannonMemoryProof": - // + // + // Generates a memory proof of `memAddr` for a trie containing memValue and memValue2 mem := memory.NewMemory() - if len(args) != 3 && len(args) != 5 { - panic("Error: cannonMemoryProofWithProof requires 2 or 4 arguments") + if len(args) != 3 && len(args) != 5 && len(args) != 7 { + panic("Error: cannonMemoryProofWithProof requires 2, 4, or 6 arguments") } pc, err := strconv.ParseUint(args[1], 10, 32) checkErr(err, "Error decoding addr") @@ -371,7 +372,7 @@ func DiffTestUtils() { mem.SetMemory(uint32(pc), uint32(insn)) var insnProof, memProof [896]byte - if len(args) == 5 { + if len(args) >= 5 { memAddr, err := strconv.ParseUint(args[3], 10, 32) checkErr(err, "Error decoding memAddr") memValue, err := strconv.ParseUint(args[4], 10, 32) @@ -379,6 +380,14 @@ func DiffTestUtils() { mem.SetMemory(uint32(memAddr), uint32(memValue)) memProof = mem.MerkleProof(uint32(memAddr)) } + if len(args) == 7 { + memAddr, err := strconv.ParseUint(args[5], 10, 32) + checkErr(err, "Error decoding memAddr") + memValue, err := strconv.ParseUint(args[6], 10, 32) + checkErr(err, "Error decoding memValue") + mem.SetMemory(uint32(memAddr), uint32(memValue)) + memProof = mem.MerkleProof(uint32(memAddr)) + } insnProof = mem.MerkleProof(uint32(pc)) output := struct { @@ -391,6 +400,40 @@ func DiffTestUtils() { packed, err := cannonMemoryProofArgs.Pack(&output) checkErr(err, "Error encoding output") fmt.Print(hexutil.Encode(packed[32:])) + case "cannonMemoryProof2": + // + // Generates a memory proof of memAddr2 for a trie containing memValue + mem := memory.NewMemory() + if len(args) != 6 { + panic("Error: cannonMemoryProofWithProof2 requires 5 arguments") + } + pc, err := strconv.ParseUint(args[1], 10, 32) + checkErr(err, "Error decoding addr") + insn, err := strconv.ParseUint(args[2], 10, 32) + checkErr(err, "Error decoding insn") + mem.SetMemory(uint32(pc), uint32(insn)) + + var memProof [896]byte + memAddr, err := strconv.ParseUint(args[3], 10, 32) + checkErr(err, "Error decoding memAddr") + memValue, err := strconv.ParseUint(args[4], 10, 32) + checkErr(err, "Error decoding memValue") + mem.SetMemory(uint32(memAddr), uint32(memValue)) + + memAddr2, err := strconv.ParseUint(args[5], 10, 32) + checkErr(err, "Error decoding memAddr") + memProof = mem.MerkleProof(uint32(memAddr2)) + + output := struct { + MemRoot common.Hash + Proof []byte + }{ + MemRoot: mem.MerkleRoot(), + Proof: memProof[:], + } + packed, err := cannonMemoryProofArgs.Pack(&output) + checkErr(err, "Error encoding output") + fmt.Print(hexutil.Encode(packed[32:])) case "cannonMemoryProofWrongLeaf": // mem := memory.NewMemory() diff --git a/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh b/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh index 4974a01dedcd..6f8706366916 100755 --- a/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh +++ b/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh @@ -51,8 +51,24 @@ fi # Initialize an array to hold relevant function names. NEW_OR_MODIFIED_TEST_NAMES="" +# these tests are too expensive to run heavily +IGNORED_FUZZ_TESTS=("MIPS.t.sol" "MIPS2.t.sol") + # Process each changed file. for FILE in $CHANGED_FILES; do + IGNORED=false + for TEST in "${IGNORED_FUZZ_TESTS[@]}"; do + FILENAME=$(basename "$FILE") + if [[ "$TEST" == "$FILENAME" ]]; then + IGNORED=true + break + fi + done + if $IGNORED; then + echo "skipping $FILE" + continue + fi + # Get the diff for the file. DIFF=$(git diff origin/develop...HEAD --unified=0 -- "$FILE") diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 255c6cc3d07d..26872bdb2c73 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -144,12 +144,12 @@ "sourceCodeHash": "0x255a3f78036745feb57da2e16a93a83fe3f52944fec42029da9b9eaa147db11c" }, "src/cannon/MIPS.sol": { - "initCodeHash": "0xd151c45f4b4b2b96d111d37c78290bb461878df4481dbc4bfdd14428e177acc5", - "sourceCodeHash": "0x23543a88057256eb8fd3b4c52d82bb97e359134bd760bdf144e5f697307ce176" + "initCodeHash": "0x6add59adb849ec02e13b33df7efd439ca80f6a8ceefdf69ebcb0963c0167da23", + "sourceCodeHash": "0xee1aef5a502f9491b7b83dab46ea2f0fc286f87ace31edcc1367c840d462bdfe" }, "src/cannon/MIPS2.sol": { - "initCodeHash": "0xf5e2bca4ba0c504ffa68f1ce5fbf4349b1fa892034777d77803d9111aed279fa", - "sourceCodeHash": "0x3c3716ac78180fc71d67b0f849b2ec28891b2e065d33d4d70b4b7279a12d4b66" + "initCodeHash": "0x3430ef0ee7697e7b98589deffb3a303cd8ce73bdc69df2edc5c957cee7486a72", + "sourceCodeHash": "0xb05a2081aa93881871d08bd95610639dfb64e5d3ce0e8fa5fd212e7ae3c3fe60" }, "src/cannon/PreimageOracle.sol": { "initCodeHash": "0x801e52f9c8439fcf7089575fa93272dfb874641dbfc7d82f36d979c987271c0b", diff --git a/packages/contracts-bedrock/snapshots/abi/MIPS.json b/packages/contracts-bedrock/snapshots/abi/MIPS.json index 7053bcaca375..7741a95c6260 100644 --- a/packages/contracts-bedrock/snapshots/abi/MIPS.json +++ b/packages/contracts-bedrock/snapshots/abi/MIPS.json @@ -64,5 +64,10 @@ ], "stateMutability": "view", "type": "function" + }, + { + "inputs": [], + "name": "InvalidMemoryProof", + "type": "error" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/MIPS2.json b/packages/contracts-bedrock/snapshots/abi/MIPS2.json index 9782bf01819c..99ba9373513d 100644 --- a/packages/contracts-bedrock/snapshots/abi/MIPS2.json +++ b/packages/contracts-bedrock/snapshots/abi/MIPS2.json @@ -56,5 +56,15 @@ "inputs": [], "name": "InvalidExitedValue", "type": "error" + }, + { + "inputs": [], + "name": "InvalidMemoryProof", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSecondMemoryProof", + "type": "error" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/src/cannon/MIPS.sol b/packages/contracts-bedrock/src/cannon/MIPS.sol index a1f1113a7aab..8c2f1465756c 100644 --- a/packages/contracts-bedrock/src/cannon/MIPS.sol +++ b/packages/contracts-bedrock/src/cannon/MIPS.sol @@ -44,8 +44,8 @@ contract MIPS is ISemver { } /// @notice The semantic version of the MIPS contract. - /// @custom:semver 1.1.1-beta.2 - string public constant version = "1.1.1-beta.2"; + /// @custom:semver 1.1.1-beta.3 + string public constant version = "1.1.1-beta.3"; /// @notice The preimage oracle contract. IPreimageOracle internal immutable ORACLE; diff --git a/packages/contracts-bedrock/src/cannon/MIPS2.sol b/packages/contracts-bedrock/src/cannon/MIPS2.sol index da6c56b6f207..4f9135b801ec 100644 --- a/packages/contracts-bedrock/src/cannon/MIPS2.sol +++ b/packages/contracts-bedrock/src/cannon/MIPS2.sol @@ -8,6 +8,7 @@ import { MIPSSyscalls as sys } from "src/cannon/libraries/MIPSSyscalls.sol"; import { MIPSState as st } from "src/cannon/libraries/MIPSState.sol"; import { MIPSInstructions as ins } from "src/cannon/libraries/MIPSInstructions.sol"; import { VMStatuses } from "src/dispute/lib/Types.sol"; +import { InvalidMemoryProof, InvalidSecondMemoryProof } from "src/cannon/libraries/CannonErrors.sol"; /// @title MIPS2 /// @notice The MIPS2 contract emulates a single MIPS instruction. @@ -51,8 +52,8 @@ contract MIPS2 is ISemver { } /// @notice The semantic version of the MIPS2 contract. - /// @custom:semver 1.0.0-beta.6 - string public constant version = "1.0.0-beta.6"; + /// @custom:semver 1.0.0-beta.7 + string public constant version = "1.0.0-beta.7"; /// @notice The preimage oracle contract. IPreimageOracle internal immutable ORACLE; @@ -383,6 +384,45 @@ contract MIPS2 is ISemver { } else if (syscall_no == sys.SYS_OPEN) { v0 = sys.SYS_ERROR_SIGNAL; v1 = sys.EBADF; + } else if (syscall_no == sys.SYS_CLOCKGETTIME) { + if (a0 == sys.CLOCK_GETTIME_REALTIME_FLAG || a0 == sys.CLOCK_GETTIME_MONOTONIC_FLAG) { + v0 = 0; + v1 = 0; + uint32 secs = 0; + uint32 nsecs = 0; + if (a0 == sys.CLOCK_GETTIME_MONOTONIC_FLAG) { + secs = uint32(state.step / sys.HZ); + nsecs = uint32((state.step % sys.HZ) * (1_000_000_000 / sys.HZ)); + } + uint32 effAddr = a1 & 0xFFffFFfc; + // First verify the effAddr path + if ( + !MIPSMemory.isValidProof( + state.memRoot, effAddr, MIPSMemory.memoryProofOffset(MEM_PROOF_OFFSET, 1) + ) + ) { + revert InvalidMemoryProof(); + } + // Recompute the new root after updating effAddr + state.memRoot = + MIPSMemory.writeMem(effAddr, MIPSMemory.memoryProofOffset(MEM_PROOF_OFFSET, 1), secs); + // Verify the second memory proof against the newly computed root + if ( + !MIPSMemory.isValidProof( + state.memRoot, effAddr + 4, MIPSMemory.memoryProofOffset(MEM_PROOF_OFFSET, 2) + ) + ) { + revert InvalidSecondMemoryProof(); + } + state.memRoot = + MIPSMemory.writeMem(effAddr + 4, MIPSMemory.memoryProofOffset(MEM_PROOF_OFFSET, 2), nsecs); + } else { + v0 = sys.SYS_ERROR_SIGNAL; + v1 = sys.EINVAL; + } + } else if (syscall_no == sys.SYS_GETPID) { + v0 = 0; + v1 = 0; } else if (syscall_no == sys.SYS_MUNMAP) { // ignored } else if (syscall_no == sys.SYS_GETAFFINITY) { @@ -443,8 +483,6 @@ contract MIPS2 is ISemver { // ignored } else if (syscall_no == sys.SYS_TIMERDELETE) { // ignored - } else if (syscall_no == sys.SYS_CLOCKGETTIME) { - // ignored } else { revert("MIPS2: unimplemented syscall"); } diff --git a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS.sol b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS.sol index e98628c3eb5a..d96432c68096 100644 --- a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS.sol +++ b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS.sol @@ -7,6 +7,8 @@ import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol"; /// @title IMIPS /// @notice Interface for the MIPS contract. interface IMIPS is ISemver { + error InvalidMemoryProof(); + function oracle() external view returns (IPreimageOracle oracle_); function step(bytes memory _stateData, bytes memory _proof, bytes32 _localContext) external returns (bytes32); } diff --git a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol index 0e4f9b5eaa55..e4f3503b6809 100644 --- a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol +++ b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol @@ -7,6 +7,8 @@ import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @notice Interface for the MIPS2 contract. interface IMIPS2 is ISemver { error InvalidExitedValue(); + error InvalidMemoryProof(); + error InvalidSecondMemoryProof(); function step(bytes memory _stateData, bytes memory _proof, bytes32 _localContext) external returns (bytes32); } diff --git a/packages/contracts-bedrock/src/cannon/libraries/CannonErrors.sol b/packages/contracts-bedrock/src/cannon/libraries/CannonErrors.sol index e45cbaf9d8de..d8ecdfe2af9a 100644 --- a/packages/contracts-bedrock/src/cannon/libraries/CannonErrors.sol +++ b/packages/contracts-bedrock/src/cannon/libraries/CannonErrors.sol @@ -54,3 +54,9 @@ error BondTransferFailed(); /// @notice Thrown when the value of the exited boolean is not 0 or 1. error InvalidExitedValue(); + +/// @notice Thrown when reading an invalid memory +error InvalidMemoryProof(); + +/// @notice Thrown when the second memory location is invalid +error InvalidSecondMemoryProof(); diff --git a/packages/contracts-bedrock/src/cannon/libraries/MIPSMemory.sol b/packages/contracts-bedrock/src/cannon/libraries/MIPSMemory.sol index 12106ed23ecc..e88f51438ef4 100644 --- a/packages/contracts-bedrock/src/cannon/libraries/MIPSMemory.sol +++ b/packages/contracts-bedrock/src/cannon/libraries/MIPSMemory.sol @@ -1,6 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +import "src/cannon/libraries/CannonErrors.sol"; + library MIPSMemory { /// @notice Reads a 32-bit value from memory. /// @param _memRoot The current memory root @@ -8,6 +10,28 @@ library MIPSMemory { /// @param _proofOffset The offset of the memory proof in calldata. /// @return out_ The hashed MIPS state. function readMem(bytes32 _memRoot, uint32 _addr, uint256 _proofOffset) internal pure returns (uint32 out_) { + bool valid; + (out_, valid) = readMemUnchecked(_memRoot, _addr, _proofOffset); + if (!valid) { + revert InvalidMemoryProof(); + } + } + + /// @notice Reads a 32-bit value from memory. + /// @param _memRoot The current memory root + /// @param _addr The address to read from. + /// @param _proofOffset The offset of the memory proof in calldata. + /// @return out_ The hashed MIPS state. + /// valid_ Whether the proof is valid. + function readMemUnchecked( + bytes32 _memRoot, + uint32 _addr, + uint256 _proofOffset + ) + internal + pure + returns (uint32 out_, bool valid_) + { unchecked { validateMemoryProofAvailability(_proofOffset); assembly { @@ -38,14 +62,12 @@ library MIPSMemory { } // Verify the root matches. - if iszero(eq(node, _memRoot)) { - mstore(0, 0x0badf00d) - revert(0, 32) + valid_ := eq(node, _memRoot) + if valid_ { + // Bits to shift = (32 - 4 - (addr % 32)) * 8 + let shamt := shl(3, sub(sub(32, 4), and(_addr, 31))) + out_ := and(shr(shamt, leaf), 0xFFffFFff) } - - // Bits to shift = (32 - 4 - (addr % 32)) * 8 - let shamt := shl(3, sub(sub(32, 4), and(_addr, 31))) - out_ := and(shr(shamt, leaf), 0xFFffFFff) } } } @@ -97,6 +119,15 @@ library MIPSMemory { } } + /// @notice Verifies a memory proof. + /// @param _memRoot The expected memory root + /// @param _addr The _addr proven. + /// @param _proofOffset The offset of the memory proof in calldata. + /// @return valid_ True iff it is a valid proof. + function isValidProof(bytes32 _memRoot, uint32 _addr, uint256 _proofOffset) internal pure returns (bool valid_) { + (, valid_) = readMemUnchecked(_memRoot, _addr, _proofOffset); + } + /// @notice Computes the offset of a memory proof in the calldata. /// @param _proofDataOffset The offset of the set of all memory proof data within calldata (proof.offset) /// Equal to the offset of the first memory proof (at _proofIndex 0). diff --git a/packages/contracts-bedrock/src/cannon/libraries/MIPSSyscalls.sol b/packages/contracts-bedrock/src/cannon/libraries/MIPSSyscalls.sol index 0576dbc7ae2c..cf2d34a56a66 100644 --- a/packages/contracts-bedrock/src/cannon/libraries/MIPSSyscalls.sol +++ b/packages/contracts-bedrock/src/cannon/libraries/MIPSSyscalls.sol @@ -41,6 +41,8 @@ library MIPSSyscalls { uint32 internal constant SYS_FUTEX = 4238; uint32 internal constant SYS_OPEN = 4005; uint32 internal constant SYS_NANOSLEEP = 4166; + uint32 internal constant SYS_CLOCKGETTIME = 4263; + uint32 internal constant SYS_GETPID = 4020; // unused syscalls uint32 internal constant SYS_MUNMAP = 4091; uint32 internal constant SYS_GETAFFINITY = 4240; @@ -74,7 +76,6 @@ library MIPSSyscalls { uint32 internal constant SYS_TIMERCREATE = 4257; uint32 internal constant SYS_TIMERSETTIME = 4258; uint32 internal constant SYS_TIMERDELETE = 4261; - uint32 internal constant SYS_CLOCKGETTIME = 4263; uint32 internal constant FD_STDIN = 0; uint32 internal constant FD_STDOUT = 1; @@ -97,6 +98,9 @@ library MIPSSyscalls { uint32 internal constant FUTEX_EMPTY_ADDR = 0xFF_FF_FF_FF; uint32 internal constant SCHED_QUANTUM = 100_000; + uint32 internal constant HZ = 10_000_000; + uint32 internal constant CLOCK_GETTIME_REALTIME_FLAG = 0; + uint32 internal constant CLOCK_GETTIME_MONOTONIC_FLAG = 1; /// @notice Start of the data segment. uint32 internal constant PROGRAM_BREAK = 0x40000000; uint32 internal constant HEAP_END = 0x60000000; diff --git a/packages/contracts-bedrock/test/cannon/MIPS.t.sol b/packages/contracts-bedrock/test/cannon/MIPS.t.sol index 7cbee449d363..db74c713de07 100644 --- a/packages/contracts-bedrock/test/cannon/MIPS.t.sol +++ b/packages/contracts-bedrock/test/cannon/MIPS.t.sol @@ -6,7 +6,7 @@ import { MIPS } from "src/cannon/MIPS.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { MIPSInstructions } from "src/cannon/libraries/MIPSInstructions.sol"; import { MIPSSyscalls as sys } from "src/cannon/libraries/MIPSSyscalls.sol"; -import { InvalidExitedValue } from "src/cannon/libraries/CannonErrors.sol"; +import { InvalidExitedValue, InvalidMemoryProof } from "src/cannon/libraries/CannonErrors.sol"; import "src/dispute/lib/Types.sol"; contract MIPS_Test is CommonTest { @@ -63,26 +63,28 @@ contract MIPS_Test is CommonTest { /// @notice Tests that the mips step function fails when the value of the exited field is /// invalid (anything greater than 1). - /// @param _exited Value to set the exited field to. - function testFuzz_step_invalidExitedValue_fails(uint8 _exited) external { - // Make sure the value of _exited is invalid. - _exited = uint8(bound(uint256(_exited), 2, type(uint8).max)); - - // Rest of this stuff doesn't matter very much, just setting up some state to edit. - // Here just using the parameters for the ADD test below. - uint32 insn = encodespec(17, 18, 8, 0x20); - (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0); - - // Compute the encoded state and manipulate it. - bytes memory enc = encodeState(state); - assembly { - // Push offset by an additional 32 bytes (0x20) to account for length prefix - mstore8(add(add(enc, 0x20), 89), _exited) + function test_step_invalidExitedValue_fails() external { + // Bound to invalid exited values. + for (uint8 exited = 2; exited <= type(uint8).max && exited != 0;) { + // Rest of this stuff doesn't matter very much, just setting up some state to edit. + // Here just using the parameters for the ADD test below. + uint32 insn = encodespec(17, 18, 8, 0x20); + (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0); + + // Compute the encoded state and manipulate it. + bytes memory enc = encodeState(state); + assembly { + // Push offset by an additional 32 bytes (0x20) to account for length prefix + mstore8(add(add(enc, 0x20), 89), exited) + } + + // Call the step function and expect a revert. + vm.expectRevert(InvalidExitedValue.selector); + mips.step(enc, proof, 0); + unchecked { + exited++; + } } - - // Call the step function and expect a revert. - vm.expectRevert(InvalidExitedValue.selector); - mips.step(enc, proof, 0); } function test_add_succeeds() external { @@ -1658,7 +1660,7 @@ contract MIPS_Test is CommonTest { for (uint256 i = 0; i < proof.length; i++) { proof[i] = 0x0; } - vm.expectRevert(hex"000000000000000000000000000000000000000000000000000000000badf00d"); + vm.expectRevert(InvalidMemoryProof.selector); mips.step(encodeState(state), proof, 0); } @@ -1677,7 +1679,7 @@ contract MIPS_Test is CommonTest { state.registers[2] = 4246; // exit_group syscall state.registers[4] = 0x5; // a0 - vm.expectRevert(hex"000000000000000000000000000000000000000000000000000000000badf00d"); + vm.expectRevert(InvalidMemoryProof.selector); mips.step(encodeState(state), proof, 0); } diff --git a/packages/contracts-bedrock/test/cannon/MIPS2.t.sol b/packages/contracts-bedrock/test/cannon/MIPS2.t.sol index 82ac77ab920a..84ae9fb6b4f1 100644 --- a/packages/contracts-bedrock/test/cannon/MIPS2.t.sol +++ b/packages/contracts-bedrock/test/cannon/MIPS2.t.sol @@ -7,7 +7,7 @@ import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { MIPSSyscalls as sys } from "src/cannon/libraries/MIPSSyscalls.sol"; import { MIPSInstructions as ins } from "src/cannon/libraries/MIPSInstructions.sol"; import "src/dispute/lib/Types.sol"; -import { InvalidExitedValue } from "src/cannon/libraries/CannonErrors.sol"; +import { InvalidExitedValue, InvalidMemoryProof, InvalidSecondMemoryProof } from "src/cannon/libraries/CannonErrors.sol"; contract ThreadStack { bytes32 internal constant EMPTY_THREAD_ROOT = hex"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5"; @@ -195,30 +195,32 @@ contract MIPS2_Test is CommonTest { /// @notice Tests that the mips step function fails when the value of the exited field is /// invalid (anything greater than 1). - /// @param _exited Value to set the exited field to. - function testFuzz_step_invalidExitedValueInState_fails(uint8 _exited) external { - // Make sure the value of _exited is invalid. - _exited = uint8(bound(uint256(_exited), 2, type(uint8).max)); - - // Setup state - uint32 insn = encodespec(17, 18, 8, 0x20); // Arbitrary instruction: add t0, s1, s2 - (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = - constructMIPSState(0, insn, 0x4, 0); + function test_step_invalidExitedValueInState_fails() external { + // Bound to invalid exited values. + for (uint8 exited = 2; exited <= type(uint8).max && exited != 0;) { + // Setup state + uint32 insn = encodespec(17, 18, 8, 0x20); // Arbitrary instruction: add t0, s1, s2 + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = + constructMIPSState(0, insn, 0x4, 0); + + // Set up step data + bytes memory encodedThread = encodeThread(thread); + bytes memory threadWitness = abi.encodePacked(encodedThread, EMPTY_THREAD_ROOT); + bytes memory proofData = bytes.concat(threadWitness, memProof); + bytes memory stateData = encodeState(state); + assembly { + // Manipulate state data + // Push offset by an additional 32 bytes (0x20) to account for length prefix + mstore8(add(add(stateData, 0x20), 73), exited) + } - // Set up step data - bytes memory encodedThread = encodeThread(thread); - bytes memory threadWitness = abi.encodePacked(encodedThread, EMPTY_THREAD_ROOT); - bytes memory proofData = bytes.concat(threadWitness, memProof); - bytes memory stateData = encodeState(state); - assembly { - // Manipulate state data - // Push offset by an additional 32 bytes (0x20) to account for length prefix - mstore8(add(add(stateData, 0x20), 73), _exited) + // Call the step function and expect a revert. + vm.expectRevert(InvalidExitedValue.selector); + mips.step(stateData, proofData, 0); + unchecked { + exited++; + } } - - // Call the step function and expect a revert. - vm.expectRevert(InvalidExitedValue.selector); - mips.step(stateData, proofData, 0); } function test_invalidThreadWitness_reverts() public { @@ -595,6 +597,211 @@ contract MIPS2_Test is CommonTest { assertEq(postState, outputState(expect), "unexpected post state"); } + function test_syscallGetPid_succeeds() public { + uint32 insn = 0x0000000c; // syscall + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = + constructMIPSState(0, insn, 0x4, 0); + thread.registers[2] = sys.SYS_GETPID; + thread.registers[7] = 0xdead; + bytes memory threadWitness = abi.encodePacked(encodeThread(thread), EMPTY_THREAD_ROOT); + updateThreadStacks(state, thread); + + MIPS2.ThreadState memory expectThread = copyThread(thread); + expectThread.pc = thread.nextPC; + expectThread.nextPC = thread.nextPC + 4; + expectThread.registers[2] = 0x0; + expectThread.registers[7] = 0x0; + MIPS2.State memory expect = copyState(state); + expect.step = state.step + 1; + expect.stepsSinceLastContextSwitch = state.stepsSinceLastContextSwitch + 1; + expect.leftThreadStack = keccak256(abi.encodePacked(EMPTY_THREAD_ROOT, keccak256(encodeThread(expectThread)))); + + bytes32 postState = mips.step(encodeState(state), bytes.concat(threadWitness, memProof), 0); + assertEq(postState, outputState(expect), "unexpected post state"); + } + + /// @dev static unit test asserting that clock_gettime syscall for monotonic time succeeds + function test_syscallClockGettimeMonotonic_succeeds() public { + _test_syscallClockGettime_succeeds(sys.CLOCK_GETTIME_MONOTONIC_FLAG); + } + + /// @dev static unit test asserting that clock_gettime syscall for real time succeeds + function test_syscallClockGettimeRealtime_succeeds() public { + _test_syscallClockGettime_succeeds(sys.CLOCK_GETTIME_REALTIME_FLAG); + } + + function _test_syscallClockGettime_succeeds(uint32 clkid) internal { + uint32 pc = 0; + uint32 insn = 0x0000000c; // syscall + uint32 timespecAddr = 0xb000; + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory insnAndMemProof) = + constructMIPSState(pc, insn, timespecAddr, 0xbad); + state.step = 100_000_004; + thread.registers[2] = sys.SYS_CLOCKGETTIME; + thread.registers[A0_REG] = clkid; + thread.registers[A1_REG] = timespecAddr; + thread.registers[7] = 0xdead; + + uint32 secs = 0; + uint32 nsecs = 0; + if (clkid == sys.CLOCK_GETTIME_MONOTONIC_FLAG) { + secs = 10; + nsecs = 500; + } + bytes memory threadWitness = abi.encodePacked(encodeThread(thread), EMPTY_THREAD_ROOT); + updateThreadStacks(state, thread); + (, bytes memory memProof2) = ffi.getCannonMemoryProof2(pc, insn, timespecAddr, secs, timespecAddr + 4); + + MIPS2.State memory expect = copyState(state); + (expect.memRoot,) = ffi.getCannonMemoryProof(pc, insn, timespecAddr, secs, timespecAddr + 4, nsecs); + expect.step = state.step + 1; + expect.stepsSinceLastContextSwitch = state.stepsSinceLastContextSwitch + 1; + MIPS2.ThreadState memory expectThread = copyThread(thread); + expectThread.pc = thread.nextPC; + expectThread.nextPC = thread.nextPC + 4; + expectThread.registers[2] = 0x0; + expectThread.registers[7] = 0x0; + expect.leftThreadStack = keccak256(abi.encodePacked(EMPTY_THREAD_ROOT, keccak256(encodeThread(expectThread)))); + + bytes32 postState = mips.step(encodeState(state), bytes.concat(threadWitness, insnAndMemProof, memProof2), 0); + assertEq(postState, outputState(expect), "unexpected post state"); + } + + /// @dev static unit test asserting that clock_gettime syscall for monotonic time succeeds in writing to an + /// unaligned address + function test_syscallClockGettimeMonotonicUnaligned_succeeds() public { + _test_syscallClockGettimeUnaligned_succeeds(sys.CLOCK_GETTIME_MONOTONIC_FLAG); + } + + /// @dev static unit test asserting that clock_gettime syscall for real time succeeds in writing to an + /// unaligned address + function test_syscallClockGettimeRealtimeUnaligned_succeeds() public { + _test_syscallClockGettimeUnaligned_succeeds(sys.CLOCK_GETTIME_REALTIME_FLAG); + } + + function _test_syscallClockGettimeUnaligned_succeeds(uint32 clkid) internal { + uint32 pc = 0; + uint32 insn = 0x0000000c; // syscall + uint32 timespecAddr = 0xb001; + uint32 timespecAddrAligned = 0xb000; + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory insnAndMemProof) = + constructMIPSState(pc, insn, timespecAddrAligned, 0xbad); + state.step = 100_000_004; + thread.registers[2] = sys.SYS_CLOCKGETTIME; + thread.registers[A0_REG] = clkid; + thread.registers[A1_REG] = timespecAddr; + thread.registers[7] = 0xdead; + + uint32 secs = 0; + uint32 nsecs = 0; + if (clkid == sys.CLOCK_GETTIME_MONOTONIC_FLAG) { + secs = 10; + nsecs = 500; + } + bytes memory threadWitness = abi.encodePacked(encodeThread(thread), EMPTY_THREAD_ROOT); + updateThreadStacks(state, thread); + (, bytes memory memProof2) = + ffi.getCannonMemoryProof2(pc, insn, timespecAddrAligned, secs, timespecAddrAligned + 4); + + MIPS2.State memory expect = copyState(state); + (expect.memRoot,) = + ffi.getCannonMemoryProof(pc, insn, timespecAddrAligned, secs, timespecAddrAligned + 4, nsecs); + expect.step = state.step + 1; + expect.stepsSinceLastContextSwitch = state.stepsSinceLastContextSwitch + 1; + MIPS2.ThreadState memory expectThread = copyThread(thread); + expectThread.pc = thread.nextPC; + expectThread.nextPC = thread.nextPC + 4; + expectThread.registers[2] = 0x0; + expectThread.registers[7] = 0x0; + expect.leftThreadStack = keccak256(abi.encodePacked(EMPTY_THREAD_ROOT, keccak256(encodeThread(expectThread)))); + + bytes32 postState = mips.step(encodeState(state), bytes.concat(threadWitness, insnAndMemProof, memProof2), 0); + assertEq(postState, outputState(expect), "unexpected post state"); + } + + /// @dev Test asserting that an clock_gettime monotonic syscall reverts on an invalid memory proof + function test_syscallClockGettimeMonotonicInvalidProof_reverts() public { + _test_syscallClockGettimeInvalidProof_reverts(sys.CLOCK_GETTIME_MONOTONIC_FLAG); + } + + /// @dev Test asserting that an clock_gettime realtime syscall reverts on an invalid memory proof + function test_syscallClockGettimeRealtimeInvalidProof_reverts() public { + _test_syscallClockGettimeInvalidProof_reverts(sys.CLOCK_GETTIME_REALTIME_FLAG); + } + + function _test_syscallClockGettimeInvalidProof_reverts(uint32 clkid) internal { + // NOTE: too slow to run this test under the forge fuzzer. + for (uint256 proofIndex = 896 + (32 * 2); proofIndex < 896 * 2; proofIndex += 32) { + // proofIndex points to a leaf in the index in the memory proof (in insnAndMemProof) that will be zeroed. + // Note that the second leaf in the memory proof is already zeroed because it's the sibling of the first + // memory write. So start from the third leaf. + + uint32 secs = 0; + if (clkid == sys.CLOCK_GETTIME_MONOTONIC_FLAG) { + secs = 10; + } + uint32 pc = 0; + uint32 insn = 0x0000000c; // syscall + uint32 timespecAddr = 0xb000; + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory insnAndMemProof) = + constructMIPSState(pc, insn, timespecAddr, 0xbad); + state.step = 100_000_004; + thread.registers[2] = sys.SYS_CLOCKGETTIME; + thread.registers[A0_REG] = sys.CLOCK_GETTIME_MONOTONIC_FLAG; + thread.registers[A1_REG] = timespecAddr; + thread.registers[7] = 0xdead; + bytes memory threadWitness = abi.encodePacked(encodeThread(thread), EMPTY_THREAD_ROOT); + updateThreadStacks(state, thread); + (, bytes memory memProof2) = ffi.getCannonMemoryProof2(pc, insn, timespecAddr, secs, timespecAddr + 4); + + bytes memory invalidInsnAndMemProof = new bytes(insnAndMemProof.length); + for (uint256 i = 0; i < invalidInsnAndMemProof.length; i++) { + // clear the 32-byte insn leaf + if (i >= proofIndex && i < proofIndex + 32) { + invalidInsnAndMemProof[i] = 0x0; + } else { + invalidInsnAndMemProof[i] = insnAndMemProof[i]; + } + } + vm.expectRevert(InvalidMemoryProof.selector); + mips.step(encodeState(state), bytes.concat(threadWitness, invalidInsnAndMemProof, memProof2), 0); + + (, bytes memory invalidMemProof2) = + ffi.getCannonMemoryProof2(pc, insn, timespecAddr, secs + 1, timespecAddr + 4); + vm.expectRevert(InvalidSecondMemoryProof.selector); + mips.step(encodeState(state), bytes.concat(threadWitness, insnAndMemProof, invalidMemProof2), 0); + } + } + + /// @dev static unit test asserting that clock_gettime syscall for non-realtime, non-monotonic time succeeds + function test_syscallClockGettimeOtherFlags_succeeds() public { + uint32 pc = 0; + uint32 insn = 0x0000000c; // syscall + uint32 timespecAddr = 0xb000; + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory insnAndMemProof) = + constructMIPSState(pc, insn, timespecAddr, 0xbad); + state.step = (sys.HZ * 10 + 5) - 1; + thread.registers[2] = sys.SYS_CLOCKGETTIME; + thread.registers[A0_REG] = sys.CLOCK_GETTIME_MONOTONIC_FLAG + 1; + thread.registers[A1_REG] = timespecAddr; + thread.registers[7] = 0xdead; + bytes memory threadWitness = abi.encodePacked(encodeThread(thread), EMPTY_THREAD_ROOT); + updateThreadStacks(state, thread); + + MIPS2.ThreadState memory expectThread = copyThread(thread); + expectThread.pc = thread.nextPC; + expectThread.nextPC = thread.nextPC + 4; + expectThread.registers[2] = sys.SYS_ERROR_SIGNAL; + expectThread.registers[7] = sys.EINVAL; + MIPS2.State memory expect = copyState(state); + expect.step = state.step + 1; + expect.stepsSinceLastContextSwitch = state.stepsSinceLastContextSwitch + 1; + expect.leftThreadStack = keccak256(abi.encodePacked(EMPTY_THREAD_ROOT, keccak256(encodeThread(expectThread)))); + + bytes32 postState = mips.step(encodeState(state), bytes.concat(threadWitness, insnAndMemProof), 0); + assertEq(postState, outputState(expect), "unexpected post state"); + } + /// @dev Static unit test asserting that VM preempts threads after a certain number of steps function test_threadQuantumSchedule_succeeds() public { MIPS2.ThreadState memory threadA = threading.createThread(); diff --git a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummary.sol b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummary.sol index 392ba885709b..2fa5057acbd7 100644 --- a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummary.sol +++ b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummary.sol @@ -27,11 +27,11 @@ contract DeploymentSummary is DeploymentSummaryCode { address internal constant l1StandardBridgeProxyAddress = 0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D; address internal constant l2OutputOracleAddress = 0x60d37db59d0D14f7EA5c7425A2C03244E08B162D; address internal constant l2OutputOracleProxyAddress = 0x39Af23E00F1e662025aA01b0cEdA19542B78DF99; - address internal constant mipsAddress = 0x46cce16e68c41f7EBdf485EF825AB3b46143F738; + address internal constant mipsAddress = 0x180CBe2EBb9F37D3a3C542DDc2546Fd160555a73; address internal constant optimismMintableERC20FactoryAddress = 0x79c3114E5f89266e2C8842871Bce16D4e5076b1e; address internal constant optimismMintableERC20FactoryProxyAddress = 0xc7B87b2b892EA5C3CfF47168881FE168C00377FB; - address internal constant optimismPortalAddress = 0xBE8eE5CEA97De55Ae8b020E778A5C93C2Af81Ed4; - address internal constant optimismPortal2Address = 0x5506077419b90A12C048500e2eBcafb4fC6Bab61; + address internal constant optimismPortalAddress = 0xb5A42f01EF5068F82C11fa1c4F9bBD4c8D346961; + address internal constant optimismPortal2Address = 0x150581358018524994Fc29800b1783637943b103; address internal constant optimismPortalProxyAddress = 0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4; address internal constant permissionedDelayedWETHProxyAddress = 0xd6EAF4c146261653EE059077B78ED088Add54309; address internal constant preimageOracleAddress = 0x7A9Eab4CE99d157AeE7A02E95b366E972a2D5b0b; @@ -430,7 +430,7 @@ contract DeploymentSummary is DeploymentSummaryCode { value = hex"0000000000000000000000000000000000000000000000000000000000000003"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"000000000000000000000000be8ee5cea97de55ae8b020e778a5c93c2af81ed4"; + value = hex"000000000000000000000000b5a42f01ef5068f82c11fa1c4f9bbd4c8d346961"; vm.store(optimismPortalProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; diff --git a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryCode.sol b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryCode.sol index 272b71f72e59..153fef71fb87 100644 --- a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryCode.sol +++ b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryCode.sol @@ -55,11 +55,11 @@ contract DeploymentSummaryCode { bytes internal constant l1ERC721BridgeCode = hex"608060405234801561001057600080fd5b50600436106100d45760003560e01c80635d93a3fc11610081578063927ede2d1161005b578063927ede2d14610231578063aa5574521461024f578063c89701a21461026257600080fd5b80635d93a3fc146101cc578063761f4493146102005780637f46ddb21461021357600080fd5b8063485cc955116100b2578063485cc9551461015857806354fd4d501461016b5780635c975abb146101b457600080fd5b806335e80ab3146100d95780633687011a146101235780633cb747bf14610138575b600080fd5b6032546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610136610131366004610fe1565b610282565b005b6001546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b610136610166366004611064565b61032e565b6101a76040518060400160405280600c81526020017f322e312e312d626574612e32000000000000000000000000000000000000000081525081565b60405161011a9190611108565b6101bc610518565b604051901515815260200161011a565b6101bc6101da366004611122565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b61013661020e366004611163565b6105b1565b60025473ffffffffffffffffffffffffffffffffffffffff166100f9565b60015473ffffffffffffffffffffffffffffffffffffffff166100f9565b61013661025d3660046111fb565b610a58565b6002546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b333b15610316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b6103268686333388888888610b30565b505050505050565b600054610100900460ff161580801561034e5750600054600160ff909116105b806103685750303b158015610368575060005460ff166001145b6103f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161030d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561045257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556104b083734200000000000000000000000000000000000014610e70565b801561051357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa158015610588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ac9190611272565b905090565b60015473ffffffffffffffffffffffffffffffffffffffff16331480156106865750600254600154604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691636e296e45916004808201926020929091908290030181865afa15801561064a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066e9190611294565b73ffffffffffffffffffffffffffffffffffffffff16145b610712576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f746865722062726964676500606482015260840161030d565b61071a610518565b15610781576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4c314552433732314272696467653a2070617573656400000000000000000000604482015260640161030d565b3073ffffffffffffffffffffffffffffffffffffffff881603610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c6600000000000000000000000000000000000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff1615156001146108f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c312042726964676500000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156109b557600080fd5b505af11580156109c9573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac87878787604051610a4794939291906112fa565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610afb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f74206265206164647265737328302900000000000000000000000000000000606482015260840161030d565b610b0b8787338888888888610b30565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b73ffffffffffffffffffffffffffffffffffffffff8716610bd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f742062652061646472657373283029000000000000000000000000000000606482015260840161030d565b600063761f449360e01b888a8989898888604051602401610bfa979695949392919061133a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610d3a57600080fd5b505af1158015610d4e573d6000803e3d6000fd5b50506001546002546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450633dbb202b9350610db1929091169085908990600401611397565b600060405180830381600087803b158015610dcb57600080fd5b505af1158015610ddf573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610e5d94939291906112fa565b60405180910390a4505050505050505050565b600054610100900460ff16610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161030d565b6001805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560028054929093169116179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610f7c57600080fd5b50565b803563ffffffff81168114610f9357600080fd5b919050565b60008083601f840112610faa57600080fd5b50813567ffffffffffffffff811115610fc257600080fd5b602083019150836020828501011115610fda57600080fd5b9250929050565b60008060008060008060a08789031215610ffa57600080fd5b863561100581610f5a565b9550602087013561101581610f5a565b94506040870135935061102a60608801610f7f565b9250608087013567ffffffffffffffff81111561104657600080fd5b61105289828a01610f98565b979a9699509497509295939492505050565b6000806040838503121561107757600080fd5b823561108281610f5a565b9150602083013561109281610f5a565b809150509250929050565b6000815180845260005b818110156110c3576020818501810151868301820152016110a7565b818111156110d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061111b602083018461109d565b9392505050565b60008060006060848603121561113757600080fd5b833561114281610f5a565b9250602084013561115281610f5a565b929592945050506040919091013590565b600080600080600080600060c0888a03121561117e57600080fd5b873561118981610f5a565b9650602088013561119981610f5a565b955060408801356111a981610f5a565b945060608801356111b981610f5a565b93506080880135925060a088013567ffffffffffffffff8111156111dc57600080fd5b6111e88a828b01610f98565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561121657600080fd5b873561122181610f5a565b9650602088013561123181610f5a565b9550604088013561124181610f5a565b94506060880135935061125660808901610f7f565b925060a088013567ffffffffffffffff8111156111dc57600080fd5b60006020828403121561128457600080fd5b8151801515811461111b57600080fd5b6000602082840312156112a657600080fd5b815161111b81610f5a565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006113306060830184866112b1565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261138a60c0830184866112b1565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006113c6606083018561109d565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a"; bytes internal constant optimismPortalCode = - hex"6080604052600436106101635760003560e01c80638c3152e9116100c0578063b69ef8a811610074578063cff0ab9611610059578063cff0ab9614610444578063e965084c146104e5578063e9e05c421461057157600080fd5b8063b69ef8a814610401578063c0c53b8b1461042457600080fd5b80639bf62d82116100a55780639bf62d821461036b578063a14238e714610398578063a35d99df146103c857600080fd5b80638c3152e91461031e5780639b5f694a1461033e57600080fd5b806354fd4d50116101175780636dbffb78116100fc5780636dbffb78146102de57806371cfaa3f146102fe5780638b4c40b01461018857600080fd5b806354fd4d501461026d5780635c975abb146102b957600080fd5b806335e80ab31161014857806335e80ab314610206578063452a9320146102385780634870496f1461024d57600080fd5b8063149f2f221461018f57806333d7e2bd146101af57600080fd5b3661018a576101883334620186a060006040518060200160405280600081525061057f565b005b600080fd5b34801561019b57600080fd5b506101886101aa366004614b97565b610624565b3480156101bb57600080fd5b506037546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561021257600080fd5b506035546101dc90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561024457600080fd5b506101dc610865565b34801561025957600080fd5b50610188610268366004614ccb565b6108fd565b34801561027957600080fd5b50604080518082018252600c81527f322e382e312d626574612e320000000000000000000000000000000000000000602082015290516101fd9190614e1d565b3480156102c557600080fd5b506102ce610eaa565b60405190151581526020016101fd565b3480156102ea57600080fd5b506102ce6102f9366004614e30565b610f3d565b34801561030a57600080fd5b50610188610319366004614e58565b610ff8565b34801561032a57600080fd5b50610188610339366004614e9e565b6111ba565b34801561034a57600080fd5b506036546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561037757600080fd5b506032546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103a457600080fd5b506102ce6103b3366004614e30565b60336020526000908152604090205460ff1681565b3480156103d457600080fd5b506103e86103e3366004614edb565b611c3c565b60405167ffffffffffffffff90911681526020016101fd565b34801561040d57600080fd5b50610416611c55565b6040519081526020016101fd565b34801561043057600080fd5b5061018861043f366004614ef6565b611caf565b34801561045057600080fd5b506001546104ac906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101fd565b3480156104f157600080fd5b50610543610500366004614e30565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101fd565b61018861057f366004614f41565b8260005a9050600061058f611f19565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906105cb57503415155b15610602576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610610883489898989611fb6565b5061061b8282612162565b50505050505050565b8260005a90506000610634611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016106a6576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546106b89190614fed565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561072a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074e9190615005565b905061077273ffffffffffffffffffffffffffffffffffffffff831633308c61242f565b61077c8982614fed565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa1580156107e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080a9190615005565b14610841576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61084f8a8a8a8a8a8a611fb6565b505061085b8282612162565b5050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f8919061501e565b905090565b610905610eaa565b1561093c576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16036109a5576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6036546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810186905260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610a15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a39919061505b565b519050610a53610a4e368690038601866150c0565b61250b565b8114610ae6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f66000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000610af187612567565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610c075750805160365460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610bdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c03919061505b565b5114155b610c93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610add565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610d5c9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610d52888a615126565b8a60400135612597565b610de8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610add565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f19573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906151aa565b6036546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101839052600091610ff29173ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd7919061505b565b602001516fffffffffffffffffffffffffffffffff166125bb565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff163314611049576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61105562030d40612661565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f000000000000000000000000000000000000000000000000000000001790529051611172969594939291016151c7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526111aa91614e1d565b60405180910390a450505050565b565b6111c2610eaa565b156111f9576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461124c576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061125782612567565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610add565b603660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d39190615005565b81602001516fffffffffffffffffffffffffffffffff16101561149e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610add565b6114bd81602001516fffffffffffffffffffffffffffffffff166125bb565b61156f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610add565b60365460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a919061505b565b82518151919250146116d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610add565b6116f381602001516fffffffffffffffffffffffffffffffff166125bb565b6117a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610add565b60008381526033602052604090205460ff1615611844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610add565b6000838152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558501516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055806118cf611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016119325761192b8660400151876080015188606001518960a001516126c3565b9150611b85565b8073ffffffffffffffffffffffffffffffffffffffff16866040015173ffffffffffffffffffffffffffffffffffffffff160361199b576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606086015115611b5c578560600151603d60008282546119bb919061522c565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015611a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a519190615005565b9050611a86876040015188606001518473ffffffffffffffffffffffffffffffffffffffff166127219092919063ffffffff16565b6060870151611a95908261522c565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015611aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b239190615005565b14611b5a576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08601515115611b805761192b8660400151876080015160008960a001516126c3565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405185907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90611be790851515815260200190565b60405180910390a281158015611bfd5750326001145b15611c34576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b6000611c49826010615243565b610ff290615208615273565b600080611c60611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601611ca7574791505090565b5050603d5490565b600054610100900460ff1615808015611ccf5750600054600160ff909116105b80611ce95750303b158015611ce9575060005460ff166001145b611d75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610add565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611dd357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603680547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8781169190911790925560378054909116858316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101008584160217905560325416611e8c57603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b611e9461277c565b8015611ef757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015611f89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fad919061529f565b90939092509050565b818015611fd8575073ffffffffffffffffffffffffffffffffffffffff861615155b1561200f576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120198151611c3c565b67ffffffffffffffff168367ffffffffffffffff161015612066576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c0815111156120a4576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333281146120c5575033731111000000000000000000000000000000001111015b600086868686866040516020016120e09594939291906151c7565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516121509190614e1d565b60405180910390a45050505050505050565b600154600090612198907801000000000000000000000000000000000000000000000000900467ffffffffffffffff164361522c565b905060006121a461288f565b90506000816020015160ff16826000015163ffffffff166121c59190615308565b905082156122fc576001546000906121fc908390700100000000000000000000000000000000900467ffffffffffffffff16615370565b90506000836040015160ff168361221391906153e4565b6001546122339084906fffffffffffffffffffffffffffffffff166153e4565b61223d9190615308565b60015490915060009061228e906122679084906fffffffffffffffffffffffffffffffff166154a0565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612950565b905060018611156122bd576122ba61226782876040015160ff1660018a6122b5919061522c565b61296f565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b6001805486919060109061232f908490700100000000000000000000000000000000900467ffffffffffffffff16615273565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1613156123bc576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906123e8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615514565b905060006123fa48633b9aca006129c4565b6124049083615551565b905060005a612413908861522c565b90508082111561085b5761085b61242a828461522c565b6129db565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052611ef79085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612a04565b6000816000015182602001518360400151846060015160405160200161254a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a0880151935160009761254a979096959101615565565b6000806125a386612b10565b90506125b181868686612b42565b9695505050505050565b603654604080517ff4daa291000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163f4daa2919160048083019260209291908290030181865afa15801561262b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264f9190615005565b6126599083614fed565b421192915050565b6001805463ffffffff8316919060109061269a908490700100000000000000000000000000000000900467ffffffffffffffff16615273565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b60008060006126d3866000612b72565b905080612709576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526127779084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612489565b505050565b600054610100900460ff16612813576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610add565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff166000036111b85760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa15801561292c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906155d0565b600061296561295f8585612b90565b83612ba0565b90505b9392505050565b6000670de0b6b3a76400006129b06129878583615308565b61299990670de0b6b3a7640000615370565b6129ab85670de0b6b3a76400006153e4565b612baf565b6129ba90866153e4565b6129659190615308565b6000818310156129d45781612968565b5090919050565b6000805a90505b825a6129ee908361522c565b1015612777576129fd82615673565b91506129e2565b6000612a66826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612be09092919063ffffffff16565b8051909150156127775780806020019051810190612a8491906151aa565b612777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610add565b60608180519060200120604051602001612b2c91815260200190565b6040516020818303038152906040529050919050565b6000612b6984612b53878686612bef565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000818312156129d45781612968565b60008183126129d45781612968565b6000612968670de0b6b3a764000083612bc78661366d565b612bd191906153e4565b612bdb9190615308565b6138b1565b60606129658484600085613af0565b60606000845111612c5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610add565b6000612c6784613c86565b90506000612c7486613d72565b9050600084604051602001612c8b91815260200190565b60405160208183030381529060405290506000805b84518110156135e4576000858281518110612cbd57612cbd6156ab565b602002602001015190508451831115612d58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610add565b82600003612e115780518051602091820120604051612da692612d8092910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610add565b612f68565b805151602011612ec75780518051602091820120604051612e3b92612d8092910190815260200190565b612e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610add565b805184516020808701919091208251919092012014612f68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610add565b612f7460106001614fed565b8160200151510361315057845183036130e857612fae8160200151601081518110612fa157612fa16156ab565b6020026020010151613dd5565b96506000875111613041576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610add565b6001865161304f919061522c565b82146130dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610add565b505050505050612968565b60008584815181106130fc576130fc6156ab565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110613127576131276156ab565b6020026020010151905061313a81613e89565b9550613147600186614fed565b945050506135d1565b60028160200151510361354957600061316882613eae565b905060008160008151811061317f5761317f6156ab565b016020015160f81c905060006131966002836156da565b6131a19060026156fc565b905060006131b2848360ff16613ed2565b905060006131c08a89613ed2565b905060006131ce8383613f08565b905080835114613260576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610add565b60ff851660021480613275575060ff85166003145b15613464578082511461330a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610add565b6133248760200151600181518110612fa157612fa16156ab565b9c5060008d51116133b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610add565b60018c516133c5919061522c565b8814613453576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610add565b505050505050505050505050612968565b60ff85161580613477575060ff85166001145b156134b6576134a38760200151600181518110613496576134966156ab565b6020026020010151613e89565b99506134af818a614fed565b985061353e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610add565b5050505050506135d1565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610add565b50806135dc81615673565b915050612ca0565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610add565b60008082136136d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b600060606136e584613fbc565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136138e257506000919050565b680755bf798b4a1bf1e58212613954576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610add565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613b82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610add565b73ffffffffffffffffffffffffffffffffffffffff85163b613c00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610add565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613c29919061571f565b60006040518083038185875af1925050503d8060008114613c66576040519150601f19603f3d011682016040523d82523d6000602084013e613c6b565b606091505b5091509150613c7b828286614092565b979650505050505050565b80516060908067ffffffffffffffff811115613ca457613ca4614a8b565b604051908082528060200260200182016040528015613ce957816020015b6040805180820190915260608082526020820152815260200190600190039081613cc25790505b50915060005b81811015613d6b576040518060400160405280858381518110613d1457613d146156ab565b60200260200101518152602001613d43868481518110613d3657613d366156ab565b60200260200101516140e5565b815250838281518110613d5857613d586156ab565b6020908102919091010152600101613cef565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015613dca578060011b82018184015160001a8060041c8253600f811660018301535050600101613d9c565b509295945050505050565b60606000806000613de5856140f8565b919450925090506000816001811115613e0057613e0061573b565b14613e37576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613e418284614fed565b855114613e7a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b6985602001518484614596565b60606020826000015110613ea557613ea082613dd5565b610ff2565b610ff28261462a565b6060610ff2613ecd8360200151600081518110612fa157612fa16156ab565b613d72565b606082518210613ef15750604080516020810190915260008152610ff2565b6129688383848651613f03919061522c565b614640565b6000808251845110613f1b578251613f1e565b83515b90505b8082108015613fa55750828281518110613f3d57613f3d6156ab565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613f7c57613f7c6156ab565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15613fb557816001019150613f21565b5092915050565b6000808211614027576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606083156140a1575081612968565b8251156140b15782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610add9190614e1d565b6060610ff26140f383614818565b614885565b6000806000836000015160000361413b576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f811161416057600060016000945094509450505061458f565b60b7811161427657600061417560808361522c565b9050808760000151116141b4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214801561422c57507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614263576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061458f915050565b60bf81116143d457600061428b60b78361522c565b9050808760000151116142ca576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361432c576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614374576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61437e8184614fed565b8951116143b7576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6143c2836001614fed565b975095506000945061458f9350505050565b60f781116144395760006143e960c08361522c565b905080876000015111614428576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061458f915050565b600061444660f78361522c565b905080876000015111614485576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036144e7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c6037811161452f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6145398184614fed565b895111614572576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61457d836001614fed565b975095506001945061458f9350505050565b9193909250565b60608167ffffffffffffffff8111156145b1576145b1614a8b565b6040519080825280601f01601f1916602001820160405280156145db576020820181803683370190505b50905081156129685760006145f08486614fed565b90506020820160005b848110156146115782810151828201526020016145f9565b84811115614620576000858301525b5050509392505050565b6060610ff2826020015160008460000151614596565b60608182601f0110156146af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b82828401101561471b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b81830184511015614788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610add565b6060821580156147a7576040519150600082526020820160405261480f565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156147e05780518352602092830192016147c8565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201528151600003614867576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000614895856140f8565b9194509250905060018160018111156148b0576148b061573b565b146148e7576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516148f38385614fed565b1461492a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816149415790505093506000835b8651811015614a2f576000806149b46040518060400160405280858c60000151614998919061522c565b8152602001858c602001516149ad9190614fed565b90526140f8565b5091509150604051806040016040528083836149d09190614fed565b8152602001848b602001516149e59190614fed565b8152508885815181106149fa576149fa6156ab565b6020908102919091010152614a10600185614fed565b9350614a1c8183614fed565b614a269084614fed565b9250505061496e565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114614a5d57600080fd5b50565b803567ffffffffffffffff81168114614a7857600080fd5b919050565b8015158114614a5d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614b0157614b01614a8b565b604052919050565b600082601f830112614b1a57600080fd5b813567ffffffffffffffff811115614b3457614b34614a8b565b614b6560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614aba565b818152846020838601011115614b7a57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614bb057600080fd5b8635614bbb81614a3b565b95506020870135945060408701359350614bd760608801614a60565b92506080870135614be781614a7d565b915060a087013567ffffffffffffffff811115614c0357600080fd5b614c0f89828a01614b09565b9150509295509295509295565b600060c08284031215614c2e57600080fd5b60405160c0810167ffffffffffffffff8282108183111715614c5257614c52614a8b565b816040528293508435835260208501359150614c6d82614a3b565b81602084015260408501359150614c8382614a3b565b816040840152606085013560608401526080850135608084015260a0850135915080821115614cb157600080fd5b50614cbe85828601614b09565b60a0830152505092915050565b600080600080600085870360e0811215614ce457600080fd5b863567ffffffffffffffff80821115614cfc57600080fd5b614d088a838b01614c1c565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614d4157600080fd5b60408901955060c0890135925080831115614d5b57600080fd5b828901925089601f840112614d6f57600080fd5b8235915080821115614d8057600080fd5b508860208260051b8401011115614d9657600080fd5b959894975092955050506020019190565b60005b83811015614dc2578181015183820152602001614daa565b83811115611ef75750506000910152565b60008151808452614deb816020860160208601614da7565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006129686020830184614dd3565b600060208284031215614e4257600080fd5b5035919050565b60ff81168114614a5d57600080fd5b60008060008060808587031215614e6e57600080fd5b8435614e7981614a3b565b93506020850135614e8981614e49565b93969395505050506040820135916060013590565b600060208284031215614eb057600080fd5b813567ffffffffffffffff811115614ec757600080fd5b614ed384828501614c1c565b949350505050565b600060208284031215614eed57600080fd5b61296882614a60565b600080600060608486031215614f0b57600080fd5b8335614f1681614a3b565b92506020840135614f2681614a3b565b91506040840135614f3681614a3b565b809150509250925092565b600080600080600060a08688031215614f5957600080fd5b8535614f6481614a3b565b945060208601359350614f7960408701614a60565b92506060860135614f8981614a7d565b9150608086013567ffffffffffffffff811115614fa557600080fd5b614fb188828901614b09565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561500057615000614fbe565b500190565b60006020828403121561501757600080fd5b5051919050565b60006020828403121561503057600080fd5b815161296881614a3b565b80516fffffffffffffffffffffffffffffffff81168114614a7857600080fd5b60006060828403121561506d57600080fd5b6040516060810181811067ffffffffffffffff8211171561509057615090614a8b565b604052825181526150a36020840161503b565b60208201526150b46040840161503b565b60408201529392505050565b6000608082840312156150d257600080fd5b6040516080810181811067ffffffffffffffff821117156150f5576150f5614a8b565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff8084111561514157615141614a8b565b8360051b6020615152818301614aba565b86815291850191818101903684111561516a57600080fd5b865b8481101561519e578035868111156151845760008081fd5b61519036828b01614b09565b84525091830191830161516c565b50979650505050505050565b6000602082840312156151bc57600080fd5b815161296881614a7d565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b60488201526000825161521b816049850160208701614da7565b919091016049019695505050505050565b60008282101561523e5761523e614fbe565b500390565b600067ffffffffffffffff8083168185168183048111821515161561526a5761526a614fbe565b02949350505050565b600067ffffffffffffffff80831681851680830382111561529657615296614fbe565b01949350505050565b600080604083850312156152b257600080fd5b82516152bd81614a3b565b60208401519092506152ce81614e49565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615317576153176152d9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561536b5761536b614fbe565b500590565b6000808312837f8000000000000000000000000000000000000000000000000000000000000000018312811516156153aa576153aa614fbe565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156153de576153de614fbe565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561542557615425614fbe565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561546057615460614fbe565b6000871292508782058712848416161561547c5761547c614fbe565b8785058712818416161561549257615492614fbe565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156154da576154da614fbe565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561550e5761550e614fbe565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561554c5761554c614fbe565b500290565b600082615560576155606152d9565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526155b060c0830184614dd3565b98975050505050505050565b805163ffffffff81168114614a7857600080fd5b600060c082840312156155e257600080fd5b60405160c0810181811067ffffffffffffffff8211171561560557615605614a8b565b604052615611836155bc565b8152602083015161562181614e49565b6020820152604083015161563481614e49565b6040820152615645606084016155bc565b6060820152615656608084016155bc565b608082015261566760a0840161503b565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036156a4576156a4614fbe565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806156ed576156ed6152d9565b8060ff84160691505092915050565b600060ff821660ff84168082101561571657615716614fbe565b90039392505050565b60008251615731818460208701614da7565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a"; + hex"6080604052600436106101635760003560e01c80638c3152e9116100c0578063b69ef8a811610074578063cff0ab9611610059578063cff0ab9614610444578063e965084c146104e5578063e9e05c421461057157600080fd5b8063b69ef8a814610401578063c0c53b8b1461042457600080fd5b80639bf62d82116100a55780639bf62d821461036b578063a14238e714610398578063a35d99df146103c857600080fd5b80638c3152e91461031e5780639b5f694a1461033e57600080fd5b806354fd4d50116101175780636dbffb78116100fc5780636dbffb78146102de57806371cfaa3f146102fe5780638b4c40b01461018857600080fd5b806354fd4d501461026d5780635c975abb146102b957600080fd5b806335e80ab31161014857806335e80ab314610206578063452a9320146102385780634870496f1461024d57600080fd5b8063149f2f221461018f57806333d7e2bd146101af57600080fd5b3661018a576101883334620186a060006040518060200160405280600081525061057f565b005b600080fd5b34801561019b57600080fd5b506101886101aa366004614c13565b610624565b3480156101bb57600080fd5b506037546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561021257600080fd5b506035546101dc90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561024457600080fd5b506101dc610865565b34801561025957600080fd5b50610188610268366004614d47565b6108fd565b34801561027957600080fd5b50604080518082018252600c81527f322e382e312d626574612e320000000000000000000000000000000000000000602082015290516101fd9190614e99565b3480156102c557600080fd5b506102ce610eaa565b60405190151581526020016101fd565b3480156102ea57600080fd5b506102ce6102f9366004614eac565b610f3d565b34801561030a57600080fd5b50610188610319366004614ed4565b610ff8565b34801561032a57600080fd5b50610188610339366004614f1a565b6111ba565b34801561034a57600080fd5b506036546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561037757600080fd5b506032546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103a457600080fd5b506102ce6103b3366004614eac565b60336020526000908152604090205460ff1681565b3480156103d457600080fd5b506103e86103e3366004614f57565b611c3c565b60405167ffffffffffffffff90911681526020016101fd565b34801561040d57600080fd5b50610416611c55565b6040519081526020016101fd565b34801561043057600080fd5b5061018861043f366004614f72565b611caf565b34801561045057600080fd5b506001546104ac906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101fd565b3480156104f157600080fd5b50610543610500366004614eac565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101fd565b61018861057f366004614fbd565b8260005a9050600061058f611f19565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906105cb57503415155b15610602576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610610883489898989611fb6565b5061061b8282612162565b50505050505050565b8260005a90506000610634611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016106a6576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546106b89190615069565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561072a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074e9190615081565b905061077273ffffffffffffffffffffffffffffffffffffffff831633308c61242f565b61077c8982615069565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa1580156107e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080a9190615081565b14610841576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61084f8a8a8a8a8a8a611fb6565b505061085b8282612162565b5050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f8919061509a565b905090565b610905610eaa565b1561093c576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16036109a5576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6036546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810186905260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610a15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3991906150d7565b519050610a53610a4e3686900386018661513c565b61250b565b8114610ae6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f66000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000610af187612567565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610c075750805160365460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610bdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0391906150d7565b5114155b610c93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610add565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610d5c9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610d52888a6151a2565b8a60400135612597565b610de8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610add565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f19573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f89190615226565b6036546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101839052600091610ff29173ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd791906150d7565b602001516fffffffffffffffffffffffffffffffff166125bb565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff163314611049576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61105562030d40612661565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f00000000000000000000000000000000000000000000000000000000179052905161117296959493929101615243565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526111aa91614e99565b60405180910390a450505050565b565b6111c2610eaa565b156111f9576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461124c576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061125782612567565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610add565b603660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d39190615081565b81602001516fffffffffffffffffffffffffffffffff16101561149e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610add565b6114bd81602001516fffffffffffffffffffffffffffffffff166125bb565b61156f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610add565b60365460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a91906150d7565b82518151919250146116d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610add565b6116f381602001516fffffffffffffffffffffffffffffffff166125bb565b6117a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610add565b60008381526033602052604090205460ff1615611844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610add565b6000838152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558501516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055806118cf611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016119325761192b8660400151876080015188606001518960a001516126c3565b9150611b85565b8073ffffffffffffffffffffffffffffffffffffffff16866040015173ffffffffffffffffffffffffffffffffffffffff160361199b576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606086015115611b5c578560600151603d60008282546119bb91906152a8565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015611a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a519190615081565b9050611a86876040015188606001518473ffffffffffffffffffffffffffffffffffffffff166127219092919063ffffffff16565b6060870151611a9590826152a8565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015611aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b239190615081565b14611b5a576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08601515115611b805761192b8660400151876080015160008960a001516126c3565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405185907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90611be790851515815260200190565b60405180910390a281158015611bfd5750326001145b15611c34576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b6000611c498260106152bf565b610ff2906152086152ef565b600080611c60611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601611ca7574791505090565b5050603d5490565b600054610100900460ff1615808015611ccf5750600054600160ff909116105b80611ce95750303b158015611ce9575060005460ff166001145b611d75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610add565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611dd357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603680547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8781169190911790925560378054909116858316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101008584160217905560325416611e8c57603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b611e9461277c565b8015611ef757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015611f89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fad919061531b565b90939092509050565b818015611fd8575073ffffffffffffffffffffffffffffffffffffffff861615155b1561200f576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120198151611c3c565b67ffffffffffffffff168367ffffffffffffffff161015612066576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c0815111156120a4576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333281146120c5575033731111000000000000000000000000000000001111015b600086868686866040516020016120e0959493929190615243565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516121509190614e99565b60405180910390a45050505050505050565b600154600090612198907801000000000000000000000000000000000000000000000000900467ffffffffffffffff16436152a8565b905060006121a461288f565b90506000816020015160ff16826000015163ffffffff166121c59190615384565b905082156122fc576001546000906121fc908390700100000000000000000000000000000000900467ffffffffffffffff166153ec565b90506000836040015160ff16836122139190615460565b6001546122339084906fffffffffffffffffffffffffffffffff16615460565b61223d9190615384565b60015490915060009061228e906122679084906fffffffffffffffffffffffffffffffff1661551c565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff166129cc565b905060018611156122bd576122ba61226782876040015160ff1660018a6122b591906152a8565b6129eb565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b6001805486919060109061232f908490700100000000000000000000000000000000900467ffffffffffffffff166152ef565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1613156123bc576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906123e8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615590565b905060006123fa48633b9aca00612a40565b61240490836155cd565b905060005a61241390886152a8565b90508082111561085b5761085b61242a82846152a8565b612a57565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052611ef79085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612a80565b6000816000015182602001518360400151846060015160405160200161254a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a0880151935160009761254a9790969591016155e1565b6000806125a386612b8c565b90506125b181868686612bbe565b9695505050505050565b603654604080517ff4daa291000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163f4daa2919160048083019260209291908290030181865afa15801561262b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264f9190615081565b6126599083615069565b421192915050565b6001805463ffffffff8316919060109061269a908490700100000000000000000000000000000000900467ffffffffffffffff166152ef565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b60008060006126d3866000612bee565b905080612709576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526127779084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612489565b505050565b600054610100900460ff16612813576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610add565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff166000036111b85760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152603754604080517fcc731b02000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163cc731b029160048083019260c09291908290030181865afa158015612931573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612955919061564c565b90506040518060c00160405280826000015163ffffffff168152602001826020015160ff168152602001826040015160ff168152602001826060015163ffffffff168152602001826080015163ffffffff1681526020018260a001516fffffffffffffffffffffffffffffffff1681525091505090565b60006129e16129db8585612c0c565b83612c1c565b90505b9392505050565b6000670de0b6b3a7640000612a2c612a038583615384565b612a1590670de0b6b3a76400006153ec565b612a2785670de0b6b3a7640000615460565b612c2b565b612a369086615460565b6129e19190615384565b600081831015612a5057816129e4565b5090919050565b6000805a90505b825a612a6a90836152a8565b101561277757612a79826156ef565b9150612a5e565b6000612ae2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612c5c9092919063ffffffff16565b8051909150156127775780806020019051810190612b009190615226565b612777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610add565b60608180519060200120604051602001612ba891815260200190565b6040516020818303038152906040529050919050565b6000612be584612bcf878686612c6b565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b600081831215612a5057816129e4565b6000818312612a5057816129e4565b60006129e4670de0b6b3a764000083612c43866136e9565b612c4d9190615460565b612c579190615384565b61392d565b60606129e18484600085613b6c565b60606000845111612cd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610add565b6000612ce384613d02565b90506000612cf086613dee565b9050600084604051602001612d0791815260200190565b60405160208183030381529060405290506000805b8451811015613660576000858281518110612d3957612d39615727565b602002602001015190508451831115612dd4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610add565b82600003612e8d5780518051602091820120604051612e2292612dfc92910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612e88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610add565b612fe4565b805151602011612f435780518051602091820120604051612eb792612dfc92910190815260200190565b612e88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610add565b805184516020808701919091208251919092012014612fe4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610add565b612ff060106001615069565b816020015151036131cc57845183036131645761302a816020015160108151811061301d5761301d615727565b6020026020010151613e51565b965060008751116130bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610add565b600186516130cb91906152a8565b8214613159576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610add565b5050505050506129e4565b600085848151811061317857613178615727565b602001015160f81c60f81b60f81c9050600082602001518260ff16815181106131a3576131a3615727565b602002602001015190506131b681613f05565b95506131c3600186615069565b9450505061364d565b6002816020015151036135c55760006131e482613f2a565b90506000816000815181106131fb576131fb615727565b016020015160f81c90506000613212600283615756565b61321d906002615778565b9050600061322e848360ff16613f4e565b9050600061323c8a89613f4e565b9050600061324a8383613f84565b9050808351146132dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610add565b60ff8516600214806132f1575060ff85166003145b156134e05780825114613386576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610add565b6133a0876020015160018151811061301d5761301d615727565b9c5060008d5111613433576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610add565b60018c5161344191906152a8565b88146134cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610add565b5050505050505050505050506129e4565b60ff851615806134f3575060ff85166001145b156135325761351f876020015160018151811061351257613512615727565b6020026020010151613f05565b995061352b818a615069565b98506135ba565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610add565b50505050505061364d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610add565b5080613658816156ef565b915050612d1c565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610add565b6000808213613754576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b6000606061376184614038565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361395e57506000919050565b680755bf798b4a1bf1e582126139d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610add565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613bfe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610add565b73ffffffffffffffffffffffffffffffffffffffff85163b613c7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610add565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613ca5919061579b565b60006040518083038185875af1925050503d8060008114613ce2576040519150601f19603f3d011682016040523d82523d6000602084013e613ce7565b606091505b5091509150613cf782828661410e565b979650505050505050565b80516060908067ffffffffffffffff811115613d2057613d20614b07565b604051908082528060200260200182016040528015613d6557816020015b6040805180820190915260608082526020820152815260200190600190039081613d3e5790505b50915060005b81811015613de7576040518060400160405280858381518110613d9057613d90615727565b60200260200101518152602001613dbf868481518110613db257613db2615727565b6020026020010151614161565b815250838281518110613dd457613dd4615727565b6020908102919091010152600101613d6b565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015613e46578060011b82018184015160001a8060041c8253600f811660018301535050600101613e18565b509295945050505050565b60606000806000613e6185614174565b919450925090506000816001811115613e7c57613e7c6157b7565b14613eb3576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613ebd8284615069565b855114613ef6576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612be585602001518484614612565b60606020826000015110613f2157613f1c82613e51565b610ff2565b610ff2826146a6565b6060610ff2613f49836020015160008151811061301d5761301d615727565b613dee565b606082518210613f6d5750604080516020810190915260008152610ff2565b6129e48383848651613f7f91906152a8565b6146bc565b6000808251845110613f97578251613f9a565b83515b90505b80821080156140215750828281518110613fb957613fb9615727565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613ff857613ff8615727565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b1561403157816001019150613f9d565b5092915050565b60008082116140a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b6060831561411d5750816129e4565b82511561412d5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610add9190614e99565b6060610ff261416f83614894565b614901565b600080600083600001516000036141b7576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f81116141dc57600060016000945094509450505061460b565b60b781116142f25760006141f16080836152a8565b905080876000015111614230576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff000000000000000000000000000000000000000000000000000000000000001690821480156142a857507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b156142df576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061460b915050565b60bf811161445057600061430760b7836152a8565b905080876000015111614346576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036143a8576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116143f0576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6143fa8184615069565b895111614433576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61443e836001615069565b975095506000945061460b9350505050565b60f781116144b557600061446560c0836152a8565b9050808760000151116144a4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061460b915050565b60006144c260f7836152a8565b905080876000015111614501576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614563576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116145ab576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6145b58184615069565b8951116145ee576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6145f9836001615069565b975095506001945061460b9350505050565b9193909250565b60608167ffffffffffffffff81111561462d5761462d614b07565b6040519080825280601f01601f191660200182016040528015614657576020820181803683370190505b50905081156129e457600061466c8486615069565b90506020820160005b8481101561468d578281015182820152602001614675565b8481111561469c576000858301525b5050509392505050565b6060610ff2826020015160008460000151614612565b60608182601f01101561472b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b828284011015614797576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b81830184511015614804576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610add565b606082158015614823576040519150600082526020820160405261488b565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561485c578051835260209283019201614844565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015281516000036148e3576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b6060600080600061491185614174565b91945092509050600181600181111561492c5761492c6157b7565b14614963576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845161496f8385615069565b146149a6576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816149bd5790505093506000835b8651811015614aab57600080614a306040518060400160405280858c60000151614a1491906152a8565b8152602001858c60200151614a299190615069565b9052614174565b509150915060405180604001604052808383614a4c9190615069565b8152602001848b60200151614a619190615069565b815250888581518110614a7657614a76615727565b6020908102919091010152614a8c600185615069565b9350614a988183615069565b614aa29084615069565b925050506149ea565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114614ad957600080fd5b50565b803567ffffffffffffffff81168114614af457600080fd5b919050565b8015158114614ad957600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614b7d57614b7d614b07565b604052919050565b600082601f830112614b9657600080fd5b813567ffffffffffffffff811115614bb057614bb0614b07565b614be160207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614b36565b818152846020838601011115614bf657600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614c2c57600080fd5b8635614c3781614ab7565b95506020870135945060408701359350614c5360608801614adc565b92506080870135614c6381614af9565b915060a087013567ffffffffffffffff811115614c7f57600080fd5b614c8b89828a01614b85565b9150509295509295509295565b600060c08284031215614caa57600080fd5b60405160c0810167ffffffffffffffff8282108183111715614cce57614cce614b07565b816040528293508435835260208501359150614ce982614ab7565b81602084015260408501359150614cff82614ab7565b816040840152606085013560608401526080850135608084015260a0850135915080821115614d2d57600080fd5b50614d3a85828601614b85565b60a0830152505092915050565b600080600080600085870360e0811215614d6057600080fd5b863567ffffffffffffffff80821115614d7857600080fd5b614d848a838b01614c98565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614dbd57600080fd5b60408901955060c0890135925080831115614dd757600080fd5b828901925089601f840112614deb57600080fd5b8235915080821115614dfc57600080fd5b508860208260051b8401011115614e1257600080fd5b959894975092955050506020019190565b60005b83811015614e3e578181015183820152602001614e26565b83811115611ef75750506000910152565b60008151808452614e67816020860160208601614e23565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006129e46020830184614e4f565b600060208284031215614ebe57600080fd5b5035919050565b60ff81168114614ad957600080fd5b60008060008060808587031215614eea57600080fd5b8435614ef581614ab7565b93506020850135614f0581614ec5565b93969395505050506040820135916060013590565b600060208284031215614f2c57600080fd5b813567ffffffffffffffff811115614f4357600080fd5b614f4f84828501614c98565b949350505050565b600060208284031215614f6957600080fd5b6129e482614adc565b600080600060608486031215614f8757600080fd5b8335614f9281614ab7565b92506020840135614fa281614ab7565b91506040840135614fb281614ab7565b809150509250925092565b600080600080600060a08688031215614fd557600080fd5b8535614fe081614ab7565b945060208601359350614ff560408701614adc565b9250606086013561500581614af9565b9150608086013567ffffffffffffffff81111561502157600080fd5b61502d88828901614b85565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561507c5761507c61503a565b500190565b60006020828403121561509357600080fd5b5051919050565b6000602082840312156150ac57600080fd5b81516129e481614ab7565b80516fffffffffffffffffffffffffffffffff81168114614af457600080fd5b6000606082840312156150e957600080fd5b6040516060810181811067ffffffffffffffff8211171561510c5761510c614b07565b6040528251815261511f602084016150b7565b6020820152615130604084016150b7565b60408201529392505050565b60006080828403121561514e57600080fd5b6040516080810181811067ffffffffffffffff8211171561517157615171614b07565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff808411156151bd576151bd614b07565b8360051b60206151ce818301614b36565b8681529185019181810190368411156151e657600080fd5b865b8481101561521a578035868111156152005760008081fd5b61520c36828b01614b85565b8452509183019183016151e8565b50979650505050505050565b60006020828403121561523857600080fd5b81516129e481614af9565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251615297816049850160208701614e23565b919091016049019695505050505050565b6000828210156152ba576152ba61503a565b500390565b600067ffffffffffffffff808316818516818304811182151516156152e6576152e661503a565b02949350505050565b600067ffffffffffffffff8083168185168083038211156153125761531261503a565b01949350505050565b6000806040838503121561532e57600080fd5b825161533981614ab7565b602084015190925061534a81614ec5565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261539357615393615355565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156153e7576153e761503a565b500590565b6000808312837f8000000000000000000000000000000000000000000000000000000000000000018312811516156154265761542661503a565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561545a5761545a61503a565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156154a1576154a161503a565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156154dc576154dc61503a565b600087129250878205871284841616156154f8576154f861503a565b8785058712818416161561550e5761550e61503a565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156155565761555661503a565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561558a5761558a61503a565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156155c8576155c861503a565b500290565b6000826155dc576155dc615355565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261562c60c0830184614e4f565b98975050505050505050565b805163ffffffff81168114614af457600080fd5b600060c0828403121561565e57600080fd5b60405160c0810181811067ffffffffffffffff8211171561568157615681614b07565b60405261568d83615638565b8152602083015161569d81614ec5565b602082015260408301516156b081614ec5565b60408201526156c160608401615638565b60608201526156d260808401615638565b60808201526156e360a084016150b7565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036157205761572061503a565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff83168061576957615769615355565b8060ff84160691505092915050565b600060ff821660ff8416808210156157925761579261503a565b90039392505050565b600082516157ad818460208701614e23565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a"; bytes internal constant l2OutputOracleCode = hex"60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec33481461049b578063e1a41bcf146104b0578063f4daa291146104c657600080fd5b8063ce5db8d614610445578063cf8e5cf01461045b578063d1de856c1461047b57600080fd5b8063a25ae557116100b0578063a25ae55714610391578063a8e4fb90146103ed578063bffa7f0f1461041a57600080fd5b806389c44cbb1461034857806393991af3146103685780639aaab6481461037e57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa5146102fc5780637f00642014610312578063887862721461033257600080fd5b806369f16eec146102a75780636abcf563146102bc5780636b4d98dd146102d157600080fd5b8063529933df11610169578063529933df146101ea578063534db0e2146101ff57806354fd4d501461025157600080fd5b80622134cc1461018f5780631c89c97d146101b35780634599c788146101d5575b600080fd5b34801561019b57600080fd5b506005545b6040519081526020015b60405180910390f35b3480156101bf57600080fd5b506101d36101ce3660046113a2565b6104db565b005b3480156101e157600080fd5b506101a06108b6565b3480156101f657600080fd5b506004546101a0565b34801561020b57600080fd5b5060065461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101aa565b34801561025d57600080fd5b5061029a6040518060400160405280600c81526020017f312e382e312d626574612e31000000000000000000000000000000000000000081525081565b6040516101aa9190611405565b3480156102b357600080fd5b506101a0610929565b3480156102c857600080fd5b506003546101a0565b3480156102dd57600080fd5b5060065473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561030857600080fd5b506101a060015481565b34801561031e57600080fd5b506101a061032d366004611478565b61093b565b34801561033e57600080fd5b506101a060025481565b34801561035457600080fd5b506101d3610363366004611478565b610b4f565b34801561037457600080fd5b506101a060055481565b6101d361038c366004611491565b610de9565b34801561039d57600080fd5b506103b16103ac366004611478565b61124a565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101aa565b3480156103f957600080fd5b5060075461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561042657600080fd5b5060075473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561045157600080fd5b506101a060085481565b34801561046757600080fd5b506103b1610476366004611478565b6112de565b34801561048757600080fd5b506101a0610496366004611478565b611316565b3480156104a757600080fd5b506101a0611346565b3480156104bc57600080fd5b506101a060045481565b3480156104d257600080fd5b506008546101a0565b600054610100900460ff16158080156104fb5750600054600160ff909116105b806105155750303b158015610515575060005460ff166001145b6105a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561060457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60008811610694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e2030000000000000606482015260840161059d565b60008711610724576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e2030000000000000000000000000606482015260840161059d565b428511156107db576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60048890556005879055600186905560028590556007805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556006805492861692909116919091179055600882905580156108ac57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b6003546000901561092057600380546108d1906001906114f2565b815481106108e1576108e1611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b600354600090610924906001906114f2565b60006109456108b6565b8211156109fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161059d565b600354610aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161059d565b6003546000905b80821015610b485760006002610acc8385611538565b610ad69190611550565b90508460038281548110610aec57610aec611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610b3e57610b37816001611538565b9250610b42565b8091505b50610ab6565b5092915050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610bf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161059d565b6003548110610cad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60085460038281548110610cc357610cc3611509565b6000918252602090912060016002909202010154610cf3906fffffffffffffffffffffffffffffffff16426114f2565b10610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161059d565b6000610db160035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60075473ffffffffffffffffffffffffffffffffffffffff163314610eb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b610ebe611346565b8314610f72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161059d565b42610f7c84611316565b10611009576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161059d565b83611096576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161059d565b81156111525781814014611152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161059d565b8261115c60035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e24260405161118e91815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b60408051606081018252600080825260208201819052918101919091526003828154811061127a5761127a611509565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b604080516060810182526000808252602082018190529181019190915260036113068361093b565b8154811061127a5761127a611509565b60006005546001548361132991906114f2565b611333919061158b565b6002546113409190611538565b92915050565b60006004546113536108b6565b6109249190611538565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b803573ffffffffffffffffffffffffffffffffffffffff8116811461139d57600080fd5b919050565b600080600080600080600060e0888a0312156113bd57600080fd5b873596506020880135955060408801359450606088013593506113e260808901611379565b92506113f060a08901611379565b915060c0880135905092959891949750929550565b600060208083528351808285015260005b8181101561143257858101830151858201604001528201611416565b81811115611444576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561148a57600080fd5b5035919050565b600080600080608085870312156114a757600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611504576115046114c3565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000821982111561154b5761154b6114c3565b500190565b600082611586577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156115c3576115c36114c3565b50029056fea164736f6c634300080f000a"; bytes internal constant optimismPortal2Code = - hex"6080604052600436106101d15760003560e01c80637fc48504116100f7578063a35d99df11610095578063bf653a5c11610064578063bf653a5c14610697578063cff0ab96146106ca578063e9e05c421461076b578063f2b4e6171461077e57600080fd5b8063a35d99df1461059b578063a3860f48146105bb578063b69ef8a8146105db578063bb2c727e146105f057600080fd5b80638e819e54116100d15780638e819e54146104eb578063952b27971461050b5780639bf62d821461053e578063a14238e71461056b57600080fd5b80637fc48504146104ab5780638b4c40b0146101f65780638c3152e9146104cb57600080fd5b80634870496f1161016f5780635c975abb1161013e5780635c975abb1461043657806371c1566e1461044b57806371cfaa3f1461046b5780637d6be8dc1461048b57600080fd5b80634870496f1461034d5780634fd0434c1461036d578063513747ab146103af57806354fd4d50146103ea57600080fd5b80633c9f397c116101ab5780633c9f397c146102a657806343ca1c50146102d8578063452a9320146102f857806345884d321461030d57600080fd5b8063149f2f22146101fd57806333d7e2bd1461021d57806335e80ab31461027457600080fd5b366101f8576101f63334620186a06000604051806020016040528060008152506107ab565b005b600080fd5b34801561020957600080fd5b506101f6610218366004614fe6565b610850565b34801561022957600080fd5b5060375461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561028057600080fd5b5060355461024a90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156102b257600080fd5b50603b546102c39063ffffffff1681565b60405163ffffffff909116815260200161026b565b3480156102e457600080fd5b506101f66102f336600461511c565b610a91565b34801561030457600080fd5b5061024a610f31565b34801561031957600080fd5b5061033d61032836600461516e565b603a6020526000908152604090205460ff1681565b604051901515815260200161026b565b34801561035957600080fd5b506101f661036836600461518b565b610fc9565b34801561037957600080fd5b50603b5461039690640100000000900467ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161026b565b3480156103bb57600080fd5b506103dc6103ca366004615267565b6000908152603c602052604090205490565b60405190815260200161026b565b3480156103f657600080fd5b50604080518082018252600d81527f332e31312e302d626574612e33000000000000000000000000000000000000006020820152905161026b91906152f6565b34801561044257600080fd5b5061033d611531565b34801561045757600080fd5b506101f6610466366004615309565b6115c4565b34801561047757600080fd5b506101f661048636600461533d565b611c7f565b34801561049757600080fd5b506101f66104a636600461516e565b611e3f565b3480156104b757600080fd5b506101f66104c6366004615395565b611f22565b3480156104d757600080fd5b506101f66104e63660046153b2565b61200e565b3480156104f757600080fd5b506101f66105063660046153ef565b61205a565b34801561051757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000066103dc565b34801561054a57600080fd5b5060325461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561057757600080fd5b5061033d610586366004615267565b60336020526000908152604090205460ff1681565b3480156105a757600080fd5b506103966105b636600461544b565b61230f565b3480156105c757600080fd5b5061024a6105d6366004615468565b61232e565b3480156105e757600080fd5b506103dc612373565b3480156105fc57600080fd5b5061066261060b366004615309565b603960209081526000928352604080842090915290825290205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900467ffffffffffffffff1682565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff90911660208301520161026b565b3480156106a357600080fd5b507f000000000000000000000000000000000000000000000000000000000000000c6103dc565b3480156106d657600080fd5b50600154610732906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff928316602085015291169082015260600161026b565b6101f661077936600461548a565b6107ab565b34801561078a57600080fd5b5060385461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b8260005a905060006107bb6123e9565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906107f757503415155b1561082e576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61083c883489898989612486565b506108478282612632565b50505050505050565b8260005a905060006108606123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016108d2576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546108e49190615538565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610956573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097a9190615550565b905061099e73ffffffffffffffffffffffffffffffffffffffff831633308c6128ff565b6109a88982615538565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a369190615550565b14610a6d576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a7b8a8a8a8a8a8a612486565b5050610a878282612632565b5050505050505050565b610a99611531565b15610ad0576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead14610b23576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610b2e836129e1565b9050610b3a81836115c4565b6000818152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558401516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905580610bc56123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601610c2857610c218560400151866080015187606001518860a00151612a2e565b9150610e7b565b8073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610c91576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606085015115610e52578460600151603d6000828254610cb19190615569565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610d23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d479190615550565b9050610d7c866040015187606001518473ffffffffffffffffffffffffffffffffffffffff16612a8c9092919063ffffffff16565b6060860151610d8b9082615569565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e199190615550565b14610e50576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08501515115610e7657610c218560400151866080015160008860a00151612a2e565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405183907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90610edd90851515815260200190565b60405180910390a281158015610ef35750326001145b15610f2a576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fa0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615580565b905090565b610fd1611531565b15611008576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603611071576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6038546040517fbb8aa1fc00000000000000000000000000000000000000000000000000000000815260048101869052600091829173ffffffffffffffffffffffffffffffffffffffff9091169063bb8aa1fc90602401606060405180830381865afa1580156110e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611109919061559d565b925050915060008173ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561115b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117f9190615550565b603b5490915063ffffffff8481169116146111c6576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111dd6111d8368890038801886155ea565b612ae7565b8114611215576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611220896129e1565b905060018373ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611293919061567f565b60028111156112a4576112a4615650565b036112db576040517fd357347400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051602081018390526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506113a49101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f010000000000000000000000000000000000000000000000000000000000000060208301529061139a898b6156a0565b8b60400135612b26565b15156000036113df576040517fb05e92fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825273ffffffffffffffffffffffffffffffffffffffff808716825267ffffffffffffffff4281166020808501918252600088815260398252868120338252825286812095518654935190941674010000000000000000000000000000000000000000027fffffffff0000000000000000000000000000000000000000000000000000000090931693851693909317919091179093558d840151928e01519351928216939091169185917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f6291a4604051339083907f798f9f13695f8f045aa5f80ed8efebb695f3c7fe65da381969f2f28bf3c60b9790600090a3506000908152603c602090815260408220805460018101825590835291200180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115a0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615724565b600082815260396020908152604080832073ffffffffffffffffffffffffffffffffffffffff85811685529083528184208251808401845290549182168082527401000000000000000000000000000000000000000090920467ffffffffffffffff1681850152818552603a90935292205490919060ff1615611673576040517f09550c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816020015167ffffffffffffffff166000036116bb576040517f94efd49b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061173c8273ffffffffffffffffffffffffffffffffffffffff1663cf09e0d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172f9190615741565b67ffffffffffffffff1690565b90508067ffffffffffffffff16836020015167ffffffffffffffff1611611810576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e20646973707574652067616d65206372656160648201527f74696f6e2074696d657374616d70000000000000000000000000000000000000608482015260a4015b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000c836020015167ffffffffffffffff164261184b9190615569565b116118d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c20686173206e6f74206d6174757265642079657400000000000000000000006064820152608401611807565b60028273ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611925573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611949919061567f565b600281111561195a5761195a615650565b14611991576040517fa080a3c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5463ffffffff1663ffffffff16611a1b8373ffffffffffffffffffffffffffffffffffffffff1663bbdc02db6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a12919061575e565b63ffffffff1690565b63ffffffff1614611a58576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5467ffffffffffffffff64010000000090910481169082161015611b26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a20646973707574652067616d652063726560448201527f61746564206265666f7265207265737065637465642067616d6520747970652060648201527f7761732075706461746564000000000000000000000000000000000000000000608482015260a401611807565b7f0000000000000000000000000000000000000000000000000000000000000006611b958373ffffffffffffffffffffffffffffffffffffffff166319effeb46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b611ba99067ffffffffffffffff1642615569565b11611c36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f696e206169722d676170000000000000000000000000000000000000000000006064820152608401611807565b60008581526033602052604090205460ff1615610f2a576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60375473ffffffffffffffffffffffffffffffffffffffff163314611cd0576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611cdc62030d40612b4a565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f000000000000000000000000000000000000000000000000000000001790529051611df99695949392910161577b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052611e31916152f6565b60405180910390a450505050565b611e47610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611eab576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152603a602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f192c289026d59a41a27f5aea08f3969b57931b0589202d14f4368cded95d3cda9190a250565b611f2a610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f8e576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b805463ffffffff83167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090911681176401000000004267ffffffffffffffff90811682029290921793849055604051930416917f049fe9dd413cdf037cce27011cc1790c753118272f3630e6e8bdfa5e8208176090600090a350565b565b612016611531565b1561204d576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120578133610a91565b50565b600054610100900460ff161580801561207a5750600054600160ff909116105b806120945750303b158015612094575060005460ff166001145b612120576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611807565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561217e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603880547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8881169190911790925560378054909116868316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff16610100868416021790556032541661229e576032805461dead7fffffffffffffffffffffffff0000000000000000000000000000000000000000909116179055603b80547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166401000000004267ffffffffffffffff16027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000161763ffffffff84161790555b6122a6612bac565b8015610f2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600061231c8260106157e0565b61232890615208615810565b92915050565b603c602052816000526040600020818154811061234a57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169150829050565b60008061237e6123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016123c5574791505090565b5050603d5490565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015612459573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247d919061583c565b90939092509050565b8180156124a8575073ffffffffffffffffffffffffffffffffffffffff861615155b156124df576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6124e9815161230f565b67ffffffffffffffff168367ffffffffffffffff161015612536576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c081511115612574576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33328114612595575033731111000000000000000000000000000000001111015b600086868686866040516020016125b095949392919061577b565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161262091906152f6565b60405180910390a45050505050505050565b600154600090612668907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643615569565b90506000612674612cbf565b90506000816020015160ff16826000015163ffffffff16612695919061589a565b905082156127cc576001546000906126cc908390700100000000000000000000000000000000900467ffffffffffffffff16615902565b90506000836040015160ff16836126e39190615976565b6001546127039084906fffffffffffffffffffffffffffffffff16615976565b61270d919061589a565b60015490915060009061275e906127379084906fffffffffffffffffffffffffffffffff16615a32565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612d80565b9050600186111561278d5761278a61273782876040015160ff1660018a6127859190615569565b612d9f565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b600180548691906010906127ff908490700100000000000000000000000000000000900467ffffffffffffffff16615810565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff16131561288c576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906128b8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615aa6565b905060006128ca48633b9aca00612df4565b6128d49083615ae3565b905060005a6128e39088615569565b905080821115610a8757610a876128fa8284615569565b612e0b565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526129db9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612e34565b50505050565b80516020808301516040808501516060860151608087015160a08801519351600097612a11979096959101615af7565b604051602081830303815290604052805190602001209050919050565b6000806000612a3e866000612f40565b905080612a74576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052612ae29084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612959565b505050565b60008160000151826020015183604001518460600151604051602001612a11949392919093845260208401929092526040830152606082015260800190565b600080612b3286612f5e565b9050612b4081868686612f90565b9695505050505050565b6001805463ffffffff83169190601090612b83908490700100000000000000000000000000000000900467ffffffffffffffff16615810565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b600054610100900460ff16612c43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611807565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff1660000361200c5760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa158015612d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615b4e565b6000612d95612d8f8585612fc0565b83612fd0565b90505b9392505050565b6000670de0b6b3a7640000612de0612db7858361589a565b612dc990670de0b6b3a7640000615902565b612ddb85670de0b6b3a7640000615976565b612fdf565b612dea9086615976565b612d95919061589a565b600081831015612e045781612d98565b5090919050565b6000805a90505b825a612e1e9083615569565b1015612ae257612e2d82615bf0565b9150612e12565b6000612e96826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130109092919063ffffffff16565b805190915015612ae25780806020019051810190612eb49190615724565b612ae2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611807565b600080603f83619c4001026040850201603f5a021015949350505050565b60608180519060200120604051602001612f7a91815260200190565b6040516020818303038152906040529050919050565b6000612fb784612fa187868661301f565b8051602091820120825192909101919091201490565b95945050505050565b600081831215612e045781612d98565b6000818312612e045781612d98565b6000612d98670de0b6b3a764000083612ff786613a9d565b6130019190615976565b61300b919061589a565b613ce1565b6060612d958484600085613f20565b6060600084511161308c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401611807565b6000613097846140b6565b905060006130a4866141a2565b90506000846040516020016130bb91815260200190565b60405160208183030381529060405290506000805b8451811015613a145760008582815181106130ed576130ed615c28565b602002602001015190508451831115613188576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401611807565b8260000361324157805180516020918201206040516131d6926131b092910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b61323c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401611807565b613398565b8051516020116132f7578051805160209182012060405161326b926131b092910190815260200190565b61323c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401611807565b805184516020808701919091208251919092012014613398576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401611807565b6133a460106001615538565b816020015151036135805784518303613518576133de81602001516010815181106133d1576133d1615c28565b6020026020010151614205565b96506000875111613471576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401611807565b6001865161347f9190615569565b821461350d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401611807565b505050505050612d98565b600085848151811061352c5761352c615c28565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061355757613557615c28565b6020026020010151905061356a816142b9565b9550613577600186615538565b94505050613a01565b600281602001515103613979576000613598826142de565b90506000816000815181106135af576135af615c28565b016020015160f81c905060006135c6600283615c57565b6135d1906002615c79565b905060006135e2848360ff16614302565b905060006135f08a89614302565b905060006135fe8383614338565b905080835114613690576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401611807565b60ff8516600214806136a5575060ff85166003145b15613894578082511461373a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401611807565b61375487602001516001815181106133d1576133d1615c28565b9c5060008d51116137e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401611807565b60018c516137f59190615569565b8814613883576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401611807565b505050505050505050505050612d98565b60ff851615806138a7575060ff85166001145b156138e6576138d387602001516001815181106138c6576138c6615c28565b60200260200101516142b9565b99506138df818a615538565b985061396e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401611807565b505050505050613a01565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401611807565b5080613a0c81615bf0565b9150506130d0565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401611807565b6000808213613b08576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b60006060613b15846143ec565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c18213613d1257506000919050565b680755bf798b4a1bf1e58212613d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401611807565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613fb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611807565b73ffffffffffffffffffffffffffffffffffffffff85163b614030576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611807565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516140599190615c9c565b60006040518083038185875af1925050503d8060008114614096576040519150601f19603f3d011682016040523d82523d6000602084013e61409b565b606091505b50915091506140ab8282866144c2565b979650505050505050565b80516060908067ffffffffffffffff8111156140d4576140d4614eb1565b60405190808252806020026020018201604052801561411957816020015b60408051808201909152606080825260208201528152602001906001900390816140f25790505b50915060005b8181101561419b57604051806040016040528085838151811061414457614144615c28565b6020026020010151815260200161417386848151811061416657614166615c28565b6020026020010151614515565b81525083828151811061418857614188615c28565b602090810291909101015260010161411f565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b838110156141fa578060011b82018184015160001a8060041c8253600f8116600183015350506001016141cc565b509295945050505050565b6060600080600061421585614528565b91945092509050600081600181111561423057614230615650565b14614267576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6142718284615538565b8551146142aa576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fb7856020015184846149c6565b606060208260000151106142d5576142d082614205565b612328565b61232882614a5a565b60606123286142fd83602001516000815181106133d1576133d1615c28565b6141a2565b6060825182106143215750604080516020810190915260008152612328565b612d9883838486516143339190615569565b614a70565b600080825184511061434b57825161434e565b83515b90505b80821080156143d5575082828151811061436d5761436d615c28565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168483815181106143ac576143ac615c28565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156143e557816001019150614351565b5092915050565b6000808211614457576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606083156144d1575081612d98565b8251156144e15782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180791906152f6565b606061232861452383614c48565b614cb5565b6000806000836000015160000361456b576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f81116145905760006001600094509450945050506149bf565b60b781116146a65760006145a5608083615569565b9050808760000151116145e4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214801561465c57507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614693576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600195509350600092506149bf915050565b60bf81116148045760006146bb60b783615569565b9050808760000151116146fa576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361475c576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116147a4576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147ae8184615538565b8951116147e7576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147f2836001615538565b97509550600094506149bf9350505050565b60f7811161486957600061481960c083615569565b905080876000015111614858576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001955093508492506149bf915050565b600061487660f783615569565b9050808760000151116148b5576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614917576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c6037811161495f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6149698184615538565b8951116149a2576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6149ad836001615538565b97509550600194506149bf9350505050565b9193909250565b60608167ffffffffffffffff8111156149e1576149e1614eb1565b6040519080825280601f01601f191660200182016040528015614a0b576020820181803683370190505b5090508115612d98576000614a208486615538565b90506020820160005b84811015614a41578281015182820152602001614a29565b84811115614a50576000858301525b5050509392505050565b60606123288260200151600084600001516149c6565b60608182601f011015614adf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b828284011015614b4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b81830184511015614bb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401611807565b606082158015614bd75760405191506000825260208201604052614c3f565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614c10578051835260209283019201614bf8565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201528151600003614c97576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000614cc585614528565b919450925090506001816001811115614ce057614ce0615650565b14614d17576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451614d238385615538565b14614d5a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081614d715790505093506000835b8651811015614e5f57600080614de46040518060400160405280858c60000151614dc89190615569565b8152602001858c60200151614ddd9190615538565b9052614528565b509150915060405180604001604052808383614e009190615538565b8152602001848b60200151614e159190615538565b815250888581518110614e2a57614e2a615c28565b6020908102919091010152614e40600185615538565b9350614e4c8183615538565b614e569084615538565b92505050614d9e565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461205757600080fd5b67ffffffffffffffff8116811461205757600080fd5b801515811461205757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715614f0357614f03614eb1565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614f5057614f50614eb1565b604052919050565b600082601f830112614f6957600080fd5b813567ffffffffffffffff811115614f8357614f83614eb1565b614fb460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614f09565b818152846020838601011115614fc957600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614fff57600080fd5b863561500a81614e6b565b95506020870135945060408701359350606087013561502881614e8d565b9250608087013561503881614ea3565b915060a087013567ffffffffffffffff81111561505457600080fd5b61506089828a01614f58565b9150509295509295509295565b600060c0828403121561507f57600080fd5b60405160c0810167ffffffffffffffff82821081831117156150a3576150a3614eb1565b8160405282935084358352602085013591506150be82614e6b565b816020840152604085013591506150d482614e6b565b816040840152606085013560608401526080850135608084015260a085013591508082111561510257600080fd5b5061510f85828601614f58565b60a0830152505092915050565b6000806040838503121561512f57600080fd5b823567ffffffffffffffff81111561514657600080fd5b6151528582860161506d565b925050602083013561516381614e6b565b809150509250929050565b60006020828403121561518057600080fd5b8135612d9881614e6b565b600080600080600085870360e08112156151a457600080fd5b863567ffffffffffffffff808211156151bc57600080fd5b6151c88a838b0161506d565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401121561520157600080fd5b60408901955060c089013592508083111561521b57600080fd5b828901925089601f84011261522f57600080fd5b823591508082111561524057600080fd5b508860208260051b840101111561525657600080fd5b959894975092955050506020019190565b60006020828403121561527957600080fd5b5035919050565b60005b8381101561529b578181015183820152602001615283565b838111156129db5750506000910152565b600081518084526152c4816020860160208601615280565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612d9860208301846152ac565b6000806040838503121561531c57600080fd5b82359150602083013561516381614e6b565b60ff8116811461205757600080fd5b6000806000806080858703121561535357600080fd5b843561535e81614e6b565b9350602085013561536e8161532e565b93969395505050506040820135916060013590565b63ffffffff8116811461205757600080fd5b6000602082840312156153a757600080fd5b8135612d9881615383565b6000602082840312156153c457600080fd5b813567ffffffffffffffff8111156153db57600080fd5b6153e78482850161506d565b949350505050565b6000806000806080858703121561540557600080fd5b843561541081614e6b565b9350602085013561542081614e6b565b9250604085013561543081614e6b565b9150606085013561544081615383565b939692955090935050565b60006020828403121561545d57600080fd5b8135612d9881614e8d565b6000806040838503121561547b57600080fd5b50508035926020909101359150565b600080600080600060a086880312156154a257600080fd5b85356154ad81614e6b565b94506020860135935060408601356154c481614e8d565b925060608601356154d481614ea3565b9150608086013567ffffffffffffffff8111156154f057600080fd5b6154fc88828901614f58565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561554b5761554b615509565b500190565b60006020828403121561556257600080fd5b5051919050565b60008282101561557b5761557b615509565b500390565b60006020828403121561559257600080fd5b8151612d9881614e6b565b6000806000606084860312156155b257600080fd5b83516155bd81615383565b60208501519093506155ce81614e8d565b60408501519092506155df81614e6b565b809150509250925092565b6000608082840312156155fc57600080fd5b6040516080810181811067ffffffffffffffff8211171561561f5761561f614eb1565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006020828403121561569157600080fd5b815160038110612d9857600080fd5b600067ffffffffffffffff808411156156bb576156bb614eb1565b8360051b60206156cc818301614f09565b8681529185019181810190368411156156e457600080fd5b865b84811015615718578035868111156156fe5760008081fd5b61570a36828b01614f58565b8452509183019183016156e6565b50979650505050505050565b60006020828403121561573657600080fd5b8151612d9881614ea3565b60006020828403121561575357600080fd5b8151612d9881614e8d565b60006020828403121561577057600080fd5b8151612d9881615383565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b6048820152600082516157cf816049850160208701615280565b919091016049019695505050505050565b600067ffffffffffffffff8083168185168183048111821515161561580757615807615509565b02949350505050565b600067ffffffffffffffff80831681851680830382111561583357615833615509565b01949350505050565b6000806040838503121561584f57600080fd5b825161585a81614e6b565b60208401519092506151638161532e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826158a9576158a961586b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156158fd576158fd615509565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561593c5761593c615509565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561597057615970615509565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156159b7576159b7615509565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156159f2576159f2615509565b60008712925087820587128484161615615a0e57615a0e615509565b87850587128184161615615a2457615a24615509565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03841381151615615a6c57615a6c615509565b827f8000000000000000000000000000000000000000000000000000000000000000038412811615615aa057615aa0615509565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615ade57615ade615509565b500290565b600082615af257615af261586b565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152615b4260c08301846152ac565b98975050505050505050565b600060c08284031215615b6057600080fd5b615b68614ee0565b8251615b7381615383565b81526020830151615b838161532e565b60208201526040830151615b968161532e565b60408201526060830151615ba981615383565b60608201526080830151615bbc81615383565b608082015260a08301516fffffffffffffffffffffffffffffffff81168114615be457600080fd5b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615c2157615c21615509565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff831680615c6a57615c6a61586b565b8060ff84160691505092915050565b600060ff821660ff841680821015615c9357615c93615509565b90039392505050565b60008251615cae818460208701615280565b919091019291505056fea164736f6c634300080f000a"; + hex"6080604052600436106101d15760003560e01c80637fc48504116100f7578063a35d99df11610095578063bf653a5c11610064578063bf653a5c14610697578063cff0ab96146106ca578063e9e05c421461076b578063f2b4e6171461077e57600080fd5b8063a35d99df1461059b578063a3860f48146105bb578063b69ef8a8146105db578063bb2c727e146105f057600080fd5b80638e819e54116100d15780638e819e54146104eb578063952b27971461050b5780639bf62d821461053e578063a14238e71461056b57600080fd5b80637fc48504146104ab5780638b4c40b0146101f65780638c3152e9146104cb57600080fd5b80634870496f1161016f5780635c975abb1161013e5780635c975abb1461043657806371c1566e1461044b57806371cfaa3f1461046b5780637d6be8dc1461048b57600080fd5b80634870496f1461034d5780634fd0434c1461036d578063513747ab146103af57806354fd4d50146103ea57600080fd5b80633c9f397c116101ab5780633c9f397c146102a657806343ca1c50146102d8578063452a9320146102f857806345884d321461030d57600080fd5b8063149f2f22146101fd57806333d7e2bd1461021d57806335e80ab31461027457600080fd5b366101f8576101f63334620186a06000604051806020016040528060008152506107ab565b005b600080fd5b34801561020957600080fd5b506101f6610218366004614feb565b610850565b34801561022957600080fd5b5060375461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561028057600080fd5b5060355461024a90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156102b257600080fd5b50603b546102c39063ffffffff1681565b60405163ffffffff909116815260200161026b565b3480156102e457600080fd5b506101f66102f3366004615121565b610a91565b34801561030457600080fd5b5061024a610f31565b34801561031957600080fd5b5061033d610328366004615173565b603a6020526000908152604090205460ff1681565b604051901515815260200161026b565b34801561035957600080fd5b506101f6610368366004615190565b610fc9565b34801561037957600080fd5b50603b5461039690640100000000900467ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161026b565b3480156103bb57600080fd5b506103dc6103ca36600461526c565b6000908152603c602052604090205490565b60405190815260200161026b565b3480156103f657600080fd5b50604080518082018252600d81527f332e31312e302d626574612e33000000000000000000000000000000000000006020820152905161026b91906152fb565b34801561044257600080fd5b5061033d611531565b34801561045757600080fd5b506101f661046636600461530e565b6115c4565b34801561047757600080fd5b506101f6610486366004615342565b611c7f565b34801561049757600080fd5b506101f66104a6366004615173565b611e3f565b3480156104b757600080fd5b506101f66104c636600461539a565b611f22565b3480156104d757600080fd5b506101f66104e63660046153b7565b61200e565b3480156104f757600080fd5b506101f66105063660046153f4565b61205a565b34801561051757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000066103dc565b34801561054a57600080fd5b5060325461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561057757600080fd5b5061033d61058636600461526c565b60336020526000908152604090205460ff1681565b3480156105a757600080fd5b506103966105b6366004615450565b61230f565b3480156105c757600080fd5b5061024a6105d636600461546d565b61232e565b3480156105e757600080fd5b506103dc612373565b3480156105fc57600080fd5b5061066261060b36600461530e565b603960209081526000928352604080842090915290825290205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900467ffffffffffffffff1682565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff90911660208301520161026b565b3480156106a357600080fd5b507f000000000000000000000000000000000000000000000000000000000000000c6103dc565b3480156106d657600080fd5b50600154610732906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff928316602085015291169082015260600161026b565b6101f661077936600461548f565b6107ab565b34801561078a57600080fd5b5060385461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b8260005a905060006107bb6123e9565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906107f757503415155b1561082e576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61083c883489898989612486565b506108478282612632565b50505050505050565b8260005a905060006108606123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016108d2576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546108e4919061553d565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610956573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097a9190615555565b905061099e73ffffffffffffffffffffffffffffffffffffffff831633308c6128ff565b6109a8898261553d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a369190615555565b14610a6d576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a7b8a8a8a8a8a8a612486565b5050610a878282612632565b5050505050505050565b610a99611531565b15610ad0576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead14610b23576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610b2e836129e1565b9050610b3a81836115c4565b6000818152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558401516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905580610bc56123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601610c2857610c218560400151866080015187606001518860a00151612a2e565b9150610e7b565b8073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610c91576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606085015115610e52578460600151603d6000828254610cb1919061556e565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610d23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d479190615555565b9050610d7c866040015187606001518473ffffffffffffffffffffffffffffffffffffffff16612a8c9092919063ffffffff16565b6060860151610d8b908261556e565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e199190615555565b14610e50576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08501515115610e7657610c218560400151866080015160008860a00151612a2e565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405183907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90610edd90851515815260200190565b60405180910390a281158015610ef35750326001145b15610f2a576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fa0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615585565b905090565b610fd1611531565b15611008576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603611071576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6038546040517fbb8aa1fc00000000000000000000000000000000000000000000000000000000815260048101869052600091829173ffffffffffffffffffffffffffffffffffffffff9091169063bb8aa1fc90602401606060405180830381865afa1580156110e5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110991906155a2565b925050915060008173ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561115b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117f9190615555565b603b5490915063ffffffff8481169116146111c6576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111dd6111d8368890038801886155ef565b612ae7565b8114611215576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611220896129e1565b905060018373ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112939190615684565b60028111156112a4576112a4615655565b036112db576040517fd357347400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051602081018390526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506113a49101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f010000000000000000000000000000000000000000000000000000000000000060208301529061139a898b6156a5565b8b60400135612b26565b15156000036113df576040517fb05e92fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825273ffffffffffffffffffffffffffffffffffffffff808716825267ffffffffffffffff4281166020808501918252600088815260398252868120338252825286812095518654935190941674010000000000000000000000000000000000000000027fffffffff0000000000000000000000000000000000000000000000000000000090931693851693909317919091179093558d840151928e01519351928216939091169185917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f6291a4604051339083907f798f9f13695f8f045aa5f80ed8efebb695f3c7fe65da381969f2f28bf3c60b9790600090a3506000908152603c602090815260408220805460018101825590835291200180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115a0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615729565b600082815260396020908152604080832073ffffffffffffffffffffffffffffffffffffffff85811685529083528184208251808401845290549182168082527401000000000000000000000000000000000000000090920467ffffffffffffffff1681850152818552603a90935292205490919060ff1615611673576040517f09550c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816020015167ffffffffffffffff166000036116bb576040517f94efd49b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061173c8273ffffffffffffffffffffffffffffffffffffffff1663cf09e0d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172f9190615746565b67ffffffffffffffff1690565b90508067ffffffffffffffff16836020015167ffffffffffffffff1611611810576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e20646973707574652067616d65206372656160648201527f74696f6e2074696d657374616d70000000000000000000000000000000000000608482015260a4015b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000c836020015167ffffffffffffffff164261184b919061556e565b116118d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c20686173206e6f74206d6174757265642079657400000000000000000000006064820152608401611807565b60028273ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611925573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119499190615684565b600281111561195a5761195a615655565b14611991576040517fa080a3c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5463ffffffff1663ffffffff16611a1b8373ffffffffffffffffffffffffffffffffffffffff1663bbdc02db6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a129190615763565b63ffffffff1690565b63ffffffff1614611a58576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5467ffffffffffffffff64010000000090910481169082161015611b26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a20646973707574652067616d652063726560448201527f61746564206265666f7265207265737065637465642067616d6520747970652060648201527f7761732075706461746564000000000000000000000000000000000000000000608482015260a401611807565b7f0000000000000000000000000000000000000000000000000000000000000006611b958373ffffffffffffffffffffffffffffffffffffffff166319effeb46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b611ba99067ffffffffffffffff164261556e565b11611c36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f696e206169722d676170000000000000000000000000000000000000000000006064820152608401611807565b60008581526033602052604090205460ff1615610f2a576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60375473ffffffffffffffffffffffffffffffffffffffff163314611cd0576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611cdc62030d40612b4a565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f000000000000000000000000000000000000000000000000000000001790529051611df996959493929101615780565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052611e31916152fb565b60405180910390a450505050565b611e47610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611eab576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152603a602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f192c289026d59a41a27f5aea08f3969b57931b0589202d14f4368cded95d3cda9190a250565b611f2a610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f8e576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b805463ffffffff83167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090911681176401000000004267ffffffffffffffff90811682029290921793849055604051930416917f049fe9dd413cdf037cce27011cc1790c753118272f3630e6e8bdfa5e8208176090600090a350565b565b612016611531565b1561204d576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120578133610a91565b50565b600054610100900460ff161580801561207a5750600054600160ff909116105b806120945750303b158015612094575060005460ff166001145b612120576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611807565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561217e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603880547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8881169190911790925560378054909116868316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff16610100868416021790556032541661229e576032805461dead7fffffffffffffffffffffffff0000000000000000000000000000000000000000909116179055603b80547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166401000000004267ffffffffffffffff16027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000161763ffffffff84161790555b6122a6612bac565b8015610f2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600061231c8260106157e5565b61232890615208615815565b92915050565b603c602052816000526040600020818154811061234a57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169150829050565b60008061237e6123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016123c5574791505090565b5050603d5490565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015612459573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247d9190615841565b90939092509050565b8180156124a8575073ffffffffffffffffffffffffffffffffffffffff861615155b156124df576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6124e9815161230f565b67ffffffffffffffff168367ffffffffffffffff161015612536576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c081511115612574576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33328114612595575033731111000000000000000000000000000000001111015b600086868686866040516020016125b0959493929190615780565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161262091906152fb565b60405180910390a45050505050505050565b600154600090612668907801000000000000000000000000000000000000000000000000900467ffffffffffffffff164361556e565b90506000612674612cbf565b90506000816020015160ff16826000015163ffffffff16612695919061589f565b905082156127cc576001546000906126cc908390700100000000000000000000000000000000900467ffffffffffffffff16615907565b90506000836040015160ff16836126e3919061597b565b6001546127039084906fffffffffffffffffffffffffffffffff1661597b565b61270d919061589f565b60015490915060009061275e906127379084906fffffffffffffffffffffffffffffffff16615a37565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612d85565b9050600186111561278d5761278a61273782876040015160ff1660018a612785919061556e565b612da4565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b600180548691906010906127ff908490700100000000000000000000000000000000900467ffffffffffffffff16615815565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff16131561288c576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906128b8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615aab565b905060006128ca48633b9aca00612df9565b6128d49083615ae8565b905060005a6128e3908861556e565b905080821115610a8757610a876128fa828461556e565b612e10565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526129db9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612e39565b50505050565b80516020808301516040808501516060860151608087015160a08801519351600097612a11979096959101615afc565b604051602081830303815290604052805190602001209050919050565b6000806000612a3e866000612f45565b905080612a74576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052612ae29084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612959565b505050565b60008160000151826020015183604001518460600151604051602001612a11949392919093845260208401929092526040830152606082015260800190565b600080612b3286612f63565b9050612b4081868686612f95565b9695505050505050565b6001805463ffffffff83169190601090612b83908490700100000000000000000000000000000000900467ffffffffffffffff16615815565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b600054610100900460ff16612c43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611807565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff1660000361200c5760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152603754604080517fcc731b02000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163cc731b029160048083019260c09291908290030181865afa158015612d61573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123289190615b53565b6000612d9a612d948585612fc5565b83612fd5565b90505b9392505050565b6000670de0b6b3a7640000612de5612dbc858361589f565b612dce90670de0b6b3a7640000615907565b612de085670de0b6b3a764000061597b565b612fe4565b612def908661597b565b612d9a919061589f565b600081831015612e095781612d9d565b5090919050565b6000805a90505b825a612e23908361556e565b1015612ae257612e3282615bf5565b9150612e17565b6000612e9b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130159092919063ffffffff16565b805190915015612ae25780806020019051810190612eb99190615729565b612ae2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611807565b600080603f83619c4001026040850201603f5a021015949350505050565b60608180519060200120604051602001612f7f91815260200190565b6040516020818303038152906040529050919050565b6000612fbc84612fa6878686613024565b8051602091820120825192909101919091201490565b95945050505050565b600081831215612e095781612d9d565b6000818312612e095781612d9d565b6000612d9d670de0b6b3a764000083612ffc86613aa2565b613006919061597b565b613010919061589f565b613ce6565b6060612d9a8484600085613f25565b60606000845111613091576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401611807565b600061309c846140bb565b905060006130a9866141a7565b90506000846040516020016130c091815260200190565b60405160208183030381529060405290506000805b8451811015613a195760008582815181106130f2576130f2615c2d565b60200260200101519050845183111561318d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401611807565b8260000361324657805180516020918201206040516131db926131b592910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b613241576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401611807565b61339d565b8051516020116132fc5780518051602091820120604051613270926131b592910190815260200190565b613241576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401611807565b80518451602080870191909120825191909201201461339d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401611807565b6133a96010600161553d565b81602001515103613585578451830361351d576133e381602001516010815181106133d6576133d6615c2d565b602002602001015161420a565b96506000875111613476576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401611807565b60018651613484919061556e565b8214613512576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401611807565b505050505050612d9d565b600085848151811061353157613531615c2d565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061355c5761355c615c2d565b6020026020010151905061356f816142be565b955061357c60018661553d565b94505050613a06565b60028160200151510361397e57600061359d826142e3565b90506000816000815181106135b4576135b4615c2d565b016020015160f81c905060006135cb600283615c5c565b6135d6906002615c7e565b905060006135e7848360ff16614307565b905060006135f58a89614307565b90506000613603838361433d565b905080835114613695576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401611807565b60ff8516600214806136aa575060ff85166003145b15613899578082511461373f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401611807565b61375987602001516001815181106133d6576133d6615c2d565b9c5060008d51116137ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401611807565b60018c516137fa919061556e565b8814613888576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401611807565b505050505050505050505050612d9d565b60ff851615806138ac575060ff85166001145b156138eb576138d887602001516001815181106138cb576138cb615c2d565b60200260200101516142be565b99506138e4818a61553d565b9850613973565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401611807565b505050505050613a06565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401611807565b5080613a1181615bf5565b9150506130d5565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401611807565b6000808213613b0d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b60006060613b1a846143f1565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c18213613d1757506000919050565b680755bf798b4a1bf1e58212613d89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401611807565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613fb7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611807565b73ffffffffffffffffffffffffffffffffffffffff85163b614035576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611807565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161405e9190615ca1565b60006040518083038185875af1925050503d806000811461409b576040519150601f19603f3d011682016040523d82523d6000602084013e6140a0565b606091505b50915091506140b08282866144c7565b979650505050505050565b80516060908067ffffffffffffffff8111156140d9576140d9614eb6565b60405190808252806020026020018201604052801561411e57816020015b60408051808201909152606080825260208201528152602001906001900390816140f75790505b50915060005b818110156141a057604051806040016040528085838151811061414957614149615c2d565b6020026020010151815260200161417886848151811061416b5761416b615c2d565b602002602001015161451a565b81525083828151811061418d5761418d615c2d565b6020908102919091010152600101614124565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b838110156141ff578060011b82018184015160001a8060041c8253600f8116600183015350506001016141d1565b509295945050505050565b6060600080600061421a8561452d565b91945092509050600081600181111561423557614235615655565b1461426c576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614276828461553d565b8551146142af576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fbc856020015184846149cb565b606060208260000151106142da576142d58261420a565b612328565b61232882614a5f565b606061232861430283602001516000815181106133d6576133d6615c2d565b6141a7565b6060825182106143265750604080516020810190915260008152612328565b612d9d8383848651614338919061556e565b614a75565b6000808251845110614350578251614353565b83515b90505b80821080156143da575082828151811061437257614372615c2d565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168483815181106143b1576143b1615c2d565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156143ea57816001019150614356565b5092915050565b600080821161445c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606083156144d6575081612d9d565b8251156144e65782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180791906152fb565b606061232861452883614c4d565b614cba565b60008060008360000151600003614570576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f81116145955760006001600094509450945050506149c4565b60b781116146ab5760006145aa60808361556e565b9050808760000151116145e9576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214801561466157507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614698576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600195509350600092506149c4915050565b60bf81116148095760006146c060b78361556e565b9050808760000151116146ff576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614761576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116147a9576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147b3818461553d565b8951116147ec576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147f783600161553d565b97509550600094506149c49350505050565b60f7811161486e57600061481e60c08361556e565b90508087600001511161485d576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001955093508492506149c4915050565b600061487b60f78361556e565b9050808760000151116148ba576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361491c576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614964576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61496e818461553d565b8951116149a7576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6149b283600161553d565b97509550600194506149c49350505050565b9193909250565b60608167ffffffffffffffff8111156149e6576149e6614eb6565b6040519080825280601f01601f191660200182016040528015614a10576020820181803683370190505b5090508115612d9d576000614a25848661553d565b90506020820160005b84811015614a46578281015182820152602001614a2e565b84811115614a55576000858301525b5050509392505050565b60606123288260200151600084600001516149cb565b60608182601f011015614ae4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b828284011015614b50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b81830184511015614bbd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401611807565b606082158015614bdc5760405191506000825260208201604052614c44565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614c15578051835260209283019201614bfd565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201528151600003614c9c576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000614cca8561452d565b919450925090506001816001811115614ce557614ce5615655565b14614d1c576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451614d28838561553d565b14614d5f576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081614d765790505093506000835b8651811015614e6457600080614de96040518060400160405280858c60000151614dcd919061556e565b8152602001858c60200151614de2919061553d565b905261452d565b509150915060405180604001604052808383614e05919061553d565b8152602001848b60200151614e1a919061553d565b815250888581518110614e2f57614e2f615c2d565b6020908102919091010152614e4560018561553d565b9350614e51818361553d565b614e5b908461553d565b92505050614da3565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461205757600080fd5b67ffffffffffffffff8116811461205757600080fd5b801515811461205757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715614f0857614f08614eb6565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614f5557614f55614eb6565b604052919050565b600082601f830112614f6e57600080fd5b813567ffffffffffffffff811115614f8857614f88614eb6565b614fb960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614f0e565b818152846020838601011115614fce57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c0878903121561500457600080fd5b863561500f81614e70565b95506020870135945060408701359350606087013561502d81614e92565b9250608087013561503d81614ea8565b915060a087013567ffffffffffffffff81111561505957600080fd5b61506589828a01614f5d565b9150509295509295509295565b600060c0828403121561508457600080fd5b60405160c0810167ffffffffffffffff82821081831117156150a8576150a8614eb6565b8160405282935084358352602085013591506150c382614e70565b816020840152604085013591506150d982614e70565b816040840152606085013560608401526080850135608084015260a085013591508082111561510757600080fd5b5061511485828601614f5d565b60a0830152505092915050565b6000806040838503121561513457600080fd5b823567ffffffffffffffff81111561514b57600080fd5b61515785828601615072565b925050602083013561516881614e70565b809150509250929050565b60006020828403121561518557600080fd5b8135612d9d81614e70565b600080600080600085870360e08112156151a957600080fd5b863567ffffffffffffffff808211156151c157600080fd5b6151cd8a838b01615072565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401121561520657600080fd5b60408901955060c089013592508083111561522057600080fd5b828901925089601f84011261523457600080fd5b823591508082111561524557600080fd5b508860208260051b840101111561525b57600080fd5b959894975092955050506020019190565b60006020828403121561527e57600080fd5b5035919050565b60005b838110156152a0578181015183820152602001615288565b838111156129db5750506000910152565b600081518084526152c9816020860160208601615285565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612d9d60208301846152b1565b6000806040838503121561532157600080fd5b82359150602083013561516881614e70565b60ff8116811461205757600080fd5b6000806000806080858703121561535857600080fd5b843561536381614e70565b9350602085013561537381615333565b93969395505050506040820135916060013590565b63ffffffff8116811461205757600080fd5b6000602082840312156153ac57600080fd5b8135612d9d81615388565b6000602082840312156153c957600080fd5b813567ffffffffffffffff8111156153e057600080fd5b6153ec84828501615072565b949350505050565b6000806000806080858703121561540a57600080fd5b843561541581614e70565b9350602085013561542581614e70565b9250604085013561543581614e70565b9150606085013561544581615388565b939692955090935050565b60006020828403121561546257600080fd5b8135612d9d81614e92565b6000806040838503121561548057600080fd5b50508035926020909101359150565b600080600080600060a086880312156154a757600080fd5b85356154b281614e70565b94506020860135935060408601356154c981614e92565b925060608601356154d981614ea8565b9150608086013567ffffffffffffffff8111156154f557600080fd5b61550188828901614f5d565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156155505761555061550e565b500190565b60006020828403121561556757600080fd5b5051919050565b6000828210156155805761558061550e565b500390565b60006020828403121561559757600080fd5b8151612d9d81614e70565b6000806000606084860312156155b757600080fd5b83516155c281615388565b60208501519093506155d381614e92565b60408501519092506155e481614e70565b809150509250925092565b60006080828403121561560157600080fd5b6040516080810181811067ffffffffffffffff8211171561562457615624614eb6565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006020828403121561569657600080fd5b815160038110612d9d57600080fd5b600067ffffffffffffffff808411156156c0576156c0614eb6565b8360051b60206156d1818301614f0e565b8681529185019181810190368411156156e957600080fd5b865b8481101561571d578035868111156157035760008081fd5b61570f36828b01614f5d565b8452509183019183016156eb565b50979650505050505050565b60006020828403121561573b57600080fd5b8151612d9d81614ea8565b60006020828403121561575857600080fd5b8151612d9d81614e92565b60006020828403121561577557600080fd5b8151612d9d81615388565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b6048820152600082516157d4816049850160208701615285565b919091016049019695505050505050565b600067ffffffffffffffff8083168185168183048111821515161561580c5761580c61550e565b02949350505050565b600067ffffffffffffffff8083168185168083038211156158385761583861550e565b01949350505050565b6000806040838503121561585457600080fd5b825161585f81614e70565b602084015190925061516881615333565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826158ae576158ae615870565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156159025761590261550e565b500590565b6000808312837f8000000000000000000000000000000000000000000000000000000000000000018312811516156159415761594161550e565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156159755761597561550e565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156159bc576159bc61550e565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156159f7576159f761550e565b60008712925087820587128484161615615a1357615a1361550e565b87850587128184161615615a2957615a2961550e565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03841381151615615a7157615a7161550e565b827f8000000000000000000000000000000000000000000000000000000000000000038412811615615aa557615aa561550e565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615ae357615ae361550e565b500290565b600082615af757615af7615870565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152615b4760c08301846152b1565b98975050505050505050565b600060c08284031215615b6557600080fd5b615b6d614ee5565b8251615b7881615388565b81526020830151615b8881615333565b60208201526040830151615b9b81615333565b60408201526060830151615bae81615388565b60608201526080830151615bc181615388565b608082015260a08301516fffffffffffffffffffffffffffffffff81168114615be957600080fd5b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615c2657615c2661550e565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff831680615c6f57615c6f615870565b8060ff84160691505092915050565b600060ff821660ff841680821015615c9857615c9861550e565b90039392505050565b60008251615cb3818460208701615285565b919091019291505056fea164736f6c634300080f000a"; bytes internal constant disputeGameFactoryCode = hex"6080604052600436106100e85760003560e01c80636593dc6e1161008a57806396cd97201161005957806396cd972014610313578063bb8aa1fc14610333578063c4d66de814610394578063f2fde38b146103b457600080fd5b80636593dc6e14610293578063715018a6146102c057806382ecf2f6146102d55780638da5cb5b146102e857600080fd5b8063254bd683116100c6578063254bd6831461019c5780634d1975b4146101c957806354fd4d50146101e85780635f0150cb1461023e57600080fd5b806314f6b1a3146100ed5780631b685b9e1461010f5780631e3342401461017c575b600080fd5b3480156100f957600080fd5b5061010d6101083660046110c6565b6103d4565b005b34801561011b57600080fd5b5061015261012a3660046110fd565b60656020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061010d610197366004611118565b61045e565b3480156101a857600080fd5b506101bc6101b7366004611142565b6104aa565b60405161017391906111ef565b3480156101d557600080fd5b506068545b604051908152602001610173565b3480156101f457600080fd5b506102316040518060400160405280600c81526020017f312e302e312d626574612e31000000000000000000000000000000000000000081525081565b60405161017391906112ac565b34801561024a57600080fd5b5061025e6102593660046112bf565b6106ee565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff909116602083015201610173565b34801561029f57600080fd5b506101da6102ae3660046110fd565b60666020526000908152604090205481565b3480156102cc57600080fd5b5061010d610741565b6101526102e33660046112bf565b610755565b3480156102f457600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff16610152565b34801561031f57600080fd5b506101da61032e3660046112bf565b6109ef565b34801561033f57600080fd5b5061035361034e366004611346565b610a28565b6040805163ffffffff909416845267ffffffffffffffff909216602084015273ffffffffffffffffffffffffffffffffffffffff1690820152606001610173565b3480156103a057600080fd5b5061010d6103af36600461135f565b610a91565b3480156103c057600080fd5b5061010d6103cf36600461135f565b610c2d565b6103dc610d00565b63ffffffff821660008181526065602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616908117909155905190917fff513d80e2c7fa487608f70a618dfbc0cf415699dc69588c747e8c71566c88de91a35050565b610466610d00565b63ffffffff8216600081815260666020526040808220849055518392917f74d6665c4b26d5596a5aa13d3014e0c06af4d322075a797f87b03cd4c5bc91ca91a35050565b606854606090831015806104bc575081155b6106e7575060408051600583901b8101602001909152825b8381116106e5576000606882815481106104f0576104f061137c565b600091825260209091200154905060e081901c60a082901c67ffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff831663ffffffff891683036106b6576001865101865260008173ffffffffffffffffffffffffffffffffffffffff1663609d33346040518163ffffffff1660e01b8152600401600060405180830381865afa15801561058a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d091908101906113da565b905060008273ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561061f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064391906114a5565b90506040518060a001604052808881526020018781526020018567ffffffffffffffff168152602001828152602001838152508860018a5161068591906114be565b815181106106955761069561137c565b6020026020010181905250888851106106b3575050505050506106e5565b50505b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191506104d49050565b505b9392505050565b60008060006106ff878787876109ef565b60009081526067602052604090205473ffffffffffffffffffffffffffffffffffffffff81169860a09190911c67ffffffffffffffff16975095505050505050565b610749610d00565b6107536000610d81565b565b63ffffffff841660009081526065602052604081205473ffffffffffffffffffffffffffffffffffffffff16806107c5576040517f031c6de400000000000000000000000000000000000000000000000000000000815263ffffffff871660048201526024015b60405180910390fd5b63ffffffff86166000908152606660205260409020543414610813576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006108206001436114be565b40905061088a338783888860405160200161083f9594939291906114fc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905273ffffffffffffffffffffffffffffffffffffffff841690610df8565b92508273ffffffffffffffffffffffffffffffffffffffff16638129fc1c346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156108d457600080fd5b505af11580156108e8573d6000803e3d6000fd5b505050505060006108fb888888886109ef565b60008181526067602052604090205490915015610947576040517f014f6fe5000000000000000000000000000000000000000000000000000000008152600481018290526024016107bc565b60004260a01b60e08a901b178517600083815260676020526040808220839055606880546001810182559083527fa2153420d844928b4421650203c77babc8b33d7f2e7b450e2966db0c220977530183905551919250899163ffffffff8c169173ffffffffffffffffffffffffffffffffffffffff8916917f5b565efe82411da98814f356d0e7bcb8f0219b8d970307c5afb4a6903a8b2e359190a450505050949350505050565b600084848484604051602001610a089493929190611549565b604051602081830303815290604052805190602001209050949350505050565b600080600080600080610a8160688881548110610a4757610a4761137c565b906000526020600020015460e081901c9160a082901c67ffffffffffffffff169173ffffffffffffffffffffffffffffffffffffffff1690565b9199909850909650945050505050565b600054610100900460ff1615808015610ab15750600054600160ff909116105b80610acb5750303b158015610acb575060005460ff166001145b610b57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107bc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610bb557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610bbd610e06565b610bc682610d81565b8015610c2957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b610c35610d00565b73ffffffffffffffffffffffffffffffffffffffff8116610cd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016107bc565b610ce181610d81565b50565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60335473ffffffffffffffffffffffffffffffffffffffff163314610753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107bc565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006106e760008484610ea5565b600054610100900460ff16610e9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b610753610feb565b600060608203516040830351602084035184518060208701018051600283016c5af43d3d93803e606057fd5bf3895289600d8a035278593da1005b363d3d373d3d3d3d610000806062363936013d738160481b1760218a03527f9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff603a8a035272fd6100003d81600a3d39f336602c57343d527f6062820160781b1761ff9e82106059018a03528060f01b8352606c8101604c8a038cf097505086610f715763301164256000526004601cfd5b905285527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08501527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa09092019190915292915050565b600054610100900460ff16611082576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b61075333610d81565b803563ffffffff8116811461109f57600080fd5b919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610ce157600080fd5b600080604083850312156110d957600080fd5b6110e28361108b565b915060208301356110f2816110a4565b809150509250929050565b60006020828403121561110f57600080fd5b6106e78261108b565b6000806040838503121561112b57600080fd5b6111348361108b565b946020939093013593505050565b60008060006060848603121561115757600080fd5b6111608461108b565b95602085013595506040909401359392505050565b60005b83811015611190578181015183820152602001611178565b8381111561119f576000848401525b50505050565b600081518084526111bd816020860160208601611175565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561129e578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001855281518051845287810151888501528681015167ffffffffffffffff16878501526060808201519085015260809081015160a09185018290529061128a818601836111a5565b968901969450505090860190600101611216565b509098975050505050505050565b6020815260006106e760208301846111a5565b600080600080606085870312156112d557600080fd5b6112de8561108b565b935060208501359250604085013567ffffffffffffffff8082111561130257600080fd5b818701915087601f83011261131657600080fd5b81358181111561132557600080fd5b88602082850101111561133757600080fd5b95989497505060200194505050565b60006020828403121561135857600080fd5b5035919050565b60006020828403121561137157600080fd5b81356106e7816110a4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156113ec57600080fd5b815167ffffffffffffffff8082111561140457600080fd5b818401915084601f83011261141857600080fd5b81518181111561142a5761142a6113ab565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611470576114706113ab565b8160405282815287602084870101111561148957600080fd5b61149a836020830160208801611175565b979650505050505050565b6000602082840312156114b757600080fd5b5051919050565b6000828210156114f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500390565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008660601b1681528460148201528360348201528183605483013760009101605401908152949350505050565b63ffffffff8516815283602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101939250505056fea164736f6c634300080f000a"; bytes internal constant delayedWETHCode = @@ -67,11 +67,11 @@ contract DeploymentSummaryCode { bytes internal constant preimageOracleCode = hex"6080604052600436106101d85760003560e01c80639d53a64811610102578063ddcd58de11610095578063ec5efcbc11610064578063ec5efcbc14610681578063f3f480d9146106a1578063faf37bc7146106d4578063fef2b4ed146106e757600080fd5b8063ddcd58de146105d4578063e03110e11461060c578063e159261114610641578063ea7139501461066157600080fd5b8063b5e7154c116100d1578063b5e7154c14610555578063d18534b51461056c578063da35c6641461058c578063dd24f9bf146105a157600080fd5b80639d53a6481461048e5780639d7e8769146104dd578063b2e67ba8146104fd578063b4801e611461053557600080fd5b806361238bde1161017a5780637ac54767116101495780637ac54767146103ca5780638542cf50146103ea578063882856ef146104355780638dc4be111461046e57600080fd5b806361238bde1461031e5780636551927b146103565780637051472e1461038e5780637917de1d146103aa57600080fd5b80633909af5c116101b65780633909af5c146102715780634d52b4c91461029357806352f0f3ad146102a857806354fd4d50146102c857600080fd5b8063013cf08b146101dd5780630359a5631461022e5780632055b36b1461025c575b600080fd5b3480156101e957600080fd5b506101fd6101f8366004612e29565b610714565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526020830191909152015b60405180910390f35b34801561023a57600080fd5b5061024e610249366004612e6b565b610759565b604051908152602001610225565b34801561026857600080fd5b5061024e601081565b34801561027d57600080fd5b5061029161028c366004613073565b610891565b005b34801561029f57600080fd5b5061024e610ae8565b3480156102b457600080fd5b5061024e6102c336600461315f565b610b03565b3480156102d457600080fd5b506103116040518060400160405280600c81526020017f312e312e332d626574612e32000000000000000000000000000000000000000081525081565b60405161022591906131c6565b34801561032a57600080fd5b5061024e610339366004613217565b600160209081526000928352604080842090915290825290205481565b34801561036257600080fd5b5061024e610371366004612e6b565b601560209081526000928352604080842090915290825290205481565b34801561039a57600080fd5b5061024e6703782dace9d9000081565b3480156103b657600080fd5b506102916103c536600461327b565b610bd9565b3480156103d657600080fd5b5061024e6103e5366004612e29565b6110dc565b3480156103f657600080fd5b50610425610405366004613217565b600260209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610225565b34801561044157600080fd5b50610455610450366004613317565b6110f3565b60405167ffffffffffffffff9091168152602001610225565b34801561047a57600080fd5b5061029161048936600461334a565b61114d565b34801561049a57600080fd5b5061024e6104a9366004612e6b565b73ffffffffffffffffffffffffffffffffffffffff9091166000908152601860209081526040808320938352929052205490565b3480156104e957600080fd5b506102916104f8366004613396565b611248565b34801561050957600080fd5b5061024e610518366004612e6b565b601760209081526000928352604080842090915290825290205481565b34801561054157600080fd5b5061024e610550366004613317565b6113ff565b34801561056157600080fd5b5061024e620186a081565b34801561057857600080fd5b50610291610587366004613073565b611431565b34801561059857600080fd5b5060135461024e565b3480156105ad57600080fd5b507f000000000000000000000000000000000000000000000000000000000000271061024e565b3480156105e057600080fd5b5061024e6105ef366004612e6b565b601660209081526000928352604080842090915290825290205481565b34801561061857600080fd5b5061062c610627366004613217565b611840565b60408051928352602083019190915201610225565b34801561064d57600080fd5b5061029161065c36600461334a565b611931565b34801561066d57600080fd5b5061029161067c366004613422565b611a39565b34801561068d57600080fd5b5061029161069c366004613491565b611b98565b3480156106ad57600080fd5b507f000000000000000000000000000000000000000000000000000000000000007861024e565b6102916106e2366004613519565b611d1e565b3480156106f357600080fd5b5061024e610702366004612e29565b60006020819052908152604090205481565b6013818154811061072457600080fd5b60009182526020909120600290910201805460019091015473ffffffffffffffffffffffffffffffffffffffff909116915082565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601560209081526040808320848452909152812054819061079c9060601c63ffffffff1690565b63ffffffff16905060005b6010811015610889578160011660010361082f5773ffffffffffffffffffffffffffffffffffffffff85166000908152601460209081526040808320878452909152902081601081106107fc576107fc613555565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250610870565b826003826010811061084357610843613555565b01546040805160208101939093528201526060016040516020818303038152906040528051906020012092505b60019190911c9080610881816135b3565b9150506107a7565b505092915050565b600061089d8a8a610759565b90506108c086868360208b01356108bb6108b68d6135eb565b611fea565b61202a565b80156108de57506108de83838360208801356108bb6108b68a6135eb565b610914576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b86604001358860405160200161092a91906136ba565b6040516020818303038152906040528051906020012014610977576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83602001358760200135600161098d91906136f8565b146109c4576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a0c886109d28680613710565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061208b92505050565b610a15886121e6565b836040013588604051602001610a2b91906136ba565b6040516020818303038152906040528051906020012003610a78576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8a1660009081526015602090815260408083208c8452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055610adc8a8a3361298e565b50505050505050505050565b6001610af660106002613897565b610b0091906138a3565b81565b6000610b0f8686612a47565b9050610b1c8360086136f8565b82101580610b2a5750602083115b15610b61576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b60608115610bf257610beb8686612af4565b9050610c2c565b85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050505b3360009081526014602090815260408083208b845290915280822081516102008101928390529160109082845b815481526020019060010190808311610c5957505050505090506000601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b81526020019081526020016000205490506000610cda8260601c63ffffffff1690565b63ffffffff169050333214610d1b576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d2b8260801c63ffffffff1690565b63ffffffff16600003610d6a576040517f87138d5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d748260c01c90565b67ffffffffffffffff1615610db5576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b898114610dee576040517f60f95d5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610dfb89898d8886612b6d565b83516020850160888204881415608883061715610e20576307b1daf16000526004601cfd5b60405160c8810160405260005b83811015610ed0578083018051835260208101516020840152604081015160408401526060810151606084015260808101516080840152508460888301526088810460051b8b013560a883015260c882206001860195508560005b610200811015610ec5576001821615610ea55782818b0152610ec5565b8981015160009081526020938452604090209260019290921c9101610e88565b505050608801610e2d565b50505050600160106002610ee49190613897565b610eee91906138a3565b811115610f27576040517f6229572300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f9c610f3a8360401c63ffffffff1690565b610f4a9063ffffffff168a6136f8565b60401b7fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff606084901b167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff8516171790565b915084156110295777ffffffffffffffffffffffffffffffffffffffffffffffff82164260c01b179150610fd68260801c63ffffffff1690565b63ffffffff16610fec8360401c63ffffffff1690565b63ffffffff1614611029576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526014602090815260408083208e8452909152902061104f90846010612d9f565b503360008181526018602090815260408083208f8452825280832080546001810182559084528284206004820401805460039092166008026101000a67ffffffffffffffff818102199093164390931602919091179055838352601582528083208f8452909152812084905560609190911b81523690601437366014016000a05050505050505050505050565b600381601081106110ec57600080fd5b0154905081565b6018602052826000526040600020602052816000526040600020818154811061111b57600080fd5b906000526020600020906004918282040191900660080292509250509054906101000a900467ffffffffffffffff1681565b60443560008060088301861061116b5763fe2549876000526004601cfd5b60c083901b60805260888386823786600882030151915060206000858360025afa90508061119857600080fd5b50600080517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0400000000000000000000000000000000000000000000000000000000000000178082526002602090815260408084208a8552825280842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558385528252808420998452988152888320939093558152908190529490942055505050565b600080603087600037602060006030600060025afa806112705763f91129696000526004601cfd5b6000517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f010000000000000000000000000000000000000000000000000000000000000017608081815260a08c905260c08b905260308a60e037603088609083013760008060c083600a5afa9250826112f2576309bde3396000526004601cfd5b602886106113085763fe2549876000526004601cfd5b6000602882015278200000000000000000000000000000000000000000000000008152600881018b905285810151935060308a8237603081019b909b52505060509098207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0500000000000000000000000000000000000000000000000000000000000000176000818152600260209081526040808320868452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209583529481528482209a909a559081528089529190912096909655505050505050565b6014602052826000526040600020602052816000526040600020816010811061142757600080fd5b0154925083915050565b73ffffffffffffffffffffffffffffffffffffffff891660009081526015602090815260408083208b845290915290205467ffffffffffffffff8116156114a4576040517fc334f06900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114ae8160c01c90565b67ffffffffffffffff166000036114f1576040517f55d4cbf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000007861151c8260c01c90565b6115309067ffffffffffffffff16426138a3565b11611567576040517f55d4cbf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006115738b8b610759565b905061158c87878360208c01356108bb6108b68e6135eb565b80156115aa57506115aa84848360208901356108bb6108b68b6135eb565b6115e0576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8760400135896040516020016115f691906136ba565b6040516020818303038152906040528051906020012014611643576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84602001358860200135600161165991906136f8565b14158061168b575060016116738360601c63ffffffff1690565b61167d91906138ba565b63ffffffff16856020013514155b156116c2576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116d0896109d28780613710565b6116d9896121e6565b60006116e48a612cc0565b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0200000000000000000000000000000000000000000000000000000000000000179050600061173b8460a01c63ffffffff1690565b67ffffffffffffffff169050600160026000848152602001908152602001600020600083815260200190815260200160002060006101000a81548160ff021916908315150217905550601760008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008d8152602001908152602001600020546001600084815260200190815260200160002060008381526020019081526020016000208190555061180d8460801c63ffffffff1690565b600083815260208190526040902063ffffffff9190911690556118318d8d8161298e565b50505050505050505050505050565b6000828152600260209081526040808320848452909152812054819060ff166118c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546118e58160086136f8565b6118f08560206136f8565b1061190e57836119018260086136f8565b61190b91906138a3565b91505b506000938452600160209081526040808620948652939052919092205492909150565b60443560008060088301861061194f5763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b60008060008060808860601b81528760c01b6014820152858782601c0137601c860181207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0600000000000000000000000000000000000000000000000000000000000000179350604088026260216001603f5a021015611ac35763dd629f866000526004601cfd5b6000808783601c018c5afa94503d6001019150600882018a10611aee5763fe2549876000526004601cfd5b60c082901b81526008018481533d6000600183013e89017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8015160008481526002602090815260408083208d8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915587845282528083209c83529b81528b8220929092559384528390529790912096909655505050505050565b6000611ba48686610759565b9050611bbd83838360208801356108bb6108b68a6135eb565b611bf3576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602084013515611c2f576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c37612ddd565b611c45816109d28780613710565b611c4e816121e6565b846040013581604051602001611c6491906136ba565b6040516020818303038152906040528051906020012003611cb1576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166000908152601560209081526040808320898452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055611d1587873361298e565b50505050505050565b6703782dace9d90000341015611d60576040517fe92c469f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333214611d99576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611da48160086138df565b63ffffffff168263ffffffff1610611de8576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000027108163ffffffff161015611e48576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152601560209081526040808320868452909152902054611e738160801c63ffffffff1690565b63ffffffff1615611eb0576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608082901b7fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff60a085901b167fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff83161717336000818152601560209081526040808320898452825280832094909455835180850185528381528082018981526013805460018101825590855291517f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a090600290930292830180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055517f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0919091015591815260168252828120968152959052909320349055505050565b600081600001518260200151836040015160405160200161200d93929190613907565b604051602081830303815290604052805190602001209050919050565b60008160005b601081101561207e578060051b880135600186831c16600181146120635760008481526020839052604090209350612074565b600082815260208590526040902093505b5050600101612030565b5090931495945050505050565b608881511461209957600080fd5b602081016020830161211a565b8260031b8201518060001a8160011a60081b178160021a60101b8260031a60181b17178160041a60201b8260051a60281b178260061a60301b8360071a60381b1717179050612114816120ff868560059190911b015190565b1867ffffffffffffffff16600586901b840152565b50505050565b612126600083836120a6565b612132600183836120a6565b61213e600283836120a6565b61214a600383836120a6565b612156600483836120a6565b612162600583836120a6565b61216e600683836120a6565b61217a600783836120a6565b612186600883836120a6565b612192600983836120a6565b61219e600a83836120a6565b6121aa600b83836120a6565b6121b6600c83836120a6565b6121c2600d83836120a6565b6121ce600e83836120a6565b6121da600f83836120a6565b612114601083836120a6565b6040805178010000000000008082800000000000808a8000000080008000602082015279808b00000000800000018000000080008081800000000000800991810191909152788a00000000000000880000000080008009000000008000000a60608201527b8000808b800000000000008b8000000000008089800000000000800360808201527f80000000000080028000000000000080000000000000800a800000008000000a60a08201527f800000008000808180000000000080800000000080000001800000008000800860c082015260009060e0016040516020818303038152906040529050602082016020820161286e565b6102808101516101e082015161014083015160a0840151845118189118186102a082015161020083015161016084015160c0850151602086015118189118186102c083015161022084015161018085015160e0860151604087015118189118186102e08401516102408501516101a0860151610100870151606088015118189118186103008501516102608601516101c0870151610120880151608089015118189118188084603f1c6123998660011b67ffffffffffffffff1690565b18188584603f1c6123b48660011b67ffffffffffffffff1690565b18188584603f1c6123cf8660011b67ffffffffffffffff1690565b181895508483603f1c6123ec8560011b67ffffffffffffffff1690565b181894508387603f1c6124098960011b67ffffffffffffffff1690565b60208b01518b51861867ffffffffffffffff168c5291189190911897508118600181901b603f9190911c18935060c08801518118601481901c602c9190911b1867ffffffffffffffff1660208901526101208801518718602c81901c60149190911b1867ffffffffffffffff1660c08901526102c08801518618600381901c603d9190911b1867ffffffffffffffff166101208901526101c08801518718601981901c60279190911b1867ffffffffffffffff166102c08901526102808801518218602e81901c60129190911b1867ffffffffffffffff166101c089015260408801518618600281901c603e9190911b1867ffffffffffffffff166102808901526101808801518618601581901c602b9190911b1867ffffffffffffffff1660408901526101a08801518518602781901c60199190911b1867ffffffffffffffff166101808901526102608801518718603881901c60089190911b1867ffffffffffffffff166101a08901526102e08801518518600881901c60389190911b1867ffffffffffffffff166102608901526101e08801518218601781901c60299190911b1867ffffffffffffffff166102e089015260808801518718602581901c601b9190911b1867ffffffffffffffff166101e08901526103008801518718603281901c600e9190911b1867ffffffffffffffff1660808901526102a08801518118603e81901c60029190911b1867ffffffffffffffff166103008901526101008801518518600981901c60379190911b1867ffffffffffffffff166102a08901526102008801518118601381901c602d9190911b1867ffffffffffffffff1661010089015260a08801518218601c81901c60249190911b1867ffffffffffffffff1661020089015260608801518518602481901c601c9190911b1867ffffffffffffffff1660a08901526102408801518518602b81901c60159190911b1867ffffffffffffffff1660608901526102208801518618603181901c600f9190911b1867ffffffffffffffff166102408901526101608801518118603681901c600a9190911b1867ffffffffffffffff166102208901525060e08701518518603a81901c60069190911b1867ffffffffffffffff166101608801526101408701518118603d81901c60039190911b1867ffffffffffffffff1660e0880152505067ffffffffffffffff81166101408601525b5050505050565b600582811b8201805160018501831b8401805160028701851b8601805160038901871b8801805160048b0190981b8901805167ffffffffffffffff861985168918811690995283198a16861889169096528819861683188816909352841986168818871690528419831684189095169052919391929190611d15565b612808600082612781565b612813600582612781565b61281e600a82612781565b612829600f82612781565b612834601482612781565b50565b612840816122dc565b612849816127fd565b600383901b820151815160c09190911c9061211490821867ffffffffffffffff168352565b61287a60008284612837565b61288660018284612837565b61289260028284612837565b61289e60038284612837565b6128aa60048284612837565b6128b660058284612837565b6128c260068284612837565b6128ce60078284612837565b6128da60088284612837565b6128e660098284612837565b6128f2600a8284612837565b6128fe600b8284612837565b61290a600c8284612837565b612916600d8284612837565b612922600e8284612837565b61292e600f8284612837565b61293a60108284612837565b61294660118284612837565b61295260128284612837565b61295e60138284612837565b61296a60148284612837565b61297660158284612837565b61298260168284612837565b61211460178284612837565b73ffffffffffffffffffffffffffffffffffffffff83811660009081526016602090815260408083208684529091528082208054908390559051909284169083908381818185875af1925050503d8060008114612a07576040519150601f19603f3d011682016040523d82523d6000602084013e612a0c565b606091505b505090508061277a576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831617612aed818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b6060604051905081602082018181018286833760888306808015612b3d5760888290038501848101848103803687375060806001820353506001845160001a1784538652612b54565b608836843760018353608060878401536088850186525b5050505050601f19603f82510116810160405292915050565b6000612b7f8260a01c63ffffffff1690565b67ffffffffffffffff1690506000612b9d8360801c63ffffffff1690565b63ffffffff1690506000612bb78460401c63ffffffff1690565b63ffffffff169050600883108015612bcd575080155b15612c015760c082901b6000908152883560085283513382526017602090815260408084208a855290915290912055612cb6565b60088310158015612c1f575080612c196008856138a3565b93508310155b8015612c335750612c3087826136f8565b83105b15612cb6576000612c4482856138a3565b905087612c528260206136f8565b10158015612c5e575085155b15612c95576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526017602090815260408083208a845290915290209089013590555b5050505050505050565b6000612d43565b66ff00ff00ff00ff8160081c1667ff00ff00ff00ff00612cf18360081b67ffffffffffffffff1690565b1617905065ffff0000ffff8160101c1667ffff0000ffff0000612d1e8360101b67ffffffffffffffff1690565b1617905060008160201c612d3c8360201b67ffffffffffffffff1690565b1792915050565b60808201516020830190612d5b90612cc7565b612cc7565b6040820151612d6990612cc7565b60401b17612d81612d5660018460059190911b015190565b825160809190911b90612d9390612cc7565b60c01b17179392505050565b8260108101928215612dcd579160200282015b82811115612dcd578251825591602001919060010190612db2565b50612dd9929150612df5565b5090565b6040518060200160405280612df0612e0a565b905290565b5b80821115612dd95760008155600101612df6565b6040518061032001604052806019906020820280368337509192915050565b600060208284031215612e3b57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612e6657600080fd5b919050565b60008060408385031215612e7e57600080fd5b612e8783612e42565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610320810167ffffffffffffffff81118282101715612ee857612ee8612e95565b60405290565b6040516060810167ffffffffffffffff81118282101715612ee857612ee8612e95565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612f5857612f58612e95565b604052919050565b803567ffffffffffffffff81168114612e6657600080fd5b6000610320808385031215612f8c57600080fd5b604051602080820182811067ffffffffffffffff82111715612fb057612fb0612e95565b806040525081935085601f860112612fc757600080fd5b612fcf612ec4565b928501928087851115612fe157600080fd5b865b8581101561300157612ff481612f60565b8352918301918301612fe3565b509092525091949350505050565b60006060828403121561302157600080fd5b50919050565b60008083601f84011261303957600080fd5b50813567ffffffffffffffff81111561305157600080fd5b6020830191508360208260051b850101111561306c57600080fd5b9250929050565b60008060008060008060008060006103e08a8c03121561309257600080fd5b61309b8a612e42565b985060208a013597506130b18b60408c01612f78565b96506103608a013567ffffffffffffffff808211156130cf57600080fd5b6130db8d838e0161300f565b97506103808c01359150808211156130f257600080fd5b6130fe8d838e01613027565b90975095506103a08c013591508082111561311857600080fd5b6131248d838e0161300f565b94506103c08c013591508082111561313b57600080fd5b506131488c828d01613027565b915080935050809150509295985092959850929598565b600080600080600060a0868803121561317757600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60005b838110156131b557818101518382015260200161319d565b838111156121145750506000910152565b60208152600082518060208401526131e581604085016020870161319a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000806040838503121561322a57600080fd5b50508035926020909101359150565b60008083601f84011261324b57600080fd5b50813567ffffffffffffffff81111561326357600080fd5b60208301915083602082850101111561306c57600080fd5b600080600080600080600060a0888a03121561329657600080fd5b8735965060208801359550604088013567ffffffffffffffff808211156132bc57600080fd5b6132c88b838c01613239565b909750955060608a01359150808211156132e157600080fd5b506132ee8a828b01613027565b9094509250506080880135801515811461330757600080fd5b8091505092959891949750929550565b60008060006060848603121561332c57600080fd5b61333584612e42565b95602085013595506040909401359392505050565b60008060006040848603121561335f57600080fd5b83359250602084013567ffffffffffffffff81111561337d57600080fd5b61338986828701613239565b9497909650939450505050565b600080600080600080600060a0888a0312156133b157600080fd5b8735965060208801359550604088013567ffffffffffffffff808211156133d757600080fd5b6133e38b838c01613239565b909750955060608a01359150808211156133fc57600080fd5b506134098a828b01613239565b989b979a50959894979596608090950135949350505050565b60008060008060006080868803121561343a57600080fd5b8535945061344a60208701612e42565b935061345860408701612f60565b9250606086013567ffffffffffffffff81111561347457600080fd5b61348088828901613239565b969995985093965092949392505050565b6000806000806000608086880312156134a957600080fd5b6134b286612e42565b945060208601359350604086013567ffffffffffffffff808211156134d657600080fd5b6134e289838a0161300f565b945060608801359150808211156134f857600080fd5b5061348088828901613027565b803563ffffffff81168114612e6657600080fd5b60008060006060848603121561352e57600080fd5b8335925061353e60208501613505565b915061354c60408501613505565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135e4576135e4613584565b5060010190565b6000606082360312156135fd57600080fd5b613605612eee565b823567ffffffffffffffff8082111561361d57600080fd5b9084019036601f83011261363057600080fd5b813560208282111561364457613644612e95565b613674817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011601612f11565b9250818352368183860101111561368a57600080fd5b81818501828501376000918301810191909152908352848101359083015250604092830135928101929092525090565b81516103208201908260005b60198110156136ef57825167ffffffffffffffff168252602092830192909101906001016136c6565b50505092915050565b6000821982111561370b5761370b613584565b500190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261374557600080fd5b83018035915067ffffffffffffffff82111561376057600080fd5b60200191503681900382131561306c57600080fd5b600181815b808511156137ce57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156137b4576137b4613584565b808516156137c157918102915b93841c939080029061377a565b509250929050565b6000826137e557506001613891565b816137f257506000613891565b816001811461380857600281146138125761382e565b6001915050613891565b60ff84111561382357613823613584565b50506001821b613891565b5060208310610133831016604e8410600b8410161715613851575081810a613891565b61385b8383613775565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561388d5761388d613584565b0290505b92915050565b6000612aed83836137d6565b6000828210156138b5576138b5613584565b500390565b600063ffffffff838116908316818110156138d7576138d7613584565b039392505050565b600063ffffffff8083168185168083038211156138fe576138fe613584565b01949350505050565b6000845161391981846020890161319a565b9190910192835250602082015260400191905056fea164736f6c634300080f000a"; bytes internal constant mipsCode = - hex"608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d50146100465780637dc0d1d014610098578063e14ced32146100dc575b600080fd5b6100826040518060400160405280600c81526020017f312e312e312d626574612e32000000000000000000000000000000000000000081525081565b60405161008f91906121ee565b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007a9eab4ce99d157aee7a02e95b366e972a2d5b0b16815260200161008f565b6100ef6100ea3660046122a3565b6100fd565b60405190815260200161008f565b6000610107612164565b6080811461011457600080fd5b6040516106001461012457600080fd5b6084871461013157600080fd5b6101a4851461013f57600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a0819052605a89013590911c6101c05260628801906101e09060018111156101f5576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b506020810181511461020657600080fd5b60200160005b602081101561023057823560e01c825260049092019160209091019060010161020c565b5050508061012001511561024e576102466103a6565b91505061039d565b6101408101805160010167ffffffffffffffff16905260006101a49050600080600061028385606001518660000151866104f7565b9250925092508163ffffffff1660001480156102a557508063ffffffff16600c145b156102bf576102b387610521565b9550505050505061039d565b6000610339866040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b6101608701518751919250610356918391906105248888886108f9565b8652805163ffffffff9081166060808901919091526020830151821660808901526040830151821660a08901528201511660c08701526103946103a6565b96505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a8401526000926102009290916062830191906001811115610453576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b60005b602081101561047a57601c8601518452602090950194600490930192600101610456565b506000835283830384a060009450806001811461049a57600395506104c2565b8280156104b257600181146104bb57600296506104c0565b600096506104c0565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b6000806000610507858786610cdf565b925050603f601a83901c8116915082165b93509350939050565b600061052b612164565b608090506000806000806105628561016001516040810151608082015160a083015160c084015160e0909401519294919390929091565b509350935093509350600080610ffa63ffffffff168663ffffffff16036105a75761059285858960e00151610d93565b63ffffffff1660e08a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03363ffffffff8716016105e05763400000009150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefe863ffffffff8716016106165760019150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef6a63ffffffff87160161066a57600161012088015260ff851661010088015261065d6103a6565b9998505050505050505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05d63ffffffff8716016107665760006040518061012001604052808763ffffffff1681526020018663ffffffff1681526020018563ffffffff16815260200189602001518152602001896040015163ffffffff1681526020018b81526020017f0000000000000000000000007a9eab4ce99d157aee7a02e95b366e972a2d5b0b73ffffffffffffffffffffffffffffffffffffffff1681526020016107386101a4600160ff16610380020190565b81528951602090910152905061074d81610e27565b8b5263ffffffff1660408b015290935091506108089050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05c63ffffffff8716016107cb57602087015160408801516107b1918791879187916105248d5161109f565b63ffffffff1660408b015260208a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff02963ffffffff871601610808576108028585611195565b90925090505b6000610882886040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b61016089015163ffffffff85811660408084019190915285821660e0909301929092526020830180518083168086526004909101831682526060808e01919091529051821660808d015291830151811660a08c0152908201511660c08a015290506108eb6103a6565b9a9950505050505050505050565b84600263ffffffff8416148061091557508263ffffffff166003145b156109675760006002856303ffffff1663ffffffff16901b896020015163f00000001617905061096189898663ffffffff1660021461095557601f610958565b60005b60ff168461124a565b50610cd4565b600080601f601087901c8116908a90601589901c166020811061098c5761098c612317565b602002015192508063ffffffff871615806109ad57508663ffffffff16601c145b156109df578a8263ffffffff16602081106109ca576109ca612317565b6020020151925050601f600b88901c16610a96565b60208763ffffffff161015610a41578663ffffffff16600c1480610a0957508663ffffffff16600d145b80610a1a57508663ffffffff16600e145b15610a2b578761ffff169250610a96565b610a3a8861ffff166010611322565b9250610a96565b60288763ffffffff16101580610a5d57508663ffffffff166022145b80610a6e57508663ffffffff166026145b15610a96578a8263ffffffff1660208110610a8b57610a8b612317565b602002015192508190505b60048763ffffffff1610158015610ab3575060088763ffffffff16105b80610ac457508663ffffffff166001145b15610ae057610ad78c8c898b8689611395565b50505050610cd4565b63ffffffff6000602089831610610b4557610b008a61ffff166010611322565b9095019463fffffffc8616610b168d828e610cdf565b915060288a63ffffffff1610158015610b3657508963ffffffff16603014155b15610b4357809250600093505b505b6000610b558b8b8b8a8a87611583565b63ffffffff1690508963ffffffff166000148015610b7a575060088963ffffffff1610155b8015610b8c5750601c8963ffffffff16105b15610c54578863ffffffff1660081480610bac57508863ffffffff166009145b15610bdf57610bd38f8f8b63ffffffff16600814610bca5786610bcd565b60005b8a61124a565b50505050505050610cd4565b8863ffffffff16600a03610c0157610bd38f8f868a63ffffffff8b1615611ca0565b8863ffffffff16600b03610c2457610bd38f8f868a63ffffffff8b161515611ca0565b60108963ffffffff1610158015610c415750601c8963ffffffff16105b15610c5457610bd38f8f8b8a8a89611d70565b8963ffffffff166038148015610c6f575063ffffffff851615155b15610c9f5760018e8663ffffffff1660208110610c8e57610c8e612317565b63ffffffff90921660209290920201525b8263ffffffff1663ffffffff14610cbe57610cbb838d83612029565b97505b610ccc8f8f86846001611ca0565b505050505050505b979650505050505050565b6000610cea826120cb565b6003831615610cf857600080fd5b6020820191358360051c8160005b601b811015610d5e5760208601953583821c6001168015610d2e5760018114610d4357610d54565b60008481526020839052604090209350610d54565b600082815260208590526040902093505b5050600101610d06565b50868114610d7457630badf00d60005260206000fd5b5050601f93909316601c0360031b9290921c63ffffffff169392505050565b6000808284610fff811615610dad57610fff811661100003015b8663ffffffff16600003610e195784935090810190636000000063ffffffff83161180610de557508463ffffffff168263ffffffff16105b80610dfb57508563ffffffff168163ffffffff16105b15610e14575063ffffffff925060169150839050610518565b610e1d565b8693505b5093509350939050565b6101008101516080820151825160009283929163ffffffff161561109857845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb01611052576000610e93866101000151876020015163fffffffc168860e00151610cdf565b606087015190915060001a600103610f1557610f0f86606001518760a0015160408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b60608701525b6000808760c0015173ffffffffffffffffffffffffffffffffffffffff1663e03110e189606001518a608001516040518363ffffffff1660e01b8152600401610f6e92919091825263ffffffff16602082015260400190565b6040805180830381865afa158015610f8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fae9190612346565b60208a015160408b01519294509092509060038216600481900384811015610fd4578094505b5083821015610fe1578193505b8460088502610100031c9450846008828660040303021b9450600180600883600403021b036001806008878560040303021b0391508119811690508581198816179650505061103f8a6020015163fffffffc168b60e0015187612029565b9298505050938601939250611098915050565b845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0161108c5784604001519350611098565b63ffffffff9350600992505b9193509193565b600080858563ffffffff8b16600114806110bf575063ffffffff8b166002145b806110d0575063ffffffff8b166004145b156110dd57889350611187565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8c160161117b57600061111d868c63fffffffc1689610cdf565b90508860038c166004038b81101561113357809b505b8b965086900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193880293841b0116911b17915060009050611187565b63ffffffff9350600992505b975097509750979350505050565b60008063ffffffff83166003036112385763ffffffff841615806111bf575063ffffffff84166005145b806111d0575063ffffffff84166003145b156111de5760009150611243565b63ffffffff8416600114806111f9575063ffffffff84166002145b8061120a575063ffffffff84166006145b8061121b575063ffffffff84166004145b156112295760019150611243565b5063ffffffff90506009611243565b5063ffffffff905060165b9250929050565b836000015160040163ffffffff16846020015163ffffffff16146112cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b835160208501805163ffffffff908116875283811690915283161561131b5780600801848463ffffffff166020811061130a5761130a612317565b63ffffffff90921660209290920201525b5050505050565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b018261137f576000611381565b815b90861663ffffffff16179250505092915050565b6000866000015160040163ffffffff16876020015163ffffffff1614611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f7400000000000000000000000060448201526064016112c6565b8463ffffffff166004148061143257508463ffffffff166005145b156114a9576000868463ffffffff166020811061145157611451612317565b602002015190508063ffffffff168363ffffffff1614801561147957508563ffffffff166004145b806114a157508063ffffffff168363ffffffff16141580156114a157508563ffffffff166005145b915050611526565b8463ffffffff166006036114c65760008260030b13159050611526565b8463ffffffff166007036114e25760008260030b139050611526565b8463ffffffff1660010361152657601f601085901c16600081900361150b5760008360030b1291505b8063ffffffff166001036115245760008360030b121591505b505b8651602088015163ffffffff168852811561156757600261154c8661ffff166010611322565b63ffffffff90811690911b8201600401166020890152611579565b60208801805160040163ffffffff1690525b5050505050505050565b600063ffffffff861615806115b0575060088663ffffffff16101580156115b05750600f8663ffffffff16105b156119b05785600881146115f357600981146115fc57600a811461160557600b811461160e57600c811461161757600d811461162057600e81146116295761162e565b6020955061162e565b6021955061162e565b602a955061162e565b602b955061162e565b6024955061162e565b6025955061162e565b602695505b508463ffffffff16600003611653575063ffffffff8216601f600688901c161b611c96565b8463ffffffff16600203611677575063ffffffff8216601f600688901c161c611c96565b8463ffffffff166003036116ab57601f600688901c166116a363ffffffff8516821c6020839003611322565b915050611c96565b8463ffffffff166004036116cb575063ffffffff8216601f84161b611c96565b8463ffffffff166006036116eb575063ffffffff8216601f84161c611c96565b8463ffffffff1660070361171357601f84166116a363ffffffff8516821c6020839003611322565b8463ffffffff16600803611728575082611c96565b8463ffffffff1660090361173d575082611c96565b8463ffffffff16600a03611752575082611c96565b8463ffffffff16600b03611767575082611c96565b8463ffffffff16600c0361177c575082611c96565b8463ffffffff16600f03611791575082611c96565b8463ffffffff166010036117a6575082611c96565b8463ffffffff166011036117bb575082611c96565b8463ffffffff166012036117d0575082611c96565b8463ffffffff166013036117e5575082611c96565b8463ffffffff166018036117fa575082611c96565b8463ffffffff1660190361180f575082611c96565b8463ffffffff16601a03611824575082611c96565b8463ffffffff16601b03611839575082611c96565b8463ffffffff166020036118505750828201611c96565b8463ffffffff166021036118675750828201611c96565b8463ffffffff1660220361187e5750818303611c96565b8463ffffffff166023036118955750818303611c96565b8463ffffffff166024036118ac5750828216611c96565b8463ffffffff166025036118c35750828217611c96565b8463ffffffff166026036118da5750828218611c96565b8463ffffffff166027036118f2575082821719611c96565b8463ffffffff16602a03611921578260030b8460030b12611914576000611917565b60015b60ff169050611c96565b8463ffffffff16602b03611949578263ffffffff168463ffffffff1610611914576000611917565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e0000000000000000000000000060448201526064016112c6565b611949565b8563ffffffff16601c03611a30578463ffffffff166002036119d55750828202611c96565b8463ffffffff16602014806119f057508463ffffffff166021145b156119ab578463ffffffff16602003611a07579219925b60005b6380000000851615611a29576401fffffffe600195861b169401611a0a565b9050611c96565b8563ffffffff16600f03611a51575065ffffffff0000601083901b16611c96565b8563ffffffff16602003611a8557611a298460031660080260180363ffffffff168363ffffffff16901c60ff166008611322565b8563ffffffff16602103611aba57611a298460021660080260100363ffffffff168363ffffffff16901c61ffff166010611322565b8563ffffffff16602203611ae8575063ffffffff60086003851602811681811b198416918316901b17611c96565b8563ffffffff16602303611afd575080611c96565b8563ffffffff16602403611b2e578360031660080260180363ffffffff168263ffffffff16901c60ff169050611c96565b8563ffffffff16602503611b60578360021660080260100363ffffffff168263ffffffff16901c61ffff169050611c96565b8563ffffffff16602603611b91575063ffffffff60086003851602601803811681811c198416918316901c17611c96565b8563ffffffff16602803611bc6575060ff63ffffffff60086003861602601803811682811b9091188316918416901b17611c96565b8563ffffffff16602903611bfc575061ffff63ffffffff60086002861602601003811682811b9091188316918416901b17611c96565b8563ffffffff16602a03611c2a575063ffffffff60086003851602811681811c198316918416901c17611c96565b8563ffffffff16602b03611c3f575081611c96565b8563ffffffff16602e03611c70575063ffffffff60086003851602601803811681811b198316918416901b17611c96565b8563ffffffff16603003611c85575080611c96565b8563ffffffff166038036119495750815b9695505050505050565b60208363ffffffff1610611d10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c696420726567697374657200000000000000000000000000000000000060448201526064016112c6565b63ffffffff831615801590611d225750805b15611d515781848463ffffffff1660208110611d4057611d40612317565b63ffffffff90921660209290920201525b5050505060208101805163ffffffff8082169093526004019091169052565b60008463ffffffff16601003611d8b57506060860151611fd1565b8463ffffffff16601103611daa5763ffffffff84166060880152611fd1565b8463ffffffff16601203611dc357506040860151611fd1565b8463ffffffff16601303611de25763ffffffff84166040880152611fd1565b8463ffffffff16601803611e165763ffffffff600385810b9085900b02602081901c821660608a0152166040880152611fd1565b8463ffffffff16601903611e475763ffffffff84811681851602602081901c821660608a0152166040880152611fd1565b8463ffffffff16601a03611f0a578260030b600003611ec2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8260030b8460030b81611ed757611ed761236a565b0763ffffffff166060880152600383810b9085900b81611ef957611ef961236a565b0563ffffffff166040880152611fd1565b8463ffffffff16601b03611fd1578263ffffffff16600003611f88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8263ffffffff168463ffffffff1681611fa357611fa361236a565b0663ffffffff908116606089015283811690851681611fc457611fc461236a565b0463ffffffff1660408801525b63ffffffff8216156120075780868363ffffffff1660208110611ff657611ff6612317565b63ffffffff90921660209290920201525b50505060208401805163ffffffff808216909652600401909416909352505050565b6000612034836120cb565b600384161561204257600080fd5b6020830192601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b8110156120c05760208601953582821c600116801561209057600181146120a5576120b6565b600085815260208390526040902094506120b6565b600082815260208690526040902094505b5050600101612068565b509095945050505050565b366103808201811015612160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f617461000000000000000000000000000000000000000000000000000000000060648201526084016112c6565b5050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915261016081016121ca6121cf565b905290565b6040518061040001604052806020906020820280368337509192915050565b600060208083528351808285015260005b8181101561221b578581018301518582016040015282016121ff565b8181111561222d576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60008083601f84011261227357600080fd5b50813567ffffffffffffffff81111561228b57600080fd5b60208301915083602082850101111561124357600080fd5b6000806000806000606086880312156122bb57600080fd5b853567ffffffffffffffff808211156122d357600080fd5b6122df89838a01612261565b909750955060208801359150808211156122f857600080fd5b5061230588828901612261565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561235957600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a"; + hex"608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d50146100465780637dc0d1d014610098578063e14ced32146100dc575b600080fd5b6100826040518060400160405280600c81526020017f312e312e312d626574612e33000000000000000000000000000000000000000081525081565b60405161008f9190612237565b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007a9eab4ce99d157aee7a02e95b366e972a2d5b0b16815260200161008f565b6100ef6100ea3660046122ec565b6100fd565b60405190815260200161008f565b60006101076121ad565b6080811461011457600080fd5b6040516106001461012457600080fd5b6084871461013157600080fd5b6101a4851461013f57600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a0819052605a89013590911c6101c05260628801906101e09060018111156101f5576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b506020810181511461020657600080fd5b60200160005b602081101561023057823560e01c825260049092019160209091019060010161020c565b5050508061012001511561024e576102466103a6565b91505061039d565b6101408101805160010167ffffffffffffffff16905260006101a49050600080600061028385606001518660000151866104f7565b9250925092508163ffffffff1660001480156102a557508063ffffffff16600c145b156102bf576102b387610521565b9550505050505061039d565b6000610339866040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b6101608701518751919250610356918391906105248888886108f9565b8652805163ffffffff9081166060808901919091526020830151821660808901526040830151821660a08901528201511660c08701526103946103a6565b96505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a8401526000926102009290916062830191906001811115610453576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b60005b602081101561047a57601c8601518452602090950194600490930192600101610456565b506000835283830384a060009450806001811461049a57600395506104c2565b8280156104b257600181146104bb57600296506104c0565b600096506104c0565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b6000806000610507858786610cdf565b925050603f601a83901c8116915082165b93509350939050565b600061052b6121ad565b608090506000806000806105628561016001516040810151608082015160a083015160c084015160e0909401519294919390929091565b509350935093509350600080610ffa63ffffffff168663ffffffff16036105a75761059285858960e00151610d31565b63ffffffff1660e08a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03363ffffffff8716016105e05763400000009150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefe863ffffffff8716016106165760019150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef6a63ffffffff87160161066a57600161012088015260ff851661010088015261065d6103a6565b9998505050505050505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05d63ffffffff8716016107665760006040518061012001604052808763ffffffff1681526020018663ffffffff1681526020018563ffffffff16815260200189602001518152602001896040015163ffffffff1681526020018b81526020017f0000000000000000000000007a9eab4ce99d157aee7a02e95b366e972a2d5b0b73ffffffffffffffffffffffffffffffffffffffff1681526020016107386101a4600160ff16610380020190565b81528951602090910152905061074d81610dc5565b8b5263ffffffff1660408b015290935091506108089050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05c63ffffffff8716016107cb57602087015160408801516107b1918791879187916105248d5161103d565b63ffffffff1660408b015260208a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff02963ffffffff871601610808576108028585611133565b90925090505b6000610882886040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b61016089015163ffffffff85811660408084019190915285821660e0909301929092526020830180518083168086526004909101831682526060808e01919091529051821660808d015291830151811660a08c0152908201511660c08a015290506108eb6103a6565b9a9950505050505050505050565b84600263ffffffff8416148061091557508263ffffffff166003145b156109675760006002856303ffffff1663ffffffff16901b896020015163f00000001617905061096189898663ffffffff1660021461095557601f610958565b60005b60ff16846111e8565b50610cd4565b600080601f601087901c8116908a90601589901c166020811061098c5761098c612360565b602002015192508063ffffffff871615806109ad57508663ffffffff16601c145b156109df578a8263ffffffff16602081106109ca576109ca612360565b6020020151925050601f600b88901c16610a96565b60208763ffffffff161015610a41578663ffffffff16600c1480610a0957508663ffffffff16600d145b80610a1a57508663ffffffff16600e145b15610a2b578761ffff169250610a96565b610a3a8861ffff1660106112c0565b9250610a96565b60288763ffffffff16101580610a5d57508663ffffffff166022145b80610a6e57508663ffffffff166026145b15610a96578a8263ffffffff1660208110610a8b57610a8b612360565b602002015192508190505b60048763ffffffff1610158015610ab3575060088763ffffffff16105b80610ac457508663ffffffff166001145b15610ae057610ad78c8c898b8689611333565b50505050610cd4565b63ffffffff6000602089831610610b4557610b008a61ffff1660106112c0565b9095019463fffffffc8616610b168d828e610cdf565b915060288a63ffffffff1610158015610b3657508963ffffffff16603014155b15610b4357809250600093505b505b6000610b558b8b8b8a8a87611521565b63ffffffff1690508963ffffffff166000148015610b7a575060088963ffffffff1610155b8015610b8c5750601c8963ffffffff16105b15610c54578863ffffffff1660081480610bac57508863ffffffff166009145b15610bdf57610bd38f8f8b63ffffffff16600814610bca5786610bcd565b60005b8a6111e8565b50505050505050610cd4565b8863ffffffff16600a03610c0157610bd38f8f868a63ffffffff8b1615611c3e565b8863ffffffff16600b03610c2457610bd38f8f868a63ffffffff8b161515611c3e565b60108963ffffffff1610158015610c415750601c8963ffffffff16105b15610c5457610bd38f8f8b8a8a89611d0e565b8963ffffffff166038148015610c6f575063ffffffff851615155b15610c9f5760018e8663ffffffff1660208110610c8e57610c8e612360565b63ffffffff90921660209290920201525b8263ffffffff1663ffffffff14610cbe57610cbb838d83611fc7565b97505b610ccc8f8f86846001611c3e565b505050505050505b979650505050505050565b600080610ced858585612069565b909250905080610d29576040517f8e77b2b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b509392505050565b6000808284610fff811615610d4b57610fff811661100003015b8663ffffffff16600003610db75784935090810190636000000063ffffffff83161180610d8357508463ffffffff168263ffffffff16105b80610d9957508563ffffffff168163ffffffff16105b15610db2575063ffffffff925060169150839050610518565b610dbb565b8693505b5093509350939050565b6101008101516080820151825160009283929163ffffffff161561103657845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb01610ff0576000610e31866101000151876020015163fffffffc168860e00151610cdf565b606087015190915060001a600103610eb357610ead86606001518760a0015160408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b60608701525b6000808760c0015173ffffffffffffffffffffffffffffffffffffffff1663e03110e189606001518a608001516040518363ffffffff1660e01b8152600401610f0c92919091825263ffffffff16602082015260400190565b6040805180830381865afa158015610f28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4c919061238f565b60208a015160408b01519294509092509060038216600481900384811015610f72578094505b5083821015610f7f578193505b8460088502610100031c9450846008828660040303021b9450600180600883600403021b036001806008878560040303021b03915081198116905085811988161796505050610fdd8a6020015163fffffffc168b60e0015187611fc7565b9298505050938601939250611036915050565b845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0161102a5784604001519350611036565b63ffffffff9350600992505b9193509193565b600080858563ffffffff8b166001148061105d575063ffffffff8b166002145b8061106e575063ffffffff8b166004145b1561107b57889350611125565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8c16016111195760006110bb868c63fffffffc1689610cdf565b90508860038c166004038b8110156110d157809b505b8b965086900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193880293841b0116911b17915060009050611125565b63ffffffff9350600992505b975097509750979350505050565b60008063ffffffff83166003036111d65763ffffffff8416158061115d575063ffffffff84166005145b8061116e575063ffffffff84166003145b1561117c57600091506111e1565b63ffffffff841660011480611197575063ffffffff84166002145b806111a8575063ffffffff84166006145b806111b9575063ffffffff84166004145b156111c757600191506111e1565b5063ffffffff905060096111e1565b5063ffffffff905060165b9250929050565b836000015160040163ffffffff16846020015163ffffffff161461126d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b835160208501805163ffffffff90811687528381169091528316156112b95780600801848463ffffffff16602081106112a8576112a8612360565b63ffffffff90921660209290920201525b5050505050565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b018261131d57600061131f565b815b90861663ffffffff16179250505092915050565b6000866000015160040163ffffffff16876020015163ffffffff16146113b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f740000000000000000000000006044820152606401611264565b8463ffffffff16600414806113d057508463ffffffff166005145b15611447576000868463ffffffff16602081106113ef576113ef612360565b602002015190508063ffffffff168363ffffffff1614801561141757508563ffffffff166004145b8061143f57508063ffffffff168363ffffffff161415801561143f57508563ffffffff166005145b9150506114c4565b8463ffffffff166006036114645760008260030b131590506114c4565b8463ffffffff166007036114805760008260030b1390506114c4565b8463ffffffff166001036114c457601f601085901c1660008190036114a95760008360030b1291505b8063ffffffff166001036114c25760008360030b121591505b505b8651602088015163ffffffff16885281156115055760026114ea8661ffff1660106112c0565b63ffffffff90811690911b8201600401166020890152611517565b60208801805160040163ffffffff1690525b5050505050505050565b600063ffffffff8616158061154e575060088663ffffffff161015801561154e5750600f8663ffffffff16105b1561194e578560088114611591576009811461159a57600a81146115a357600b81146115ac57600c81146115b557600d81146115be57600e81146115c7576115cc565b602095506115cc565b602195506115cc565b602a95506115cc565b602b95506115cc565b602495506115cc565b602595506115cc565b602695505b508463ffffffff166000036115f1575063ffffffff8216601f600688901c161b611c34565b8463ffffffff16600203611615575063ffffffff8216601f600688901c161c611c34565b8463ffffffff1660030361164957601f600688901c1661164163ffffffff8516821c60208390036112c0565b915050611c34565b8463ffffffff16600403611669575063ffffffff8216601f84161b611c34565b8463ffffffff16600603611689575063ffffffff8216601f84161c611c34565b8463ffffffff166007036116b157601f841661164163ffffffff8516821c60208390036112c0565b8463ffffffff166008036116c6575082611c34565b8463ffffffff166009036116db575082611c34565b8463ffffffff16600a036116f0575082611c34565b8463ffffffff16600b03611705575082611c34565b8463ffffffff16600c0361171a575082611c34565b8463ffffffff16600f0361172f575082611c34565b8463ffffffff16601003611744575082611c34565b8463ffffffff16601103611759575082611c34565b8463ffffffff1660120361176e575082611c34565b8463ffffffff16601303611783575082611c34565b8463ffffffff16601803611798575082611c34565b8463ffffffff166019036117ad575082611c34565b8463ffffffff16601a036117c2575082611c34565b8463ffffffff16601b036117d7575082611c34565b8463ffffffff166020036117ee5750828201611c34565b8463ffffffff166021036118055750828201611c34565b8463ffffffff1660220361181c5750818303611c34565b8463ffffffff166023036118335750818303611c34565b8463ffffffff1660240361184a5750828216611c34565b8463ffffffff166025036118615750828217611c34565b8463ffffffff166026036118785750828218611c34565b8463ffffffff16602703611890575082821719611c34565b8463ffffffff16602a036118bf578260030b8460030b126118b25760006118b5565b60015b60ff169050611c34565b8463ffffffff16602b036118e7578263ffffffff168463ffffffff16106118b25760006118b5565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e000000000000000000000000006044820152606401611264565b6118e7565b8563ffffffff16601c036119ce578463ffffffff166002036119735750828202611c34565b8463ffffffff166020148061198e57508463ffffffff166021145b15611949578463ffffffff166020036119a5579219925b60005b63800000008516156119c7576401fffffffe600195861b1694016119a8565b9050611c34565b8563ffffffff16600f036119ef575065ffffffff0000601083901b16611c34565b8563ffffffff16602003611a23576119c78460031660080260180363ffffffff168363ffffffff16901c60ff1660086112c0565b8563ffffffff16602103611a58576119c78460021660080260100363ffffffff168363ffffffff16901c61ffff1660106112c0565b8563ffffffff16602203611a86575063ffffffff60086003851602811681811b198416918316901b17611c34565b8563ffffffff16602303611a9b575080611c34565b8563ffffffff16602403611acc578360031660080260180363ffffffff168263ffffffff16901c60ff169050611c34565b8563ffffffff16602503611afe578360021660080260100363ffffffff168263ffffffff16901c61ffff169050611c34565b8563ffffffff16602603611b2f575063ffffffff60086003851602601803811681811c198416918316901c17611c34565b8563ffffffff16602803611b64575060ff63ffffffff60086003861602601803811682811b9091188316918416901b17611c34565b8563ffffffff16602903611b9a575061ffff63ffffffff60086002861602601003811682811b9091188316918416901b17611c34565b8563ffffffff16602a03611bc8575063ffffffff60086003851602811681811c198316918416901c17611c34565b8563ffffffff16602b03611bdd575081611c34565b8563ffffffff16602e03611c0e575063ffffffff60086003851602601803811681811b198316918416901b17611c34565b8563ffffffff16603003611c23575080611c34565b8563ffffffff166038036118e75750815b9695505050505050565b60208363ffffffff1610611cae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c69642072656769737465720000000000000000000000000000000000006044820152606401611264565b63ffffffff831615801590611cc05750805b15611cef5781848463ffffffff1660208110611cde57611cde612360565b63ffffffff90921660209290920201525b5050505060208101805163ffffffff8082169093526004019091169052565b60008463ffffffff16601003611d2957506060860151611f6f565b8463ffffffff16601103611d485763ffffffff84166060880152611f6f565b8463ffffffff16601203611d6157506040860151611f6f565b8463ffffffff16601303611d805763ffffffff84166040880152611f6f565b8463ffffffff16601803611db45763ffffffff600385810b9085900b02602081901c821660608a0152166040880152611f6f565b8463ffffffff16601903611de55763ffffffff84811681851602602081901c821660608a0152166040880152611f6f565b8463ffffffff16601a03611ea8578260030b600003611e60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f000000000000000000006044820152606401611264565b8260030b8460030b81611e7557611e756123b3565b0763ffffffff166060880152600383810b9085900b81611e9757611e976123b3565b0563ffffffff166040880152611f6f565b8463ffffffff16601b03611f6f578263ffffffff16600003611f26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f000000000000000000006044820152606401611264565b8263ffffffff168463ffffffff1681611f4157611f416123b3565b0663ffffffff908116606089015283811690851681611f6257611f626123b3565b0463ffffffff1660408801525b63ffffffff821615611fa55780868363ffffffff1660208110611f9457611f94612360565b63ffffffff90921660209290920201525b50505060208401805163ffffffff808216909652600401909416909352505050565b6000611fd283612114565b6003841615611fe057600080fd5b6020830192601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b81101561205e5760208601953582821c600116801561202e576001811461204357612054565b60008581526020839052604090209450612054565b600082815260208690526040902094505b5050600101612006565b509095945050505050565b60008061207583612114565b600384161561208357600080fd5b6020830192358460051c8160005b601b8110156120e95760208701963583821c60011680156120b957600181146120ce576120df565b600084815260208390526040902093506120df565b600082815260208590526040902093505b5050600101612091565b508714925050811561210b57601f8516601c0360031b81901c63ffffffff1692505b50935093915050565b3661038082018110156121a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f61746100000000000000000000000000000000000000000000000000000000006064820152608401611264565b5050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101612213612218565b905290565b6040518061040001604052806020906020820280368337509192915050565b600060208083528351808285015260005b8181101561226457858101830151858201604001528201612248565b81811115612276576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60008083601f8401126122bc57600080fd5b50813567ffffffffffffffff8111156122d457600080fd5b6020830191508360208285010111156111e157600080fd5b60008060008060006060868803121561230457600080fd5b853567ffffffffffffffff8082111561231c57600080fd5b61232889838a016122aa565b9097509550602088013591508082111561234157600080fd5b5061234e888289016122aa565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080604083850312156123a257600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a"; bytes internal constant anchorStateRegistryCode = hex"608060405234801561001057600080fd5b506004361061007d5760003560e01c80635e05fbd01161005b5780635e05fbd01461012a5780637258a8071461013d578063838c2d1e14610179578063f2b4e6171461018157600080fd5b806317cf21a91461008257806335e80ab31461009757806354fd4d50146100e1575b600080fd5b610095610090366004610b4c565b6101a7565b005b6002546100b79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61011d6040518060400160405280600c81526020017f322e302e312d626574612e32000000000000000000000000000000000000000081525081565b6040516100d89190610bea565b610095610138366004610cc6565b61061c565b61016461014b366004610df0565b6001602081905260009182526040909120805491015482565b604080519283526020830191909152016100d8565b610095610853565b7f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d6100b7565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610214573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102389190610e0d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461029c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156102ec573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526103329190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161039793929190610efb565b6040805180830381865afa1580156103b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d79190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043f576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561048c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b09190610f9f565b60028111156104c1576104c1610f70565b146104f8576040517f8f8af25f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806105788773ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610551573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105759190610fc0565b90565b81526020018673ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ec9190610fc0565b905263ffffffff909416600090815260016020818152604090922086518155959091015194019390935550505050565b600054610100900460ff161580801561063c5750600054600160ff909116105b806106565750303b158015610656575060005460ff166001145b6106e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561074457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60005b83518110156107aa57600084828151811061076457610764610fd9565b60209081029190910181015180820151905163ffffffff1660009081526001808452604090912082518155919092015191015550806107a281611008565b915050610747565b50600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055801561084e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600033905060008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108a8573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526108ee9190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161095393929190610efb565b6040805180830381865afa15801561096f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109939190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109fb576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160008563ffffffff1663ffffffff168152602001908152602001600020600101548573ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8d9190610fc0565b11610a99575050505050565b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ae6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0a9190610f9f565b6002811115610b1b57610b1b610f70565b146104f8575050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4957600080fd5b50565b600060208284031215610b5e57600080fd5b8135610b6981610b27565b9392505050565b60005b83811015610b8b578181015183820152602001610b73565b83811115610b9a576000848401525b50505050565b60008151808452610bb8816020860160208601610b70565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610b696020830184610ba0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610c4f57610c4f610bfd565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610c9c57610c9c610bfd565b604052919050565b63ffffffff81168114610b4957600080fd5b8035610cc181610b27565b919050565b6000806040808486031215610cda57600080fd5b833567ffffffffffffffff80821115610cf257600080fd5b818601915086601f830112610d0657600080fd5b8135602082821115610d1a57610d1a610bfd565b610d28818360051b01610c55565b8281528181019350606092830285018201928a841115610d4757600080fd5b948201945b83861015610dd457858b0381811215610d655760008081fd5b610d6d610c2c565b8735610d7881610ca4565b81527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201891315610daa5760008081fd5b610db2610c2c565b8886013581528989013586820152818601528652509485019493820193610d4c565b509650610de2888201610cb6565b955050505050509250929050565b600060208284031215610e0257600080fd5b8135610b6981610ca4565b600060208284031215610e1f57600080fd5b8151610b6981610b27565b600080600060608486031215610e3f57600080fd5b8351610e4a81610ca4565b60208501516040860151919450925067ffffffffffffffff80821115610e6f57600080fd5b818601915086601f830112610e8357600080fd5b815181811115610e9557610e95610bfd565b610ec660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610c55565b9150808252876020828501011115610edd57600080fd5b610eee816020840160208601610b70565b5080925050509250925092565b63ffffffff84168152826020820152606060408201526000610f206060830184610ba0565b95945050505050565b60008060408385031215610f3c57600080fd5b8251610f4781610b27565b602084015190925067ffffffffffffffff81168114610f6557600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060208284031215610fb157600080fd5b815160038110610b6957600080fd5b600060208284031215610fd257600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611060577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea164736f6c634300080f000a"; bytes internal constant acc33Code = - hex"6080604052600436106102f25760003560e01c806370872aa51161018f578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b18578063fa315aa914610b3c578063fe2bbeb214610b6f57600080fd5b8063ec5e630814610a95578063eff0f59214610ac8578063f8f43ff614610af857600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a0f578063d8cc1a3c14610a42578063dabd396d14610a6257600080fd5b8063c6f0308c14610937578063cf09e0d0146109c1578063d5d44d80146109e257600080fd5b80638d450a9511610143578063bcef3b551161011d578063bcef3b55146108b7578063bd8da956146108f7578063c395e1ca1461091757600080fd5b80638d450a9514610777578063a445ece6146107aa578063bbdc02db1461087657600080fd5b80638129fc1c116101745780638129fc1c1461071a5780638980e0cc146107225780638b85902b1461073757600080fd5b806370872aa5146106f25780637b0f0adc1461070757600080fd5b80633fc8cef3116102485780635c0cba33116101fc5780636361506d116101d65780636361506d1461066c5780636b6716c0146106ac5780636f034409146106df57600080fd5b80635c0cba3314610604578063609d33341461063757806360e274641461064c57600080fd5b806354fd4d501161022d57806354fd4d501461055e57806357da950e146105b45780635a5fa2d9146105e457600080fd5b80633fc8cef314610518578063472777c61461054b57600080fd5b80632810e1d6116102aa57806337b1b2291161028457806337b1b229146104655780633a768463146104a55780633e3ac912146104d857600080fd5b80632810e1d6146103de5780632ad69aeb146103f357806330dbe5701461041357600080fd5b806319effeb4116102db57806319effeb414610339578063200d2ed21461038457806325fc2ace146103bf57600080fd5b806301935130146102f757806303c2924d14610319575b600080fd5b34801561030357600080fd5b506103176103123660046154e2565b610b9f565b005b34801561032557600080fd5b5061031761033436600461553d565b610ec0565b34801561034557600080fd5b506000546103669068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561039057600080fd5b506000546103b290700100000000000000000000000000000000900460ff1681565b60405161037b919061558e565b3480156103cb57600080fd5b506008545b60405190815260200161037b565b3480156103ea57600080fd5b506103b2611566565b3480156103ff57600080fd5b506103d061040e36600461553d565b61180b565b34801561041f57600080fd5b506001546104409073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161037b565b34801561047157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610440565b3480156104b157600080fd5b507f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f738610440565b3480156104e457600080fd5b50600054610508907201000000000000000000000000000000000000900460ff1681565b604051901515815260200161037b565b34801561052457600080fd5b507f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92610440565b6103176105593660046155cf565b611841565b34801561056a57600080fd5b506105a76040518060400160405280600c81526020017f312e332e312d626574612e32000000000000000000000000000000000000000081525081565b60405161037b9190615666565b3480156105c057600080fd5b506008546009546105cf919082565b6040805192835260208301919091520161037b565b3480156105f057600080fd5b506103d06105ff366004615679565b611853565b34801561061057600080fd5b507f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e610440565b34801561064357600080fd5b506105a761188d565b34801561065857600080fd5b506103176106673660046156b7565b61189b565b34801561067857600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103d0565b3480156106b857600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610366565b6103176106ed3660046156e9565b611a42565b3480156106fe57600080fd5b506009546103d0565b6103176107153660046155cf565b61251b565b610317612528565b34801561072e57600080fd5b506002546103d0565b34801561074357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103d0565b34801561078357600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103d0565b3480156107b657600080fd5b506108226107c5366004615679565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff16606082015260800161037b565b34801561088257600080fd5b5060405163ffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260200161037b565b3480156108c357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103d0565b34801561090357600080fd5b50610366610912366004615679565b612a81565b34801561092357600080fd5b506103d0610932366004615728565b612c60565b34801561094357600080fd5b50610957610952366004615679565b612e43565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e00161037b565b3480156109cd57600080fd5b506000546103669067ffffffffffffffff1681565b3480156109ee57600080fd5b506103d06109fd3660046156b7565b60036020526000908152604090205481565b348015610a1b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000003856103d0565b348015610a4e57600080fd5b50610317610a5d36600461575a565b612eda565b348015610a6e57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b0610366565b348015610aa157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000046103d0565b348015610ad457600080fd5b50610508610ae3366004615679565b60046020526000908152604090205460ff1681565b348015610b0457600080fd5b50610317610b133660046155cf565b613509565b348015610b2457600080fd5b50610b2d6139c6565b60405161037b939291906157e4565b348015610b4857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000086103d0565b348015610b7b57600080fd5b50610508610b8a366004615679565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610bcb57610bcb61555f565b14610c02576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610c55576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610ca3610c9e36869003860186615838565b613a41565b14610cda576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610cef9291906158c5565b604051809103902014610d2e576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d77610d7284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613a9d92505050565b613b0a565b90506000610d9e82600881518110610d9157610d916158d5565b6020026020010151613cc0565b9050602081511115610ddc576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610e51576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610eec57610eec61555f565b14610f23576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610f3857610f386158d5565b906000526020600020906005020190506000610f5384612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b081169082161015610fbc576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611005576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561102257508515155b156110bd578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110555781611071565b600186015473ffffffffffffffffffffffffffffffffffffffff165b905061107d8187613d74565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff166060830152611160576fffffffffffffffffffffffffffffffff6040820152600181526000869003611160578195505b600086826020015163ffffffff166111789190615933565b90506000838211611189578161118b565b835b602084015190915063ffffffff165b818110156112d75760008682815481106111b6576111b66158d5565b6000918252602080832090910154808352600690915260409091205490915060ff1661120e576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611223576112236158d5565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112805750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b156112c257600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b505080806112cf9061594b565b91505061119a565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921790915584900361155b57606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558915801561145757506000547201000000000000000000000000000000000000900460ff165b156114cc5760015473ffffffffffffffffffffffffffffffffffffffff1661147f818a613d74565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff909116178855611559565b61151373ffffffffffffffffffffffffffffffffffffffff8216156114f1578161150d565b600189015473ffffffffffffffffffffffffffffffffffffffff165b89613d74565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff1660028111156115945761159461555f565b146115cb576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff1661162f576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008154811061165b5761165b6158d5565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611696576001611699565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff9091161770010000000000000000000000000000000083600281111561174a5761174a61555f565b02179055600281111561175f5761175f61555f565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e73ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156117f057600080fd5b505af1158015611804573d6000803e3d6000fd5b5050505090565b6005602052816000526040600020818154811061182757600080fd5b90600052602060002001600091509150505481565b905090565b61184e8383836001611a42565b505050565b6000818152600760209081526040808320600590925282208054825461188490610100900463ffffffff1682615983565b95945050505050565b606061183c60546020613e75565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260036020526040812080549082905590819003611900576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169063f3fef3a390604401600060405180830381600087803b15801561199057600080fd5b505af11580156119a4573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a02576040519150601f19603f3d011682016040523d82523d6000602084013e611a07565b606091505b505090508061184e576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008054700100000000000000000000000000000000900460ff166002811115611a6e57611a6e61555f565b14611aa5576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110611aba57611aba6158d5565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514611ba1576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000611c61826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580611c9c5750611c997f00000000000000000000000000000000000000000000000000000000000000046002615933565b81145b8015611ca6575084155b15611cdd576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015611d03575086155b15611d3a576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000008811115611d94576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dbf7f00000000000000000000000000000000000000000000000000000000000000046001615933565b8103611dd157611dd186888588613ec7565b34611ddb83612c60565b14611e12576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611e1d88612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b0811690821603611e85576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611eb260017f0000000000000000000000000000000000000000000000000000000000000008615983565b8303611ff0577f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f47919061599a565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb591906159b7565b611fe9907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166159d0565b9050612083565b61201b60017f0000000000000000000000000000000000000000000000000000000000000004615983565b830361205657611fe97f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1660026159fc565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b6120b7817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b67ffffffffffffffff166120d28367ffffffffffffffff1690565b67ffffffffffffffff16111561211957612116817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615612197576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c8152602001908152602001600020600160028054905061242d9190615983565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169263d0e30db09234926004808301939282900301818588803b1580156124c557600080fd5b505af11580156124d9573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b61184e8383836000611a42565b60005471010000000000000000000000000000000000900460ff161561257a576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e1690637258a807906024016040805180830381865afa15801561262e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126529190615a55565b90925090508161268e576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a146126c157639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401351161275b576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd929092169363d0e30db093926004828101939282900301818588803b158015612a3057600080fd5b505af1158015612a44573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b600080600054700100000000000000000000000000000000900460ff166002811115612aaf57612aaf61555f565b14612ae6576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110612afb57612afb6158d5565b600091825260208220600590910201805490925063ffffffff90811614612b6a57815460028054909163ffffffff16908110612b3957612b396158d5565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090612ba290700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b612bb69067ffffffffffffffff1642615983565b612bd5612b95846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16612be99190615933565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b01667ffffffffffffffff168167ffffffffffffffff1611612c365780611884565b7f00000000000000000000000000000000000000000000000000000000000004b095945050505050565b600080612cff836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000008811115612d5e576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000612d798383615aa8565b9050670de0b6b3a76400006000612db0827f0000000000000000000000000000000000000000000000000000000000000008615abc565b90506000612dce612dc9670de0b6b3a764000086615abc565b614078565b90506000612ddc84846142d3565b90506000612dea8383614322565b90506000612df782614350565b90506000612e1682612e11670de0b6b3a76400008f615abc565b614538565b90506000612e248b83614322565b9050612e30818d615abc565b9f9e505050505050505050505050505050565b60028181548110612e5357600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b60008054700100000000000000000000000000000000900460ff166002811115612f0657612f0661555f565b14612f3d576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028781548110612f5257612f526158d5565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b9050612fb17f00000000000000000000000000000000000000000000000000000000000000086001615933565b61304d826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1614613087576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561317e576130da7f00000000000000000000000000000000000000000000000000000000000000047f0000000000000000000000000000000000000000000000000000000000000008615983565b6001901b6130f9846fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff166131159190615af9565b156131525761314961313a60016fffffffffffffffffffffffffffffffff8716615b0d565b865463ffffffff166000614608565b60030154613174565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506131a8565b600385015491506131a561313a6fffffffffffffffffffffffffffffffff86166001615b36565b90505b600882901b60088a8a6040516131bf9291906158c5565b6040518091039020901b14613200576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061320b8c6146ec565b9050600061321a836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff169063e14ced3290613294908f908f908f908f908a90600401615baa565b6020604051808303816000875af11580156132b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d791906159b7565b600485015491149150600090600290613382906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b61341e896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6134289190615be4565b6134329190615c07565b60ff161590508115158103613473576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156134ca576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff1660028111156135355761353561555f565b1461356c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061357b8661471b565b9350935093509350600061359185858585614b24565b905060007f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015613600573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613624919061599a565b90506001890361371c5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a84613680367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af11580156136f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061371691906159b7565b5061155b565b600289036137485773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8489613680565b600389036137745773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8487613680565b600489036138fb5760006137ba6fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000004614bde565b6009546137c79190615933565b6137d2906001615933565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061383b57367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036054013561383d565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156138d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f491906159b7565b505061155b565b60058903613994576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000038560c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016136d3565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060613a1f61188d565b9050909192565b600081831015613a365781613a38565b825b90505b92915050565b60008160000151826020015183604001518460600151604051602001613a80949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003613aec576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000613b1a85614c8c565b919450925090506001816001811115613b3557613b3561555f565b14613b6c576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451613b788385615933565b14613baf576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081613bc65790505093506000835b8651811015613cb457600080613c396040518060400160405280858c60000151613c1d9190615983565b8152602001858c60200151613c329190615933565b9052614c8c565b509150915060405180604001604052808383613c559190615933565b8152602001848b60200151613c6a9190615933565b815250888581518110613c7f57613c7f6158d5565b6020908102919091010152613c95600185615933565b9350613ca18183615933565b613cab9084615933565b92505050613bf3565b50845250919392505050565b60606000806000613cd085614c8c565b919450925090506000816001811115613ceb57613ceb61555f565b14613d22576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613d2c8284615933565b855114613d65576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118848560200151848461512a565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff90931692839290613dc3908490615933565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd921690637eee288d90604401600060405180830381600087803b158015613e5857600080fd5b505af1158015613e6c573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b6000613ee66fffffffffffffffffffffffffffffffff84166001615b36565b90506000613ef682866001614608565b9050600086901a8380613fe25750613f2f60027f0000000000000000000000000000000000000000000000000000000000000004615af9565b6004830154600290613fd3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b613fdd9190615c07565b60ff16145b1561403a5760ff811660011480613ffc575060ff81166002145b614035576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b613e6c565b60ff811615613e6c576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b17600082136140d757631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a76400000215820261431057637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b6000816000190483118202156143405763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d7821361437e57919050565b680755bf798b4a1bf1e5821261439c5763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000613a38670de0b6b3a76400008361455086614078565b61455a9190615c29565b6145649190615ce5565b614350565b6000806145f6837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826146515761464c6fffffffffffffffffffffffffffffffff86167f00000000000000000000000000000000000000000000000000000000000000046151bf565b61466c565b61466c856fffffffffffffffffffffffffffffffff1661534b565b905060028481548110614681576146816158d5565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff8281169116146146e457815460028054909163ffffffff169081106146cf576146cf6158d5565b90600052602060002090600502019150614692565b509392505050565b60008060008060006146fd8661471b565b935093509350935061471184848484614b24565b9695505050505050565b600080600080600085905060006002828154811061473b5761473b6158d5565b600091825260209091206004600590920201908101549091507f000000000000000000000000000000000000000000000000000000000000000490614812906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff161161484c576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f000000000000000000000000000000000000000000000000000000000000000490614913906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16925082111561498857825463ffffffff166149527f00000000000000000000000000000000000000000000000000000000000000046001615933565b830361495c578391505b6002818154811061496f5761496f6158d5565b9060005260206000209060050201935080945050614850565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149f16149dc856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff161490508015614ac0576000614a29836fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff161115614a94576000614a6b614a6360016fffffffffffffffffffffffffffffffff8616615b0d565b896001614608565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a50614a9a9050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614b16565b6000614ae2614a636fffffffffffffffffffffffffffffffff85166001615b36565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614b915760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611884565b8282604051602001614bbf9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614c6b847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614ccf576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614cf4576000600160009450945094505050615123565b60b78111614e0a576000614d09608083615983565b905080876000015111614d48576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614dc057507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614df7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060019550935060009250615123915050565b60bf8111614f68576000614e1f60b783615983565b905080876000015111614e5e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614ec0576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614f08576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f128184615933565b895111614f4b576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f56836001615933565b97509550600094506151239350505050565b60f78111614fcd576000614f7d60c083615983565b905080876000015111614fbc576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600195509350849250615123915050565b6000614fda60f783615983565b905080876000015111615019576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361507b576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116150c3576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6150cd8184615933565b895111615106576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615111836001615933565b97509550600194506151239350505050565b9193909250565b60608167ffffffffffffffff81111561514557615145615809565b6040519080825280601f01601f19166020018201604052801561516f576020820181803683370190505b50905081156151b85760006151848486615933565b90506020820160005b848110156151a557828101518282015260200161518d565b848111156151b4576000858301525b5050505b9392505050565b60008161525e846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116152745763b34b5c226000526004601cfd5b61527d8361534b565b90508161531c826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611613a3b57613a38615332836001615933565b6fffffffffffffffffffffffffffffffff8316906153f0565b600081196001830116816153df827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b60008061547d847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f8401126154ab57600080fd5b50813567ffffffffffffffff8111156154c357600080fd5b6020830191508360208285010111156154db57600080fd5b9250929050565b600080600083850360a08112156154f857600080fd5b608081121561550657600080fd5b50839250608084013567ffffffffffffffff81111561552457600080fd5b61553086828701615499565b9497909650939450505050565b6000806040838503121561555057600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106155c9577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806000606084860312156155e457600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561562157602081850181015186830182015201615605565b81811115615633576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000613a3860208301846155fb565b60006020828403121561568b57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146156b457600080fd5b50565b6000602082840312156156c957600080fd5b81356151b881615692565b803580151581146156e457600080fd5b919050565b600080600080608085870312156156ff57600080fd5b84359350602085013592506040850135915061571d606086016156d4565b905092959194509250565b60006020828403121561573a57600080fd5b81356fffffffffffffffffffffffffffffffff811681146151b857600080fd5b6000806000806000806080878903121561577357600080fd5b86359550615783602088016156d4565b9450604087013567ffffffffffffffff808211156157a057600080fd5b6157ac8a838b01615499565b909650945060608901359150808211156157c557600080fd5b506157d289828a01615499565b979a9699509497509295939492505050565b63ffffffff8416815282602082015260606040820152600061188460608301846155fb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006080828403121561584a57600080fd5b6040516080810181811067ffffffffffffffff82111715615894577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561594657615946615904565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361597c5761597c615904565b5060010190565b60008282101561599557615995615904565b500390565b6000602082840312156159ac57600080fd5b81516151b881615692565b6000602082840312156159c957600080fd5b5051919050565b600067ffffffffffffffff8083168185168083038211156159f3576159f3615904565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615a2357615a23615904565b02949350505050565b600067ffffffffffffffff83811690831681811015615a4d57615a4d615904565b039392505050565b60008060408385031215615a6857600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615ab757615ab7615a79565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615af457615af4615904565b500290565b600082615b0857615b08615a79565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615a4d57615a4d615904565b60006fffffffffffffffffffffffffffffffff8083168185168083038211156159f3576159f3615904565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615bbe606083018789615b61565b8281036020840152615bd1818688615b61565b9150508260408301529695505050505050565b600060ff821660ff841680821015615bfe57615bfe615904565b90039392505050565b600060ff831680615c1a57615c1a615a79565b8060ff84160691505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615c6a57615c6a615904565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615ca557615ca5615904565b60008712925087820587128484161615615cc157615cc1615904565b87850587128184161615615cd757615cd7615904565b505050929093029392505050565b600082615cf457615cf4615a79565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615d4857615d48615904565b50059056fea164736f6c634300080f000a"; + hex"6080604052600436106102f25760003560e01c806370872aa51161018f578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b18578063fa315aa914610b3c578063fe2bbeb214610b6f57600080fd5b8063ec5e630814610a95578063eff0f59214610ac8578063f8f43ff614610af857600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a0f578063d8cc1a3c14610a42578063dabd396d14610a6257600080fd5b8063c6f0308c14610937578063cf09e0d0146109c1578063d5d44d80146109e257600080fd5b80638d450a9511610143578063bcef3b551161011d578063bcef3b55146108b7578063bd8da956146108f7578063c395e1ca1461091757600080fd5b80638d450a9514610777578063a445ece6146107aa578063bbdc02db1461087657600080fd5b80638129fc1c116101745780638129fc1c1461071a5780638980e0cc146107225780638b85902b1461073757600080fd5b806370872aa5146106f25780637b0f0adc1461070757600080fd5b80633fc8cef3116102485780635c0cba33116101fc5780636361506d116101d65780636361506d1461066c5780636b6716c0146106ac5780636f034409146106df57600080fd5b80635c0cba3314610604578063609d33341461063757806360e274641461064c57600080fd5b806354fd4d501161022d57806354fd4d501461055e57806357da950e146105b45780635a5fa2d9146105e457600080fd5b80633fc8cef314610518578063472777c61461054b57600080fd5b80632810e1d6116102aa57806337b1b2291161028457806337b1b229146104655780633a768463146104a55780633e3ac912146104d857600080fd5b80632810e1d6146103de5780632ad69aeb146103f357806330dbe5701461041357600080fd5b806319effeb4116102db57806319effeb414610339578063200d2ed21461038457806325fc2ace146103bf57600080fd5b806301935130146102f757806303c2924d14610319575b600080fd5b34801561030357600080fd5b506103176103123660046154e2565b610b9f565b005b34801561032557600080fd5b5061031761033436600461553d565b610ec0565b34801561034557600080fd5b506000546103669068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561039057600080fd5b506000546103b290700100000000000000000000000000000000900460ff1681565b60405161037b919061558e565b3480156103cb57600080fd5b506008545b60405190815260200161037b565b3480156103ea57600080fd5b506103b2611566565b3480156103ff57600080fd5b506103d061040e36600461553d565b61180b565b34801561041f57600080fd5b506001546104409073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161037b565b34801561047157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610440565b3480156104b157600080fd5b507f000000000000000000000000180cbe2ebb9f37d3a3c542ddc2546fd160555a73610440565b3480156104e457600080fd5b50600054610508907201000000000000000000000000000000000000900460ff1681565b604051901515815260200161037b565b34801561052457600080fd5b507f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92610440565b6103176105593660046155cf565b611841565b34801561056a57600080fd5b506105a76040518060400160405280600c81526020017f312e332e312d626574612e32000000000000000000000000000000000000000081525081565b60405161037b9190615666565b3480156105c057600080fd5b506008546009546105cf919082565b6040805192835260208301919091520161037b565b3480156105f057600080fd5b506103d06105ff366004615679565b611853565b34801561061057600080fd5b507f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e610440565b34801561064357600080fd5b506105a761188d565b34801561065857600080fd5b506103176106673660046156b7565b61189b565b34801561067857600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103d0565b3480156106b857600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610366565b6103176106ed3660046156e9565b611a42565b3480156106fe57600080fd5b506009546103d0565b6103176107153660046155cf565b61251b565b610317612528565b34801561072e57600080fd5b506002546103d0565b34801561074357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103d0565b34801561078357600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103d0565b3480156107b657600080fd5b506108226107c5366004615679565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff16606082015260800161037b565b34801561088257600080fd5b5060405163ffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260200161037b565b3480156108c357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103d0565b34801561090357600080fd5b50610366610912366004615679565b612a81565b34801561092357600080fd5b506103d0610932366004615728565b612c60565b34801561094357600080fd5b50610957610952366004615679565b612e43565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e00161037b565b3480156109cd57600080fd5b506000546103669067ffffffffffffffff1681565b3480156109ee57600080fd5b506103d06109fd3660046156b7565b60036020526000908152604090205481565b348015610a1b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000003856103d0565b348015610a4e57600080fd5b50610317610a5d36600461575a565b612eda565b348015610a6e57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b0610366565b348015610aa157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000046103d0565b348015610ad457600080fd5b50610508610ae3366004615679565b60046020526000908152604090205460ff1681565b348015610b0457600080fd5b50610317610b133660046155cf565b613509565b348015610b2457600080fd5b50610b2d6139c6565b60405161037b939291906157e4565b348015610b4857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000086103d0565b348015610b7b57600080fd5b50610508610b8a366004615679565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610bcb57610bcb61555f565b14610c02576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610c55576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610ca3610c9e36869003860186615838565b613a41565b14610cda576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610cef9291906158c5565b604051809103902014610d2e576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d77610d7284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613a9d92505050565b613b0a565b90506000610d9e82600881518110610d9157610d916158d5565b6020026020010151613cc0565b9050602081511115610ddc576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610e51576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610eec57610eec61555f565b14610f23576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610f3857610f386158d5565b906000526020600020906005020190506000610f5384612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b081169082161015610fbc576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611005576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561102257508515155b156110bd578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110555781611071565b600186015473ffffffffffffffffffffffffffffffffffffffff165b905061107d8187613d74565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff166060830152611160576fffffffffffffffffffffffffffffffff6040820152600181526000869003611160578195505b600086826020015163ffffffff166111789190615933565b90506000838211611189578161118b565b835b602084015190915063ffffffff165b818110156112d75760008682815481106111b6576111b66158d5565b6000918252602080832090910154808352600690915260409091205490915060ff1661120e576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611223576112236158d5565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112805750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b156112c257600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b505080806112cf9061594b565b91505061119a565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921790915584900361155b57606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558915801561145757506000547201000000000000000000000000000000000000900460ff165b156114cc5760015473ffffffffffffffffffffffffffffffffffffffff1661147f818a613d74565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff909116178855611559565b61151373ffffffffffffffffffffffffffffffffffffffff8216156114f1578161150d565b600189015473ffffffffffffffffffffffffffffffffffffffff165b89613d74565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff1660028111156115945761159461555f565b146115cb576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff1661162f576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008154811061165b5761165b6158d5565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611696576001611699565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff9091161770010000000000000000000000000000000083600281111561174a5761174a61555f565b02179055600281111561175f5761175f61555f565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e73ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156117f057600080fd5b505af1158015611804573d6000803e3d6000fd5b5050505090565b6005602052816000526040600020818154811061182757600080fd5b90600052602060002001600091509150505481565b905090565b61184e8383836001611a42565b505050565b6000818152600760209081526040808320600590925282208054825461188490610100900463ffffffff1682615983565b95945050505050565b606061183c60546020613e75565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260036020526040812080549082905590819003611900576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169063f3fef3a390604401600060405180830381600087803b15801561199057600080fd5b505af11580156119a4573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a02576040519150601f19603f3d011682016040523d82523d6000602084013e611a07565b606091505b505090508061184e576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008054700100000000000000000000000000000000900460ff166002811115611a6e57611a6e61555f565b14611aa5576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110611aba57611aba6158d5565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514611ba1576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000611c61826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580611c9c5750611c997f00000000000000000000000000000000000000000000000000000000000000046002615933565b81145b8015611ca6575084155b15611cdd576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015611d03575086155b15611d3a576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000008811115611d94576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dbf7f00000000000000000000000000000000000000000000000000000000000000046001615933565b8103611dd157611dd186888588613ec7565b34611ddb83612c60565b14611e12576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611e1d88612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b0811690821603611e85576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611eb260017f0000000000000000000000000000000000000000000000000000000000000008615983565b8303611ff0577f000000000000000000000000180cbe2ebb9f37d3a3c542ddc2546fd160555a7373ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f47919061599a565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb591906159b7565b611fe9907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166159d0565b9050612083565b61201b60017f0000000000000000000000000000000000000000000000000000000000000004615983565b830361205657611fe97f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1660026159fc565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b6120b7817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b67ffffffffffffffff166120d28367ffffffffffffffff1690565b67ffffffffffffffff16111561211957612116817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615612197576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c8152602001908152602001600020600160028054905061242d9190615983565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169263d0e30db09234926004808301939282900301818588803b1580156124c557600080fd5b505af11580156124d9573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b61184e8383836000611a42565b60005471010000000000000000000000000000000000900460ff161561257a576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e1690637258a807906024016040805180830381865afa15801561262e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126529190615a55565b90925090508161268e576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a146126c157639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401351161275b576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd929092169363d0e30db093926004828101939282900301818588803b158015612a3057600080fd5b505af1158015612a44573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b600080600054700100000000000000000000000000000000900460ff166002811115612aaf57612aaf61555f565b14612ae6576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110612afb57612afb6158d5565b600091825260208220600590910201805490925063ffffffff90811614612b6a57815460028054909163ffffffff16908110612b3957612b396158d5565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090612ba290700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b612bb69067ffffffffffffffff1642615983565b612bd5612b95846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16612be99190615933565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b01667ffffffffffffffff168167ffffffffffffffff1611612c365780611884565b7f00000000000000000000000000000000000000000000000000000000000004b095945050505050565b600080612cff836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000008811115612d5e576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000612d798383615aa8565b9050670de0b6b3a76400006000612db0827f0000000000000000000000000000000000000000000000000000000000000008615abc565b90506000612dce612dc9670de0b6b3a764000086615abc565b614078565b90506000612ddc84846142d3565b90506000612dea8383614322565b90506000612df782614350565b90506000612e1682612e11670de0b6b3a76400008f615abc565b614538565b90506000612e248b83614322565b9050612e30818d615abc565b9f9e505050505050505050505050505050565b60028181548110612e5357600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b60008054700100000000000000000000000000000000900460ff166002811115612f0657612f0661555f565b14612f3d576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028781548110612f5257612f526158d5565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b9050612fb17f00000000000000000000000000000000000000000000000000000000000000086001615933565b61304d826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1614613087576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561317e576130da7f00000000000000000000000000000000000000000000000000000000000000047f0000000000000000000000000000000000000000000000000000000000000008615983565b6001901b6130f9846fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff166131159190615af9565b156131525761314961313a60016fffffffffffffffffffffffffffffffff8716615b0d565b865463ffffffff166000614608565b60030154613174565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506131a8565b600385015491506131a561313a6fffffffffffffffffffffffffffffffff86166001615b36565b90505b600882901b60088a8a6040516131bf9291906158c5565b6040518091039020901b14613200576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061320b8c6146ec565b9050600061321a836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000180cbe2ebb9f37d3a3c542ddc2546fd160555a7373ffffffffffffffffffffffffffffffffffffffff169063e14ced3290613294908f908f908f908f908a90600401615baa565b6020604051808303816000875af11580156132b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d791906159b7565b600485015491149150600090600290613382906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b61341e896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6134289190615be4565b6134329190615c07565b60ff161590508115158103613473576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156134ca576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff1660028111156135355761353561555f565b1461356c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061357b8661471b565b9350935093509350600061359185858585614b24565b905060007f000000000000000000000000180cbe2ebb9f37d3a3c542ddc2546fd160555a7373ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015613600573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613624919061599a565b90506001890361371c5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a84613680367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af11580156136f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061371691906159b7565b5061155b565b600289036137485773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8489613680565b600389036137745773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8487613680565b600489036138fb5760006137ba6fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000004614bde565b6009546137c79190615933565b6137d2906001615933565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061383b57367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036054013561383d565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156138d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f491906159b7565b505061155b565b60058903613994576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000038560c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016136d3565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060613a1f61188d565b9050909192565b600081831015613a365781613a38565b825b90505b92915050565b60008160000151826020015183604001518460600151604051602001613a80949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003613aec576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000613b1a85614c8c565b919450925090506001816001811115613b3557613b3561555f565b14613b6c576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451613b788385615933565b14613baf576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081613bc65790505093506000835b8651811015613cb457600080613c396040518060400160405280858c60000151613c1d9190615983565b8152602001858c60200151613c329190615933565b9052614c8c565b509150915060405180604001604052808383613c559190615933565b8152602001848b60200151613c6a9190615933565b815250888581518110613c7f57613c7f6158d5565b6020908102919091010152613c95600185615933565b9350613ca18183615933565b613cab9084615933565b92505050613bf3565b50845250919392505050565b60606000806000613cd085614c8c565b919450925090506000816001811115613ceb57613ceb61555f565b14613d22576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613d2c8284615933565b855114613d65576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118848560200151848461512a565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff90931692839290613dc3908490615933565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd921690637eee288d90604401600060405180830381600087803b158015613e5857600080fd5b505af1158015613e6c573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b6000613ee66fffffffffffffffffffffffffffffffff84166001615b36565b90506000613ef682866001614608565b9050600086901a8380613fe25750613f2f60027f0000000000000000000000000000000000000000000000000000000000000004615af9565b6004830154600290613fd3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b613fdd9190615c07565b60ff16145b1561403a5760ff811660011480613ffc575060ff81166002145b614035576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b613e6c565b60ff811615613e6c576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b17600082136140d757631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a76400000215820261431057637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b6000816000190483118202156143405763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d7821361437e57919050565b680755bf798b4a1bf1e5821261439c5763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000613a38670de0b6b3a76400008361455086614078565b61455a9190615c29565b6145649190615ce5565b614350565b6000806145f6837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826146515761464c6fffffffffffffffffffffffffffffffff86167f00000000000000000000000000000000000000000000000000000000000000046151bf565b61466c565b61466c856fffffffffffffffffffffffffffffffff1661534b565b905060028481548110614681576146816158d5565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff8281169116146146e457815460028054909163ffffffff169081106146cf576146cf6158d5565b90600052602060002090600502019150614692565b509392505050565b60008060008060006146fd8661471b565b935093509350935061471184848484614b24565b9695505050505050565b600080600080600085905060006002828154811061473b5761473b6158d5565b600091825260209091206004600590920201908101549091507f000000000000000000000000000000000000000000000000000000000000000490614812906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff161161484c576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f000000000000000000000000000000000000000000000000000000000000000490614913906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16925082111561498857825463ffffffff166149527f00000000000000000000000000000000000000000000000000000000000000046001615933565b830361495c578391505b6002818154811061496f5761496f6158d5565b9060005260206000209060050201935080945050614850565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149f16149dc856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff161490508015614ac0576000614a29836fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff161115614a94576000614a6b614a6360016fffffffffffffffffffffffffffffffff8616615b0d565b896001614608565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a50614a9a9050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614b16565b6000614ae2614a636fffffffffffffffffffffffffffffffff85166001615b36565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614b915760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611884565b8282604051602001614bbf9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614c6b847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614ccf576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614cf4576000600160009450945094505050615123565b60b78111614e0a576000614d09608083615983565b905080876000015111614d48576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614dc057507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614df7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060019550935060009250615123915050565b60bf8111614f68576000614e1f60b783615983565b905080876000015111614e5e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614ec0576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614f08576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f128184615933565b895111614f4b576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f56836001615933565b97509550600094506151239350505050565b60f78111614fcd576000614f7d60c083615983565b905080876000015111614fbc576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600195509350849250615123915050565b6000614fda60f783615983565b905080876000015111615019576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361507b576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116150c3576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6150cd8184615933565b895111615106576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615111836001615933565b97509550600194506151239350505050565b9193909250565b60608167ffffffffffffffff81111561514557615145615809565b6040519080825280601f01601f19166020018201604052801561516f576020820181803683370190505b50905081156151b85760006151848486615933565b90506020820160005b848110156151a557828101518282015260200161518d565b848111156151b4576000858301525b5050505b9392505050565b60008161525e846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116152745763b34b5c226000526004601cfd5b61527d8361534b565b90508161531c826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611613a3b57613a38615332836001615933565b6fffffffffffffffffffffffffffffffff8316906153f0565b600081196001830116816153df827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b60008061547d847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f8401126154ab57600080fd5b50813567ffffffffffffffff8111156154c357600080fd5b6020830191508360208285010111156154db57600080fd5b9250929050565b600080600083850360a08112156154f857600080fd5b608081121561550657600080fd5b50839250608084013567ffffffffffffffff81111561552457600080fd5b61553086828701615499565b9497909650939450505050565b6000806040838503121561555057600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106155c9577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806000606084860312156155e457600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561562157602081850181015186830182015201615605565b81811115615633576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000613a3860208301846155fb565b60006020828403121561568b57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146156b457600080fd5b50565b6000602082840312156156c957600080fd5b81356151b881615692565b803580151581146156e457600080fd5b919050565b600080600080608085870312156156ff57600080fd5b84359350602085013592506040850135915061571d606086016156d4565b905092959194509250565b60006020828403121561573a57600080fd5b81356fffffffffffffffffffffffffffffffff811681146151b857600080fd5b6000806000806000806080878903121561577357600080fd5b86359550615783602088016156d4565b9450604087013567ffffffffffffffff808211156157a057600080fd5b6157ac8a838b01615499565b909650945060608901359150808211156157c557600080fd5b506157d289828a01615499565b979a9699509497509295939492505050565b63ffffffff8416815282602082015260606040820152600061188460608301846155fb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006080828403121561584a57600080fd5b6040516080810181811067ffffffffffffffff82111715615894577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561594657615946615904565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361597c5761597c615904565b5060010190565b60008282101561599557615995615904565b500390565b6000602082840312156159ac57600080fd5b81516151b881615692565b6000602082840312156159c957600080fd5b5051919050565b600067ffffffffffffffff8083168185168083038211156159f3576159f3615904565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615a2357615a23615904565b02949350505050565b600067ffffffffffffffff83811690831681811015615a4d57615a4d615904565b039392505050565b60008060408385031215615a6857600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615ab757615ab7615a79565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615af457615af4615904565b500290565b600082615b0857615b08615a79565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615a4d57615a4d615904565b60006fffffffffffffffffffffffffffffffff8083168185168083038211156159f3576159f3615904565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615bbe606083018789615b61565b8281036020840152615bd1818688615b61565b9150508260408301529695505050505050565b600060ff821660ff841680821015615bfe57615bfe615904565b90039392505050565b600060ff831680615c1a57615c1a615a79565b8060ff84160691505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615c6a57615c6a615904565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615ca557615ca5615904565b60008712925087820587128484161615615cc157615cc1615904565b87850587128184161615615cd757615cd7615904565b505050929093029392505050565b600082615cf457615cf4615a79565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615d4857615d48615904565b50059056fea164736f6c634300080f000a"; bytes internal constant acc34Code = - hex"6080604052600436106103085760003560e01c806370872aa51161019a578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b94578063fa315aa914610bb8578063fe2bbeb214610beb57600080fd5b8063ec5e630814610b11578063eff0f59214610b44578063f8f43ff614610b7457600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a8b578063d8cc1a3c14610abe578063dabd396d14610ade57600080fd5b8063c6f0308c146109b3578063cf09e0d014610a3d578063d5d44d8014610a5e57600080fd5b8063a445ece611610143578063bcef3b551161011d578063bcef3b5514610933578063bd8da95614610973578063c395e1ca1461099357600080fd5b8063a445ece6146107f3578063a8e4fb90146108bf578063bbdc02db146108f257600080fd5b80638980e0cc116101745780638980e0cc1461076b5780638b85902b146107805780638d450a95146107c057600080fd5b806370872aa51461073b5780637b0f0adc146107505780638129fc1c1461076357600080fd5b80633fc8cef31161025e5780635c0cba33116102075780636361506d116101e15780636361506d146106b55780636b6716c0146106f55780636f0344091461072857600080fd5b80635c0cba331461064d578063609d33341461068057806360e274641461069557600080fd5b806354fd4d501161023857806354fd4d50146105a757806357da950e146105fd5780635a5fa2d91461062d57600080fd5b80633fc8cef31461052e578063472777c614610561578063534db0e21461057457600080fd5b80632810e1d6116102c057806337b1b2291161029a57806337b1b2291461047b5780633a768463146104bb5780633e3ac912146104ee57600080fd5b80632810e1d6146103f45780632ad69aeb1461040957806330dbe5701461042957600080fd5b806319effeb4116102f157806319effeb41461034f578063200d2ed21461039a57806325fc2ace146103d557600080fd5b8063019351301461030d57806303c2924d1461032f575b600080fd5b34801561031957600080fd5b5061032d61032836600461575d565b610c1b565b005b34801561033b57600080fd5b5061032d61034a3660046157b8565b610f3c565b34801561035b57600080fd5b5060005461037c9068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156103a657600080fd5b506000546103c890700100000000000000000000000000000000900460ff1681565b6040516103919190615809565b3480156103e157600080fd5b506008545b604051908152602001610391565b34801561040057600080fd5b506103c86115e2565b34801561041557600080fd5b506103e66104243660046157b8565b611887565b34801561043557600080fd5b506001546104569073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610391565b34801561048757600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610456565b3480156104c757600080fd5b507f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f738610456565b3480156104fa57600080fd5b5060005461051e907201000000000000000000000000000000000000900460ff1681565b6040519015158152602001610391565b34801561053a57600080fd5b507f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309610456565b61032d61056f36600461584a565b6118bd565b34801561058057600080fd5b507f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63610456565b3480156105b357600080fd5b506105f06040518060400160405280600c81526020017f312e332e312d626574612e32000000000000000000000000000000000000000081525081565b60405161039191906158e1565b34801561060957600080fd5b50600854600954610618919082565b60408051928352602083019190915201610391565b34801561063957600080fd5b506103e66106483660046158f4565b6118cf565b34801561065957600080fd5b507f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e610456565b34801561068c57600080fd5b506105f0611909565b3480156106a157600080fd5b5061032d6106b0366004615932565b611917565b3480156106c157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103e6565b34801561070157600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061037c565b61032d610736366004615964565b611abe565b34801561074757600080fd5b506009546103e6565b61032d61075e36600461584a565b611b7f565b61032d611b8c565b34801561077757600080fd5b506002546103e6565b34801561078c57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103e6565b3480156107cc57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103e6565b3480156107ff57600080fd5b5061086b61080e3660046158f4565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff166060820152608001610391565b3480156108cb57600080fd5b507f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8610456565b3480156108fe57600080fd5b5060405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000001168152602001610391565b34801561093f57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103e6565b34801561097f57600080fd5b5061037c61098e3660046158f4565b611c05565b34801561099f57600080fd5b506103e66109ae3660046159a3565b611de4565b3480156109bf57600080fd5b506109d36109ce3660046158f4565b611fc7565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e001610391565b348015610a4957600080fd5b5060005461037c9067ffffffffffffffff1681565b348015610a6a57600080fd5b506103e6610a79366004615932565b60036020526000908152604090205481565b348015610a9757600080fd5b507f00000000000000000000000000000000000000000000000000000000000003856103e6565b348015610aca57600080fd5b5061032d610ad93660046159d5565b61205e565b348015610aea57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b061037c565b348015610b1d57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000046103e6565b348015610b5057600080fd5b5061051e610b5f3660046158f4565b60046020526000908152604090205460ff1681565b348015610b8057600080fd5b5061032d610b8f36600461584a565b612123565b348015610ba057600080fd5b50610ba96125e0565b60405161039193929190615a5f565b348015610bc457600080fd5b507f00000000000000000000000000000000000000000000000000000000000000086103e6565b348015610bf757600080fd5b5061051e610c063660046158f4565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610c4757610c476157da565b14610c7e576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610cd1576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d08367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610d1f610d1a36869003860186615ab3565b61265b565b14610d56576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610d6b929190615b40565b604051809103902014610daa576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610df3610dee84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506126b792505050565b612724565b90506000610e1a82600881518110610e0d57610e0d615b50565b60200260200101516128da565b9050602081511115610e58576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610ecd576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610f6857610f686157da565b14610f9f576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610fb457610fb4615b50565b906000526020600020906005020190506000610fcf84611c05565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b081169082161015611038576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611081576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561109e57508515155b15611139578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110d157816110ed565b600186015473ffffffffffffffffffffffffffffffffffffffff165b90506110f9818761298e565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff1660608301526111dc576fffffffffffffffffffffffffffffffff60408201526001815260008690036111dc578195505b600086826020015163ffffffff166111f49190615bae565b905060008382116112055781611207565b835b602084015190915063ffffffff165b8181101561135357600086828154811061123257611232615b50565b6000918252602080832090910154808352600690915260409091205490915060ff1661128a576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002828154811061129f5761129f615b50565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112fc5750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b1561133e57600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b5050808061134b90615bc6565b915050611216565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909316929092179091558490036115d757606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055891580156114d357506000547201000000000000000000000000000000000000900460ff165b156115485760015473ffffffffffffffffffffffffffffffffffffffff166114fb818a61298e565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff9091161788556115d5565b61158f73ffffffffffffffffffffffffffffffffffffffff82161561156d5781611589565b600189015473ffffffffffffffffffffffffffffffffffffffff165b8961298e565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff166002811115611610576116106157da565b14611647576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff166116ab576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660026000815481106116d7576116d7615b50565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611712576001611715565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff909116177001000000000000000000000000000000008360028111156117c6576117c66157da565b0217905560028111156117db576117db6157da565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e73ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561186c57600080fd5b505af1158015611880573d6000803e3d6000fd5b5050505090565b600560205281600052604060002081815481106118a357600080fd5b90600052602060002001600091509150505481565b905090565b6118ca8383836001611abe565b505050565b6000818152600760209081526040808320600590925282208054825461190090610100900463ffffffff1682615bfe565b95945050505050565b60606118b860546020612a8f565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604081208054908290559081900361197c576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309169063f3fef3a390604401600060405180830381600087803b158015611a0c57600080fd5b505af1158015611a20573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a7e576040519150601f19603f3d011682016040523d82523d6000602084013e611a83565b606091505b50509050806118ca576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8161480611b3757503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b6316145b611b6d576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b7984848484612ae1565b50505050565b6118ca8383836000611abe565b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c81614611bfb576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c036135ba565b565b600080600054700100000000000000000000000000000000900460ff166002811115611c3357611c336157da565b14611c6a576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110611c7f57611c7f615b50565b600091825260208220600590910201805490925063ffffffff90811614611cee57815460028054909163ffffffff16908110611cbd57611cbd615b50565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090611d2690700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b611d3a9067ffffffffffffffff1642615bfe565b611d59611d19846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16611d6d9190615bae565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b01667ffffffffffffffff168167ffffffffffffffff1611611dba5780611900565b7f00000000000000000000000000000000000000000000000000000000000004b095945050505050565b600080611e83836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000008811115611ee2576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000611efd8383615c44565b9050670de0b6b3a76400006000611f34827f0000000000000000000000000000000000000000000000000000000000000008615c58565b90506000611f52611f4d670de0b6b3a764000086615c58565b613b13565b90506000611f608484613d6e565b90506000611f6e8383613dbd565b90506000611f7b82613deb565b90506000611f9a82611f95670de0b6b3a76400008f615c58565b613fd3565b90506000611fa88b83613dbd565b9050611fb4818d615c58565b9f9e505050505050505050505050505050565b60028181548110611fd757600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c81614806120d757503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b6316145b61210d576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61211b868686868686614004565b505050505050565b60008054700100000000000000000000000000000000900460ff16600281111561214f5761214f6157da565b14612186576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061219586614633565b935093509350935060006121ab85858585614a3c565b905060007f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561221a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223e9190615c95565b9050600189036123365773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8461229a367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af115801561230c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123309190615cb2565b506115d7565b600289036123625773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848961229a565b6003890361238e5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848761229a565b600489036125155760006123d46fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000004614af6565b6009546123e19190615bae565b6123ec906001615bae565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061245557367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135612457565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156124ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250e9190615cb2565b50506115d7565b600589036125ae576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000038560c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016122ed565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000001367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060612639611909565b9050909192565b6000818310156126505781612652565b825b90505b92915050565b6000816000015182602001518360400151846060015160405160200161269a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003612706576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b6060600080600061273485614ba4565b91945092509050600181600181111561274f5761274f6157da565b14612786576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516127928385615bae565b146127c9576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816127e05790505093506000835b86518110156128ce576000806128536040518060400160405280858c600001516128379190615bfe565b8152602001858c6020015161284c9190615bae565b9052614ba4565b50915091506040518060400160405280838361286f9190615bae565b8152602001848b602001516128849190615bae565b81525088858151811061289957612899615b50565b60209081029190910101526128af600185615bae565b93506128bb8183615bae565b6128c59084615bae565b9250505061280d565b50845250919392505050565b606060008060006128ea85614ba4565b919450925090506000816001811115612905576129056157da565b1461293c576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129468284615bae565b85511461297f576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61190085602001518484615042565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff909316928392906129dd908490615bae565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f000000000000000000000000d6eaf4c146261653ee059077b78ed088add543091690637eee288d90604401600060405180830381600087803b158015612a7257600080fd5b505af1158015612a86573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b60008054700100000000000000000000000000000000900460ff166002811115612b0d57612b0d6157da565b14612b44576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110612b5957612b59615b50565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514612c40576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000612d00826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580612d3b5750612d387f00000000000000000000000000000000000000000000000000000000000000046002615bae565b81145b8015612d45575084155b15612d7c576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015612da2575086155b15612dd9576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000008811115612e33576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e5e7f00000000000000000000000000000000000000000000000000000000000000046001615bae565b8103612e7057612e70868885886150d7565b34612e7a83611de4565b14612eb1576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612ebc88611c05565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b0811690821603612f24576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612f5160017f0000000000000000000000000000000000000000000000000000000000000008615bfe565b830361308f577f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fe69190615c95565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015613030573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130549190615cb2565b613088907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16615ccb565b9050613122565b6130ba60017f0000000000000000000000000000000000000000000000000000000000000004615bfe565b83036130f5576130887f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166002615cf7565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b613156817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615d27565b67ffffffffffffffff166131718367ffffffffffffffff1690565b67ffffffffffffffff1611156131b8576131b5817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615d27565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615613236576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c815260200190815260200160002060016002805490506134cc9190615bfe565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309169263d0e30db09234926004808301939282900301818588803b15801561356457600080fd5b505af1158015613578573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b60005471010000000000000000000000000000000000900460ff161561360c576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000001166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e1690637258a807906024016040805180830381865afa1580156136c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136e49190615d50565b909250905081613720576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a1461375357639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135116137ed576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f000000000000000000000000d6eaf4c146261653ee059077b78ed088add543099092169363d0e30db093926004828101939282900301818588803b158015613ac257600080fd5b505af1158015613ad6573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b1760008213613b7257631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a764000002158202613dab57637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b600081600019048311820215613ddb5763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d78213613e1957919050565b680755bf798b4a1bf1e58212613e375763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000612652670de0b6b3a764000083613feb86613b13565b613ff59190615d74565b613fff9190615e30565b613deb565b60008054700100000000000000000000000000000000900460ff166002811115614030576140306157da565b14614067576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002878154811061407c5761407c615b50565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506140db7f00000000000000000000000000000000000000000000000000000000000000086001615bae565b614177826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16146141b1576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008089156142a8576142047f00000000000000000000000000000000000000000000000000000000000000047f0000000000000000000000000000000000000000000000000000000000000008615bfe565b6001901b614223846fffffffffffffffffffffffffffffffff16615288565b6fffffffffffffffffffffffffffffffff1661423f9190615e98565b1561427c5761427361426460016fffffffffffffffffffffffffffffffff8716615eac565b865463ffffffff166000615327565b6003015461429e565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506142d2565b600385015491506142cf6142646fffffffffffffffffffffffffffffffff86166001615ed5565b90505b600882901b60088a8a6040516142e9929190615b40565b6040518091039020901b1461432a576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006143358c61540b565b90506000614344836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff169063e14ced32906143be908f908f908f908f908a90600401615f49565b6020604051808303816000875af11580156143dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144019190615cb2565b6004850154911491506000906002906144ac906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b614548896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6145529190615f83565b61455c9190615fa6565b60ff16159050811515810361459d576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156145f4576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b600080600080600085905060006002828154811061465357614653615b50565b600091825260209091206004600590920201908101549091507f00000000000000000000000000000000000000000000000000000000000000049061472a906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611614764576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f00000000000000000000000000000000000000000000000000000000000000049061482b906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1692508211156148a057825463ffffffff1661486a7f00000000000000000000000000000000000000000000000000000000000000046001615bae565b8303614874578391505b6002818154811061488757614887615b50565b9060005260206000209060050201935080945050614768565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149096148f4856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff1614905080156149d8576000614941836fffffffffffffffffffffffffffffffff16615288565b6fffffffffffffffffffffffffffffffff1611156149ac57600061498361497b60016fffffffffffffffffffffffffffffffff8616615eac565b896001615327565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a506149b29050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614a2e565b60006149fa61497b6fffffffffffffffffffffffffffffffff85166001615ed5565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614aa95760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611900565b8282604051602001614ad79291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614b83847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614be7576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614c0c57600060016000945094509450505061503b565b60b78111614d22576000614c21608083615bfe565b905080876000015111614c60576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614cd857507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614d0f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061503b915050565b60bf8111614e80576000614d3760b783615bfe565b905080876000015111614d76576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614dd8576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614e20576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614e2a8184615bae565b895111614e63576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614e6e836001615bae565b975095506000945061503b9350505050565b60f78111614ee5576000614e9560c083615bfe565b905080876000015111614ed4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061503b915050565b6000614ef260f783615bfe565b905080876000015111614f31576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614f93576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614fdb576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614fe58184615bae565b89511161501e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615029836001615bae565b975095506001945061503b9350505050565b9193909250565b60608167ffffffffffffffff81111561505d5761505d615a84565b6040519080825280601f01601f191660200182016040528015615087576020820181803683370190505b50905081156150d057600061509c8486615bae565b90506020820160005b848110156150bd5782810151828201526020016150a5565b848111156150cc576000858301525b5050505b9392505050565b60006150f66fffffffffffffffffffffffffffffffff84166001615ed5565b9050600061510682866001615327565b9050600086901a83806151f2575061513f60027f0000000000000000000000000000000000000000000000000000000000000004615e98565b60048301546002906151e3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6151ed9190615fa6565b60ff16145b1561524a5760ff81166001148061520c575060ff81166002145b615245576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016137e4565b612a86565b60ff811615612a86576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016137e4565b600080615315837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826153705761536b6fffffffffffffffffffffffffffffffff86167f000000000000000000000000000000000000000000000000000000000000000461543a565b61538b565b61538b856fffffffffffffffffffffffffffffffff166155c6565b9050600284815481106153a0576153a0615b50565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff82811691161461540357815460028054909163ffffffff169081106153ee576153ee615b50565b906000526020600020906005020191506153b1565b509392505050565b600080600080600061541c86614633565b935093509350935061543084848484614a3c565b9695505050505050565b6000816154d9846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116154ef5763b34b5c226000526004601cfd5b6154f8836155c6565b905081615597826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611612655576126526155ad836001615bae565b6fffffffffffffffffffffffffffffffff83169061566b565b6000811960018301168161565a827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b6000806156f8847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f84011261572657600080fd5b50813567ffffffffffffffff81111561573e57600080fd5b60208301915083602082850101111561575657600080fd5b9250929050565b600080600083850360a081121561577357600080fd5b608081121561578157600080fd5b50839250608084013567ffffffffffffffff81111561579f57600080fd5b6157ab86828701615714565b9497909650939450505050565b600080604083850312156157cb57600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310615844577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060006060848603121561585f57600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561589c57602081850181015186830182015201615880565b818111156158ae576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006126526020830184615876565b60006020828403121561590657600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461592f57600080fd5b50565b60006020828403121561594457600080fd5b81356150d08161590d565b8035801515811461595f57600080fd5b919050565b6000806000806080858703121561597a57600080fd5b8435935060208501359250604085013591506159986060860161594f565b905092959194509250565b6000602082840312156159b557600080fd5b81356fffffffffffffffffffffffffffffffff811681146150d057600080fd5b600080600080600080608087890312156159ee57600080fd5b863595506159fe6020880161594f565b9450604087013567ffffffffffffffff80821115615a1b57600080fd5b615a278a838b01615714565b90965094506060890135915080821115615a4057600080fd5b50615a4d89828a01615714565b979a9699509497509295939492505050565b63ffffffff841681528260208201526060604082015260006119006060830184615876565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060808284031215615ac557600080fd5b6040516080810181811067ffffffffffffffff82111715615b0f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115615bc157615bc1615b7f565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615bf757615bf7615b7f565b5060010190565b600082821015615c1057615c10615b7f565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615c5357615c53615c15565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615c9057615c90615b7f565b500290565b600060208284031215615ca757600080fd5b81516150d08161590d565b600060208284031215615cc457600080fd5b5051919050565b600067ffffffffffffffff808316818516808303821115615cee57615cee615b7f565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615d1e57615d1e615b7f565b02949350505050565b600067ffffffffffffffff83811690831681811015615d4857615d48615b7f565b039392505050565b60008060408385031215615d6357600080fd5b505080516020909101519092909150565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615db557615db5615b7f565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615df057615df0615b7f565b60008712925087820587128484161615615e0c57615e0c615b7f565b87850587128184161615615e2257615e22615b7f565b505050929093029392505050565b600082615e3f57615e3f615c15565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615e9357615e93615b7f565b500590565b600082615ea757615ea7615c15565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615d4857615d48615b7f565b60006fffffffffffffffffffffffffffffffff808316818516808303821115615cee57615cee615b7f565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615f5d606083018789615f00565b8281036020840152615f70818688615f00565b9150508260408301529695505050505050565b600060ff821660ff841680821015615f9d57615f9d615b7f565b90039392505050565b600060ff831680615fb957615fb9615c15565b8060ff8416069150509291505056fea164736f6c634300080f000a"; + hex"6080604052600436106103085760003560e01c806370872aa51161019a578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b94578063fa315aa914610bb8578063fe2bbeb214610beb57600080fd5b8063ec5e630814610b11578063eff0f59214610b44578063f8f43ff614610b7457600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a8b578063d8cc1a3c14610abe578063dabd396d14610ade57600080fd5b8063c6f0308c146109b3578063cf09e0d014610a3d578063d5d44d8014610a5e57600080fd5b8063a445ece611610143578063bcef3b551161011d578063bcef3b5514610933578063bd8da95614610973578063c395e1ca1461099357600080fd5b8063a445ece6146107f3578063a8e4fb90146108bf578063bbdc02db146108f257600080fd5b80638980e0cc116101745780638980e0cc1461076b5780638b85902b146107805780638d450a95146107c057600080fd5b806370872aa51461073b5780637b0f0adc146107505780638129fc1c1461076357600080fd5b80633fc8cef31161025e5780635c0cba33116102075780636361506d116101e15780636361506d146106b55780636b6716c0146106f55780636f0344091461072857600080fd5b80635c0cba331461064d578063609d33341461068057806360e274641461069557600080fd5b806354fd4d501161023857806354fd4d50146105a757806357da950e146105fd5780635a5fa2d91461062d57600080fd5b80633fc8cef31461052e578063472777c614610561578063534db0e21461057457600080fd5b80632810e1d6116102c057806337b1b2291161029a57806337b1b2291461047b5780633a768463146104bb5780633e3ac912146104ee57600080fd5b80632810e1d6146103f45780632ad69aeb1461040957806330dbe5701461042957600080fd5b806319effeb4116102f157806319effeb41461034f578063200d2ed21461039a57806325fc2ace146103d557600080fd5b8063019351301461030d57806303c2924d1461032f575b600080fd5b34801561031957600080fd5b5061032d61032836600461575d565b610c1b565b005b34801561033b57600080fd5b5061032d61034a3660046157b8565b610f3c565b34801561035b57600080fd5b5060005461037c9068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156103a657600080fd5b506000546103c890700100000000000000000000000000000000900460ff1681565b6040516103919190615809565b3480156103e157600080fd5b506008545b604051908152602001610391565b34801561040057600080fd5b506103c86115e2565b34801561041557600080fd5b506103e66104243660046157b8565b611887565b34801561043557600080fd5b506001546104569073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610391565b34801561048757600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610456565b3480156104c757600080fd5b507f000000000000000000000000180cbe2ebb9f37d3a3c542ddc2546fd160555a73610456565b3480156104fa57600080fd5b5060005461051e907201000000000000000000000000000000000000900460ff1681565b6040519015158152602001610391565b34801561053a57600080fd5b507f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309610456565b61032d61056f36600461584a565b6118bd565b34801561058057600080fd5b507f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63610456565b3480156105b357600080fd5b506105f06040518060400160405280600c81526020017f312e332e312d626574612e32000000000000000000000000000000000000000081525081565b60405161039191906158e1565b34801561060957600080fd5b50600854600954610618919082565b60408051928352602083019190915201610391565b34801561063957600080fd5b506103e66106483660046158f4565b6118cf565b34801561065957600080fd5b507f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e610456565b34801561068c57600080fd5b506105f0611909565b3480156106a157600080fd5b5061032d6106b0366004615932565b611917565b3480156106c157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103e6565b34801561070157600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061037c565b61032d610736366004615964565b611abe565b34801561074757600080fd5b506009546103e6565b61032d61075e36600461584a565b611b7f565b61032d611b8c565b34801561077757600080fd5b506002546103e6565b34801561078c57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103e6565b3480156107cc57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103e6565b3480156107ff57600080fd5b5061086b61080e3660046158f4565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff166060820152608001610391565b3480156108cb57600080fd5b507f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8610456565b3480156108fe57600080fd5b5060405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000001168152602001610391565b34801561093f57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103e6565b34801561097f57600080fd5b5061037c61098e3660046158f4565b611c05565b34801561099f57600080fd5b506103e66109ae3660046159a3565b611de4565b3480156109bf57600080fd5b506109d36109ce3660046158f4565b611fc7565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e001610391565b348015610a4957600080fd5b5060005461037c9067ffffffffffffffff1681565b348015610a6a57600080fd5b506103e6610a79366004615932565b60036020526000908152604090205481565b348015610a9757600080fd5b507f00000000000000000000000000000000000000000000000000000000000003856103e6565b348015610aca57600080fd5b5061032d610ad93660046159d5565b61205e565b348015610aea57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b061037c565b348015610b1d57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000046103e6565b348015610b5057600080fd5b5061051e610b5f3660046158f4565b60046020526000908152604090205460ff1681565b348015610b8057600080fd5b5061032d610b8f36600461584a565b612123565b348015610ba057600080fd5b50610ba96125e0565b60405161039193929190615a5f565b348015610bc457600080fd5b507f00000000000000000000000000000000000000000000000000000000000000086103e6565b348015610bf757600080fd5b5061051e610c063660046158f4565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610c4757610c476157da565b14610c7e576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610cd1576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d08367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610d1f610d1a36869003860186615ab3565b61265b565b14610d56576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610d6b929190615b40565b604051809103902014610daa576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610df3610dee84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506126b792505050565b612724565b90506000610e1a82600881518110610e0d57610e0d615b50565b60200260200101516128da565b9050602081511115610e58576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610ecd576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610f6857610f686157da565b14610f9f576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610fb457610fb4615b50565b906000526020600020906005020190506000610fcf84611c05565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b081169082161015611038576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611081576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561109e57508515155b15611139578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110d157816110ed565b600186015473ffffffffffffffffffffffffffffffffffffffff165b90506110f9818761298e565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff1660608301526111dc576fffffffffffffffffffffffffffffffff60408201526001815260008690036111dc578195505b600086826020015163ffffffff166111f49190615bae565b905060008382116112055781611207565b835b602084015190915063ffffffff165b8181101561135357600086828154811061123257611232615b50565b6000918252602080832090910154808352600690915260409091205490915060ff1661128a576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002828154811061129f5761129f615b50565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112fc5750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b1561133e57600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b5050808061134b90615bc6565b915050611216565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909316929092179091558490036115d757606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055891580156114d357506000547201000000000000000000000000000000000000900460ff165b156115485760015473ffffffffffffffffffffffffffffffffffffffff166114fb818a61298e565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff9091161788556115d5565b61158f73ffffffffffffffffffffffffffffffffffffffff82161561156d5781611589565b600189015473ffffffffffffffffffffffffffffffffffffffff165b8961298e565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff166002811115611610576116106157da565b14611647576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff166116ab576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660026000815481106116d7576116d7615b50565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611712576001611715565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff909116177001000000000000000000000000000000008360028111156117c6576117c66157da565b0217905560028111156117db576117db6157da565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e73ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561186c57600080fd5b505af1158015611880573d6000803e3d6000fd5b5050505090565b600560205281600052604060002081815481106118a357600080fd5b90600052602060002001600091509150505481565b905090565b6118ca8383836001611abe565b505050565b6000818152600760209081526040808320600590925282208054825461190090610100900463ffffffff1682615bfe565b95945050505050565b60606118b860546020612a8f565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604081208054908290559081900361197c576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309169063f3fef3a390604401600060405180830381600087803b158015611a0c57600080fd5b505af1158015611a20573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a7e576040519150601f19603f3d011682016040523d82523d6000602084013e611a83565b606091505b50509050806118ca576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8161480611b3757503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b6316145b611b6d576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b7984848484612ae1565b50505050565b6118ca8383836000611abe565b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c81614611bfb576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c036135ba565b565b600080600054700100000000000000000000000000000000900460ff166002811115611c3357611c336157da565b14611c6a576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110611c7f57611c7f615b50565b600091825260208220600590910201805490925063ffffffff90811614611cee57815460028054909163ffffffff16908110611cbd57611cbd615b50565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090611d2690700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b611d3a9067ffffffffffffffff1642615bfe565b611d59611d19846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16611d6d9190615bae565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b01667ffffffffffffffff168167ffffffffffffffff1611611dba5780611900565b7f00000000000000000000000000000000000000000000000000000000000004b095945050505050565b600080611e83836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000008811115611ee2576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000611efd8383615c44565b9050670de0b6b3a76400006000611f34827f0000000000000000000000000000000000000000000000000000000000000008615c58565b90506000611f52611f4d670de0b6b3a764000086615c58565b613b13565b90506000611f608484613d6e565b90506000611f6e8383613dbd565b90506000611f7b82613deb565b90506000611f9a82611f95670de0b6b3a76400008f615c58565b613fd3565b90506000611fa88b83613dbd565b9050611fb4818d615c58565b9f9e505050505050505050505050505050565b60028181548110611fd757600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c81614806120d757503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b6316145b61210d576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61211b868686868686614004565b505050505050565b60008054700100000000000000000000000000000000900460ff16600281111561214f5761214f6157da565b14612186576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061219586614633565b935093509350935060006121ab85858585614a3c565b905060007f000000000000000000000000180cbe2ebb9f37d3a3c542ddc2546fd160555a7373ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561221a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223e9190615c95565b9050600189036123365773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8461229a367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af115801561230c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123309190615cb2565b506115d7565b600289036123625773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848961229a565b6003890361238e5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848761229a565b600489036125155760006123d46fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000004614af6565b6009546123e19190615bae565b6123ec906001615bae565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061245557367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135612457565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156124ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250e9190615cb2565b50506115d7565b600589036125ae576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000038560c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016122ed565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000001367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060612639611909565b9050909192565b6000818310156126505781612652565b825b90505b92915050565b6000816000015182602001518360400151846060015160405160200161269a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003612706576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b6060600080600061273485614ba4565b91945092509050600181600181111561274f5761274f6157da565b14612786576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516127928385615bae565b146127c9576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816127e05790505093506000835b86518110156128ce576000806128536040518060400160405280858c600001516128379190615bfe565b8152602001858c6020015161284c9190615bae565b9052614ba4565b50915091506040518060400160405280838361286f9190615bae565b8152602001848b602001516128849190615bae565b81525088858151811061289957612899615b50565b60209081029190910101526128af600185615bae565b93506128bb8183615bae565b6128c59084615bae565b9250505061280d565b50845250919392505050565b606060008060006128ea85614ba4565b919450925090506000816001811115612905576129056157da565b1461293c576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129468284615bae565b85511461297f576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61190085602001518484615042565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff909316928392906129dd908490615bae565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f000000000000000000000000d6eaf4c146261653ee059077b78ed088add543091690637eee288d90604401600060405180830381600087803b158015612a7257600080fd5b505af1158015612a86573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b60008054700100000000000000000000000000000000900460ff166002811115612b0d57612b0d6157da565b14612b44576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110612b5957612b59615b50565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514612c40576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000612d00826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580612d3b5750612d387f00000000000000000000000000000000000000000000000000000000000000046002615bae565b81145b8015612d45575084155b15612d7c576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015612da2575086155b15612dd9576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000008811115612e33576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e5e7f00000000000000000000000000000000000000000000000000000000000000046001615bae565b8103612e7057612e70868885886150d7565b34612e7a83611de4565b14612eb1576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612ebc88611c05565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b0811690821603612f24576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612f5160017f0000000000000000000000000000000000000000000000000000000000000008615bfe565b830361308f577f000000000000000000000000180cbe2ebb9f37d3a3c542ddc2546fd160555a7373ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fe69190615c95565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015613030573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130549190615cb2565b613088907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16615ccb565b9050613122565b6130ba60017f0000000000000000000000000000000000000000000000000000000000000004615bfe565b83036130f5576130887f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166002615cf7565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b613156817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615d27565b67ffffffffffffffff166131718367ffffffffffffffff1690565b67ffffffffffffffff1611156131b8576131b5817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615d27565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615613236576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c815260200190815260200160002060016002805490506134cc9190615bfe565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309169263d0e30db09234926004808301939282900301818588803b15801561356457600080fd5b505af1158015613578573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b60005471010000000000000000000000000000000000900460ff161561360c576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000001166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e1690637258a807906024016040805180830381865afa1580156136c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136e49190615d50565b909250905081613720576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a1461375357639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135116137ed576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f000000000000000000000000d6eaf4c146261653ee059077b78ed088add543099092169363d0e30db093926004828101939282900301818588803b158015613ac257600080fd5b505af1158015613ad6573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b1760008213613b7257631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a764000002158202613dab57637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b600081600019048311820215613ddb5763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d78213613e1957919050565b680755bf798b4a1bf1e58212613e375763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000612652670de0b6b3a764000083613feb86613b13565b613ff59190615d74565b613fff9190615e30565b613deb565b60008054700100000000000000000000000000000000900460ff166002811115614030576140306157da565b14614067576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002878154811061407c5761407c615b50565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506140db7f00000000000000000000000000000000000000000000000000000000000000086001615bae565b614177826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16146141b1576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008089156142a8576142047f00000000000000000000000000000000000000000000000000000000000000047f0000000000000000000000000000000000000000000000000000000000000008615bfe565b6001901b614223846fffffffffffffffffffffffffffffffff16615288565b6fffffffffffffffffffffffffffffffff1661423f9190615e98565b1561427c5761427361426460016fffffffffffffffffffffffffffffffff8716615eac565b865463ffffffff166000615327565b6003015461429e565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506142d2565b600385015491506142cf6142646fffffffffffffffffffffffffffffffff86166001615ed5565b90505b600882901b60088a8a6040516142e9929190615b40565b6040518091039020901b1461432a576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006143358c61540b565b90506000614344836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000180cbe2ebb9f37d3a3c542ddc2546fd160555a7373ffffffffffffffffffffffffffffffffffffffff169063e14ced32906143be908f908f908f908f908a90600401615f49565b6020604051808303816000875af11580156143dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144019190615cb2565b6004850154911491506000906002906144ac906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b614548896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6145529190615f83565b61455c9190615fa6565b60ff16159050811515810361459d576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156145f4576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b600080600080600085905060006002828154811061465357614653615b50565b600091825260209091206004600590920201908101549091507f00000000000000000000000000000000000000000000000000000000000000049061472a906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611614764576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f00000000000000000000000000000000000000000000000000000000000000049061482b906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1692508211156148a057825463ffffffff1661486a7f00000000000000000000000000000000000000000000000000000000000000046001615bae565b8303614874578391505b6002818154811061488757614887615b50565b9060005260206000209060050201935080945050614768565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149096148f4856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff1614905080156149d8576000614941836fffffffffffffffffffffffffffffffff16615288565b6fffffffffffffffffffffffffffffffff1611156149ac57600061498361497b60016fffffffffffffffffffffffffffffffff8616615eac565b896001615327565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a506149b29050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614a2e565b60006149fa61497b6fffffffffffffffffffffffffffffffff85166001615ed5565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614aa95760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611900565b8282604051602001614ad79291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614b83847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614be7576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614c0c57600060016000945094509450505061503b565b60b78111614d22576000614c21608083615bfe565b905080876000015111614c60576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614cd857507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614d0f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061503b915050565b60bf8111614e80576000614d3760b783615bfe565b905080876000015111614d76576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614dd8576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614e20576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614e2a8184615bae565b895111614e63576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614e6e836001615bae565b975095506000945061503b9350505050565b60f78111614ee5576000614e9560c083615bfe565b905080876000015111614ed4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061503b915050565b6000614ef260f783615bfe565b905080876000015111614f31576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614f93576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614fdb576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614fe58184615bae565b89511161501e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615029836001615bae565b975095506001945061503b9350505050565b9193909250565b60608167ffffffffffffffff81111561505d5761505d615a84565b6040519080825280601f01601f191660200182016040528015615087576020820181803683370190505b50905081156150d057600061509c8486615bae565b90506020820160005b848110156150bd5782810151828201526020016150a5565b848111156150cc576000858301525b5050505b9392505050565b60006150f66fffffffffffffffffffffffffffffffff84166001615ed5565b9050600061510682866001615327565b9050600086901a83806151f2575061513f60027f0000000000000000000000000000000000000000000000000000000000000004615e98565b60048301546002906151e3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6151ed9190615fa6565b60ff16145b1561524a5760ff81166001148061520c575060ff81166002145b615245576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016137e4565b612a86565b60ff811615612a86576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016137e4565b600080615315837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826153705761536b6fffffffffffffffffffffffffffffffff86167f000000000000000000000000000000000000000000000000000000000000000461543a565b61538b565b61538b856fffffffffffffffffffffffffffffffff166155c6565b9050600284815481106153a0576153a0615b50565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff82811691161461540357815460028054909163ffffffff169081106153ee576153ee615b50565b906000526020600020906005020191506153b1565b509392505050565b600080600080600061541c86614633565b935093509350935061543084848484614a3c565b9695505050505050565b6000816154d9846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116154ef5763b34b5c226000526004601cfd5b6154f8836155c6565b905081615597826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611612655576126526155ad836001615bae565b6fffffffffffffffffffffffffffffffff83169061566b565b6000811960018301168161565a827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b6000806156f8847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f84011261572657600080fd5b50813567ffffffffffffffff81111561573e57600080fd5b60208301915083602082850101111561575657600080fd5b9250929050565b600080600083850360a081121561577357600080fd5b608081121561578157600080fd5b50839250608084013567ffffffffffffffff81111561579f57600080fd5b6157ab86828701615714565b9497909650939450505050565b600080604083850312156157cb57600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310615844577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060006060848603121561585f57600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561589c57602081850181015186830182015201615880565b818111156158ae576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006126526020830184615876565b60006020828403121561590657600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461592f57600080fd5b50565b60006020828403121561594457600080fd5b81356150d08161590d565b8035801515811461595f57600080fd5b919050565b6000806000806080858703121561597a57600080fd5b8435935060208501359250604085013591506159986060860161594f565b905092959194509250565b6000602082840312156159b557600080fd5b81356fffffffffffffffffffffffffffffffff811681146150d057600080fd5b600080600080600080608087890312156159ee57600080fd5b863595506159fe6020880161594f565b9450604087013567ffffffffffffffff80821115615a1b57600080fd5b615a278a838b01615714565b90965094506060890135915080821115615a4057600080fd5b50615a4d89828a01615714565b979a9699509497509295939492505050565b63ffffffff841681528260208201526060604082015260006119006060830184615876565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060808284031215615ac557600080fd5b6040516080810181811067ffffffffffffffff82111715615b0f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115615bc157615bc1615b7f565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615bf757615bf7615b7f565b5060010190565b600082821015615c1057615c10615b7f565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615c5357615c53615c15565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615c9057615c90615b7f565b500290565b600060208284031215615ca757600080fd5b81516150d08161590d565b600060208284031215615cc457600080fd5b5051919050565b600067ffffffffffffffff808316818516808303821115615cee57615cee615b7f565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615d1e57615d1e615b7f565b02949350505050565b600067ffffffffffffffff83811690831681811015615d4857615d48615b7f565b039392505050565b60008060408385031215615d6357600080fd5b505080516020909101519092909150565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615db557615db5615b7f565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615df057615df0615b7f565b60008712925087820587128484161615615e0c57615e0c615b7f565b87850587128184161615615e2257615e22615b7f565b505050929093029392505050565b600082615e3f57615e3f615c15565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615e9357615e93615b7f565b500590565b600082615ea757615ea7615c15565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615d4857615d48615b7f565b60006fffffffffffffffffffffffffffffffff808316818516808303821115615cee57615cee615b7f565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615f5d606083018789615f00565b8281036020840152615f70818688615f00565b9150508260408301529695505050505050565b600060ff821660ff841680821015615f9d57615f9d615b7f565b90039392505050565b600060ff831680615fb957615fb9615c15565b8060ff8416069150509291505056fea164736f6c634300080f000a"; } diff --git a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofs.sol b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofs.sol index 9750b8deb973..3b54141df2d7 100644 --- a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofs.sol +++ b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofs.sol @@ -27,11 +27,11 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { address internal constant l1StandardBridgeProxyAddress = 0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D; address internal constant l2OutputOracleAddress = 0x60d37db59d0D14f7EA5c7425A2C03244E08B162D; address internal constant l2OutputOracleProxyAddress = 0x39Af23E00F1e662025aA01b0cEdA19542B78DF99; - address internal constant mipsAddress = 0x46cce16e68c41f7EBdf485EF825AB3b46143F738; + address internal constant mipsAddress = 0x180CBe2EBb9F37D3a3C542DDc2546Fd160555a73; address internal constant optimismMintableERC20FactoryAddress = 0x79c3114E5f89266e2C8842871Bce16D4e5076b1e; address internal constant optimismMintableERC20FactoryProxyAddress = 0xc7B87b2b892EA5C3CfF47168881FE168C00377FB; - address internal constant optimismPortalAddress = 0xBE8eE5CEA97De55Ae8b020E778A5C93C2Af81Ed4; - address internal constant optimismPortal2Address = 0x5506077419b90A12C048500e2eBcafb4fC6Bab61; + address internal constant optimismPortalAddress = 0xb5A42f01EF5068F82C11fa1c4F9bBD4c8D346961; + address internal constant optimismPortal2Address = 0x150581358018524994Fc29800b1783637943b103; address internal constant optimismPortalProxyAddress = 0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4; address internal constant permissionedDelayedWETHProxyAddress = 0xd6EAF4c146261653EE059077B78ED088Add54309; address internal constant preimageOracleAddress = 0x7A9Eab4CE99d157AeE7A02E95b366E972a2D5b0b; @@ -430,7 +430,7 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { value = hex"0000000000000000000000000000000000000000000000000000000000000003"; vm.store(systemOwnerSafeAddress, slot, value); slot = hex"360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - value = hex"0000000000000000000000005506077419b90a12c048500e2ebcafb4fc6bab61"; + value = hex"000000000000000000000000150581358018524994fc29800b1783637943b103"; vm.store(optimismPortalProxyAddress, slot, value); slot = hex"0000000000000000000000000000000000000000000000000000000000000000"; value = hex"0000000000000000000000000000000000000000000000000000000000000001"; diff --git a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofsCode.sol b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofsCode.sol index e68d91067864..a2809e334863 100644 --- a/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofsCode.sol +++ b/packages/contracts-bedrock/test/kontrol/proofs/utils/DeploymentSummaryFaultProofsCode.sol @@ -55,11 +55,11 @@ contract DeploymentSummaryFaultProofsCode { bytes internal constant l1ERC721BridgeCode = hex"608060405234801561001057600080fd5b50600436106100d45760003560e01c80635d93a3fc11610081578063927ede2d1161005b578063927ede2d14610231578063aa5574521461024f578063c89701a21461026257600080fd5b80635d93a3fc146101cc578063761f4493146102005780637f46ddb21461021357600080fd5b8063485cc955116100b2578063485cc9551461015857806354fd4d501461016b5780635c975abb146101b457600080fd5b806335e80ab3146100d95780633687011a146101235780633cb747bf14610138575b600080fd5b6032546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610136610131366004610fe1565b610282565b005b6001546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b610136610166366004611064565b61032e565b6101a76040518060400160405280600c81526020017f322e312e312d626574612e32000000000000000000000000000000000000000081525081565b60405161011a9190611108565b6101bc610518565b604051901515815260200161011a565b6101bc6101da366004611122565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b61013661020e366004611163565b6105b1565b60025473ffffffffffffffffffffffffffffffffffffffff166100f9565b60015473ffffffffffffffffffffffffffffffffffffffff166100f9565b61013661025d3660046111fb565b610a58565b6002546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b333b15610316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b6103268686333388888888610b30565b505050505050565b600054610100900460ff161580801561034e5750600054600160ff909116105b806103685750303b158015610368575060005460ff166001145b6103f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161030d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561045257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556104b083734200000000000000000000000000000000000014610e70565b801561051357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa158015610588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ac9190611272565b905090565b60015473ffffffffffffffffffffffffffffffffffffffff16331480156106865750600254600154604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691636e296e45916004808201926020929091908290030181865afa15801561064a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066e9190611294565b73ffffffffffffffffffffffffffffffffffffffff16145b610712576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f746865722062726964676500606482015260840161030d565b61071a610518565b15610781576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4c314552433732314272696467653a2070617573656400000000000000000000604482015260640161030d565b3073ffffffffffffffffffffffffffffffffffffffff881603610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c6600000000000000000000000000000000000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff1615156001146108f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c312042726964676500000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156109b557600080fd5b505af11580156109c9573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac87878787604051610a4794939291906112fa565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610afb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f74206265206164647265737328302900000000000000000000000000000000606482015260840161030d565b610b0b8787338888888888610b30565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b73ffffffffffffffffffffffffffffffffffffffff8716610bd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f742062652061646472657373283029000000000000000000000000000000606482015260840161030d565b600063761f449360e01b888a8989898888604051602401610bfa979695949392919061133a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610d3a57600080fd5b505af1158015610d4e573d6000803e3d6000fd5b50506001546002546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450633dbb202b9350610db1929091169085908990600401611397565b600060405180830381600087803b158015610dcb57600080fd5b505af1158015610ddf573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610e5d94939291906112fa565b60405180910390a4505050505050505050565b600054610100900460ff16610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161030d565b6001805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560028054929093169116179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610f7c57600080fd5b50565b803563ffffffff81168114610f9357600080fd5b919050565b60008083601f840112610faa57600080fd5b50813567ffffffffffffffff811115610fc257600080fd5b602083019150836020828501011115610fda57600080fd5b9250929050565b60008060008060008060a08789031215610ffa57600080fd5b863561100581610f5a565b9550602087013561101581610f5a565b94506040870135935061102a60608801610f7f565b9250608087013567ffffffffffffffff81111561104657600080fd5b61105289828a01610f98565b979a9699509497509295939492505050565b6000806040838503121561107757600080fd5b823561108281610f5a565b9150602083013561109281610f5a565b809150509250929050565b6000815180845260005b818110156110c3576020818501810151868301820152016110a7565b818111156110d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061111b602083018461109d565b9392505050565b60008060006060848603121561113757600080fd5b833561114281610f5a565b9250602084013561115281610f5a565b929592945050506040919091013590565b600080600080600080600060c0888a03121561117e57600080fd5b873561118981610f5a565b9650602088013561119981610f5a565b955060408801356111a981610f5a565b945060608801356111b981610f5a565b93506080880135925060a088013567ffffffffffffffff8111156111dc57600080fd5b6111e88a828b01610f98565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561121657600080fd5b873561122181610f5a565b9650602088013561123181610f5a565b9550604088013561124181610f5a565b94506060880135935061125660808901610f7f565b925060a088013567ffffffffffffffff8111156111dc57600080fd5b60006020828403121561128457600080fd5b8151801515811461111b57600080fd5b6000602082840312156112a657600080fd5b815161111b81610f5a565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006113306060830184866112b1565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261138a60c0830184866112b1565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006113c6606083018561109d565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a"; bytes internal constant optimismPortalCode = - hex"6080604052600436106101635760003560e01c80638c3152e9116100c0578063b69ef8a811610074578063cff0ab9611610059578063cff0ab9614610444578063e965084c146104e5578063e9e05c421461057157600080fd5b8063b69ef8a814610401578063c0c53b8b1461042457600080fd5b80639bf62d82116100a55780639bf62d821461036b578063a14238e714610398578063a35d99df146103c857600080fd5b80638c3152e91461031e5780639b5f694a1461033e57600080fd5b806354fd4d50116101175780636dbffb78116100fc5780636dbffb78146102de57806371cfaa3f146102fe5780638b4c40b01461018857600080fd5b806354fd4d501461026d5780635c975abb146102b957600080fd5b806335e80ab31161014857806335e80ab314610206578063452a9320146102385780634870496f1461024d57600080fd5b8063149f2f221461018f57806333d7e2bd146101af57600080fd5b3661018a576101883334620186a060006040518060200160405280600081525061057f565b005b600080fd5b34801561019b57600080fd5b506101886101aa366004614b97565b610624565b3480156101bb57600080fd5b506037546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561021257600080fd5b506035546101dc90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561024457600080fd5b506101dc610865565b34801561025957600080fd5b50610188610268366004614ccb565b6108fd565b34801561027957600080fd5b50604080518082018252600c81527f322e382e312d626574612e320000000000000000000000000000000000000000602082015290516101fd9190614e1d565b3480156102c557600080fd5b506102ce610eaa565b60405190151581526020016101fd565b3480156102ea57600080fd5b506102ce6102f9366004614e30565b610f3d565b34801561030a57600080fd5b50610188610319366004614e58565b610ff8565b34801561032a57600080fd5b50610188610339366004614e9e565b6111ba565b34801561034a57600080fd5b506036546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561037757600080fd5b506032546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103a457600080fd5b506102ce6103b3366004614e30565b60336020526000908152604090205460ff1681565b3480156103d457600080fd5b506103e86103e3366004614edb565b611c3c565b60405167ffffffffffffffff90911681526020016101fd565b34801561040d57600080fd5b50610416611c55565b6040519081526020016101fd565b34801561043057600080fd5b5061018861043f366004614ef6565b611caf565b34801561045057600080fd5b506001546104ac906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101fd565b3480156104f157600080fd5b50610543610500366004614e30565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101fd565b61018861057f366004614f41565b8260005a9050600061058f611f19565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906105cb57503415155b15610602576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610610883489898989611fb6565b5061061b8282612162565b50505050505050565b8260005a90506000610634611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016106a6576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546106b89190614fed565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561072a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074e9190615005565b905061077273ffffffffffffffffffffffffffffffffffffffff831633308c61242f565b61077c8982614fed565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa1580156107e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080a9190615005565b14610841576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61084f8a8a8a8a8a8a611fb6565b505061085b8282612162565b5050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f8919061501e565b905090565b610905610eaa565b1561093c576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16036109a5576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6036546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810186905260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610a15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a39919061505b565b519050610a53610a4e368690038601866150c0565b61250b565b8114610ae6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f66000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000610af187612567565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610c075750805160365460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610bdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c03919061505b565b5114155b610c93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610add565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610d5c9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610d52888a615126565b8a60400135612597565b610de8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610add565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f19573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906151aa565b6036546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101839052600091610ff29173ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd7919061505b565b602001516fffffffffffffffffffffffffffffffff166125bb565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff163314611049576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61105562030d40612661565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f000000000000000000000000000000000000000000000000000000001790529051611172969594939291016151c7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526111aa91614e1d565b60405180910390a450505050565b565b6111c2610eaa565b156111f9576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461124c576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061125782612567565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610add565b603660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d39190615005565b81602001516fffffffffffffffffffffffffffffffff16101561149e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610add565b6114bd81602001516fffffffffffffffffffffffffffffffff166125bb565b61156f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610add565b60365460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a919061505b565b82518151919250146116d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610add565b6116f381602001516fffffffffffffffffffffffffffffffff166125bb565b6117a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610add565b60008381526033602052604090205460ff1615611844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610add565b6000838152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558501516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055806118cf611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016119325761192b8660400151876080015188606001518960a001516126c3565b9150611b85565b8073ffffffffffffffffffffffffffffffffffffffff16866040015173ffffffffffffffffffffffffffffffffffffffff160361199b576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606086015115611b5c578560600151603d60008282546119bb919061522c565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015611a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a519190615005565b9050611a86876040015188606001518473ffffffffffffffffffffffffffffffffffffffff166127219092919063ffffffff16565b6060870151611a95908261522c565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015611aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b239190615005565b14611b5a576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08601515115611b805761192b8660400151876080015160008960a001516126c3565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405185907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90611be790851515815260200190565b60405180910390a281158015611bfd5750326001145b15611c34576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b6000611c49826010615243565b610ff290615208615273565b600080611c60611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601611ca7574791505090565b5050603d5490565b600054610100900460ff1615808015611ccf5750600054600160ff909116105b80611ce95750303b158015611ce9575060005460ff166001145b611d75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610add565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611dd357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603680547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8781169190911790925560378054909116858316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101008584160217905560325416611e8c57603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b611e9461277c565b8015611ef757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015611f89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fad919061529f565b90939092509050565b818015611fd8575073ffffffffffffffffffffffffffffffffffffffff861615155b1561200f576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120198151611c3c565b67ffffffffffffffff168367ffffffffffffffff161015612066576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c0815111156120a4576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333281146120c5575033731111000000000000000000000000000000001111015b600086868686866040516020016120e09594939291906151c7565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516121509190614e1d565b60405180910390a45050505050505050565b600154600090612198907801000000000000000000000000000000000000000000000000900467ffffffffffffffff164361522c565b905060006121a461288f565b90506000816020015160ff16826000015163ffffffff166121c59190615308565b905082156122fc576001546000906121fc908390700100000000000000000000000000000000900467ffffffffffffffff16615370565b90506000836040015160ff168361221391906153e4565b6001546122339084906fffffffffffffffffffffffffffffffff166153e4565b61223d9190615308565b60015490915060009061228e906122679084906fffffffffffffffffffffffffffffffff166154a0565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612950565b905060018611156122bd576122ba61226782876040015160ff1660018a6122b5919061522c565b61296f565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b6001805486919060109061232f908490700100000000000000000000000000000000900467ffffffffffffffff16615273565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1613156123bc576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906123e8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615514565b905060006123fa48633b9aca006129c4565b6124049083615551565b905060005a612413908861522c565b90508082111561085b5761085b61242a828461522c565b6129db565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052611ef79085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612a04565b6000816000015182602001518360400151846060015160405160200161254a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a0880151935160009761254a979096959101615565565b6000806125a386612b10565b90506125b181868686612b42565b9695505050505050565b603654604080517ff4daa291000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163f4daa2919160048083019260209291908290030181865afa15801561262b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264f9190615005565b6126599083614fed565b421192915050565b6001805463ffffffff8316919060109061269a908490700100000000000000000000000000000000900467ffffffffffffffff16615273565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b60008060006126d3866000612b72565b905080612709576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526127779084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612489565b505050565b600054610100900460ff16612813576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610add565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff166000036111b85760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa15801561292c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f891906155d0565b600061296561295f8585612b90565b83612ba0565b90505b9392505050565b6000670de0b6b3a76400006129b06129878583615308565b61299990670de0b6b3a7640000615370565b6129ab85670de0b6b3a76400006153e4565b612baf565b6129ba90866153e4565b6129659190615308565b6000818310156129d45781612968565b5090919050565b6000805a90505b825a6129ee908361522c565b1015612777576129fd82615673565b91506129e2565b6000612a66826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612be09092919063ffffffff16565b8051909150156127775780806020019051810190612a8491906151aa565b612777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610add565b60608180519060200120604051602001612b2c91815260200190565b6040516020818303038152906040529050919050565b6000612b6984612b53878686612bef565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000818312156129d45781612968565b60008183126129d45781612968565b6000612968670de0b6b3a764000083612bc78661366d565b612bd191906153e4565b612bdb9190615308565b6138b1565b60606129658484600085613af0565b60606000845111612c5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610add565b6000612c6784613c86565b90506000612c7486613d72565b9050600084604051602001612c8b91815260200190565b60405160208183030381529060405290506000805b84518110156135e4576000858281518110612cbd57612cbd6156ab565b602002602001015190508451831115612d58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610add565b82600003612e115780518051602091820120604051612da692612d8092910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610add565b612f68565b805151602011612ec75780518051602091820120604051612e3b92612d8092910190815260200190565b612e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610add565b805184516020808701919091208251919092012014612f68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610add565b612f7460106001614fed565b8160200151510361315057845183036130e857612fae8160200151601081518110612fa157612fa16156ab565b6020026020010151613dd5565b96506000875111613041576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610add565b6001865161304f919061522c565b82146130dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610add565b505050505050612968565b60008584815181106130fc576130fc6156ab565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110613127576131276156ab565b6020026020010151905061313a81613e89565b9550613147600186614fed565b945050506135d1565b60028160200151510361354957600061316882613eae565b905060008160008151811061317f5761317f6156ab565b016020015160f81c905060006131966002836156da565b6131a19060026156fc565b905060006131b2848360ff16613ed2565b905060006131c08a89613ed2565b905060006131ce8383613f08565b905080835114613260576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610add565b60ff851660021480613275575060ff85166003145b15613464578082511461330a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610add565b6133248760200151600181518110612fa157612fa16156ab565b9c5060008d51116133b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610add565b60018c516133c5919061522c565b8814613453576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610add565b505050505050505050505050612968565b60ff85161580613477575060ff85166001145b156134b6576134a38760200151600181518110613496576134966156ab565b6020026020010151613e89565b99506134af818a614fed565b985061353e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610add565b5050505050506135d1565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610add565b50806135dc81615673565b915050612ca0565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610add565b60008082136136d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b600060606136e584613fbc565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136138e257506000919050565b680755bf798b4a1bf1e58212613954576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610add565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613b82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610add565b73ffffffffffffffffffffffffffffffffffffffff85163b613c00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610add565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613c29919061571f565b60006040518083038185875af1925050503d8060008114613c66576040519150601f19603f3d011682016040523d82523d6000602084013e613c6b565b606091505b5091509150613c7b828286614092565b979650505050505050565b80516060908067ffffffffffffffff811115613ca457613ca4614a8b565b604051908082528060200260200182016040528015613ce957816020015b6040805180820190915260608082526020820152815260200190600190039081613cc25790505b50915060005b81811015613d6b576040518060400160405280858381518110613d1457613d146156ab565b60200260200101518152602001613d43868481518110613d3657613d366156ab565b60200260200101516140e5565b815250838281518110613d5857613d586156ab565b6020908102919091010152600101613cef565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015613dca578060011b82018184015160001a8060041c8253600f811660018301535050600101613d9c565b509295945050505050565b60606000806000613de5856140f8565b919450925090506000816001811115613e0057613e0061573b565b14613e37576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613e418284614fed565b855114613e7a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b6985602001518484614596565b60606020826000015110613ea557613ea082613dd5565b610ff2565b610ff28261462a565b6060610ff2613ecd8360200151600081518110612fa157612fa16156ab565b613d72565b606082518210613ef15750604080516020810190915260008152610ff2565b6129688383848651613f03919061522c565b614640565b6000808251845110613f1b578251613f1e565b83515b90505b8082108015613fa55750828281518110613f3d57613f3d6156ab565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613f7c57613f7c6156ab565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15613fb557816001019150613f21565b5092915050565b6000808211614027576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606083156140a1575081612968565b8251156140b15782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610add9190614e1d565b6060610ff26140f383614818565b614885565b6000806000836000015160000361413b576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f811161416057600060016000945094509450505061458f565b60b7811161427657600061417560808361522c565b9050808760000151116141b4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214801561422c57507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614263576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061458f915050565b60bf81116143d457600061428b60b78361522c565b9050808760000151116142ca576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361432c576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614374576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61437e8184614fed565b8951116143b7576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6143c2836001614fed565b975095506000945061458f9350505050565b60f781116144395760006143e960c08361522c565b905080876000015111614428576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061458f915050565b600061444660f78361522c565b905080876000015111614485576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036144e7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c6037811161452f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6145398184614fed565b895111614572576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61457d836001614fed565b975095506001945061458f9350505050565b9193909250565b60608167ffffffffffffffff8111156145b1576145b1614a8b565b6040519080825280601f01601f1916602001820160405280156145db576020820181803683370190505b50905081156129685760006145f08486614fed565b90506020820160005b848110156146115782810151828201526020016145f9565b84811115614620576000858301525b5050509392505050565b6060610ff2826020015160008460000151614596565b60608182601f0110156146af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b82828401101561471b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b81830184511015614788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610add565b6060821580156147a7576040519150600082526020820160405261480f565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156147e05780518352602092830192016147c8565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201528151600003614867576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000614895856140f8565b9194509250905060018160018111156148b0576148b061573b565b146148e7576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516148f38385614fed565b1461492a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816149415790505093506000835b8651811015614a2f576000806149b46040518060400160405280858c60000151614998919061522c565b8152602001858c602001516149ad9190614fed565b90526140f8565b5091509150604051806040016040528083836149d09190614fed565b8152602001848b602001516149e59190614fed565b8152508885815181106149fa576149fa6156ab565b6020908102919091010152614a10600185614fed565b9350614a1c8183614fed565b614a269084614fed565b9250505061496e565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114614a5d57600080fd5b50565b803567ffffffffffffffff81168114614a7857600080fd5b919050565b8015158114614a5d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614b0157614b01614a8b565b604052919050565b600082601f830112614b1a57600080fd5b813567ffffffffffffffff811115614b3457614b34614a8b565b614b6560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614aba565b818152846020838601011115614b7a57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614bb057600080fd5b8635614bbb81614a3b565b95506020870135945060408701359350614bd760608801614a60565b92506080870135614be781614a7d565b915060a087013567ffffffffffffffff811115614c0357600080fd5b614c0f89828a01614b09565b9150509295509295509295565b600060c08284031215614c2e57600080fd5b60405160c0810167ffffffffffffffff8282108183111715614c5257614c52614a8b565b816040528293508435835260208501359150614c6d82614a3b565b81602084015260408501359150614c8382614a3b565b816040840152606085013560608401526080850135608084015260a0850135915080821115614cb157600080fd5b50614cbe85828601614b09565b60a0830152505092915050565b600080600080600085870360e0811215614ce457600080fd5b863567ffffffffffffffff80821115614cfc57600080fd5b614d088a838b01614c1c565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614d4157600080fd5b60408901955060c0890135925080831115614d5b57600080fd5b828901925089601f840112614d6f57600080fd5b8235915080821115614d8057600080fd5b508860208260051b8401011115614d9657600080fd5b959894975092955050506020019190565b60005b83811015614dc2578181015183820152602001614daa565b83811115611ef75750506000910152565b60008151808452614deb816020860160208601614da7565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006129686020830184614dd3565b600060208284031215614e4257600080fd5b5035919050565b60ff81168114614a5d57600080fd5b60008060008060808587031215614e6e57600080fd5b8435614e7981614a3b565b93506020850135614e8981614e49565b93969395505050506040820135916060013590565b600060208284031215614eb057600080fd5b813567ffffffffffffffff811115614ec757600080fd5b614ed384828501614c1c565b949350505050565b600060208284031215614eed57600080fd5b61296882614a60565b600080600060608486031215614f0b57600080fd5b8335614f1681614a3b565b92506020840135614f2681614a3b565b91506040840135614f3681614a3b565b809150509250925092565b600080600080600060a08688031215614f5957600080fd5b8535614f6481614a3b565b945060208601359350614f7960408701614a60565b92506060860135614f8981614a7d565b9150608086013567ffffffffffffffff811115614fa557600080fd5b614fb188828901614b09565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561500057615000614fbe565b500190565b60006020828403121561501757600080fd5b5051919050565b60006020828403121561503057600080fd5b815161296881614a3b565b80516fffffffffffffffffffffffffffffffff81168114614a7857600080fd5b60006060828403121561506d57600080fd5b6040516060810181811067ffffffffffffffff8211171561509057615090614a8b565b604052825181526150a36020840161503b565b60208201526150b46040840161503b565b60408201529392505050565b6000608082840312156150d257600080fd5b6040516080810181811067ffffffffffffffff821117156150f5576150f5614a8b565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff8084111561514157615141614a8b565b8360051b6020615152818301614aba565b86815291850191818101903684111561516a57600080fd5b865b8481101561519e578035868111156151845760008081fd5b61519036828b01614b09565b84525091830191830161516c565b50979650505050505050565b6000602082840312156151bc57600080fd5b815161296881614a7d565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b60488201526000825161521b816049850160208701614da7565b919091016049019695505050505050565b60008282101561523e5761523e614fbe565b500390565b600067ffffffffffffffff8083168185168183048111821515161561526a5761526a614fbe565b02949350505050565b600067ffffffffffffffff80831681851680830382111561529657615296614fbe565b01949350505050565b600080604083850312156152b257600080fd5b82516152bd81614a3b565b60208401519092506152ce81614e49565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615317576153176152d9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561536b5761536b614fbe565b500590565b6000808312837f8000000000000000000000000000000000000000000000000000000000000000018312811516156153aa576153aa614fbe565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156153de576153de614fbe565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561542557615425614fbe565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561546057615460614fbe565b6000871292508782058712848416161561547c5761547c614fbe565b8785058712818416161561549257615492614fbe565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156154da576154da614fbe565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561550e5761550e614fbe565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561554c5761554c614fbe565b500290565b600082615560576155606152d9565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526155b060c0830184614dd3565b98975050505050505050565b805163ffffffff81168114614a7857600080fd5b600060c082840312156155e257600080fd5b60405160c0810181811067ffffffffffffffff8211171561560557615605614a8b565b604052615611836155bc565b8152602083015161562181614e49565b6020820152604083015161563481614e49565b6040820152615645606084016155bc565b6060820152615656608084016155bc565b608082015261566760a0840161503b565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036156a4576156a4614fbe565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806156ed576156ed6152d9565b8060ff84160691505092915050565b600060ff821660ff84168082101561571657615716614fbe565b90039392505050565b60008251615731818460208701614da7565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a"; + hex"6080604052600436106101635760003560e01c80638c3152e9116100c0578063b69ef8a811610074578063cff0ab9611610059578063cff0ab9614610444578063e965084c146104e5578063e9e05c421461057157600080fd5b8063b69ef8a814610401578063c0c53b8b1461042457600080fd5b80639bf62d82116100a55780639bf62d821461036b578063a14238e714610398578063a35d99df146103c857600080fd5b80638c3152e91461031e5780639b5f694a1461033e57600080fd5b806354fd4d50116101175780636dbffb78116100fc5780636dbffb78146102de57806371cfaa3f146102fe5780638b4c40b01461018857600080fd5b806354fd4d501461026d5780635c975abb146102b957600080fd5b806335e80ab31161014857806335e80ab314610206578063452a9320146102385780634870496f1461024d57600080fd5b8063149f2f221461018f57806333d7e2bd146101af57600080fd5b3661018a576101883334620186a060006040518060200160405280600081525061057f565b005b600080fd5b34801561019b57600080fd5b506101886101aa366004614c13565b610624565b3480156101bb57600080fd5b506037546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561021257600080fd5b506035546101dc90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561024457600080fd5b506101dc610865565b34801561025957600080fd5b50610188610268366004614d47565b6108fd565b34801561027957600080fd5b50604080518082018252600c81527f322e382e312d626574612e320000000000000000000000000000000000000000602082015290516101fd9190614e99565b3480156102c557600080fd5b506102ce610eaa565b60405190151581526020016101fd565b3480156102ea57600080fd5b506102ce6102f9366004614eac565b610f3d565b34801561030a57600080fd5b50610188610319366004614ed4565b610ff8565b34801561032a57600080fd5b50610188610339366004614f1a565b6111ba565b34801561034a57600080fd5b506036546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561037757600080fd5b506032546101dc9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103a457600080fd5b506102ce6103b3366004614eac565b60336020526000908152604090205460ff1681565b3480156103d457600080fd5b506103e86103e3366004614f57565b611c3c565b60405167ffffffffffffffff90911681526020016101fd565b34801561040d57600080fd5b50610416611c55565b6040519081526020016101fd565b34801561043057600080fd5b5061018861043f366004614f72565b611caf565b34801561045057600080fd5b506001546104ac906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101fd565b3480156104f157600080fd5b50610543610500366004614eac565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101fd565b61018861057f366004614fbd565b8260005a9050600061058f611f19565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906105cb57503415155b15610602576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610610883489898989611fb6565b5061061b8282612162565b50505050505050565b8260005a90506000610634611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016106a6576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546106b89190615069565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561072a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074e9190615081565b905061077273ffffffffffffffffffffffffffffffffffffffff831633308c61242f565b61077c8982615069565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa1580156107e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080a9190615081565b14610841576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61084f8a8a8a8a8a8a611fb6565b505061085b8282612162565b5050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f8919061509a565b905090565b610905610eaa565b1561093c576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16036109a5576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6036546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810186905260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610a15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3991906150d7565b519050610a53610a4e3686900386018661513c565b61250b565b8114610ae6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f66000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000610af187612567565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610c075750805160365460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610bdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0391906150d7565b5114155b610c93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610add565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610d5c9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610d52888a6151a2565b8a60400135612597565b610de8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610add565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f19573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f89190615226565b6036546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101839052600091610ff29173ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd791906150d7565b602001516fffffffffffffffffffffffffffffffff166125bb565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff163314611049576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61105562030d40612661565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f00000000000000000000000000000000000000000000000000000000179052905161117296959493929101615243565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526111aa91614e99565b60405180910390a450505050565b565b6111c2610eaa565b156111f9576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461124c576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061125782612567565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610add565b603660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d39190615081565b81602001516fffffffffffffffffffffffffffffffff16101561149e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610add565b6114bd81602001516fffffffffffffffffffffffffffffffff166125bb565b61156f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610add565b60365460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a91906150d7565b82518151919250146116d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610add565b6116f381602001516fffffffffffffffffffffffffffffffff166125bb565b6117a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610add565b60008381526033602052604090205460ff1615611844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610add565b6000838152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558501516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055806118cf611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016119325761192b8660400151876080015188606001518960a001516126c3565b9150611b85565b8073ffffffffffffffffffffffffffffffffffffffff16866040015173ffffffffffffffffffffffffffffffffffffffff160361199b576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606086015115611b5c578560600151603d60008282546119bb91906152a8565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015611a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a519190615081565b9050611a86876040015188606001518473ffffffffffffffffffffffffffffffffffffffff166127219092919063ffffffff16565b6060870151611a9590826152a8565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015611aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b239190615081565b14611b5a576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08601515115611b805761192b8660400151876080015160008960a001516126c3565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405185907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90611be790851515815260200190565b60405180910390a281158015611bfd5750326001145b15611c34576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b6000611c498260106152bf565b610ff2906152086152ef565b600080611c60611f19565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601611ca7574791505090565b5050603d5490565b600054610100900460ff1615808015611ccf5750600054600160ff909116105b80611ce95750303b158015611ce9575060005460ff166001145b611d75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610add565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611dd357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603680547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8781169190911790925560378054909116858316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101008584160217905560325416611e8c57603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b611e9461277c565b8015611ef757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015611f89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fad919061531b565b90939092509050565b818015611fd8575073ffffffffffffffffffffffffffffffffffffffff861615155b1561200f576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120198151611c3c565b67ffffffffffffffff168367ffffffffffffffff161015612066576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c0815111156120a4576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333281146120c5575033731111000000000000000000000000000000001111015b600086868686866040516020016120e0959493929190615243565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516121509190614e99565b60405180910390a45050505050505050565b600154600090612198907801000000000000000000000000000000000000000000000000900467ffffffffffffffff16436152a8565b905060006121a461288f565b90506000816020015160ff16826000015163ffffffff166121c59190615384565b905082156122fc576001546000906121fc908390700100000000000000000000000000000000900467ffffffffffffffff166153ec565b90506000836040015160ff16836122139190615460565b6001546122339084906fffffffffffffffffffffffffffffffff16615460565b61223d9190615384565b60015490915060009061228e906122679084906fffffffffffffffffffffffffffffffff1661551c565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff166129cc565b905060018611156122bd576122ba61226782876040015160ff1660018a6122b591906152a8565b6129eb565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b6001805486919060109061232f908490700100000000000000000000000000000000900467ffffffffffffffff166152ef565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1613156123bc576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906123e8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615590565b905060006123fa48633b9aca00612a40565b61240490836155cd565b905060005a61241390886152a8565b90508082111561085b5761085b61242a82846152a8565b612a57565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052611ef79085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612a80565b6000816000015182602001518360400151846060015160405160200161254a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a0880151935160009761254a9790969591016155e1565b6000806125a386612b8c565b90506125b181868686612bbe565b9695505050505050565b603654604080517ff4daa291000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163f4daa2919160048083019260209291908290030181865afa15801561262b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264f9190615081565b6126599083615069565b421192915050565b6001805463ffffffff8316919060109061269a908490700100000000000000000000000000000000900467ffffffffffffffff166152ef565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b60008060006126d3866000612bee565b905080612709576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526127779084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612489565b505050565b600054610100900460ff16612813576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610add565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff166000036111b85760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152603754604080517fcc731b02000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163cc731b029160048083019260c09291908290030181865afa158015612931573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612955919061564c565b90506040518060c00160405280826000015163ffffffff168152602001826020015160ff168152602001826040015160ff168152602001826060015163ffffffff168152602001826080015163ffffffff1681526020018260a001516fffffffffffffffffffffffffffffffff1681525091505090565b60006129e16129db8585612c0c565b83612c1c565b90505b9392505050565b6000670de0b6b3a7640000612a2c612a038583615384565b612a1590670de0b6b3a76400006153ec565b612a2785670de0b6b3a7640000615460565b612c2b565b612a369086615460565b6129e19190615384565b600081831015612a5057816129e4565b5090919050565b6000805a90505b825a612a6a90836152a8565b101561277757612a79826156ef565b9150612a5e565b6000612ae2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612c5c9092919063ffffffff16565b8051909150156127775780806020019051810190612b009190615226565b612777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610add565b60608180519060200120604051602001612ba891815260200190565b6040516020818303038152906040529050919050565b6000612be584612bcf878686612c6b565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b600081831215612a5057816129e4565b6000818312612a5057816129e4565b60006129e4670de0b6b3a764000083612c43866136e9565b612c4d9190615460565b612c579190615384565b61392d565b60606129e18484600085613b6c565b60606000845111612cd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610add565b6000612ce384613d02565b90506000612cf086613dee565b9050600084604051602001612d0791815260200190565b60405160208183030381529060405290506000805b8451811015613660576000858281518110612d3957612d39615727565b602002602001015190508451831115612dd4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610add565b82600003612e8d5780518051602091820120604051612e2292612dfc92910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612e88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610add565b612fe4565b805151602011612f435780518051602091820120604051612eb792612dfc92910190815260200190565b612e88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610add565b805184516020808701919091208251919092012014612fe4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610add565b612ff060106001615069565b816020015151036131cc57845183036131645761302a816020015160108151811061301d5761301d615727565b6020026020010151613e51565b965060008751116130bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610add565b600186516130cb91906152a8565b8214613159576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610add565b5050505050506129e4565b600085848151811061317857613178615727565b602001015160f81c60f81b60f81c9050600082602001518260ff16815181106131a3576131a3615727565b602002602001015190506131b681613f05565b95506131c3600186615069565b9450505061364d565b6002816020015151036135c55760006131e482613f2a565b90506000816000815181106131fb576131fb615727565b016020015160f81c90506000613212600283615756565b61321d906002615778565b9050600061322e848360ff16613f4e565b9050600061323c8a89613f4e565b9050600061324a8383613f84565b9050808351146132dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610add565b60ff8516600214806132f1575060ff85166003145b156134e05780825114613386576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610add565b6133a0876020015160018151811061301d5761301d615727565b9c5060008d5111613433576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610add565b60018c5161344191906152a8565b88146134cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610add565b5050505050505050505050506129e4565b60ff851615806134f3575060ff85166001145b156135325761351f876020015160018151811061351257613512615727565b6020026020010151613f05565b995061352b818a615069565b98506135ba565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610add565b50505050505061364d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610add565b5080613658816156ef565b915050612d1c565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610add565b6000808213613754576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b6000606061376184614038565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361395e57506000919050565b680755bf798b4a1bf1e582126139d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610add565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613bfe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610add565b73ffffffffffffffffffffffffffffffffffffffff85163b613c7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610add565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613ca5919061579b565b60006040518083038185875af1925050503d8060008114613ce2576040519150601f19603f3d011682016040523d82523d6000602084013e613ce7565b606091505b5091509150613cf782828661410e565b979650505050505050565b80516060908067ffffffffffffffff811115613d2057613d20614b07565b604051908082528060200260200182016040528015613d6557816020015b6040805180820190915260608082526020820152815260200190600190039081613d3e5790505b50915060005b81811015613de7576040518060400160405280858381518110613d9057613d90615727565b60200260200101518152602001613dbf868481518110613db257613db2615727565b6020026020010151614161565b815250838281518110613dd457613dd4615727565b6020908102919091010152600101613d6b565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015613e46578060011b82018184015160001a8060041c8253600f811660018301535050600101613e18565b509295945050505050565b60606000806000613e6185614174565b919450925090506000816001811115613e7c57613e7c6157b7565b14613eb3576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613ebd8284615069565b855114613ef6576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612be585602001518484614612565b60606020826000015110613f2157613f1c82613e51565b610ff2565b610ff2826146a6565b6060610ff2613f49836020015160008151811061301d5761301d615727565b613dee565b606082518210613f6d5750604080516020810190915260008152610ff2565b6129e48383848651613f7f91906152a8565b6146bc565b6000808251845110613f97578251613f9a565b83515b90505b80821080156140215750828281518110613fb957613fb9615727565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613ff857613ff8615727565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b1561403157816001019150613f9d565b5092915050565b60008082116140a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610add565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b6060831561411d5750816129e4565b82511561412d5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610add9190614e99565b6060610ff261416f83614894565b614901565b600080600083600001516000036141b7576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f81116141dc57600060016000945094509450505061460b565b60b781116142f25760006141f16080836152a8565b905080876000015111614230576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff000000000000000000000000000000000000000000000000000000000000001690821480156142a857507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b156142df576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061460b915050565b60bf811161445057600061430760b7836152a8565b905080876000015111614346576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036143a8576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116143f0576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6143fa8184615069565b895111614433576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61443e836001615069565b975095506000945061460b9350505050565b60f781116144b557600061446560c0836152a8565b9050808760000151116144a4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061460b915050565b60006144c260f7836152a8565b905080876000015111614501576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614563576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116145ab576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6145b58184615069565b8951116145ee576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6145f9836001615069565b975095506001945061460b9350505050565b9193909250565b60608167ffffffffffffffff81111561462d5761462d614b07565b6040519080825280601f01601f191660200182016040528015614657576020820181803683370190505b50905081156129e457600061466c8486615069565b90506020820160005b8481101561468d578281015182820152602001614675565b8481111561469c576000858301525b5050509392505050565b6060610ff2826020015160008460000151614612565b60608182601f01101561472b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b828284011015614797576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610add565b81830184511015614804576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610add565b606082158015614823576040519150600082526020820160405261488b565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561485c578051835260209283019201614844565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015281516000036148e3576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b6060600080600061491185614174565b91945092509050600181600181111561492c5761492c6157b7565b14614963576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845161496f8385615069565b146149a6576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816149bd5790505093506000835b8651811015614aab57600080614a306040518060400160405280858c60000151614a1491906152a8565b8152602001858c60200151614a299190615069565b9052614174565b509150915060405180604001604052808383614a4c9190615069565b8152602001848b60200151614a619190615069565b815250888581518110614a7657614a76615727565b6020908102919091010152614a8c600185615069565b9350614a988183615069565b614aa29084615069565b925050506149ea565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114614ad957600080fd5b50565b803567ffffffffffffffff81168114614af457600080fd5b919050565b8015158114614ad957600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614b7d57614b7d614b07565b604052919050565b600082601f830112614b9657600080fd5b813567ffffffffffffffff811115614bb057614bb0614b07565b614be160207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614b36565b818152846020838601011115614bf657600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614c2c57600080fd5b8635614c3781614ab7565b95506020870135945060408701359350614c5360608801614adc565b92506080870135614c6381614af9565b915060a087013567ffffffffffffffff811115614c7f57600080fd5b614c8b89828a01614b85565b9150509295509295509295565b600060c08284031215614caa57600080fd5b60405160c0810167ffffffffffffffff8282108183111715614cce57614cce614b07565b816040528293508435835260208501359150614ce982614ab7565b81602084015260408501359150614cff82614ab7565b816040840152606085013560608401526080850135608084015260a0850135915080821115614d2d57600080fd5b50614d3a85828601614b85565b60a0830152505092915050565b600080600080600085870360e0811215614d6057600080fd5b863567ffffffffffffffff80821115614d7857600080fd5b614d848a838b01614c98565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614dbd57600080fd5b60408901955060c0890135925080831115614dd757600080fd5b828901925089601f840112614deb57600080fd5b8235915080821115614dfc57600080fd5b508860208260051b8401011115614e1257600080fd5b959894975092955050506020019190565b60005b83811015614e3e578181015183820152602001614e26565b83811115611ef75750506000910152565b60008151808452614e67816020860160208601614e23565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006129e46020830184614e4f565b600060208284031215614ebe57600080fd5b5035919050565b60ff81168114614ad957600080fd5b60008060008060808587031215614eea57600080fd5b8435614ef581614ab7565b93506020850135614f0581614ec5565b93969395505050506040820135916060013590565b600060208284031215614f2c57600080fd5b813567ffffffffffffffff811115614f4357600080fd5b614f4f84828501614c98565b949350505050565b600060208284031215614f6957600080fd5b6129e482614adc565b600080600060608486031215614f8757600080fd5b8335614f9281614ab7565b92506020840135614fa281614ab7565b91506040840135614fb281614ab7565b809150509250925092565b600080600080600060a08688031215614fd557600080fd5b8535614fe081614ab7565b945060208601359350614ff560408701614adc565b9250606086013561500581614af9565b9150608086013567ffffffffffffffff81111561502157600080fd5b61502d88828901614b85565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561507c5761507c61503a565b500190565b60006020828403121561509357600080fd5b5051919050565b6000602082840312156150ac57600080fd5b81516129e481614ab7565b80516fffffffffffffffffffffffffffffffff81168114614af457600080fd5b6000606082840312156150e957600080fd5b6040516060810181811067ffffffffffffffff8211171561510c5761510c614b07565b6040528251815261511f602084016150b7565b6020820152615130604084016150b7565b60408201529392505050565b60006080828403121561514e57600080fd5b6040516080810181811067ffffffffffffffff8211171561517157615171614b07565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff808411156151bd576151bd614b07565b8360051b60206151ce818301614b36565b8681529185019181810190368411156151e657600080fd5b865b8481101561521a578035868111156152005760008081fd5b61520c36828b01614b85565b8452509183019183016151e8565b50979650505050505050565b60006020828403121561523857600080fd5b81516129e481614af9565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251615297816049850160208701614e23565b919091016049019695505050505050565b6000828210156152ba576152ba61503a565b500390565b600067ffffffffffffffff808316818516818304811182151516156152e6576152e661503a565b02949350505050565b600067ffffffffffffffff8083168185168083038211156153125761531261503a565b01949350505050565b6000806040838503121561532e57600080fd5b825161533981614ab7565b602084015190925061534a81614ec5565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261539357615393615355565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156153e7576153e761503a565b500590565b6000808312837f8000000000000000000000000000000000000000000000000000000000000000018312811516156154265761542661503a565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561545a5761545a61503a565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156154a1576154a161503a565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156154dc576154dc61503a565b600087129250878205871284841616156154f8576154f861503a565b8785058712818416161561550e5761550e61503a565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156155565761555661503a565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561558a5761558a61503a565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156155c8576155c861503a565b500290565b6000826155dc576155dc615355565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261562c60c0830184614e4f565b98975050505050505050565b805163ffffffff81168114614af457600080fd5b600060c0828403121561565e57600080fd5b60405160c0810181811067ffffffffffffffff8211171561568157615681614b07565b60405261568d83615638565b8152602083015161569d81614ec5565b602082015260408301516156b081614ec5565b60408201526156c160608401615638565b60608201526156d260808401615638565b60808201526156e360a084016150b7565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036157205761572061503a565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff83168061576957615769615355565b8060ff84160691505092915050565b600060ff821660ff8416808210156157925761579261503a565b90039392505050565b600082516157ad818460208701614e23565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a"; bytes internal constant l2OutputOracleCode = hex"60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec33481461049b578063e1a41bcf146104b0578063f4daa291146104c657600080fd5b8063ce5db8d614610445578063cf8e5cf01461045b578063d1de856c1461047b57600080fd5b8063a25ae557116100b0578063a25ae55714610391578063a8e4fb90146103ed578063bffa7f0f1461041a57600080fd5b806389c44cbb1461034857806393991af3146103685780639aaab6481461037e57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa5146102fc5780637f00642014610312578063887862721461033257600080fd5b806369f16eec146102a75780636abcf563146102bc5780636b4d98dd146102d157600080fd5b8063529933df11610169578063529933df146101ea578063534db0e2146101ff57806354fd4d501461025157600080fd5b80622134cc1461018f5780631c89c97d146101b35780634599c788146101d5575b600080fd5b34801561019b57600080fd5b506005545b6040519081526020015b60405180910390f35b3480156101bf57600080fd5b506101d36101ce3660046113a2565b6104db565b005b3480156101e157600080fd5b506101a06108b6565b3480156101f657600080fd5b506004546101a0565b34801561020b57600080fd5b5060065461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101aa565b34801561025d57600080fd5b5061029a6040518060400160405280600c81526020017f312e382e312d626574612e31000000000000000000000000000000000000000081525081565b6040516101aa9190611405565b3480156102b357600080fd5b506101a0610929565b3480156102c857600080fd5b506003546101a0565b3480156102dd57600080fd5b5060065473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561030857600080fd5b506101a060015481565b34801561031e57600080fd5b506101a061032d366004611478565b61093b565b34801561033e57600080fd5b506101a060025481565b34801561035457600080fd5b506101d3610363366004611478565b610b4f565b34801561037457600080fd5b506101a060055481565b6101d361038c366004611491565b610de9565b34801561039d57600080fd5b506103b16103ac366004611478565b61124a565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101aa565b3480156103f957600080fd5b5060075461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561042657600080fd5b5060075473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561045157600080fd5b506101a060085481565b34801561046757600080fd5b506103b1610476366004611478565b6112de565b34801561048757600080fd5b506101a0610496366004611478565b611316565b3480156104a757600080fd5b506101a0611346565b3480156104bc57600080fd5b506101a060045481565b3480156104d257600080fd5b506008546101a0565b600054610100900460ff16158080156104fb5750600054600160ff909116105b806105155750303b158015610515575060005460ff166001145b6105a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561060457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60008811610694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e2030000000000000606482015260840161059d565b60008711610724576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e2030000000000000000000000000606482015260840161059d565b428511156107db576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60048890556005879055600186905560028590556007805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556006805492861692909116919091179055600882905580156108ac57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b6003546000901561092057600380546108d1906001906114f2565b815481106108e1576108e1611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b600354600090610924906001906114f2565b60006109456108b6565b8211156109fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161059d565b600354610aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161059d565b6003546000905b80821015610b485760006002610acc8385611538565b610ad69190611550565b90508460038281548110610aec57610aec611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610b3e57610b37816001611538565b9250610b42565b8091505b50610ab6565b5092915050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610bf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161059d565b6003548110610cad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60085460038281548110610cc357610cc3611509565b6000918252602090912060016002909202010154610cf3906fffffffffffffffffffffffffffffffff16426114f2565b10610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161059d565b6000610db160035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60075473ffffffffffffffffffffffffffffffffffffffff163314610eb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b610ebe611346565b8314610f72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161059d565b42610f7c84611316565b10611009576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161059d565b83611096576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161059d565b81156111525781814014611152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161059d565b8261115c60035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e24260405161118e91815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b60408051606081018252600080825260208201819052918101919091526003828154811061127a5761127a611509565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b604080516060810182526000808252602082018190529181019190915260036113068361093b565b8154811061127a5761127a611509565b60006005546001548361132991906114f2565b611333919061158b565b6002546113409190611538565b92915050565b60006004546113536108b6565b6109249190611538565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b803573ffffffffffffffffffffffffffffffffffffffff8116811461139d57600080fd5b919050565b600080600080600080600060e0888a0312156113bd57600080fd5b873596506020880135955060408801359450606088013593506113e260808901611379565b92506113f060a08901611379565b915060c0880135905092959891949750929550565b600060208083528351808285015260005b8181101561143257858101830151858201604001528201611416565b81811115611444576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561148a57600080fd5b5035919050565b600080600080608085870312156114a757600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611504576115046114c3565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000821982111561154b5761154b6114c3565b500190565b600082611586577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156115c3576115c36114c3565b50029056fea164736f6c634300080f000a"; bytes internal constant optimismPortal2Code = - hex"6080604052600436106101d15760003560e01c80637fc48504116100f7578063a35d99df11610095578063bf653a5c11610064578063bf653a5c14610697578063cff0ab96146106ca578063e9e05c421461076b578063f2b4e6171461077e57600080fd5b8063a35d99df1461059b578063a3860f48146105bb578063b69ef8a8146105db578063bb2c727e146105f057600080fd5b80638e819e54116100d15780638e819e54146104eb578063952b27971461050b5780639bf62d821461053e578063a14238e71461056b57600080fd5b80637fc48504146104ab5780638b4c40b0146101f65780638c3152e9146104cb57600080fd5b80634870496f1161016f5780635c975abb1161013e5780635c975abb1461043657806371c1566e1461044b57806371cfaa3f1461046b5780637d6be8dc1461048b57600080fd5b80634870496f1461034d5780634fd0434c1461036d578063513747ab146103af57806354fd4d50146103ea57600080fd5b80633c9f397c116101ab5780633c9f397c146102a657806343ca1c50146102d8578063452a9320146102f857806345884d321461030d57600080fd5b8063149f2f22146101fd57806333d7e2bd1461021d57806335e80ab31461027457600080fd5b366101f8576101f63334620186a06000604051806020016040528060008152506107ab565b005b600080fd5b34801561020957600080fd5b506101f6610218366004614fe6565b610850565b34801561022957600080fd5b5060375461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561028057600080fd5b5060355461024a90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156102b257600080fd5b50603b546102c39063ffffffff1681565b60405163ffffffff909116815260200161026b565b3480156102e457600080fd5b506101f66102f336600461511c565b610a91565b34801561030457600080fd5b5061024a610f31565b34801561031957600080fd5b5061033d61032836600461516e565b603a6020526000908152604090205460ff1681565b604051901515815260200161026b565b34801561035957600080fd5b506101f661036836600461518b565b610fc9565b34801561037957600080fd5b50603b5461039690640100000000900467ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161026b565b3480156103bb57600080fd5b506103dc6103ca366004615267565b6000908152603c602052604090205490565b60405190815260200161026b565b3480156103f657600080fd5b50604080518082018252600d81527f332e31312e302d626574612e33000000000000000000000000000000000000006020820152905161026b91906152f6565b34801561044257600080fd5b5061033d611531565b34801561045757600080fd5b506101f6610466366004615309565b6115c4565b34801561047757600080fd5b506101f661048636600461533d565b611c7f565b34801561049757600080fd5b506101f66104a636600461516e565b611e3f565b3480156104b757600080fd5b506101f66104c6366004615395565b611f22565b3480156104d757600080fd5b506101f66104e63660046153b2565b61200e565b3480156104f757600080fd5b506101f66105063660046153ef565b61205a565b34801561051757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000066103dc565b34801561054a57600080fd5b5060325461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561057757600080fd5b5061033d610586366004615267565b60336020526000908152604090205460ff1681565b3480156105a757600080fd5b506103966105b636600461544b565b61230f565b3480156105c757600080fd5b5061024a6105d6366004615468565b61232e565b3480156105e757600080fd5b506103dc612373565b3480156105fc57600080fd5b5061066261060b366004615309565b603960209081526000928352604080842090915290825290205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900467ffffffffffffffff1682565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff90911660208301520161026b565b3480156106a357600080fd5b507f000000000000000000000000000000000000000000000000000000000000000c6103dc565b3480156106d657600080fd5b50600154610732906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff928316602085015291169082015260600161026b565b6101f661077936600461548a565b6107ab565b34801561078a57600080fd5b5060385461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b8260005a905060006107bb6123e9565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906107f757503415155b1561082e576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61083c883489898989612486565b506108478282612632565b50505050505050565b8260005a905060006108606123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016108d2576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546108e49190615538565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610956573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097a9190615550565b905061099e73ffffffffffffffffffffffffffffffffffffffff831633308c6128ff565b6109a88982615538565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a369190615550565b14610a6d576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a7b8a8a8a8a8a8a612486565b5050610a878282612632565b5050505050505050565b610a99611531565b15610ad0576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead14610b23576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610b2e836129e1565b9050610b3a81836115c4565b6000818152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558401516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905580610bc56123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601610c2857610c218560400151866080015187606001518860a00151612a2e565b9150610e7b565b8073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610c91576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606085015115610e52578460600151603d6000828254610cb19190615569565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610d23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d479190615550565b9050610d7c866040015187606001518473ffffffffffffffffffffffffffffffffffffffff16612a8c9092919063ffffffff16565b6060860151610d8b9082615569565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e199190615550565b14610e50576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08501515115610e7657610c218560400151866080015160008860a00151612a2e565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405183907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90610edd90851515815260200190565b60405180910390a281158015610ef35750326001145b15610f2a576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fa0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615580565b905090565b610fd1611531565b15611008576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603611071576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6038546040517fbb8aa1fc00000000000000000000000000000000000000000000000000000000815260048101869052600091829173ffffffffffffffffffffffffffffffffffffffff9091169063bb8aa1fc90602401606060405180830381865afa1580156110e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611109919061559d565b925050915060008173ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561115b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117f9190615550565b603b5490915063ffffffff8481169116146111c6576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111dd6111d8368890038801886155ea565b612ae7565b8114611215576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611220896129e1565b905060018373ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611293919061567f565b60028111156112a4576112a4615650565b036112db576040517fd357347400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051602081018390526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506113a49101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f010000000000000000000000000000000000000000000000000000000000000060208301529061139a898b6156a0565b8b60400135612b26565b15156000036113df576040517fb05e92fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825273ffffffffffffffffffffffffffffffffffffffff808716825267ffffffffffffffff4281166020808501918252600088815260398252868120338252825286812095518654935190941674010000000000000000000000000000000000000000027fffffffff0000000000000000000000000000000000000000000000000000000090931693851693909317919091179093558d840151928e01519351928216939091169185917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f6291a4604051339083907f798f9f13695f8f045aa5f80ed8efebb695f3c7fe65da381969f2f28bf3c60b9790600090a3506000908152603c602090815260408220805460018101825590835291200180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115a0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615724565b600082815260396020908152604080832073ffffffffffffffffffffffffffffffffffffffff85811685529083528184208251808401845290549182168082527401000000000000000000000000000000000000000090920467ffffffffffffffff1681850152818552603a90935292205490919060ff1615611673576040517f09550c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816020015167ffffffffffffffff166000036116bb576040517f94efd49b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061173c8273ffffffffffffffffffffffffffffffffffffffff1663cf09e0d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172f9190615741565b67ffffffffffffffff1690565b90508067ffffffffffffffff16836020015167ffffffffffffffff1611611810576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e20646973707574652067616d65206372656160648201527f74696f6e2074696d657374616d70000000000000000000000000000000000000608482015260a4015b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000c836020015167ffffffffffffffff164261184b9190615569565b116118d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c20686173206e6f74206d6174757265642079657400000000000000000000006064820152608401611807565b60028273ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611925573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611949919061567f565b600281111561195a5761195a615650565b14611991576040517fa080a3c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5463ffffffff1663ffffffff16611a1b8373ffffffffffffffffffffffffffffffffffffffff1663bbdc02db6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a12919061575e565b63ffffffff1690565b63ffffffff1614611a58576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5467ffffffffffffffff64010000000090910481169082161015611b26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a20646973707574652067616d652063726560448201527f61746564206265666f7265207265737065637465642067616d6520747970652060648201527f7761732075706461746564000000000000000000000000000000000000000000608482015260a401611807565b7f0000000000000000000000000000000000000000000000000000000000000006611b958373ffffffffffffffffffffffffffffffffffffffff166319effeb46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b611ba99067ffffffffffffffff1642615569565b11611c36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f696e206169722d676170000000000000000000000000000000000000000000006064820152608401611807565b60008581526033602052604090205460ff1615610f2a576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60375473ffffffffffffffffffffffffffffffffffffffff163314611cd0576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611cdc62030d40612b4a565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f000000000000000000000000000000000000000000000000000000001790529051611df99695949392910161577b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052611e31916152f6565b60405180910390a450505050565b611e47610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611eab576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152603a602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f192c289026d59a41a27f5aea08f3969b57931b0589202d14f4368cded95d3cda9190a250565b611f2a610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f8e576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b805463ffffffff83167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090911681176401000000004267ffffffffffffffff90811682029290921793849055604051930416917f049fe9dd413cdf037cce27011cc1790c753118272f3630e6e8bdfa5e8208176090600090a350565b565b612016611531565b1561204d576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120578133610a91565b50565b600054610100900460ff161580801561207a5750600054600160ff909116105b806120945750303b158015612094575060005460ff166001145b612120576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611807565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561217e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603880547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8881169190911790925560378054909116868316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff16610100868416021790556032541661229e576032805461dead7fffffffffffffffffffffffff0000000000000000000000000000000000000000909116179055603b80547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166401000000004267ffffffffffffffff16027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000161763ffffffff84161790555b6122a6612bac565b8015610f2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600061231c8260106157e0565b61232890615208615810565b92915050565b603c602052816000526040600020818154811061234a57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169150829050565b60008061237e6123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016123c5574791505090565b5050603d5490565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015612459573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247d919061583c565b90939092509050565b8180156124a8575073ffffffffffffffffffffffffffffffffffffffff861615155b156124df576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6124e9815161230f565b67ffffffffffffffff168367ffffffffffffffff161015612536576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c081511115612574576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33328114612595575033731111000000000000000000000000000000001111015b600086868686866040516020016125b095949392919061577b565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161262091906152f6565b60405180910390a45050505050505050565b600154600090612668907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643615569565b90506000612674612cbf565b90506000816020015160ff16826000015163ffffffff16612695919061589a565b905082156127cc576001546000906126cc908390700100000000000000000000000000000000900467ffffffffffffffff16615902565b90506000836040015160ff16836126e39190615976565b6001546127039084906fffffffffffffffffffffffffffffffff16615976565b61270d919061589a565b60015490915060009061275e906127379084906fffffffffffffffffffffffffffffffff16615a32565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612d80565b9050600186111561278d5761278a61273782876040015160ff1660018a6127859190615569565b612d9f565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b600180548691906010906127ff908490700100000000000000000000000000000000900467ffffffffffffffff16615810565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff16131561288c576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906128b8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615aa6565b905060006128ca48633b9aca00612df4565b6128d49083615ae3565b905060005a6128e39088615569565b905080821115610a8757610a876128fa8284615569565b612e0b565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526129db9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612e34565b50505050565b80516020808301516040808501516060860151608087015160a08801519351600097612a11979096959101615af7565b604051602081830303815290604052805190602001209050919050565b6000806000612a3e866000612f40565b905080612a74576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052612ae29084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612959565b505050565b60008160000151826020015183604001518460600151604051602001612a11949392919093845260208401929092526040830152606082015260800190565b600080612b3286612f5e565b9050612b4081868686612f90565b9695505050505050565b6001805463ffffffff83169190601090612b83908490700100000000000000000000000000000000900467ffffffffffffffff16615810565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b600054610100900460ff16612c43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611807565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff1660000361200c5760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa158015612d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615b4e565b6000612d95612d8f8585612fc0565b83612fd0565b90505b9392505050565b6000670de0b6b3a7640000612de0612db7858361589a565b612dc990670de0b6b3a7640000615902565b612ddb85670de0b6b3a7640000615976565b612fdf565b612dea9086615976565b612d95919061589a565b600081831015612e045781612d98565b5090919050565b6000805a90505b825a612e1e9083615569565b1015612ae257612e2d82615bf0565b9150612e12565b6000612e96826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130109092919063ffffffff16565b805190915015612ae25780806020019051810190612eb49190615724565b612ae2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611807565b600080603f83619c4001026040850201603f5a021015949350505050565b60608180519060200120604051602001612f7a91815260200190565b6040516020818303038152906040529050919050565b6000612fb784612fa187868661301f565b8051602091820120825192909101919091201490565b95945050505050565b600081831215612e045781612d98565b6000818312612e045781612d98565b6000612d98670de0b6b3a764000083612ff786613a9d565b6130019190615976565b61300b919061589a565b613ce1565b6060612d958484600085613f20565b6060600084511161308c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401611807565b6000613097846140b6565b905060006130a4866141a2565b90506000846040516020016130bb91815260200190565b60405160208183030381529060405290506000805b8451811015613a145760008582815181106130ed576130ed615c28565b602002602001015190508451831115613188576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401611807565b8260000361324157805180516020918201206040516131d6926131b092910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b61323c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401611807565b613398565b8051516020116132f7578051805160209182012060405161326b926131b092910190815260200190565b61323c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401611807565b805184516020808701919091208251919092012014613398576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401611807565b6133a460106001615538565b816020015151036135805784518303613518576133de81602001516010815181106133d1576133d1615c28565b6020026020010151614205565b96506000875111613471576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401611807565b6001865161347f9190615569565b821461350d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401611807565b505050505050612d98565b600085848151811061352c5761352c615c28565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061355757613557615c28565b6020026020010151905061356a816142b9565b9550613577600186615538565b94505050613a01565b600281602001515103613979576000613598826142de565b90506000816000815181106135af576135af615c28565b016020015160f81c905060006135c6600283615c57565b6135d1906002615c79565b905060006135e2848360ff16614302565b905060006135f08a89614302565b905060006135fe8383614338565b905080835114613690576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401611807565b60ff8516600214806136a5575060ff85166003145b15613894578082511461373a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401611807565b61375487602001516001815181106133d1576133d1615c28565b9c5060008d51116137e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401611807565b60018c516137f59190615569565b8814613883576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401611807565b505050505050505050505050612d98565b60ff851615806138a7575060ff85166001145b156138e6576138d387602001516001815181106138c6576138c6615c28565b60200260200101516142b9565b99506138df818a615538565b985061396e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401611807565b505050505050613a01565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401611807565b5080613a0c81615bf0565b9150506130d0565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401611807565b6000808213613b08576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b60006060613b15846143ec565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c18213613d1257506000919050565b680755bf798b4a1bf1e58212613d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401611807565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613fb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611807565b73ffffffffffffffffffffffffffffffffffffffff85163b614030576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611807565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516140599190615c9c565b60006040518083038185875af1925050503d8060008114614096576040519150601f19603f3d011682016040523d82523d6000602084013e61409b565b606091505b50915091506140ab8282866144c2565b979650505050505050565b80516060908067ffffffffffffffff8111156140d4576140d4614eb1565b60405190808252806020026020018201604052801561411957816020015b60408051808201909152606080825260208201528152602001906001900390816140f25790505b50915060005b8181101561419b57604051806040016040528085838151811061414457614144615c28565b6020026020010151815260200161417386848151811061416657614166615c28565b6020026020010151614515565b81525083828151811061418857614188615c28565b602090810291909101015260010161411f565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b838110156141fa578060011b82018184015160001a8060041c8253600f8116600183015350506001016141cc565b509295945050505050565b6060600080600061421585614528565b91945092509050600081600181111561423057614230615650565b14614267576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6142718284615538565b8551146142aa576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fb7856020015184846149c6565b606060208260000151106142d5576142d082614205565b612328565b61232882614a5a565b60606123286142fd83602001516000815181106133d1576133d1615c28565b6141a2565b6060825182106143215750604080516020810190915260008152612328565b612d9883838486516143339190615569565b614a70565b600080825184511061434b57825161434e565b83515b90505b80821080156143d5575082828151811061436d5761436d615c28565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168483815181106143ac576143ac615c28565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156143e557816001019150614351565b5092915050565b6000808211614457576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606083156144d1575081612d98565b8251156144e15782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180791906152f6565b606061232861452383614c48565b614cb5565b6000806000836000015160000361456b576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f81116145905760006001600094509450945050506149bf565b60b781116146a65760006145a5608083615569565b9050808760000151116145e4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214801561465c57507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614693576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600195509350600092506149bf915050565b60bf81116148045760006146bb60b783615569565b9050808760000151116146fa576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361475c576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116147a4576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147ae8184615538565b8951116147e7576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147f2836001615538565b97509550600094506149bf9350505050565b60f7811161486957600061481960c083615569565b905080876000015111614858576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001955093508492506149bf915050565b600061487660f783615569565b9050808760000151116148b5576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614917576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c6037811161495f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6149698184615538565b8951116149a2576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6149ad836001615538565b97509550600194506149bf9350505050565b9193909250565b60608167ffffffffffffffff8111156149e1576149e1614eb1565b6040519080825280601f01601f191660200182016040528015614a0b576020820181803683370190505b5090508115612d98576000614a208486615538565b90506020820160005b84811015614a41578281015182820152602001614a29565b84811115614a50576000858301525b5050509392505050565b60606123288260200151600084600001516149c6565b60608182601f011015614adf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b828284011015614b4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b81830184511015614bb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401611807565b606082158015614bd75760405191506000825260208201604052614c3f565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614c10578051835260209283019201614bf8565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201528151600003614c97576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000614cc585614528565b919450925090506001816001811115614ce057614ce0615650565b14614d17576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451614d238385615538565b14614d5a576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081614d715790505093506000835b8651811015614e5f57600080614de46040518060400160405280858c60000151614dc89190615569565b8152602001858c60200151614ddd9190615538565b9052614528565b509150915060405180604001604052808383614e009190615538565b8152602001848b60200151614e159190615538565b815250888581518110614e2a57614e2a615c28565b6020908102919091010152614e40600185615538565b9350614e4c8183615538565b614e569084615538565b92505050614d9e565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461205757600080fd5b67ffffffffffffffff8116811461205757600080fd5b801515811461205757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715614f0357614f03614eb1565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614f5057614f50614eb1565b604052919050565b600082601f830112614f6957600080fd5b813567ffffffffffffffff811115614f8357614f83614eb1565b614fb460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614f09565b818152846020838601011115614fc957600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614fff57600080fd5b863561500a81614e6b565b95506020870135945060408701359350606087013561502881614e8d565b9250608087013561503881614ea3565b915060a087013567ffffffffffffffff81111561505457600080fd5b61506089828a01614f58565b9150509295509295509295565b600060c0828403121561507f57600080fd5b60405160c0810167ffffffffffffffff82821081831117156150a3576150a3614eb1565b8160405282935084358352602085013591506150be82614e6b565b816020840152604085013591506150d482614e6b565b816040840152606085013560608401526080850135608084015260a085013591508082111561510257600080fd5b5061510f85828601614f58565b60a0830152505092915050565b6000806040838503121561512f57600080fd5b823567ffffffffffffffff81111561514657600080fd5b6151528582860161506d565b925050602083013561516381614e6b565b809150509250929050565b60006020828403121561518057600080fd5b8135612d9881614e6b565b600080600080600085870360e08112156151a457600080fd5b863567ffffffffffffffff808211156151bc57600080fd5b6151c88a838b0161506d565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401121561520157600080fd5b60408901955060c089013592508083111561521b57600080fd5b828901925089601f84011261522f57600080fd5b823591508082111561524057600080fd5b508860208260051b840101111561525657600080fd5b959894975092955050506020019190565b60006020828403121561527957600080fd5b5035919050565b60005b8381101561529b578181015183820152602001615283565b838111156129db5750506000910152565b600081518084526152c4816020860160208601615280565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612d9860208301846152ac565b6000806040838503121561531c57600080fd5b82359150602083013561516381614e6b565b60ff8116811461205757600080fd5b6000806000806080858703121561535357600080fd5b843561535e81614e6b565b9350602085013561536e8161532e565b93969395505050506040820135916060013590565b63ffffffff8116811461205757600080fd5b6000602082840312156153a757600080fd5b8135612d9881615383565b6000602082840312156153c457600080fd5b813567ffffffffffffffff8111156153db57600080fd5b6153e78482850161506d565b949350505050565b6000806000806080858703121561540557600080fd5b843561541081614e6b565b9350602085013561542081614e6b565b9250604085013561543081614e6b565b9150606085013561544081615383565b939692955090935050565b60006020828403121561545d57600080fd5b8135612d9881614e8d565b6000806040838503121561547b57600080fd5b50508035926020909101359150565b600080600080600060a086880312156154a257600080fd5b85356154ad81614e6b565b94506020860135935060408601356154c481614e8d565b925060608601356154d481614ea3565b9150608086013567ffffffffffffffff8111156154f057600080fd5b6154fc88828901614f58565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561554b5761554b615509565b500190565b60006020828403121561556257600080fd5b5051919050565b60008282101561557b5761557b615509565b500390565b60006020828403121561559257600080fd5b8151612d9881614e6b565b6000806000606084860312156155b257600080fd5b83516155bd81615383565b60208501519093506155ce81614e8d565b60408501519092506155df81614e6b565b809150509250925092565b6000608082840312156155fc57600080fd5b6040516080810181811067ffffffffffffffff8211171561561f5761561f614eb1565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006020828403121561569157600080fd5b815160038110612d9857600080fd5b600067ffffffffffffffff808411156156bb576156bb614eb1565b8360051b60206156cc818301614f09565b8681529185019181810190368411156156e457600080fd5b865b84811015615718578035868111156156fe5760008081fd5b61570a36828b01614f58565b8452509183019183016156e6565b50979650505050505050565b60006020828403121561573657600080fd5b8151612d9881614ea3565b60006020828403121561575357600080fd5b8151612d9881614e8d565b60006020828403121561577057600080fd5b8151612d9881615383565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b6048820152600082516157cf816049850160208701615280565b919091016049019695505050505050565b600067ffffffffffffffff8083168185168183048111821515161561580757615807615509565b02949350505050565b600067ffffffffffffffff80831681851680830382111561583357615833615509565b01949350505050565b6000806040838503121561584f57600080fd5b825161585a81614e6b565b60208401519092506151638161532e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826158a9576158a961586b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156158fd576158fd615509565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561593c5761593c615509565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561597057615970615509565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156159b7576159b7615509565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156159f2576159f2615509565b60008712925087820587128484161615615a0e57615a0e615509565b87850587128184161615615a2457615a24615509565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03841381151615615a6c57615a6c615509565b827f8000000000000000000000000000000000000000000000000000000000000000038412811615615aa057615aa0615509565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615ade57615ade615509565b500290565b600082615af257615af261586b565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152615b4260c08301846152ac565b98975050505050505050565b600060c08284031215615b6057600080fd5b615b68614ee0565b8251615b7381615383565b81526020830151615b838161532e565b60208201526040830151615b968161532e565b60408201526060830151615ba981615383565b60608201526080830151615bbc81615383565b608082015260a08301516fffffffffffffffffffffffffffffffff81168114615be457600080fd5b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615c2157615c21615509565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff831680615c6a57615c6a61586b565b8060ff84160691505092915050565b600060ff821660ff841680821015615c9357615c93615509565b90039392505050565b60008251615cae818460208701615280565b919091019291505056fea164736f6c634300080f000a"; + hex"6080604052600436106101d15760003560e01c80637fc48504116100f7578063a35d99df11610095578063bf653a5c11610064578063bf653a5c14610697578063cff0ab96146106ca578063e9e05c421461076b578063f2b4e6171461077e57600080fd5b8063a35d99df1461059b578063a3860f48146105bb578063b69ef8a8146105db578063bb2c727e146105f057600080fd5b80638e819e54116100d15780638e819e54146104eb578063952b27971461050b5780639bf62d821461053e578063a14238e71461056b57600080fd5b80637fc48504146104ab5780638b4c40b0146101f65780638c3152e9146104cb57600080fd5b80634870496f1161016f5780635c975abb1161013e5780635c975abb1461043657806371c1566e1461044b57806371cfaa3f1461046b5780637d6be8dc1461048b57600080fd5b80634870496f1461034d5780634fd0434c1461036d578063513747ab146103af57806354fd4d50146103ea57600080fd5b80633c9f397c116101ab5780633c9f397c146102a657806343ca1c50146102d8578063452a9320146102f857806345884d321461030d57600080fd5b8063149f2f22146101fd57806333d7e2bd1461021d57806335e80ab31461027457600080fd5b366101f8576101f63334620186a06000604051806020016040528060008152506107ab565b005b600080fd5b34801561020957600080fd5b506101f6610218366004614feb565b610850565b34801561022957600080fd5b5060375461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561028057600080fd5b5060355461024a90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156102b257600080fd5b50603b546102c39063ffffffff1681565b60405163ffffffff909116815260200161026b565b3480156102e457600080fd5b506101f66102f3366004615121565b610a91565b34801561030457600080fd5b5061024a610f31565b34801561031957600080fd5b5061033d610328366004615173565b603a6020526000908152604090205460ff1681565b604051901515815260200161026b565b34801561035957600080fd5b506101f6610368366004615190565b610fc9565b34801561037957600080fd5b50603b5461039690640100000000900467ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161026b565b3480156103bb57600080fd5b506103dc6103ca36600461526c565b6000908152603c602052604090205490565b60405190815260200161026b565b3480156103f657600080fd5b50604080518082018252600d81527f332e31312e302d626574612e33000000000000000000000000000000000000006020820152905161026b91906152fb565b34801561044257600080fd5b5061033d611531565b34801561045757600080fd5b506101f661046636600461530e565b6115c4565b34801561047757600080fd5b506101f6610486366004615342565b611c7f565b34801561049757600080fd5b506101f66104a6366004615173565b611e3f565b3480156104b757600080fd5b506101f66104c636600461539a565b611f22565b3480156104d757600080fd5b506101f66104e63660046153b7565b61200e565b3480156104f757600080fd5b506101f66105063660046153f4565b61205a565b34801561051757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000066103dc565b34801561054a57600080fd5b5060325461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561057757600080fd5b5061033d61058636600461526c565b60336020526000908152604090205460ff1681565b3480156105a757600080fd5b506103966105b6366004615450565b61230f565b3480156105c757600080fd5b5061024a6105d636600461546d565b61232e565b3480156105e757600080fd5b506103dc612373565b3480156105fc57600080fd5b5061066261060b36600461530e565b603960209081526000928352604080842090915290825290205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900467ffffffffffffffff1682565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff90911660208301520161026b565b3480156106a357600080fd5b507f000000000000000000000000000000000000000000000000000000000000000c6103dc565b3480156106d657600080fd5b50600154610732906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff928316602085015291169082015260600161026b565b6101f661077936600461548f565b6107ab565b34801561078a57600080fd5b5060385461024a9073ffffffffffffffffffffffffffffffffffffffff1681565b8260005a905060006107bb6123e9565b50905073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906107f757503415155b1561082e576040517ff2365b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61083c883489898989612486565b506108478282612632565b50505050505050565b8260005a905060006108606123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016108d2576040517f0eaf3c0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87603d60008282546108e4919061553d565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610956573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097a9190615555565b905061099e73ffffffffffffffffffffffffffffffffffffffff831633308c6128ff565b6109a8898261553d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a369190615555565b14610a6d576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a7b8a8a8a8a8a8a612486565b5050610a878282612632565b5050505050505050565b610a99611531565b15610ad0576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60325473ffffffffffffffffffffffffffffffffffffffff1661dead14610b23576040517f9396d15600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610b2e836129e1565b9050610b3a81836115c4565b6000818152603360209081526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558401516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905580610bc56123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff821601610c2857610c218560400151866080015187606001518860a00151612a2e565b9150610e7b565b8073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610c91576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606085015115610e52578460600151603d6000828254610cb1919061556e565b90915550506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610d23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d479190615555565b9050610d7c866040015187606001518473ffffffffffffffffffffffffffffffffffffffff16612a8c9092919063ffffffff16565b6060860151610d8b908261556e565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e199190615555565b14610e50576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60a08501515115610e7657610c218560400151866080015160008860a00151612a2e565b600191505b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405183907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90610edd90851515815260200190565b60405180910390a281158015610ef35750326001145b15610f2a576040517feeae4ed300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fa0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615585565b905090565b610fd1611531565b15611008576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603611071576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6038546040517fbb8aa1fc00000000000000000000000000000000000000000000000000000000815260048101869052600091829173ffffffffffffffffffffffffffffffffffffffff9091169063bb8aa1fc90602401606060405180830381865afa1580156110e5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110991906155a2565b925050915060008173ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561115b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117f9190615555565b603b5490915063ffffffff8481169116146111c6576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111dd6111d8368890038801886155ef565b612ae7565b8114611215576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611220896129e1565b905060018373ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112939190615684565b60028111156112a4576112a4615655565b036112db576040517fd357347400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051602081018390526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506113a49101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f010000000000000000000000000000000000000000000000000000000000000060208301529061139a898b6156a5565b8b60400135612b26565b15156000036113df576040517fb05e92fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825273ffffffffffffffffffffffffffffffffffffffff808716825267ffffffffffffffff4281166020808501918252600088815260398252868120338252825286812095518654935190941674010000000000000000000000000000000000000000027fffffffff0000000000000000000000000000000000000000000000000000000090931693851693909317919091179093558d840151928e01519351928216939091169185917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f6291a4604051339083907f798f9f13695f8f045aa5f80ed8efebb695f3c7fe65da381969f2f28bf3c60b9790600090a3506000908152603c602090815260408220805460018101825590835291200180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115a0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc49190615729565b600082815260396020908152604080832073ffffffffffffffffffffffffffffffffffffffff85811685529083528184208251808401845290549182168082527401000000000000000000000000000000000000000090920467ffffffffffffffff1681850152818552603a90935292205490919060ff1615611673576040517f09550c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816020015167ffffffffffffffff166000036116bb576040517f94efd49b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061173c8273ffffffffffffffffffffffffffffffffffffffff1663cf09e0d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172f9190615746565b67ffffffffffffffff1690565b90508067ffffffffffffffff16836020015167ffffffffffffffff1611611810576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e20646973707574652067616d65206372656160648201527f74696f6e2074696d657374616d70000000000000000000000000000000000000608482015260a4015b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000c836020015167ffffffffffffffff164261184b919061556e565b116118d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c20686173206e6f74206d6174757265642079657400000000000000000000006064820152608401611807565b60028273ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611925573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119499190615684565b600281111561195a5761195a615655565b14611991576040517fa080a3c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5463ffffffff1663ffffffff16611a1b8373ffffffffffffffffffffffffffffffffffffffff1663bbdc02db6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a129190615763565b63ffffffff1690565b63ffffffff1614611a58576040517f27a10cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b5467ffffffffffffffff64010000000090910481169082161015611b26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a20646973707574652067616d652063726560448201527f61746564206265666f7265207265737065637465642067616d6520747970652060648201527f7761732075706461746564000000000000000000000000000000000000000000608482015260a401611807565b7f0000000000000000000000000000000000000000000000000000000000000006611b958373ffffffffffffffffffffffffffffffffffffffff166319effeb46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170b573d6000803e3d6000fd5b611ba99067ffffffffffffffff164261556e565b11611c36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f696e206169722d676170000000000000000000000000000000000000000000006064820152608401611807565b60008581526033602052604090205460ff1615610f2a576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60375473ffffffffffffffffffffffffffffffffffffffff163314611cd0576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611cdc62030d40612b4a565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260ff8416604482015260648101839052608481018290526000907342000000000000000000000000000000000000159073deaddeaddeaddeaddeaddeaddeaddeaddead0001907fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32908490819062030d4090829060a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f71cfaa3f000000000000000000000000000000000000000000000000000000001790529051611df996959493929101615780565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052611e31916152fb565b60405180910390a450505050565b611e47610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611eab576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152603a602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f192c289026d59a41a27f5aea08f3969b57931b0589202d14f4368cded95d3cda9190a250565b611f2a610f31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f8e576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603b805463ffffffff83167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090911681176401000000004267ffffffffffffffff90811682029290921793849055604051930416917f049fe9dd413cdf037cce27011cc1790c753118272f3630e6e8bdfa5e8208176090600090a350565b565b612016611531565b1561204d576040517ff480973e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120578133610a91565b50565b600054610100900460ff161580801561207a5750600054600160ff909116105b806120945750303b158015612094575060005460ff166001145b612120576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611807565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561217e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603880547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8881169190911790925560378054909116868316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff16610100868416021790556032541661229e576032805461dead7fffffffffffffffffffffffff0000000000000000000000000000000000000000909116179055603b80547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166401000000004267ffffffffffffffff16027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000161763ffffffff84161790555b6122a6612bac565b8015610f2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600061231c8260106157e5565b61232890615208615815565b92915050565b603c602052816000526040600020818154811061234a57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169150829050565b60008061237e6123e9565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016123c5574791505090565b5050603d5490565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b603754604080517f4397dfef0000000000000000000000000000000000000000000000000000000081528151600093849373ffffffffffffffffffffffffffffffffffffffff90911692634397dfef92600480830193928290030181865afa158015612459573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247d9190615841565b90939092509050565b8180156124a8575073ffffffffffffffffffffffffffffffffffffffff861615155b156124df576040517f13496fda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6124e9815161230f565b67ffffffffffffffff168367ffffffffffffffff161015612536576040517f4929b80800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201d4c081511115612574576040517f73052b0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33328114612595575033731111000000000000000000000000000000001111015b600086868686866040516020016125b0959493929190615780565b604051602081830303815290604052905060008873ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161262091906152fb565b60405180910390a45050505050505050565b600154600090612668907801000000000000000000000000000000000000000000000000900467ffffffffffffffff164361556e565b90506000612674612cbf565b90506000816020015160ff16826000015163ffffffff16612695919061589f565b905082156127cc576001546000906126cc908390700100000000000000000000000000000000900467ffffffffffffffff16615907565b90506000836040015160ff16836126e3919061597b565b6001546127039084906fffffffffffffffffffffffffffffffff1661597b565b61270d919061589f565b60015490915060009061275e906127379084906fffffffffffffffffffffffffffffffff16615a37565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612d85565b9050600186111561278d5761278a61273782876040015160ff1660018a612785919061556e565b612da4565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b600180548691906010906127ff908490700100000000000000000000000000000000900467ffffffffffffffff16615815565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff16131561288c576040517f77ebef4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546000906128b8906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615aab565b905060006128ca48633b9aca00612df9565b6128d49083615ae8565b905060005a6128e3908861556e565b905080821115610a8757610a876128fa828461556e565b612e10565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526129db9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612e39565b50505050565b80516020808301516040808501516060860151608087015160a08801519351600097612a11979096959101615afc565b604051602081830303815290604052805190602001209050919050565b6000806000612a3e866000612f45565b905080612a74576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052612ae29084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612959565b505050565b60008160000151826020015183604001518460600151604051602001612a11949392919093845260208401929092526040830152606082015260800190565b600080612b3286612f63565b9050612b4081868686612f95565b9695505050505050565b6001805463ffffffff83169190601090612b83908490700100000000000000000000000000000000900467ffffffffffffffff16615815565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b600054610100900460ff16612c43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611807565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff1660000361200c5760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152603754604080517fcc731b02000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163cc731b029160048083019260c09291908290030181865afa158015612d61573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123289190615b53565b6000612d9a612d948585612fc5565b83612fd5565b90505b9392505050565b6000670de0b6b3a7640000612de5612dbc858361589f565b612dce90670de0b6b3a7640000615907565b612de085670de0b6b3a764000061597b565b612fe4565b612def908661597b565b612d9a919061589f565b600081831015612e095781612d9d565b5090919050565b6000805a90505b825a612e23908361556e565b1015612ae257612e3282615bf5565b9150612e17565b6000612e9b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130159092919063ffffffff16565b805190915015612ae25780806020019051810190612eb99190615729565b612ae2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611807565b600080603f83619c4001026040850201603f5a021015949350505050565b60608180519060200120604051602001612f7f91815260200190565b6040516020818303038152906040529050919050565b6000612fbc84612fa6878686613024565b8051602091820120825192909101919091201490565b95945050505050565b600081831215612e095781612d9d565b6000818312612e095781612d9d565b6000612d9d670de0b6b3a764000083612ffc86613aa2565b613006919061597b565b613010919061589f565b613ce6565b6060612d9a8484600085613f25565b60606000845111613091576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401611807565b600061309c846140bb565b905060006130a9866141a7565b90506000846040516020016130c091815260200190565b60405160208183030381529060405290506000805b8451811015613a195760008582815181106130f2576130f2615c2d565b60200260200101519050845183111561318d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401611807565b8260000361324657805180516020918201206040516131db926131b592910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b613241576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401611807565b61339d565b8051516020116132fc5780518051602091820120604051613270926131b592910190815260200190565b613241576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401611807565b80518451602080870191909120825191909201201461339d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401611807565b6133a96010600161553d565b81602001515103613585578451830361351d576133e381602001516010815181106133d6576133d6615c2d565b602002602001015161420a565b96506000875111613476576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401611807565b60018651613484919061556e565b8214613512576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401611807565b505050505050612d9d565b600085848151811061353157613531615c2d565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061355c5761355c615c2d565b6020026020010151905061356f816142be565b955061357c60018661553d565b94505050613a06565b60028160200151510361397e57600061359d826142e3565b90506000816000815181106135b4576135b4615c2d565b016020015160f81c905060006135cb600283615c5c565b6135d6906002615c7e565b905060006135e7848360ff16614307565b905060006135f58a89614307565b90506000613603838361433d565b905080835114613695576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401611807565b60ff8516600214806136aa575060ff85166003145b15613899578082511461373f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401611807565b61375987602001516001815181106133d6576133d6615c2d565b9c5060008d51116137ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401611807565b60018c516137fa919061556e565b8814613888576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401611807565b505050505050505050505050612d9d565b60ff851615806138ac575060ff85166001145b156138eb576138d887602001516001815181106138cb576138cb615c2d565b60200260200101516142be565b99506138e4818a61553d565b9850613973565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401611807565b505050505050613a06565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401611807565b5080613a1181615bf5565b9150506130d5565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401611807565b6000808213613b0d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b60006060613b1a846143f1565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c18213613d1757506000919050565b680755bf798b4a1bf1e58212613d89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401611807565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606082471015613fb7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611807565b73ffffffffffffffffffffffffffffffffffffffff85163b614035576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611807565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161405e9190615ca1565b60006040518083038185875af1925050503d806000811461409b576040519150601f19603f3d011682016040523d82523d6000602084013e6140a0565b606091505b50915091506140b08282866144c7565b979650505050505050565b80516060908067ffffffffffffffff8111156140d9576140d9614eb6565b60405190808252806020026020018201604052801561411e57816020015b60408051808201909152606080825260208201528152602001906001900390816140f75790505b50915060005b818110156141a057604051806040016040528085838151811061414957614149615c2d565b6020026020010151815260200161417886848151811061416b5761416b615c2d565b602002602001015161451a565b81525083828151811061418d5761418d615c2d565b6020908102919091010152600101614124565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b838110156141ff578060011b82018184015160001a8060041c8253600f8116600183015350506001016141d1565b509295945050505050565b6060600080600061421a8561452d565b91945092509050600081600181111561423557614235615655565b1461426c576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614276828461553d565b8551146142af576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fbc856020015184846149cb565b606060208260000151106142da576142d58261420a565b612328565b61232882614a5f565b606061232861430283602001516000815181106133d6576133d6615c2d565b6141a7565b6060825182106143265750604080516020810190915260008152612328565b612d9d8383848651614338919061556e565b614a75565b6000808251845110614350578251614353565b83515b90505b80821080156143da575082828151811061437257614372615c2d565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168483815181106143b1576143b1615c2d565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156143ea57816001019150614356565b5092915050565b600080821161445c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401611807565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606083156144d6575081612d9d565b8251156144e65782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180791906152fb565b606061232861452883614c4d565b614cba565b60008060008360000151600003614570576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f81116145955760006001600094509450945050506149c4565b60b781116146ab5760006145aa60808361556e565b9050808760000151116145e9576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214801561466157507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614698576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600195509350600092506149c4915050565b60bf81116148095760006146c060b78361556e565b9050808760000151116146ff576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614761576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116147a9576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147b3818461553d565b8951116147ec576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6147f783600161553d565b97509550600094506149c49350505050565b60f7811161486e57600061481e60c08361556e565b90508087600001511161485d576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001955093508492506149c4915050565b600061487b60f78361556e565b9050808760000151116148ba576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361491c576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614964576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61496e818461553d565b8951116149a7576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6149b283600161553d565b97509550600194506149c49350505050565b9193909250565b60608167ffffffffffffffff8111156149e6576149e6614eb6565b6040519080825280601f01601f191660200182016040528015614a10576020820181803683370190505b5090508115612d9d576000614a25848661553d565b90506020820160005b84811015614a46578281015182820152602001614a2e565b84811115614a55576000858301525b5050509392505050565b60606123288260200151600084600001516149cb565b60608182601f011015614ae4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b828284011015614b50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401611807565b81830184511015614bbd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401611807565b606082158015614bdc5760405191506000825260208201604052614c44565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614c15578051835260209283019201614bfd565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201528151600003614c9c576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000614cca8561452d565b919450925090506001816001811115614ce557614ce5615655565b14614d1c576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451614d28838561553d565b14614d5f576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081614d765790505093506000835b8651811015614e6457600080614de96040518060400160405280858c60000151614dcd919061556e565b8152602001858c60200151614de2919061553d565b905261452d565b509150915060405180604001604052808383614e05919061553d565b8152602001848b60200151614e1a919061553d565b815250888581518110614e2f57614e2f615c2d565b6020908102919091010152614e4560018561553d565b9350614e51818361553d565b614e5b908461553d565b92505050614da3565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461205757600080fd5b67ffffffffffffffff8116811461205757600080fd5b801515811461205757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715614f0857614f08614eb6565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614f5557614f55614eb6565b604052919050565b600082601f830112614f6e57600080fd5b813567ffffffffffffffff811115614f8857614f88614eb6565b614fb960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614f0e565b818152846020838601011115614fce57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c0878903121561500457600080fd5b863561500f81614e70565b95506020870135945060408701359350606087013561502d81614e92565b9250608087013561503d81614ea8565b915060a087013567ffffffffffffffff81111561505957600080fd5b61506589828a01614f5d565b9150509295509295509295565b600060c0828403121561508457600080fd5b60405160c0810167ffffffffffffffff82821081831117156150a8576150a8614eb6565b8160405282935084358352602085013591506150c382614e70565b816020840152604085013591506150d982614e70565b816040840152606085013560608401526080850135608084015260a085013591508082111561510757600080fd5b5061511485828601614f5d565b60a0830152505092915050565b6000806040838503121561513457600080fd5b823567ffffffffffffffff81111561514b57600080fd5b61515785828601615072565b925050602083013561516881614e70565b809150509250929050565b60006020828403121561518557600080fd5b8135612d9d81614e70565b600080600080600085870360e08112156151a957600080fd5b863567ffffffffffffffff808211156151c157600080fd5b6151cd8a838b01615072565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401121561520657600080fd5b60408901955060c089013592508083111561522057600080fd5b828901925089601f84011261523457600080fd5b823591508082111561524557600080fd5b508860208260051b840101111561525b57600080fd5b959894975092955050506020019190565b60006020828403121561527e57600080fd5b5035919050565b60005b838110156152a0578181015183820152602001615288565b838111156129db5750506000910152565b600081518084526152c9816020860160208601615285565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612d9d60208301846152b1565b6000806040838503121561532157600080fd5b82359150602083013561516881614e70565b60ff8116811461205757600080fd5b6000806000806080858703121561535857600080fd5b843561536381614e70565b9350602085013561537381615333565b93969395505050506040820135916060013590565b63ffffffff8116811461205757600080fd5b6000602082840312156153ac57600080fd5b8135612d9d81615388565b6000602082840312156153c957600080fd5b813567ffffffffffffffff8111156153e057600080fd5b6153ec84828501615072565b949350505050565b6000806000806080858703121561540a57600080fd5b843561541581614e70565b9350602085013561542581614e70565b9250604085013561543581614e70565b9150606085013561544581615388565b939692955090935050565b60006020828403121561546257600080fd5b8135612d9d81614e92565b6000806040838503121561548057600080fd5b50508035926020909101359150565b600080600080600060a086880312156154a757600080fd5b85356154b281614e70565b94506020860135935060408601356154c981614e92565b925060608601356154d981614ea8565b9150608086013567ffffffffffffffff8111156154f557600080fd5b61550188828901614f5d565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156155505761555061550e565b500190565b60006020828403121561556757600080fd5b5051919050565b6000828210156155805761558061550e565b500390565b60006020828403121561559757600080fd5b8151612d9d81614e70565b6000806000606084860312156155b757600080fd5b83516155c281615388565b60208501519093506155d381614e92565b60408501519092506155e481614e70565b809150509250925092565b60006080828403121561560157600080fd5b6040516080810181811067ffffffffffffffff8211171561562457615624614eb6565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006020828403121561569657600080fd5b815160038110612d9d57600080fd5b600067ffffffffffffffff808411156156c0576156c0614eb6565b8360051b60206156d1818301614f0e565b8681529185019181810190368411156156e957600080fd5b865b8481101561571d578035868111156157035760008081fd5b61570f36828b01614f5d565b8452509183019183016156eb565b50979650505050505050565b60006020828403121561573b57600080fd5b8151612d9d81614ea8565b60006020828403121561575857600080fd5b8151612d9d81614e92565b60006020828403121561577557600080fd5b8151612d9d81615388565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b6048820152600082516157d4816049850160208701615285565b919091016049019695505050505050565b600067ffffffffffffffff8083168185168183048111821515161561580c5761580c61550e565b02949350505050565b600067ffffffffffffffff8083168185168083038211156158385761583861550e565b01949350505050565b6000806040838503121561585457600080fd5b825161585f81614e70565b602084015190925061516881615333565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826158ae576158ae615870565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156159025761590261550e565b500590565b6000808312837f8000000000000000000000000000000000000000000000000000000000000000018312811516156159415761594161550e565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156159755761597561550e565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156159bc576159bc61550e565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156159f7576159f761550e565b60008712925087820587128484161615615a1357615a1361550e565b87850587128184161615615a2957615a2961550e565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03841381151615615a7157615a7161550e565b827f8000000000000000000000000000000000000000000000000000000000000000038412811615615aa557615aa561550e565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615ae357615ae361550e565b500290565b600082615af757615af7615870565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152615b4760c08301846152b1565b98975050505050505050565b600060c08284031215615b6557600080fd5b615b6d614ee5565b8251615b7881615388565b81526020830151615b8881615333565b60208201526040830151615b9b81615333565b60408201526060830151615bae81615388565b60608201526080830151615bc181615388565b608082015260a08301516fffffffffffffffffffffffffffffffff81168114615be957600080fd5b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615c2657615c2661550e565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff831680615c6f57615c6f615870565b8060ff84160691505092915050565b600060ff821660ff841680821015615c9857615c9861550e565b90039392505050565b60008251615cb3818460208701615285565b919091019291505056fea164736f6c634300080f000a"; bytes internal constant disputeGameFactoryCode = hex"6080604052600436106100e85760003560e01c80636593dc6e1161008a57806396cd97201161005957806396cd972014610313578063bb8aa1fc14610333578063c4d66de814610394578063f2fde38b146103b457600080fd5b80636593dc6e14610293578063715018a6146102c057806382ecf2f6146102d55780638da5cb5b146102e857600080fd5b8063254bd683116100c6578063254bd6831461019c5780634d1975b4146101c957806354fd4d50146101e85780635f0150cb1461023e57600080fd5b806314f6b1a3146100ed5780631b685b9e1461010f5780631e3342401461017c575b600080fd5b3480156100f957600080fd5b5061010d6101083660046110c6565b6103d4565b005b34801561011b57600080fd5b5061015261012a3660046110fd565b60656020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061010d610197366004611118565b61045e565b3480156101a857600080fd5b506101bc6101b7366004611142565b6104aa565b60405161017391906111ef565b3480156101d557600080fd5b506068545b604051908152602001610173565b3480156101f457600080fd5b506102316040518060400160405280600c81526020017f312e302e312d626574612e31000000000000000000000000000000000000000081525081565b60405161017391906112ac565b34801561024a57600080fd5b5061025e6102593660046112bf565b6106ee565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff909116602083015201610173565b34801561029f57600080fd5b506101da6102ae3660046110fd565b60666020526000908152604090205481565b3480156102cc57600080fd5b5061010d610741565b6101526102e33660046112bf565b610755565b3480156102f457600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff16610152565b34801561031f57600080fd5b506101da61032e3660046112bf565b6109ef565b34801561033f57600080fd5b5061035361034e366004611346565b610a28565b6040805163ffffffff909416845267ffffffffffffffff909216602084015273ffffffffffffffffffffffffffffffffffffffff1690820152606001610173565b3480156103a057600080fd5b5061010d6103af36600461135f565b610a91565b3480156103c057600080fd5b5061010d6103cf36600461135f565b610c2d565b6103dc610d00565b63ffffffff821660008181526065602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616908117909155905190917fff513d80e2c7fa487608f70a618dfbc0cf415699dc69588c747e8c71566c88de91a35050565b610466610d00565b63ffffffff8216600081815260666020526040808220849055518392917f74d6665c4b26d5596a5aa13d3014e0c06af4d322075a797f87b03cd4c5bc91ca91a35050565b606854606090831015806104bc575081155b6106e7575060408051600583901b8101602001909152825b8381116106e5576000606882815481106104f0576104f061137c565b600091825260209091200154905060e081901c60a082901c67ffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff831663ffffffff891683036106b6576001865101865260008173ffffffffffffffffffffffffffffffffffffffff1663609d33346040518163ffffffff1660e01b8152600401600060405180830381865afa15801561058a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d091908101906113da565b905060008273ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561061f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064391906114a5565b90506040518060a001604052808881526020018781526020018567ffffffffffffffff168152602001828152602001838152508860018a5161068591906114be565b815181106106955761069561137c565b6020026020010181905250888851106106b3575050505050506106e5565b50505b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191506104d49050565b505b9392505050565b60008060006106ff878787876109ef565b60009081526067602052604090205473ffffffffffffffffffffffffffffffffffffffff81169860a09190911c67ffffffffffffffff16975095505050505050565b610749610d00565b6107536000610d81565b565b63ffffffff841660009081526065602052604081205473ffffffffffffffffffffffffffffffffffffffff16806107c5576040517f031c6de400000000000000000000000000000000000000000000000000000000815263ffffffff871660048201526024015b60405180910390fd5b63ffffffff86166000908152606660205260409020543414610813576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006108206001436114be565b40905061088a338783888860405160200161083f9594939291906114fc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905273ffffffffffffffffffffffffffffffffffffffff841690610df8565b92508273ffffffffffffffffffffffffffffffffffffffff16638129fc1c346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156108d457600080fd5b505af11580156108e8573d6000803e3d6000fd5b505050505060006108fb888888886109ef565b60008181526067602052604090205490915015610947576040517f014f6fe5000000000000000000000000000000000000000000000000000000008152600481018290526024016107bc565b60004260a01b60e08a901b178517600083815260676020526040808220839055606880546001810182559083527fa2153420d844928b4421650203c77babc8b33d7f2e7b450e2966db0c220977530183905551919250899163ffffffff8c169173ffffffffffffffffffffffffffffffffffffffff8916917f5b565efe82411da98814f356d0e7bcb8f0219b8d970307c5afb4a6903a8b2e359190a450505050949350505050565b600084848484604051602001610a089493929190611549565b604051602081830303815290604052805190602001209050949350505050565b600080600080600080610a8160688881548110610a4757610a4761137c565b906000526020600020015460e081901c9160a082901c67ffffffffffffffff169173ffffffffffffffffffffffffffffffffffffffff1690565b9199909850909650945050505050565b600054610100900460ff1615808015610ab15750600054600160ff909116105b80610acb5750303b158015610acb575060005460ff166001145b610b57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107bc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610bb557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610bbd610e06565b610bc682610d81565b8015610c2957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b610c35610d00565b73ffffffffffffffffffffffffffffffffffffffff8116610cd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016107bc565b610ce181610d81565b50565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60335473ffffffffffffffffffffffffffffffffffffffff163314610753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107bc565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006106e760008484610ea5565b600054610100900460ff16610e9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b610753610feb565b600060608203516040830351602084035184518060208701018051600283016c5af43d3d93803e606057fd5bf3895289600d8a035278593da1005b363d3d373d3d3d3d610000806062363936013d738160481b1760218a03527f9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff603a8a035272fd6100003d81600a3d39f336602c57343d527f6062820160781b1761ff9e82106059018a03528060f01b8352606c8101604c8a038cf097505086610f715763301164256000526004601cfd5b905285527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08501527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa09092019190915292915050565b600054610100900460ff16611082576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b61075333610d81565b803563ffffffff8116811461109f57600080fd5b919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610ce157600080fd5b600080604083850312156110d957600080fd5b6110e28361108b565b915060208301356110f2816110a4565b809150509250929050565b60006020828403121561110f57600080fd5b6106e78261108b565b6000806040838503121561112b57600080fd5b6111348361108b565b946020939093013593505050565b60008060006060848603121561115757600080fd5b6111608461108b565b95602085013595506040909401359392505050565b60005b83811015611190578181015183820152602001611178565b8381111561119f576000848401525b50505050565b600081518084526111bd816020860160208601611175565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561129e578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001855281518051845287810151888501528681015167ffffffffffffffff16878501526060808201519085015260809081015160a09185018290529061128a818601836111a5565b968901969450505090860190600101611216565b509098975050505050505050565b6020815260006106e760208301846111a5565b600080600080606085870312156112d557600080fd5b6112de8561108b565b935060208501359250604085013567ffffffffffffffff8082111561130257600080fd5b818701915087601f83011261131657600080fd5b81358181111561132557600080fd5b88602082850101111561133757600080fd5b95989497505060200194505050565b60006020828403121561135857600080fd5b5035919050565b60006020828403121561137157600080fd5b81356106e7816110a4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156113ec57600080fd5b815167ffffffffffffffff8082111561140457600080fd5b818401915084601f83011261141857600080fd5b81518181111561142a5761142a6113ab565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611470576114706113ab565b8160405282815287602084870101111561148957600080fd5b61149a836020830160208801611175565b979650505050505050565b6000602082840312156114b757600080fd5b5051919050565b6000828210156114f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500390565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008660601b1681528460148201528360348201528183605483013760009101605401908152949350505050565b63ffffffff8516815283602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101939250505056fea164736f6c634300080f000a"; bytes internal constant delayedWETHCode = @@ -67,11 +67,11 @@ contract DeploymentSummaryFaultProofsCode { bytes internal constant preimageOracleCode = hex"6080604052600436106101d85760003560e01c80639d53a64811610102578063ddcd58de11610095578063ec5efcbc11610064578063ec5efcbc14610681578063f3f480d9146106a1578063faf37bc7146106d4578063fef2b4ed146106e757600080fd5b8063ddcd58de146105d4578063e03110e11461060c578063e159261114610641578063ea7139501461066157600080fd5b8063b5e7154c116100d1578063b5e7154c14610555578063d18534b51461056c578063da35c6641461058c578063dd24f9bf146105a157600080fd5b80639d53a6481461048e5780639d7e8769146104dd578063b2e67ba8146104fd578063b4801e611461053557600080fd5b806361238bde1161017a5780637ac54767116101495780637ac54767146103ca5780638542cf50146103ea578063882856ef146104355780638dc4be111461046e57600080fd5b806361238bde1461031e5780636551927b146103565780637051472e1461038e5780637917de1d146103aa57600080fd5b80633909af5c116101b65780633909af5c146102715780634d52b4c91461029357806352f0f3ad146102a857806354fd4d50146102c857600080fd5b8063013cf08b146101dd5780630359a5631461022e5780632055b36b1461025c575b600080fd5b3480156101e957600080fd5b506101fd6101f8366004612e29565b610714565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526020830191909152015b60405180910390f35b34801561023a57600080fd5b5061024e610249366004612e6b565b610759565b604051908152602001610225565b34801561026857600080fd5b5061024e601081565b34801561027d57600080fd5b5061029161028c366004613073565b610891565b005b34801561029f57600080fd5b5061024e610ae8565b3480156102b457600080fd5b5061024e6102c336600461315f565b610b03565b3480156102d457600080fd5b506103116040518060400160405280600c81526020017f312e312e332d626574612e32000000000000000000000000000000000000000081525081565b60405161022591906131c6565b34801561032a57600080fd5b5061024e610339366004613217565b600160209081526000928352604080842090915290825290205481565b34801561036257600080fd5b5061024e610371366004612e6b565b601560209081526000928352604080842090915290825290205481565b34801561039a57600080fd5b5061024e6703782dace9d9000081565b3480156103b657600080fd5b506102916103c536600461327b565b610bd9565b3480156103d657600080fd5b5061024e6103e5366004612e29565b6110dc565b3480156103f657600080fd5b50610425610405366004613217565b600260209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610225565b34801561044157600080fd5b50610455610450366004613317565b6110f3565b60405167ffffffffffffffff9091168152602001610225565b34801561047a57600080fd5b5061029161048936600461334a565b61114d565b34801561049a57600080fd5b5061024e6104a9366004612e6b565b73ffffffffffffffffffffffffffffffffffffffff9091166000908152601860209081526040808320938352929052205490565b3480156104e957600080fd5b506102916104f8366004613396565b611248565b34801561050957600080fd5b5061024e610518366004612e6b565b601760209081526000928352604080842090915290825290205481565b34801561054157600080fd5b5061024e610550366004613317565b6113ff565b34801561056157600080fd5b5061024e620186a081565b34801561057857600080fd5b50610291610587366004613073565b611431565b34801561059857600080fd5b5060135461024e565b3480156105ad57600080fd5b507f000000000000000000000000000000000000000000000000000000000000271061024e565b3480156105e057600080fd5b5061024e6105ef366004612e6b565b601660209081526000928352604080842090915290825290205481565b34801561061857600080fd5b5061062c610627366004613217565b611840565b60408051928352602083019190915201610225565b34801561064d57600080fd5b5061029161065c36600461334a565b611931565b34801561066d57600080fd5b5061029161067c366004613422565b611a39565b34801561068d57600080fd5b5061029161069c366004613491565b611b98565b3480156106ad57600080fd5b507f000000000000000000000000000000000000000000000000000000000000007861024e565b6102916106e2366004613519565b611d1e565b3480156106f357600080fd5b5061024e610702366004612e29565b60006020819052908152604090205481565b6013818154811061072457600080fd5b60009182526020909120600290910201805460019091015473ffffffffffffffffffffffffffffffffffffffff909116915082565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601560209081526040808320848452909152812054819061079c9060601c63ffffffff1690565b63ffffffff16905060005b6010811015610889578160011660010361082f5773ffffffffffffffffffffffffffffffffffffffff85166000908152601460209081526040808320878452909152902081601081106107fc576107fc613555565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250610870565b826003826010811061084357610843613555565b01546040805160208101939093528201526060016040516020818303038152906040528051906020012092505b60019190911c9080610881816135b3565b9150506107a7565b505092915050565b600061089d8a8a610759565b90506108c086868360208b01356108bb6108b68d6135eb565b611fea565b61202a565b80156108de57506108de83838360208801356108bb6108b68a6135eb565b610914576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b86604001358860405160200161092a91906136ba565b6040516020818303038152906040528051906020012014610977576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83602001358760200135600161098d91906136f8565b146109c4576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a0c886109d28680613710565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061208b92505050565b610a15886121e6565b836040013588604051602001610a2b91906136ba565b6040516020818303038152906040528051906020012003610a78576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8a1660009081526015602090815260408083208c8452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055610adc8a8a3361298e565b50505050505050505050565b6001610af660106002613897565b610b0091906138a3565b81565b6000610b0f8686612a47565b9050610b1c8360086136f8565b82101580610b2a5750602083115b15610b61576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b60608115610bf257610beb8686612af4565b9050610c2c565b85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050505b3360009081526014602090815260408083208b845290915280822081516102008101928390529160109082845b815481526020019060010190808311610c5957505050505090506000601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b81526020019081526020016000205490506000610cda8260601c63ffffffff1690565b63ffffffff169050333214610d1b576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d2b8260801c63ffffffff1690565b63ffffffff16600003610d6a576040517f87138d5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d748260c01c90565b67ffffffffffffffff1615610db5576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b898114610dee576040517f60f95d5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610dfb89898d8886612b6d565b83516020850160888204881415608883061715610e20576307b1daf16000526004601cfd5b60405160c8810160405260005b83811015610ed0578083018051835260208101516020840152604081015160408401526060810151606084015260808101516080840152508460888301526088810460051b8b013560a883015260c882206001860195508560005b610200811015610ec5576001821615610ea55782818b0152610ec5565b8981015160009081526020938452604090209260019290921c9101610e88565b505050608801610e2d565b50505050600160106002610ee49190613897565b610eee91906138a3565b811115610f27576040517f6229572300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f9c610f3a8360401c63ffffffff1690565b610f4a9063ffffffff168a6136f8565b60401b7fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff606084901b167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff8516171790565b915084156110295777ffffffffffffffffffffffffffffffffffffffffffffffff82164260c01b179150610fd68260801c63ffffffff1690565b63ffffffff16610fec8360401c63ffffffff1690565b63ffffffff1614611029576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526014602090815260408083208e8452909152902061104f90846010612d9f565b503360008181526018602090815260408083208f8452825280832080546001810182559084528284206004820401805460039092166008026101000a67ffffffffffffffff818102199093164390931602919091179055838352601582528083208f8452909152812084905560609190911b81523690601437366014016000a05050505050505050505050565b600381601081106110ec57600080fd5b0154905081565b6018602052826000526040600020602052816000526040600020818154811061111b57600080fd5b906000526020600020906004918282040191900660080292509250509054906101000a900467ffffffffffffffff1681565b60443560008060088301861061116b5763fe2549876000526004601cfd5b60c083901b60805260888386823786600882030151915060206000858360025afa90508061119857600080fd5b50600080517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0400000000000000000000000000000000000000000000000000000000000000178082526002602090815260408084208a8552825280842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558385528252808420998452988152888320939093558152908190529490942055505050565b600080603087600037602060006030600060025afa806112705763f91129696000526004601cfd5b6000517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f010000000000000000000000000000000000000000000000000000000000000017608081815260a08c905260c08b905260308a60e037603088609083013760008060c083600a5afa9250826112f2576309bde3396000526004601cfd5b602886106113085763fe2549876000526004601cfd5b6000602882015278200000000000000000000000000000000000000000000000008152600881018b905285810151935060308a8237603081019b909b52505060509098207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0500000000000000000000000000000000000000000000000000000000000000176000818152600260209081526040808320868452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209583529481528482209a909a559081528089529190912096909655505050505050565b6014602052826000526040600020602052816000526040600020816010811061142757600080fd5b0154925083915050565b73ffffffffffffffffffffffffffffffffffffffff891660009081526015602090815260408083208b845290915290205467ffffffffffffffff8116156114a4576040517fc334f06900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114ae8160c01c90565b67ffffffffffffffff166000036114f1576040517f55d4cbf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000007861151c8260c01c90565b6115309067ffffffffffffffff16426138a3565b11611567576040517f55d4cbf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006115738b8b610759565b905061158c87878360208c01356108bb6108b68e6135eb565b80156115aa57506115aa84848360208901356108bb6108b68b6135eb565b6115e0576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8760400135896040516020016115f691906136ba565b6040516020818303038152906040528051906020012014611643576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84602001358860200135600161165991906136f8565b14158061168b575060016116738360601c63ffffffff1690565b61167d91906138ba565b63ffffffff16856020013514155b156116c2576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116d0896109d28780613710565b6116d9896121e6565b60006116e48a612cc0565b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0200000000000000000000000000000000000000000000000000000000000000179050600061173b8460a01c63ffffffff1690565b67ffffffffffffffff169050600160026000848152602001908152602001600020600083815260200190815260200160002060006101000a81548160ff021916908315150217905550601760008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008d8152602001908152602001600020546001600084815260200190815260200160002060008381526020019081526020016000208190555061180d8460801c63ffffffff1690565b600083815260208190526040902063ffffffff9190911690556118318d8d8161298e565b50505050505050505050505050565b6000828152600260209081526040808320848452909152812054819060ff166118c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546118e58160086136f8565b6118f08560206136f8565b1061190e57836119018260086136f8565b61190b91906138a3565b91505b506000938452600160209081526040808620948652939052919092205492909150565b60443560008060088301861061194f5763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b60008060008060808860601b81528760c01b6014820152858782601c0137601c860181207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0600000000000000000000000000000000000000000000000000000000000000179350604088026260216001603f5a021015611ac35763dd629f866000526004601cfd5b6000808783601c018c5afa94503d6001019150600882018a10611aee5763fe2549876000526004601cfd5b60c082901b81526008018481533d6000600183013e89017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8015160008481526002602090815260408083208d8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915587845282528083209c83529b81528b8220929092559384528390529790912096909655505050505050565b6000611ba48686610759565b9050611bbd83838360208801356108bb6108b68a6135eb565b611bf3576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602084013515611c2f576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c37612ddd565b611c45816109d28780613710565b611c4e816121e6565b846040013581604051602001611c6491906136ba565b6040516020818303038152906040528051906020012003611cb1576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166000908152601560209081526040808320898452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055611d1587873361298e565b50505050505050565b6703782dace9d90000341015611d60576040517fe92c469f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333214611d99576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611da48160086138df565b63ffffffff168263ffffffff1610611de8576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000027108163ffffffff161015611e48576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152601560209081526040808320868452909152902054611e738160801c63ffffffff1690565b63ffffffff1615611eb0576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608082901b7fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff60a085901b167fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff83161717336000818152601560209081526040808320898452825280832094909455835180850185528381528082018981526013805460018101825590855291517f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a090600290930292830180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055517f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0919091015591815260168252828120968152959052909320349055505050565b600081600001518260200151836040015160405160200161200d93929190613907565b604051602081830303815290604052805190602001209050919050565b60008160005b601081101561207e578060051b880135600186831c16600181146120635760008481526020839052604090209350612074565b600082815260208590526040902093505b5050600101612030565b5090931495945050505050565b608881511461209957600080fd5b602081016020830161211a565b8260031b8201518060001a8160011a60081b178160021a60101b8260031a60181b17178160041a60201b8260051a60281b178260061a60301b8360071a60381b1717179050612114816120ff868560059190911b015190565b1867ffffffffffffffff16600586901b840152565b50505050565b612126600083836120a6565b612132600183836120a6565b61213e600283836120a6565b61214a600383836120a6565b612156600483836120a6565b612162600583836120a6565b61216e600683836120a6565b61217a600783836120a6565b612186600883836120a6565b612192600983836120a6565b61219e600a83836120a6565b6121aa600b83836120a6565b6121b6600c83836120a6565b6121c2600d83836120a6565b6121ce600e83836120a6565b6121da600f83836120a6565b612114601083836120a6565b6040805178010000000000008082800000000000808a8000000080008000602082015279808b00000000800000018000000080008081800000000000800991810191909152788a00000000000000880000000080008009000000008000000a60608201527b8000808b800000000000008b8000000000008089800000000000800360808201527f80000000000080028000000000000080000000000000800a800000008000000a60a08201527f800000008000808180000000000080800000000080000001800000008000800860c082015260009060e0016040516020818303038152906040529050602082016020820161286e565b6102808101516101e082015161014083015160a0840151845118189118186102a082015161020083015161016084015160c0850151602086015118189118186102c083015161022084015161018085015160e0860151604087015118189118186102e08401516102408501516101a0860151610100870151606088015118189118186103008501516102608601516101c0870151610120880151608089015118189118188084603f1c6123998660011b67ffffffffffffffff1690565b18188584603f1c6123b48660011b67ffffffffffffffff1690565b18188584603f1c6123cf8660011b67ffffffffffffffff1690565b181895508483603f1c6123ec8560011b67ffffffffffffffff1690565b181894508387603f1c6124098960011b67ffffffffffffffff1690565b60208b01518b51861867ffffffffffffffff168c5291189190911897508118600181901b603f9190911c18935060c08801518118601481901c602c9190911b1867ffffffffffffffff1660208901526101208801518718602c81901c60149190911b1867ffffffffffffffff1660c08901526102c08801518618600381901c603d9190911b1867ffffffffffffffff166101208901526101c08801518718601981901c60279190911b1867ffffffffffffffff166102c08901526102808801518218602e81901c60129190911b1867ffffffffffffffff166101c089015260408801518618600281901c603e9190911b1867ffffffffffffffff166102808901526101808801518618601581901c602b9190911b1867ffffffffffffffff1660408901526101a08801518518602781901c60199190911b1867ffffffffffffffff166101808901526102608801518718603881901c60089190911b1867ffffffffffffffff166101a08901526102e08801518518600881901c60389190911b1867ffffffffffffffff166102608901526101e08801518218601781901c60299190911b1867ffffffffffffffff166102e089015260808801518718602581901c601b9190911b1867ffffffffffffffff166101e08901526103008801518718603281901c600e9190911b1867ffffffffffffffff1660808901526102a08801518118603e81901c60029190911b1867ffffffffffffffff166103008901526101008801518518600981901c60379190911b1867ffffffffffffffff166102a08901526102008801518118601381901c602d9190911b1867ffffffffffffffff1661010089015260a08801518218601c81901c60249190911b1867ffffffffffffffff1661020089015260608801518518602481901c601c9190911b1867ffffffffffffffff1660a08901526102408801518518602b81901c60159190911b1867ffffffffffffffff1660608901526102208801518618603181901c600f9190911b1867ffffffffffffffff166102408901526101608801518118603681901c600a9190911b1867ffffffffffffffff166102208901525060e08701518518603a81901c60069190911b1867ffffffffffffffff166101608801526101408701518118603d81901c60039190911b1867ffffffffffffffff1660e0880152505067ffffffffffffffff81166101408601525b5050505050565b600582811b8201805160018501831b8401805160028701851b8601805160038901871b8801805160048b0190981b8901805167ffffffffffffffff861985168918811690995283198a16861889169096528819861683188816909352841986168818871690528419831684189095169052919391929190611d15565b612808600082612781565b612813600582612781565b61281e600a82612781565b612829600f82612781565b612834601482612781565b50565b612840816122dc565b612849816127fd565b600383901b820151815160c09190911c9061211490821867ffffffffffffffff168352565b61287a60008284612837565b61288660018284612837565b61289260028284612837565b61289e60038284612837565b6128aa60048284612837565b6128b660058284612837565b6128c260068284612837565b6128ce60078284612837565b6128da60088284612837565b6128e660098284612837565b6128f2600a8284612837565b6128fe600b8284612837565b61290a600c8284612837565b612916600d8284612837565b612922600e8284612837565b61292e600f8284612837565b61293a60108284612837565b61294660118284612837565b61295260128284612837565b61295e60138284612837565b61296a60148284612837565b61297660158284612837565b61298260168284612837565b61211460178284612837565b73ffffffffffffffffffffffffffffffffffffffff83811660009081526016602090815260408083208684529091528082208054908390559051909284169083908381818185875af1925050503d8060008114612a07576040519150601f19603f3d011682016040523d82523d6000602084013e612a0c565b606091505b505090508061277a576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831617612aed818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b6060604051905081602082018181018286833760888306808015612b3d5760888290038501848101848103803687375060806001820353506001845160001a1784538652612b54565b608836843760018353608060878401536088850186525b5050505050601f19603f82510116810160405292915050565b6000612b7f8260a01c63ffffffff1690565b67ffffffffffffffff1690506000612b9d8360801c63ffffffff1690565b63ffffffff1690506000612bb78460401c63ffffffff1690565b63ffffffff169050600883108015612bcd575080155b15612c015760c082901b6000908152883560085283513382526017602090815260408084208a855290915290912055612cb6565b60088310158015612c1f575080612c196008856138a3565b93508310155b8015612c335750612c3087826136f8565b83105b15612cb6576000612c4482856138a3565b905087612c528260206136f8565b10158015612c5e575085155b15612c95576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526017602090815260408083208a845290915290209089013590555b5050505050505050565b6000612d43565b66ff00ff00ff00ff8160081c1667ff00ff00ff00ff00612cf18360081b67ffffffffffffffff1690565b1617905065ffff0000ffff8160101c1667ffff0000ffff0000612d1e8360101b67ffffffffffffffff1690565b1617905060008160201c612d3c8360201b67ffffffffffffffff1690565b1792915050565b60808201516020830190612d5b90612cc7565b612cc7565b6040820151612d6990612cc7565b60401b17612d81612d5660018460059190911b015190565b825160809190911b90612d9390612cc7565b60c01b17179392505050565b8260108101928215612dcd579160200282015b82811115612dcd578251825591602001919060010190612db2565b50612dd9929150612df5565b5090565b6040518060200160405280612df0612e0a565b905290565b5b80821115612dd95760008155600101612df6565b6040518061032001604052806019906020820280368337509192915050565b600060208284031215612e3b57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612e6657600080fd5b919050565b60008060408385031215612e7e57600080fd5b612e8783612e42565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610320810167ffffffffffffffff81118282101715612ee857612ee8612e95565b60405290565b6040516060810167ffffffffffffffff81118282101715612ee857612ee8612e95565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612f5857612f58612e95565b604052919050565b803567ffffffffffffffff81168114612e6657600080fd5b6000610320808385031215612f8c57600080fd5b604051602080820182811067ffffffffffffffff82111715612fb057612fb0612e95565b806040525081935085601f860112612fc757600080fd5b612fcf612ec4565b928501928087851115612fe157600080fd5b865b8581101561300157612ff481612f60565b8352918301918301612fe3565b509092525091949350505050565b60006060828403121561302157600080fd5b50919050565b60008083601f84011261303957600080fd5b50813567ffffffffffffffff81111561305157600080fd5b6020830191508360208260051b850101111561306c57600080fd5b9250929050565b60008060008060008060008060006103e08a8c03121561309257600080fd5b61309b8a612e42565b985060208a013597506130b18b60408c01612f78565b96506103608a013567ffffffffffffffff808211156130cf57600080fd5b6130db8d838e0161300f565b97506103808c01359150808211156130f257600080fd5b6130fe8d838e01613027565b90975095506103a08c013591508082111561311857600080fd5b6131248d838e0161300f565b94506103c08c013591508082111561313b57600080fd5b506131488c828d01613027565b915080935050809150509295985092959850929598565b600080600080600060a0868803121561317757600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60005b838110156131b557818101518382015260200161319d565b838111156121145750506000910152565b60208152600082518060208401526131e581604085016020870161319a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000806040838503121561322a57600080fd5b50508035926020909101359150565b60008083601f84011261324b57600080fd5b50813567ffffffffffffffff81111561326357600080fd5b60208301915083602082850101111561306c57600080fd5b600080600080600080600060a0888a03121561329657600080fd5b8735965060208801359550604088013567ffffffffffffffff808211156132bc57600080fd5b6132c88b838c01613239565b909750955060608a01359150808211156132e157600080fd5b506132ee8a828b01613027565b9094509250506080880135801515811461330757600080fd5b8091505092959891949750929550565b60008060006060848603121561332c57600080fd5b61333584612e42565b95602085013595506040909401359392505050565b60008060006040848603121561335f57600080fd5b83359250602084013567ffffffffffffffff81111561337d57600080fd5b61338986828701613239565b9497909650939450505050565b600080600080600080600060a0888a0312156133b157600080fd5b8735965060208801359550604088013567ffffffffffffffff808211156133d757600080fd5b6133e38b838c01613239565b909750955060608a01359150808211156133fc57600080fd5b506134098a828b01613239565b989b979a50959894979596608090950135949350505050565b60008060008060006080868803121561343a57600080fd5b8535945061344a60208701612e42565b935061345860408701612f60565b9250606086013567ffffffffffffffff81111561347457600080fd5b61348088828901613239565b969995985093965092949392505050565b6000806000806000608086880312156134a957600080fd5b6134b286612e42565b945060208601359350604086013567ffffffffffffffff808211156134d657600080fd5b6134e289838a0161300f565b945060608801359150808211156134f857600080fd5b5061348088828901613027565b803563ffffffff81168114612e6657600080fd5b60008060006060848603121561352e57600080fd5b8335925061353e60208501613505565b915061354c60408501613505565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135e4576135e4613584565b5060010190565b6000606082360312156135fd57600080fd5b613605612eee565b823567ffffffffffffffff8082111561361d57600080fd5b9084019036601f83011261363057600080fd5b813560208282111561364457613644612e95565b613674817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011601612f11565b9250818352368183860101111561368a57600080fd5b81818501828501376000918301810191909152908352848101359083015250604092830135928101929092525090565b81516103208201908260005b60198110156136ef57825167ffffffffffffffff168252602092830192909101906001016136c6565b50505092915050565b6000821982111561370b5761370b613584565b500190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261374557600080fd5b83018035915067ffffffffffffffff82111561376057600080fd5b60200191503681900382131561306c57600080fd5b600181815b808511156137ce57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156137b4576137b4613584565b808516156137c157918102915b93841c939080029061377a565b509250929050565b6000826137e557506001613891565b816137f257506000613891565b816001811461380857600281146138125761382e565b6001915050613891565b60ff84111561382357613823613584565b50506001821b613891565b5060208310610133831016604e8410600b8410161715613851575081810a613891565b61385b8383613775565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561388d5761388d613584565b0290505b92915050565b6000612aed83836137d6565b6000828210156138b5576138b5613584565b500390565b600063ffffffff838116908316818110156138d7576138d7613584565b039392505050565b600063ffffffff8083168185168083038211156138fe576138fe613584565b01949350505050565b6000845161391981846020890161319a565b9190910192835250602082015260400191905056fea164736f6c634300080f000a"; bytes internal constant mipsCode = - hex"608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d50146100465780637dc0d1d014610098578063e14ced32146100dc575b600080fd5b6100826040518060400160405280600c81526020017f312e312e312d626574612e32000000000000000000000000000000000000000081525081565b60405161008f91906121ee565b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007a9eab4ce99d157aee7a02e95b366e972a2d5b0b16815260200161008f565b6100ef6100ea3660046122a3565b6100fd565b60405190815260200161008f565b6000610107612164565b6080811461011457600080fd5b6040516106001461012457600080fd5b6084871461013157600080fd5b6101a4851461013f57600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a0819052605a89013590911c6101c05260628801906101e09060018111156101f5576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b506020810181511461020657600080fd5b60200160005b602081101561023057823560e01c825260049092019160209091019060010161020c565b5050508061012001511561024e576102466103a6565b91505061039d565b6101408101805160010167ffffffffffffffff16905260006101a49050600080600061028385606001518660000151866104f7565b9250925092508163ffffffff1660001480156102a557508063ffffffff16600c145b156102bf576102b387610521565b9550505050505061039d565b6000610339866040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b6101608701518751919250610356918391906105248888886108f9565b8652805163ffffffff9081166060808901919091526020830151821660808901526040830151821660a08901528201511660c08701526103946103a6565b96505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a8401526000926102009290916062830191906001811115610453576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b60005b602081101561047a57601c8601518452602090950194600490930192600101610456565b506000835283830384a060009450806001811461049a57600395506104c2565b8280156104b257600181146104bb57600296506104c0565b600096506104c0565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b6000806000610507858786610cdf565b925050603f601a83901c8116915082165b93509350939050565b600061052b612164565b608090506000806000806105628561016001516040810151608082015160a083015160c084015160e0909401519294919390929091565b509350935093509350600080610ffa63ffffffff168663ffffffff16036105a75761059285858960e00151610d93565b63ffffffff1660e08a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03363ffffffff8716016105e05763400000009150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefe863ffffffff8716016106165760019150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef6a63ffffffff87160161066a57600161012088015260ff851661010088015261065d6103a6565b9998505050505050505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05d63ffffffff8716016107665760006040518061012001604052808763ffffffff1681526020018663ffffffff1681526020018563ffffffff16815260200189602001518152602001896040015163ffffffff1681526020018b81526020017f0000000000000000000000007a9eab4ce99d157aee7a02e95b366e972a2d5b0b73ffffffffffffffffffffffffffffffffffffffff1681526020016107386101a4600160ff16610380020190565b81528951602090910152905061074d81610e27565b8b5263ffffffff1660408b015290935091506108089050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05c63ffffffff8716016107cb57602087015160408801516107b1918791879187916105248d5161109f565b63ffffffff1660408b015260208a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff02963ffffffff871601610808576108028585611195565b90925090505b6000610882886040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b61016089015163ffffffff85811660408084019190915285821660e0909301929092526020830180518083168086526004909101831682526060808e01919091529051821660808d015291830151811660a08c0152908201511660c08a015290506108eb6103a6565b9a9950505050505050505050565b84600263ffffffff8416148061091557508263ffffffff166003145b156109675760006002856303ffffff1663ffffffff16901b896020015163f00000001617905061096189898663ffffffff1660021461095557601f610958565b60005b60ff168461124a565b50610cd4565b600080601f601087901c8116908a90601589901c166020811061098c5761098c612317565b602002015192508063ffffffff871615806109ad57508663ffffffff16601c145b156109df578a8263ffffffff16602081106109ca576109ca612317565b6020020151925050601f600b88901c16610a96565b60208763ffffffff161015610a41578663ffffffff16600c1480610a0957508663ffffffff16600d145b80610a1a57508663ffffffff16600e145b15610a2b578761ffff169250610a96565b610a3a8861ffff166010611322565b9250610a96565b60288763ffffffff16101580610a5d57508663ffffffff166022145b80610a6e57508663ffffffff166026145b15610a96578a8263ffffffff1660208110610a8b57610a8b612317565b602002015192508190505b60048763ffffffff1610158015610ab3575060088763ffffffff16105b80610ac457508663ffffffff166001145b15610ae057610ad78c8c898b8689611395565b50505050610cd4565b63ffffffff6000602089831610610b4557610b008a61ffff166010611322565b9095019463fffffffc8616610b168d828e610cdf565b915060288a63ffffffff1610158015610b3657508963ffffffff16603014155b15610b4357809250600093505b505b6000610b558b8b8b8a8a87611583565b63ffffffff1690508963ffffffff166000148015610b7a575060088963ffffffff1610155b8015610b8c5750601c8963ffffffff16105b15610c54578863ffffffff1660081480610bac57508863ffffffff166009145b15610bdf57610bd38f8f8b63ffffffff16600814610bca5786610bcd565b60005b8a61124a565b50505050505050610cd4565b8863ffffffff16600a03610c0157610bd38f8f868a63ffffffff8b1615611ca0565b8863ffffffff16600b03610c2457610bd38f8f868a63ffffffff8b161515611ca0565b60108963ffffffff1610158015610c415750601c8963ffffffff16105b15610c5457610bd38f8f8b8a8a89611d70565b8963ffffffff166038148015610c6f575063ffffffff851615155b15610c9f5760018e8663ffffffff1660208110610c8e57610c8e612317565b63ffffffff90921660209290920201525b8263ffffffff1663ffffffff14610cbe57610cbb838d83612029565b97505b610ccc8f8f86846001611ca0565b505050505050505b979650505050505050565b6000610cea826120cb565b6003831615610cf857600080fd5b6020820191358360051c8160005b601b811015610d5e5760208601953583821c6001168015610d2e5760018114610d4357610d54565b60008481526020839052604090209350610d54565b600082815260208590526040902093505b5050600101610d06565b50868114610d7457630badf00d60005260206000fd5b5050601f93909316601c0360031b9290921c63ffffffff169392505050565b6000808284610fff811615610dad57610fff811661100003015b8663ffffffff16600003610e195784935090810190636000000063ffffffff83161180610de557508463ffffffff168263ffffffff16105b80610dfb57508563ffffffff168163ffffffff16105b15610e14575063ffffffff925060169150839050610518565b610e1d565b8693505b5093509350939050565b6101008101516080820151825160009283929163ffffffff161561109857845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb01611052576000610e93866101000151876020015163fffffffc168860e00151610cdf565b606087015190915060001a600103610f1557610f0f86606001518760a0015160408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b60608701525b6000808760c0015173ffffffffffffffffffffffffffffffffffffffff1663e03110e189606001518a608001516040518363ffffffff1660e01b8152600401610f6e92919091825263ffffffff16602082015260400190565b6040805180830381865afa158015610f8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fae9190612346565b60208a015160408b01519294509092509060038216600481900384811015610fd4578094505b5083821015610fe1578193505b8460088502610100031c9450846008828660040303021b9450600180600883600403021b036001806008878560040303021b0391508119811690508581198816179650505061103f8a6020015163fffffffc168b60e0015187612029565b9298505050938601939250611098915050565b845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0161108c5784604001519350611098565b63ffffffff9350600992505b9193509193565b600080858563ffffffff8b16600114806110bf575063ffffffff8b166002145b806110d0575063ffffffff8b166004145b156110dd57889350611187565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8c160161117b57600061111d868c63fffffffc1689610cdf565b90508860038c166004038b81101561113357809b505b8b965086900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193880293841b0116911b17915060009050611187565b63ffffffff9350600992505b975097509750979350505050565b60008063ffffffff83166003036112385763ffffffff841615806111bf575063ffffffff84166005145b806111d0575063ffffffff84166003145b156111de5760009150611243565b63ffffffff8416600114806111f9575063ffffffff84166002145b8061120a575063ffffffff84166006145b8061121b575063ffffffff84166004145b156112295760019150611243565b5063ffffffff90506009611243565b5063ffffffff905060165b9250929050565b836000015160040163ffffffff16846020015163ffffffff16146112cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b835160208501805163ffffffff908116875283811690915283161561131b5780600801848463ffffffff166020811061130a5761130a612317565b63ffffffff90921660209290920201525b5050505050565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b018261137f576000611381565b815b90861663ffffffff16179250505092915050565b6000866000015160040163ffffffff16876020015163ffffffff1614611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f7400000000000000000000000060448201526064016112c6565b8463ffffffff166004148061143257508463ffffffff166005145b156114a9576000868463ffffffff166020811061145157611451612317565b602002015190508063ffffffff168363ffffffff1614801561147957508563ffffffff166004145b806114a157508063ffffffff168363ffffffff16141580156114a157508563ffffffff166005145b915050611526565b8463ffffffff166006036114c65760008260030b13159050611526565b8463ffffffff166007036114e25760008260030b139050611526565b8463ffffffff1660010361152657601f601085901c16600081900361150b5760008360030b1291505b8063ffffffff166001036115245760008360030b121591505b505b8651602088015163ffffffff168852811561156757600261154c8661ffff166010611322565b63ffffffff90811690911b8201600401166020890152611579565b60208801805160040163ffffffff1690525b5050505050505050565b600063ffffffff861615806115b0575060088663ffffffff16101580156115b05750600f8663ffffffff16105b156119b05785600881146115f357600981146115fc57600a811461160557600b811461160e57600c811461161757600d811461162057600e81146116295761162e565b6020955061162e565b6021955061162e565b602a955061162e565b602b955061162e565b6024955061162e565b6025955061162e565b602695505b508463ffffffff16600003611653575063ffffffff8216601f600688901c161b611c96565b8463ffffffff16600203611677575063ffffffff8216601f600688901c161c611c96565b8463ffffffff166003036116ab57601f600688901c166116a363ffffffff8516821c6020839003611322565b915050611c96565b8463ffffffff166004036116cb575063ffffffff8216601f84161b611c96565b8463ffffffff166006036116eb575063ffffffff8216601f84161c611c96565b8463ffffffff1660070361171357601f84166116a363ffffffff8516821c6020839003611322565b8463ffffffff16600803611728575082611c96565b8463ffffffff1660090361173d575082611c96565b8463ffffffff16600a03611752575082611c96565b8463ffffffff16600b03611767575082611c96565b8463ffffffff16600c0361177c575082611c96565b8463ffffffff16600f03611791575082611c96565b8463ffffffff166010036117a6575082611c96565b8463ffffffff166011036117bb575082611c96565b8463ffffffff166012036117d0575082611c96565b8463ffffffff166013036117e5575082611c96565b8463ffffffff166018036117fa575082611c96565b8463ffffffff1660190361180f575082611c96565b8463ffffffff16601a03611824575082611c96565b8463ffffffff16601b03611839575082611c96565b8463ffffffff166020036118505750828201611c96565b8463ffffffff166021036118675750828201611c96565b8463ffffffff1660220361187e5750818303611c96565b8463ffffffff166023036118955750818303611c96565b8463ffffffff166024036118ac5750828216611c96565b8463ffffffff166025036118c35750828217611c96565b8463ffffffff166026036118da5750828218611c96565b8463ffffffff166027036118f2575082821719611c96565b8463ffffffff16602a03611921578260030b8460030b12611914576000611917565b60015b60ff169050611c96565b8463ffffffff16602b03611949578263ffffffff168463ffffffff1610611914576000611917565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e0000000000000000000000000060448201526064016112c6565b611949565b8563ffffffff16601c03611a30578463ffffffff166002036119d55750828202611c96565b8463ffffffff16602014806119f057508463ffffffff166021145b156119ab578463ffffffff16602003611a07579219925b60005b6380000000851615611a29576401fffffffe600195861b169401611a0a565b9050611c96565b8563ffffffff16600f03611a51575065ffffffff0000601083901b16611c96565b8563ffffffff16602003611a8557611a298460031660080260180363ffffffff168363ffffffff16901c60ff166008611322565b8563ffffffff16602103611aba57611a298460021660080260100363ffffffff168363ffffffff16901c61ffff166010611322565b8563ffffffff16602203611ae8575063ffffffff60086003851602811681811b198416918316901b17611c96565b8563ffffffff16602303611afd575080611c96565b8563ffffffff16602403611b2e578360031660080260180363ffffffff168263ffffffff16901c60ff169050611c96565b8563ffffffff16602503611b60578360021660080260100363ffffffff168263ffffffff16901c61ffff169050611c96565b8563ffffffff16602603611b91575063ffffffff60086003851602601803811681811c198416918316901c17611c96565b8563ffffffff16602803611bc6575060ff63ffffffff60086003861602601803811682811b9091188316918416901b17611c96565b8563ffffffff16602903611bfc575061ffff63ffffffff60086002861602601003811682811b9091188316918416901b17611c96565b8563ffffffff16602a03611c2a575063ffffffff60086003851602811681811c198316918416901c17611c96565b8563ffffffff16602b03611c3f575081611c96565b8563ffffffff16602e03611c70575063ffffffff60086003851602601803811681811b198316918416901b17611c96565b8563ffffffff16603003611c85575080611c96565b8563ffffffff166038036119495750815b9695505050505050565b60208363ffffffff1610611d10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c696420726567697374657200000000000000000000000000000000000060448201526064016112c6565b63ffffffff831615801590611d225750805b15611d515781848463ffffffff1660208110611d4057611d40612317565b63ffffffff90921660209290920201525b5050505060208101805163ffffffff8082169093526004019091169052565b60008463ffffffff16601003611d8b57506060860151611fd1565b8463ffffffff16601103611daa5763ffffffff84166060880152611fd1565b8463ffffffff16601203611dc357506040860151611fd1565b8463ffffffff16601303611de25763ffffffff84166040880152611fd1565b8463ffffffff16601803611e165763ffffffff600385810b9085900b02602081901c821660608a0152166040880152611fd1565b8463ffffffff16601903611e475763ffffffff84811681851602602081901c821660608a0152166040880152611fd1565b8463ffffffff16601a03611f0a578260030b600003611ec2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8260030b8460030b81611ed757611ed761236a565b0763ffffffff166060880152600383810b9085900b81611ef957611ef961236a565b0563ffffffff166040880152611fd1565b8463ffffffff16601b03611fd1578263ffffffff16600003611f88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f0000000000000000000060448201526064016112c6565b8263ffffffff168463ffffffff1681611fa357611fa361236a565b0663ffffffff908116606089015283811690851681611fc457611fc461236a565b0463ffffffff1660408801525b63ffffffff8216156120075780868363ffffffff1660208110611ff657611ff6612317565b63ffffffff90921660209290920201525b50505060208401805163ffffffff808216909652600401909416909352505050565b6000612034836120cb565b600384161561204257600080fd5b6020830192601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b8110156120c05760208601953582821c600116801561209057600181146120a5576120b6565b600085815260208390526040902094506120b6565b600082815260208690526040902094505b5050600101612068565b509095945050505050565b366103808201811015612160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f617461000000000000000000000000000000000000000000000000000000000060648201526084016112c6565b5050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915261016081016121ca6121cf565b905290565b6040518061040001604052806020906020820280368337509192915050565b600060208083528351808285015260005b8181101561221b578581018301518582016040015282016121ff565b8181111561222d576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60008083601f84011261227357600080fd5b50813567ffffffffffffffff81111561228b57600080fd5b60208301915083602082850101111561124357600080fd5b6000806000806000606086880312156122bb57600080fd5b853567ffffffffffffffff808211156122d357600080fd5b6122df89838a01612261565b909750955060208801359150808211156122f857600080fd5b5061230588828901612261565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561235957600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a"; + hex"608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d50146100465780637dc0d1d014610098578063e14ced32146100dc575b600080fd5b6100826040518060400160405280600c81526020017f312e312e312d626574612e33000000000000000000000000000000000000000081525081565b60405161008f9190612237565b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007a9eab4ce99d157aee7a02e95b366e972a2d5b0b16815260200161008f565b6100ef6100ea3660046122ec565b6100fd565b60405190815260200161008f565b60006101076121ad565b6080811461011457600080fd5b6040516106001461012457600080fd5b6084871461013157600080fd5b6101a4851461013f57600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a0819052605a89013590911c6101c05260628801906101e09060018111156101f5576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b506020810181511461020657600080fd5b60200160005b602081101561023057823560e01c825260049092019160209091019060010161020c565b5050508061012001511561024e576102466103a6565b91505061039d565b6101408101805160010167ffffffffffffffff16905260006101a49050600080600061028385606001518660000151866104f7565b9250925092508163ffffffff1660001480156102a557508063ffffffff16600c145b156102bf576102b387610521565b9550505050505061039d565b6000610339866040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b6101608701518751919250610356918391906105248888886108f9565b8652805163ffffffff9081166060808901919091526020830151821660808901526040830151821660a08901528201511660c08701526103946103a6565b96505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a8401526000926102009290916062830191906001811115610453576040517f0136cc76000000000000000000000000000000000000000000000000000000008152600481fd5b60005b602081101561047a57601c8601518452602090950194600490930192600101610456565b506000835283830384a060009450806001811461049a57600395506104c2565b8280156104b257600181146104bb57600296506104c0565b600096506104c0565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b6000806000610507858786610cdf565b925050603f601a83901c8116915082165b93509350939050565b600061052b6121ad565b608090506000806000806105628561016001516040810151608082015160a083015160c084015160e0909401519294919390929091565b509350935093509350600080610ffa63ffffffff168663ffffffff16036105a75761059285858960e00151610d31565b63ffffffff1660e08a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03363ffffffff8716016105e05763400000009150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefe863ffffffff8716016106165760019150610808565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef6a63ffffffff87160161066a57600161012088015260ff851661010088015261065d6103a6565b9998505050505050505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05d63ffffffff8716016107665760006040518061012001604052808763ffffffff1681526020018663ffffffff1681526020018563ffffffff16815260200189602001518152602001896040015163ffffffff1681526020018b81526020017f0000000000000000000000007a9eab4ce99d157aee7a02e95b366e972a2d5b0b73ffffffffffffffffffffffffffffffffffffffff1681526020016107386101a4600160ff16610380020190565b81528951602090910152905061074d81610dc5565b8b5263ffffffff1660408b015290935091506108089050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05c63ffffffff8716016107cb57602087015160408801516107b1918791879187916105248d5161103d565b63ffffffff1660408b015260208a01529092509050610808565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff02963ffffffff871601610808576108028585611133565b90925090505b6000610882886040805160808101825260008082526020820181905291810182905260608101919091526040518060800160405280836060015163ffffffff168152602001836080015163ffffffff1681526020018360a0015163ffffffff1681526020018360c0015163ffffffff168152509050919050565b61016089015163ffffffff85811660408084019190915285821660e0909301929092526020830180518083168086526004909101831682526060808e01919091529051821660808d015291830151811660a08c0152908201511660c08a015290506108eb6103a6565b9a9950505050505050505050565b84600263ffffffff8416148061091557508263ffffffff166003145b156109675760006002856303ffffff1663ffffffff16901b896020015163f00000001617905061096189898663ffffffff1660021461095557601f610958565b60005b60ff16846111e8565b50610cd4565b600080601f601087901c8116908a90601589901c166020811061098c5761098c612360565b602002015192508063ffffffff871615806109ad57508663ffffffff16601c145b156109df578a8263ffffffff16602081106109ca576109ca612360565b6020020151925050601f600b88901c16610a96565b60208763ffffffff161015610a41578663ffffffff16600c1480610a0957508663ffffffff16600d145b80610a1a57508663ffffffff16600e145b15610a2b578761ffff169250610a96565b610a3a8861ffff1660106112c0565b9250610a96565b60288763ffffffff16101580610a5d57508663ffffffff166022145b80610a6e57508663ffffffff166026145b15610a96578a8263ffffffff1660208110610a8b57610a8b612360565b602002015192508190505b60048763ffffffff1610158015610ab3575060088763ffffffff16105b80610ac457508663ffffffff166001145b15610ae057610ad78c8c898b8689611333565b50505050610cd4565b63ffffffff6000602089831610610b4557610b008a61ffff1660106112c0565b9095019463fffffffc8616610b168d828e610cdf565b915060288a63ffffffff1610158015610b3657508963ffffffff16603014155b15610b4357809250600093505b505b6000610b558b8b8b8a8a87611521565b63ffffffff1690508963ffffffff166000148015610b7a575060088963ffffffff1610155b8015610b8c5750601c8963ffffffff16105b15610c54578863ffffffff1660081480610bac57508863ffffffff166009145b15610bdf57610bd38f8f8b63ffffffff16600814610bca5786610bcd565b60005b8a6111e8565b50505050505050610cd4565b8863ffffffff16600a03610c0157610bd38f8f868a63ffffffff8b1615611c3e565b8863ffffffff16600b03610c2457610bd38f8f868a63ffffffff8b161515611c3e565b60108963ffffffff1610158015610c415750601c8963ffffffff16105b15610c5457610bd38f8f8b8a8a89611d0e565b8963ffffffff166038148015610c6f575063ffffffff851615155b15610c9f5760018e8663ffffffff1660208110610c8e57610c8e612360565b63ffffffff90921660209290920201525b8263ffffffff1663ffffffff14610cbe57610cbb838d83611fc7565b97505b610ccc8f8f86846001611c3e565b505050505050505b979650505050505050565b600080610ced858585612069565b909250905080610d29576040517f8e77b2b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b509392505050565b6000808284610fff811615610d4b57610fff811661100003015b8663ffffffff16600003610db75784935090810190636000000063ffffffff83161180610d8357508463ffffffff168263ffffffff16105b80610d9957508563ffffffff168163ffffffff16105b15610db2575063ffffffff925060169150839050610518565b610dbb565b8693505b5093509350939050565b6101008101516080820151825160009283929163ffffffff161561103657845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb01610ff0576000610e31866101000151876020015163fffffffc168860e00151610cdf565b606087015190915060001a600103610eb357610ead86606001518760a0015160408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b60608701525b6000808760c0015173ffffffffffffffffffffffffffffffffffffffff1663e03110e189606001518a608001516040518363ffffffff1660e01b8152600401610f0c92919091825263ffffffff16602082015260400190565b6040805180830381865afa158015610f28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4c919061238f565b60208a015160408b01519294509092509060038216600481900384811015610f72578094505b5083821015610f7f578193505b8460088502610100031c9450846008828660040303021b9450600180600883600403021b036001806008878560040303021b03915081198116905085811988161796505050610fdd8a6020015163fffffffc168b60e0015187611fc7565b9298505050938601939250611036915050565b845163ffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0161102a5784604001519350611036565b63ffffffff9350600992505b9193509193565b600080858563ffffffff8b166001148061105d575063ffffffff8b166002145b8061106e575063ffffffff8b166004145b1561107b57889350611125565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8c16016111195760006110bb868c63fffffffc1689610cdf565b90508860038c166004038b8110156110d157809b505b8b965086900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193880293841b0116911b17915060009050611125565b63ffffffff9350600992505b975097509750979350505050565b60008063ffffffff83166003036111d65763ffffffff8416158061115d575063ffffffff84166005145b8061116e575063ffffffff84166003145b1561117c57600091506111e1565b63ffffffff841660011480611197575063ffffffff84166002145b806111a8575063ffffffff84166006145b806111b9575063ffffffff84166004145b156111c757600191506111e1565b5063ffffffff905060096111e1565b5063ffffffff905060165b9250929050565b836000015160040163ffffffff16846020015163ffffffff161461126d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b835160208501805163ffffffff90811687528381169091528316156112b95780600801848463ffffffff16602081106112a8576112a8612360565b63ffffffff90921660209290920201525b5050505050565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b018261131d57600061131f565b815b90861663ffffffff16179250505092915050565b6000866000015160040163ffffffff16876020015163ffffffff16146113b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f740000000000000000000000006044820152606401611264565b8463ffffffff16600414806113d057508463ffffffff166005145b15611447576000868463ffffffff16602081106113ef576113ef612360565b602002015190508063ffffffff168363ffffffff1614801561141757508563ffffffff166004145b8061143f57508063ffffffff168363ffffffff161415801561143f57508563ffffffff166005145b9150506114c4565b8463ffffffff166006036114645760008260030b131590506114c4565b8463ffffffff166007036114805760008260030b1390506114c4565b8463ffffffff166001036114c457601f601085901c1660008190036114a95760008360030b1291505b8063ffffffff166001036114c25760008360030b121591505b505b8651602088015163ffffffff16885281156115055760026114ea8661ffff1660106112c0565b63ffffffff90811690911b8201600401166020890152611517565b60208801805160040163ffffffff1690525b5050505050505050565b600063ffffffff8616158061154e575060088663ffffffff161015801561154e5750600f8663ffffffff16105b1561194e578560088114611591576009811461159a57600a81146115a357600b81146115ac57600c81146115b557600d81146115be57600e81146115c7576115cc565b602095506115cc565b602195506115cc565b602a95506115cc565b602b95506115cc565b602495506115cc565b602595506115cc565b602695505b508463ffffffff166000036115f1575063ffffffff8216601f600688901c161b611c34565b8463ffffffff16600203611615575063ffffffff8216601f600688901c161c611c34565b8463ffffffff1660030361164957601f600688901c1661164163ffffffff8516821c60208390036112c0565b915050611c34565b8463ffffffff16600403611669575063ffffffff8216601f84161b611c34565b8463ffffffff16600603611689575063ffffffff8216601f84161c611c34565b8463ffffffff166007036116b157601f841661164163ffffffff8516821c60208390036112c0565b8463ffffffff166008036116c6575082611c34565b8463ffffffff166009036116db575082611c34565b8463ffffffff16600a036116f0575082611c34565b8463ffffffff16600b03611705575082611c34565b8463ffffffff16600c0361171a575082611c34565b8463ffffffff16600f0361172f575082611c34565b8463ffffffff16601003611744575082611c34565b8463ffffffff16601103611759575082611c34565b8463ffffffff1660120361176e575082611c34565b8463ffffffff16601303611783575082611c34565b8463ffffffff16601803611798575082611c34565b8463ffffffff166019036117ad575082611c34565b8463ffffffff16601a036117c2575082611c34565b8463ffffffff16601b036117d7575082611c34565b8463ffffffff166020036117ee5750828201611c34565b8463ffffffff166021036118055750828201611c34565b8463ffffffff1660220361181c5750818303611c34565b8463ffffffff166023036118335750818303611c34565b8463ffffffff1660240361184a5750828216611c34565b8463ffffffff166025036118615750828217611c34565b8463ffffffff166026036118785750828218611c34565b8463ffffffff16602703611890575082821719611c34565b8463ffffffff16602a036118bf578260030b8460030b126118b25760006118b5565b60015b60ff169050611c34565b8463ffffffff16602b036118e7578263ffffffff168463ffffffff16106118b25760006118b5565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e000000000000000000000000006044820152606401611264565b6118e7565b8563ffffffff16601c036119ce578463ffffffff166002036119735750828202611c34565b8463ffffffff166020148061198e57508463ffffffff166021145b15611949578463ffffffff166020036119a5579219925b60005b63800000008516156119c7576401fffffffe600195861b1694016119a8565b9050611c34565b8563ffffffff16600f036119ef575065ffffffff0000601083901b16611c34565b8563ffffffff16602003611a23576119c78460031660080260180363ffffffff168363ffffffff16901c60ff1660086112c0565b8563ffffffff16602103611a58576119c78460021660080260100363ffffffff168363ffffffff16901c61ffff1660106112c0565b8563ffffffff16602203611a86575063ffffffff60086003851602811681811b198416918316901b17611c34565b8563ffffffff16602303611a9b575080611c34565b8563ffffffff16602403611acc578360031660080260180363ffffffff168263ffffffff16901c60ff169050611c34565b8563ffffffff16602503611afe578360021660080260100363ffffffff168263ffffffff16901c61ffff169050611c34565b8563ffffffff16602603611b2f575063ffffffff60086003851602601803811681811c198416918316901c17611c34565b8563ffffffff16602803611b64575060ff63ffffffff60086003861602601803811682811b9091188316918416901b17611c34565b8563ffffffff16602903611b9a575061ffff63ffffffff60086002861602601003811682811b9091188316918416901b17611c34565b8563ffffffff16602a03611bc8575063ffffffff60086003851602811681811c198316918416901c17611c34565b8563ffffffff16602b03611bdd575081611c34565b8563ffffffff16602e03611c0e575063ffffffff60086003851602601803811681811b198316918416901b17611c34565b8563ffffffff16603003611c23575080611c34565b8563ffffffff166038036118e75750815b9695505050505050565b60208363ffffffff1610611cae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c69642072656769737465720000000000000000000000000000000000006044820152606401611264565b63ffffffff831615801590611cc05750805b15611cef5781848463ffffffff1660208110611cde57611cde612360565b63ffffffff90921660209290920201525b5050505060208101805163ffffffff8082169093526004019091169052565b60008463ffffffff16601003611d2957506060860151611f6f565b8463ffffffff16601103611d485763ffffffff84166060880152611f6f565b8463ffffffff16601203611d6157506040860151611f6f565b8463ffffffff16601303611d805763ffffffff84166040880152611f6f565b8463ffffffff16601803611db45763ffffffff600385810b9085900b02602081901c821660608a0152166040880152611f6f565b8463ffffffff16601903611de55763ffffffff84811681851602602081901c821660608a0152166040880152611f6f565b8463ffffffff16601a03611ea8578260030b600003611e60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f000000000000000000006044820152606401611264565b8260030b8460030b81611e7557611e756123b3565b0763ffffffff166060880152600383810b9085900b81611e9757611e976123b3565b0563ffffffff166040880152611f6f565b8463ffffffff16601b03611f6f578263ffffffff16600003611f26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d4950533a206469766973696f6e206279207a65726f000000000000000000006044820152606401611264565b8263ffffffff168463ffffffff1681611f4157611f416123b3565b0663ffffffff908116606089015283811690851681611f6257611f626123b3565b0463ffffffff1660408801525b63ffffffff821615611fa55780868363ffffffff1660208110611f9457611f94612360565b63ffffffff90921660209290920201525b50505060208401805163ffffffff808216909652600401909416909352505050565b6000611fd283612114565b6003841615611fe057600080fd5b6020830192601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b81101561205e5760208601953582821c600116801561202e576001811461204357612054565b60008581526020839052604090209450612054565b600082815260208690526040902094505b5050600101612006565b509095945050505050565b60008061207583612114565b600384161561208357600080fd5b6020830192358460051c8160005b601b8110156120e95760208701963583821c60011680156120b957600181146120ce576120df565b600084815260208390526040902093506120df565b600082815260208590526040902093505b5050600101612091565b508714925050811561210b57601f8516601c0360031b81901c63ffffffff1692505b50935093915050565b3661038082018110156121a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f61746100000000000000000000000000000000000000000000000000000000006064820152608401611264565b5050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101612213612218565b905290565b6040518061040001604052806020906020820280368337509192915050565b600060208083528351808285015260005b8181101561226457858101830151858201604001528201612248565b81811115612276576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60008083601f8401126122bc57600080fd5b50813567ffffffffffffffff8111156122d457600080fd5b6020830191508360208285010111156111e157600080fd5b60008060008060006060868803121561230457600080fd5b853567ffffffffffffffff8082111561231c57600080fd5b61232889838a016122aa565b9097509550602088013591508082111561234157600080fd5b5061234e888289016122aa565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080604083850312156123a257600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a"; bytes internal constant anchorStateRegistryCode = hex"608060405234801561001057600080fd5b506004361061007d5760003560e01c80635e05fbd01161005b5780635e05fbd01461012a5780637258a8071461013d578063838c2d1e14610179578063f2b4e6171461018157600080fd5b806317cf21a91461008257806335e80ab31461009757806354fd4d50146100e1575b600080fd5b610095610090366004610b4c565b6101a7565b005b6002546100b79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61011d6040518060400160405280600c81526020017f322e302e312d626574612e32000000000000000000000000000000000000000081525081565b6040516100d89190610bea565b610095610138366004610cc6565b61061c565b61016461014b366004610df0565b6001602081905260009182526040909120805491015482565b604080519283526020830191909152016100d8565b610095610853565b7f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d6100b7565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610214573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102389190610e0d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461029c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156102ec573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526103329190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161039793929190610efb565b6040805180830381865afa1580156103b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d79190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043f576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561048c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b09190610f9f565b60028111156104c1576104c1610f70565b146104f8576040517f8f8af25f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806105788773ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610551573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105759190610fc0565b90565b81526020018673ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ec9190610fc0565b905263ffffffff909416600090815260016020818152604090922086518155959091015194019390935550505050565b600054610100900460ff161580801561063c5750600054600160ff909116105b806106565750303b158015610656575060005460ff166001145b6106e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561074457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60005b83518110156107aa57600084828151811061076457610764610fd9565b60209081029190910181015180820151905163ffffffff1660009081526001808452604090912082518155919092015191015550806107a281611008565b915050610747565b50600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055801561084e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600033905060008060008373ffffffffffffffffffffffffffffffffffffffff1663fa24f7436040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108a8573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526108ee9190810190610e2a565b92509250925060007f0000000000000000000000005207cfa0166e8de0fcdfd78b4d17b68587be306d73ffffffffffffffffffffffffffffffffffffffff16635f0150cb8585856040518463ffffffff1660e01b815260040161095393929190610efb565b6040805180830381865afa15801561096f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109939190610f29565b5090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109fb576040517f6b0f689100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160008563ffffffff1663ffffffff168152602001908152602001600020600101548573ffffffffffffffffffffffffffffffffffffffff16638b85902b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8d9190610fc0565b11610a99575050505050565b60028573ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ae6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0a9190610f9f565b6002811115610b1b57610b1b610f70565b146104f8575050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4957600080fd5b50565b600060208284031215610b5e57600080fd5b8135610b6981610b27565b9392505050565b60005b83811015610b8b578181015183820152602001610b73565b83811115610b9a576000848401525b50505050565b60008151808452610bb8816020860160208601610b70565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610b696020830184610ba0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610c4f57610c4f610bfd565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610c9c57610c9c610bfd565b604052919050565b63ffffffff81168114610b4957600080fd5b8035610cc181610b27565b919050565b6000806040808486031215610cda57600080fd5b833567ffffffffffffffff80821115610cf257600080fd5b818601915086601f830112610d0657600080fd5b8135602082821115610d1a57610d1a610bfd565b610d28818360051b01610c55565b8281528181019350606092830285018201928a841115610d4757600080fd5b948201945b83861015610dd457858b0381811215610d655760008081fd5b610d6d610c2c565b8735610d7881610ca4565b81527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201891315610daa5760008081fd5b610db2610c2c565b8886013581528989013586820152818601528652509485019493820193610d4c565b509650610de2888201610cb6565b955050505050509250929050565b600060208284031215610e0257600080fd5b8135610b6981610ca4565b600060208284031215610e1f57600080fd5b8151610b6981610b27565b600080600060608486031215610e3f57600080fd5b8351610e4a81610ca4565b60208501516040860151919450925067ffffffffffffffff80821115610e6f57600080fd5b818601915086601f830112610e8357600080fd5b815181811115610e9557610e95610bfd565b610ec660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610c55565b9150808252876020828501011115610edd57600080fd5b610eee816020840160208601610b70565b5080925050509250925092565b63ffffffff84168152826020820152606060408201526000610f206060830184610ba0565b95945050505050565b60008060408385031215610f3c57600080fd5b8251610f4781610b27565b602084015190925067ffffffffffffffff81168114610f6557600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060208284031215610fb157600080fd5b815160038110610b6957600080fd5b600060208284031215610fd257600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611060577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea164736f6c634300080f000a"; bytes internal constant acc33Code = - hex"6080604052600436106102f25760003560e01c806370872aa51161018f578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b18578063fa315aa914610b3c578063fe2bbeb214610b6f57600080fd5b8063ec5e630814610a95578063eff0f59214610ac8578063f8f43ff614610af857600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a0f578063d8cc1a3c14610a42578063dabd396d14610a6257600080fd5b8063c6f0308c14610937578063cf09e0d0146109c1578063d5d44d80146109e257600080fd5b80638d450a9511610143578063bcef3b551161011d578063bcef3b55146108b7578063bd8da956146108f7578063c395e1ca1461091757600080fd5b80638d450a9514610777578063a445ece6146107aa578063bbdc02db1461087657600080fd5b80638129fc1c116101745780638129fc1c1461071a5780638980e0cc146107225780638b85902b1461073757600080fd5b806370872aa5146106f25780637b0f0adc1461070757600080fd5b80633fc8cef3116102485780635c0cba33116101fc5780636361506d116101d65780636361506d1461066c5780636b6716c0146106ac5780636f034409146106df57600080fd5b80635c0cba3314610604578063609d33341461063757806360e274641461064c57600080fd5b806354fd4d501161022d57806354fd4d501461055e57806357da950e146105b45780635a5fa2d9146105e457600080fd5b80633fc8cef314610518578063472777c61461054b57600080fd5b80632810e1d6116102aa57806337b1b2291161028457806337b1b229146104655780633a768463146104a55780633e3ac912146104d857600080fd5b80632810e1d6146103de5780632ad69aeb146103f357806330dbe5701461041357600080fd5b806319effeb4116102db57806319effeb414610339578063200d2ed21461038457806325fc2ace146103bf57600080fd5b806301935130146102f757806303c2924d14610319575b600080fd5b34801561030357600080fd5b506103176103123660046154e2565b610b9f565b005b34801561032557600080fd5b5061031761033436600461553d565b610ec0565b34801561034557600080fd5b506000546103669068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561039057600080fd5b506000546103b290700100000000000000000000000000000000900460ff1681565b60405161037b919061558e565b3480156103cb57600080fd5b506008545b60405190815260200161037b565b3480156103ea57600080fd5b506103b2611566565b3480156103ff57600080fd5b506103d061040e36600461553d565b61180b565b34801561041f57600080fd5b506001546104409073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161037b565b34801561047157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610440565b3480156104b157600080fd5b507f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f738610440565b3480156104e457600080fd5b50600054610508907201000000000000000000000000000000000000900460ff1681565b604051901515815260200161037b565b34801561052457600080fd5b507f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92610440565b6103176105593660046155cf565b611841565b34801561056a57600080fd5b506105a76040518060400160405280600c81526020017f312e332e312d626574612e32000000000000000000000000000000000000000081525081565b60405161037b9190615666565b3480156105c057600080fd5b506008546009546105cf919082565b6040805192835260208301919091520161037b565b3480156105f057600080fd5b506103d06105ff366004615679565b611853565b34801561061057600080fd5b507f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e610440565b34801561064357600080fd5b506105a761188d565b34801561065857600080fd5b506103176106673660046156b7565b61189b565b34801561067857600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103d0565b3480156106b857600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610366565b6103176106ed3660046156e9565b611a42565b3480156106fe57600080fd5b506009546103d0565b6103176107153660046155cf565b61251b565b610317612528565b34801561072e57600080fd5b506002546103d0565b34801561074357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103d0565b34801561078357600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103d0565b3480156107b657600080fd5b506108226107c5366004615679565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff16606082015260800161037b565b34801561088257600080fd5b5060405163ffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260200161037b565b3480156108c357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103d0565b34801561090357600080fd5b50610366610912366004615679565b612a81565b34801561092357600080fd5b506103d0610932366004615728565b612c60565b34801561094357600080fd5b50610957610952366004615679565b612e43565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e00161037b565b3480156109cd57600080fd5b506000546103669067ffffffffffffffff1681565b3480156109ee57600080fd5b506103d06109fd3660046156b7565b60036020526000908152604090205481565b348015610a1b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000003856103d0565b348015610a4e57600080fd5b50610317610a5d36600461575a565b612eda565b348015610a6e57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b0610366565b348015610aa157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000046103d0565b348015610ad457600080fd5b50610508610ae3366004615679565b60046020526000908152604090205460ff1681565b348015610b0457600080fd5b50610317610b133660046155cf565b613509565b348015610b2457600080fd5b50610b2d6139c6565b60405161037b939291906157e4565b348015610b4857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000086103d0565b348015610b7b57600080fd5b50610508610b8a366004615679565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610bcb57610bcb61555f565b14610c02576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610c55576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610ca3610c9e36869003860186615838565b613a41565b14610cda576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610cef9291906158c5565b604051809103902014610d2e576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d77610d7284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613a9d92505050565b613b0a565b90506000610d9e82600881518110610d9157610d916158d5565b6020026020010151613cc0565b9050602081511115610ddc576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610e51576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610eec57610eec61555f565b14610f23576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610f3857610f386158d5565b906000526020600020906005020190506000610f5384612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b081169082161015610fbc576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611005576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561102257508515155b156110bd578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110555781611071565b600186015473ffffffffffffffffffffffffffffffffffffffff165b905061107d8187613d74565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff166060830152611160576fffffffffffffffffffffffffffffffff6040820152600181526000869003611160578195505b600086826020015163ffffffff166111789190615933565b90506000838211611189578161118b565b835b602084015190915063ffffffff165b818110156112d75760008682815481106111b6576111b66158d5565b6000918252602080832090910154808352600690915260409091205490915060ff1661120e576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611223576112236158d5565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112805750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b156112c257600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b505080806112cf9061594b565b91505061119a565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921790915584900361155b57606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558915801561145757506000547201000000000000000000000000000000000000900460ff165b156114cc5760015473ffffffffffffffffffffffffffffffffffffffff1661147f818a613d74565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff909116178855611559565b61151373ffffffffffffffffffffffffffffffffffffffff8216156114f1578161150d565b600189015473ffffffffffffffffffffffffffffffffffffffff165b89613d74565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff1660028111156115945761159461555f565b146115cb576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff1661162f576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008154811061165b5761165b6158d5565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611696576001611699565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff9091161770010000000000000000000000000000000083600281111561174a5761174a61555f565b02179055600281111561175f5761175f61555f565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e73ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156117f057600080fd5b505af1158015611804573d6000803e3d6000fd5b5050505090565b6005602052816000526040600020818154811061182757600080fd5b90600052602060002001600091509150505481565b905090565b61184e8383836001611a42565b505050565b6000818152600760209081526040808320600590925282208054825461188490610100900463ffffffff1682615983565b95945050505050565b606061183c60546020613e75565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260036020526040812080549082905590819003611900576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169063f3fef3a390604401600060405180830381600087803b15801561199057600080fd5b505af11580156119a4573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a02576040519150601f19603f3d011682016040523d82523d6000602084013e611a07565b606091505b505090508061184e576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008054700100000000000000000000000000000000900460ff166002811115611a6e57611a6e61555f565b14611aa5576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110611aba57611aba6158d5565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514611ba1576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000611c61826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580611c9c5750611c997f00000000000000000000000000000000000000000000000000000000000000046002615933565b81145b8015611ca6575084155b15611cdd576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015611d03575086155b15611d3a576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000008811115611d94576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dbf7f00000000000000000000000000000000000000000000000000000000000000046001615933565b8103611dd157611dd186888588613ec7565b34611ddb83612c60565b14611e12576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611e1d88612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b0811690821603611e85576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611eb260017f0000000000000000000000000000000000000000000000000000000000000008615983565b8303611ff0577f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f47919061599a565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb591906159b7565b611fe9907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166159d0565b9050612083565b61201b60017f0000000000000000000000000000000000000000000000000000000000000004615983565b830361205657611fe97f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1660026159fc565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b6120b7817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b67ffffffffffffffff166120d28367ffffffffffffffff1690565b67ffffffffffffffff16111561211957612116817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615612197576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c8152602001908152602001600020600160028054905061242d9190615983565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169263d0e30db09234926004808301939282900301818588803b1580156124c557600080fd5b505af11580156124d9573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b61184e8383836000611a42565b60005471010000000000000000000000000000000000900460ff161561257a576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e1690637258a807906024016040805180830381865afa15801561262e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126529190615a55565b90925090508161268e576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a146126c157639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401351161275b576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd929092169363d0e30db093926004828101939282900301818588803b158015612a3057600080fd5b505af1158015612a44573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b600080600054700100000000000000000000000000000000900460ff166002811115612aaf57612aaf61555f565b14612ae6576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110612afb57612afb6158d5565b600091825260208220600590910201805490925063ffffffff90811614612b6a57815460028054909163ffffffff16908110612b3957612b396158d5565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090612ba290700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b612bb69067ffffffffffffffff1642615983565b612bd5612b95846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16612be99190615933565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b01667ffffffffffffffff168167ffffffffffffffff1611612c365780611884565b7f00000000000000000000000000000000000000000000000000000000000004b095945050505050565b600080612cff836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000008811115612d5e576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000612d798383615aa8565b9050670de0b6b3a76400006000612db0827f0000000000000000000000000000000000000000000000000000000000000008615abc565b90506000612dce612dc9670de0b6b3a764000086615abc565b614078565b90506000612ddc84846142d3565b90506000612dea8383614322565b90506000612df782614350565b90506000612e1682612e11670de0b6b3a76400008f615abc565b614538565b90506000612e248b83614322565b9050612e30818d615abc565b9f9e505050505050505050505050505050565b60028181548110612e5357600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b60008054700100000000000000000000000000000000900460ff166002811115612f0657612f0661555f565b14612f3d576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028781548110612f5257612f526158d5565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b9050612fb17f00000000000000000000000000000000000000000000000000000000000000086001615933565b61304d826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1614613087576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561317e576130da7f00000000000000000000000000000000000000000000000000000000000000047f0000000000000000000000000000000000000000000000000000000000000008615983565b6001901b6130f9846fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff166131159190615af9565b156131525761314961313a60016fffffffffffffffffffffffffffffffff8716615b0d565b865463ffffffff166000614608565b60030154613174565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506131a8565b600385015491506131a561313a6fffffffffffffffffffffffffffffffff86166001615b36565b90505b600882901b60088a8a6040516131bf9291906158c5565b6040518091039020901b14613200576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061320b8c6146ec565b9050600061321a836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff169063e14ced3290613294908f908f908f908f908a90600401615baa565b6020604051808303816000875af11580156132b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d791906159b7565b600485015491149150600090600290613382906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b61341e896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6134289190615be4565b6134329190615c07565b60ff161590508115158103613473576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156134ca576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff1660028111156135355761353561555f565b1461356c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061357b8661471b565b9350935093509350600061359185858585614b24565b905060007f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015613600573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613624919061599a565b90506001890361371c5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a84613680367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af11580156136f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061371691906159b7565b5061155b565b600289036137485773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8489613680565b600389036137745773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8487613680565b600489036138fb5760006137ba6fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000004614bde565b6009546137c79190615933565b6137d2906001615933565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061383b57367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036054013561383d565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156138d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f491906159b7565b505061155b565b60058903613994576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000038560c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016136d3565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060613a1f61188d565b9050909192565b600081831015613a365781613a38565b825b90505b92915050565b60008160000151826020015183604001518460600151604051602001613a80949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003613aec576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000613b1a85614c8c565b919450925090506001816001811115613b3557613b3561555f565b14613b6c576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451613b788385615933565b14613baf576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081613bc65790505093506000835b8651811015613cb457600080613c396040518060400160405280858c60000151613c1d9190615983565b8152602001858c60200151613c329190615933565b9052614c8c565b509150915060405180604001604052808383613c559190615933565b8152602001848b60200151613c6a9190615933565b815250888581518110613c7f57613c7f6158d5565b6020908102919091010152613c95600185615933565b9350613ca18183615933565b613cab9084615933565b92505050613bf3565b50845250919392505050565b60606000806000613cd085614c8c565b919450925090506000816001811115613ceb57613ceb61555f565b14613d22576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613d2c8284615933565b855114613d65576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118848560200151848461512a565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff90931692839290613dc3908490615933565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd921690637eee288d90604401600060405180830381600087803b158015613e5857600080fd5b505af1158015613e6c573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b6000613ee66fffffffffffffffffffffffffffffffff84166001615b36565b90506000613ef682866001614608565b9050600086901a8380613fe25750613f2f60027f0000000000000000000000000000000000000000000000000000000000000004615af9565b6004830154600290613fd3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b613fdd9190615c07565b60ff16145b1561403a5760ff811660011480613ffc575060ff81166002145b614035576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b613e6c565b60ff811615613e6c576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b17600082136140d757631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a76400000215820261431057637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b6000816000190483118202156143405763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d7821361437e57919050565b680755bf798b4a1bf1e5821261439c5763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000613a38670de0b6b3a76400008361455086614078565b61455a9190615c29565b6145649190615ce5565b614350565b6000806145f6837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826146515761464c6fffffffffffffffffffffffffffffffff86167f00000000000000000000000000000000000000000000000000000000000000046151bf565b61466c565b61466c856fffffffffffffffffffffffffffffffff1661534b565b905060028481548110614681576146816158d5565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff8281169116146146e457815460028054909163ffffffff169081106146cf576146cf6158d5565b90600052602060002090600502019150614692565b509392505050565b60008060008060006146fd8661471b565b935093509350935061471184848484614b24565b9695505050505050565b600080600080600085905060006002828154811061473b5761473b6158d5565b600091825260209091206004600590920201908101549091507f000000000000000000000000000000000000000000000000000000000000000490614812906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff161161484c576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f000000000000000000000000000000000000000000000000000000000000000490614913906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16925082111561498857825463ffffffff166149527f00000000000000000000000000000000000000000000000000000000000000046001615933565b830361495c578391505b6002818154811061496f5761496f6158d5565b9060005260206000209060050201935080945050614850565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149f16149dc856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff161490508015614ac0576000614a29836fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff161115614a94576000614a6b614a6360016fffffffffffffffffffffffffffffffff8616615b0d565b896001614608565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a50614a9a9050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614b16565b6000614ae2614a636fffffffffffffffffffffffffffffffff85166001615b36565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614b915760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611884565b8282604051602001614bbf9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614c6b847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614ccf576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614cf4576000600160009450945094505050615123565b60b78111614e0a576000614d09608083615983565b905080876000015111614d48576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614dc057507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614df7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060019550935060009250615123915050565b60bf8111614f68576000614e1f60b783615983565b905080876000015111614e5e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614ec0576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614f08576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f128184615933565b895111614f4b576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f56836001615933565b97509550600094506151239350505050565b60f78111614fcd576000614f7d60c083615983565b905080876000015111614fbc576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600195509350849250615123915050565b6000614fda60f783615983565b905080876000015111615019576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361507b576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116150c3576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6150cd8184615933565b895111615106576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615111836001615933565b97509550600194506151239350505050565b9193909250565b60608167ffffffffffffffff81111561514557615145615809565b6040519080825280601f01601f19166020018201604052801561516f576020820181803683370190505b50905081156151b85760006151848486615933565b90506020820160005b848110156151a557828101518282015260200161518d565b848111156151b4576000858301525b5050505b9392505050565b60008161525e846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116152745763b34b5c226000526004601cfd5b61527d8361534b565b90508161531c826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611613a3b57613a38615332836001615933565b6fffffffffffffffffffffffffffffffff8316906153f0565b600081196001830116816153df827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b60008061547d847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f8401126154ab57600080fd5b50813567ffffffffffffffff8111156154c357600080fd5b6020830191508360208285010111156154db57600080fd5b9250929050565b600080600083850360a08112156154f857600080fd5b608081121561550657600080fd5b50839250608084013567ffffffffffffffff81111561552457600080fd5b61553086828701615499565b9497909650939450505050565b6000806040838503121561555057600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106155c9577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806000606084860312156155e457600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561562157602081850181015186830182015201615605565b81811115615633576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000613a3860208301846155fb565b60006020828403121561568b57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146156b457600080fd5b50565b6000602082840312156156c957600080fd5b81356151b881615692565b803580151581146156e457600080fd5b919050565b600080600080608085870312156156ff57600080fd5b84359350602085013592506040850135915061571d606086016156d4565b905092959194509250565b60006020828403121561573a57600080fd5b81356fffffffffffffffffffffffffffffffff811681146151b857600080fd5b6000806000806000806080878903121561577357600080fd5b86359550615783602088016156d4565b9450604087013567ffffffffffffffff808211156157a057600080fd5b6157ac8a838b01615499565b909650945060608901359150808211156157c557600080fd5b506157d289828a01615499565b979a9699509497509295939492505050565b63ffffffff8416815282602082015260606040820152600061188460608301846155fb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006080828403121561584a57600080fd5b6040516080810181811067ffffffffffffffff82111715615894577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561594657615946615904565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361597c5761597c615904565b5060010190565b60008282101561599557615995615904565b500390565b6000602082840312156159ac57600080fd5b81516151b881615692565b6000602082840312156159c957600080fd5b5051919050565b600067ffffffffffffffff8083168185168083038211156159f3576159f3615904565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615a2357615a23615904565b02949350505050565b600067ffffffffffffffff83811690831681811015615a4d57615a4d615904565b039392505050565b60008060408385031215615a6857600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615ab757615ab7615a79565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615af457615af4615904565b500290565b600082615b0857615b08615a79565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615a4d57615a4d615904565b60006fffffffffffffffffffffffffffffffff8083168185168083038211156159f3576159f3615904565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615bbe606083018789615b61565b8281036020840152615bd1818688615b61565b9150508260408301529695505050505050565b600060ff821660ff841680821015615bfe57615bfe615904565b90039392505050565b600060ff831680615c1a57615c1a615a79565b8060ff84160691505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615c6a57615c6a615904565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615ca557615ca5615904565b60008712925087820587128484161615615cc157615cc1615904565b87850587128184161615615cd757615cd7615904565b505050929093029392505050565b600082615cf457615cf4615a79565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615d4857615d48615904565b50059056fea164736f6c634300080f000a"; + hex"6080604052600436106102f25760003560e01c806370872aa51161018f578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b18578063fa315aa914610b3c578063fe2bbeb214610b6f57600080fd5b8063ec5e630814610a95578063eff0f59214610ac8578063f8f43ff614610af857600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a0f578063d8cc1a3c14610a42578063dabd396d14610a6257600080fd5b8063c6f0308c14610937578063cf09e0d0146109c1578063d5d44d80146109e257600080fd5b80638d450a9511610143578063bcef3b551161011d578063bcef3b55146108b7578063bd8da956146108f7578063c395e1ca1461091757600080fd5b80638d450a9514610777578063a445ece6146107aa578063bbdc02db1461087657600080fd5b80638129fc1c116101745780638129fc1c1461071a5780638980e0cc146107225780638b85902b1461073757600080fd5b806370872aa5146106f25780637b0f0adc1461070757600080fd5b80633fc8cef3116102485780635c0cba33116101fc5780636361506d116101d65780636361506d1461066c5780636b6716c0146106ac5780636f034409146106df57600080fd5b80635c0cba3314610604578063609d33341461063757806360e274641461064c57600080fd5b806354fd4d501161022d57806354fd4d501461055e57806357da950e146105b45780635a5fa2d9146105e457600080fd5b80633fc8cef314610518578063472777c61461054b57600080fd5b80632810e1d6116102aa57806337b1b2291161028457806337b1b229146104655780633a768463146104a55780633e3ac912146104d857600080fd5b80632810e1d6146103de5780632ad69aeb146103f357806330dbe5701461041357600080fd5b806319effeb4116102db57806319effeb414610339578063200d2ed21461038457806325fc2ace146103bf57600080fd5b806301935130146102f757806303c2924d14610319575b600080fd5b34801561030357600080fd5b506103176103123660046154e2565b610b9f565b005b34801561032557600080fd5b5061031761033436600461553d565b610ec0565b34801561034557600080fd5b506000546103669068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561039057600080fd5b506000546103b290700100000000000000000000000000000000900460ff1681565b60405161037b919061558e565b3480156103cb57600080fd5b506008545b60405190815260200161037b565b3480156103ea57600080fd5b506103b2611566565b3480156103ff57600080fd5b506103d061040e36600461553d565b61180b565b34801561041f57600080fd5b506001546104409073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161037b565b34801561047157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610440565b3480156104b157600080fd5b507f000000000000000000000000180cbe2ebb9f37d3a3c542ddc2546fd160555a73610440565b3480156104e457600080fd5b50600054610508907201000000000000000000000000000000000000900460ff1681565b604051901515815260200161037b565b34801561052457600080fd5b507f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92610440565b6103176105593660046155cf565b611841565b34801561056a57600080fd5b506105a76040518060400160405280600c81526020017f312e332e312d626574612e32000000000000000000000000000000000000000081525081565b60405161037b9190615666565b3480156105c057600080fd5b506008546009546105cf919082565b6040805192835260208301919091520161037b565b3480156105f057600080fd5b506103d06105ff366004615679565b611853565b34801561061057600080fd5b507f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e610440565b34801561064357600080fd5b506105a761188d565b34801561065857600080fd5b506103176106673660046156b7565b61189b565b34801561067857600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103d0565b3480156106b857600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610366565b6103176106ed3660046156e9565b611a42565b3480156106fe57600080fd5b506009546103d0565b6103176107153660046155cf565b61251b565b610317612528565b34801561072e57600080fd5b506002546103d0565b34801561074357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103d0565b34801561078357600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103d0565b3480156107b657600080fd5b506108226107c5366004615679565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff16606082015260800161037b565b34801561088257600080fd5b5060405163ffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260200161037b565b3480156108c357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103d0565b34801561090357600080fd5b50610366610912366004615679565b612a81565b34801561092357600080fd5b506103d0610932366004615728565b612c60565b34801561094357600080fd5b50610957610952366004615679565b612e43565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e00161037b565b3480156109cd57600080fd5b506000546103669067ffffffffffffffff1681565b3480156109ee57600080fd5b506103d06109fd3660046156b7565b60036020526000908152604090205481565b348015610a1b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000003856103d0565b348015610a4e57600080fd5b50610317610a5d36600461575a565b612eda565b348015610a6e57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b0610366565b348015610aa157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000046103d0565b348015610ad457600080fd5b50610508610ae3366004615679565b60046020526000908152604090205460ff1681565b348015610b0457600080fd5b50610317610b133660046155cf565b613509565b348015610b2457600080fd5b50610b2d6139c6565b60405161037b939291906157e4565b348015610b4857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000086103d0565b348015610b7b57600080fd5b50610508610b8a366004615679565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610bcb57610bcb61555f565b14610c02576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610c55576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610ca3610c9e36869003860186615838565b613a41565b14610cda576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610cef9291906158c5565b604051809103902014610d2e576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d77610d7284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613a9d92505050565b613b0a565b90506000610d9e82600881518110610d9157610d916158d5565b6020026020010151613cc0565b9050602081511115610ddc576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610e51576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610eec57610eec61555f565b14610f23576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610f3857610f386158d5565b906000526020600020906005020190506000610f5384612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b081169082161015610fbc576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611005576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561102257508515155b156110bd578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110555781611071565b600186015473ffffffffffffffffffffffffffffffffffffffff165b905061107d8187613d74565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff166060830152611160576fffffffffffffffffffffffffffffffff6040820152600181526000869003611160578195505b600086826020015163ffffffff166111789190615933565b90506000838211611189578161118b565b835b602084015190915063ffffffff165b818110156112d75760008682815481106111b6576111b66158d5565b6000918252602080832090910154808352600690915260409091205490915060ff1661120e576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611223576112236158d5565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112805750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b156112c257600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b505080806112cf9061594b565b91505061119a565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921790915584900361155b57606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558915801561145757506000547201000000000000000000000000000000000000900460ff165b156114cc5760015473ffffffffffffffffffffffffffffffffffffffff1661147f818a613d74565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff909116178855611559565b61151373ffffffffffffffffffffffffffffffffffffffff8216156114f1578161150d565b600189015473ffffffffffffffffffffffffffffffffffffffff165b89613d74565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff1660028111156115945761159461555f565b146115cb576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff1661162f576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008154811061165b5761165b6158d5565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611696576001611699565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff9091161770010000000000000000000000000000000083600281111561174a5761174a61555f565b02179055600281111561175f5761175f61555f565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e73ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156117f057600080fd5b505af1158015611804573d6000803e3d6000fd5b5050505090565b6005602052816000526040600020818154811061182757600080fd5b90600052602060002001600091509150505481565b905090565b61184e8383836001611a42565b505050565b6000818152600760209081526040808320600590925282208054825461188490610100900463ffffffff1682615983565b95945050505050565b606061183c60546020613e75565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260036020526040812080549082905590819003611900576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169063f3fef3a390604401600060405180830381600087803b15801561199057600080fd5b505af11580156119a4573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a02576040519150601f19603f3d011682016040523d82523d6000602084013e611a07565b606091505b505090508061184e576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008054700100000000000000000000000000000000900460ff166002811115611a6e57611a6e61555f565b14611aa5576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110611aba57611aba6158d5565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514611ba1576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000611c61826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580611c9c5750611c997f00000000000000000000000000000000000000000000000000000000000000046002615933565b81145b8015611ca6575084155b15611cdd576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015611d03575086155b15611d3a576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000008811115611d94576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dbf7f00000000000000000000000000000000000000000000000000000000000000046001615933565b8103611dd157611dd186888588613ec7565b34611ddb83612c60565b14611e12576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611e1d88612a81565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b0811690821603611e85576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611eb260017f0000000000000000000000000000000000000000000000000000000000000008615983565b8303611ff0577f000000000000000000000000180cbe2ebb9f37d3a3c542ddc2546fd160555a7373ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f47919061599a565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb591906159b7565b611fe9907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166159d0565b9050612083565b61201b60017f0000000000000000000000000000000000000000000000000000000000000004615983565b830361205657611fe97f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1660026159fc565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b6120b7817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b67ffffffffffffffff166120d28367ffffffffffffffff1690565b67ffffffffffffffff16111561211957612116817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615a2c565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615612197576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c8152602001908152602001600020600160028054905061242d9190615983565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd92169263d0e30db09234926004808301939282900301818588803b1580156124c557600080fd5b505af11580156124d9573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b61184e8383836000611a42565b60005471010000000000000000000000000000000000900460ff161561257a576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e1690637258a807906024016040805180830381865afa15801561262e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126529190615a55565b90925090508161268e576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a146126c157639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401351161275b576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd929092169363d0e30db093926004828101939282900301818588803b158015612a3057600080fd5b505af1158015612a44573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b600080600054700100000000000000000000000000000000900460ff166002811115612aaf57612aaf61555f565b14612ae6576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110612afb57612afb6158d5565b600091825260208220600590910201805490925063ffffffff90811614612b6a57815460028054909163ffffffff16908110612b3957612b396158d5565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090612ba290700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b612bb69067ffffffffffffffff1642615983565b612bd5612b95846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16612be99190615933565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b01667ffffffffffffffff168167ffffffffffffffff1611612c365780611884565b7f00000000000000000000000000000000000000000000000000000000000004b095945050505050565b600080612cff836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000008811115612d5e576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000612d798383615aa8565b9050670de0b6b3a76400006000612db0827f0000000000000000000000000000000000000000000000000000000000000008615abc565b90506000612dce612dc9670de0b6b3a764000086615abc565b614078565b90506000612ddc84846142d3565b90506000612dea8383614322565b90506000612df782614350565b90506000612e1682612e11670de0b6b3a76400008f615abc565b614538565b90506000612e248b83614322565b9050612e30818d615abc565b9f9e505050505050505050505050505050565b60028181548110612e5357600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b60008054700100000000000000000000000000000000900460ff166002811115612f0657612f0661555f565b14612f3d576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028781548110612f5257612f526158d5565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b9050612fb17f00000000000000000000000000000000000000000000000000000000000000086001615933565b61304d826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1614613087576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561317e576130da7f00000000000000000000000000000000000000000000000000000000000000047f0000000000000000000000000000000000000000000000000000000000000008615983565b6001901b6130f9846fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff166131159190615af9565b156131525761314961313a60016fffffffffffffffffffffffffffffffff8716615b0d565b865463ffffffff166000614608565b60030154613174565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506131a8565b600385015491506131a561313a6fffffffffffffffffffffffffffffffff86166001615b36565b90505b600882901b60088a8a6040516131bf9291906158c5565b6040518091039020901b14613200576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061320b8c6146ec565b9050600061321a836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000180cbe2ebb9f37d3a3c542ddc2546fd160555a7373ffffffffffffffffffffffffffffffffffffffff169063e14ced3290613294908f908f908f908f908a90600401615baa565b6020604051808303816000875af11580156132b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d791906159b7565b600485015491149150600090600290613382906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b61341e896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6134289190615be4565b6134329190615c07565b60ff161590508115158103613473576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156134ca576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff1660028111156135355761353561555f565b1461356c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061357b8661471b565b9350935093509350600061359185858585614b24565b905060007f000000000000000000000000180cbe2ebb9f37d3a3c542ddc2546fd160555a7373ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015613600573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613624919061599a565b90506001890361371c5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a84613680367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af11580156136f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061371691906159b7565b5061155b565b600289036137485773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8489613680565b600389036137745773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8487613680565b600489036138fb5760006137ba6fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000004614bde565b6009546137c79190615933565b6137d2906001615933565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061383b57367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036054013561383d565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156138d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f491906159b7565b505061155b565b60058903613994576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000038560c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016136d3565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060613a1f61188d565b9050909192565b600081831015613a365781613a38565b825b90505b92915050565b60008160000151826020015183604001518460600151604051602001613a80949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003613aec576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b60606000806000613b1a85614c8c565b919450925090506001816001811115613b3557613b3561555f565b14613b6c576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451613b788385615933565b14613baf576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081613bc65790505093506000835b8651811015613cb457600080613c396040518060400160405280858c60000151613c1d9190615983565b8152602001858c60200151613c329190615933565b9052614c8c565b509150915060405180604001604052808383613c559190615933565b8152602001848b60200151613c6a9190615933565b815250888581518110613c7f57613c7f6158d5565b6020908102919091010152613c95600185615933565b9350613ca18183615933565b613cab9084615933565b92505050613bf3565b50845250919392505050565b60606000806000613cd085614c8c565b919450925090506000816001811115613ceb57613ceb61555f565b14613d22576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613d2c8284615933565b855114613d65576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118848560200151848461512a565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff90931692839290613dc3908490615933565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f000000000000000000000000ef179756ea6525afade217ca5ab0b1b5cfe0fd921690637eee288d90604401600060405180830381600087803b158015613e5857600080fd5b505af1158015613e6c573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b6000613ee66fffffffffffffffffffffffffffffffff84166001615b36565b90506000613ef682866001614608565b9050600086901a8380613fe25750613f2f60027f0000000000000000000000000000000000000000000000000000000000000004615af9565b6004830154600290613fd3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b613fdd9190615c07565b60ff16145b1561403a5760ff811660011480613ffc575060ff81166002145b614035576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b613e6c565b60ff811615613e6c576040517ff40239db00000000000000000000000000000000000000000000000000000000815260048101889052602401612752565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b17600082136140d757631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a76400000215820261431057637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b6000816000190483118202156143405763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d7821361437e57919050565b680755bf798b4a1bf1e5821261439c5763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000613a38670de0b6b3a76400008361455086614078565b61455a9190615c29565b6145649190615ce5565b614350565b6000806145f6837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826146515761464c6fffffffffffffffffffffffffffffffff86167f00000000000000000000000000000000000000000000000000000000000000046151bf565b61466c565b61466c856fffffffffffffffffffffffffffffffff1661534b565b905060028481548110614681576146816158d5565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff8281169116146146e457815460028054909163ffffffff169081106146cf576146cf6158d5565b90600052602060002090600502019150614692565b509392505050565b60008060008060006146fd8661471b565b935093509350935061471184848484614b24565b9695505050505050565b600080600080600085905060006002828154811061473b5761473b6158d5565b600091825260209091206004600590920201908101549091507f000000000000000000000000000000000000000000000000000000000000000490614812906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff161161484c576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f000000000000000000000000000000000000000000000000000000000000000490614913906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16925082111561498857825463ffffffff166149527f00000000000000000000000000000000000000000000000000000000000000046001615933565b830361495c578391505b6002818154811061496f5761496f6158d5565b9060005260206000209060050201935080945050614850565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149f16149dc856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff161490508015614ac0576000614a29836fffffffffffffffffffffffffffffffff16614569565b6fffffffffffffffffffffffffffffffff161115614a94576000614a6b614a6360016fffffffffffffffffffffffffffffffff8616615b0d565b896001614608565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a50614a9a9050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614b16565b6000614ae2614a636fffffffffffffffffffffffffffffffff85166001615b36565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614b915760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611884565b8282604051602001614bbf9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614c6b847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614ccf576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614cf4576000600160009450945094505050615123565b60b78111614e0a576000614d09608083615983565b905080876000015111614d48576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614dc057507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614df7576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060019550935060009250615123915050565b60bf8111614f68576000614e1f60b783615983565b905080876000015111614e5e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614ec0576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614f08576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f128184615933565b895111614f4b576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614f56836001615933565b97509550600094506151239350505050565b60f78111614fcd576000614f7d60c083615983565b905080876000015111614fbc576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600195509350849250615123915050565b6000614fda60f783615983565b905080876000015111615019576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361507b576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c603781116150c3576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6150cd8184615933565b895111615106576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615111836001615933565b97509550600194506151239350505050565b9193909250565b60608167ffffffffffffffff81111561514557615145615809565b6040519080825280601f01601f19166020018201604052801561516f576020820181803683370190505b50905081156151b85760006151848486615933565b90506020820160005b848110156151a557828101518282015260200161518d565b848111156151b4576000858301525b5050505b9392505050565b60008161525e846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116152745763b34b5c226000526004601cfd5b61527d8361534b565b90508161531c826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611613a3b57613a38615332836001615933565b6fffffffffffffffffffffffffffffffff8316906153f0565b600081196001830116816153df827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b60008061547d847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f8401126154ab57600080fd5b50813567ffffffffffffffff8111156154c357600080fd5b6020830191508360208285010111156154db57600080fd5b9250929050565b600080600083850360a08112156154f857600080fd5b608081121561550657600080fd5b50839250608084013567ffffffffffffffff81111561552457600080fd5b61553086828701615499565b9497909650939450505050565b6000806040838503121561555057600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106155c9577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806000606084860312156155e457600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561562157602081850181015186830182015201615605565b81811115615633576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000613a3860208301846155fb565b60006020828403121561568b57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146156b457600080fd5b50565b6000602082840312156156c957600080fd5b81356151b881615692565b803580151581146156e457600080fd5b919050565b600080600080608085870312156156ff57600080fd5b84359350602085013592506040850135915061571d606086016156d4565b905092959194509250565b60006020828403121561573a57600080fd5b81356fffffffffffffffffffffffffffffffff811681146151b857600080fd5b6000806000806000806080878903121561577357600080fd5b86359550615783602088016156d4565b9450604087013567ffffffffffffffff808211156157a057600080fd5b6157ac8a838b01615499565b909650945060608901359150808211156157c557600080fd5b506157d289828a01615499565b979a9699509497509295939492505050565b63ffffffff8416815282602082015260606040820152600061188460608301846155fb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006080828403121561584a57600080fd5b6040516080810181811067ffffffffffffffff82111715615894577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561594657615946615904565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361597c5761597c615904565b5060010190565b60008282101561599557615995615904565b500390565b6000602082840312156159ac57600080fd5b81516151b881615692565b6000602082840312156159c957600080fd5b5051919050565b600067ffffffffffffffff8083168185168083038211156159f3576159f3615904565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615a2357615a23615904565b02949350505050565b600067ffffffffffffffff83811690831681811015615a4d57615a4d615904565b039392505050565b60008060408385031215615a6857600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615ab757615ab7615a79565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615af457615af4615904565b500290565b600082615b0857615b08615a79565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615a4d57615a4d615904565b60006fffffffffffffffffffffffffffffffff8083168185168083038211156159f3576159f3615904565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615bbe606083018789615b61565b8281036020840152615bd1818688615b61565b9150508260408301529695505050505050565b600060ff821660ff841680821015615bfe57615bfe615904565b90039392505050565b600060ff831680615c1a57615c1a615a79565b8060ff84160691505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615c6a57615c6a615904565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615ca557615ca5615904565b60008712925087820587128484161615615cc157615cc1615904565b87850587128184161615615cd757615cd7615904565b505050929093029392505050565b600082615cf457615cf4615a79565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615d4857615d48615904565b50059056fea164736f6c634300080f000a"; bytes internal constant acc34Code = - hex"6080604052600436106103085760003560e01c806370872aa51161019a578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b94578063fa315aa914610bb8578063fe2bbeb214610beb57600080fd5b8063ec5e630814610b11578063eff0f59214610b44578063f8f43ff614610b7457600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a8b578063d8cc1a3c14610abe578063dabd396d14610ade57600080fd5b8063c6f0308c146109b3578063cf09e0d014610a3d578063d5d44d8014610a5e57600080fd5b8063a445ece611610143578063bcef3b551161011d578063bcef3b5514610933578063bd8da95614610973578063c395e1ca1461099357600080fd5b8063a445ece6146107f3578063a8e4fb90146108bf578063bbdc02db146108f257600080fd5b80638980e0cc116101745780638980e0cc1461076b5780638b85902b146107805780638d450a95146107c057600080fd5b806370872aa51461073b5780637b0f0adc146107505780638129fc1c1461076357600080fd5b80633fc8cef31161025e5780635c0cba33116102075780636361506d116101e15780636361506d146106b55780636b6716c0146106f55780636f0344091461072857600080fd5b80635c0cba331461064d578063609d33341461068057806360e274641461069557600080fd5b806354fd4d501161023857806354fd4d50146105a757806357da950e146105fd5780635a5fa2d91461062d57600080fd5b80633fc8cef31461052e578063472777c614610561578063534db0e21461057457600080fd5b80632810e1d6116102c057806337b1b2291161029a57806337b1b2291461047b5780633a768463146104bb5780633e3ac912146104ee57600080fd5b80632810e1d6146103f45780632ad69aeb1461040957806330dbe5701461042957600080fd5b806319effeb4116102f157806319effeb41461034f578063200d2ed21461039a57806325fc2ace146103d557600080fd5b8063019351301461030d57806303c2924d1461032f575b600080fd5b34801561031957600080fd5b5061032d61032836600461575d565b610c1b565b005b34801561033b57600080fd5b5061032d61034a3660046157b8565b610f3c565b34801561035b57600080fd5b5060005461037c9068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156103a657600080fd5b506000546103c890700100000000000000000000000000000000900460ff1681565b6040516103919190615809565b3480156103e157600080fd5b506008545b604051908152602001610391565b34801561040057600080fd5b506103c86115e2565b34801561041557600080fd5b506103e66104243660046157b8565b611887565b34801561043557600080fd5b506001546104569073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610391565b34801561048757600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610456565b3480156104c757600080fd5b507f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f738610456565b3480156104fa57600080fd5b5060005461051e907201000000000000000000000000000000000000900460ff1681565b6040519015158152602001610391565b34801561053a57600080fd5b507f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309610456565b61032d61056f36600461584a565b6118bd565b34801561058057600080fd5b507f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63610456565b3480156105b357600080fd5b506105f06040518060400160405280600c81526020017f312e332e312d626574612e32000000000000000000000000000000000000000081525081565b60405161039191906158e1565b34801561060957600080fd5b50600854600954610618919082565b60408051928352602083019190915201610391565b34801561063957600080fd5b506103e66106483660046158f4565b6118cf565b34801561065957600080fd5b507f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e610456565b34801561068c57600080fd5b506105f0611909565b3480156106a157600080fd5b5061032d6106b0366004615932565b611917565b3480156106c157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103e6565b34801561070157600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061037c565b61032d610736366004615964565b611abe565b34801561074757600080fd5b506009546103e6565b61032d61075e36600461584a565b611b7f565b61032d611b8c565b34801561077757600080fd5b506002546103e6565b34801561078c57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103e6565b3480156107cc57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103e6565b3480156107ff57600080fd5b5061086b61080e3660046158f4565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff166060820152608001610391565b3480156108cb57600080fd5b507f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8610456565b3480156108fe57600080fd5b5060405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000001168152602001610391565b34801561093f57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103e6565b34801561097f57600080fd5b5061037c61098e3660046158f4565b611c05565b34801561099f57600080fd5b506103e66109ae3660046159a3565b611de4565b3480156109bf57600080fd5b506109d36109ce3660046158f4565b611fc7565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e001610391565b348015610a4957600080fd5b5060005461037c9067ffffffffffffffff1681565b348015610a6a57600080fd5b506103e6610a79366004615932565b60036020526000908152604090205481565b348015610a9757600080fd5b507f00000000000000000000000000000000000000000000000000000000000003856103e6565b348015610aca57600080fd5b5061032d610ad93660046159d5565b61205e565b348015610aea57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b061037c565b348015610b1d57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000046103e6565b348015610b5057600080fd5b5061051e610b5f3660046158f4565b60046020526000908152604090205460ff1681565b348015610b8057600080fd5b5061032d610b8f36600461584a565b612123565b348015610ba057600080fd5b50610ba96125e0565b60405161039193929190615a5f565b348015610bc457600080fd5b507f00000000000000000000000000000000000000000000000000000000000000086103e6565b348015610bf757600080fd5b5061051e610c063660046158f4565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610c4757610c476157da565b14610c7e576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610cd1576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d08367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610d1f610d1a36869003860186615ab3565b61265b565b14610d56576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610d6b929190615b40565b604051809103902014610daa576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610df3610dee84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506126b792505050565b612724565b90506000610e1a82600881518110610e0d57610e0d615b50565b60200260200101516128da565b9050602081511115610e58576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610ecd576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610f6857610f686157da565b14610f9f576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610fb457610fb4615b50565b906000526020600020906005020190506000610fcf84611c05565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b081169082161015611038576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611081576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561109e57508515155b15611139578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110d157816110ed565b600186015473ffffffffffffffffffffffffffffffffffffffff165b90506110f9818761298e565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff1660608301526111dc576fffffffffffffffffffffffffffffffff60408201526001815260008690036111dc578195505b600086826020015163ffffffff166111f49190615bae565b905060008382116112055781611207565b835b602084015190915063ffffffff165b8181101561135357600086828154811061123257611232615b50565b6000918252602080832090910154808352600690915260409091205490915060ff1661128a576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002828154811061129f5761129f615b50565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112fc5750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b1561133e57600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b5050808061134b90615bc6565b915050611216565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909316929092179091558490036115d757606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055891580156114d357506000547201000000000000000000000000000000000000900460ff165b156115485760015473ffffffffffffffffffffffffffffffffffffffff166114fb818a61298e565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff9091161788556115d5565b61158f73ffffffffffffffffffffffffffffffffffffffff82161561156d5781611589565b600189015473ffffffffffffffffffffffffffffffffffffffff165b8961298e565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff166002811115611610576116106157da565b14611647576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff166116ab576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660026000815481106116d7576116d7615b50565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611712576001611715565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff909116177001000000000000000000000000000000008360028111156117c6576117c66157da565b0217905560028111156117db576117db6157da565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e73ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561186c57600080fd5b505af1158015611880573d6000803e3d6000fd5b5050505090565b600560205281600052604060002081815481106118a357600080fd5b90600052602060002001600091509150505481565b905090565b6118ca8383836001611abe565b505050565b6000818152600760209081526040808320600590925282208054825461190090610100900463ffffffff1682615bfe565b95945050505050565b60606118b860546020612a8f565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604081208054908290559081900361197c576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309169063f3fef3a390604401600060405180830381600087803b158015611a0c57600080fd5b505af1158015611a20573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a7e576040519150601f19603f3d011682016040523d82523d6000602084013e611a83565b606091505b50509050806118ca576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8161480611b3757503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b6316145b611b6d576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b7984848484612ae1565b50505050565b6118ca8383836000611abe565b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c81614611bfb576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c036135ba565b565b600080600054700100000000000000000000000000000000900460ff166002811115611c3357611c336157da565b14611c6a576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110611c7f57611c7f615b50565b600091825260208220600590910201805490925063ffffffff90811614611cee57815460028054909163ffffffff16908110611cbd57611cbd615b50565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090611d2690700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b611d3a9067ffffffffffffffff1642615bfe565b611d59611d19846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16611d6d9190615bae565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b01667ffffffffffffffff168167ffffffffffffffff1611611dba5780611900565b7f00000000000000000000000000000000000000000000000000000000000004b095945050505050565b600080611e83836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000008811115611ee2576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000611efd8383615c44565b9050670de0b6b3a76400006000611f34827f0000000000000000000000000000000000000000000000000000000000000008615c58565b90506000611f52611f4d670de0b6b3a764000086615c58565b613b13565b90506000611f608484613d6e565b90506000611f6e8383613dbd565b90506000611f7b82613deb565b90506000611f9a82611f95670de0b6b3a76400008f615c58565b613fd3565b90506000611fa88b83613dbd565b9050611fb4818d615c58565b9f9e505050505050505050505050505050565b60028181548110611fd757600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c81614806120d757503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b6316145b61210d576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61211b868686868686614004565b505050505050565b60008054700100000000000000000000000000000000900460ff16600281111561214f5761214f6157da565b14612186576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061219586614633565b935093509350935060006121ab85858585614a3c565b905060007f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561221a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223e9190615c95565b9050600189036123365773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8461229a367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af115801561230c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123309190615cb2565b506115d7565b600289036123625773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848961229a565b6003890361238e5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848761229a565b600489036125155760006123d46fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000004614af6565b6009546123e19190615bae565b6123ec906001615bae565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061245557367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135612457565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156124ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250e9190615cb2565b50506115d7565b600589036125ae576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000038560c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016122ed565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000001367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060612639611909565b9050909192565b6000818310156126505781612652565b825b90505b92915050565b6000816000015182602001518360400151846060015160405160200161269a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003612706576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b6060600080600061273485614ba4565b91945092509050600181600181111561274f5761274f6157da565b14612786576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516127928385615bae565b146127c9576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816127e05790505093506000835b86518110156128ce576000806128536040518060400160405280858c600001516128379190615bfe565b8152602001858c6020015161284c9190615bae565b9052614ba4565b50915091506040518060400160405280838361286f9190615bae565b8152602001848b602001516128849190615bae565b81525088858151811061289957612899615b50565b60209081029190910101526128af600185615bae565b93506128bb8183615bae565b6128c59084615bae565b9250505061280d565b50845250919392505050565b606060008060006128ea85614ba4565b919450925090506000816001811115612905576129056157da565b1461293c576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129468284615bae565b85511461297f576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61190085602001518484615042565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff909316928392906129dd908490615bae565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f000000000000000000000000d6eaf4c146261653ee059077b78ed088add543091690637eee288d90604401600060405180830381600087803b158015612a7257600080fd5b505af1158015612a86573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b60008054700100000000000000000000000000000000900460ff166002811115612b0d57612b0d6157da565b14612b44576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110612b5957612b59615b50565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514612c40576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000612d00826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580612d3b5750612d387f00000000000000000000000000000000000000000000000000000000000000046002615bae565b81145b8015612d45575084155b15612d7c576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015612da2575086155b15612dd9576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000008811115612e33576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e5e7f00000000000000000000000000000000000000000000000000000000000000046001615bae565b8103612e7057612e70868885886150d7565b34612e7a83611de4565b14612eb1576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612ebc88611c05565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b0811690821603612f24576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612f5160017f0000000000000000000000000000000000000000000000000000000000000008615bfe565b830361308f577f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fe69190615c95565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015613030573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130549190615cb2565b613088907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16615ccb565b9050613122565b6130ba60017f0000000000000000000000000000000000000000000000000000000000000004615bfe565b83036130f5576130887f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166002615cf7565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b613156817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615d27565b67ffffffffffffffff166131718367ffffffffffffffff1690565b67ffffffffffffffff1611156131b8576131b5817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615d27565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615613236576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c815260200190815260200160002060016002805490506134cc9190615bfe565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309169263d0e30db09234926004808301939282900301818588803b15801561356457600080fd5b505af1158015613578573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b60005471010000000000000000000000000000000000900460ff161561360c576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000001166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e1690637258a807906024016040805180830381865afa1580156136c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136e49190615d50565b909250905081613720576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a1461375357639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135116137ed576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f000000000000000000000000d6eaf4c146261653ee059077b78ed088add543099092169363d0e30db093926004828101939282900301818588803b158015613ac257600080fd5b505af1158015613ad6573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b1760008213613b7257631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a764000002158202613dab57637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b600081600019048311820215613ddb5763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d78213613e1957919050565b680755bf798b4a1bf1e58212613e375763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000612652670de0b6b3a764000083613feb86613b13565b613ff59190615d74565b613fff9190615e30565b613deb565b60008054700100000000000000000000000000000000900460ff166002811115614030576140306157da565b14614067576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002878154811061407c5761407c615b50565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506140db7f00000000000000000000000000000000000000000000000000000000000000086001615bae565b614177826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16146141b1576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008089156142a8576142047f00000000000000000000000000000000000000000000000000000000000000047f0000000000000000000000000000000000000000000000000000000000000008615bfe565b6001901b614223846fffffffffffffffffffffffffffffffff16615288565b6fffffffffffffffffffffffffffffffff1661423f9190615e98565b1561427c5761427361426460016fffffffffffffffffffffffffffffffff8716615eac565b865463ffffffff166000615327565b6003015461429e565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506142d2565b600385015491506142cf6142646fffffffffffffffffffffffffffffffff86166001615ed5565b90505b600882901b60088a8a6040516142e9929190615b40565b6040518091039020901b1461432a576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006143358c61540b565b90506000614344836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f00000000000000000000000046cce16e68c41f7ebdf485ef825ab3b46143f73873ffffffffffffffffffffffffffffffffffffffff169063e14ced32906143be908f908f908f908f908a90600401615f49565b6020604051808303816000875af11580156143dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144019190615cb2565b6004850154911491506000906002906144ac906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b614548896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6145529190615f83565b61455c9190615fa6565b60ff16159050811515810361459d576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156145f4576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b600080600080600085905060006002828154811061465357614653615b50565b600091825260209091206004600590920201908101549091507f00000000000000000000000000000000000000000000000000000000000000049061472a906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611614764576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f00000000000000000000000000000000000000000000000000000000000000049061482b906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1692508211156148a057825463ffffffff1661486a7f00000000000000000000000000000000000000000000000000000000000000046001615bae565b8303614874578391505b6002818154811061488757614887615b50565b9060005260206000209060050201935080945050614768565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149096148f4856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff1614905080156149d8576000614941836fffffffffffffffffffffffffffffffff16615288565b6fffffffffffffffffffffffffffffffff1611156149ac57600061498361497b60016fffffffffffffffffffffffffffffffff8616615eac565b896001615327565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a506149b29050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614a2e565b60006149fa61497b6fffffffffffffffffffffffffffffffff85166001615ed5565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614aa95760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611900565b8282604051602001614ad79291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614b83847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614be7576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614c0c57600060016000945094509450505061503b565b60b78111614d22576000614c21608083615bfe565b905080876000015111614c60576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614cd857507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614d0f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061503b915050565b60bf8111614e80576000614d3760b783615bfe565b905080876000015111614d76576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614dd8576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614e20576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614e2a8184615bae565b895111614e63576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614e6e836001615bae565b975095506000945061503b9350505050565b60f78111614ee5576000614e9560c083615bfe565b905080876000015111614ed4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061503b915050565b6000614ef260f783615bfe565b905080876000015111614f31576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614f93576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614fdb576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614fe58184615bae565b89511161501e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615029836001615bae565b975095506001945061503b9350505050565b9193909250565b60608167ffffffffffffffff81111561505d5761505d615a84565b6040519080825280601f01601f191660200182016040528015615087576020820181803683370190505b50905081156150d057600061509c8486615bae565b90506020820160005b848110156150bd5782810151828201526020016150a5565b848111156150cc576000858301525b5050505b9392505050565b60006150f66fffffffffffffffffffffffffffffffff84166001615ed5565b9050600061510682866001615327565b9050600086901a83806151f2575061513f60027f0000000000000000000000000000000000000000000000000000000000000004615e98565b60048301546002906151e3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6151ed9190615fa6565b60ff16145b1561524a5760ff81166001148061520c575060ff81166002145b615245576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016137e4565b612a86565b60ff811615612a86576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016137e4565b600080615315837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826153705761536b6fffffffffffffffffffffffffffffffff86167f000000000000000000000000000000000000000000000000000000000000000461543a565b61538b565b61538b856fffffffffffffffffffffffffffffffff166155c6565b9050600284815481106153a0576153a0615b50565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff82811691161461540357815460028054909163ffffffff169081106153ee576153ee615b50565b906000526020600020906005020191506153b1565b509392505050565b600080600080600061541c86614633565b935093509350935061543084848484614a3c565b9695505050505050565b6000816154d9846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116154ef5763b34b5c226000526004601cfd5b6154f8836155c6565b905081615597826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611612655576126526155ad836001615bae565b6fffffffffffffffffffffffffffffffff83169061566b565b6000811960018301168161565a827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b6000806156f8847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f84011261572657600080fd5b50813567ffffffffffffffff81111561573e57600080fd5b60208301915083602082850101111561575657600080fd5b9250929050565b600080600083850360a081121561577357600080fd5b608081121561578157600080fd5b50839250608084013567ffffffffffffffff81111561579f57600080fd5b6157ab86828701615714565b9497909650939450505050565b600080604083850312156157cb57600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310615844577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060006060848603121561585f57600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561589c57602081850181015186830182015201615880565b818111156158ae576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006126526020830184615876565b60006020828403121561590657600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461592f57600080fd5b50565b60006020828403121561594457600080fd5b81356150d08161590d565b8035801515811461595f57600080fd5b919050565b6000806000806080858703121561597a57600080fd5b8435935060208501359250604085013591506159986060860161594f565b905092959194509250565b6000602082840312156159b557600080fd5b81356fffffffffffffffffffffffffffffffff811681146150d057600080fd5b600080600080600080608087890312156159ee57600080fd5b863595506159fe6020880161594f565b9450604087013567ffffffffffffffff80821115615a1b57600080fd5b615a278a838b01615714565b90965094506060890135915080821115615a4057600080fd5b50615a4d89828a01615714565b979a9699509497509295939492505050565b63ffffffff841681528260208201526060604082015260006119006060830184615876565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060808284031215615ac557600080fd5b6040516080810181811067ffffffffffffffff82111715615b0f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115615bc157615bc1615b7f565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615bf757615bf7615b7f565b5060010190565b600082821015615c1057615c10615b7f565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615c5357615c53615c15565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615c9057615c90615b7f565b500290565b600060208284031215615ca757600080fd5b81516150d08161590d565b600060208284031215615cc457600080fd5b5051919050565b600067ffffffffffffffff808316818516808303821115615cee57615cee615b7f565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615d1e57615d1e615b7f565b02949350505050565b600067ffffffffffffffff83811690831681811015615d4857615d48615b7f565b039392505050565b60008060408385031215615d6357600080fd5b505080516020909101519092909150565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615db557615db5615b7f565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615df057615df0615b7f565b60008712925087820587128484161615615e0c57615e0c615b7f565b87850587128184161615615e2257615e22615b7f565b505050929093029392505050565b600082615e3f57615e3f615c15565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615e9357615e93615b7f565b500590565b600082615ea757615ea7615c15565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615d4857615d48615b7f565b60006fffffffffffffffffffffffffffffffff808316818516808303821115615cee57615cee615b7f565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615f5d606083018789615f00565b8281036020840152615f70818688615f00565b9150508260408301529695505050505050565b600060ff821660ff841680821015615f9d57615f9d615b7f565b90039392505050565b600060ff831680615fb957615fb9615c15565b8060ff8416069150509291505056fea164736f6c634300080f000a"; + hex"6080604052600436106103085760003560e01c806370872aa51161019a578063c6f0308c116100e1578063ec5e63081161008a578063fa24f74311610064578063fa24f74314610b94578063fa315aa914610bb8578063fe2bbeb214610beb57600080fd5b8063ec5e630814610b11578063eff0f59214610b44578063f8f43ff614610b7457600080fd5b8063d6ae3cd5116100bb578063d6ae3cd514610a8b578063d8cc1a3c14610abe578063dabd396d14610ade57600080fd5b8063c6f0308c146109b3578063cf09e0d014610a3d578063d5d44d8014610a5e57600080fd5b8063a445ece611610143578063bcef3b551161011d578063bcef3b5514610933578063bd8da95614610973578063c395e1ca1461099357600080fd5b8063a445ece6146107f3578063a8e4fb90146108bf578063bbdc02db146108f257600080fd5b80638980e0cc116101745780638980e0cc1461076b5780638b85902b146107805780638d450a95146107c057600080fd5b806370872aa51461073b5780637b0f0adc146107505780638129fc1c1461076357600080fd5b80633fc8cef31161025e5780635c0cba33116102075780636361506d116101e15780636361506d146106b55780636b6716c0146106f55780636f0344091461072857600080fd5b80635c0cba331461064d578063609d33341461068057806360e274641461069557600080fd5b806354fd4d501161023857806354fd4d50146105a757806357da950e146105fd5780635a5fa2d91461062d57600080fd5b80633fc8cef31461052e578063472777c614610561578063534db0e21461057457600080fd5b80632810e1d6116102c057806337b1b2291161029a57806337b1b2291461047b5780633a768463146104bb5780633e3ac912146104ee57600080fd5b80632810e1d6146103f45780632ad69aeb1461040957806330dbe5701461042957600080fd5b806319effeb4116102f157806319effeb41461034f578063200d2ed21461039a57806325fc2ace146103d557600080fd5b8063019351301461030d57806303c2924d1461032f575b600080fd5b34801561031957600080fd5b5061032d61032836600461575d565b610c1b565b005b34801561033b57600080fd5b5061032d61034a3660046157b8565b610f3c565b34801561035b57600080fd5b5060005461037c9068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156103a657600080fd5b506000546103c890700100000000000000000000000000000000900460ff1681565b6040516103919190615809565b3480156103e157600080fd5b506008545b604051908152602001610391565b34801561040057600080fd5b506103c86115e2565b34801561041557600080fd5b506103e66104243660046157b8565b611887565b34801561043557600080fd5b506001546104569073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610391565b34801561048757600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560601c610456565b3480156104c757600080fd5b507f000000000000000000000000180cbe2ebb9f37d3a3c542ddc2546fd160555a73610456565b3480156104fa57600080fd5b5060005461051e907201000000000000000000000000000000000000900460ff1681565b6040519015158152602001610391565b34801561053a57600080fd5b507f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309610456565b61032d61056f36600461584a565b6118bd565b34801561058057600080fd5b507f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b63610456565b3480156105b357600080fd5b506105f06040518060400160405280600c81526020017f312e332e312d626574612e32000000000000000000000000000000000000000081525081565b60405161039191906158e1565b34801561060957600080fd5b50600854600954610618919082565b60408051928352602083019190915201610391565b34801561063957600080fd5b506103e66106483660046158f4565b6118cf565b34801561065957600080fd5b507f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e610456565b34801561068c57600080fd5b506105f0611909565b3480156106a157600080fd5b5061032d6106b0366004615932565b611917565b3480156106c157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003603401356103e6565b34801561070157600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061037c565b61032d610736366004615964565b611abe565b34801561074757600080fd5b506009546103e6565b61032d61075e36600461584a565b611b7f565b61032d611b8c565b34801561077757600080fd5b506002546103e6565b34801561078c57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401356103e6565b3480156107cc57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103e6565b3480156107ff57600080fd5b5061086b61080e3660046158f4565b6007602052600090815260409020805460019091015460ff821691610100810463ffffffff1691650100000000009091046fffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b60408051941515855263ffffffff90931660208501526fffffffffffffffffffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff166060820152608001610391565b3480156108cb57600080fd5b507f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8610456565b3480156108fe57600080fd5b5060405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000001168152602001610391565b34801561093f57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356103e6565b34801561097f57600080fd5b5061037c61098e3660046158f4565b611c05565b34801561099f57600080fd5b506103e66109ae3660046159a3565b611de4565b3480156109bf57600080fd5b506109d36109ce3660046158f4565b611fc7565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e001610391565b348015610a4957600080fd5b5060005461037c9067ffffffffffffffff1681565b348015610a6a57600080fd5b506103e6610a79366004615932565b60036020526000908152604090205481565b348015610a9757600080fd5b507f00000000000000000000000000000000000000000000000000000000000003856103e6565b348015610aca57600080fd5b5061032d610ad93660046159d5565b61205e565b348015610aea57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b061037c565b348015610b1d57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000046103e6565b348015610b5057600080fd5b5061051e610b5f3660046158f4565b60046020526000908152604090205460ff1681565b348015610b8057600080fd5b5061032d610b8f36600461584a565b612123565b348015610ba057600080fd5b50610ba96125e0565b60405161039193929190615a5f565b348015610bc457600080fd5b507f00000000000000000000000000000000000000000000000000000000000000086103e6565b348015610bf757600080fd5b5061051e610c063660046158f4565b60066020526000908152604090205460ff1681565b60008054700100000000000000000000000000000000900460ff166002811115610c4757610c476157da565b14610c7e576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff1615610cd1576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d08367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013590565b90565b610d1f610d1a36869003860186615ab3565b61265b565b14610d56576040517f9cc00b5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82606001358282604051610d6b929190615b40565b604051809103902014610daa576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610df3610dee84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506126b792505050565b612724565b90506000610e1a82600881518110610e0d57610e0d615b50565b60200260200101516128da565b9050602081511115610e58576040517fd81d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081810151825190910360031b1c367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003605401358103610ecd576040517fb8ed883000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555050600080547fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1672010000000000000000000000000000000000001790555050565b60008054700100000000000000000000000000000000900460ff166002811115610f6857610f686157da565b14610f9f576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110610fb457610fb4615b50565b906000526020600020906005020190506000610fcf84611c05565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b081169082161015611038576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604090205460ff1615611081576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084815260056020526040902080548015801561109e57508515155b15611139578354640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156110d157816110ed565b600186015473ffffffffffffffffffffffffffffffffffffffff165b90506110f9818761298e565b50505060009485525050600660205250506040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000868152600760209081526040918290208251608081018452815460ff81161515808352610100820463ffffffff16948301949094526501000000000090046fffffffffffffffffffffffffffffffff16938101939093526001015473ffffffffffffffffffffffffffffffffffffffff1660608301526111dc576fffffffffffffffffffffffffffffffff60408201526001815260008690036111dc578195505b600086826020015163ffffffff166111f49190615bae565b905060008382116112055781611207565b835b602084015190915063ffffffff165b8181101561135357600086828154811061123257611232615b50565b6000918252602080832090910154808352600690915260409091205490915060ff1661128a576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002828154811061129f5761129f615b50565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156112fc5750600481015460408701516fffffffffffffffffffffffffffffffff9182169116115b1561133e57600181015473ffffffffffffffffffffffffffffffffffffffff16606087015260048101546fffffffffffffffffffffffffffffffff1660408701525b5050808061134b90615bc6565b915050611216565b5063ffffffff818116602085810191825260008c81526007909152604090819020865181549351928801517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009094169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff161761010092909416918202939093177fffffffffffffffffffffff00000000000000000000000000000000ffffffffff16650100000000006fffffffffffffffffffffffffffffffff909316929092029190911782556060850151600190920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909316929092179091558490036115d757606083015160008a815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055891580156114d357506000547201000000000000000000000000000000000000900460ff165b156115485760015473ffffffffffffffffffffffffffffffffffffffff166114fb818a61298e565b885473ffffffffffffffffffffffffffffffffffffffff909116640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff9091161788556115d5565b61158f73ffffffffffffffffffffffffffffffffffffffff82161561156d5781611589565b600189015473ffffffffffffffffffffffffffffffffffffffff165b8961298e565b87547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8316021788555b505b505050505050505050565b600080600054700100000000000000000000000000000000900460ff166002811115611610576116106157da565b14611647576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff166116ab576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660026000815481106116d7576116d7615b50565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614611712576001611715565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff909116177001000000000000000000000000000000008360028111156117c6576117c66157da565b0217905560028111156117db576117db6157da565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e73ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561186c57600080fd5b505af1158015611880573d6000803e3d6000fd5b5050505090565b600560205281600052604060002081815481106118a357600080fd5b90600052602060002001600091509150505481565b905090565b6118ca8383836001611abe565b505050565b6000818152600760209081526040808320600590925282208054825461190090610100900463ffffffff1682615bfe565b95945050505050565b60606118b860546020612a8f565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604081208054908290559081900361197c576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309169063f3fef3a390604401600060405180830381600087803b158015611a0c57600080fd5b505af1158015611a20573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611a7e576040519150601f19603f3d011682016040523d82523d6000602084013e611a83565b606091505b50509050806118ca576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8161480611b3757503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b6316145b611b6d576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b7984848484612ae1565b50505050565b6118ca8383836000611abe565b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c81614611bfb576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c036135ba565b565b600080600054700100000000000000000000000000000000900460ff166002811115611c3357611c336157da565b14611c6a576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028381548110611c7f57611c7f615b50565b600091825260208220600590910201805490925063ffffffff90811614611cee57815460028054909163ffffffff16908110611cbd57611cbd615b50565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b6004820154600090611d2690700100000000000000000000000000000000900467ffffffffffffffff165b67ffffffffffffffff1690565b611d3a9067ffffffffffffffff1642615bfe565b611d59611d19846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16611d6d9190615bae565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b01667ffffffffffffffff168167ffffffffffffffff1611611dba5780611900565b7f00000000000000000000000000000000000000000000000000000000000004b095945050505050565b600080611e83836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690507f0000000000000000000000000000000000000000000000000000000000000008811115611ee2576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a806311e1a3006000611efd8383615c44565b9050670de0b6b3a76400006000611f34827f0000000000000000000000000000000000000000000000000000000000000008615c58565b90506000611f52611f4d670de0b6b3a764000086615c58565b613b13565b90506000611f608484613d6e565b90506000611f6e8383613dbd565b90506000611f7b82613deb565b90506000611f9a82611f95670de0b6b3a76400008f615c58565b613fd3565b90506000611fa88b83613dbd565b9050611fb4818d615c58565b9f9e505050505050505050505050505050565b60028181548110611fd757600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c81614806120d757503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006925b8704ff96dee942623d6fb5e946ef5884b6316145b61210d576040517fd386ef3e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61211b868686868686614004565b505050505050565b60008054700100000000000000000000000000000000900460ff16600281111561214f5761214f6157da565b14612186576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061219586614633565b935093509350935060006121ab85858585614a3c565b905060007f000000000000000000000000180cbe2ebb9f37d3a3c542ddc2546fd160555a7373ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561221a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223e9190615c95565b9050600189036123365773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8461229a367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036034013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af115801561230c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123309190615cb2565b506115d7565b600289036123625773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848961229a565b6003890361238e5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848761229a565b600489036125155760006123d46fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000004614af6565b6009546123e19190615bae565b6123ec906001615bae565b9050367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135811061245557367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135612457565b805b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af11580156124ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250e9190615cb2565b50506115d7565b600589036125ae576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000038560c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016122ed565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000001367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003601401356060612639611909565b9050909192565b6000818310156126505781612652565b825b90505b92915050565b6000816000015182602001518360400151846060015160405160200161269a949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60408051808201909152600080825260208201528151600003612706576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091528151815260209182019181019190915290565b6060600080600061273485614ba4565b91945092509050600181600181111561274f5761274f6157da565b14612786576040517f4b9c6abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516127928385615bae565b146127c9576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816127e05790505093506000835b86518110156128ce576000806128536040518060400160405280858c600001516128379190615bfe565b8152602001858c6020015161284c9190615bae565b9052614ba4565b50915091506040518060400160405280838361286f9190615bae565b8152602001848b602001516128849190615bae565b81525088858151811061289957612899615b50565b60209081029190910101526128af600185615bae565b93506128bb8183615bae565b6128c59084615bae565b9250505061280d565b50845250919392505050565b606060008060006128ea85614ba4565b919450925090506000816001811115612905576129056157da565b1461293c576040517f1ff9b2e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129468284615bae565b85511461297f576040517f5c5537b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61190085602001518484615042565b600281015473ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546fffffffffffffffffffffffffffffffff909316928392906129dd908490615bae565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f000000000000000000000000d6eaf4c146261653ee059077b78ed088add543091690637eee288d90604401600060405180830381600087803b158015612a7257600080fd5b505af1158015612a86573d6000803e3d6000fd5b50505050505050565b604051818152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90038284820160208401378260208301016000815260208101604052505092915050565b60008054700100000000000000000000000000000000900460ff166002811115612b0d57612b0d6157da565b14612b44576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110612b5957612b59615b50565b60009182526020918290206040805160e0810182526005909302909101805463ffffffff8116845273ffffffffffffffffffffffffffffffffffffffff64010000000090910481169484019490945260018101549093169082015260028201546fffffffffffffffffffffffffffffffff908116606083015260038301546080830181905260049093015480821660a084015270010000000000000000000000000000000090041660c082015291508514612c40576040517f3014033200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151600083156fffffffffffffffffffffffffffffffff83161760011b90506000612d00826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050861580612d3b5750612d387f00000000000000000000000000000000000000000000000000000000000000046002615bae565b81145b8015612d45575084155b15612d7c576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000547201000000000000000000000000000000000000900460ff168015612da2575086155b15612dd9576040517f0ea2e75200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000008811115612e33576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e5e7f00000000000000000000000000000000000000000000000000000000000000046001615bae565b8103612e7057612e70868885886150d7565b34612e7a83611de4565b14612eb1576040517f8620aa1900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612ebc88611c05565b905067ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b0811690821603612f24576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612f5160017f0000000000000000000000000000000000000000000000000000000000000008615bfe565b830361308f577f000000000000000000000000180cbe2ebb9f37d3a3c542ddc2546fd160555a7373ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fe69190615c95565b73ffffffffffffffffffffffffffffffffffffffff1663f3f480d96040518163ffffffff1660e01b8152600401602060405180830381865afa158015613030573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130549190615cb2565b613088907f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16615ccb565b9050613122565b6130ba60017f0000000000000000000000000000000000000000000000000000000000000004615bfe565b83036130f5576130887f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166002615cf7565b507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff165b613156817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615d27565b67ffffffffffffffff166131718367ffffffffffffffff1690565b67ffffffffffffffff1611156131b8576131b5817f00000000000000000000000000000000000000000000000000000000000004b067ffffffffffffffff16615d27565b91505b6000604083901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615613236576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600560008c815260200190815260200160002060016002805490506134cc9190615bfe565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000d6eaf4c146261653ee059077b78ed088add54309169263d0e30db09234926004808301939282900301818588803b15801561356457600080fd5b505af1158015613578573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a4505050505050505050505050565b60005471010000000000000000000000000000000000900460ff161561360c576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000001166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000970670459734a83899773a0fd45941b5afc1200e1690637258a807906024016040805180830381865afa1580156136c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136e49190615d50565b909250905081613720576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091528281526020018190526008829055600981905536607a1461375357639824bdab6000526004601cfd5b80367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360540135116137ed576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036014013560048201526024015b60405180910390fd5b6040805160e08101825263ffffffff8082526000602083018181527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90038035606090811c868801908152346fffffffffffffffffffffffffffffffff81811693890193845260149094013560808901908152600160a08a0181815242871660c08c019081526002805493840181558a529a5160059092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0860180549186167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921691909117905591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad185015551955182167001000000000000000000000000000000000295909116949094177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091015580547fffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000017815583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f000000000000000000000000d6eaf4c146261653ee059077b78ed088add543099092169363d0e30db093926004828101939282900301818588803b158015613ac257600080fd5b505af1158015613ad6573d6000803e3d6000fd5b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161790555050505050565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b1760008213613b7257631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a764000002158202613dab57637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b600081600019048311820215613ddb5763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d78213613e1957919050565b680755bf798b4a1bf1e58212613e375763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000612652670de0b6b3a764000083613feb86613b13565b613ff59190615d74565b613fff9190615e30565b613deb565b60008054700100000000000000000000000000000000900460ff166002811115614030576140306157da565b14614067576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002878154811061407c5761407c615b50565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506140db7f00000000000000000000000000000000000000000000000000000000000000086001615bae565b614177826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16146141b1576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008089156142a8576142047f00000000000000000000000000000000000000000000000000000000000000047f0000000000000000000000000000000000000000000000000000000000000008615bfe565b6001901b614223846fffffffffffffffffffffffffffffffff16615288565b6fffffffffffffffffffffffffffffffff1661423f9190615e98565b1561427c5761427361426460016fffffffffffffffffffffffffffffffff8716615eac565b865463ffffffff166000615327565b6003015461429e565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506142d2565b600385015491506142cf6142646fffffffffffffffffffffffffffffffff86166001615ed5565b90505b600882901b60088a8a6040516142e9929190615b40565b6040518091039020901b1461432a576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006143358c61540b565b90506000614344836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000180cbe2ebb9f37d3a3c542ddc2546fd160555a7373ffffffffffffffffffffffffffffffffffffffff169063e14ced32906143be908f908f908f908f908a90600401615f49565b6020604051808303816000875af11580156143dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144019190615cb2565b6004850154911491506000906002906144ac906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b614548896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6145529190615f83565b61455c9190615fa6565b60ff16159050811515810361459d576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156145f4576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b600080600080600085905060006002828154811061465357614653615b50565b600091825260209091206004600590920201908101549091507f00000000000000000000000000000000000000000000000000000000000000049061472a906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611614764576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f00000000000000000000000000000000000000000000000000000000000000049061482b906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1692508211156148a057825463ffffffff1661486a7f00000000000000000000000000000000000000000000000000000000000000046001615bae565b8303614874578391505b6002818154811061488757614887615b50565b9060005260206000209060050201935080945050614768565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166149096148f4856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff1614905080156149d8576000614941836fffffffffffffffffffffffffffffffff16615288565b6fffffffffffffffffffffffffffffffff1611156149ac57600061498361497b60016fffffffffffffffffffffffffffffffff8616615eac565b896001615327565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a506149b29050565b6008549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750614a2e565b60006149fa61497b6fffffffffffffffffffffffffffffffff85166001615ed5565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841615614aa95760408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a00160405160208183030381529060405280519060200120611900565b8282604051602001614ad79291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012095945050505050565b600080614b83847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1690508083036001841b600180831b0386831b17039250505092915050565b60008060008360000151600003614be7576040517f5ab458fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020840151805160001a607f8111614c0c57600060016000945094509450505061503b565b60b78111614d22576000614c21608083615bfe565b905080876000015111614c60576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082148015614cd857507f80000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216105b15614d0f576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001955093506000925061503b915050565b60bf8111614e80576000614d3760b783615bfe565b905080876000015111614d76576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614dd8576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614e20576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614e2a8184615bae565b895111614e63576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614e6e836001615bae565b975095506000945061503b9350505050565b60f78111614ee5576000614e9560c083615bfe565b905080876000015111614ed4576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019550935084925061503b915050565b6000614ef260f783615bfe565b905080876000015111614f31576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614f93576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184015160088302610100031c60378111614fdb576040517fbabb01dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614fe58184615bae565b89511161501e576040517f66c9448500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b615029836001615bae565b975095506001945061503b9350505050565b9193909250565b60608167ffffffffffffffff81111561505d5761505d615a84565b6040519080825280601f01601f191660200182016040528015615087576020820181803683370190505b50905081156150d057600061509c8486615bae565b90506020820160005b848110156150bd5782810151828201526020016150a5565b848111156150cc576000858301525b5050505b9392505050565b60006150f66fffffffffffffffffffffffffffffffff84166001615ed5565b9050600061510682866001615327565b9050600086901a83806151f2575061513f60027f0000000000000000000000000000000000000000000000000000000000000004615e98565b60048301546002906151e3906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6151ed9190615fa6565b60ff16145b1561524a5760ff81166001148061520c575060ff81166002145b615245576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016137e4565b612a86565b60ff811615612a86576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016137e4565b600080615315837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600160ff919091161b90920392915050565b600080826153705761536b6fffffffffffffffffffffffffffffffff86167f000000000000000000000000000000000000000000000000000000000000000461543a565b61538b565b61538b856fffffffffffffffffffffffffffffffff166155c6565b9050600284815481106153a0576153a0615b50565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff82811691161461540357815460028054909163ffffffff169081106153ee576153ee615b50565b906000526020600020906005020191506153b1565b509392505050565b600080600080600061541c86614633565b935093509350935061543084848484614a3c565b9695505050505050565b6000816154d9846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff16116154ef5763b34b5c226000526004601cfd5b6154f8836155c6565b905081615597826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff1611612655576126526155ad836001615bae565b6fffffffffffffffffffffffffffffffff83169061566b565b6000811960018301168161565a827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169390931c8015179392505050565b6000806156f8847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b60ff169050808303600180821b0385821b179250505092915050565b60008083601f84011261572657600080fd5b50813567ffffffffffffffff81111561573e57600080fd5b60208301915083602082850101111561575657600080fd5b9250929050565b600080600083850360a081121561577357600080fd5b608081121561578157600080fd5b50839250608084013567ffffffffffffffff81111561579f57600080fd5b6157ab86828701615714565b9497909650939450505050565b600080604083850312156157cb57600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310615844577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060006060848603121561585f57600080fd5b505081359360208301359350604090920135919050565b6000815180845260005b8181101561589c57602081850181015186830182015201615880565b818111156158ae576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006126526020830184615876565b60006020828403121561590657600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461592f57600080fd5b50565b60006020828403121561594457600080fd5b81356150d08161590d565b8035801515811461595f57600080fd5b919050565b6000806000806080858703121561597a57600080fd5b8435935060208501359250604085013591506159986060860161594f565b905092959194509250565b6000602082840312156159b557600080fd5b81356fffffffffffffffffffffffffffffffff811681146150d057600080fd5b600080600080600080608087890312156159ee57600080fd5b863595506159fe6020880161594f565b9450604087013567ffffffffffffffff80821115615a1b57600080fd5b615a278a838b01615714565b90965094506060890135915080821115615a4057600080fd5b50615a4d89828a01615714565b979a9699509497509295939492505050565b63ffffffff841681528260208201526060604082015260006119006060830184615876565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060808284031215615ac557600080fd5b6040516080810181811067ffffffffffffffff82111715615b0f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115615bc157615bc1615b7f565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615bf757615bf7615b7f565b5060010190565b600082821015615c1057615c10615b7f565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615c5357615c53615c15565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615c9057615c90615b7f565b500290565b600060208284031215615ca757600080fd5b81516150d08161590d565b600060208284031215615cc457600080fd5b5051919050565b600067ffffffffffffffff808316818516808303821115615cee57615cee615b7f565b01949350505050565b600067ffffffffffffffff80831681851681830481118215151615615d1e57615d1e615b7f565b02949350505050565b600067ffffffffffffffff83811690831681811015615d4857615d48615b7f565b039392505050565b60008060408385031215615d6357600080fd5b505080516020909101519092909150565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615db557615db5615b7f565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615df057615df0615b7f565b60008712925087820587128484161615615e0c57615e0c615b7f565b87850587128184161615615e2257615e22615b7f565b505050929093029392505050565b600082615e3f57615e3f615c15565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615e9357615e93615b7f565b500590565b600082615ea757615ea7615c15565b500690565b60006fffffffffffffffffffffffffffffffff83811690831681811015615d4857615d48615b7f565b60006fffffffffffffffffffffffffffffffff808316818516808303821115615cee57615cee615b7f565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000615f5d606083018789615f00565b8281036020840152615f70818688615f00565b9150508260408301529695505050505050565b600060ff821660ff841680821015615f9d57615f9d615b7f565b90039392505050565b600060ff831680615fb957615fb9615c15565b8060ff8416069150509291505056fea164736f6c634300080f000a"; } diff --git a/packages/contracts-bedrock/test/setup/FFIInterface.sol b/packages/contracts-bedrock/test/setup/FFIInterface.sol index c07c9f58fbd5..727402a37c2c 100644 --- a/packages/contracts-bedrock/test/setup/FFIInterface.sol +++ b/packages/contracts-bedrock/test/setup/FFIInterface.sol @@ -245,6 +245,56 @@ contract FFIInterface { return (memRoot, proof); } + function getCannonMemoryProof( + uint32 pc, + uint32 insn, + uint32 memAddr, + uint32 memVal, + uint32 memAddr2, + uint32 memVal2 + ) + external + returns (bytes32, bytes memory) + { + string[] memory cmds = new string[](9); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "cannonMemoryProof"; + cmds[3] = vm.toString(pc); + cmds[4] = vm.toString(insn); + cmds[5] = vm.toString(memAddr); + cmds[6] = vm.toString(memVal); + cmds[7] = vm.toString(memAddr2); + cmds[8] = vm.toString(memVal2); + bytes memory result = Process.run(cmds); + (bytes32 memRoot, bytes memory proof) = abi.decode(result, (bytes32, bytes)); + return (memRoot, proof); + } + + function getCannonMemoryProof2( + uint32 pc, + uint32 insn, + uint32 memAddr, + uint32 memVal, + uint32 memAddrForProof + ) + external + returns (bytes32, bytes memory) + { + string[] memory cmds = new string[](8); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "cannonMemoryProof2"; + cmds[3] = vm.toString(pc); + cmds[4] = vm.toString(insn); + cmds[5] = vm.toString(memAddr); + cmds[6] = vm.toString(memVal); + cmds[7] = vm.toString(memAddrForProof); + bytes memory result = Process.run(cmds); + (bytes32 memRoot, bytes memory proof) = abi.decode(result, (bytes32, bytes)); + return (memRoot, proof); + } + function getCannonMemoryProofWrongLeaf( uint32 pc, uint32 insn, From e374443006d757d93330b7d5263bc90b20032faa Mon Sep 17 00:00:00 2001 From: wissyLeeei Date: Thu, 12 Sep 2024 05:32:45 +0300 Subject: [PATCH 113/264] Fix the error usage in cannon (#11368) --- cannon/cmd/run.go | 3 ++- cannon/mipsevm/program/patch.go | 3 ++- cannon/mipsevm/testutil/mips.go | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cannon/cmd/run.go b/cannon/cmd/run.go index 2fe67fc3e44c..49c248f6f9d2 100644 --- a/cannon/cmd/run.go +++ b/cannon/cmd/run.go @@ -2,6 +2,7 @@ package cmd import ( "context" + "errors" "fmt" "os" "os/exec" @@ -375,7 +376,7 @@ func Run(ctx *cli.Context) error { debugProgram := ctx.Bool(RunDebugFlag.Name) if debugProgram { if metaPath := ctx.Path(RunMetaFlag.Name); metaPath == "" { - return fmt.Errorf("cannot enable debug mode without a metadata file") + return errors.New("cannot enable debug mode without a metadata file") } if err := vm.InitDebug(); err != nil { return fmt.Errorf("failed to initialize debug mode: %w", err) diff --git a/cannon/mipsevm/program/patch.go b/cannon/mipsevm/program/patch.go index 46b75a69ff1c..0380d3bfcc87 100644 --- a/cannon/mipsevm/program/patch.go +++ b/cannon/mipsevm/program/patch.go @@ -4,6 +4,7 @@ import ( "bytes" "debug/elf" "encoding/binary" + "errors" "fmt" "github.com/ethereum-optimism/optimism/cannon/mipsevm" @@ -57,7 +58,7 @@ func PatchStack(st mipsevm.FPVMState) error { sp := uint32(0x7f_ff_d0_00) // allocate 1 page for the initial stack data, and 16KB = 4 pages for the stack to grow if err := st.GetMemory().SetMemoryRange(sp-4*memory.PageSize, bytes.NewReader(make([]byte, 5*memory.PageSize))); err != nil { - return fmt.Errorf("failed to allocate page for stack content") + return errors.New("failed to allocate page for stack content") } st.GetRegistersRef()[29] = sp diff --git a/cannon/mipsevm/testutil/mips.go b/cannon/mipsevm/testutil/mips.go index f596e0e4de7b..ac9d8b2b3092 100644 --- a/cannon/mipsevm/testutil/mips.go +++ b/cannon/mipsevm/testutil/mips.go @@ -123,7 +123,7 @@ func EncodePreimageOracleInput(t *testing.T, wit *mipsevm.StepWitness, localCont return input, nil case preimage.PrecompileKeyType: if localOracle == nil { - return nil, fmt.Errorf("local oracle is required for precompile preimages") + return nil, errors.New("local oracle is required for precompile preimages") } preimage := localOracle.GetPreimage(preimage.Keccak256Key(wit.PreimageKey).PreimageKey()) precompile := common.BytesToAddress(preimage[:20]) From d887cfa990a39b30bb102e480661a1f09e0add67 Mon Sep 17 00:00:00 2001 From: clabby Date: Wed, 11 Sep 2024 22:58:34 -0400 Subject: [PATCH 114/264] chore(op-program): Turn off `fsync` on pebble KV store (#11863) * chore: Cleanup proofs actions * tidy * lint * adrian review * move `RunFaultProofProgram` onto the `L2FaultProofEnv` type * chore(op-program): Turn off `fsync` on pebble KV store --- op-program/host/kvstore/pebble.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op-program/host/kvstore/pebble.go b/op-program/host/kvstore/pebble.go index 1276fa6b7ef7..fc68d07853c9 100644 --- a/op-program/host/kvstore/pebble.go +++ b/op-program/host/kvstore/pebble.go @@ -38,7 +38,7 @@ func NewPebbleKV(path string) *PebbleKV { func (d *PebbleKV) Put(k common.Hash, v []byte) error { d.Lock() defer d.Unlock() - return d.db.Set(k.Bytes(), v, pebble.Sync) + return d.db.Set(k.Bytes(), v, pebble.NoSync) } func (d *PebbleKV) Get(k common.Hash) ([]byte, error) { From 97aa08a670a43647d06fc86e454443e3271a9cf5 Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Thu, 12 Sep 2024 07:56:13 -0600 Subject: [PATCH 115/264] Add SendAsync to TxMgr (#11843) * Add SendAsync to TxMgr Adds a SendAsync method to TxMgr. I'd like to use this for `op-deployer`, which needs to send multiple transactions in parallel but with predictable nonces. `SendAsync` returns a channel that resolves with the result of each send, but synchronously increases the nonce and prepares the first send prior to returning. * review updates + tests --- op-challenger/sender/sender_test.go | 4 + op-e2e/actions/l2_proposer.go | 4 + op-service/txmgr/mocks/TxManager.go | 5 + op-service/txmgr/txmgr.go | 93 +++++++- op-service/txmgr/txmgr_test.go | 342 +++++++++++++++------------- 5 files changed, 285 insertions(+), 163 deletions(-) diff --git a/op-challenger/sender/sender_test.go b/op-challenger/sender/sender_test.go index 2e0f09830605..c8fcae07a07b 100644 --- a/op-challenger/sender/sender_test.go +++ b/op-challenger/sender/sender_test.go @@ -128,6 +128,10 @@ func (s *stubTxMgr) Send(ctx context.Context, candidate txmgr.TxCandidate) (*typ return <-ch, nil } +func (s *stubTxMgr) SendAsync(ctx context.Context, candidate txmgr.TxCandidate, ch chan txmgr.SendResponse) { + panic("unimplemented") +} + func (s *stubTxMgr) recordTx(candidate txmgr.TxCandidate) chan *types.Receipt { s.m.Lock() defer s.m.Unlock() diff --git a/op-e2e/actions/l2_proposer.go b/op-e2e/actions/l2_proposer.go index 9298548f0abf..6f7edd0e5057 100644 --- a/op-e2e/actions/l2_proposer.go +++ b/op-e2e/actions/l2_proposer.go @@ -69,6 +69,10 @@ func (f fakeTxMgr) Send(_ context.Context, _ txmgr.TxCandidate) (*types.Receipt, panic("unimplemented") } +func (f fakeTxMgr) SendAsync(ctx context.Context, candidate txmgr.TxCandidate, ch chan txmgr.SendResponse) { + panic("unimplemented") +} + func (f fakeTxMgr) Close() { } diff --git a/op-service/txmgr/mocks/TxManager.go b/op-service/txmgr/mocks/TxManager.go index a6ea6b72a914..e0791c7bfbe2 100644 --- a/op-service/txmgr/mocks/TxManager.go +++ b/op-service/txmgr/mocks/TxManager.go @@ -120,6 +120,11 @@ func (_m *TxManager) Send(ctx context.Context, candidate txmgr.TxCandidate) (*ty return r0, r1 } +// SendAsync provides a mock function with given fields: ctx, candidate, ch +func (_m *TxManager) SendAsync(ctx context.Context, candidate txmgr.TxCandidate, ch chan txmgr.SendResponse) { + _m.Called(ctx, candidate, ch) +} + type mockConstructorTestingTNewTxManager interface { mock.TestingT Cleanup(func()) diff --git a/op-service/txmgr/txmgr.go b/op-service/txmgr/txmgr.go index 1093d7220957..fac48cf55ce0 100644 --- a/op-service/txmgr/txmgr.go +++ b/op-service/txmgr/txmgr.go @@ -46,6 +46,12 @@ var ( ErrClosed = errors.New("transaction manager is closed") ) +type SendResponse struct { + Receipt *types.Receipt + Nonce uint64 + Err error +} + // TxManager is an interface that allows callers to reliably publish txs, // bumping the gas price if needed, and obtain the receipt of the resulting tx. // @@ -63,6 +69,14 @@ type TxManager interface { // mempool and is in need of replacement or cancellation. Send(ctx context.Context, candidate TxCandidate) (*types.Receipt, error) + // SendAsync is used to create & send a transaction asynchronously. It has similar internal + // semantics to Send, however it returns a channel that will receive the result of the + // send operation once it completes. Transactions crafted synchronously - that is, nonce + // management and gas estimation happen prior to the method returning. This allows callers + // that rely on predictable nonces to send multiple transactions in parallel while preserving + // the order of nonce increments. + SendAsync(ctx context.Context, candidate TxCandidate, ch chan SendResponse) + // From returns the sending address associated with the instance of the transaction manager. // It is static for a single instance of a TxManager. From() common.Address @@ -222,24 +236,83 @@ func (m *SimpleTxManager) Send(ctx context.Context, candidate TxCandidate) (*typ if m.closed.Load() { return nil, ErrClosed } + m.metr.RecordPendingTx(m.pending.Add(1)) - defer func() { - m.metr.RecordPendingTx(m.pending.Add(-1)) - }() - receipt, err := m.send(ctx, candidate) + defer m.metr.RecordPendingTx(m.pending.Add(-1)) + + var cancel context.CancelFunc + if m.cfg.TxSendTimeout == 0 { + ctx, cancel = context.WithCancel(ctx) + } else { + ctx, cancel = context.WithTimeout(ctx, m.cfg.TxSendTimeout) + } + defer cancel() + + tx, err := m.prepare(ctx, candidate) if err != nil { m.resetNonce() + return nil, err + } + receipt, err := m.sendTx(ctx, tx) + if err != nil { + m.resetNonce() + return nil, err } return receipt, err } -// send performs the actual transaction creation and sending. -func (m *SimpleTxManager) send(ctx context.Context, candidate TxCandidate) (*types.Receipt, error) { - if m.cfg.TxSendTimeout != 0 { - var cancel context.CancelFunc +func (m *SimpleTxManager) SendAsync(ctx context.Context, candidate TxCandidate, ch chan SendResponse) { + if cap(ch) == 0 { + panic("SendAsync: channel must be buffered") + } + + // refuse new requests if the tx manager is closed + if m.closed.Load() { + ch <- SendResponse{ + Receipt: nil, + Err: ErrClosed, + } + return + } + + m.metr.RecordPendingTx(m.pending.Add(1)) + + var cancel context.CancelFunc + if m.cfg.TxSendTimeout == 0 { + ctx, cancel = context.WithCancel(ctx) + } else { ctx, cancel = context.WithTimeout(ctx, m.cfg.TxSendTimeout) - defer cancel() } + + tx, err := m.prepare(ctx, candidate) + if err != nil { + m.resetNonce() + cancel() + m.metr.RecordPendingTx(m.pending.Add(-1)) + ch <- SendResponse{ + Receipt: nil, + Err: err, + } + return + } + + go func() { + defer m.metr.RecordPendingTx(m.pending.Add(-1)) + defer cancel() + receipt, err := m.sendTx(ctx, tx) + if err != nil { + m.resetNonce() + } + ch <- SendResponse{ + Receipt: receipt, + Nonce: tx.Nonce(), + Err: err, + } + }() +} + +// prepare prepares the transaction for sending. +func (m *SimpleTxManager) prepare(ctx context.Context, candidate TxCandidate) (*types.Transaction, error) { tx, err := retry.Do(ctx, 30, retry.Fixed(2*time.Second), func() (*types.Transaction, error) { if m.closed.Load() { return nil, ErrClosed @@ -253,7 +326,7 @@ func (m *SimpleTxManager) send(ctx context.Context, candidate TxCandidate) (*typ if err != nil { return nil, fmt.Errorf("failed to create the tx: %w", err) } - return m.sendTx(ctx, tx) + return tx, nil } // craftTx creates the signed transaction diff --git a/op-service/txmgr/txmgr_test.go b/op-service/txmgr/txmgr_test.go index c5cf4bca40e5..e451597cd129 100644 --- a/op-service/txmgr/txmgr_test.go +++ b/op-service/txmgr/txmgr_test.go @@ -338,6 +338,27 @@ func (b *mockBackend) TransactionReceipt(ctx context.Context, txHash common.Hash func (b *mockBackend) Close() { } +type testSendVariantsFn func(ctx context.Context, h *testHarness, tx TxCandidate) (*types.Receipt, error) + +func testSendVariants(t *testing.T, testFn func(t *testing.T, send testSendVariantsFn)) { + t.Parallel() + + t.Run("Send", func(t *testing.T) { + testFn(t, func(ctx context.Context, h *testHarness, tx TxCandidate) (*types.Receipt, error) { + return h.mgr.Send(ctx, tx) + }) + }) + + t.Run("SendAsync", func(t *testing.T) { + testFn(t, func(ctx context.Context, h *testHarness, tx TxCandidate) (*types.Receipt, error) { + ch := make(chan SendResponse, 1) + h.mgr.SendAsync(ctx, tx, ch) + res := <-ch + return res.Receipt, res.Err + }) + }) +} + // TestTxMgrConfirmAtMinGasPrice asserts that Send returns the min gas price tx // if the tx is mined instantly. func TestTxMgrConfirmAtMinGasPrice(t *testing.T) { @@ -400,32 +421,32 @@ func TestTxMgrNeverConfirmCancel(t *testing.T) { // TestTxMgrTxSendTimeout tests that the TxSendTimeout is respected when trying to send a // transaction, even if NetworkTimeout expires first. func TestTxMgrTxSendTimeout(t *testing.T) { - t.Parallel() - - conf := configWithNumConfs(1) - conf.TxSendTimeout = 3 * time.Second - conf.NetworkTimeout = 1 * time.Second + testSendVariants(t, func(t *testing.T, send testSendVariantsFn) { + conf := configWithNumConfs(1) + conf.TxSendTimeout = 3 * time.Second + conf.NetworkTimeout = 1 * time.Second + + h := newTestHarnessWithConfig(t, conf) + + txCandidate := h.createTxCandidate() + sendCount := 0 + sendTx := func(ctx context.Context, tx *types.Transaction) error { + sendCount++ + <-ctx.Done() + return context.DeadlineExceeded + } + h.backend.setTxSender(sendTx) - h := newTestHarnessWithConfig(t, conf) + ctx, cancel := context.WithTimeout(context.Background(), time.Hour) + defer cancel() - txCandidate := h.createTxCandidate() - sendCount := 0 - sendTx := func(ctx context.Context, tx *types.Transaction) error { - sendCount++ - <-ctx.Done() - return context.DeadlineExceeded - } - h.backend.setTxSender(sendTx) - - ctx, cancel := context.WithTimeout(context.Background(), time.Hour) - defer cancel() - - receipt, err := h.mgr.send(ctx, txCandidate) - require.ErrorIs(t, err, context.DeadlineExceeded) - // Because network timeout is much shorter than send timeout, we should see multiple send attempts - // before the overall send fails. - require.Greater(t, sendCount, 1) - require.Nil(t, receipt) + receipt, err := send(ctx, h, txCandidate) + require.ErrorIs(t, err, context.DeadlineExceeded) + // Because network timeout is much shorter than send timeout, we should see multiple send attempts + // before the overall send fails. + require.Greater(t, sendCount, 1) + require.Nil(t, receipt) + }) } // TestAlreadyReserved tests that AlreadyReserved error results in immediate abort of transaction @@ -1326,40 +1347,42 @@ func TestErrStringMatch(t *testing.T) { } func TestNonceReset(t *testing.T) { - conf := configWithNumConfs(1) - conf.SafeAbortNonceTooLowCount = 1 - h := newTestHarnessWithConfig(t, conf) - - index := -1 - var nonces []uint64 - sendTx := func(ctx context.Context, tx *types.Transaction) error { - index++ - nonces = append(nonces, tx.Nonce()) - // fail every 3rd tx - if index%3 == 0 { - return core.ErrNonceTooLow + testSendVariants(t, func(t *testing.T, send testSendVariantsFn) { + conf := configWithNumConfs(1) + conf.SafeAbortNonceTooLowCount = 1 + h := newTestHarnessWithConfig(t, conf) + + index := -1 + var nonces []uint64 + sendTx := func(ctx context.Context, tx *types.Transaction) error { + index++ + nonces = append(nonces, tx.Nonce()) + // fail every 3rd tx + if index%3 == 0 { + return core.ErrNonceTooLow + } + txHash := tx.Hash() + h.backend.mine(&txHash, tx.GasFeeCap(), nil) + return nil } - txHash := tx.Hash() - h.backend.mine(&txHash, tx.GasFeeCap(), nil) - return nil - } - h.backend.setTxSender(sendTx) + h.backend.setTxSender(sendTx) - ctx := context.Background() - for i := 0; i < 8; i++ { - _, err := h.mgr.Send(ctx, TxCandidate{ - To: &common.Address{}, - }) - // expect every 3rd tx to fail - if i%3 == 0 { - require.Error(t, err) - } else { - require.NoError(t, err) + ctx := context.Background() + for i := 0; i < 8; i++ { + _, err := send(ctx, h, TxCandidate{ + To: &common.Address{}, + }) + // expect every 3rd tx to fail + if i%3 == 0 { + require.Error(t, err) + } else { + require.NoError(t, err) + } } - } - // internal nonce tracking should be reset to startingNonce value every 3rd tx - require.Equal(t, []uint64{1, 1, 2, 3, 1, 2, 3, 1}, nonces) + // internal nonce tracking should be reset to startingNonce value every 3rd tx + require.Equal(t, []uint64{1, 1, 2, 3, 1, 2, 3, 1}, nonces) + }) } func TestMinFees(t *testing.T) { @@ -1431,114 +1454,118 @@ func TestMinFees(t *testing.T) { // TestClose ensures that the tx manager will refuse new work and cancel any in progress func TestClose(t *testing.T) { - conf := configWithNumConfs(1) - h := newTestHarnessWithConfig(t, conf) - - sendingSignal := make(chan struct{}) - - // Ensure the manager is not closed - require.False(t, h.mgr.closed.Load()) - - // sendTx will fail until it is called a retry-number of times - called := 0 - const retries = 4 - sendTx := func(ctx context.Context, tx *types.Transaction) (err error) { - called += 1 - // sendingSignal is used when the tx begins to be sent - if called == 1 { - sendingSignal <- struct{}{} - } - if called%retries == 0 { - txHash := tx.Hash() - h.backend.mine(&txHash, tx.GasFeeCap(), big.NewInt(1)) - } else { - time.Sleep(10 * time.Millisecond) - err = errRpcFailure + testSendVariants(t, func(t *testing.T, send testSendVariantsFn) { + conf := configWithNumConfs(1) + h := newTestHarnessWithConfig(t, conf) + + sendingSignal := make(chan struct{}) + + // Ensure the manager is not closed + require.False(t, h.mgr.closed.Load()) + + // sendTx will fail until it is called a retry-number of times + called := 0 + const retries = 4 + sendTx := func(ctx context.Context, tx *types.Transaction) (err error) { + called += 1 + // sendingSignal is used when the tx begins to be sent + if called == 1 { + sendingSignal <- struct{}{} + } + if called%retries == 0 { + txHash := tx.Hash() + h.backend.mine(&txHash, tx.GasFeeCap(), big.NewInt(1)) + } else { + time.Sleep(10 * time.Millisecond) + err = errRpcFailure + } + return } - return - } - h.backend.setTxSender(sendTx) - - // on the first call, we don't use the sending signal but we still need to drain it - go func() { - <-sendingSignal - }() - // demonstrate that a tx is sent, even when it must retry repeatedly - ctx := context.Background() - _, err := h.mgr.Send(ctx, TxCandidate{ - To: &common.Address{}, - }) - require.NoError(t, err) - require.Equal(t, retries, called) - called = 0 - // Ensure the manager is *still* not closed - require.False(t, h.mgr.closed.Load()) - - // on the second call, we close the manager while the tx is in progress by consuming the sending signal - go func() { - <-sendingSignal - h.mgr.Close() - }() - // demonstrate that a tx will cancel if it is in progress when the manager is closed - _, err = h.mgr.Send(ctx, TxCandidate{ - To: &common.Address{}, - }) - require.ErrorIs(t, err, ErrClosed) - // confirm that the tx was canceled before it retried to completion - require.Less(t, called, retries) - require.True(t, h.mgr.closed.Load()) - called = 0 - - // demonstrate that new calls to Send will also fail when the manager is closed - // there should be no need to capture the sending signal here because the manager is already closed and will return immediately - _, err = h.mgr.Send(ctx, TxCandidate{ - To: &common.Address{}, + h.backend.setTxSender(sendTx) + + // on the first call, we don't use the sending signal but we still need to drain it + go func() { + <-sendingSignal + }() + // demonstrate that a tx is sent, even when it must retry repeatedly + ctx := context.Background() + _, err := send(ctx, h, TxCandidate{ + To: &common.Address{}, + }) + require.NoError(t, err) + require.Equal(t, retries, called) + called = 0 + // Ensure the manager is *still* not closed + require.False(t, h.mgr.closed.Load()) + + // on the second call, we close the manager while the tx is in progress by consuming the sending signal + go func() { + <-sendingSignal + h.mgr.Close() + }() + // demonstrate that a tx will cancel if it is in progress when the manager is closed + _, err = send(ctx, h, TxCandidate{ + To: &common.Address{}, + }) + require.ErrorIs(t, err, ErrClosed) + // confirm that the tx was canceled before it retried to completion + require.Less(t, called, retries) + require.True(t, h.mgr.closed.Load()) + called = 0 + + // demonstrate that new calls to Send will also fail when the manager is closed + // there should be no need to capture the sending signal here because the manager is already closed and will return immediately + _, err = send(ctx, h, TxCandidate{ + To: &common.Address{}, + }) + require.ErrorIs(t, err, ErrClosed) + // confirm that the tx was canceled before it ever made it to the backend + require.Equal(t, 0, called) }) - require.ErrorIs(t, err, ErrClosed) - // confirm that the tx was canceled before it ever made it to the backend - require.Equal(t, 0, called) } // TestCloseWaitingForConfirmation ensures that the tx manager will wait for confirmation of a tx in flight, even when closed func TestCloseWaitingForConfirmation(t *testing.T) { - // two confirmations required so that we can mine and not yet be fully confirmed - conf := configWithNumConfs(2) - h := newTestHarnessWithConfig(t, conf) + testSendVariants(t, func(t *testing.T, send testSendVariantsFn) { + // two confirmations required so that we can mine and not yet be fully confirmed + conf := configWithNumConfs(2) + h := newTestHarnessWithConfig(t, conf) - // sendDone is a signal that the tx has been sent from the sendTx function - sendDone := make(chan struct{}) - // closeDone is a signal that the txmanager has closed - closeDone := make(chan struct{}) + // sendDone is a signal that the tx has been sent from the sendTx function + sendDone := make(chan struct{}) + // closeDone is a signal that the txmanager has closed + closeDone := make(chan struct{}) - sendTx := func(ctx context.Context, tx *types.Transaction) error { - txHash := tx.Hash() - h.backend.mine(&txHash, tx.GasFeeCap(), big.NewInt(1)) - close(sendDone) - return nil - } - h.backend.setTxSender(sendTx) - - // this goroutine will close the manager when the tx sending is complete - // the transaction is not yet confirmed, so the manager will wait for confirmation - go func() { - <-sendDone - h.mgr.Close() - close(closeDone) - }() - - // this goroutine will complete confirmation of the tx when the manager is closed - // by forcing this to happen after close, we are able to observe a closing manager waiting for confirmation - go func() { - <-closeDone - h.backend.mine(nil, nil, big.NewInt(1)) - }() - - ctx := context.Background() - _, err := h.mgr.Send(ctx, TxCandidate{ - To: &common.Address{}, + sendTx := func(ctx context.Context, tx *types.Transaction) error { + txHash := tx.Hash() + h.backend.mine(&txHash, tx.GasFeeCap(), big.NewInt(1)) + close(sendDone) + return nil + } + h.backend.setTxSender(sendTx) + + // this goroutine will close the manager when the tx sending is complete + // the transaction is not yet confirmed, so the manager will wait for confirmation + go func() { + <-sendDone + h.mgr.Close() + close(closeDone) + }() + + // this goroutine will complete confirmation of the tx when the manager is closed + // by forcing this to happen after close, we are able to observe a closing manager waiting for confirmation + go func() { + <-closeDone + h.backend.mine(nil, nil, big.NewInt(1)) + }() + + ctx := context.Background() + _, err := send(ctx, h, TxCandidate{ + To: &common.Address{}, + }) + require.True(t, h.mgr.closed.Load()) + require.NoError(t, err) }) - require.True(t, h.mgr.closed.Load()) - require.NoError(t, err) } func TestMakeSidecar(t *testing.T) { @@ -1561,3 +1588,12 @@ func TestMakeSidecar(t *testing.T) { require.Equal(t, hashes[i], eth.KZGToVersionedHash(commit)) } } + +func TestSendAsyncUnbufferedChan(t *testing.T) { + conf := configWithNumConfs(2) + h := newTestHarnessWithConfig(t, conf) + + require.Panics(t, func() { + h.mgr.SendAsync(context.Background(), TxCandidate{}, make(chan SendResponse)) + }) +} From 232c54d44ba206220a9997b076c829d6000c79f5 Mon Sep 17 00:00:00 2001 From: AgusDuha <81362284+agusduha@users.noreply.github.com> Date: Thu, 12 Sep 2024 11:12:26 -0300 Subject: [PATCH 116/264] feat: introduce OptimismSuperchainERC20Factory (#11617) * test: add L2 standard bridge interop unit tests (#13) * test: add L2 standard bridge interop unit tests * fix: add tests natspec * fix: unit tests fixes * fix: super to legacy tests failing * fix: mock and expect mint and burn * fix: add generic factory interface (#14) * test: add L2 standard bridge interop unit tests * fix: add tests natspec * fix: add generic factory interface * feat: modify OptimismMintableERC20Factory for convert (#17) * test: add L2 standard bridge interop unit tests * fix: add tests natspec * fix: add generic factory interface * feat: modify OptimismMintableERC20Factory for convert * fix: use only a public function for create3 * feat: rollback interop factory, modify legacy one * fix: delete local token return variable * fix: PR fixes * feat: add superchain erc20 factory implementation (#23) * feat: add superchain erc20 factory implementation * fix: remove createX comments * test: add superchain erc20 factory tests (#25) * test: add superchain erc20 factory tests * test: add erc20 asserts * test: fix expect emit * fix: remove comments * feat: add constructor to superchain ERC20 beacon (#34) * test: remove factory predeploy etch ---------- Co-authored-by: 0xng Co-authored-by: 0xParticle Co-authored-by: gotzenx <78360669+gotzenx@users.noreply.github.com> * fix: set an arbitrary address for superchain erc20 impl * fix: deploy a proxy for the beacon on genesis (#45) --------- Co-authored-by: 0xng * fix: conflicts and imports * fix: interfaces * chore: add .testdata * fix: adding back .testdata to gitignore * fix: new conflicts from ci improvements --------- Co-authored-by: 0xng Co-authored-by: 0xParticle Co-authored-by: gotzenx <78360669+gotzenx@users.noreply.github.com> Co-authored-by: Disco <131301107+0xDiscotech@users.noreply.github.com> --- packages/contracts-bedrock/.gas-snapshot | 8 +- .../contracts-bedrock/scripts/Artifacts.s.sol | 4 + .../contracts-bedrock/scripts/L2Genesis.s.sol | 26 ++++ packages/contracts-bedrock/semver-lock.json | 8 ++ .../abi/OptimismSuperchainERC20Beacon.json | 39 ++++++ .../abi/OptimismSuperchainERC20Factory.json | 93 +++++++++++++++ .../OptimismSuperchainERC20Beacon.json | 1 + .../OptimismSuperchainERC20Factory.json | 9 ++ .../src/L2/OptimismSuperchainERC20Beacon.sol | 27 +++++ .../src/L2/OptimismSuperchainERC20Factory.sol | 62 ++++++++++ .../src/libraries/Predeploys.sol | 12 +- .../test/L2/L2StandardBridgeInterop.t.sol | 19 +-- .../test/L2/OptimismSuperchainERC20.t.sol | 31 ++++- .../L2/OptimismSuperchainERC20Factory.t.sol | 111 ++++++++++++++++++ .../contracts-bedrock/test/L2Genesis.t.sol | 4 +- .../contracts-bedrock/test/Predeploys.t.sol | 80 +++++++------ .../contracts-bedrock/test/setup/Setup.sol | 7 ++ 17 files changed, 483 insertions(+), 58 deletions(-) create mode 100644 packages/contracts-bedrock/snapshots/abi/OptimismSuperchainERC20Beacon.json create mode 100644 packages/contracts-bedrock/snapshots/abi/OptimismSuperchainERC20Factory.json create mode 100644 packages/contracts-bedrock/snapshots/storageLayout/OptimismSuperchainERC20Beacon.json create mode 100644 packages/contracts-bedrock/snapshots/storageLayout/OptimismSuperchainERC20Factory.json create mode 100644 packages/contracts-bedrock/src/L2/OptimismSuperchainERC20Beacon.sol create mode 100644 packages/contracts-bedrock/src/L2/OptimismSuperchainERC20Factory.sol create mode 100644 packages/contracts-bedrock/test/L2/OptimismSuperchainERC20Factory.t.sol diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index f42bdc83dcb7..ecfb713d05a0 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -6,12 +6,12 @@ GasBenchMark_L1Block_SetValuesEcotone:test_setL1BlockValuesEcotone_benchmark() ( GasBenchMark_L1Block_SetValuesEcotone_Warm:test_setL1BlockValuesEcotone_benchmark() (gas: 7597) GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 369242) GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2967382) -GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 564356) -GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4076571) +GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 564362) +GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4076577) GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 467019) GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3512701) GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 72618) -GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 92973) +GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 92970) GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68312) GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68943) -GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 155610) \ No newline at end of file +GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 155607) \ No newline at end of file diff --git a/packages/contracts-bedrock/scripts/Artifacts.s.sol b/packages/contracts-bedrock/scripts/Artifacts.s.sol index 350d3d99ae68..bfac0c367bfc 100644 --- a/packages/contracts-bedrock/scripts/Artifacts.s.sol +++ b/packages/contracts-bedrock/scripts/Artifacts.s.sol @@ -154,6 +154,10 @@ abstract contract Artifacts { return payable(Predeploys.SCHEMA_REGISTRY); } else if (digest == keccak256(bytes("EAS"))) { return payable(Predeploys.EAS); + } else if (digest == keccak256(bytes("OptimismSuperchainERC20Factory"))) { + return payable(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY); + } else if (digest == keccak256(bytes("OptimismSuperchainERC20Beacon"))) { + return payable(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_BEACON); } return payable(address(0)); } diff --git a/packages/contracts-bedrock/scripts/L2Genesis.s.sol b/packages/contracts-bedrock/scripts/L2Genesis.s.sol index 1ab494b052f8..2dccb76e5118 100644 --- a/packages/contracts-bedrock/scripts/L2Genesis.s.sol +++ b/packages/contracts-bedrock/scripts/L2Genesis.s.sol @@ -22,6 +22,7 @@ import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol"; import { BaseFeeVault } from "src/L2/BaseFeeVault.sol"; import { L1FeeVault } from "src/L2/L1FeeVault.sol"; +import { OptimismSuperchainERC20Beacon } from "src/L2/OptimismSuperchainERC20Beacon.sol"; import { OptimismMintableERC721Factory } from "src/universal/OptimismMintableERC721Factory.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol"; @@ -262,6 +263,8 @@ contract L2Genesis is Deployer { setL2ToL2CrossDomainMessenger(); // 23 setSuperchainWETH(); // 24 setETHLiquidity(); // 25 + setOptimismSuperchainERC20Factory(); // 26 + setOptimismSuperchainERC20Beacon(); // 27 } } @@ -513,6 +516,29 @@ contract L2Genesis is Deployer { _setImplementationCode(Predeploys.SUPERCHAIN_WETH); } + /// @notice This predeploy is following the safety invariant #1. + /// This contract has no initializer. + function setOptimismSuperchainERC20Factory() internal { + _setImplementationCode(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY); + } + + /// @notice This predeploy is following the safety invariant #2. + function setOptimismSuperchainERC20Beacon() internal { + address superchainERC20Impl = Predeploys.OPTIMISM_SUPERCHAIN_ERC20; + console.log("Setting %s implementation at: %s", "OptimismSuperchainERC20", superchainERC20Impl); + vm.etch(superchainERC20Impl, vm.getDeployedCode("OptimismSuperchainERC20.sol:OptimismSuperchainERC20")); + + OptimismSuperchainERC20Beacon beacon = new OptimismSuperchainERC20Beacon(superchainERC20Impl); + address beaconImpl = Predeploys.predeployToCodeNamespace(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_BEACON); + + console.log("Setting %s implementation at: %s", "OptimismSuperchainERC20Beacon", beaconImpl); + vm.etch(beaconImpl, address(beacon).code); + + /// Reset so its not included state dump + vm.etch(address(beacon), ""); + vm.resetNonce(address(beacon)); + } + /// @notice Sets all the preinstalls. /// Warning: the creator-accounts of the preinstall contracts have 0 nonce values. /// When performing a regular user-initiated contract-creation of a preinstall, diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 26872bdb2c73..01a17e96adb2 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -119,6 +119,14 @@ "initCodeHash": "0xdd16dbc0ccbbac53ec2d4273f06334960a907a9f20b7c40300833227ee31d0de", "sourceCodeHash": "0x910d43a17800df64dbc104f69ef1f900ca761cec4949c01d1c1126fde5268349" }, + "src/L2/OptimismSuperchainERC20Beacon.sol": { + "initCodeHash": "0x99ce8095b23c124850d866cbc144fee6cee05dbc6bb5d83acadfe00b90cf42c7", + "sourceCodeHash": "0x5e58b7c867fafa49fe39d68d83875425e9cf94f05f2835bdcdaa08fc8bc6b68e" + }, + "src/L2/OptimismSuperchainERC20Factory.sol": { + "initCodeHash": "0x98011045722178751e4a1112892f7d9a11bc1f5e42ac18205b6d30a1f1476d24", + "sourceCodeHash": "0x9e72b2a77d82fcf3963734232ba9faff9d63962594a032041c2561f0a9f1b0b5" + }, "src/L2/SequencerFeeVault.sol": { "initCodeHash": "0x2e6551705e493bacba8cffe22e564d5c401ae5bb02577a5424e0d32784e13e74", "sourceCodeHash": "0xd56922cb04597dea469c65e5a49d4b3c50c171e603601e6f41da9517cae0b11a" diff --git a/packages/contracts-bedrock/snapshots/abi/OptimismSuperchainERC20Beacon.json b/packages/contracts-bedrock/snapshots/abi/OptimismSuperchainERC20Beacon.json new file mode 100644 index 000000000000..0bdfc64ed2fe --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/OptimismSuperchainERC20Beacon.json @@ -0,0 +1,39 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/OptimismSuperchainERC20Factory.json b/packages/contracts-bedrock/snapshots/abi/OptimismSuperchainERC20Factory.json new file mode 100644 index 000000000000..7171cf1f3198 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/OptimismSuperchainERC20Factory.json @@ -0,0 +1,93 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "_decimals", + "type": "uint8" + } + ], + "name": "deploy", + "outputs": [ + { + "internalType": "address", + "name": "_superchainERC20", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "superchainToken", + "type": "address" + } + ], + "name": "deployments", + "outputs": [ + { + "internalType": "address", + "name": "remoteToken", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "superchainToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "remoteToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "deployer", + "type": "address" + } + ], + "name": "OptimismSuperchainERC20Created", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OptimismSuperchainERC20Beacon.json b/packages/contracts-bedrock/snapshots/storageLayout/OptimismSuperchainERC20Beacon.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/OptimismSuperchainERC20Beacon.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OptimismSuperchainERC20Factory.json b/packages/contracts-bedrock/snapshots/storageLayout/OptimismSuperchainERC20Factory.json new file mode 100644 index 000000000000..3dd455fbc1bd --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/OptimismSuperchainERC20Factory.json @@ -0,0 +1,9 @@ +[ + { + "bytes": "32", + "label": "deployments", + "offset": 0, + "slot": "0", + "type": "mapping(address => address)" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20Beacon.sol b/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20Beacon.sol new file mode 100644 index 000000000000..d1160819a2ec --- /dev/null +++ b/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20Beacon.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { IBeacon } from "@openzeppelin/contracts/proxy/beacon/IBeacon.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; + +/// @custom:proxied +/// @custom:predeployed 0x4200000000000000000000000000000000000027 +/// @title OptimismSuperchainERC20Beacon +/// @notice OptimismSuperchainERC20Beacon is the beacon proxy for the OptimismSuperchainERC20 implementation. +contract OptimismSuperchainERC20Beacon is IBeacon, ISemver { + /// @notice Address of the OptimismSuperchainERC20 implementation. + address internal immutable IMPLEMENTATION; + + /// @notice Semantic version. + /// @custom:semver 1.0.0-beta.1 + string public constant version = "1.0.0-beta.1"; + + constructor(address _implementation) { + IMPLEMENTATION = _implementation; + } + + /// @inheritdoc IBeacon + function implementation() external view override returns (address) { + return IMPLEMENTATION; + } +} diff --git a/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20Factory.sol b/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20Factory.sol new file mode 100644 index 000000000000..426510159720 --- /dev/null +++ b/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20Factory.sol @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +import { IOptimismERC20Factory } from "src/L2/interfaces/IOptimismERC20Factory.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { OptimismSuperchainERC20 } from "src/L2/OptimismSuperchainERC20.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { BeaconProxy } from "@openzeppelin/contracts-v5/proxy/beacon/BeaconProxy.sol"; +import { CREATE3 } from "@rari-capital/solmate/src/utils/CREATE3.sol"; + +/// @custom:proxied +/// @custom:predeployed 0x4200000000000000000000000000000000000026 +/// @title OptimismSuperchainERC20Factory +/// @notice OptimismSuperchainERC20Factory is a factory contract that deploys OptimismSuperchainERC20 Beacon Proxies +/// using CREATE3. +contract OptimismSuperchainERC20Factory is IOptimismERC20Factory, ISemver { + /// @notice Mapping of the deployed OptimismSuperchainERC20 to the remote token address. + /// This is used to keep track of the token deployments. + mapping(address superchainToken => address remoteToken) public deployments; + + /// @notice Emitted when an OptimismSuperchainERC20 is deployed. + /// @param superchainToken Address of the SuperchainERC20 deployment. + /// @param remoteToken Address of the corresponding token on the remote chain. + /// @param deployer Address of the account that deployed the token. + event OptimismSuperchainERC20Created( + address indexed superchainToken, address indexed remoteToken, address deployer + ); + + /// @notice Semantic version. + /// @custom:semver 1.0.0-beta.1 + string public constant version = "1.0.0-beta.1"; + + /// @notice Deploys a OptimismSuperchainERC20 Beacon Proxy using CREATE3. + /// @param _remoteToken Address of the remote token. + /// @param _name Name of the OptimismSuperchainERC20. + /// @param _symbol Symbol of the OptimismSuperchainERC20. + /// @param _decimals Decimals of the OptimismSuperchainERC20. + /// @return _superchainERC20 Address of the OptimismSuperchainERC20 deployment. + function deploy( + address _remoteToken, + string memory _name, + string memory _symbol, + uint8 _decimals + ) + external + returns (address _superchainERC20) + { + bytes memory initCallData = + abi.encodeCall(OptimismSuperchainERC20.initialize, (_remoteToken, _name, _symbol, _decimals)); + + bytes memory creationCode = bytes.concat( + type(BeaconProxy).creationCode, abi.encode(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_BEACON, initCallData) + ); + + bytes32 salt = keccak256(abi.encode(_remoteToken, _name, _symbol, _decimals)); + _superchainERC20 = CREATE3.deploy({ salt: salt, creationCode: creationCode, value: 0 }); + + deployments[_superchainERC20] = _remoteToken; + + emit OptimismSuperchainERC20Created(_superchainERC20, _remoteToken, msg.sender); + } +} diff --git a/packages/contracts-bedrock/src/libraries/Predeploys.sol b/packages/contracts-bedrock/src/libraries/Predeploys.sol index 9dcd7f0a95d0..c8fca4376bde 100644 --- a/packages/contracts-bedrock/src/libraries/Predeploys.sol +++ b/packages/contracts-bedrock/src/libraries/Predeploys.sol @@ -95,10 +95,16 @@ library Predeploys { /// @notice Address of the ETHLiquidity predeploy. address internal constant ETH_LIQUIDITY = 0x4200000000000000000000000000000000000025; - /// TODO: Add correct predeploy address for OptimismSuperchainERC20Factory /// @notice Address of the OptimismSuperchainERC20Factory predeploy. address internal constant OPTIMISM_SUPERCHAIN_ERC20_FACTORY = 0x4200000000000000000000000000000000000026; + /// @notice Address of the OptimismSuperchainERC20Beacon predeploy. + address internal constant OPTIMISM_SUPERCHAIN_ERC20_BEACON = 0x4200000000000000000000000000000000000027; + + // TODO: Precalculate the address of the implementation contract + /// @notice Arbitrary address of the OptimismSuperchainERC20 implementation contract. + address internal constant OPTIMISM_SUPERCHAIN_ERC20 = 0xB9415c6cA93bdC545D4c5177512FCC22EFa38F28; + /// @notice Returns the name of the predeploy at the given address. function getName(address _addr) internal pure returns (string memory out_) { require(isPredeployNamespace(_addr), "Predeploys: address must be a predeploy"); @@ -128,6 +134,7 @@ library Predeploys { if (_addr == SUPERCHAIN_WETH) return "SuperchainWETH"; if (_addr == ETH_LIQUIDITY) return "ETHLiquidity"; if (_addr == OPTIMISM_SUPERCHAIN_ERC20_FACTORY) return "OptimismSuperchainERC20Factory"; + if (_addr == OPTIMISM_SUPERCHAIN_ERC20_BEACON) return "OptimismSuperchainERC20Beacon"; revert("Predeploys: unnamed predeploy"); } @@ -146,7 +153,8 @@ library Predeploys { || _addr == L1_FEE_VAULT || _addr == SCHEMA_REGISTRY || _addr == EAS || _addr == GOVERNANCE_TOKEN || (_useInterop && _addr == CROSS_L2_INBOX) || (_useInterop && _addr == L2_TO_L2_CROSS_DOMAIN_MESSENGER) || (_useInterop && _addr == SUPERCHAIN_WETH) || (_useInterop && _addr == ETH_LIQUIDITY) - || (_useInterop && _addr == OPTIMISM_SUPERCHAIN_ERC20_FACTORY); + || (_useInterop && _addr == OPTIMISM_SUPERCHAIN_ERC20_FACTORY) + || (_useInterop && _addr == OPTIMISM_SUPERCHAIN_ERC20_BEACON); } function isPredeployNamespace(address _addr) internal pure returns (bool) { diff --git a/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol b/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol index 57c95147314d..8e90cd611d69 100644 --- a/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol +++ b/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol @@ -19,9 +19,6 @@ import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol import { IOptimismMintableERC20 } from "src/universal/interfaces/IOptimismMintableERC20.sol"; import { ILegacyMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; -// TODO: Replace Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY with optimismSuperchainERC20Factory -import { Predeploys } from "src/libraries/Predeploys.sol"; - contract L2StandardBridgeInterop_Test is Bridge_Initializer { /// @notice Emitted when a conversion is made. event Converted(address indexed from, address indexed to, address indexed caller, uint256 amount); @@ -30,10 +27,6 @@ contract L2StandardBridgeInterop_Test is Bridge_Initializer { function setUp() public virtual override { super.enableInterop(); super.setUp(); - - // TODO: Remove it once the `OptimismSuperchainERC20Factory` is added to predeploys. - // Ensure OPTIMISM_SUPERCHAIN_ERC20_FACTORY's code is not empty. - vm.etch(Predeploys.predeployToCodeNamespace(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY), address(this).code); } /// @notice Helper function to setup a mock and expect a call to it. @@ -146,7 +139,7 @@ contract L2StandardBridgeInterop_LegacyToSuper_Test is L2StandardBridgeInterop_T _mockDeployments(address(l2OptimismMintableERC20Factory), _from, _remoteToken); // Mock the superchain factory to return address(0) - _mockDeployments(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY, _to, address(0)); + _mockDeployments(address(l2OptimismSuperchainERC20Factory), _to, address(0)); // Expect the revert with `InvalidSuperchainERC20Address` selector vm.expectRevert(InvalidSuperchainERC20Address.selector); @@ -177,7 +170,7 @@ contract L2StandardBridgeInterop_LegacyToSuper_Test is L2StandardBridgeInterop_T _mockDeployments(address(l2OptimismMintableERC20Factory), _from, _fromRemoteToken); // Mock the superchain factory to return `_toRemoteToken` - _mockDeployments(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY, _to, _toRemoteToken); + _mockDeployments(address(l2OptimismSuperchainERC20Factory), _to, _toRemoteToken); // Expect the revert with `InvalidTokenPair` selector vm.expectRevert(InvalidTokenPair.selector); @@ -204,7 +197,7 @@ contract L2StandardBridgeInterop_LegacyToSuper_Test is L2StandardBridgeInterop_T // Mock the legacy and superchain factory to return `_remoteToken` _mockDeployments(address(l2OptimismMintableERC20Factory), _from, _remoteToken); - _mockDeployments(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY, _to, _remoteToken); + _mockDeployments(address(l2OptimismSuperchainERC20Factory), _to, _remoteToken); // Expect the `Converted` event to be emitted vm.expectEmit(address(l2StandardBridge)); @@ -300,7 +293,7 @@ contract L2StandardBridgeInterop_SuperToLegacy_Test is L2StandardBridgeInterop_T _mockDeployments(address(l2OptimismMintableERC20Factory), _to, _remoteToken); // Mock the superchain factory to return address(0) - _mockDeployments(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY, _from, address(0)); + _mockDeployments(address(l2OptimismSuperchainERC20Factory), _from, address(0)); // Expect the revert with `InvalidSuperchainERC20Address` selector vm.expectRevert(InvalidSuperchainERC20Address.selector); @@ -331,7 +324,7 @@ contract L2StandardBridgeInterop_SuperToLegacy_Test is L2StandardBridgeInterop_T _mockDeployments(address(l2OptimismMintableERC20Factory), _to, _fromRemoteToken); // Mock the superchain factory to return `_toRemoteToken` - _mockDeployments(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY, _from, _toRemoteToken); + _mockDeployments(address(l2OptimismSuperchainERC20Factory), _from, _toRemoteToken); // Expect the revert with `InvalidTokenPair` selector vm.expectRevert(InvalidTokenPair.selector); @@ -358,7 +351,7 @@ contract L2StandardBridgeInterop_SuperToLegacy_Test is L2StandardBridgeInterop_T // Mock the legacy and superchain factory to return `_remoteToken` _mockDeployments(address(l2OptimismMintableERC20Factory), _to, _remoteToken); - _mockDeployments(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY, _from, _remoteToken); + _mockDeployments(address(l2OptimismSuperchainERC20Factory), _from, _remoteToken); // Expect the `Converted` event to be emitted vm.expectEmit(address(l2StandardBridge)); diff --git a/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20.t.sol b/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20.t.sol index 0e82aca948a2..0fc7d88d0b7c 100644 --- a/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20.t.sol +++ b/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20.t.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.25; // Testing utilities import { Test } from "forge-std/Test.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; // Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; @@ -11,6 +12,8 @@ import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomai import { ERC1967Proxy } from "@openzeppelin/contracts-v5/proxy/ERC1967/ERC1967Proxy.sol"; import { Initializable } from "@openzeppelin/contracts-v5/proxy/utils/Initializable.sol"; import { IERC165 } from "@openzeppelin/contracts-v5/utils/introspection/IERC165.sol"; +import { IBeacon } from "@openzeppelin/contracts-v5/proxy/beacon/IBeacon.sol"; +import { BeaconProxy } from "@openzeppelin/contracts-v5/proxy/beacon/BeaconProxy.sol"; // Target contract import { @@ -40,9 +43,32 @@ contract OptimismSuperchainERC20Test is Test { /// @notice Sets up the test suite. function setUp() public { superchainERC20Impl = new OptimismSuperchainERC20(); + + // Deploy the OptimismSuperchainERC20Beacon contract + _deployBeacon(); + superchainERC20 = _deploySuperchainERC20Proxy(REMOTE_TOKEN, NAME, SYMBOL, DECIMALS); } + /// @notice Deploy the OptimismSuperchainERC20Beacon predeploy contract + function _deployBeacon() internal { + // Deploy the OptimismSuperchainERC20Beacon implementation + address _addr = Predeploys.OPTIMISM_SUPERCHAIN_ERC20_BEACON; + address _impl = Predeploys.predeployToCodeNamespace(_addr); + vm.etch(_impl, vm.getDeployedCode("OptimismSuperchainERC20Beacon.sol:OptimismSuperchainERC20Beacon")); + + // Deploy the ERC1967Proxy contract at the Predeploy + bytes memory code = vm.getDeployedCode("universal/Proxy.sol:Proxy"); + vm.etch(_addr, code); + EIP1967Helper.setAdmin(_addr, Predeploys.PROXY_ADMIN); + EIP1967Helper.setImplementation(_addr, _impl); + + // Mock implementation address + vm.mockCall( + _impl, abi.encodeWithSelector(IBeacon.implementation.selector), abi.encode(address(superchainERC20Impl)) + ); + } + /// @notice Helper function to deploy a proxy of the OptimismSuperchainERC20 contract. function _deploySuperchainERC20Proxy( address _remoteToken, @@ -55,9 +81,8 @@ contract OptimismSuperchainERC20Test is Test { { return OptimismSuperchainERC20( address( - // TODO: Use the SuperchainERC20 Beacon Proxy - new ERC1967Proxy( - address(superchainERC20Impl), + new BeaconProxy( + Predeploys.OPTIMISM_SUPERCHAIN_ERC20_BEACON, abi.encodeCall(OptimismSuperchainERC20.initialize, (_remoteToken, _name, _symbol, _decimals)) ) ) diff --git a/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20Factory.t.sol b/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20Factory.t.sol new file mode 100644 index 000000000000..3951ebf7452e --- /dev/null +++ b/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20Factory.t.sol @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +// Testing utilities +import { Test } from "forge-std/Test.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; + +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { CREATE3, Bytes32AddressLib } from "@rari-capital/solmate/src/utils/CREATE3.sol"; +import { IBeacon } from "@openzeppelin/contracts-v5/proxy/beacon/IBeacon.sol"; + +// Target contract +import { OptimismSuperchainERC20Factory, OptimismSuperchainERC20 } from "src/L2/OptimismSuperchainERC20Factory.sol"; + +/// @title OptimismSuperchainERC20FactoryTest +/// @notice Contract for testing the OptimismSuperchainERC20Factory contract. +contract OptimismSuperchainERC20FactoryTest is Test { + using Bytes32AddressLib for bytes32; + + OptimismSuperchainERC20 public superchainERC20Impl; + OptimismSuperchainERC20Factory public superchainERC20Factory; + + /// @notice Sets up the test suite. + function setUp() public { + superchainERC20Impl = new OptimismSuperchainERC20(); + + // Deploy the OptimismSuperchainERC20Beacon contract + _deployBeacon(); + + superchainERC20Factory = new OptimismSuperchainERC20Factory(); + } + + /// @notice Deploy the OptimismSuperchainERC20Beacon predeploy contract + function _deployBeacon() internal { + // Deploy the OptimismSuperchainERC20Beacon implementation + address _addr = Predeploys.OPTIMISM_SUPERCHAIN_ERC20_BEACON; + address _impl = Predeploys.predeployToCodeNamespace(_addr); + vm.etch(_impl, vm.getDeployedCode("OptimismSuperchainERC20Beacon.sol:OptimismSuperchainERC20Beacon")); + + // Deploy the ERC1967Proxy contract at the Predeploy + bytes memory code = vm.getDeployedCode("universal/Proxy.sol:Proxy"); + vm.etch(_addr, code); + EIP1967Helper.setAdmin(_addr, Predeploys.PROXY_ADMIN); + EIP1967Helper.setImplementation(_addr, _impl); + + // Mock implementation address + vm.mockCall( + _impl, abi.encodeWithSelector(IBeacon.implementation.selector), abi.encode(address(superchainERC20Impl)) + ); + } + + /// @notice Test that calling `deploy` with valid parameters succeeds. + function test_deploy_succeeds( + address _caller, + address _remoteToken, + string memory _name, + string memory _symbol, + uint8 _decimals + ) + public + { + // Arrange + bytes32 salt = keccak256(abi.encode(_remoteToken, _name, _symbol, _decimals)); + address deployment = _calculateTokenAddress(salt, address(superchainERC20Factory)); + + vm.expectEmit(address(superchainERC20Factory)); + emit OptimismSuperchainERC20Factory.OptimismSuperchainERC20Created(deployment, _remoteToken, _caller); + + // Act + vm.prank(_caller); + address addr = superchainERC20Factory.deploy(_remoteToken, _name, _symbol, _decimals); + + // Assert + assertTrue(addr == deployment); + assertTrue(OptimismSuperchainERC20(deployment).decimals() == _decimals); + assertTrue(OptimismSuperchainERC20(deployment).remoteToken() == _remoteToken); + assertEq(OptimismSuperchainERC20(deployment).name(), _name); + assertEq(OptimismSuperchainERC20(deployment).symbol(), _symbol); + assertEq(superchainERC20Factory.deployments(deployment), _remoteToken); + } + + /// @notice Test that calling `deploy` with the same parameters twice reverts. + function test_deploy_sameTwice_reverts( + address _caller, + address _remoteToken, + string memory _name, + string memory _symbol, + uint8 _decimals + ) + external + { + // Arrange + vm.prank(_caller); + superchainERC20Factory.deploy(_remoteToken, _name, _symbol, _decimals); + + vm.expectRevert(bytes("DEPLOYMENT_FAILED")); + + // Act + vm.prank(_caller); + superchainERC20Factory.deploy(_remoteToken, _name, _symbol, _decimals); + } + + /// @notice Precalculates the address of the token contract using CREATE3. + function _calculateTokenAddress(bytes32 _salt, address _deployer) internal pure returns (address) { + address proxy = + keccak256(abi.encodePacked(bytes1(0xFF), _deployer, _salt, CREATE3.PROXY_BYTECODE_HASH)).fromLast20Bytes(); + + return keccak256(abi.encodePacked(hex"d694", proxy, hex"01")).fromLast20Bytes(); + } +} diff --git a/packages/contracts-bedrock/test/L2Genesis.t.sol b/packages/contracts-bedrock/test/L2Genesis.t.sol index be5cc0c50edf..ee993fe1110c 100644 --- a/packages/contracts-bedrock/test/L2Genesis.t.sol +++ b/packages/contracts-bedrock/test/L2Genesis.t.sol @@ -150,8 +150,8 @@ contract L2GenesisTest is Test { // 2 predeploys do not have proxies assertEq(getCodeCount(_path, "Proxy.sol:Proxy"), Predeploys.PREDEPLOY_COUNT - 2); - // 22 proxies have the implementation set if useInterop is true and 17 if useInterop is false - assertEq(getPredeployCountWithSlotSet(_path, Constants.PROXY_IMPLEMENTATION_ADDRESS), _useInterop ? 22 : 17); + // 23 proxies have the implementation set if useInterop is true and 17 if useInterop is false + assertEq(getPredeployCountWithSlotSet(_path, Constants.PROXY_IMPLEMENTATION_ADDRESS), _useInterop ? 23 : 17); // All proxies except 2 have the proxy 1967 admin slot set to the proxy admin assertEq( diff --git a/packages/contracts-bedrock/test/Predeploys.t.sol b/packages/contracts-bedrock/test/Predeploys.t.sol index d39eb8b0ff61..0d9e4879fd6b 100644 --- a/packages/contracts-bedrock/test/Predeploys.t.sol +++ b/packages/contracts-bedrock/test/Predeploys.t.sol @@ -7,26 +7,21 @@ import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; /// @title PredeploysTest -contract PredeploysTest is CommonTest { +contract PredeploysBaseTest is CommonTest { ////////////////////////////////////////////////////// /// Internal helpers ////////////////////////////////////////////////////// - /// @dev Returns true if the address is a predeploy that is active (i.e. embedded in L2 genesis). - function _isPredeploy(address _addr) internal pure returns (bool) { - return _addr == Predeploys.L2_TO_L1_MESSAGE_PASSER || _addr == Predeploys.L2_CROSS_DOMAIN_MESSENGER - || _addr == Predeploys.L2_STANDARD_BRIDGE || _addr == Predeploys.L2_ERC721_BRIDGE - || _addr == Predeploys.SEQUENCER_FEE_WALLET || _addr == Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY - || _addr == Predeploys.OPTIMISM_MINTABLE_ERC721_FACTORY || _addr == Predeploys.L1_BLOCK_ATTRIBUTES - || _addr == Predeploys.GAS_PRICE_ORACLE || _addr == Predeploys.DEPLOYER_WHITELIST || _addr == Predeploys.WETH - || _addr == Predeploys.L1_BLOCK_NUMBER || _addr == Predeploys.LEGACY_MESSAGE_PASSER - || _addr == Predeploys.PROXY_ADMIN || _addr == Predeploys.BASE_FEE_VAULT || _addr == Predeploys.L1_FEE_VAULT - || _addr == Predeploys.GOVERNANCE_TOKEN || _addr == Predeploys.SCHEMA_REGISTRY || _addr == Predeploys.EAS; + /// @dev Returns true if the address is an interop predeploy. + function _isInterop(address _addr) internal pure returns (bool) { + return _addr == Predeploys.CROSS_L2_INBOX || _addr == Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER + || _addr == Predeploys.SUPERCHAIN_WETH || _addr == Predeploys.ETH_LIQUIDITY + || _addr == Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY || _addr == Predeploys.OPTIMISM_SUPERCHAIN_ERC20_BEACON; } - /// @dev Returns true if the address is not proxied. - function _notProxied(address _addr) internal pure returns (bool) { - return _addr == Predeploys.GOVERNANCE_TOKEN || _addr == Predeploys.WETH; + /// @dev Returns true if the address is a predeploy that has a different code in the interop mode. + function _interopCodeDiffer(address _addr) internal pure returns (bool) { + return _addr == Predeploys.L1_BLOCK_ATTRIBUTES || _addr == Predeploys.L2_STANDARD_BRIDGE; } /// @dev Returns true if the account is not meant to be in the L2 genesis anymore. @@ -34,22 +29,17 @@ contract PredeploysTest is CommonTest { return _addr == Predeploys.L1_MESSAGE_SENDER; } + /// @dev Returns true if the predeploy is initializable. function _isInitializable(address _addr) internal pure returns (bool) { - return !( - _addr == Predeploys.LEGACY_MESSAGE_PASSER || _addr == Predeploys.DEPLOYER_WHITELIST - || _addr == Predeploys.GAS_PRICE_ORACLE || _addr == Predeploys.SEQUENCER_FEE_WALLET - || _addr == Predeploys.BASE_FEE_VAULT || _addr == Predeploys.L1_FEE_VAULT - || _addr == Predeploys.L1_BLOCK_NUMBER || _addr == Predeploys.L1_BLOCK_ATTRIBUTES - || _addr == Predeploys.L2_TO_L1_MESSAGE_PASSER || _addr == Predeploys.OPTIMISM_MINTABLE_ERC721_FACTORY - || _addr == Predeploys.PROXY_ADMIN || _addr == Predeploys.SCHEMA_REGISTRY || _addr == Predeploys.EAS - || _addr == Predeploys.GOVERNANCE_TOKEN - ); + return _addr == Predeploys.L2_CROSS_DOMAIN_MESSENGER || _addr == Predeploys.L2_STANDARD_BRIDGE + || _addr == Predeploys.L2_ERC721_BRIDGE || _addr == Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY; } + /// @dev Returns true if the predeploy uses immutables. function _usesImmutables(address _addr) internal pure returns (bool) { return _addr == Predeploys.OPTIMISM_MINTABLE_ERC721_FACTORY || _addr == Predeploys.SEQUENCER_FEE_WALLET || _addr == Predeploys.BASE_FEE_VAULT || _addr == Predeploys.L1_FEE_VAULT || _addr == Predeploys.EAS - || _addr == Predeploys.GOVERNANCE_TOKEN; + || _addr == Predeploys.GOVERNANCE_TOKEN || _addr == Predeploys.OPTIMISM_SUPERCHAIN_ERC20_BEACON; } function test_predeployToCodeNamespace() external pure { @@ -67,9 +57,7 @@ contract PredeploysTest is CommonTest { ); } - /// @dev Tests that the predeploy addresses are set correctly. They have code - /// and the proxied accounts have the correct admin. - function test_predeploys_succeeds() external { + function _test_predeploys(bool _useInterop) internal { uint256 count = 2048; uint160 prefix = uint160(0x420) << 148; @@ -77,23 +65,25 @@ contract PredeploysTest is CommonTest { for (uint256 i = 0; i < count; i++) { address addr = address(prefix | uint160(i)); - bytes memory code = addr.code; - assertTrue(code.length > 0); - address implAddr = Predeploys.predeployToCodeNamespace(addr); if (_isOmitted(addr)) { assertEq(implAddr.code.length, 0, "must have no code"); continue; } - bool isPredeploy = _isPredeploy(addr); + + bool isPredeploy = Predeploys.isSupportedPredeploy(addr, _useInterop); + + bytes memory code = addr.code; + if (isPredeploy) assertTrue(code.length > 0); + + bool proxied = Predeploys.notProxied(addr) == false; if (!isPredeploy) { // All of the predeploys, even if inactive, have their admin set to the proxy admin - assertEq(EIP1967Helper.getAdmin(addr), Predeploys.PROXY_ADMIN, "Admin mismatch"); + if (proxied) assertEq(EIP1967Helper.getAdmin(addr), Predeploys.PROXY_ADMIN, "Admin mismatch"); continue; } - bool proxied = _notProxied(addr) == false; string memory cname = Predeploys.getName(addr); assertNotEq(cname, "", "must have a name"); @@ -118,7 +108,7 @@ contract PredeploysTest is CommonTest { string.concat("Implementation mismatch for ", vm.toString(addr)) ); assertNotEq(implAddr.code.length, 0, "predeploy implementation account must have code"); - if (!_usesImmutables(addr)) { + if (!_usesImmutables(addr) && !_interopCodeDiffer(addr)) { // can't check bytecode if it's modified with immutables in genesis. assertEq(implAddr.code, supposedCode, "proxy implementation contract should match contract source"); } @@ -129,3 +119,25 @@ contract PredeploysTest is CommonTest { } } } + +contract PredeploysTest is PredeploysBaseTest { + /// @dev Tests that the predeploy addresses are set correctly. They have code + /// and the proxied accounts have the correct admin. + function test_predeploys_succeeds() external { + _test_predeploys(false); + } +} + +contract PredeploysInteropTest is PredeploysBaseTest { + /// @notice Test setup. Enabling interop to get all predeploys. + function setUp() public virtual override { + super.enableInterop(); + super.setUp(); + } + + /// @dev Tests that the predeploy addresses are set correctly. They have code + /// and the proxied accounts have the correct admin. Using interop. + function test_predeploys_succeeds() external { + _test_predeploys(true); + } +} diff --git a/packages/contracts-bedrock/test/setup/Setup.sol b/packages/contracts-bedrock/test/setup/Setup.sol index 5bfd5328144c..74c1225116e5 100644 --- a/packages/contracts-bedrock/test/setup/Setup.sol +++ b/packages/contracts-bedrock/test/setup/Setup.sol @@ -51,6 +51,7 @@ import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol"; import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol"; import { IAddressManager } from "src/legacy/interfaces/IAddressManager.sol"; +import { IOptimismERC20Factory } from "src/L2/interfaces/IOptimismERC20Factory.sol"; /// @title Setup /// @dev This contact is responsible for setting up the contracts in state. It currently @@ -109,6 +110,10 @@ contract Setup { SuperchainWETH superchainWeth = SuperchainWETH(payable(Predeploys.SUPERCHAIN_WETH)); ETHLiquidity ethLiquidity = ETHLiquidity(Predeploys.ETH_LIQUIDITY); + // TODO: Replace with OptimismSuperchainERC20Factory when updating pragmas + IOptimismERC20Factory l2OptimismSuperchainERC20Factory = + IOptimismERC20Factory(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY); + /// @dev Deploys the Deploy contract without including its bytecode in the bytecode /// of this contract by fetching the bytecode dynamically using `vm.getCode()`. /// If the Deploy bytecode is included in this contract, then it will double @@ -227,6 +232,8 @@ contract Setup { labelPredeploy(Predeploys.WETH); labelPredeploy(Predeploys.SUPERCHAIN_WETH); labelPredeploy(Predeploys.ETH_LIQUIDITY); + labelPredeploy(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY); + labelPredeploy(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_BEACON); // L2 Preinstalls labelPreinstall(Preinstalls.MultiCall3); From 0260adb1b6bd5bbed27efb5231ef927c110fbf19 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Thu, 12 Sep 2024 10:38:53 -0400 Subject: [PATCH 117/264] fix: do not delete test data directory (#11869) Our "just clean" command was deleting the entirety of .testdata which gets in several scripts now. We don't actually want to delete the entirety of .testdata, we want to delete anything inside of it (except for the gitkeep file). --- packages/contracts-bedrock/justfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/justfile b/packages/contracts-bedrock/justfile index 49b39c0c4837..bf96fd17cad1 100644 --- a/packages/contracts-bedrock/justfile +++ b/packages/contracts-bedrock/justfile @@ -111,8 +111,11 @@ validate-spacers-no-build: validate-spacers: build validate-spacers-no-build +# Cleans build artifacts and deployments. +# Removes everything inside of .testdata (except the .gitkeep file). clean: - rm -rf ./artifacts ./forge-artifacts ./cache ./scripts/go-ffi/go-ffi ./.testdata ./deployments/hardhat/* + rm -rf ./artifacts ./forge-artifacts ./cache ./scripts/go-ffi/go-ffi ./deployments/hardhat/* + find ./.testdata -mindepth 1 -not -name '.gitkeep' -delete pre-pr-no-build: gas-snapshot-no-build snapshots-no-build semver-lock autogen-invariant-docs lint From 849680b836a6b014e967abca062c48eded237d07 Mon Sep 17 00:00:00 2001 From: Sebastian Stammler Date: Thu, 12 Sep 2024 17:04:05 +0200 Subject: [PATCH 118/264] codeowners: move go-reviewers team at the end (#11877) --- .github/CODEOWNERS | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0d55c426dc98..4c22e9eda31e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,28 +2,28 @@ * @ethereum-optimism/go-reviewers # OP Stack general -/bedrock-devnet @ethereum-optimism/go-reviewers @ethereum-optimism/op-stack -/op-alt-da @ethereum-optimism/go-reviewers @ethereum-optimism/op-stack -/op-batcher @ethereum-optimism/go-reviewers @ethereum-optimism/op-stack -/op-chain-ops @ethereum-optimism/go-reviewers @ethereum-optimism/op-stack -/op-e2e @ethereum-optimism/go-reviewers @ethereum-optimism/op-stack -/op-node @ethereum-optimism/go-reviewers @ethereum-optimism/op-stack -/op-proposer @ethereum-optimism/go-reviewers @ethereum-optimism/op-stack -/op-wheel @ethereum-optimism/go-reviewers @ethereum-optimism/op-stack -/ops-bedrock @ethereum-optimism/go-reviewers @ethereum-optimism/op-stack +/bedrock-devnet @ethereum-optimism/op-stack @ethereum-optimism/go-reviewers +/op-alt-da @ethereum-optimism/op-stack @ethereum-optimism/go-reviewers +/op-batcher @ethereum-optimism/op-stack @ethereum-optimism/go-reviewers +/op-chain-ops @ethereum-optimism/op-stack @ethereum-optimism/go-reviewers +/op-e2e @ethereum-optimism/op-stack @ethereum-optimism/go-reviewers +/op-node @ethereum-optimism/op-stack @ethereum-optimism/go-reviewers +/op-proposer @ethereum-optimism/op-stack @ethereum-optimism/go-reviewers +/op-wheel @ethereum-optimism/op-stack @ethereum-optimism/go-reviewers +/ops-bedrock @ethereum-optimism/op-stack @ethereum-optimism/go-reviewers # Expert areas -/op-node/rollup @ethereum-optimism/go-reviewers @ethereum-optimism/consensus +/op-node/rollup @ethereum-optimism/consensus @ethereum-optimism/go-reviewers -/op-supervisor @ethereum-optimism/go-reviewers @ethereum-optimism/interop +/op-supervisor @ethereum-optimism/interop @ethereum-optimism/go-reviewers -/op-conductor @ethereum-optimism/go-reviewers @ethereum-optimism/op-conductor +/op-conductor @ethereum-optimism/op-conductor @ethereum-optimism/go-reviewers -/cannon @ethereum-optimism/go-reviewers @ethereum-optimism/proofs -/op-dispute-mon @ethereum-optimism/go-reviewers @ethereum-optimism/proofs -/op-challenger @ethereum-optimism/go-reviewers @ethereum-optimism/proofs -/op-preimage @ethereum-optimism/go-reviewers @ethereum-optimism/proofs -/op-program @ethereum-optimism/go-reviewers @ethereum-optimism/proofs +/cannon @ethereum-optimism/proofs @ethereum-optimism/go-reviewers +/op-dispute-mon @ethereum-optimism/proofs @ethereum-optimism/go-reviewers +/op-challenger @ethereum-optimism/proofs @ethereum-optimism/go-reviewers +/op-preimage @ethereum-optimism/proofs @ethereum-optimism/go-reviewers +/op-program @ethereum-optimism/proofs @ethereum-optimism/go-reviewers # Ops /.circleci @ethereum-optimism/monorepo-ops-reviewers From 87af6f0d033996b0cad2437f75fe8bc626a2b5d5 Mon Sep 17 00:00:00 2001 From: Sebastian Stammler Date: Thu, 12 Sep 2024 17:33:58 +0200 Subject: [PATCH 119/264] txmgr: improve code sharing between Send and SendAsync (#11876) --- op-service/txmgr/txmgr.go | 61 +++++++++------------------------- op-service/txmgr/txmgr_test.go | 12 ++----- 2 files changed, 17 insertions(+), 56 deletions(-) diff --git a/op-service/txmgr/txmgr.go b/op-service/txmgr/txmgr.go index fac48cf55ce0..ba4b8eaecfe9 100644 --- a/op-service/txmgr/txmgr.go +++ b/op-service/txmgr/txmgr.go @@ -232,9 +232,14 @@ type TxCandidate struct { // // NOTE: Send can be called concurrently, the nonce will be managed internally. func (m *SimpleTxManager) Send(ctx context.Context, candidate TxCandidate) (*types.Receipt, error) { + _, r, err := m.send(ctx, candidate) + return r, err +} + +func (m *SimpleTxManager) send(ctx context.Context, candidate TxCandidate) (*types.Transaction, *types.Receipt, error) { // refuse new requests if the tx manager is closed if m.closed.Load() { - return nil, ErrClosed + return nil, nil, ErrClosed } m.metr.RecordPendingTx(m.pending.Add(1)) @@ -251,63 +256,27 @@ func (m *SimpleTxManager) Send(ctx context.Context, candidate TxCandidate) (*typ tx, err := m.prepare(ctx, candidate) if err != nil { m.resetNonce() - return nil, err + return tx, nil, err } receipt, err := m.sendTx(ctx, tx) if err != nil { m.resetNonce() - return nil, err + return nil, nil, err } - return receipt, err + return tx, receipt, err } func (m *SimpleTxManager) SendAsync(ctx context.Context, candidate TxCandidate, ch chan SendResponse) { - if cap(ch) == 0 { - panic("SendAsync: channel must be buffered") - } - - // refuse new requests if the tx manager is closed - if m.closed.Load() { - ch <- SendResponse{ - Receipt: nil, - Err: ErrClosed, - } - return - } - - m.metr.RecordPendingTx(m.pending.Add(1)) - - var cancel context.CancelFunc - if m.cfg.TxSendTimeout == 0 { - ctx, cancel = context.WithCancel(ctx) - } else { - ctx, cancel = context.WithTimeout(ctx, m.cfg.TxSendTimeout) - } - - tx, err := m.prepare(ctx, candidate) - if err != nil { - m.resetNonce() - cancel() - m.metr.RecordPendingTx(m.pending.Add(-1)) - ch <- SendResponse{ - Receipt: nil, - Err: err, - } - return - } - go func() { - defer m.metr.RecordPendingTx(m.pending.Add(-1)) - defer cancel() - receipt, err := m.sendTx(ctx, tx) - if err != nil { - m.resetNonce() - } - ch <- SendResponse{ + tx, receipt, err := m.send(ctx, candidate) + r := SendResponse{ Receipt: receipt, - Nonce: tx.Nonce(), Err: err, } + if tx != nil { + r.Nonce = tx.Nonce() + } + ch <- r }() } diff --git a/op-service/txmgr/txmgr_test.go b/op-service/txmgr/txmgr_test.go index e451597cd129..945ae5a04b8c 100644 --- a/op-service/txmgr/txmgr_test.go +++ b/op-service/txmgr/txmgr_test.go @@ -351,7 +351,8 @@ func testSendVariants(t *testing.T, testFn func(t *testing.T, send testSendVaria t.Run("SendAsync", func(t *testing.T) { testFn(t, func(ctx context.Context, h *testHarness, tx TxCandidate) (*types.Receipt, error) { - ch := make(chan SendResponse, 1) + // unbuffered is ok, will be written to from a goroutine spawned inside SendAsync + ch := make(chan SendResponse) h.mgr.SendAsync(ctx, tx, ch) res := <-ch return res.Receipt, res.Err @@ -1588,12 +1589,3 @@ func TestMakeSidecar(t *testing.T) { require.Equal(t, hashes[i], eth.KZGToVersionedHash(commit)) } } - -func TestSendAsyncUnbufferedChan(t *testing.T) { - conf := configWithNumConfs(2) - h := newTestHarnessWithConfig(t, conf) - - require.Panics(t, func() { - h.mgr.SendAsync(context.Background(), TxCandidate{}, make(chan SendResponse)) - }) -} From fe4890f640a42955a4ee2c7fadfffa105c2b600f Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Thu, 12 Sep 2024 11:33:34 -0600 Subject: [PATCH 120/264] Revert "txmgr: improve code sharing between Send and SendAsync (#11876)" (#11883) This reverts commit 87af6f0d033996b0cad2437f75fe8bc626a2b5d5. --- op-service/txmgr/txmgr.go | 61 +++++++++++++++++++++++++--------- op-service/txmgr/txmgr_test.go | 12 +++++-- 2 files changed, 56 insertions(+), 17 deletions(-) diff --git a/op-service/txmgr/txmgr.go b/op-service/txmgr/txmgr.go index ba4b8eaecfe9..fac48cf55ce0 100644 --- a/op-service/txmgr/txmgr.go +++ b/op-service/txmgr/txmgr.go @@ -232,14 +232,9 @@ type TxCandidate struct { // // NOTE: Send can be called concurrently, the nonce will be managed internally. func (m *SimpleTxManager) Send(ctx context.Context, candidate TxCandidate) (*types.Receipt, error) { - _, r, err := m.send(ctx, candidate) - return r, err -} - -func (m *SimpleTxManager) send(ctx context.Context, candidate TxCandidate) (*types.Transaction, *types.Receipt, error) { // refuse new requests if the tx manager is closed if m.closed.Load() { - return nil, nil, ErrClosed + return nil, ErrClosed } m.metr.RecordPendingTx(m.pending.Add(1)) @@ -256,27 +251,63 @@ func (m *SimpleTxManager) send(ctx context.Context, candidate TxCandidate) (*typ tx, err := m.prepare(ctx, candidate) if err != nil { m.resetNonce() - return tx, nil, err + return nil, err } receipt, err := m.sendTx(ctx, tx) if err != nil { m.resetNonce() - return nil, nil, err + return nil, err } - return tx, receipt, err + return receipt, err } func (m *SimpleTxManager) SendAsync(ctx context.Context, candidate TxCandidate, ch chan SendResponse) { + if cap(ch) == 0 { + panic("SendAsync: channel must be buffered") + } + + // refuse new requests if the tx manager is closed + if m.closed.Load() { + ch <- SendResponse{ + Receipt: nil, + Err: ErrClosed, + } + return + } + + m.metr.RecordPendingTx(m.pending.Add(1)) + + var cancel context.CancelFunc + if m.cfg.TxSendTimeout == 0 { + ctx, cancel = context.WithCancel(ctx) + } else { + ctx, cancel = context.WithTimeout(ctx, m.cfg.TxSendTimeout) + } + + tx, err := m.prepare(ctx, candidate) + if err != nil { + m.resetNonce() + cancel() + m.metr.RecordPendingTx(m.pending.Add(-1)) + ch <- SendResponse{ + Receipt: nil, + Err: err, + } + return + } + go func() { - tx, receipt, err := m.send(ctx, candidate) - r := SendResponse{ + defer m.metr.RecordPendingTx(m.pending.Add(-1)) + defer cancel() + receipt, err := m.sendTx(ctx, tx) + if err != nil { + m.resetNonce() + } + ch <- SendResponse{ Receipt: receipt, + Nonce: tx.Nonce(), Err: err, } - if tx != nil { - r.Nonce = tx.Nonce() - } - ch <- r }() } diff --git a/op-service/txmgr/txmgr_test.go b/op-service/txmgr/txmgr_test.go index 945ae5a04b8c..e451597cd129 100644 --- a/op-service/txmgr/txmgr_test.go +++ b/op-service/txmgr/txmgr_test.go @@ -351,8 +351,7 @@ func testSendVariants(t *testing.T, testFn func(t *testing.T, send testSendVaria t.Run("SendAsync", func(t *testing.T) { testFn(t, func(ctx context.Context, h *testHarness, tx TxCandidate) (*types.Receipt, error) { - // unbuffered is ok, will be written to from a goroutine spawned inside SendAsync - ch := make(chan SendResponse) + ch := make(chan SendResponse, 1) h.mgr.SendAsync(ctx, tx, ch) res := <-ch return res.Receipt, res.Err @@ -1589,3 +1588,12 @@ func TestMakeSidecar(t *testing.T) { require.Equal(t, hashes[i], eth.KZGToVersionedHash(commit)) } } + +func TestSendAsyncUnbufferedChan(t *testing.T) { + conf := configWithNumConfs(2) + h := newTestHarnessWithConfig(t, conf) + + require.Panics(t, func() { + h.mgr.SendAsync(context.Background(), TxCandidate{}, make(chan SendResponse)) + }) +} From e9b80ee12900b1a3658396ad32ab943242797acc Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Thu, 12 Sep 2024 12:03:43 -0600 Subject: [PATCH 121/264] Add op-deployer proof-of-concept (#11804) This PR adds a proof-of-concept for `op-deployer`, a CLI tool that allows declarative management of live OP Stack chains. This POC supports initializing the declarative chain config (called an "intent") and deploying the Superchain smart contracts using the OP Stack Manager. An example intent for a Sepolia chain looks like this: ```toml l1ChainID = 11155111 useFaultProofs = true useAltDA = false fundDevAccounts = true contractArtifactsURL = "file:///Users/matthewslipper/dev/optimism/packages/contracts-bedrock/forge-artifacts" [superchainRoles] proxyAdminOwner = "0xb9cdf788704088a4c0191d045c151fcbe2db14a4" protocolVersionsOwner = "0xb910764be39c84d572ff17713c615b5bfd7df650" guardian = "0x8c7e4a51acb17719d225bd17598b8a94b46c8767" ``` When deployed, it produces a state file that looks like this: ```json { "version": 1, "appliedIntent": { "l1ChainID": 11155111, "superchainRoles": { "proxyAdminOwner": "0xb9cdf788704088a4c0191d045c151fcbe2db14a4", "protocolVersionsOwner": "0xb910764be39c84d572ff17713c615b5bfd7df650", "guardian": "0x8c7e4a51acb17719d225bd17598b8a94b46c8767" }, "useFaultProofs": true, "useAltDA": false, "fundDevAccounts": true, "contractArtifactsURL": "file:///Users/matthewslipper/dev/optimism/packages/contracts-bedrock/forge-artifacts", "chains": null }, "superchainDeployment": { "proxyAdminAddress": "0x54a6088c04a7782e69b5031579a1973a9e3c1a8c", "superchainConfigProxyAddress": "0xc969afc4799a9350f9f05b60748bc62f2829b03a", "superchainConfigImplAddress": "0x08426b74350e7cba5b52be4909c542d28b6b3962", "protocolVersionsProxyAddress": "0x212a023892803c7570eb317c77672c8391bf3dde", "protocolVersionsImplAddress": "0x2633ac74edb7ae1f1b5656e042285015f9ee477d" } } ``` To use `op-deployer`, run `op-deployer init --dev --l1-chain-id `. This will initialize a deployment intent using the development keys in the repo. Then, run `op-deployer apply --l1-rpc-url --private-key ` to apply the deployment. - The contracts deployment is performed by the local Go/Forge tooling. - Upgrades of the contracts (i.e. modifying them after deploying the contracts afresh) is not currently supported. This will be supported in the future. - The rest of the pipeline (i.e., deploying L2s and generating genesis files) is not included in this PR to keep it smaller and allow us to get buy-in on the fundamental concepts behind `op-deployer` before further implementation. --- op-chain-ops/.gitignore | 2 + op-chain-ops/Makefile | 5 +- op-chain-ops/cmd/op-deployer/main.go | 38 ++++ op-chain-ops/deployer/apply.go | 135 ++++++++++++ .../deployer/broadcaster/broadcaster.go | 21 ++ op-chain-ops/deployer/broadcaster/keyed.go | 192 ++++++++++++++++++ op-chain-ops/deployer/flags.go | 83 ++++++++ op-chain-ops/deployer/init.go | 92 +++++++++ op-chain-ops/deployer/opsm/superchain.go | 132 ++++++++++++ op-chain-ops/deployer/pipeline/env.go | 48 +++++ op-chain-ops/deployer/pipeline/init.go | 63 ++++++ op-chain-ops/deployer/pipeline/superchain.go | 84 ++++++++ op-chain-ops/deployer/state/artifacts_url.go | 18 ++ op-chain-ops/deployer/state/intent.go | 137 +++++++++++++ op-chain-ops/deployer/state/state.go | 37 ++++ op-chain-ops/devkeys/devkeys.go | 13 +- op-chain-ops/foundry/artifactsfs.go | 6 +- op-chain-ops/script/prank.go | 20 ++ op-service/crypto/signature.go | 6 + op-service/jsonutil/json.go | 116 ++++++++++- op-service/jsonutil/json_test.go | 3 +- 21 files changed, 1234 insertions(+), 17 deletions(-) create mode 100644 op-chain-ops/cmd/op-deployer/main.go create mode 100644 op-chain-ops/deployer/apply.go create mode 100644 op-chain-ops/deployer/broadcaster/broadcaster.go create mode 100644 op-chain-ops/deployer/broadcaster/keyed.go create mode 100644 op-chain-ops/deployer/flags.go create mode 100644 op-chain-ops/deployer/init.go create mode 100644 op-chain-ops/deployer/opsm/superchain.go create mode 100644 op-chain-ops/deployer/pipeline/env.go create mode 100644 op-chain-ops/deployer/pipeline/init.go create mode 100644 op-chain-ops/deployer/pipeline/superchain.go create mode 100644 op-chain-ops/deployer/state/artifacts_url.go create mode 100644 op-chain-ops/deployer/state/intent.go create mode 100644 op-chain-ops/deployer/state/state.go diff --git a/op-chain-ops/.gitignore b/op-chain-ops/.gitignore index ba077a4031ad..2d94eb56a7db 100644 --- a/op-chain-ops/.gitignore +++ b/op-chain-ops/.gitignore @@ -1 +1,3 @@ bin +intent.toml +state.json \ No newline at end of file diff --git a/op-chain-ops/Makefile b/op-chain-ops/Makefile index 1f119a95f62d..a18f76961599 100644 --- a/op-chain-ops/Makefile +++ b/op-chain-ops/Makefile @@ -12,10 +12,13 @@ receipt-reference-builder: test: go test ./... +op-deployer: + go build -o ./bin/op-deployer ./cmd/op-deployer/main.go + fuzz: go test $(FUZZLDFLAGS) -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzEncodeDecodeWithdrawal ./crossdomain go test $(FUZZLDFLAGS) -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzEncodeDecodeLegacyWithdrawal ./crossdomain go test $(FUZZLDFLAGS) -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzAliasing ./crossdomain go test $(FUZZLDFLAGS) -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzVersionedNonce ./crossdomain -.PHONY: test fuzz +.PHONY: test fuzz op-deployer \ No newline at end of file diff --git a/op-chain-ops/cmd/op-deployer/main.go b/op-chain-ops/cmd/op-deployer/main.go new file mode 100644 index 000000000000..dd176f40bea2 --- /dev/null +++ b/op-chain-ops/cmd/op-deployer/main.go @@ -0,0 +1,38 @@ +package main + +import ( + "fmt" + "os" + + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer" + "github.com/ethereum-optimism/optimism/op-service/cliapp" + "github.com/urfave/cli/v2" +) + +func main() { + app := cli.NewApp() + app.Name = "op-deployer" + app.Usage = "Tool to configure and deploy OP Chains." + app.Flags = cliapp.ProtectFlags(deployer.GlobalFlags) + app.Commands = []*cli.Command{ + { + Name: "init", + Usage: "initializes a chain intent and state file", + Flags: cliapp.ProtectFlags(deployer.InitFlags), + Action: deployer.InitCLI(), + }, + { + Name: "apply", + Usage: "applies a chain intent to the chain", + Flags: cliapp.ProtectFlags(deployer.ApplyFlags), + Action: deployer.ApplyCLI(), + }, + } + app.Writer = os.Stdout + app.ErrWriter = os.Stderr + err := app.Run(os.Args) + if err != nil { + _, _ = fmt.Fprintf(os.Stderr, "Application failed: %v\n", err) + os.Exit(1) + } +} diff --git a/op-chain-ops/deployer/apply.go b/op-chain-ops/deployer/apply.go new file mode 100644 index 000000000000..a58a0654c3be --- /dev/null +++ b/op-chain-ops/deployer/apply.go @@ -0,0 +1,135 @@ +package deployer + +import ( + "context" + "crypto/ecdsa" + "fmt" + "strings" + + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/pipeline" + opcrypto "github.com/ethereum-optimism/optimism/op-service/crypto" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + "github.com/urfave/cli/v2" +) + +type ApplyConfig struct { + L1RPCUrl string + Workdir string + PrivateKey string + Logger log.Logger + + privateKeyECDSA *ecdsa.PrivateKey +} + +func (a *ApplyConfig) Check() error { + if a.L1RPCUrl == "" { + return fmt.Errorf("l1RPCUrl must be specified") + } + + if a.Workdir == "" { + return fmt.Errorf("workdir must be specified") + } + + if a.PrivateKey == "" { + return fmt.Errorf("private key must be specified") + } + + privECDSA, err := crypto.HexToECDSA(strings.TrimPrefix(a.PrivateKey, "0x")) + if err != nil { + return fmt.Errorf("failed to parse private key: %w", err) + } + a.privateKeyECDSA = privECDSA + + if a.Logger == nil { + return fmt.Errorf("logger must be specified") + } + + return nil +} + +func ApplyCLI() func(cliCtx *cli.Context) error { + return func(cliCtx *cli.Context) error { + logCfg := oplog.ReadCLIConfig(cliCtx) + l := oplog.NewLogger(oplog.AppOut(cliCtx), logCfg) + oplog.SetGlobalLogHandler(l.Handler()) + + l1RPCUrl := cliCtx.String(L1RPCURLFlagName) + workdir := cliCtx.String(WorkdirFlagName) + privateKey := cliCtx.String(PrivateKeyFlagName) + + ctx := ctxinterrupt.WithCancelOnInterrupt(cliCtx.Context) + + return Apply(ctx, ApplyConfig{ + L1RPCUrl: l1RPCUrl, + Workdir: workdir, + PrivateKey: privateKey, + Logger: l, + }) + } +} + +func Apply(ctx context.Context, cfg ApplyConfig) error { + if err := cfg.Check(); err != nil { + return fmt.Errorf("invalid config for apply: %w", err) + } + + l1Client, err := ethclient.Dial(cfg.L1RPCUrl) + if err != nil { + return fmt.Errorf("failed to connect to L1 RPC: %w", err) + } + + chainID, err := l1Client.ChainID(ctx) + if err != nil { + return fmt.Errorf("failed to get chain ID: %w", err) + } + + signer := opcrypto.SignerFnFromBind(opcrypto.PrivateKeySignerFn(cfg.privateKeyECDSA, chainID)) + deployer := crypto.PubkeyToAddress(cfg.privateKeyECDSA.PublicKey) + + env := &pipeline.Env{ + Workdir: cfg.Workdir, + L1RPCUrl: cfg.L1RPCUrl, + L1Client: l1Client, + Logger: cfg.Logger, + Signer: signer, + Deployer: deployer, + } + + intent, err := env.ReadIntent() + if err != nil { + return err + } + + if err := intent.Check(); err != nil { + return fmt.Errorf("invalid intent: %w", err) + } + + st, err := env.ReadState() + if err != nil { + return err + } + + pline := []struct { + name string + stage pipeline.Stage + }{ + {"init", pipeline.Init}, + {"deploy-superchain", pipeline.DeploySuperchain}, + } + for _, stage := range pline { + if err := stage.stage(ctx, env, intent, st); err != nil { + return fmt.Errorf("error in pipeline stage: %w", err) + } + } + + st.AppliedIntent = intent + if err := env.WriteState(st); err != nil { + return err + } + + return nil +} diff --git a/op-chain-ops/deployer/broadcaster/broadcaster.go b/op-chain-ops/deployer/broadcaster/broadcaster.go new file mode 100644 index 000000000000..641d1f73dfb5 --- /dev/null +++ b/op-chain-ops/deployer/broadcaster/broadcaster.go @@ -0,0 +1,21 @@ +package broadcaster + +import ( + "context" + + "github.com/ethereum-optimism/optimism/op-chain-ops/script" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +type Broadcaster interface { + Broadcast(ctx context.Context) ([]BroadcastResult, error) + Hook(bcast script.Broadcast) +} + +type BroadcastResult struct { + Broadcast script.Broadcast `json:"broadcast"` + TxHash common.Hash `json:"txHash"` + Receipt *types.Receipt `json:"receipt"` + Err error `json:"-"` +} diff --git a/op-chain-ops/deployer/broadcaster/keyed.go b/op-chain-ops/deployer/broadcaster/keyed.go new file mode 100644 index 000000000000..3df4cd9ed1eb --- /dev/null +++ b/op-chain-ops/deployer/broadcaster/keyed.go @@ -0,0 +1,192 @@ +package broadcaster + +import ( + "context" + "fmt" + "math/big" + "time" + + "github.com/ethereum-optimism/optimism/op-chain-ops/script" + opcrypto "github.com/ethereum-optimism/optimism/op-service/crypto" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + "github.com/hashicorp/go-multierror" + "github.com/holiman/uint256" +) + +const ( + GasPadFactor = 1.5 +) + +type KeyedBroadcaster struct { + lgr log.Logger + mgr txmgr.TxManager + bcasts []script.Broadcast +} + +type KeyedBroadcasterOpts struct { + Logger log.Logger + ChainID *big.Int + Client *ethclient.Client + Signer opcrypto.SignerFn + From common.Address +} + +func NewKeyedBroadcaster(cfg KeyedBroadcasterOpts) (*KeyedBroadcaster, error) { + mgrCfg := &txmgr.Config{ + Backend: cfg.Client, + ChainID: cfg.ChainID, + TxSendTimeout: 5 * time.Minute, + TxNotInMempoolTimeout: time.Minute, + NetworkTimeout: 10 * time.Second, + ReceiptQueryInterval: time.Second, + NumConfirmations: 1, + SafeAbortNonceTooLowCount: 3, + Signer: cfg.Signer, + From: cfg.From, + } + + minTipCap, err := eth.GweiToWei(1.0) + if err != nil { + panic(err) + } + minBaseFee, err := eth.GweiToWei(1.0) + if err != nil { + panic(err) + } + + mgrCfg.ResubmissionTimeout.Store(int64(48 * time.Second)) + mgrCfg.FeeLimitMultiplier.Store(5) + mgrCfg.FeeLimitThreshold.Store(big.NewInt(100)) + mgrCfg.MinTipCap.Store(minTipCap) + mgrCfg.MinTipCap.Store(minBaseFee) + + mgr, err := txmgr.NewSimpleTxManagerFromConfig( + "transactor", + log.NewLogger(log.DiscardHandler()), + &metrics.NoopTxMetrics{}, + mgrCfg, + ) + + if err != nil { + return nil, fmt.Errorf("failed to create tx manager: %w", err) + } + + return &KeyedBroadcaster{ + lgr: cfg.Logger, + mgr: mgr, + }, nil +} + +func (t *KeyedBroadcaster) Hook(bcast script.Broadcast) { + t.bcasts = append(t.bcasts, bcast) +} + +func (t *KeyedBroadcaster) Broadcast(ctx context.Context) ([]BroadcastResult, error) { + results := make([]BroadcastResult, len(t.bcasts)) + futures := make([]<-chan txmgr.SendResponse, len(t.bcasts)) + ids := make([]common.Hash, len(t.bcasts)) + + for i, bcast := range t.bcasts { + futures[i], ids[i] = t.broadcast(ctx, bcast) + t.lgr.Info( + "transaction broadcasted", + "id", ids[i], + "nonce", bcast.Nonce, + ) + } + + var err *multierror.Error + var completed int + for i, fut := range futures { + bcastRes := <-fut + completed++ + outRes := BroadcastResult{ + Broadcast: t.bcasts[i], + } + + if bcastRes.Err == nil { + outRes.Receipt = bcastRes.Receipt + outRes.TxHash = bcastRes.Receipt.TxHash + + if bcastRes.Receipt.Status == 0 { + failErr := fmt.Errorf("transaction failed: %s", outRes.Receipt.TxHash.String()) + err = multierror.Append(err, failErr) + outRes.Err = failErr + t.lgr.Error( + "transaction failed on chain", + "id", ids[i], + "completed", completed, + "total", len(t.bcasts), + "hash", outRes.Receipt.TxHash.String(), + "nonce", outRes.Broadcast.Nonce, + ) + } else { + t.lgr.Info( + "transaction confirmed", + "id", ids[i], + "completed", completed, + "total", len(t.bcasts), + "hash", outRes.Receipt.TxHash.String(), + "nonce", outRes.Broadcast.Nonce, + "creation", outRes.Receipt.ContractAddress, + ) + } + } else { + err = multierror.Append(err, bcastRes.Err) + outRes.Err = bcastRes.Err + t.lgr.Error( + "transaction failed", + "id", ids[i], + "completed", completed, + "total", len(t.bcasts), + "err", bcastRes.Err, + ) + } + + results = append(results, outRes) + } + return results, err.ErrorOrNil() +} + +func (t *KeyedBroadcaster) broadcast(ctx context.Context, bcast script.Broadcast) (<-chan txmgr.SendResponse, common.Hash) { + id := bcast.ID() + + value := ((*uint256.Int)(bcast.Value)).ToBig() + var candidate txmgr.TxCandidate + switch bcast.Type { + case script.BroadcastCall: + to := &bcast.To + candidate = txmgr.TxCandidate{ + TxData: bcast.Input, + To: to, + Value: value, + GasLimit: padGasLimit(bcast.Input, bcast.GasUsed, false), + } + case script.BroadcastCreate: + candidate = txmgr.TxCandidate{ + TxData: bcast.Input, + To: nil, + GasLimit: padGasLimit(bcast.Input, bcast.GasUsed, true), + } + } + + ch := make(chan txmgr.SendResponse, 1) + t.mgr.SendAsync(ctx, candidate, ch) + return ch, id +} + +func padGasLimit(data []byte, gasUsed uint64, creation bool) uint64 { + intrinsicGas, err := core.IntrinsicGas(data, nil, creation, true, true, false) + // This method never errors - we should look into it if it does. + if err != nil { + panic(err) + } + + return uint64(float64(intrinsicGas+gasUsed) * GasPadFactor) +} diff --git a/op-chain-ops/deployer/flags.go b/op-chain-ops/deployer/flags.go new file mode 100644 index 000000000000..d2bfd0eff5b4 --- /dev/null +++ b/op-chain-ops/deployer/flags.go @@ -0,0 +1,83 @@ +package deployer + +import ( + "os" + + op_service "github.com/ethereum-optimism/optimism/op-service" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/urfave/cli/v2" +) + +const ( + EnvVarPrefix = "DEPLOYER" + L1RPCURLFlagName = "l1-rpc-url" + L1ChainIDFlagName = "l1-chain-id" + WorkdirFlagName = "workdir" + OutdirFlagName = "outdir" + DevFlagName = "dev" + PrivateKeyFlagName = "private-key" +) + +var ( + L1RPCURLFlag = &cli.StringFlag{ + Name: L1RPCURLFlagName, + Usage: "RPC URL for the L1 chain. Can be set to 'genesis' for deployments " + + "that will be deployed at the launch of the L1.", + EnvVars: []string{ + "L1_RPC_URL", + }, + } + L1ChainIDFlag = &cli.Uint64Flag{ + Name: L1ChainIDFlagName, + Usage: "Chain ID of the L1 chain.", + EnvVars: prefixEnvVar("L1_CHAIN_ID"), + Value: 900, + } + WorkdirFlag = &cli.StringFlag{ + Name: WorkdirFlagName, + Usage: "Directory storing intent and stage. Defaults to the current directory.", + EnvVars: prefixEnvVar("WORKDIR"), + Value: cwd(), + Aliases: []string{ + OutdirFlagName, + }, + } + DevFlag = &cli.BoolFlag{ + Name: DevFlagName, + Usage: "Use development mode. This will use the development mnemonic to own the chain" + + " and fund dev accounts.", + EnvVars: prefixEnvVar("DEV"), + } + + PrivateKeyFlag = &cli.StringFlag{ + Name: PrivateKeyFlagName, + Usage: "Private key of the deployer account.", + EnvVars: prefixEnvVar("PRIVATE_KEY"), + } +) + +var GlobalFlags = append([]cli.Flag{}, oplog.CLIFlags(EnvVarPrefix)...) + +var InitFlags = []cli.Flag{ + L1ChainIDFlag, + WorkdirFlag, + DevFlag, +} + +var ApplyFlags = []cli.Flag{ + L1RPCURLFlag, + WorkdirFlag, + PrivateKeyFlag, +} + +func prefixEnvVar(name string) []string { + return op_service.PrefixEnvVar(EnvVarPrefix, name) +} + +func cwd() string { + dir, err := os.Getwd() + if err != nil { + return "" + } + return dir +} diff --git a/op-chain-ops/deployer/init.go b/op-chain-ops/deployer/init.go new file mode 100644 index 000000000000..f3f181c2186f --- /dev/null +++ b/op-chain-ops/deployer/init.go @@ -0,0 +1,92 @@ +package deployer + +import ( + "fmt" + "path" + + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" + "github.com/ethereum-optimism/optimism/op-chain-ops/devkeys" + "github.com/ethereum/go-ethereum/common" + "github.com/urfave/cli/v2" +) + +const devMnemonic = "test test test test test test test test test test test junk" + +type InitConfig struct { + L1ChainID uint64 + Outdir string + Dev bool +} + +func (c *InitConfig) Check() error { + if c.L1ChainID == 0 { + return fmt.Errorf("l1ChainID must be specified") + } + + if c.Outdir == "" { + return fmt.Errorf("outdir must be specified") + } + + return nil +} + +func InitCLI() func(ctx *cli.Context) error { + return func(ctx *cli.Context) error { + l1ChainID := ctx.Uint64(L1ChainIDFlagName) + outdir := ctx.String(OutdirFlagName) + dev := ctx.Bool(DevFlagName) + + return Init(InitConfig{ + L1ChainID: l1ChainID, + Outdir: outdir, + Dev: dev, + }) + } +} + +func Init(cfg InitConfig) error { + if err := cfg.Check(); err != nil { + return fmt.Errorf("invalid config for init: %w", err) + } + + intent := &state.Intent{ + L1ChainID: cfg.L1ChainID, + UseFaultProofs: true, + FundDevAccounts: cfg.Dev, + } + + l1ChainIDBig := intent.L1ChainIDBig() + + if cfg.Dev { + dk, err := devkeys.NewMnemonicDevKeys(devMnemonic) + if err != nil { + return fmt.Errorf("failed to create dev keys: %w", err) + } + + addrFor := func(key devkeys.Key) common.Address { + // The error below should never happen, so panic if it does. + addr, err := dk.Address(key) + if err != nil { + panic(err) + } + return addr + } + intent.SuperchainRoles = state.SuperchainRoles{ + ProxyAdminOwner: addrFor(devkeys.L1ProxyAdminOwnerRole.Key(l1ChainIDBig)), + ProtocolVersionsOwner: addrFor(devkeys.SuperchainDeployerKey.Key(l1ChainIDBig)), + Guardian: addrFor(devkeys.SuperchainConfigGuardianKey.Key(l1ChainIDBig)), + } + } + + st := &state.State{ + Version: 1, + } + + if err := intent.WriteToFile(path.Join(cfg.Outdir, "intent.toml")); err != nil { + return fmt.Errorf("failed to write intent to file: %w", err) + } + if err := st.WriteToFile(path.Join(cfg.Outdir, "state.json")); err != nil { + return fmt.Errorf("failed to write state to file: %w", err) + } + return nil +} diff --git a/op-chain-ops/deployer/opsm/superchain.go b/op-chain-ops/deployer/opsm/superchain.go new file mode 100644 index 000000000000..99adb77817e1 --- /dev/null +++ b/op-chain-ops/deployer/opsm/superchain.go @@ -0,0 +1,132 @@ +package opsm + +import ( + "context" + "fmt" + "math/big" + + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/broadcaster" + "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" + "github.com/ethereum-optimism/optimism/op-chain-ops/script" + opcrypto "github.com/ethereum-optimism/optimism/op-service/crypto" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" +) + +type DeploySuperchainInput struct { + ProxyAdminOwner common.Address `toml:"proxyAdminOwner"` + ProtocolVersionsOwner common.Address `toml:"protocolVersionsOwner"` + Guardian common.Address `toml:"guardian"` + Paused bool `toml:"paused"` + RequiredProtocolVersion params.ProtocolVersion `toml:"requiredProtocolVersion"` + RecommendedProtocolVersion params.ProtocolVersion `toml:"recommendedProtocolVersion"` +} + +func (dsi *DeploySuperchainInput) InputSet() bool { + return true +} + +type DeploySuperchainOutput struct { + SuperchainProxyAdmin common.Address `toml:"superchainProxyAdmin"` + SuperchainConfigImpl common.Address `toml:"superchainConfigImpl"` + SuperchainConfigProxy common.Address `toml:"superchainConfigProxy"` + ProtocolVersionsImpl common.Address `toml:"protocolVersionsImpl"` + ProtocolVersionsProxy common.Address `toml:"protocolVersionsProxy"` +} + +func (output *DeploySuperchainOutput) CheckOutput() error { + return nil +} + +type DeploySuperchainScript struct { + Run func(in common.Address, out common.Address) error +} + +type DeploySuperchainOpts struct { + ChainID *big.Int + ArtifactsFS foundry.StatDirFs + Deployer common.Address + Signer opcrypto.SignerFn + Input DeploySuperchainInput + Client *ethclient.Client + Logger log.Logger +} + +func DeploySuperchainForge(ctx context.Context, opts DeploySuperchainOpts) (DeploySuperchainOutput, error) { + var dso DeploySuperchainOutput + + bcaster, err := broadcaster.NewKeyedBroadcaster(broadcaster.KeyedBroadcasterOpts{ + Logger: opts.Logger, + ChainID: opts.ChainID, + Client: opts.Client, + Signer: opts.Signer, + From: opts.Deployer, + }) + if err != nil { + return dso, fmt.Errorf("failed to create broadcaster: %w", err) + } + + scriptCtx := script.DefaultContext + scriptCtx.Sender = opts.Deployer + scriptCtx.Origin = opts.Deployer + artifacts := &foundry.ArtifactsFS{FS: opts.ArtifactsFS} + h := script.NewHost( + opts.Logger, + artifacts, + nil, + scriptCtx, + script.WithBroadcastHook(bcaster.Hook), + script.WithIsolatedBroadcasts(), + ) + + if err := h.EnableCheats(); err != nil { + return dso, fmt.Errorf("failed to enable cheats: %w", err) + } + + nonce, err := opts.Client.NonceAt(ctx, opts.Deployer, nil) + if err != nil { + return dso, fmt.Errorf("failed to get deployer nonce: %w", err) + } + + inputAddr := h.NewScriptAddress() + outputAddr := h.NewScriptAddress() + + cleanupInput, err := script.WithPrecompileAtAddress[*DeploySuperchainInput](h, inputAddr, &opts.Input) + if err != nil { + return dso, fmt.Errorf("failed to insert DeploySuperchainInput precompile: %w", err) + } + defer cleanupInput() + + cleanupOutput, err := script.WithPrecompileAtAddress[*DeploySuperchainOutput]( + h, + outputAddr, + &dso, + script.WithFieldSetter[*DeploySuperchainOutput], + ) + if err != nil { + return dso, fmt.Errorf("failed to insert DeploySuperchainOutput precompile: %w", err) + } + defer cleanupOutput() + + deployScript, cleanupDeploy, err := script.WithScript[DeploySuperchainScript](h, "DeploySuperchain.s.sol", "DeploySuperchain") + if err != nil { + return dso, fmt.Errorf("failed to load DeploySuperchain script: %w", err) + } + defer cleanupDeploy() + + h.SetNonce(opts.Deployer, nonce) + + opts.Logger.Info("deployer nonce", "nonce", nonce) + + if err := deployScript.Run(inputAddr, outputAddr); err != nil { + return dso, fmt.Errorf("failed to run DeploySuperchain script: %w", err) + } + + if _, err := bcaster.Broadcast(ctx); err != nil { + return dso, fmt.Errorf("failed to broadcast transactions: %w", err) + } + + return dso, nil +} diff --git a/op-chain-ops/deployer/pipeline/env.go b/op-chain-ops/deployer/pipeline/env.go new file mode 100644 index 000000000000..d77beacac596 --- /dev/null +++ b/op-chain-ops/deployer/pipeline/env.go @@ -0,0 +1,48 @@ +package pipeline + +import ( + "context" + "fmt" + "path" + + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" + opcrypto "github.com/ethereum-optimism/optimism/op-service/crypto" + "github.com/ethereum-optimism/optimism/op-service/jsonutil" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" +) + +type Env struct { + Workdir string + L1Client *ethclient.Client + L1RPCUrl string + Signer opcrypto.SignerFn + Deployer common.Address + Logger log.Logger +} + +func (e *Env) ReadIntent() (*state.Intent, error) { + intentPath := path.Join(e.Workdir, "intent.toml") + intent, err := jsonutil.LoadTOML[state.Intent](intentPath) + if err != nil { + return nil, fmt.Errorf("failed to read intent file: %w", err) + } + return intent, nil +} + +func (e *Env) ReadState() (*state.State, error) { + statePath := path.Join(e.Workdir, "state.json") + st, err := jsonutil.LoadJSON[state.State](statePath) + if err != nil { + return nil, fmt.Errorf("failed to read state file: %w", err) + } + return st, nil +} + +func (e *Env) WriteState(st *state.State) error { + statePath := path.Join(e.Workdir, "state.json") + return st.WriteToFile(statePath) +} + +type Stage func(ctx context.Context, env *Env, intent *state.Intent, state2 *state.State) error diff --git a/op-chain-ops/deployer/pipeline/init.go b/op-chain-ops/deployer/pipeline/init.go new file mode 100644 index 000000000000..9f4227f856b0 --- /dev/null +++ b/op-chain-ops/deployer/pipeline/init.go @@ -0,0 +1,63 @@ +package pipeline + +import ( + "context" + "fmt" + + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" +) + +func IsSupportedStateVersion(version int) bool { + return version == 1 +} + +func Init(ctx context.Context, env *Env, intent *state.Intent, st *state.State) error { + lgr := env.Logger.New("stage", "init") + lgr.Info("initializing pipeline") + + // Ensure the state version is supported. + if !IsSupportedStateVersion(st.Version) { + return fmt.Errorf("unsupported state version: %d", st.Version) + } + + // If the state has never been applied, we don't need to perform + // any additional checks. + if st.AppliedIntent == nil { + return nil + } + + // If the state has been applied, we need to check if any immutable + // fields have changed. + if st.AppliedIntent.L1ChainID != intent.L1ChainID { + return immutableErr("L1ChainID", st.AppliedIntent.L1ChainID, intent.L1ChainID) + } + + if st.AppliedIntent.UseFaultProofs != intent.UseFaultProofs { + return immutableErr("useFaultProofs", st.AppliedIntent.UseFaultProofs, intent.UseFaultProofs) + } + + if st.AppliedIntent.UseAltDA != intent.UseAltDA { + return immutableErr("useAltDA", st.AppliedIntent.UseAltDA, intent.UseAltDA) + } + + if st.AppliedIntent.FundDevAccounts != intent.FundDevAccounts { + return immutableErr("fundDevAccounts", st.AppliedIntent.FundDevAccounts, intent.FundDevAccounts) + } + + l1ChainID, err := env.L1Client.ChainID(ctx) + if err != nil { + return fmt.Errorf("failed to get L1 chain ID: %w", err) + } + + if l1ChainID.Cmp(intent.L1ChainIDBig()) != 0 { + return fmt.Errorf("L1 chain ID mismatch: got %d, expected %d", l1ChainID, intent.L1ChainID) + } + + // TODO: validate individual L2s + + return nil +} + +func immutableErr(field string, was, is any) error { + return fmt.Errorf("%s is immutable: was %v, is %v", field, was, is) +} diff --git a/op-chain-ops/deployer/pipeline/superchain.go b/op-chain-ops/deployer/pipeline/superchain.go new file mode 100644 index 000000000000..5b44b2ee01c3 --- /dev/null +++ b/op-chain-ops/deployer/pipeline/superchain.go @@ -0,0 +1,84 @@ +package pipeline + +import ( + "context" + "fmt" + "math/big" + "os" + + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opsm" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" + "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" + "github.com/ethereum-optimism/optimism/op-node/rollup" +) + +const DefaultContractsBedrockRepo = "us-docker.pkg.dev/oplabs-tools-artifacts/images/contracts-bedrock" + +func DeploySuperchain(ctx context.Context, env *Env, intent *state.Intent, st *state.State) error { + lgr := env.Logger.New("stage", "deploy-superchain") + + if !shouldDeploySuperchain(intent, st) { + lgr.Info("superchain deployment not needed") + return nil + } + + lgr.Info("deploying superchain") + + var artifactsFS foundry.StatDirFs + var err error + if intent.ContractArtifactsURL.Scheme == "file" { + fs := os.DirFS(intent.ContractArtifactsURL.Path) + artifactsFS = fs.(foundry.StatDirFs) + } else { + return fmt.Errorf("only file:// artifacts URLs are supported") + } + + dso, err := opsm.DeploySuperchainForge( + ctx, + opsm.DeploySuperchainOpts{ + Input: opsm.DeploySuperchainInput{ + ProxyAdminOwner: intent.SuperchainRoles.ProxyAdminOwner, + ProtocolVersionsOwner: intent.SuperchainRoles.ProtocolVersionsOwner, + Guardian: intent.SuperchainRoles.Guardian, + Paused: false, + RequiredProtocolVersion: rollup.OPStackSupport, + RecommendedProtocolVersion: rollup.OPStackSupport, + }, + ArtifactsFS: artifactsFS, + ChainID: big.NewInt(int64(intent.L1ChainID)), + Client: env.L1Client, + Signer: env.Signer, + Deployer: env.Deployer, + Logger: lgr, + }, + ) + if err != nil { + return fmt.Errorf("error deploying superchain: %w", err) + } + + st.SuperchainDeployment = &state.SuperchainDeployment{ + ProxyAdminAddress: dso.SuperchainProxyAdmin, + SuperchainConfigProxyAddress: dso.SuperchainConfigProxy, + SuperchainConfigImplAddress: dso.SuperchainConfigImpl, + ProtocolVersionsProxyAddress: dso.ProtocolVersionsProxy, + ProtocolVersionsImplAddress: dso.ProtocolVersionsImpl, + } + + if err := env.WriteState(st); err != nil { + return err + } + + return nil +} + +func shouldDeploySuperchain(intent *state.Intent, st *state.State) bool { + if st.AppliedIntent == nil { + return true + } + + if st.SuperchainDeployment == nil { + return true + } + + return false +} diff --git a/op-chain-ops/deployer/state/artifacts_url.go b/op-chain-ops/deployer/state/artifacts_url.go new file mode 100644 index 000000000000..5ea576d79eec --- /dev/null +++ b/op-chain-ops/deployer/state/artifacts_url.go @@ -0,0 +1,18 @@ +package state + +import "net/url" + +type ArtifactsURL url.URL + +func (a *ArtifactsURL) MarshalText() ([]byte, error) { + return []byte((*url.URL)(a).String()), nil +} + +func (a *ArtifactsURL) UnmarshalText(text []byte) error { + u, err := url.Parse(string(text)) + if err != nil { + return err + } + *a = ArtifactsURL(*u) + return nil +} diff --git a/op-chain-ops/deployer/state/intent.go b/op-chain-ops/deployer/state/intent.go new file mode 100644 index 000000000000..5184a3bb28ef --- /dev/null +++ b/op-chain-ops/deployer/state/intent.go @@ -0,0 +1,137 @@ +package state + +import ( + "fmt" + "math/big" + + "github.com/ethereum-optimism/optimism/op-service/ioutil" + "github.com/ethereum-optimism/optimism/op-service/jsonutil" + "github.com/ethereum/go-ethereum/common" +) + +var emptyAddress common.Address + +type Intent struct { + L1ChainID uint64 `json:"l1ChainID" toml:"l1ChainID"` + + SuperchainRoles SuperchainRoles `json:"superchainRoles" toml:"superchainRoles"` + + UseFaultProofs bool `json:"useFaultProofs" toml:"useFaultProofs"` + + UseAltDA bool `json:"useAltDA" toml:"useAltDA"` + + FundDevAccounts bool `json:"fundDevAccounts" toml:"fundDevAccounts"` + + ContractArtifactsURL *ArtifactsURL `json:"contractArtifactsURL" toml:"contractArtifactsURL"` + + Chains []Chain `json:"chains" toml:"chains"` +} + +func (c Intent) L1ChainIDBig() *big.Int { + return big.NewInt(int64(c.L1ChainID)) +} +func (c Intent) Check() error { + if c.L1ChainID == 0 { + return fmt.Errorf("l1ChainID must be set") + } + + if c.UseFaultProofs && c.UseAltDA { + return fmt.Errorf("cannot use both fault proofs and alt-DA") + } + + if c.SuperchainRoles.ProxyAdminOwner == emptyAddress { + return fmt.Errorf("proxyAdminOwner must be set") + } + + if c.SuperchainRoles.ProtocolVersionsOwner == emptyAddress { + c.SuperchainRoles.ProtocolVersionsOwner = c.SuperchainRoles.ProxyAdminOwner + } + + if c.SuperchainRoles.Guardian == emptyAddress { + c.SuperchainRoles.Guardian = c.SuperchainRoles.ProxyAdminOwner + } + + if c.ContractArtifactsURL == nil { + return fmt.Errorf("contractArtifactsURL must be set") + } + + if c.ContractArtifactsURL.Scheme != "file" { + return fmt.Errorf("contractArtifactsURL must be a file URL") + } + + return nil +} + +func (c Intent) Chain(id uint64) (Chain, error) { + for i := range c.Chains { + if c.Chains[i].ID == id { + return c.Chains[i], nil + } + } + + return Chain{}, fmt.Errorf("chain %d not found", id) +} + +func (c Intent) WriteToFile(path string) error { + return jsonutil.WriteTOML(c, ioutil.ToAtomicFile(path, 0o755)) +} + +type SuperchainRoles struct { + ProxyAdminOwner common.Address `json:"proxyAdminOwner" toml:"proxyAdminOwner"` + + ProtocolVersionsOwner common.Address `json:"protocolVersionsOwner" toml:"protocolVersionsOwner"` + + Guardian common.Address `json:"guardian" toml:"guardian"` +} + +type Chain struct { + ID uint64 `json:"id"` + + Roles ChainRoles `json:"roles"` + + Overrides map[string]any `json:"overrides"` +} + +type ChainRoles struct { + ProxyAdminOwner common.Address `json:"proxyAdminOwner"` + + SystemConfigOwner common.Address `json:"systemConfigOwner"` + + GovernanceTokenOwner common.Address `json:"governanceTokenOwner"` + + UnsafeBlockSigner common.Address `json:"unsafeBlockSigner"` + + Batcher common.Address `json:"batcher"` + + Proposer common.Address `json:"proposer"` + + Challenger common.Address `json:"challenger"` +} + +func (c *Chain) Check() error { + if c.ID == 0 { + return fmt.Errorf("id must be set") + } + + if c.Roles.ProxyAdminOwner == emptyAddress { + return fmt.Errorf("proxyAdminOwner must be set") + } + + if c.Roles.SystemConfigOwner == emptyAddress { + c.Roles.SystemConfigOwner = c.Roles.ProxyAdminOwner + } + + if c.Roles.GovernanceTokenOwner == emptyAddress { + c.Roles.GovernanceTokenOwner = c.Roles.ProxyAdminOwner + } + + if c.Roles.UnsafeBlockSigner == emptyAddress { + return fmt.Errorf("unsafeBlockSigner must be set") + } + + if c.Roles.Batcher == emptyAddress { + return fmt.Errorf("batcher must be set") + } + + return nil +} diff --git a/op-chain-ops/deployer/state/state.go b/op-chain-ops/deployer/state/state.go new file mode 100644 index 000000000000..19addf79938d --- /dev/null +++ b/op-chain-ops/deployer/state/state.go @@ -0,0 +1,37 @@ +package state + +import ( + "github.com/ethereum-optimism/optimism/op-service/ioutil" + "github.com/ethereum-optimism/optimism/op-service/jsonutil" + "github.com/ethereum/go-ethereum/common" +) + +// State contains the data needed to recreate the deployment +// as it progresses and once it is fully applied. +type State struct { + // Version versions the state so we can update it later. + Version int `json:"version"` + + // AppliedIntent contains the chain intent that was last + // successfully applied. It is diffed against new intent + // in order to determine what deployment steps to take. + // This field is nil for new deployments. + AppliedIntent *Intent `json:"appliedIntent"` + + // SuperchainDeployment contains the addresses of the Superchain + // deployment. It only contains the proxies because the implementations + // can be looked up on chain. + SuperchainDeployment *SuperchainDeployment `json:"superchainDeployment"` +} + +func (s State) WriteToFile(path string) error { + return jsonutil.WriteJSON(s, ioutil.ToAtomicFile(path, 0o755)) +} + +type SuperchainDeployment struct { + ProxyAdminAddress common.Address `json:"proxyAdminAddress"` + SuperchainConfigProxyAddress common.Address `json:"superchainConfigProxyAddress"` + SuperchainConfigImplAddress common.Address `json:"superchainConfigImplAddress"` + ProtocolVersionsProxyAddress common.Address `json:"protocolVersionsProxyAddress"` + ProtocolVersionsImplAddress common.Address `json:"protocolVersionsImplAddress"` +} diff --git a/op-chain-ops/devkeys/devkeys.go b/op-chain-ops/devkeys/devkeys.go index c79739500ffa..d0526c8c1d3a 100644 --- a/op-chain-ops/devkeys/devkeys.go +++ b/op-chain-ops/devkeys/devkeys.go @@ -49,6 +49,10 @@ func ChainUserKeys(chainID *big.Int) func(index uint64) ChainUserKey { } } +type Role interface { + Key(chainID *big.Int) Key +} + // SuperchainOperatorRole identifies an account used in the operations of superchain contracts type SuperchainOperatorRole uint64 @@ -82,6 +86,13 @@ func (role SuperchainOperatorRole) String() string { } } +func (role SuperchainOperatorRole) Key(chainID *big.Int) Key { + return &SuperchainOperatorKey{ + ChainID: chainID, + Role: role, + } +} + // SuperchainOperatorKey is an account specific to an OperationRole of a given OP-Stack chain. type SuperchainOperatorKey struct { ChainID *big.Int @@ -163,7 +174,7 @@ func (role ChainOperatorRole) String() string { } } -func (role ChainOperatorRole) Key(chainID *big.Int) *ChainOperatorKey { +func (role ChainOperatorRole) Key(chainID *big.Int) Key { return &ChainOperatorKey{ ChainID: chainID, Role: role, diff --git a/op-chain-ops/foundry/artifactsfs.go b/op-chain-ops/foundry/artifactsfs.go index 2b5599c85c20..13229c41bc06 100644 --- a/op-chain-ops/foundry/artifactsfs.go +++ b/op-chain-ops/foundry/artifactsfs.go @@ -9,14 +9,14 @@ import ( "strings" ) -type statDirFs interface { +type StatDirFs interface { fs.StatFS fs.ReadDirFS } func OpenArtifactsDir(dirPath string) *ArtifactsFS { dir := os.DirFS(dirPath) - if d, ok := dir.(statDirFs); !ok { + if d, ok := dir.(StatDirFs); !ok { panic("Go DirFS guarantees changed") } else { return &ArtifactsFS{FS: d} @@ -29,7 +29,7 @@ func OpenArtifactsDir(dirPath string) *ArtifactsFS { // See OpenArtifactsDir for reading from a local directory. // Alternative FS systems, like a tarball, may be used too. type ArtifactsFS struct { - FS statDirFs + FS StatDirFs } // ListArtifacts lists the artifacts. Each artifact matches a source-file name. diff --git a/op-chain-ops/script/prank.go b/op-chain-ops/script/prank.go index d7cca3068e63..eaf611e9e85d 100644 --- a/op-chain-ops/script/prank.go +++ b/op-chain-ops/script/prank.go @@ -2,6 +2,8 @@ package script import ( "bytes" + "crypto/sha256" + "encoding/binary" "errors" "fmt" "math/big" @@ -205,6 +207,24 @@ type Broadcast struct { Nonce uint64 `json:"nonce"` // pre-state nonce of From, before any increment (always 0 if create2) } +// ID returns a hash that can be used to identify the broadcast. +// This is used instead of the transaction hash since broadcasting +// tools can change gas limits and other fields which would change +// the resulting transaction hash. +func (b Broadcast) ID() common.Hash { + h := sha256.New() + _, _ = h.Write(b.From[:]) + _, _ = h.Write(b.To[:]) + _, _ = h.Write(b.Input) + _, _ = h.Write(((*uint256.Int)(b.Value)).Bytes()) + _, _ = h.Write(b.Salt[:]) + nonce := make([]byte, 8) + binary.BigEndian.PutUint64(nonce, b.Nonce) + _, _ = h.Write(nonce) + sum := h.Sum(nil) + return common.BytesToHash(sum) +} + // NewBroadcast creates a Broadcast from a parent callframe, and the completed child callframe. // This method is preferred to manually creating the struct since it correctly handles // data that must be copied prior to being returned to prevent accidental mutation. diff --git a/op-service/crypto/signature.go b/op-service/crypto/signature.go index 0b0afc02ecef..a6a7c1cc0d1e 100644 --- a/op-service/crypto/signature.go +++ b/op-service/crypto/signature.go @@ -35,6 +35,12 @@ func PrivateKeySignerFn(key *ecdsa.PrivateKey, chainID *big.Int) bind.SignerFn { } } +func SignerFnFromBind(fn bind.SignerFn) SignerFn { + return func(_ context.Context, address common.Address, tx *types.Transaction) (*types.Transaction, error) { + return fn(address, tx) + } +} + // SignerFn is a generic transaction signing function. It may be a remote signer so it takes a context. // It also takes the address that should be used to sign the transaction with. type SignerFn func(context.Context, common.Address, *types.Transaction) (*types.Transaction, error) diff --git a/op-service/jsonutil/json.go b/op-service/jsonutil/json.go index 5f2a8596a6be..5993138595b4 100644 --- a/op-service/jsonutil/json.go +++ b/op-service/jsonutil/json.go @@ -6,10 +6,105 @@ import ( "fmt" "io" + "github.com/BurntSushi/toml" + "github.com/ethereum-optimism/optimism/op-service/ioutil" ) +type Decoder interface { + Decode(v interface{}) error +} + +type DecoderFactory func(r io.Reader) Decoder + +type Encoder interface { + Encode(v interface{}) error +} + +type EncoderFactory func(w io.Writer) Encoder + +type jsonDecoder struct { + d *json.Decoder +} + +func newJSONDecoder(r io.Reader) Decoder { + return &jsonDecoder{ + d: json.NewDecoder(r), + } +} + +func (d *jsonDecoder) Decode(v interface{}) error { + if err := d.d.Decode(v); err != nil { + return fmt.Errorf("failed to decode JSON: %w", err) + } + if _, err := d.d.Token(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil +} + +type tomlDecoder struct { + r io.Reader +} + +func newTOMLDecoder(r io.Reader) Decoder { + return &tomlDecoder{ + r: r, + } +} + +func (d *tomlDecoder) Decode(v interface{}) error { + if _, err := toml.NewDecoder(d.r).Decode(v); err != nil { + return fmt.Errorf("failed to decode TOML: %w", err) + } + return nil +} + +type jsonEncoder struct { + e *json.Encoder +} + +func newJSONEncoder(w io.Writer) Encoder { + e := json.NewEncoder(w) + e.SetIndent("", " ") + return &jsonEncoder{ + e: e, + } +} + +func (e *jsonEncoder) Encode(v interface{}) error { + if err := e.e.Encode(v); err != nil { + return fmt.Errorf("failed to encode JSON: %w", err) + } + return nil +} + +type tomlEncoder struct { + w io.Writer +} + +func newTOMLEncoder(w io.Writer) Encoder { + return &tomlEncoder{ + w: w, + } +} + +func (e *tomlEncoder) Encode(v interface{}) error { + if err := toml.NewEncoder(e.w).Encode(v); err != nil { + return fmt.Errorf("failed to encode TOML: %w", err) + } + return nil +} + func LoadJSON[X any](inputPath string) (*X, error) { + return load[X](inputPath, newJSONDecoder) +} + +func LoadTOML[X any](inputPath string) (*X, error) { + return load[X](inputPath, newTOMLDecoder) +} + +func load[X any](inputPath string, dec DecoderFactory) (*X, error) { if inputPath == "" { return nil, errors.New("no path specified") } @@ -20,18 +115,21 @@ func LoadJSON[X any](inputPath string) (*X, error) { } defer f.Close() var state X - decoder := json.NewDecoder(f) - if err := decoder.Decode(&state); err != nil { + if err := dec(f).Decode(&state); err != nil { return nil, fmt.Errorf("failed to decode file %q: %w", inputPath, err) } - // We are only expecting 1 JSON object - confirm there is no trailing data - if _, err := decoder.Token(); err != io.EOF { - return nil, fmt.Errorf("unexpected trailing data in file %q", inputPath) - } return &state, nil } func WriteJSON[X any](value X, target ioutil.OutputTarget) error { + return write(value, target, newJSONEncoder) +} + +func WriteTOML[X any](value X, target ioutil.OutputTarget) error { + return write(value, target, newTOMLEncoder) +} + +func write[X any](value X, target ioutil.OutputTarget, enc EncoderFactory) error { out, closer, abort, err := target() if err != nil { return err @@ -40,10 +138,8 @@ func WriteJSON[X any](value X, target ioutil.OutputTarget) error { return nil // No output stream selected so skip generating the content entirely } defer abort() - enc := json.NewEncoder(out) - enc.SetIndent("", " ") - if err := enc.Encode(value); err != nil { - return fmt.Errorf("failed to encode to JSON: %w", err) + if err := enc(out).Encode(value); err != nil { + return fmt.Errorf("failed to encode: %w", err) } _, err = out.Write([]byte{'\n'}) if err != nil { diff --git a/op-service/jsonutil/json_test.go b/op-service/jsonutil/json_test.go index b8da7d8de70f..36bda167491b 100644 --- a/op-service/jsonutil/json_test.go +++ b/op-service/jsonutil/json_test.go @@ -2,7 +2,6 @@ package jsonutil import ( "encoding/json" - "fmt" "os" "path/filepath" "testing" @@ -95,7 +94,7 @@ func TestLoadJSONWithExtraDataAppended(t *testing.T) { var result *jsonTestData result, err = LoadJSON[jsonTestData](file) - require.ErrorContains(t, err, fmt.Sprintf("unexpected trailing data in file %q", file)) + require.ErrorContains(t, err, "unexpected trailing data") require.Nil(t, result) }) } From c3daaf454e5ba021bf1d562563b3f98f206c140e Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Thu, 12 Sep 2024 15:07:31 -0400 Subject: [PATCH 122/264] fix(ci): skip files without modified functions (#11891) Updates test-heavy-fuzz-modified-tests to skip any files that don't have any modified fuzz tests. --- .../scripts/testing/test-heavy-fuzz-modified-tests.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh b/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh index 6f8706366916..b608f88bea08 100755 --- a/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh +++ b/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh @@ -88,6 +88,11 @@ for FILE in $CHANGED_FILES; do # Extract function names and their line numbers from the entire file FUNCTION_LINES=$(awk '/function testFuzz_|function invariant_/ {print FNR, $0}' "$FILE") + # If there are no function lines, skip the file. + if [ -z "$FUNCTION_LINES" ]; then + continue + fi + # Reverse the function lines so we can match the last function modified. # We'd otherwise end up matching the first function with a line number less # than the modified line number which is not what we want. From ea665b5ac96c1b1f58cb2e303d3f3d071b602fd5 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Thu, 12 Sep 2024 16:05:43 -0400 Subject: [PATCH 123/264] fix(ci): tweak heavy fuzz run parameters (#11894) Tweaks various parameters for the heavy fuzz run tests to prevent the test from taking too long. We can run a daily super heavy fuzz run instead to catch any rare flakes. --- .circleci/config.yml | 7 ++++++- .../scripts/testing/test-heavy-fuzz-modified-tests.sh | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8afcb1af6df4..8c01d9d9f917 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -559,6 +559,10 @@ jobs: test_command: description: List of test files to run type: string + test_timeout: + description: Timeout for running tests + type: string + default: 15m parallelism: <> steps: - checkout @@ -596,7 +600,7 @@ jobs: environment: FOUNDRY_PROFILE: ci working_directory: packages/contracts-bedrock - no_output_timeout: 15m + no_output_timeout: <> - run: name: print failed test traces command: just test-rerun @@ -1579,6 +1583,7 @@ workflows: # Heavily fuzz any fuzz tests that have been added or modified. name: contracts-bedrock-tests-heavy-fuzz-modified test_parallelism: 1 + test_timeout: 1h test_command: just test-heavy-fuzz-modified-tests - contracts-bedrock-coverage - contracts-bedrock-checks: diff --git a/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh b/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh index b608f88bea08..058d1c3f68cf 100755 --- a/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh +++ b/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh @@ -12,10 +12,10 @@ set -euo pipefail # modified. # Set the number of fuzz runs to run. -# 350000 fuzz runs will guarantee that any test that fails 1% of the time with -# the default 512 fuzz runs will fail 99.9% of the time (on average) inside of +# 75000 fuzz runs will guarantee that any test that fails 5% of the time with +# the default 512 fuzz runs will fail >99.9% of the time (on average) inside of # this script. -FUZZ_RUNS=${1:-350000} +FUZZ_RUNS=${1:-75000} # Set the number of invariant runs to run. # Invariant runs are generally slower than fuzz runs so we can't afford to run From e3cf320f9357f57c07d456d81517def0ab7fcdad Mon Sep 17 00:00:00 2001 From: zhiqiangxu <652732310@qq.com> Date: Fri, 13 Sep 2024 04:25:44 +0800 Subject: [PATCH 124/264] discard candidate when ahead (#11874) * discard candidate when ahead * also discard result.Unsafe for consistency * remove unnecessary type convertion for FakeGenesis * Revert "also discard result.Unsafe for consistency" This reverts commit d2288d4a01bb4176fd1a3c6e1901646c7bb404c7. * remove type cast --- op-node/rollup/sync/start.go | 2 ++ op-node/rollup/sync/start_test.go | 2 +- op-service/testutils/fake_chain.go | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/op-node/rollup/sync/start.go b/op-node/rollup/sync/start.go index e9a53806080c..15a811bce57f 100644 --- a/op-node/rollup/sync/start.go +++ b/op-node/rollup/sync/start.go @@ -214,6 +214,8 @@ func FindL2Heads(ctx context.Context, cfg *rollup.Config, l1 L1Chain, l2 L2Chain } if ahead { + // discard previous candidate + highestL2WithCanonicalL1Origin = eth.L2BlockRef{} // keep the unsafe head if we can't tell if its L1 origin is canonical or not yet. } else if l1Block.Hash == n.L1Origin.Hash { // if L2 matches canonical chain, even if unsafe, diff --git a/op-node/rollup/sync/start_test.go b/op-node/rollup/sync/start_test.go index 0c202543c5de..e2cfee7712cc 100644 --- a/op-node/rollup/sync/start_test.go +++ b/op-node/rollup/sync/start_test.go @@ -26,7 +26,7 @@ func (c *syncStartTestCase) generateFakeL2(t *testing.T) (*testutils.FakeChainSo log := testlog.Logger(t, log.LevelError) chain := testutils.NewFakeChainSource([]string{c.L1, c.NewL1}, []string{c.L2}, int(c.GenesisL1Num), log) chain.SetL2Head(len(c.L2) - 1) - genesis := testutils.FakeGenesis(c.GenesisL1, c.GenesisL2, int(c.GenesisL1Num)) + genesis := testutils.FakeGenesis(c.GenesisL1, c.GenesisL2, c.GenesisL1Num) chain.ReorgL1() for i := 0; i < len(c.NewL1)-1; i++ { chain.AdvanceL1() diff --git a/op-service/testutils/fake_chain.go b/op-service/testutils/fake_chain.go index 8110e37779f1..eca4de1160b6 100644 --- a/op-service/testutils/fake_chain.go +++ b/op-service/testutils/fake_chain.go @@ -14,9 +14,9 @@ import ( "github.com/ethereum-optimism/optimism/op-service/eth" ) -func FakeGenesis(l1 rune, l2 rune, l1GenesisNumber int) rollup.Genesis { +func FakeGenesis(l1 rune, l2 rune, l1GenesisNumber uint64) rollup.Genesis { return rollup.Genesis{ - L1: fakeID(l1, uint64(l1GenesisNumber)), + L1: fakeID(l1, l1GenesisNumber), L2: fakeID(l2, 0), } } From 7d8ffa2e7cf25197f076ba671db1441a1ea3f275 Mon Sep 17 00:00:00 2001 From: Sebastian Stammler Date: Thu, 12 Sep 2024 22:31:24 +0200 Subject: [PATCH 125/264] codeowners: own op-e2e/actions/proofs by proofs team (#11895) --- .github/CODEOWNERS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 4c22e9eda31e..1e1823fce0ac 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -20,10 +20,11 @@ /op-conductor @ethereum-optimism/op-conductor @ethereum-optimism/go-reviewers /cannon @ethereum-optimism/proofs @ethereum-optimism/go-reviewers -/op-dispute-mon @ethereum-optimism/proofs @ethereum-optimism/go-reviewers /op-challenger @ethereum-optimism/proofs @ethereum-optimism/go-reviewers +/op-dispute-mon @ethereum-optimism/proofs @ethereum-optimism/go-reviewers /op-preimage @ethereum-optimism/proofs @ethereum-optimism/go-reviewers /op-program @ethereum-optimism/proofs @ethereum-optimism/go-reviewers +/op-e2e/actions/proofs @ethereum-optimism/proofs @ethereum-optimism/go-reviewers # Ops /.circleci @ethereum-optimism/monorepo-ops-reviewers From fb11507db1b1240a45bf86c43abf3e12a38af145 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Thu, 12 Sep 2024 16:38:34 -0400 Subject: [PATCH 126/264] maint: add interfaces for governance contracts (#11878) Adds interfaces for the two governance contracts. --- .../snapshots/abi/MintManager.json | 2 +- .../src/governance/MintManager.sol | 9 ++-- .../interfaces/IGovernanceToken.sol | 50 +++++++++++++++++++ .../governance/interfaces/IMintManager.sol | 19 +++++++ packages/contracts-bedrock/test/Specs.t.sol | 3 +- .../test/governance/MintManager.t.sol | 18 ++++--- .../contracts-bedrock/test/setup/Setup.sol | 4 +- 7 files changed, 90 insertions(+), 15 deletions(-) create mode 100644 packages/contracts-bedrock/src/governance/interfaces/IGovernanceToken.sol create mode 100644 packages/contracts-bedrock/src/governance/interfaces/IMintManager.sol diff --git a/packages/contracts-bedrock/snapshots/abi/MintManager.json b/packages/contracts-bedrock/snapshots/abi/MintManager.json index 36afd1e16719..e942fbd3eddc 100644 --- a/packages/contracts-bedrock/snapshots/abi/MintManager.json +++ b/packages/contracts-bedrock/snapshots/abi/MintManager.json @@ -59,7 +59,7 @@ "name": "governanceToken", "outputs": [ { - "internalType": "contract GovernanceToken", + "internalType": "contract IGovernanceToken", "name": "", "type": "address" } diff --git a/packages/contracts-bedrock/src/governance/MintManager.sol b/packages/contracts-bedrock/src/governance/MintManager.sol index d9feae71dfb3..57abeece6b62 100644 --- a/packages/contracts-bedrock/src/governance/MintManager.sol +++ b/packages/contracts-bedrock/src/governance/MintManager.sol @@ -1,8 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Contracts import "@openzeppelin/contracts/access/Ownable.sol"; -import "./GovernanceToken.sol"; + +// Interfaces +import { IGovernanceToken } from "src/governance/interfaces/IGovernanceToken.sol"; /// @title MintManager /// @notice Set as `owner` of the governance token and responsible for the token inflation @@ -11,7 +14,7 @@ import "./GovernanceToken.sol"; /// token supply. Upgradable to allow changes in the inflation schedule. contract MintManager is Ownable { /// @notice The GovernanceToken that the MintManager can mint tokens - GovernanceToken public immutable governanceToken; + IGovernanceToken public immutable governanceToken; /// @notice The amount of tokens that can be minted per year. /// The value is a fixed point number with 4 decimals. @@ -32,7 +35,7 @@ contract MintManager is Ownable { /// @param _governanceToken The governance token this contract can mint tokens of. constructor(address _upgrader, address _governanceToken) { transferOwnership(_upgrader); - governanceToken = GovernanceToken(_governanceToken); + governanceToken = IGovernanceToken(_governanceToken); } /// @notice Only the token owner is allowed to mint a certain amount of the diff --git a/packages/contracts-bedrock/src/governance/interfaces/IGovernanceToken.sol b/packages/contracts-bedrock/src/governance/interfaces/IGovernanceToken.sol new file mode 100644 index 000000000000..dbef37042f63 --- /dev/null +++ b/packages/contracts-bedrock/src/governance/interfaces/IGovernanceToken.sol @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ERC20Votes } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol"; + +interface IGovernanceToken { + event Approval(address indexed owner, address indexed spender, uint256 value); + event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); + event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance); + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + event Transfer(address indexed from, address indexed to, uint256 value); + + function DOMAIN_SEPARATOR() external view returns (bytes32); + function allowance(address owner, address spender) external view returns (uint256); + function approve(address spender, uint256 amount) external returns (bool); + function balanceOf(address account) external view returns (uint256); + function burn(uint256 amount) external; + function burnFrom(address account, uint256 amount) external; + function checkpoints(address account, uint32 pos) external view returns (ERC20Votes.Checkpoint memory); + function decimals() external view returns (uint8); + function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool); + function delegate(address delegatee) external; + function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external; + function delegates(address account) external view returns (address); + function getPastTotalSupply(uint256 blockNumber) external view returns (uint256); + function getPastVotes(address account, uint256 blockNumber) external view returns (uint256); + function getVotes(address account) external view returns (uint256); + function increaseAllowance(address spender, uint256 addedValue) external returns (bool); + function mint(address _account, uint256 _amount) external; + function name() external view returns (string memory); + function nonces(address owner) external view returns (uint256); + function numCheckpoints(address account) external view returns (uint32); + function owner() external view returns (address); + function permit( + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) + external; + function renounceOwnership() external; + function symbol() external view returns (string memory); + function totalSupply() external view returns (uint256); + function transfer(address to, uint256 amount) external returns (bool); + function transferFrom(address from, address to, uint256 amount) external returns (bool); + function transferOwnership(address newOwner) external; +} diff --git a/packages/contracts-bedrock/src/governance/interfaces/IMintManager.sol b/packages/contracts-bedrock/src/governance/interfaces/IMintManager.sol new file mode 100644 index 000000000000..2bd9da196d62 --- /dev/null +++ b/packages/contracts-bedrock/src/governance/interfaces/IMintManager.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { IGovernanceToken } from "src/governance/interfaces/IGovernanceToken.sol"; + +interface IMintManager { + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + function DENOMINATOR() external view returns (uint256); + function MINT_CAP() external view returns (uint256); + function MINT_PERIOD() external view returns (uint256); + function governanceToken() external view returns (IGovernanceToken); + function mint(address _account, uint256 _amount) external; + function mintPermittedAfter() external view returns (uint256); + function owner() external view returns (address); + function renounceOwnership() external; + function transferOwnership(address newOwner) external; + function upgrade(address _newMintManager) external; +} diff --git a/packages/contracts-bedrock/test/Specs.t.sol b/packages/contracts-bedrock/test/Specs.t.sol index 419ffa69ece3..9fb7d000cad0 100644 --- a/packages/contracts-bedrock/test/Specs.t.sol +++ b/packages/contracts-bedrock/test/Specs.t.sol @@ -940,11 +940,12 @@ contract Specification_Test is CommonTest { /// @notice Ensures that there's an auth spec for every L1 contract function. function testContractAuth() public { - string[] memory pathExcludes = new string[](4); + string[] memory pathExcludes = new string[](5); pathExcludes[0] = "src/dispute/interfaces/*"; pathExcludes[1] = "src/dispute/lib/*"; pathExcludes[2] = "src/Safe/SafeSigners.sol"; pathExcludes[3] = "src/L1/interfaces/*"; + pathExcludes[4] = "src/governance/interfaces/*"; Abi[] memory abis = ForgeArtifacts.getContractFunctionAbis( "src/{L1,dispute,governance,Safe,universal/ProxyAdmin.sol}", pathExcludes ); diff --git a/packages/contracts-bedrock/test/governance/MintManager.t.sol b/packages/contracts-bedrock/test/governance/MintManager.t.sol index 690fa15c0d25..4c008863ed69 100644 --- a/packages/contracts-bedrock/test/governance/MintManager.t.sol +++ b/packages/contracts-bedrock/test/governance/MintManager.t.sol @@ -1,30 +1,32 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Testing utilities +// Testing import { CommonTest } from "test/setup/CommonTest.sol"; -// Target contract dependencies +// Contracts import { GovernanceToken } from "src/governance/GovernanceToken.sol"; - -// Target contract import { MintManager } from "src/governance/MintManager.sol"; +// Interfaces +import { IGovernanceToken } from "src/governance/interfaces/IGovernanceToken.sol"; +import { IMintManager } from "src/governance/interfaces/IMintManager.sol"; + contract MintManager_Initializer is CommonTest { address constant owner = address(0x1234); address constant rando = address(0x5678); - GovernanceToken internal gov; - MintManager internal manager; + IGovernanceToken internal gov; + IMintManager internal manager; /// @dev Sets up the test suite. function setUp() public virtual override { super.setUp(); vm.prank(owner); - gov = new GovernanceToken(); + gov = IGovernanceToken(address(new GovernanceToken())); vm.prank(owner); - manager = new MintManager(owner, address(gov)); + manager = IMintManager(address(new MintManager(owner, address(gov)))); vm.prank(owner); gov.transferOwnership(address(manager)); diff --git a/packages/contracts-bedrock/test/setup/Setup.sol b/packages/contracts-bedrock/test/setup/Setup.sol index 74c1225116e5..01f4e9838cd6 100644 --- a/packages/contracts-bedrock/test/setup/Setup.sol +++ b/packages/contracts-bedrock/test/setup/Setup.sol @@ -24,7 +24,6 @@ import { L1FeeVault } from "src/L2/L1FeeVault.sol"; import { GasPriceOracle } from "src/L2/GasPriceOracle.sol"; import { L1Block } from "src/L2/L1Block.sol"; import { LegacyMessagePasser } from "src/legacy/LegacyMessagePasser.sol"; -import { GovernanceToken } from "src/governance/GovernanceToken.sol"; import { FeeVault } from "src/universal/FeeVault.sol"; import { WETH } from "src/L2/WETH.sol"; import { SuperchainWETH } from "src/L2/SuperchainWETH.sol"; @@ -52,6 +51,7 @@ import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol"; import { IAddressManager } from "src/legacy/interfaces/IAddressManager.sol"; import { IOptimismERC20Factory } from "src/L2/interfaces/IOptimismERC20Factory.sol"; +import { IGovernanceToken } from "src/governance/interfaces/IGovernanceToken.sol"; /// @title Setup /// @dev This contact is responsible for setting up the contracts in state. It currently @@ -105,7 +105,7 @@ contract Setup { GasPriceOracle gasPriceOracle = GasPriceOracle(Predeploys.GAS_PRICE_ORACLE); L1Block l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES); LegacyMessagePasser legacyMessagePasser = LegacyMessagePasser(Predeploys.LEGACY_MESSAGE_PASSER); - GovernanceToken governanceToken = GovernanceToken(Predeploys.GOVERNANCE_TOKEN); + IGovernanceToken governanceToken = IGovernanceToken(Predeploys.GOVERNANCE_TOKEN); WETH weth = WETH(payable(Predeploys.WETH)); SuperchainWETH superchainWeth = SuperchainWETH(payable(Predeploys.SUPERCHAIN_WETH)); ETHLiquidity ethLiquidity = ETHLiquidity(Predeploys.ETH_LIQUIDITY); From 935de9cbeaec9707ad9432b8ea37a4d8ac5241b9 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Thu, 12 Sep 2024 17:30:41 -0400 Subject: [PATCH 127/264] maint: rename Safe folder to safe (#11882) Renames the Safe folder (uppercase) to safe (lowercase) in line with all other folders. --- .../scripts/deploy/DeployOwnership.s.sol | 6 ++--- .../testing/test-heavy-fuzz-modified-tests.sh | 9 ++----- packages/contracts-bedrock/semver-lock.json | 24 +++++++++---------- .../{Safe => safe}/DeputyGuardianModule.sol | 0 .../src/{Safe => safe}/LivenessGuard.sol | 2 +- .../src/{Safe => safe}/LivenessModule.sol | 2 +- .../src/{Safe => safe}/SafeSigners.sol | 0 packages/contracts-bedrock/test/Specs.t.sol | 4 ++-- .../test/{Safe => safe}/DeployOwnership.t.sol | 6 ++--- .../{Safe => safe}/DeputyGuardianModule.t.sol | 2 +- .../test/{Safe => safe}/LivenessGuard.t.sol | 13 ++++++++-- .../test/{Safe => safe}/LivenessModule.t.sol | 4 ++-- .../test/{Safe => safe}/SafeSigners.t.sol | 2 +- 13 files changed, 39 insertions(+), 35 deletions(-) rename packages/contracts-bedrock/src/{Safe => safe}/DeputyGuardianModule.sol (100%) rename packages/contracts-bedrock/src/{Safe => safe}/LivenessGuard.sol (99%) rename packages/contracts-bedrock/src/{Safe => safe}/LivenessModule.sol (99%) rename packages/contracts-bedrock/src/{Safe => safe}/SafeSigners.sol (100%) rename packages/contracts-bedrock/test/{Safe => safe}/DeployOwnership.t.sol (96%) rename packages/contracts-bedrock/test/{Safe => safe}/DeputyGuardianModule.t.sol (99%) rename packages/contracts-bedrock/test/{Safe => safe}/LivenessGuard.t.sol (96%) rename packages/contracts-bedrock/test/{Safe => safe}/LivenessModule.t.sol (99%) rename packages/contracts-bedrock/test/{Safe => safe}/SafeSigners.t.sol (98%) diff --git a/packages/contracts-bedrock/scripts/deploy/DeployOwnership.s.sol b/packages/contracts-bedrock/scripts/deploy/DeployOwnership.s.sol index a40c06a17c0f..252b4703b203 100644 --- a/packages/contracts-bedrock/scripts/deploy/DeployOwnership.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/DeployOwnership.s.sol @@ -11,9 +11,9 @@ import { GuardManager } from "safe-contracts/base/GuardManager.sol"; import { Deployer } from "scripts/deploy/Deployer.sol"; -import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; -import { LivenessModule } from "src/Safe/LivenessModule.sol"; -import { DeputyGuardianModule } from "src/Safe/DeputyGuardianModule.sol"; +import { LivenessGuard } from "src/safe/LivenessGuard.sol"; +import { LivenessModule } from "src/safe/LivenessModule.sol"; +import { DeputyGuardianModule } from "src/safe/DeputyGuardianModule.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { Deploy } from "./Deploy.s.sol"; diff --git a/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh b/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh index 058d1c3f68cf..2649c85a5016 100755 --- a/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh +++ b/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh @@ -12,15 +12,10 @@ set -euo pipefail # modified. # Set the number of fuzz runs to run. -# 75000 fuzz runs will guarantee that any test that fails 5% of the time with -# the default 512 fuzz runs will fail >99.9% of the time (on average) inside of -# this script. -FUZZ_RUNS=${1:-75000} +FUZZ_RUNS=${1:-10000} # Set the number of invariant runs to run. -# Invariant runs are generally slower than fuzz runs so we can't afford to run -# as many of them. 25000 is probably good enough for most cases. -INVARIANT_RUNS=${2:-25000} +INVARIANT_RUNS=${2:-10000} # Verify that FUZZ_RUNS is a number. if ! [[ "$FUZZ_RUNS" =~ ^[0-9]+$ ]]; then diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 01a17e96adb2..1d3f5c04399f 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -139,18 +139,6 @@ "initCodeHash": "0x789916977b4930eb266f2187a100bc432c12b76e3872931be673a7ef2773507a", "sourceCodeHash": "0x3f7bd622a788b8d00fe1631b14b761488eedccf56879f7ea2d610dd5ce81efbe" }, - "src/Safe/DeputyGuardianModule.sol": { - "initCodeHash": "0x785cb529957f4d42d1659f2c37967dce7c621f3c6e06550600897205c2551a88", - "sourceCodeHash": "0xc8df2c0ae90cff18ddd4d2b8e2d44689e3c4c98e96c746c4ee9baaebf6a80ec4" - }, - "src/Safe/LivenessGuard.sol": { - "initCodeHash": "0xfd74ff89e7b689b38ab97515d64429ffaf6c0cd1ea6488c6a4743a0665419c85", - "sourceCodeHash": "0xcfeadabe8da944fb64d85c9c971ee364baddcc6aa5b5a0701049669ce372cd90" - }, - "src/Safe/LivenessModule.sol": { - "initCodeHash": "0xcfccdd9e423c95a0ddc6e09ccb6333d5fc8429ed2b8fc872f1290d392ae13aad", - "sourceCodeHash": "0x255a3f78036745feb57da2e16a93a83fe3f52944fec42029da9b9eaa147db11c" - }, "src/cannon/MIPS.sol": { "initCodeHash": "0x6add59adb849ec02e13b33df7efd439ca80f6a8ceefdf69ebcb0963c0167da23", "sourceCodeHash": "0xee1aef5a502f9491b7b83dab46ea2f0fc286f87ace31edcc1367c840d462bdfe" @@ -207,6 +195,18 @@ "initCodeHash": "0x28dfa6676702a7abd19609cc773158d1f958210bc0a38c008d67a002dc1df862", "sourceCodeHash": "0x3a0a294932d6deba043f6a2b46b4e8477ee96e7fb054d7e7229a43ce4352c68d" }, + "src/safe/DeputyGuardianModule.sol": { + "initCodeHash": "0x785cb529957f4d42d1659f2c37967dce7c621f3c6e06550600897205c2551a88", + "sourceCodeHash": "0xc8df2c0ae90cff18ddd4d2b8e2d44689e3c4c98e96c746c4ee9baaebf6a80ec4" + }, + "src/safe/LivenessGuard.sol": { + "initCodeHash": "0xfd74ff89e7b689b38ab97515d64429ffaf6c0cd1ea6488c6a4743a0665419c85", + "sourceCodeHash": "0xa40ea6472d9c7e124791489c0899822d6f6b19b16e583d3b437674c615e4bac3" + }, + "src/safe/LivenessModule.sol": { + "initCodeHash": "0xcfccdd9e423c95a0ddc6e09ccb6333d5fc8429ed2b8fc872f1290d392ae13aad", + "sourceCodeHash": "0xd1479c60087f352385b6d5379ef3cc07839f671d617626b4c94ece91da781ef2" + }, "src/universal/OptimismMintableERC20.sol": { "initCodeHash": "0xfc77e4db406c232d8b84a3f77b939fb08fa27852faa5f4b0d78d998402caf308", "sourceCodeHash": "0xd7957c662ef03fc0cc3440a6ec6737a55f90b52a977262a260cd99fe96494267" diff --git a/packages/contracts-bedrock/src/Safe/DeputyGuardianModule.sol b/packages/contracts-bedrock/src/safe/DeputyGuardianModule.sol similarity index 100% rename from packages/contracts-bedrock/src/Safe/DeputyGuardianModule.sol rename to packages/contracts-bedrock/src/safe/DeputyGuardianModule.sol diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/safe/LivenessGuard.sol similarity index 99% rename from packages/contracts-bedrock/src/Safe/LivenessGuard.sol rename to packages/contracts-bedrock/src/safe/LivenessGuard.sol index f6bfb6aaf8eb..d4fe5c98c89b 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/safe/LivenessGuard.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; import { GnosisSafe as Safe } from "safe-contracts/GnosisSafe.sol"; import { Guard as BaseGuard } from "safe-contracts/base/GuardManager.sol"; -import { SafeSigners } from "src/Safe/SafeSigners.sol"; +import { SafeSigners } from "src/safe/SafeSigners.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/safe/LivenessModule.sol similarity index 99% rename from packages/contracts-bedrock/src/Safe/LivenessModule.sol rename to packages/contracts-bedrock/src/safe/LivenessModule.sol index cf0eab99b8c2..cd41c6e2dd53 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/safe/LivenessModule.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.15; import { GnosisSafe as Safe } from "safe-contracts/GnosisSafe.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; import { OwnerManager } from "safe-contracts/base/OwnerManager.sol"; -import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; +import { LivenessGuard } from "src/safe/LivenessGuard.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @title LivenessModule diff --git a/packages/contracts-bedrock/src/Safe/SafeSigners.sol b/packages/contracts-bedrock/src/safe/SafeSigners.sol similarity index 100% rename from packages/contracts-bedrock/src/Safe/SafeSigners.sol rename to packages/contracts-bedrock/src/safe/SafeSigners.sol diff --git a/packages/contracts-bedrock/test/Specs.t.sol b/packages/contracts-bedrock/test/Specs.t.sol index 9fb7d000cad0..15e20f4d01f1 100644 --- a/packages/contracts-bedrock/test/Specs.t.sol +++ b/packages/contracts-bedrock/test/Specs.t.sol @@ -943,11 +943,11 @@ contract Specification_Test is CommonTest { string[] memory pathExcludes = new string[](5); pathExcludes[0] = "src/dispute/interfaces/*"; pathExcludes[1] = "src/dispute/lib/*"; - pathExcludes[2] = "src/Safe/SafeSigners.sol"; + pathExcludes[2] = "src/safe/SafeSigners.sol"; pathExcludes[3] = "src/L1/interfaces/*"; pathExcludes[4] = "src/governance/interfaces/*"; Abi[] memory abis = ForgeArtifacts.getContractFunctionAbis( - "src/{L1,dispute,governance,Safe,universal/ProxyAdmin.sol}", pathExcludes + "src/{L1,dispute,governance,safe,universal/ProxyAdmin.sol}", pathExcludes ); uint256 numCheckedEntries = 0; diff --git a/packages/contracts-bedrock/test/Safe/DeployOwnership.t.sol b/packages/contracts-bedrock/test/safe/DeployOwnership.t.sol similarity index 96% rename from packages/contracts-bedrock/test/Safe/DeployOwnership.t.sol rename to packages/contracts-bedrock/test/safe/DeployOwnership.t.sol index 516c8443f035..8e3a939686cb 100644 --- a/packages/contracts-bedrock/test/Safe/DeployOwnership.t.sol +++ b/packages/contracts-bedrock/test/safe/DeployOwnership.t.sol @@ -15,9 +15,9 @@ import { GnosisSafe as Safe } from "safe-contracts/GnosisSafe.sol"; import { ModuleManager } from "safe-contracts/base/ModuleManager.sol"; import { GuardManager } from "safe-contracts/base/GuardManager.sol"; -import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; -import { LivenessModule } from "src/Safe/LivenessModule.sol"; -import { DeputyGuardianModule } from "src/Safe/DeputyGuardianModule.sol"; +import { LivenessGuard } from "src/safe/LivenessGuard.sol"; +import { LivenessModule } from "src/safe/LivenessModule.sol"; +import { DeputyGuardianModule } from "src/safe/DeputyGuardianModule.sol"; contract DeployOwnershipTest is Test, DeployOwnership { address internal constant SENTINEL_MODULES = address(0x1); diff --git a/packages/contracts-bedrock/test/Safe/DeputyGuardianModule.t.sol b/packages/contracts-bedrock/test/safe/DeputyGuardianModule.t.sol similarity index 99% rename from packages/contracts-bedrock/test/Safe/DeputyGuardianModule.t.sol rename to packages/contracts-bedrock/test/safe/DeputyGuardianModule.t.sol index 4bc5879bbf64..9ebc60d6100d 100644 --- a/packages/contracts-bedrock/test/Safe/DeputyGuardianModule.t.sol +++ b/packages/contracts-bedrock/test/safe/DeputyGuardianModule.t.sol @@ -9,7 +9,7 @@ import "test/safe-tools/SafeTestTools.sol"; import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; -import { DeputyGuardianModule } from "src/Safe/DeputyGuardianModule.sol"; +import { DeputyGuardianModule } from "src/safe/DeputyGuardianModule.sol"; import "src/dispute/lib/Types.sol"; diff --git a/packages/contracts-bedrock/test/Safe/LivenessGuard.t.sol b/packages/contracts-bedrock/test/safe/LivenessGuard.t.sol similarity index 96% rename from packages/contracts-bedrock/test/Safe/LivenessGuard.t.sol rename to packages/contracts-bedrock/test/safe/LivenessGuard.t.sol index b8d67506da6d..41db45ac974a 100644 --- a/packages/contracts-bedrock/test/Safe/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/safe/LivenessGuard.t.sol @@ -10,7 +10,7 @@ import { Enum } from "safe-contracts/common/Enum.sol"; import "test/safe-tools/SafeTestTools.sol"; import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; -import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; +import { LivenessGuard } from "src/safe/LivenessGuard.sol"; /// @dev A wrapper contract exposing the length of the ownersBefore set in the LivenessGuard. contract WrappedGuard is LivenessGuard { @@ -235,7 +235,16 @@ contract LivenessGuard_FuzzOwnerManagement_Test is StdCheats, StdUtils, Liveness ) external { - vm.assume(changes.length < 20); + // Cut down the changes array to a maximum of 20. + // We don't use vm.assume to avoid throwing out too many inputs. + OwnerChange[] memory boundedChanges = new OwnerChange[](bound(changes.length, 0, 20)); + for (uint256 i; i < boundedChanges.length; i++) { + boundedChanges[i] = changes[i]; + } + + // Update the original array. + changes = boundedChanges; + // Initialize the safe with more owners than changes, to ensure we don't try to remove them all initialOwners = bound(initialOwners, changes.length, 2 * changes.length); diff --git a/packages/contracts-bedrock/test/Safe/LivenessModule.t.sol b/packages/contracts-bedrock/test/safe/LivenessModule.t.sol similarity index 99% rename from packages/contracts-bedrock/test/Safe/LivenessModule.t.sol rename to packages/contracts-bedrock/test/safe/LivenessModule.t.sol index f27e8aab4c50..060dfb389ca4 100644 --- a/packages/contracts-bedrock/test/Safe/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/safe/LivenessModule.t.sol @@ -7,8 +7,8 @@ import { OwnerManager } from "safe-contracts/base/OwnerManager.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; import "test/safe-tools/SafeTestTools.sol"; -import { LivenessModule } from "src/Safe/LivenessModule.sol"; -import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; +import { LivenessModule } from "src/safe/LivenessModule.sol"; +import { LivenessGuard } from "src/safe/LivenessGuard.sol"; contract LivenessModule_TestInit is Test, SafeTestTools { using SafeTestLib for SafeInstance; diff --git a/packages/contracts-bedrock/test/Safe/SafeSigners.t.sol b/packages/contracts-bedrock/test/safe/SafeSigners.t.sol similarity index 98% rename from packages/contracts-bedrock/test/Safe/SafeSigners.t.sol rename to packages/contracts-bedrock/test/safe/SafeSigners.t.sol index 2006a44b9e71..a6caf2a487ff 100644 --- a/packages/contracts-bedrock/test/Safe/SafeSigners.t.sol +++ b/packages/contracts-bedrock/test/safe/SafeSigners.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; import { GnosisSafe as Safe } from "safe-contracts/GnosisSafe.sol"; -import { SafeSigners } from "src/Safe/SafeSigners.sol"; +import { SafeSigners } from "src/safe/SafeSigners.sol"; import "test/safe-tools/SafeTestTools.sol"; contract SafeSigners_Test is Test, SafeTestTools { From ef1bf0acd23572c90f93eeb8be19eea603eea33e Mon Sep 17 00:00:00 2001 From: Matt Solomon Date: Thu, 12 Sep 2024 15:14:18 -0700 Subject: [PATCH 128/264] opsm: remove remaining structs (#11854) * refactor: remove structs from DeployImplementations * refactor: remove structs from DeployOPChain * test: fix tests * Update packages/contracts-bedrock/test/DeployOPChain.t.sol Co-authored-by: Blaine Malone * Update packages/contracts-bedrock/test/DeployOPChain.t.sol Co-authored-by: Blaine Malone * test: add missing assertions * fix: update fuzz test timeout --------- Co-authored-by: Blaine Malone Co-authored-by: Kelvin Fichter --- .../scripts/DeployImplementations.s.sol | 247 ++++++----- .../scripts/DeployOPChain.s.sol | 308 +++++++------- .../scripts/DeploySuperchain.s.sol | 3 +- .../test/DeployImplementations.t.sol | 289 ++++++------- .../test/DeployOPChain.t.sol | 396 +++++++++--------- .../test/L1/OPStackManager.t.sol | 56 ++- 6 files changed, 644 insertions(+), 655 deletions(-) diff --git a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol index dfe6a61cdaa1..4db20bab5871 100644 --- a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol +++ b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol @@ -3,6 +3,8 @@ pragma solidity 0.8.15; import { Script } from "forge-std/Script.sol"; +import { LibString } from "@solady/utils/LibString.sol"; + import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { Proxy } from "src/universal/Proxy.sol"; import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol"; @@ -36,119 +38,128 @@ import { Solarray } from "scripts/libraries/Solarray.sol"; // See DeploySuperchain.s.sol for detailed comments on the script architecture used here. contract DeployImplementationsInput { - struct Input { - uint256 withdrawalDelaySeconds; - uint256 minProposalSizeBytes; - uint256 challengePeriodSeconds; - uint256 proofMaturityDelaySeconds; - uint256 disputeGameFinalityDelaySeconds; - // We also deploy OP Stack Manager here, which has a dependency on the prior step of deploying - // the superchain contracts. - string release; // The release version to set OPSM implementations for, of the format `op-contracts/vX.Y.Z`. - SuperchainConfig superchainConfigProxy; - ProtocolVersions protocolVersionsProxy; - } - - bool public inputSet = false; - Input internal inputs; - - function loadInputFile(string memory _infile) public { - _infile; - Input memory parsedInput; - loadInput(parsedInput); - require(false, "DeployImplementationsInput: not implemented"); + uint256 internal _withdrawalDelaySeconds; + uint256 internal _minProposalSizeBytes; + uint256 internal _challengePeriodSeconds; + uint256 internal _proofMaturityDelaySeconds; + uint256 internal _disputeGameFinalityDelaySeconds; + + // The release version to set OPSM implementations for, of the format `op-contracts/vX.Y.Z`. + string internal _release; + + // Outputs from DeploySuperchain.s.sol. + SuperchainConfig internal _superchainConfigProxy; + ProtocolVersions internal _protocolVersionsProxy; + + function set(bytes4 sel, uint256 _value) public { + require(_value != 0, "DeployImplementationsInput: cannot set zero value"); + + if (sel == this.withdrawalDelaySeconds.selector) { + _withdrawalDelaySeconds = _value; + } else if (sel == this.minProposalSizeBytes.selector) { + _minProposalSizeBytes = _value; + } else if (sel == this.challengePeriodSeconds.selector) { + require(_value <= type(uint64).max, "DeployImplementationsInput: challengePeriodSeconds too large"); + _challengePeriodSeconds = _value; + } else if (sel == this.proofMaturityDelaySeconds.selector) { + _proofMaturityDelaySeconds = _value; + } else if (sel == this.disputeGameFinalityDelaySeconds.selector) { + _disputeGameFinalityDelaySeconds = _value; + } else { + revert("DeployImplementationsInput: unknown selector"); + } } - function loadInput(Input memory _input) public { - require(!inputSet, "DeployImplementationsInput: input already set"); - require( - _input.challengePeriodSeconds <= type(uint64).max, "DeployImplementationsInput: challenge period too large" - ); - - inputSet = true; - inputs = _input; + function set(bytes4 sel, string memory _value) public { + require(!LibString.eq(_value, ""), "DeployImplementationsInput: cannot set empty string"); + if (sel == this.release.selector) _release = _value; + else revert("DeployImplementationsInput: unknown selector"); } - function assertInputSet() internal view { - require(inputSet, "DeployImplementationsInput: input not set"); + function set(bytes4 sel, address _addr) public { + require(_addr != address(0), "DeployImplementationsInput: cannot set zero address"); + if (sel == this.superchainConfigProxy.selector) _superchainConfigProxy = SuperchainConfig(_addr); + else if (sel == this.protocolVersionsProxy.selector) _protocolVersionsProxy = ProtocolVersions(_addr); + else revert("DeployImplementationsInput: unknown selector"); } - function input() public view returns (Input memory) { - assertInputSet(); - return inputs; + function loadInputFile(string memory _infile) public pure { + _infile; + require(false, "DeployImplementationsInput: not implemented"); } function withdrawalDelaySeconds() public view returns (uint256) { - assertInputSet(); - return inputs.withdrawalDelaySeconds; + require(_withdrawalDelaySeconds != 0, "DeployImplementationsInput: not set"); + return _withdrawalDelaySeconds; } function minProposalSizeBytes() public view returns (uint256) { - assertInputSet(); - return inputs.minProposalSizeBytes; + require(_minProposalSizeBytes != 0, "DeployImplementationsInput: not set"); + return _minProposalSizeBytes; } function challengePeriodSeconds() public view returns (uint256) { - assertInputSet(); - return inputs.challengePeriodSeconds; + require(_challengePeriodSeconds != 0, "DeployImplementationsInput: not set"); + require( + _challengePeriodSeconds <= type(uint64).max, "DeployImplementationsInput: challengePeriodSeconds too large" + ); + return _challengePeriodSeconds; } function proofMaturityDelaySeconds() public view returns (uint256) { - assertInputSet(); - return inputs.proofMaturityDelaySeconds; + require(_proofMaturityDelaySeconds != 0, "DeployImplementationsInput: not set"); + return _proofMaturityDelaySeconds; } function disputeGameFinalityDelaySeconds() public view returns (uint256) { - assertInputSet(); - return inputs.disputeGameFinalityDelaySeconds; + require(_disputeGameFinalityDelaySeconds != 0, "DeployImplementationsInput: not set"); + return _disputeGameFinalityDelaySeconds; } function release() public view returns (string memory) { - assertInputSet(); - return inputs.release; + require(!LibString.eq(_release, ""), "DeployImplementationsInput: not set"); + return _release; } function superchainConfigProxy() public view returns (SuperchainConfig) { - assertInputSet(); - return inputs.superchainConfigProxy; + require(address(_superchainConfigProxy) != address(0), "DeployImplementationsInput: not set"); + return _superchainConfigProxy; } function protocolVersionsProxy() public view returns (ProtocolVersions) { - assertInputSet(); - return inputs.protocolVersionsProxy; + require(address(_protocolVersionsProxy) != address(0), "DeployImplementationsInput: not set"); + return _protocolVersionsProxy; } } contract DeployImplementationsOutput { - struct Output { - OPStackManager opsm; - DelayedWETH delayedWETHImpl; - OptimismPortal2 optimismPortalImpl; - PreimageOracle preimageOracleSingleton; - MIPS mipsSingleton; - SystemConfig systemConfigImpl; - L1CrossDomainMessenger l1CrossDomainMessengerImpl; - L1ERC721Bridge l1ERC721BridgeImpl; - L1StandardBridge l1StandardBridgeImpl; - OptimismMintableERC20Factory optimismMintableERC20FactoryImpl; - DisputeGameFactory disputeGameFactoryImpl; - } - - Output internal outputs; + OPStackManager internal _opsm; + DelayedWETH internal _delayedWETHImpl; + OptimismPortal2 internal _optimismPortalImpl; + PreimageOracle internal _preimageOracleSingleton; + MIPS internal _mipsSingleton; + SystemConfig internal _systemConfigImpl; + L1CrossDomainMessenger internal _l1CrossDomainMessengerImpl; + L1ERC721Bridge internal _l1ERC721BridgeImpl; + L1StandardBridge internal _l1StandardBridgeImpl; + OptimismMintableERC20Factory internal _optimismMintableERC20FactoryImpl; + DisputeGameFactory internal _disputeGameFactoryImpl; function set(bytes4 sel, address _addr) public { + require(_addr != address(0), "DeployImplementationsOutput: cannot set zero address"); + // forgefmt: disable-start - if (sel == this.opsm.selector) outputs.opsm = OPStackManager(payable(_addr)); - else if (sel == this.optimismPortalImpl.selector) outputs.optimismPortalImpl = OptimismPortal2(payable(_addr)); - else if (sel == this.delayedWETHImpl.selector) outputs.delayedWETHImpl = DelayedWETH(payable(_addr)); - else if (sel == this.preimageOracleSingleton.selector) outputs.preimageOracleSingleton = PreimageOracle(_addr); - else if (sel == this.mipsSingleton.selector) outputs.mipsSingleton = MIPS(_addr); - else if (sel == this.systemConfigImpl.selector) outputs.systemConfigImpl = SystemConfig(_addr); - else if (sel == this.l1CrossDomainMessengerImpl.selector) outputs.l1CrossDomainMessengerImpl = L1CrossDomainMessenger(_addr); - else if (sel == this.l1ERC721BridgeImpl.selector) outputs.l1ERC721BridgeImpl = L1ERC721Bridge(_addr); - else if (sel == this.l1StandardBridgeImpl.selector) outputs.l1StandardBridgeImpl = L1StandardBridge(payable(_addr)); - else if (sel == this.optimismMintableERC20FactoryImpl.selector) outputs.optimismMintableERC20FactoryImpl = OptimismMintableERC20Factory(_addr); - else if (sel == this.disputeGameFactoryImpl.selector) outputs.disputeGameFactoryImpl = DisputeGameFactory(_addr); + if (sel == this.opsm.selector) _opsm = OPStackManager(payable(_addr)); + else if (sel == this.optimismPortalImpl.selector) _optimismPortalImpl = OptimismPortal2(payable(_addr)); + else if (sel == this.delayedWETHImpl.selector) _delayedWETHImpl = DelayedWETH(payable(_addr)); + else if (sel == this.preimageOracleSingleton.selector) _preimageOracleSingleton = PreimageOracle(_addr); + else if (sel == this.mipsSingleton.selector) _mipsSingleton = MIPS(_addr); + else if (sel == this.systemConfigImpl.selector) _systemConfigImpl = SystemConfig(_addr); + else if (sel == this.l1CrossDomainMessengerImpl.selector) _l1CrossDomainMessengerImpl = L1CrossDomainMessenger(_addr); + else if (sel == this.l1ERC721BridgeImpl.selector) _l1ERC721BridgeImpl = L1ERC721Bridge(_addr); + else if (sel == this.l1StandardBridgeImpl.selector) _l1StandardBridgeImpl = L1StandardBridge(payable(_addr)); + else if (sel == this.optimismMintableERC20FactoryImpl.selector) _optimismMintableERC20FactoryImpl = OptimismMintableERC20Factory(_addr); + else if (sel == this.disputeGameFactoryImpl.selector) _disputeGameFactoryImpl = DisputeGameFactory(_addr); else revert("DeployImplementationsOutput: unknown selector"); // forgefmt: disable-end } @@ -158,80 +169,76 @@ contract DeployImplementationsOutput { require(false, "DeployImplementationsOutput: not implemented"); } - function output() public view returns (Output memory) { - return outputs; - } - function checkOutput() public view { address[] memory addrs = Solarray.addresses( - address(outputs.opsm), - address(outputs.optimismPortalImpl), - address(outputs.delayedWETHImpl), - address(outputs.preimageOracleSingleton), - address(outputs.mipsSingleton), - address(outputs.systemConfigImpl), - address(outputs.l1CrossDomainMessengerImpl), - address(outputs.l1ERC721BridgeImpl), - address(outputs.l1StandardBridgeImpl), - address(outputs.optimismMintableERC20FactoryImpl), - address(outputs.disputeGameFactoryImpl) + address(this.opsm()), + address(this.optimismPortalImpl()), + address(this.delayedWETHImpl()), + address(this.preimageOracleSingleton()), + address(this.mipsSingleton()), + address(this.systemConfigImpl()), + address(this.l1CrossDomainMessengerImpl()), + address(this.l1ERC721BridgeImpl()), + address(this.l1StandardBridgeImpl()), + address(this.optimismMintableERC20FactoryImpl()), + address(this.disputeGameFactoryImpl()) ); DeployUtils.assertValidContractAddresses(addrs); } function opsm() public view returns (OPStackManager) { - DeployUtils.assertValidContractAddress(address(outputs.opsm)); - return outputs.opsm; + DeployUtils.assertValidContractAddress(address(_opsm)); + return _opsm; } function optimismPortalImpl() public view returns (OptimismPortal2) { - DeployUtils.assertValidContractAddress(address(outputs.optimismPortalImpl)); - return outputs.optimismPortalImpl; + DeployUtils.assertValidContractAddress(address(_optimismPortalImpl)); + return _optimismPortalImpl; } function delayedWETHImpl() public view returns (DelayedWETH) { - DeployUtils.assertValidContractAddress(address(outputs.delayedWETHImpl)); - return outputs.delayedWETHImpl; + DeployUtils.assertValidContractAddress(address(_delayedWETHImpl)); + return _delayedWETHImpl; } function preimageOracleSingleton() public view returns (PreimageOracle) { - DeployUtils.assertValidContractAddress(address(outputs.preimageOracleSingleton)); - return outputs.preimageOracleSingleton; + DeployUtils.assertValidContractAddress(address(_preimageOracleSingleton)); + return _preimageOracleSingleton; } function mipsSingleton() public view returns (MIPS) { - DeployUtils.assertValidContractAddress(address(outputs.mipsSingleton)); - return outputs.mipsSingleton; + DeployUtils.assertValidContractAddress(address(_mipsSingleton)); + return _mipsSingleton; } function systemConfigImpl() public view returns (SystemConfig) { - DeployUtils.assertValidContractAddress(address(outputs.systemConfigImpl)); - return outputs.systemConfigImpl; + DeployUtils.assertValidContractAddress(address(_systemConfigImpl)); + return _systemConfigImpl; } function l1CrossDomainMessengerImpl() public view returns (L1CrossDomainMessenger) { - DeployUtils.assertValidContractAddress(address(outputs.l1CrossDomainMessengerImpl)); - return outputs.l1CrossDomainMessengerImpl; + DeployUtils.assertValidContractAddress(address(_l1CrossDomainMessengerImpl)); + return _l1CrossDomainMessengerImpl; } function l1ERC721BridgeImpl() public view returns (L1ERC721Bridge) { - DeployUtils.assertValidContractAddress(address(outputs.l1ERC721BridgeImpl)); - return outputs.l1ERC721BridgeImpl; + DeployUtils.assertValidContractAddress(address(_l1ERC721BridgeImpl)); + return _l1ERC721BridgeImpl; } function l1StandardBridgeImpl() public view returns (L1StandardBridge) { - DeployUtils.assertValidContractAddress(address(outputs.l1StandardBridgeImpl)); - return outputs.l1StandardBridgeImpl; + DeployUtils.assertValidContractAddress(address(_l1StandardBridgeImpl)); + return _l1StandardBridgeImpl; } function optimismMintableERC20FactoryImpl() public view returns (OptimismMintableERC20Factory) { - DeployUtils.assertValidContractAddress(address(outputs.optimismMintableERC20FactoryImpl)); - return outputs.optimismMintableERC20FactoryImpl; + DeployUtils.assertValidContractAddress(address(_optimismMintableERC20FactoryImpl)); + return _optimismMintableERC20FactoryImpl; } function disputeGameFactoryImpl() public view returns (DisputeGameFactory) { - DeployUtils.assertValidContractAddress(address(outputs.disputeGameFactoryImpl)); - return outputs.disputeGameFactoryImpl; + DeployUtils.assertValidContractAddress(address(_disputeGameFactoryImpl)); + return _disputeGameFactoryImpl; } } @@ -247,19 +254,7 @@ contract DeployImplementations is Script { require(false, "DeployImplementations: run is not implemented"); } - function run(DeployImplementationsInput.Input memory _input) - public - returns (DeployImplementationsOutput.Output memory) - { - (DeployImplementationsInput dii, DeployImplementationsOutput dio) = etchIOContracts(); - dii.loadInput(_input); - run(dii, dio); - return dio.output(); - } - function run(DeployImplementationsInput _dii, DeployImplementationsOutput _dio) public { - require(_dii.inputSet(), "DeployImplementations: input not set"); - // Deploy the implementations. deploySystemConfigImpl(_dii, _dio); deployL1CrossDomainMessengerImpl(_dii, _dio); @@ -521,7 +516,7 @@ contract DeployImplementations is Script { // -------- Utilities -------- - function etchIOContracts() internal returns (DeployImplementationsInput dii_, DeployImplementationsOutput dio_) { + function etchIOContracts() public returns (DeployImplementationsInput dii_, DeployImplementationsOutput dio_) { (dii_, dio_) = getIOContracts(); vm.etch(address(dii_), type(DeployImplementationsInput).runtimeCode); vm.etch(address(dio_), type(DeployImplementationsOutput).runtimeCode); diff --git a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol index 1c0c29c83f83..9aac4aefc5c2 100644 --- a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol @@ -3,6 +3,8 @@ pragma solidity 0.8.15; import { Script } from "forge-std/Script.sol"; +import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol"; + import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; import { Solarray } from "scripts/libraries/Solarray.sol"; @@ -24,151 +26,138 @@ import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; contract DeployOPChainInput { - struct Roles { - address opChainProxyAdminOwner; - address systemConfigOwner; - address batcher; - address unsafeBlockSigner; - address proposer; - address challenger; - } + address internal _opChainProxyAdminOwner; + address internal _systemConfigOwner; + address internal _batcher; + address internal _unsafeBlockSigner; + address internal _proposer; + address internal _challenger; // TODO Add fault proofs inputs in a future PR. - struct Input { - Roles roles; - uint32 basefeeScalar; - uint32 blobBaseFeeScalar; - uint256 l2ChainId; - OPStackManager opsm; - } - - bool public inputSet = false; - Input internal inputs; - - function loadInputFile(string memory _infile) public { + uint32 internal _basefeeScalar; + uint32 internal _blobBaseFeeScalar; + uint256 internal _l2ChainId; + OPStackManager internal _opsm; + + function set(bytes4 _sel, address _addr) public { + require(_addr != address(0), "DeployOPChainInput: cannot set zero address"); + if (_sel == this.opChainProxyAdminOwner.selector) _opChainProxyAdminOwner = _addr; + else if (_sel == this.systemConfigOwner.selector) _systemConfigOwner = _addr; + else if (_sel == this.batcher.selector) _batcher = _addr; + else if (_sel == this.unsafeBlockSigner.selector) _unsafeBlockSigner = _addr; + else if (_sel == this.proposer.selector) _proposer = _addr; + else if (_sel == this.challenger.selector) _challenger = _addr; + else if (_sel == this.opsm.selector) _opsm = OPStackManager(_addr); + else revert("DeployOPChainInput: unknown selector"); + } + + function set(bytes4 _sel, uint256 _value) public { + if (_sel == this.basefeeScalar.selector) { + _basefeeScalar = SafeCast.toUint32(_value); + } else if (_sel == this.blobBaseFeeScalar.selector) { + _blobBaseFeeScalar = SafeCast.toUint32(_value); + } else if (_sel == this.l2ChainId.selector) { + require(_value != 0 && _value != block.chainid, "DeployOPChainInput: invalid l2ChainId"); + _l2ChainId = _value; + } else { + revert("DeployOPChainInput: unknown selector"); + } + } + + function loadInputFile(string memory _infile) public pure { _infile; - Input memory parsedInput; - loadInput(parsedInput); require(false, "DeployOPChainInput: not implemented"); } - function loadInput(Input memory _input) public { - require(!inputSet, "DeployOPChainInput: input already set"); - - require(_input.roles.opChainProxyAdminOwner != address(0), "DeployOPChainInput: null opChainProxyAdminOwner"); - require(_input.roles.systemConfigOwner != address(0), "DeployOPChainInput: null systemConfigOwner"); - require(_input.roles.batcher != address(0), "DeployOPChainInput: null batcher"); - require(_input.roles.unsafeBlockSigner != address(0), "DeployOPChainInput: null unsafeBlockSigner"); - require(_input.roles.proposer != address(0), "DeployOPChainInput: null proposer"); - require(_input.roles.challenger != address(0), "DeployOPChainInput: null challenger"); - require(_input.l2ChainId != 0 && _input.l2ChainId != block.chainid, "DeployOPChainInput: invalid l2ChainId"); - require(address(_input.opsm) != address(0), "DeployOPChainInput: null opsm"); - - inputSet = true; - inputs = _input; - } - - function assertInputSet() internal view { - require(inputSet, "DeployOPChainInput: input not set"); - } - - function input() public view returns (Input memory) { - assertInputSet(); - return inputs; - } - function opChainProxyAdminOwner() public view returns (address) { - assertInputSet(); - return inputs.roles.opChainProxyAdminOwner; + require(_opChainProxyAdminOwner != address(0), "DeployOPChainInput: not set"); + return _opChainProxyAdminOwner; } function systemConfigOwner() public view returns (address) { - assertInputSet(); - return inputs.roles.systemConfigOwner; + require(_systemConfigOwner != address(0), "DeployOPChainInput: not set"); + return _systemConfigOwner; } function batcher() public view returns (address) { - assertInputSet(); - return inputs.roles.batcher; + require(_batcher != address(0), "DeployOPChainInput: not set"); + return _batcher; } function unsafeBlockSigner() public view returns (address) { - assertInputSet(); - return inputs.roles.unsafeBlockSigner; + require(_unsafeBlockSigner != address(0), "DeployOPChainInput: not set"); + return _unsafeBlockSigner; } function proposer() public view returns (address) { - assertInputSet(); - return inputs.roles.proposer; + require(_proposer != address(0), "DeployOPChainInput: not set"); + return _proposer; } function challenger() public view returns (address) { - assertInputSet(); - return inputs.roles.challenger; + require(_challenger != address(0), "DeployOPChainInput: not set"); + return _challenger; } function basefeeScalar() public view returns (uint32) { - assertInputSet(); - return inputs.basefeeScalar; + require(_basefeeScalar != 0, "DeployOPChainInput: not set"); + return _basefeeScalar; } function blobBaseFeeScalar() public view returns (uint32) { - assertInputSet(); - return inputs.blobBaseFeeScalar; + require(_blobBaseFeeScalar != 0, "DeployOPChainInput: not set"); + return _blobBaseFeeScalar; } function l2ChainId() public view returns (uint256) { - assertInputSet(); - return inputs.l2ChainId; + require(_l2ChainId != 0, "DeployOPChainInput: not set"); + require(_l2ChainId != block.chainid, "DeployOPChainInput: invalid l2ChainId"); + return _l2ChainId; } function opsm() public view returns (OPStackManager) { - assertInputSet(); - return inputs.opsm; + require(address(_opsm) != address(0), "DeployOPChainInput: not set"); + return _opsm; } } contract DeployOPChainOutput { - struct Output { - ProxyAdmin opChainProxyAdmin; - AddressManager addressManager; - L1ERC721Bridge l1ERC721BridgeProxy; - SystemConfig systemConfigProxy; - OptimismMintableERC20Factory optimismMintableERC20FactoryProxy; - L1StandardBridge l1StandardBridgeProxy; - L1CrossDomainMessenger l1CrossDomainMessengerProxy; - // Fault proof contracts below. - OptimismPortal2 optimismPortalProxy; - DisputeGameFactory disputeGameFactoryProxy; - DisputeGameFactory disputeGameFactoryImpl; - AnchorStateRegistry anchorStateRegistryProxy; - AnchorStateRegistry anchorStateRegistryImpl; - FaultDisputeGame faultDisputeGame; - PermissionedDisputeGame permissionedDisputeGame; - DelayedWETH delayedWETHPermissionedGameProxy; - DelayedWETH delayedWETHPermissionlessGameProxy; - } - - Output internal outputs; + ProxyAdmin internal _opChainProxyAdmin; + AddressManager internal _addressManager; + L1ERC721Bridge internal _l1ERC721BridgeProxy; + SystemConfig internal _systemConfigProxy; + OptimismMintableERC20Factory internal _optimismMintableERC20FactoryProxy; + L1StandardBridge internal _l1StandardBridgeProxy; + L1CrossDomainMessenger internal _l1CrossDomainMessengerProxy; + OptimismPortal2 internal _optimismPortalProxy; + DisputeGameFactory internal _disputeGameFactoryProxy; + DisputeGameFactory internal _disputeGameFactoryImpl; + AnchorStateRegistry internal _anchorStateRegistryProxy; + AnchorStateRegistry internal _anchorStateRegistryImpl; + FaultDisputeGame internal _faultDisputeGame; + PermissionedDisputeGame internal _permissionedDisputeGame; + DelayedWETH internal _delayedWETHPermissionedGameProxy; + DelayedWETH internal _delayedWETHPermissionlessGameProxy; function set(bytes4 sel, address _addr) public { + require(_addr != address(0), "DeployOPChainOutput: cannot set zero address"); // forgefmt: disable-start - if (sel == this.opChainProxyAdmin.selector) outputs.opChainProxyAdmin = ProxyAdmin(_addr) ; - else if (sel == this.addressManager.selector) outputs.addressManager = AddressManager(_addr) ; - else if (sel == this.l1ERC721BridgeProxy.selector) outputs.l1ERC721BridgeProxy = L1ERC721Bridge(_addr) ; - else if (sel == this.systemConfigProxy.selector) outputs.systemConfigProxy = SystemConfig(_addr) ; - else if (sel == this.optimismMintableERC20FactoryProxy.selector) outputs.optimismMintableERC20FactoryProxy = OptimismMintableERC20Factory(_addr) ; - else if (sel == this.l1StandardBridgeProxy.selector) outputs.l1StandardBridgeProxy = L1StandardBridge(payable(_addr)) ; - else if (sel == this.l1CrossDomainMessengerProxy.selector) outputs.l1CrossDomainMessengerProxy = L1CrossDomainMessenger(_addr) ; - else if (sel == this.optimismPortalProxy.selector) outputs.optimismPortalProxy = OptimismPortal2(payable(_addr)) ; - else if (sel == this.disputeGameFactoryProxy.selector) outputs.disputeGameFactoryProxy = DisputeGameFactory(_addr) ; - else if (sel == this.disputeGameFactoryImpl.selector) outputs.disputeGameFactoryImpl = DisputeGameFactory(_addr) ; - else if (sel == this.anchorStateRegistryProxy.selector) outputs.anchorStateRegistryProxy = AnchorStateRegistry(_addr) ; - else if (sel == this.anchorStateRegistryImpl.selector) outputs.anchorStateRegistryImpl = AnchorStateRegistry(_addr) ; - else if (sel == this.faultDisputeGame.selector) outputs.faultDisputeGame = FaultDisputeGame(_addr) ; - else if (sel == this.permissionedDisputeGame.selector) outputs.permissionedDisputeGame = PermissionedDisputeGame(_addr) ; - else if (sel == this.delayedWETHPermissionedGameProxy.selector) outputs.delayedWETHPermissionedGameProxy = DelayedWETH(payable(_addr)) ; - else if (sel == this.delayedWETHPermissionlessGameProxy.selector) outputs.delayedWETHPermissionlessGameProxy = DelayedWETH(payable(_addr)) ; + if (sel == this.opChainProxyAdmin.selector) _opChainProxyAdmin = ProxyAdmin(_addr) ; + else if (sel == this.addressManager.selector) _addressManager = AddressManager(_addr) ; + else if (sel == this.l1ERC721BridgeProxy.selector) _l1ERC721BridgeProxy = L1ERC721Bridge(_addr) ; + else if (sel == this.systemConfigProxy.selector) _systemConfigProxy = SystemConfig(_addr) ; + else if (sel == this.optimismMintableERC20FactoryProxy.selector) _optimismMintableERC20FactoryProxy = OptimismMintableERC20Factory(_addr) ; + else if (sel == this.l1StandardBridgeProxy.selector) _l1StandardBridgeProxy = L1StandardBridge(payable(_addr)) ; + else if (sel == this.l1CrossDomainMessengerProxy.selector) _l1CrossDomainMessengerProxy = L1CrossDomainMessenger(_addr) ; + else if (sel == this.optimismPortalProxy.selector) _optimismPortalProxy = OptimismPortal2(payable(_addr)) ; + else if (sel == this.disputeGameFactoryProxy.selector) _disputeGameFactoryProxy = DisputeGameFactory(_addr) ; + else if (sel == this.disputeGameFactoryImpl.selector) _disputeGameFactoryImpl = DisputeGameFactory(_addr) ; + else if (sel == this.anchorStateRegistryProxy.selector) _anchorStateRegistryProxy = AnchorStateRegistry(_addr) ; + else if (sel == this.anchorStateRegistryImpl.selector) _anchorStateRegistryImpl = AnchorStateRegistry(_addr) ; + else if (sel == this.faultDisputeGame.selector) _faultDisputeGame = FaultDisputeGame(_addr) ; + else if (sel == this.permissionedDisputeGame.selector) _permissionedDisputeGame = PermissionedDisputeGame(_addr) ; + else if (sel == this.delayedWETHPermissionedGameProxy.selector) _delayedWETHPermissionedGameProxy = DelayedWETH(payable(_addr)) ; + else if (sel == this.delayedWETHPermissionlessGameProxy.selector) _delayedWETHPermissionlessGameProxy = DelayedWETH(payable(_addr)) ; else revert("DeployOPChainOutput: unknown selector"); // forgefmt: disable-end } @@ -178,114 +167,110 @@ contract DeployOPChainOutput { require(false, "DeployOPChainOutput: not implemented"); } - function output() public view returns (Output memory) { - return outputs; - } - function checkOutput() public view { // With 16 addresses, we'd get a stack too deep error if we tried to do this inline as a // single call to `Solarray.addresses`. So we split it into two calls. address[] memory addrs1 = Solarray.addresses( - address(outputs.opChainProxyAdmin), - address(outputs.addressManager), - address(outputs.l1ERC721BridgeProxy), - address(outputs.systemConfigProxy), - address(outputs.optimismMintableERC20FactoryProxy), - address(outputs.l1StandardBridgeProxy), - address(outputs.l1CrossDomainMessengerProxy) + address(_opChainProxyAdmin), + address(_addressManager), + address(_l1ERC721BridgeProxy), + address(_systemConfigProxy), + address(_optimismMintableERC20FactoryProxy), + address(_l1StandardBridgeProxy), + address(_l1CrossDomainMessengerProxy) ); address[] memory addrs2 = Solarray.addresses( - address(outputs.optimismPortalProxy), - address(outputs.disputeGameFactoryProxy), - address(outputs.disputeGameFactoryImpl), - address(outputs.anchorStateRegistryProxy), - address(outputs.anchorStateRegistryImpl), - address(outputs.faultDisputeGame), - address(outputs.permissionedDisputeGame), - address(outputs.delayedWETHPermissionedGameProxy), - address(outputs.delayedWETHPermissionlessGameProxy) + address(_optimismPortalProxy), + address(_disputeGameFactoryProxy), + address(_disputeGameFactoryImpl), + address(_anchorStateRegistryProxy), + address(_anchorStateRegistryImpl), + address(_faultDisputeGame), + address(_permissionedDisputeGame), + address(_delayedWETHPermissionedGameProxy), + address(_delayedWETHPermissionlessGameProxy) ); DeployUtils.assertValidContractAddresses(Solarray.extend(addrs1, addrs2)); } function opChainProxyAdmin() public view returns (ProxyAdmin) { - DeployUtils.assertValidContractAddress(address(outputs.opChainProxyAdmin)); - return outputs.opChainProxyAdmin; + DeployUtils.assertValidContractAddress(address(_opChainProxyAdmin)); + return _opChainProxyAdmin; } function addressManager() public view returns (AddressManager) { - DeployUtils.assertValidContractAddress(address(outputs.addressManager)); - return outputs.addressManager; + DeployUtils.assertValidContractAddress(address(_addressManager)); + return _addressManager; } function l1ERC721BridgeProxy() public view returns (L1ERC721Bridge) { - DeployUtils.assertValidContractAddress(address(outputs.l1ERC721BridgeProxy)); - return outputs.l1ERC721BridgeProxy; + DeployUtils.assertValidContractAddress(address(_l1ERC721BridgeProxy)); + return _l1ERC721BridgeProxy; } function systemConfigProxy() public view returns (SystemConfig) { - DeployUtils.assertValidContractAddress(address(outputs.systemConfigProxy)); - return outputs.systemConfigProxy; + DeployUtils.assertValidContractAddress(address(_systemConfigProxy)); + return _systemConfigProxy; } function optimismMintableERC20FactoryProxy() public view returns (OptimismMintableERC20Factory) { - DeployUtils.assertValidContractAddress(address(outputs.optimismMintableERC20FactoryProxy)); - return outputs.optimismMintableERC20FactoryProxy; + DeployUtils.assertValidContractAddress(address(_optimismMintableERC20FactoryProxy)); + return _optimismMintableERC20FactoryProxy; } function l1StandardBridgeProxy() public view returns (L1StandardBridge) { - DeployUtils.assertValidContractAddress(address(outputs.l1StandardBridgeProxy)); - return outputs.l1StandardBridgeProxy; + DeployUtils.assertValidContractAddress(address(_l1StandardBridgeProxy)); + return _l1StandardBridgeProxy; } function l1CrossDomainMessengerProxy() public view returns (L1CrossDomainMessenger) { - DeployUtils.assertValidContractAddress(address(outputs.l1CrossDomainMessengerProxy)); - return outputs.l1CrossDomainMessengerProxy; + DeployUtils.assertValidContractAddress(address(_l1CrossDomainMessengerProxy)); + return _l1CrossDomainMessengerProxy; } function optimismPortalProxy() public view returns (OptimismPortal2) { - DeployUtils.assertValidContractAddress(address(outputs.optimismPortalProxy)); - return outputs.optimismPortalProxy; + DeployUtils.assertValidContractAddress(address(_optimismPortalProxy)); + return _optimismPortalProxy; } function disputeGameFactoryProxy() public view returns (DisputeGameFactory) { - DeployUtils.assertValidContractAddress(address(outputs.disputeGameFactoryProxy)); - return outputs.disputeGameFactoryProxy; + DeployUtils.assertValidContractAddress(address(_disputeGameFactoryProxy)); + return _disputeGameFactoryProxy; } function disputeGameFactoryImpl() public view returns (DisputeGameFactory) { - DeployUtils.assertValidContractAddress(address(outputs.disputeGameFactoryImpl)); - return outputs.disputeGameFactoryImpl; + DeployUtils.assertValidContractAddress(address(_disputeGameFactoryImpl)); + return _disputeGameFactoryImpl; } function anchorStateRegistryProxy() public view returns (AnchorStateRegistry) { - DeployUtils.assertValidContractAddress(address(outputs.anchorStateRegistryProxy)); - return outputs.anchorStateRegistryProxy; + DeployUtils.assertValidContractAddress(address(_anchorStateRegistryProxy)); + return _anchorStateRegistryProxy; } function anchorStateRegistryImpl() public view returns (AnchorStateRegistry) { - DeployUtils.assertValidContractAddress(address(outputs.anchorStateRegistryImpl)); - return outputs.anchorStateRegistryImpl; + DeployUtils.assertValidContractAddress(address(_anchorStateRegistryImpl)); + return _anchorStateRegistryImpl; } function faultDisputeGame() public view returns (FaultDisputeGame) { - DeployUtils.assertValidContractAddress(address(outputs.faultDisputeGame)); - return outputs.faultDisputeGame; + DeployUtils.assertValidContractAddress(address(_faultDisputeGame)); + return _faultDisputeGame; } function permissionedDisputeGame() public view returns (PermissionedDisputeGame) { - DeployUtils.assertValidContractAddress(address(outputs.permissionedDisputeGame)); - return outputs.permissionedDisputeGame; + DeployUtils.assertValidContractAddress(address(_permissionedDisputeGame)); + return _permissionedDisputeGame; } function delayedWETHPermissionedGameProxy() public view returns (DelayedWETH) { - DeployUtils.assertValidContractAddress(address(outputs.delayedWETHPermissionedGameProxy)); - return outputs.delayedWETHPermissionedGameProxy; + DeployUtils.assertValidContractAddress(address(_delayedWETHPermissionedGameProxy)); + return _delayedWETHPermissionedGameProxy; } function delayedWETHPermissionlessGameProxy() public view returns (DelayedWETH) { - DeployUtils.assertValidContractAddress(address(outputs.delayedWETHPermissionlessGameProxy)); - return outputs.delayedWETHPermissionlessGameProxy; + DeployUtils.assertValidContractAddress(address(_delayedWETHPermissionlessGameProxy)); + return _delayedWETHPermissionlessGameProxy; } } @@ -300,16 +285,7 @@ contract DeployOPChain is Script { require(false, "DeployOPChain: run is not implemented"); } - function run(DeployOPChainInput.Input memory _input) public returns (DeployOPChainOutput.Output memory) { - (DeployOPChainInput doi, DeployOPChainOutput doo) = etchIOContracts(); - doi.loadInput(_input); - run(doi, doo); - return doo.output(); - } - function run(DeployOPChainInput _doi, DeployOPChainOutput _doo) public { - require(_doi.inputSet(), "DeployOPChain: input not set"); - OPStackManager opsm = _doi.opsm(); OPStackManager.Roles memory roles = OPStackManager.Roles({ @@ -373,7 +349,7 @@ contract DeployOPChain is Script { // -------- Utilities -------- - function etchIOContracts() internal returns (DeployOPChainInput doi_, DeployOPChainOutput doo_) { + function etchIOContracts() public returns (DeployOPChainInput doi_, DeployOPChainOutput doo_) { (doi_, doo_) = getIOContracts(); vm.etch(address(doi_), type(DeployOPChainInput).runtimeCode); vm.etch(address(doo_), type(DeployOPChainOutput).runtimeCode); diff --git a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol index e735d00f31d3..5db9788ad813 100644 --- a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol +++ b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol @@ -88,7 +88,7 @@ contract DeploySuperchainInput is CommonBase { // These `set` methods let each input be set individually. The selector of an input's getter method // is used to determine which field to set. function set(bytes4 _sel, address _address) public { - require(_address != address(0), "DeploySuperchainInput: cannot set null address"); + require(_address != address(0), "DeploySuperchainInput: cannot set zero address"); if (_sel == this.guardian.selector) _guardian = _address; else if (_sel == this.protocolVersionsOwner.selector) _protocolVersionsOwner = _address; else if (_sel == this.proxyAdminOwner.selector) _proxyAdminOwner = _address; @@ -181,6 +181,7 @@ contract DeploySuperchainOutput is CommonBase { // This method lets each field be set individually. The selector of an output's getter method // is used to determine which field to set. function set(bytes4 sel, address _address) public { + require(_address != address(0), "DeploySuperchainOutput: cannot set zero address"); if (sel == this.superchainProxyAdmin.selector) _superchainProxyAdmin = ProxyAdmin(_address); else if (sel == this.superchainConfigImpl.selector) _superchainConfigImpl = SuperchainConfig(_address); else if (sel == this.superchainConfigProxy.selector) _superchainConfigProxy = SuperchainConfig(_address); diff --git a/packages/contracts-bedrock/test/DeployImplementations.t.sol b/packages/contracts-bedrock/test/DeployImplementations.t.sol index 1acbed7b60e3..4b00813836ee 100644 --- a/packages/contracts-bedrock/test/DeployImplementations.t.sol +++ b/packages/contracts-bedrock/test/DeployImplementations.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Test } from "forge-std/Test.sol"; +import { Test, stdStorage, StdStorage } from "forge-std/Test.sol"; import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; @@ -28,54 +28,56 @@ import { contract DeployImplementationsInput_Test is Test { DeployImplementationsInput dii; - DeployImplementationsInput.Input input = DeployImplementationsInput.Input({ - withdrawalDelaySeconds: 100, - minProposalSizeBytes: 200, - challengePeriodSeconds: 300, - proofMaturityDelaySeconds: 400, - disputeGameFinalityDelaySeconds: 500, - release: "op-contracts/latest", - superchainConfigProxy: SuperchainConfig(makeAddr("superchainConfigProxy")), - protocolVersionsProxy: ProtocolVersions(makeAddr("protocolVersionsProxy")) - }); + uint256 withdrawalDelaySeconds = 100; + uint256 minProposalSizeBytes = 200; + uint256 challengePeriodSeconds = 300; + uint256 proofMaturityDelaySeconds = 400; + uint256 disputeGameFinalityDelaySeconds = 500; + string release = "op-contracts/latest"; + SuperchainConfig superchainConfigProxy = SuperchainConfig(makeAddr("superchainConfigProxy")); + ProtocolVersions protocolVersionsProxy = ProtocolVersions(makeAddr("protocolVersionsProxy")); function setUp() public { dii = new DeployImplementationsInput(); } - function test_loadInput_succeeds() public { - dii.loadInput(input); - - assertTrue(dii.inputSet(), "100"); - - // Compare the test input struct to the getter methods. - assertEq(input.withdrawalDelaySeconds, dii.withdrawalDelaySeconds(), "200"); - assertEq(input.minProposalSizeBytes, dii.minProposalSizeBytes(), "300"); - assertEq(input.challengePeriodSeconds, dii.challengePeriodSeconds(), "400"); - assertEq(input.proofMaturityDelaySeconds, dii.proofMaturityDelaySeconds(), "500"); - assertEq(input.disputeGameFinalityDelaySeconds, dii.disputeGameFinalityDelaySeconds(), "600"); - - // Compare the test input struct to the `input` getter method. - assertEq(keccak256(abi.encode(input)), keccak256(abi.encode(dii.input())), "800"); + function test_loadInputFile_succeeds() public { + // See `test_loadInputFile_succeeds` in `DeploySuperchain.t.sol` for a reference implementation. + // This test is currently skipped because loadInputFile is not implemented. + vm.skip(true); + + // Compare the test inputs to the getter methods. + // assertEq(withdrawalDelaySeconds, dii.withdrawalDelaySeconds(), "100"); + // assertEq(minProposalSizeBytes, dii.minProposalSizeBytes(), "200"); + // assertEq(challengePeriodSeconds, dii.challengePeriodSeconds(), "300"); + // assertEq(proofMaturityDelaySeconds, dii.proofMaturityDelaySeconds(), "400"); + // assertEq(disputeGameFinalityDelaySeconds, dii.disputeGameFinalityDelaySeconds(), "500"); } function test_getters_whenNotSet_revert() public { - bytes memory expectedErr = "DeployImplementationsInput: input not set"; - - vm.expectRevert(expectedErr); + vm.expectRevert("DeployImplementationsInput: not set"); dii.withdrawalDelaySeconds(); - vm.expectRevert(expectedErr); + vm.expectRevert("DeployImplementationsInput: not set"); dii.minProposalSizeBytes(); - vm.expectRevert(expectedErr); + vm.expectRevert("DeployImplementationsInput: not set"); dii.challengePeriodSeconds(); - vm.expectRevert(expectedErr); + vm.expectRevert("DeployImplementationsInput: not set"); dii.proofMaturityDelaySeconds(); - vm.expectRevert(expectedErr); + vm.expectRevert("DeployImplementationsInput: not set"); dii.disputeGameFinalityDelaySeconds(); + + vm.expectRevert("DeployImplementationsInput: not set"); + dii.release(); + + vm.expectRevert("DeployImplementationsInput: not set"); + dii.superchainConfigProxy(); + + vm.expectRevert("DeployImplementationsInput: not set"); + dii.protocolVersionsProxy(); } } @@ -87,58 +89,54 @@ contract DeployImplementationsOutput_Test is Test { } function test_set_succeeds() public { - DeployImplementationsOutput.Output memory output = DeployImplementationsOutput.Output({ - opsm: OPStackManager(makeAddr("opsm")), - optimismPortalImpl: OptimismPortal2(payable(makeAddr("optimismPortalImpl"))), - delayedWETHImpl: DelayedWETH(payable(makeAddr("delayedWETHImpl"))), - preimageOracleSingleton: PreimageOracle(makeAddr("preimageOracleSingleton")), - mipsSingleton: MIPS(makeAddr("mipsSingleton")), - systemConfigImpl: SystemConfig(makeAddr("systemConfigImpl")), - l1CrossDomainMessengerImpl: L1CrossDomainMessenger(makeAddr("l1CrossDomainMessengerImpl")), - l1ERC721BridgeImpl: L1ERC721Bridge(makeAddr("l1ERC721BridgeImpl")), - l1StandardBridgeImpl: L1StandardBridge(payable(makeAddr("l1StandardBridgeImpl"))), - optimismMintableERC20FactoryImpl: OptimismMintableERC20Factory(makeAddr("optimismMintableERC20FactoryImpl")), - disputeGameFactoryImpl: DisputeGameFactory(makeAddr("disputeGameFactoryImpl")) - }); - - vm.etch(address(output.opsm), hex"01"); - vm.etch(address(output.optimismPortalImpl), hex"01"); - vm.etch(address(output.delayedWETHImpl), hex"01"); - vm.etch(address(output.preimageOracleSingleton), hex"01"); - vm.etch(address(output.mipsSingleton), hex"01"); - vm.etch(address(output.systemConfigImpl), hex"01"); - vm.etch(address(output.l1CrossDomainMessengerImpl), hex"01"); - vm.etch(address(output.l1ERC721BridgeImpl), hex"01"); - vm.etch(address(output.l1StandardBridgeImpl), hex"01"); - vm.etch(address(output.optimismMintableERC20FactoryImpl), hex"01"); - vm.etch(address(output.disputeGameFactoryImpl), hex"01"); - dio.set(dio.opsm.selector, address(output.opsm)); - dio.set(dio.optimismPortalImpl.selector, address(output.optimismPortalImpl)); - dio.set(dio.delayedWETHImpl.selector, address(output.delayedWETHImpl)); - dio.set(dio.preimageOracleSingleton.selector, address(output.preimageOracleSingleton)); - dio.set(dio.mipsSingleton.selector, address(output.mipsSingleton)); - dio.set(dio.systemConfigImpl.selector, address(output.systemConfigImpl)); - dio.set(dio.l1CrossDomainMessengerImpl.selector, address(output.l1CrossDomainMessengerImpl)); - dio.set(dio.l1ERC721BridgeImpl.selector, address(output.l1ERC721BridgeImpl)); - dio.set(dio.l1StandardBridgeImpl.selector, address(output.l1StandardBridgeImpl)); - dio.set(dio.optimismMintableERC20FactoryImpl.selector, address(output.optimismMintableERC20FactoryImpl)); - dio.set(dio.disputeGameFactoryImpl.selector, address(output.disputeGameFactoryImpl)); - - assertEq(address(output.opsm), address(dio.opsm()), "50"); - assertEq(address(output.optimismPortalImpl), address(dio.optimismPortalImpl()), "100"); - assertEq(address(output.delayedWETHImpl), address(dio.delayedWETHImpl()), "200"); - assertEq(address(output.preimageOracleSingleton), address(dio.preimageOracleSingleton()), "300"); - assertEq(address(output.mipsSingleton), address(dio.mipsSingleton()), "400"); - assertEq(address(output.systemConfigImpl), address(dio.systemConfigImpl()), "500"); - assertEq(address(output.l1CrossDomainMessengerImpl), address(dio.l1CrossDomainMessengerImpl()), "600"); - assertEq(address(output.l1ERC721BridgeImpl), address(dio.l1ERC721BridgeImpl()), "700"); - assertEq(address(output.l1StandardBridgeImpl), address(dio.l1StandardBridgeImpl()), "800"); - assertEq( - address(output.optimismMintableERC20FactoryImpl), address(dio.optimismMintableERC20FactoryImpl()), "900" - ); - assertEq(address(output.disputeGameFactoryImpl), address(dio.disputeGameFactoryImpl()), "950"); - - assertEq(keccak256(abi.encode(output)), keccak256(abi.encode(dio.output())), "1000"); + OPStackManager opsm = OPStackManager(makeAddr("opsm")); + OptimismPortal2 optimismPortalImpl = OptimismPortal2(payable(makeAddr("optimismPortalImpl"))); + DelayedWETH delayedWETHImpl = DelayedWETH(payable(makeAddr("delayedWETHImpl"))); + PreimageOracle preimageOracleSingleton = PreimageOracle(makeAddr("preimageOracleSingleton")); + MIPS mipsSingleton = MIPS(makeAddr("mipsSingleton")); + SystemConfig systemConfigImpl = SystemConfig(makeAddr("systemConfigImpl")); + L1CrossDomainMessenger l1CrossDomainMessengerImpl = + L1CrossDomainMessenger(makeAddr("l1CrossDomainMessengerImpl")); + L1ERC721Bridge l1ERC721BridgeImpl = L1ERC721Bridge(makeAddr("l1ERC721BridgeImpl")); + L1StandardBridge l1StandardBridgeImpl = L1StandardBridge(payable(makeAddr("l1StandardBridgeImpl"))); + OptimismMintableERC20Factory optimismMintableERC20FactoryImpl = + OptimismMintableERC20Factory(makeAddr("optimismMintableERC20FactoryImpl")); + DisputeGameFactory disputeGameFactoryImpl = DisputeGameFactory(makeAddr("disputeGameFactoryImpl")); + + vm.etch(address(opsm), hex"01"); + vm.etch(address(optimismPortalImpl), hex"01"); + vm.etch(address(delayedWETHImpl), hex"01"); + vm.etch(address(preimageOracleSingleton), hex"01"); + vm.etch(address(mipsSingleton), hex"01"); + vm.etch(address(systemConfigImpl), hex"01"); + vm.etch(address(l1CrossDomainMessengerImpl), hex"01"); + vm.etch(address(l1ERC721BridgeImpl), hex"01"); + vm.etch(address(l1StandardBridgeImpl), hex"01"); + vm.etch(address(optimismMintableERC20FactoryImpl), hex"01"); + vm.etch(address(disputeGameFactoryImpl), hex"01"); + dio.set(dio.opsm.selector, address(opsm)); + dio.set(dio.optimismPortalImpl.selector, address(optimismPortalImpl)); + dio.set(dio.delayedWETHImpl.selector, address(delayedWETHImpl)); + dio.set(dio.preimageOracleSingleton.selector, address(preimageOracleSingleton)); + dio.set(dio.mipsSingleton.selector, address(mipsSingleton)); + dio.set(dio.systemConfigImpl.selector, address(systemConfigImpl)); + dio.set(dio.l1CrossDomainMessengerImpl.selector, address(l1CrossDomainMessengerImpl)); + dio.set(dio.l1ERC721BridgeImpl.selector, address(l1ERC721BridgeImpl)); + dio.set(dio.l1StandardBridgeImpl.selector, address(l1StandardBridgeImpl)); + dio.set(dio.optimismMintableERC20FactoryImpl.selector, address(optimismMintableERC20FactoryImpl)); + dio.set(dio.disputeGameFactoryImpl.selector, address(disputeGameFactoryImpl)); + + assertEq(address(opsm), address(dio.opsm()), "50"); + assertEq(address(optimismPortalImpl), address(dio.optimismPortalImpl()), "100"); + assertEq(address(delayedWETHImpl), address(dio.delayedWETHImpl()), "200"); + assertEq(address(preimageOracleSingleton), address(dio.preimageOracleSingleton()), "300"); + assertEq(address(mipsSingleton), address(dio.mipsSingleton()), "400"); + assertEq(address(systemConfigImpl), address(dio.systemConfigImpl()), "500"); + assertEq(address(l1CrossDomainMessengerImpl), address(dio.l1CrossDomainMessengerImpl()), "600"); + assertEq(address(l1ERC721BridgeImpl), address(dio.l1ERC721BridgeImpl()), "700"); + assertEq(address(l1StandardBridgeImpl), address(dio.l1StandardBridgeImpl()), "800"); + assertEq(address(optimismMintableERC20FactoryImpl), address(dio.optimismMintableERC20FactoryImpl()), "900"); + assertEq(address(disputeGameFactoryImpl), address(dio.disputeGameFactoryImpl()), "950"); } function test_getters_whenNotSet_revert() public { @@ -218,25 +216,25 @@ contract DeployImplementationsOutput_Test is Test { } contract DeployImplementations_Test is Test { + using stdStorage for StdStorage; + DeployImplementations deployImplementations; DeployImplementationsInput dii; DeployImplementationsOutput dio; - // Define a default input struct for testing. - DeployImplementationsInput.Input input = DeployImplementationsInput.Input({ - withdrawalDelaySeconds: 100, - minProposalSizeBytes: 200, - challengePeriodSeconds: 300, - proofMaturityDelaySeconds: 400, - disputeGameFinalityDelaySeconds: 500, - release: "op-contracts/latest", - superchainConfigProxy: SuperchainConfig(makeAddr("superchainConfigProxy")), - protocolVersionsProxy: ProtocolVersions(makeAddr("protocolVersionsProxy")) - }); + // Define default inputs for testing. + uint256 withdrawalDelaySeconds = 100; + uint256 minProposalSizeBytes = 200; + uint256 challengePeriodSeconds = 300; + uint256 proofMaturityDelaySeconds = 400; + uint256 disputeGameFinalityDelaySeconds = 500; + string release = "op-contracts/latest"; + SuperchainConfig superchainConfigProxy = SuperchainConfig(makeAddr("superchainConfigProxy")); + ProtocolVersions protocolVersionsProxy = ProtocolVersions(makeAddr("protocolVersionsProxy")); function setUp() public virtual { deployImplementations = new DeployImplementations(); - (dii, dio) = deployImplementations.getIOContracts(); + (dii, dio) = deployImplementations.etchIOContracts(); } // By deploying the `DeployImplementations` contract with this virtual function, we provide a @@ -246,50 +244,43 @@ contract DeployImplementations_Test is Test { return new DeployImplementations(); } - function testFuzz_run_succeeds(DeployImplementationsInput.Input memory _input) public { - // This is a requirement in the PreimageOracle contract. - _input.challengePeriodSeconds = bound(_input.challengePeriodSeconds, 0, type(uint64).max); - - DeployImplementationsOutput.Output memory output = deployImplementations.run(_input); - - // Assert that individual input fields were properly set based on the input struct. - assertEq(_input.withdrawalDelaySeconds, dii.withdrawalDelaySeconds(), "100"); - assertEq(_input.minProposalSizeBytes, dii.minProposalSizeBytes(), "200"); - assertEq(_input.challengePeriodSeconds, dii.challengePeriodSeconds(), "300"); - assertEq(_input.proofMaturityDelaySeconds, dii.proofMaturityDelaySeconds(), "400"); - assertEq(_input.disputeGameFinalityDelaySeconds, dii.disputeGameFinalityDelaySeconds(), "500"); - - // Assert that individual output fields were properly set based on the output struct. - assertEq(address(output.optimismPortalImpl), address(dio.optimismPortalImpl()), "600"); - assertEq(address(output.delayedWETHImpl), address(dio.delayedWETHImpl()), "700"); - assertEq(address(output.preimageOracleSingleton), address(dio.preimageOracleSingleton()), "800"); - assertEq(address(output.mipsSingleton), address(dio.mipsSingleton()), "900"); - assertEq(address(output.systemConfigImpl), address(dio.systemConfigImpl()), "1000"); - assertEq(address(output.l1CrossDomainMessengerImpl), address(dio.l1CrossDomainMessengerImpl()), "1100"); - assertEq(address(output.l1ERC721BridgeImpl), address(dio.l1ERC721BridgeImpl()), "1200"); - assertEq(address(output.l1StandardBridgeImpl), address(dio.l1StandardBridgeImpl()), "1300"); - assertEq( - address(output.optimismMintableERC20FactoryImpl), address(dio.optimismMintableERC20FactoryImpl()), "1400" - ); - assertEq(address(output.disputeGameFactoryImpl), address(dio.disputeGameFactoryImpl()), "1450"); - - // Assert that the full input and output structs were properly set. - assertEq(keccak256(abi.encode(_input)), keccak256(abi.encode(DeployImplementationsInput(dii).input())), "1500"); - assertEq( - keccak256(abi.encode(output)), keccak256(abi.encode(DeployImplementationsOutput(dio).output())), "1600" - ); - - // Assert inputs were properly passed through to the contract initializers. - assertEq(output.delayedWETHImpl.delay(), _input.withdrawalDelaySeconds, "1700"); - assertEq(output.preimageOracleSingleton.challengePeriod(), _input.challengePeriodSeconds, "1800"); - assertEq(output.preimageOracleSingleton.minProposalSize(), _input.minProposalSizeBytes, "1900"); - assertEq(output.optimismPortalImpl.proofMaturityDelaySeconds(), _input.proofMaturityDelaySeconds, "2000"); - assertEq( - output.optimismPortalImpl.disputeGameFinalityDelaySeconds(), _input.disputeGameFinalityDelaySeconds, "2100" - ); + function hash(bytes32 _seed, uint256 _i) internal pure returns (bytes32) { + return keccak256(abi.encode(_seed, _i)); + } + + function testFuzz_run_memory_succeeds(bytes32 _seed) public { + withdrawalDelaySeconds = uint256(hash(_seed, 0)); + minProposalSizeBytes = uint256(hash(_seed, 1)); + challengePeriodSeconds = bound(uint256(hash(_seed, 2)), 0, type(uint64).max); + proofMaturityDelaySeconds = uint256(hash(_seed, 3)); + disputeGameFinalityDelaySeconds = uint256(hash(_seed, 4)); + release = string(bytes.concat(hash(_seed, 5))); + superchainConfigProxy = SuperchainConfig(address(uint160(uint256(hash(_seed, 6))))); + protocolVersionsProxy = ProtocolVersions(address(uint160(uint256(hash(_seed, 7))))); + + dii.set(dii.withdrawalDelaySeconds.selector, withdrawalDelaySeconds); + dii.set(dii.minProposalSizeBytes.selector, minProposalSizeBytes); + dii.set(dii.challengePeriodSeconds.selector, challengePeriodSeconds); + dii.set(dii.proofMaturityDelaySeconds.selector, proofMaturityDelaySeconds); + dii.set(dii.disputeGameFinalityDelaySeconds.selector, disputeGameFinalityDelaySeconds); + dii.set(dii.release.selector, release); + dii.set(dii.superchainConfigProxy.selector, address(superchainConfigProxy)); + dii.set(dii.protocolVersionsProxy.selector, address(protocolVersionsProxy)); + + deployImplementations.run(dii, dio); + + // Assert that individual input fields were properly set based on the inputs. + assertEq(withdrawalDelaySeconds, dii.withdrawalDelaySeconds(), "100"); + assertEq(minProposalSizeBytes, dii.minProposalSizeBytes(), "200"); + assertEq(challengePeriodSeconds, dii.challengePeriodSeconds(), "300"); + assertEq(proofMaturityDelaySeconds, dii.proofMaturityDelaySeconds(), "400"); + assertEq(disputeGameFinalityDelaySeconds, dii.disputeGameFinalityDelaySeconds(), "500"); + assertEq(release, dii.release(), "525"); + assertEq(address(superchainConfigProxy), address(dii.superchainConfigProxy()), "550"); + assertEq(address(protocolVersionsProxy), address(dii.protocolVersionsProxy()), "575"); // Architecture assertions. - assertEq(address(output.mipsSingleton.oracle()), address(output.preimageOracleSingleton), "2200"); + assertEq(address(dio.mipsSingleton().oracle()), address(dio.preimageOracleSingleton()), "600"); // Ensure that `checkOutput` passes. This is called by the `run` function during execution, // so this just acts as a sanity check. It reverts on failure. @@ -297,9 +288,25 @@ contract DeployImplementations_Test is Test { } function testFuzz_run_largeChallengePeriodSeconds_reverts(uint256 _challengePeriodSeconds) public { - input.challengePeriodSeconds = bound(_challengePeriodSeconds, uint256(type(uint64).max) + 1, type(uint256).max); - vm.expectRevert("DeployImplementationsInput: challenge period too large"); - deployImplementations.run(input); + // Set the defaults. + dii.set(dii.withdrawalDelaySeconds.selector, withdrawalDelaySeconds); + dii.set(dii.minProposalSizeBytes.selector, minProposalSizeBytes); + dii.set(dii.challengePeriodSeconds.selector, challengePeriodSeconds); + dii.set(dii.proofMaturityDelaySeconds.selector, proofMaturityDelaySeconds); + dii.set(dii.disputeGameFinalityDelaySeconds.selector, disputeGameFinalityDelaySeconds); + dii.set(dii.release.selector, release); + dii.set(dii.superchainConfigProxy.selector, address(superchainConfigProxy)); + dii.set(dii.protocolVersionsProxy.selector, address(protocolVersionsProxy)); + + // Set the challenge period to a value that is too large, using vm.store because the setter + // method won't allow it. + challengePeriodSeconds = bound(_challengePeriodSeconds, uint256(type(uint64).max) + 1, type(uint256).max); + uint256 slot = + stdstore.enable_packed_slots().target(address(dii)).sig(dii.challengePeriodSeconds.selector).find(); + vm.store(address(dii), bytes32(slot), bytes32(challengePeriodSeconds)); + + vm.expectRevert("DeployImplementationsInput: challengePeriodSeconds too large"); + deployImplementations.run(dii, dio); } } diff --git a/packages/contracts-bedrock/test/DeployOPChain.t.sol b/packages/contracts-bedrock/test/DeployOPChain.t.sol index b2861c2af328..4f58b5d53299 100644 --- a/packages/contracts-bedrock/test/DeployOPChain.t.sol +++ b/packages/contracts-bedrock/test/DeployOPChain.t.sol @@ -34,48 +34,48 @@ import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC2 contract DeployOPChainInput_Test is Test { DeployOPChainInput doi; - DeployOPChainInput.Input input = DeployOPChainInput.Input({ - roles: DeployOPChainInput.Roles({ - opChainProxyAdminOwner: makeAddr("opChainProxyAdminOwner"), - systemConfigOwner: makeAddr("systemConfigOwner"), - batcher: makeAddr("batcher"), - unsafeBlockSigner: makeAddr("unsafeBlockSigner"), - proposer: makeAddr("proposer"), - challenger: makeAddr("challenger") - }), - basefeeScalar: 100, - blobBaseFeeScalar: 200, - l2ChainId: 300, - opsm: OPStackManager(makeAddr("opsm")) - }); + // Define defaults. + address opChainProxyAdminOwner = makeAddr("opChainProxyAdminOwner"); + address systemConfigOwner = makeAddr("systemConfigOwner"); + address batcher = makeAddr("batcher"); + address unsafeBlockSigner = makeAddr("unsafeBlockSigner"); + address proposer = makeAddr("proposer"); + address challenger = makeAddr("challenger"); + uint32 basefeeScalar = 100; + uint32 blobBaseFeeScalar = 200; + uint256 l2ChainId = 300; + OPStackManager opsm = OPStackManager(makeAddr("opsm")); function setUp() public { doi = new DeployOPChainInput(); } - function test_loadInput_succeeds() public { - doi.loadInput(input); - - assertTrue(doi.inputSet(), "100"); - - // Compare the test input struct to the getter methods. - assertEq(input.roles.opChainProxyAdminOwner, doi.opChainProxyAdminOwner(), "200"); - assertEq(input.roles.systemConfigOwner, doi.systemConfigOwner(), "300"); - assertEq(input.roles.batcher, doi.batcher(), "400"); - assertEq(input.roles.unsafeBlockSigner, doi.unsafeBlockSigner(), "500"); - assertEq(input.roles.proposer, doi.proposer(), "600"); - assertEq(input.roles.challenger, doi.challenger(), "700"); - assertEq(input.basefeeScalar, doi.basefeeScalar(), "800"); - assertEq(input.blobBaseFeeScalar, doi.blobBaseFeeScalar(), "900"); - assertEq(input.l2ChainId, doi.l2ChainId(), "1000"); - assertEq(address(input.opsm), address(doi.opsm()), "1100"); - - // Compare the test input struct to the `input` getter method. - assertEq(keccak256(abi.encode(input)), keccak256(abi.encode(doi.input())), "1200"); + function test_set_succeeds() public { + doi.set(doi.opChainProxyAdminOwner.selector, opChainProxyAdminOwner); + doi.set(doi.systemConfigOwner.selector, systemConfigOwner); + doi.set(doi.batcher.selector, batcher); + doi.set(doi.unsafeBlockSigner.selector, unsafeBlockSigner); + doi.set(doi.proposer.selector, proposer); + doi.set(doi.challenger.selector, challenger); + doi.set(doi.basefeeScalar.selector, basefeeScalar); + doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar); + doi.set(doi.l2ChainId.selector, l2ChainId); + doi.set(doi.opsm.selector, address(opsm)); + // Compare the default inputs to the getter methods. + assertEq(opChainProxyAdminOwner, doi.opChainProxyAdminOwner(), "200"); + assertEq(systemConfigOwner, doi.systemConfigOwner(), "300"); + assertEq(batcher, doi.batcher(), "400"); + assertEq(unsafeBlockSigner, doi.unsafeBlockSigner(), "500"); + assertEq(proposer, doi.proposer(), "600"); + assertEq(challenger, doi.challenger(), "700"); + assertEq(basefeeScalar, doi.basefeeScalar(), "800"); + assertEq(blobBaseFeeScalar, doi.blobBaseFeeScalar(), "900"); + assertEq(l2ChainId, doi.l2ChainId(), "1000"); + assertEq(address(opsm), address(doi.opsm()), "1100"); } function test_getters_whenNotSet_revert() public { - bytes memory expectedErr = "DeployOPChainInput: input not set"; + bytes memory expectedErr = "DeployOPChainInput: not set"; vm.expectRevert(expectedErr); doi.opChainProxyAdminOwner(); @@ -109,90 +109,82 @@ contract DeployOPChainInput_Test is Test { contract DeployOPChainOutput_Test is Test { DeployOPChainOutput doo; + // Define default outputs to set. + // We set these in storage because doing it locally in test_set_succeeds results in stack too deep. + ProxyAdmin opChainProxyAdmin = ProxyAdmin(makeAddr("optimismPortal2Impl")); + AddressManager addressManager = AddressManager(makeAddr("delayedWETHImpl")); + L1ERC721Bridge l1ERC721BridgeProxy = L1ERC721Bridge(makeAddr("l1ERC721BridgeProxy")); + SystemConfig systemConfigProxy = SystemConfig(makeAddr("systemConfigProxy")); + OptimismMintableERC20Factory optimismMintableERC20FactoryProxy = + OptimismMintableERC20Factory(makeAddr("optimismMintableERC20FactoryProxy")); + L1StandardBridge l1StandardBridgeProxy = L1StandardBridge(payable(makeAddr("l1StandardBridgeProxy"))); + L1CrossDomainMessenger l1CrossDomainMessengerProxy = L1CrossDomainMessenger(makeAddr("l1CrossDomainMessengerProxy")); + OptimismPortal2 optimismPortalProxy = OptimismPortal2(payable(makeAddr("optimismPortalProxy"))); + DisputeGameFactory disputeGameFactoryProxy = DisputeGameFactory(makeAddr("disputeGameFactoryProxy")); + DisputeGameFactory disputeGameFactoryImpl = DisputeGameFactory(makeAddr("disputeGameFactoryImpl")); + AnchorStateRegistry anchorStateRegistryProxy = AnchorStateRegistry(makeAddr("anchorStateRegistryProxy")); + AnchorStateRegistry anchorStateRegistryImpl = AnchorStateRegistry(makeAddr("anchorStateRegistryImpl")); + FaultDisputeGame faultDisputeGame = FaultDisputeGame(makeAddr("faultDisputeGame")); + PermissionedDisputeGame permissionedDisputeGame = PermissionedDisputeGame(makeAddr("permissionedDisputeGame")); + DelayedWETH delayedWETHPermissionedGameProxy = DelayedWETH(payable(makeAddr("delayedWETHPermissionedGameProxy"))); + DelayedWETH delayedWETHPermissionlessGameProxy = + DelayedWETH(payable(makeAddr("delayedWETHPermissionlessGameProxy"))); + function setUp() public { doo = new DeployOPChainOutput(); } function test_set_succeeds() public { - DeployOPChainOutput.Output memory output = DeployOPChainOutput.Output({ - opChainProxyAdmin: ProxyAdmin(makeAddr("optimismPortal2Impl")), - addressManager: AddressManager(makeAddr("delayedWETHImpl")), - l1ERC721BridgeProxy: L1ERC721Bridge(makeAddr("l1ERC721BridgeProxy")), - systemConfigProxy: SystemConfig(makeAddr("systemConfigProxy")), - optimismMintableERC20FactoryProxy: OptimismMintableERC20Factory(makeAddr("optimismMintableERC20FactoryProxy")), - l1StandardBridgeProxy: L1StandardBridge(payable(makeAddr("l1StandardBridgeProxy"))), - l1CrossDomainMessengerProxy: L1CrossDomainMessenger(makeAddr("l1CrossDomainMessengerProxy")), - optimismPortalProxy: OptimismPortal2(payable(makeAddr("optimismPortalProxy"))), - disputeGameFactoryProxy: DisputeGameFactory(makeAddr("disputeGameFactoryProxy")), - disputeGameFactoryImpl: DisputeGameFactory(makeAddr("disputeGameFactoryImpl")), - anchorStateRegistryProxy: AnchorStateRegistry(makeAddr("anchorStateRegistryProxy")), - anchorStateRegistryImpl: AnchorStateRegistry(makeAddr("anchorStateRegistryImpl")), - faultDisputeGame: FaultDisputeGame(makeAddr("faultDisputeGame")), - permissionedDisputeGame: PermissionedDisputeGame(makeAddr("permissionedDisputeGame")), - delayedWETHPermissionedGameProxy: DelayedWETH(payable(makeAddr("delayedWETHPermissionedGameProxy"))), - delayedWETHPermissionlessGameProxy: DelayedWETH(payable(makeAddr("delayedWETHPermissionlessGameProxy"))) - }); - - vm.etch(address(output.opChainProxyAdmin), hex"01"); - vm.etch(address(output.addressManager), hex"01"); - vm.etch(address(output.l1ERC721BridgeProxy), hex"01"); - vm.etch(address(output.systemConfigProxy), hex"01"); - vm.etch(address(output.optimismMintableERC20FactoryProxy), hex"01"); - vm.etch(address(output.l1StandardBridgeProxy), hex"01"); - vm.etch(address(output.l1CrossDomainMessengerProxy), hex"01"); - vm.etch(address(output.optimismPortalProxy), hex"01"); - vm.etch(address(output.disputeGameFactoryProxy), hex"01"); - vm.etch(address(output.disputeGameFactoryImpl), hex"01"); - vm.etch(address(output.anchorStateRegistryProxy), hex"01"); - vm.etch(address(output.anchorStateRegistryImpl), hex"01"); - vm.etch(address(output.faultDisputeGame), hex"01"); - vm.etch(address(output.permissionedDisputeGame), hex"01"); - vm.etch(address(output.delayedWETHPermissionedGameProxy), hex"01"); - vm.etch(address(output.delayedWETHPermissionlessGameProxy), hex"01"); - - doo.set(doo.opChainProxyAdmin.selector, address(output.opChainProxyAdmin)); - doo.set(doo.addressManager.selector, address(output.addressManager)); - doo.set(doo.l1ERC721BridgeProxy.selector, address(output.l1ERC721BridgeProxy)); - doo.set(doo.systemConfigProxy.selector, address(output.systemConfigProxy)); - doo.set(doo.optimismMintableERC20FactoryProxy.selector, address(output.optimismMintableERC20FactoryProxy)); - doo.set(doo.l1StandardBridgeProxy.selector, address(output.l1StandardBridgeProxy)); - doo.set(doo.l1CrossDomainMessengerProxy.selector, address(output.l1CrossDomainMessengerProxy)); - doo.set(doo.optimismPortalProxy.selector, address(output.optimismPortalProxy)); - doo.set(doo.disputeGameFactoryProxy.selector, address(output.disputeGameFactoryProxy)); - doo.set(doo.disputeGameFactoryImpl.selector, address(output.disputeGameFactoryImpl)); - doo.set(doo.anchorStateRegistryProxy.selector, address(output.anchorStateRegistryProxy)); - doo.set(doo.anchorStateRegistryImpl.selector, address(output.anchorStateRegistryImpl)); - doo.set(doo.faultDisputeGame.selector, address(output.faultDisputeGame)); - doo.set(doo.permissionedDisputeGame.selector, address(output.permissionedDisputeGame)); - doo.set(doo.delayedWETHPermissionedGameProxy.selector, address(output.delayedWETHPermissionedGameProxy)); - doo.set(doo.delayedWETHPermissionlessGameProxy.selector, address(output.delayedWETHPermissionlessGameProxy)); - - assertEq(address(output.opChainProxyAdmin), address(doo.opChainProxyAdmin()), "100"); - assertEq(address(output.addressManager), address(doo.addressManager()), "200"); - assertEq(address(output.l1ERC721BridgeProxy), address(doo.l1ERC721BridgeProxy()), "300"); - assertEq(address(output.systemConfigProxy), address(doo.systemConfigProxy()), "400"); - assertEq( - address(output.optimismMintableERC20FactoryProxy), address(doo.optimismMintableERC20FactoryProxy()), "500" - ); - assertEq(address(output.l1StandardBridgeProxy), address(doo.l1StandardBridgeProxy()), "600"); - assertEq(address(output.l1CrossDomainMessengerProxy), address(doo.l1CrossDomainMessengerProxy()), "700"); - assertEq(address(output.optimismPortalProxy), address(doo.optimismPortalProxy()), "800"); - assertEq(address(output.disputeGameFactoryProxy), address(doo.disputeGameFactoryProxy()), "900"); - assertEq(address(output.disputeGameFactoryImpl), address(doo.disputeGameFactoryImpl()), "1000"); - assertEq(address(output.anchorStateRegistryProxy), address(doo.anchorStateRegistryProxy()), "1100"); - assertEq(address(output.anchorStateRegistryImpl), address(doo.anchorStateRegistryImpl()), "1200"); - assertEq(address(output.faultDisputeGame), address(doo.faultDisputeGame()), "1300"); - assertEq(address(output.permissionedDisputeGame), address(doo.permissionedDisputeGame()), "1400"); - assertEq( - address(output.delayedWETHPermissionedGameProxy), address(doo.delayedWETHPermissionedGameProxy()), "1500" - ); - assertEq( - address(output.delayedWETHPermissionlessGameProxy), - address(doo.delayedWETHPermissionlessGameProxy()), - "1600" - ); - - assertEq(keccak256(abi.encode(output)), keccak256(abi.encode(doo.output())), "1700"); + vm.etch(address(opChainProxyAdmin), hex"01"); + vm.etch(address(addressManager), hex"01"); + vm.etch(address(l1ERC721BridgeProxy), hex"01"); + vm.etch(address(systemConfigProxy), hex"01"); + vm.etch(address(optimismMintableERC20FactoryProxy), hex"01"); + vm.etch(address(l1StandardBridgeProxy), hex"01"); + vm.etch(address(l1CrossDomainMessengerProxy), hex"01"); + vm.etch(address(optimismPortalProxy), hex"01"); + vm.etch(address(disputeGameFactoryProxy), hex"01"); + vm.etch(address(disputeGameFactoryImpl), hex"01"); + vm.etch(address(anchorStateRegistryProxy), hex"01"); + vm.etch(address(anchorStateRegistryImpl), hex"01"); + vm.etch(address(faultDisputeGame), hex"01"); + vm.etch(address(permissionedDisputeGame), hex"01"); + vm.etch(address(delayedWETHPermissionedGameProxy), hex"01"); + vm.etch(address(delayedWETHPermissionlessGameProxy), hex"01"); + + doo.set(doo.opChainProxyAdmin.selector, address(opChainProxyAdmin)); + doo.set(doo.addressManager.selector, address(addressManager)); + doo.set(doo.l1ERC721BridgeProxy.selector, address(l1ERC721BridgeProxy)); + doo.set(doo.systemConfigProxy.selector, address(systemConfigProxy)); + doo.set(doo.optimismMintableERC20FactoryProxy.selector, address(optimismMintableERC20FactoryProxy)); + doo.set(doo.l1StandardBridgeProxy.selector, address(l1StandardBridgeProxy)); + doo.set(doo.l1CrossDomainMessengerProxy.selector, address(l1CrossDomainMessengerProxy)); + doo.set(doo.optimismPortalProxy.selector, address(optimismPortalProxy)); + doo.set(doo.disputeGameFactoryProxy.selector, address(disputeGameFactoryProxy)); + doo.set(doo.disputeGameFactoryImpl.selector, address(disputeGameFactoryImpl)); + doo.set(doo.anchorStateRegistryProxy.selector, address(anchorStateRegistryProxy)); + doo.set(doo.anchorStateRegistryImpl.selector, address(anchorStateRegistryImpl)); + doo.set(doo.faultDisputeGame.selector, address(faultDisputeGame)); + doo.set(doo.permissionedDisputeGame.selector, address(permissionedDisputeGame)); + doo.set(doo.delayedWETHPermissionedGameProxy.selector, address(delayedWETHPermissionedGameProxy)); + doo.set(doo.delayedWETHPermissionlessGameProxy.selector, address(delayedWETHPermissionlessGameProxy)); + + assertEq(address(opChainProxyAdmin), address(doo.opChainProxyAdmin()), "100"); + assertEq(address(addressManager), address(doo.addressManager()), "200"); + assertEq(address(l1ERC721BridgeProxy), address(doo.l1ERC721BridgeProxy()), "300"); + assertEq(address(systemConfigProxy), address(doo.systemConfigProxy()), "400"); + assertEq(address(optimismMintableERC20FactoryProxy), address(doo.optimismMintableERC20FactoryProxy()), "500"); + assertEq(address(l1StandardBridgeProxy), address(doo.l1StandardBridgeProxy()), "600"); + assertEq(address(l1CrossDomainMessengerProxy), address(doo.l1CrossDomainMessengerProxy()), "700"); + assertEq(address(optimismPortalProxy), address(doo.optimismPortalProxy()), "800"); + assertEq(address(disputeGameFactoryProxy), address(doo.disputeGameFactoryProxy()), "900"); + assertEq(address(disputeGameFactoryImpl), address(doo.disputeGameFactoryImpl()), "1000"); + assertEq(address(anchorStateRegistryProxy), address(doo.anchorStateRegistryProxy()), "1100"); + assertEq(address(anchorStateRegistryImpl), address(doo.anchorStateRegistryImpl()), "1200"); + assertEq(address(faultDisputeGame), address(doo.faultDisputeGame()), "1300"); + assertEq(address(permissionedDisputeGame), address(doo.permissionedDisputeGame()), "1400"); + assertEq(address(delayedWETHPermissionedGameProxy), address(doo.delayedWETHPermissionedGameProxy()), "1500"); + assertEq(address(delayedWETHPermissionlessGameProxy), address(doo.delayedWETHPermissionlessGameProxy()), "1600"); } function test_getters_whenNotSet_revert() public { @@ -324,8 +316,7 @@ contract DeployOPChain_TestBase is Test { DeployOPChainInput doi; DeployOPChainOutput doo; - // We define a default initial input set for DeploySuperchain. The other inputs are dependent - // on the outputs of the previous scripts, so we initialize them in the `setUp` method. + // Define default inputs for DeploySuperchain. address proxyAdminOwner = makeAddr("defaultProxyAdminOwner"); address protocolVersionsOwner = makeAddr("defaultProtocolVersionsOwner"); address guardian = makeAddr("defaultGuardian"); @@ -333,38 +324,32 @@ contract DeployOPChain_TestBase is Test { ProtocolVersion requiredProtocolVersion = ProtocolVersion.wrap(1); ProtocolVersion recommendedProtocolVersion = ProtocolVersion.wrap(2); - DeployImplementationsInput.Input deployImplementationsInput = DeployImplementationsInput.Input({ - withdrawalDelaySeconds: 100, - minProposalSizeBytes: 200, - challengePeriodSeconds: 300, - proofMaturityDelaySeconds: 400, - disputeGameFinalityDelaySeconds: 500, - release: "op-contracts/latest", - // These are set during `setUp` since they are outputs of the previous step. - superchainConfigProxy: SuperchainConfig(address(0)), - protocolVersionsProxy: ProtocolVersions(address(0)) - }); - - DeployOPChainInput.Input deployOPChainInput = DeployOPChainInput.Input({ - roles: DeployOPChainInput.Roles({ - opChainProxyAdminOwner: makeAddr("defaultOPChainProxyAdminOwner"), - systemConfigOwner: makeAddr("defaultSystemConfigOwner"), - batcher: makeAddr("defaultBatcher"), - unsafeBlockSigner: makeAddr("defaultUnsafeBlockSigner"), - proposer: makeAddr("defaultProposer"), - challenger: makeAddr("defaultChallenger") - }), - basefeeScalar: 100, - blobBaseFeeScalar: 200, - l2ChainId: 300, - // This is set during `setUp` since it is an output of the previous step. - opsm: OPStackManager(address(0)) - }); - - // Set during `setUp`. - DeployImplementationsOutput.Output deployImplementationsOutput; - - function setUp() public { + // Define default inputs for DeployImplementations. + // `superchainConfigProxy` and `protocolVersionsProxy` are set during `setUp` since they are + // outputs of the previous step. + uint256 withdrawalDelaySeconds = 100; + uint256 minProposalSizeBytes = 200; + uint256 challengePeriodSeconds = 300; + uint256 proofMaturityDelaySeconds = 400; + uint256 disputeGameFinalityDelaySeconds = 500; + string release = "op-contracts/latest"; + SuperchainConfig superchainConfigProxy; + ProtocolVersions protocolVersionsProxy; + + // Define default inputs for DeployOPChain. + // `opsm` is set during `setUp` since it is an output of the previous step. + address opChainProxyAdminOwner = makeAddr("defaultOPChainProxyAdminOwner"); + address systemConfigOwner = makeAddr("defaultSystemConfigOwner"); + address batcher = makeAddr("defaultBatcher"); + address unsafeBlockSigner = makeAddr("defaultUnsafeBlockSigner"); + address proposer = makeAddr("defaultProposer"); + address challenger = makeAddr("defaultChallenger"); + uint32 basefeeScalar = 100; + uint32 blobBaseFeeScalar = 200; + uint256 l2ChainId = 300; + OPStackManager opsm = OPStackManager(address(0)); + + function setUp() public virtual { // Initialize deploy scripts. DeploySuperchain deploySuperchain = new DeploySuperchain(); (DeploySuperchainInput dsi, DeploySuperchainOutput dso) = deploySuperchain.etchIOContracts(); @@ -376,21 +361,31 @@ contract DeployOPChain_TestBase is Test { dsi.set(dsi.recommendedProtocolVersion.selector, recommendedProtocolVersion); DeployImplementations deployImplementations = new DeployImplementations(); + (DeployImplementationsInput dii, DeployImplementationsOutput dio) = deployImplementations.etchIOContracts(); + deployOPChain = new DeployOPChain(); - (doi, doo) = deployOPChain.getIOContracts(); + (doi, doo) = deployOPChain.etchIOContracts(); // Deploy the superchain contracts. deploySuperchain.run(dsi, dso); - // Populate the input struct for DeployImplementations based on the output of DeploySuperchain. - deployImplementationsInput.superchainConfigProxy = dso.superchainConfigProxy(); - deployImplementationsInput.protocolVersionsProxy = dso.protocolVersionsProxy(); - - // Deploy the implementations using the updated DeployImplementations input struct. - deployImplementationsOutput = deployImplementations.run(deployImplementationsInput); - - // Set the OPStackManager on the input struct for DeployOPChain. - deployOPChainInput.opsm = deployImplementationsOutput.opsm; + // Populate the inputs for DeployImplementations based on the output of DeploySuperchain. + superchainConfigProxy = dso.superchainConfigProxy(); + protocolVersionsProxy = dso.protocolVersionsProxy(); + + // Deploy the implementations. + dii.set(dii.withdrawalDelaySeconds.selector, withdrawalDelaySeconds); + dii.set(dii.minProposalSizeBytes.selector, minProposalSizeBytes); + dii.set(dii.challengePeriodSeconds.selector, challengePeriodSeconds); + dii.set(dii.proofMaturityDelaySeconds.selector, proofMaturityDelaySeconds); + dii.set(dii.disputeGameFinalityDelaySeconds.selector, disputeGameFinalityDelaySeconds); + dii.set(dii.release.selector, release); + dii.set(dii.superchainConfigProxy.selector, address(superchainConfigProxy)); + dii.set(dii.protocolVersionsProxy.selector, address(protocolVersionsProxy)); + deployImplementations.run(dii, dio); + + // Set the OPStackManager input for DeployOPChain. + opsm = dio.opsm(); } // See the function of the same name in the `DeployImplementations_Test` contract of @@ -401,56 +396,55 @@ contract DeployOPChain_TestBase is Test { } contract DeployOPChain_Test is DeployOPChain_TestBase { - function testFuzz_run_succeeds(DeployOPChainInput.Input memory _input) public { - vm.assume(_input.roles.opChainProxyAdminOwner != address(0)); - vm.assume(_input.roles.systemConfigOwner != address(0)); - vm.assume(_input.roles.batcher != address(0)); - vm.assume(_input.roles.unsafeBlockSigner != address(0)); - vm.assume(_input.roles.proposer != address(0)); - vm.assume(_input.roles.challenger != address(0)); - vm.assume(_input.l2ChainId != 0 && _input.l2ChainId != block.chainid); - - _input.opsm = deployOPChainInput.opsm; + function hash(bytes32 _seed, uint256 _i) internal pure returns (bytes32) { + return keccak256(abi.encode(_seed, _i)); + } - DeployOPChainOutput.Output memory output = deployOPChain.run(_input); + function testFuzz_run_memory_succeeds(bytes32 _seed) public { + opChainProxyAdminOwner = address(uint160(uint256(hash(_seed, 0)))); + systemConfigOwner = address(uint160(uint256(hash(_seed, 1)))); + batcher = address(uint160(uint256(hash(_seed, 2)))); + unsafeBlockSigner = address(uint160(uint256(hash(_seed, 3)))); + proposer = address(uint160(uint256(hash(_seed, 4)))); + challenger = address(uint160(uint256(hash(_seed, 5)))); + basefeeScalar = uint32(uint256(hash(_seed, 6))); + blobBaseFeeScalar = uint32(uint256(hash(_seed, 7))); + l2ChainId = uint256(uint256(hash(_seed, 8))); + + doi.set(doi.opChainProxyAdminOwner.selector, opChainProxyAdminOwner); + doi.set(doi.systemConfigOwner.selector, systemConfigOwner); + doi.set(doi.batcher.selector, batcher); + doi.set(doi.unsafeBlockSigner.selector, unsafeBlockSigner); + doi.set(doi.proposer.selector, proposer); + doi.set(doi.challenger.selector, challenger); + doi.set(doi.basefeeScalar.selector, basefeeScalar); + doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar); + doi.set(doi.l2ChainId.selector, l2ChainId); + doi.set(doi.opsm.selector, address(opsm)); // Not fuzzed since it must be an actual instance. + + deployOPChain.run(doi, doo); // TODO Add fault proof contract assertions below once OPSM fully supports them. - // Assert that individual input fields were properly set based on the input struct. - assertEq(_input.roles.opChainProxyAdminOwner, doi.opChainProxyAdminOwner(), "100"); - assertEq(_input.roles.systemConfigOwner, doi.systemConfigOwner(), "200"); - assertEq(_input.roles.batcher, doi.batcher(), "300"); - assertEq(_input.roles.unsafeBlockSigner, doi.unsafeBlockSigner(), "400"); - assertEq(_input.roles.proposer, doi.proposer(), "500"); - assertEq(_input.roles.challenger, doi.challenger(), "600"); - assertEq(_input.basefeeScalar, doi.basefeeScalar(), "700"); - assertEq(_input.blobBaseFeeScalar, doi.blobBaseFeeScalar(), "800"); - assertEq(_input.l2ChainId, doi.l2ChainId(), "900"); - - // Assert that individual output fields were properly set based on the output struct. - assertEq(address(output.opChainProxyAdmin), address(doo.opChainProxyAdmin()), "1100"); - assertEq(address(output.addressManager), address(doo.addressManager()), "1200"); - assertEq(address(output.l1ERC721BridgeProxy), address(doo.l1ERC721BridgeProxy()), "1300"); - assertEq(address(output.systemConfigProxy), address(doo.systemConfigProxy()), "1400"); - assertEq( - address(output.optimismMintableERC20FactoryProxy), address(doo.optimismMintableERC20FactoryProxy()), "1500" - ); - assertEq(address(output.l1StandardBridgeProxy), address(doo.l1StandardBridgeProxy()), "1600"); - assertEq(address(output.l1CrossDomainMessengerProxy), address(doo.l1CrossDomainMessengerProxy()), "1700"); - assertEq(address(output.optimismPortalProxy), address(doo.optimismPortalProxy()), "1800"); - - // Assert that the full input and output structs were properly set. - assertEq(keccak256(abi.encode(_input)), keccak256(abi.encode(DeployOPChainInput(doi).input())), "1900"); - assertEq(keccak256(abi.encode(output)), keccak256(abi.encode(DeployOPChainOutput(doo).output())), "2000"); + // Assert that individual input fields were properly set based on the inputs. + assertEq(opChainProxyAdminOwner, doi.opChainProxyAdminOwner(), "100"); + assertEq(systemConfigOwner, doi.systemConfigOwner(), "200"); + assertEq(batcher, doi.batcher(), "300"); + assertEq(unsafeBlockSigner, doi.unsafeBlockSigner(), "400"); + assertEq(proposer, doi.proposer(), "500"); + assertEq(challenger, doi.challenger(), "600"); + assertEq(basefeeScalar, doi.basefeeScalar(), "700"); + assertEq(blobBaseFeeScalar, doi.blobBaseFeeScalar(), "800"); + assertEq(l2ChainId, doi.l2ChainId(), "900"); // Assert inputs were properly passed through to the contract initializers. - assertEq(address(output.opChainProxyAdmin.owner()), _input.roles.opChainProxyAdminOwner, "2100"); - assertEq(address(output.systemConfigProxy.owner()), _input.roles.systemConfigOwner, "2200"); - address batcher = address(uint160(uint256(output.systemConfigProxy.batcherHash()))); - assertEq(batcher, _input.roles.batcher, "2300"); - assertEq(address(output.systemConfigProxy.unsafeBlockSigner()), _input.roles.unsafeBlockSigner, "2400"); - // assertEq(address(...proposer()), _input.roles.proposer, "2500"); // TODO once we deploy dispute games. - // assertEq(address(...challenger()), _input.roles.challenger, "2600"); // TODO once we deploy dispute games. + assertEq(address(doo.opChainProxyAdmin().owner()), opChainProxyAdminOwner, "2100"); + assertEq(address(doo.systemConfigProxy().owner()), systemConfigOwner, "2200"); + address batcherActual = address(uint160(uint256(doo.systemConfigProxy().batcherHash()))); + assertEq(batcherActual, batcher, "2300"); + assertEq(address(doo.systemConfigProxy().unsafeBlockSigner()), unsafeBlockSigner, "2400"); + // assertEq(address(...proposer()), proposer, "2500"); // TODO once we deploy dispute games. + // assertEq(address(...challenger()), challenger, "2600"); // TODO once we deploy dispute games. // Most architecture assertions are handled within the OP Stack Manager itself and therefore // we only assert on the things that are not visible onchain. diff --git a/packages/contracts-bedrock/test/L1/OPStackManager.t.sol b/packages/contracts-bedrock/test/L1/OPStackManager.t.sol index b1af4fc1409f..4d5929021b5d 100644 --- a/packages/contracts-bedrock/test/L1/OPStackManager.t.sol +++ b/packages/contracts-bedrock/test/L1/OPStackManager.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Test } from "forge-std/Test.sol"; +import { Test, stdStorage, StdStorage } from "forge-std/Test.sol"; import { DeployOPChainInput } from "scripts/DeployOPChain.s.sol"; import { DeployOPChain_TestBase } from "test/DeployOPChain.t.sol"; @@ -32,42 +32,58 @@ contract OPStackManager_Harness is OPStackManager { // we can use its setup to deploy the implementations similarly to how a real deployment would // happen. contract OPStackManager_Deploy_Test is DeployOPChain_TestBase { + using stdStorage for StdStorage; + + function setUp() public override { + DeployOPChain_TestBase.setUp(); + + doi.set(doi.opChainProxyAdminOwner.selector, opChainProxyAdminOwner); + doi.set(doi.systemConfigOwner.selector, systemConfigOwner); + doi.set(doi.batcher.selector, batcher); + doi.set(doi.unsafeBlockSigner.selector, unsafeBlockSigner); + doi.set(doi.proposer.selector, proposer); + doi.set(doi.challenger.selector, challenger); + doi.set(doi.basefeeScalar.selector, basefeeScalar); + doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar); + doi.set(doi.l2ChainId.selector, l2ChainId); + doi.set(doi.opsm.selector, address(opsm)); + } + // This helper function is used to convert the input struct type defined in DeployOPChain.s.sol // to the input struct type defined in OPStackManager.sol. - function toOPSMDeployInput(DeployOPChainInput.Input memory input) - internal - pure - returns (OPStackManager.DeployInput memory) - { + function toOPSMDeployInput(DeployOPChainInput _doi) internal view returns (OPStackManager.DeployInput memory) { return OPStackManager.DeployInput({ roles: OPStackManager.Roles({ - opChainProxyAdminOwner: input.roles.opChainProxyAdminOwner, - systemConfigOwner: input.roles.systemConfigOwner, - batcher: input.roles.batcher, - unsafeBlockSigner: input.roles.unsafeBlockSigner, - proposer: input.roles.proposer, - challenger: input.roles.challenger + opChainProxyAdminOwner: _doi.opChainProxyAdminOwner(), + systemConfigOwner: _doi.systemConfigOwner(), + batcher: _doi.batcher(), + unsafeBlockSigner: _doi.unsafeBlockSigner(), + proposer: _doi.proposer(), + challenger: _doi.challenger() }), - basefeeScalar: input.basefeeScalar, - blobBasefeeScalar: input.blobBaseFeeScalar, - l2ChainId: input.l2ChainId + basefeeScalar: _doi.basefeeScalar(), + blobBasefeeScalar: _doi.blobBaseFeeScalar(), + l2ChainId: _doi.l2ChainId() }); } function test_deploy_l2ChainIdEqualsZero_reverts() public { - deployOPChainInput.l2ChainId = 0; + OPStackManager.DeployInput memory deployInput = toOPSMDeployInput(doi); + deployInput.l2ChainId = 0; vm.expectRevert(OPStackManager.InvalidChainId.selector); - deployImplementationsOutput.opsm.deploy(toOPSMDeployInput(deployOPChainInput)); + opsm.deploy(deployInput); } function test_deploy_l2ChainIdEqualsCurrentChainId_reverts() public { - deployOPChainInput.l2ChainId = block.chainid; + OPStackManager.DeployInput memory deployInput = toOPSMDeployInput(doi); + deployInput.l2ChainId = block.chainid; + vm.expectRevert(OPStackManager.InvalidChainId.selector); - deployImplementationsOutput.opsm.deploy(toOPSMDeployInput(deployOPChainInput)); + opsm.deploy(deployInput); } function test_deploy_succeeds() public { - deployImplementationsOutput.opsm.deploy(toOPSMDeployInput(deployOPChainInput)); + opsm.deploy(toOPSMDeployInput(doi)); } } From deb9bac17d078f5c44fd921bf9e7f62e371ab228 Mon Sep 17 00:00:00 2001 From: clabby Date: Thu, 12 Sep 2024 21:01:40 -0400 Subject: [PATCH 129/264] feat: Add channel timeout tests for `op-program` (#11885) * feat: Add channel timeout tests for `op-program` * typo * assert error * fix comment --- op-e2e/actions/proofs/channel_timeout_test.go | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 op-e2e/actions/proofs/channel_timeout_test.go diff --git a/op-e2e/actions/proofs/channel_timeout_test.go b/op-e2e/actions/proofs/channel_timeout_test.go new file mode 100644 index 000000000000..2f3fb555b5d3 --- /dev/null +++ b/op-e2e/actions/proofs/channel_timeout_test.go @@ -0,0 +1,142 @@ +package proofs + +import ( + "testing" + + "github.com/ethereum-optimism/optimism/op-e2e/actions" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-program/client/claim" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/stretchr/testify/require" +) + +// Run a test that exercises the channel timeout functionality in `op-program`. +// +// Steps: +// 1. Build `NumL2Blocks` empty blocks on L2. +// 2. Buffer the first half of the L2 blocks in the batcher, and submit the frame data. +// 3. Time out the channel by mining `ChannelTimeout + 1` empty blocks on L1. +// 4. Submit the channel frame data across 2 transactions. +// 5. Instruct the sequencer to derive the L2 chain. +// 6. Run the FPP on the safe head. +func runChannelTimeoutTest(gt *testing.T, checkResult func(gt *testing.T, err error), inputParams ...FixtureInputParam) { + t := actions.NewDefaultTesting(gt) + tp := NewTestParams(func(tp *e2eutils.TestParams) { + // Set the channel timeout to 10 blocks, 12x lower than the sequencing window. + tp.ChannelTimeout = 10 + }) + dp := NewDeployParams(t, func(dp *e2eutils.DeployParams) { + genesisBlock := hexutil.Uint64(0) + + // Enable Cancun on L1 & Granite on L2 at genesis + dp.DeployConfig.L1CancunTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisRegolithTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisFjordTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisGraniteTimeOffset = &genesisBlock + }) + bCfg := NewBatcherCfg() + env := NewL2FaultProofEnv(t, tp, dp, bCfg) + + const NumL2Blocks = 10 + + // Build NumL2Blocks empty blocks on L2 + for i := 0; i < NumL2Blocks; i++ { + env.sequencer.ActL2StartBlock(t) + env.sequencer.ActL2EndBlock(t) + } + + // Buffer the first half of L2 blocks in the batcher, and submit it. + for i := 0; i < NumL2Blocks/2; i++ { + env.batcher.ActL2BatchBuffer(t) + } + env.batcher.ActL2BatchSubmit(t) + + // Instruct the batcher to submit the first channel frame to L1, and include the transaction. + env.miner.ActL1StartBlock(12)(t) + env.miner.ActL1IncludeTxByHash(env.batcher.LastSubmitted.Hash())(t) + env.miner.ActL1EndBlock(t) + + // Finalize the block with the first channel frame on L1. + env.miner.ActL1SafeNext(t) + env.miner.ActL1FinalizeNext(t) + + // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. + env.sequencer.ActL1HeadSignal(t) + env.sequencer.ActL2PipelineFull(t) + + // Ensure that the safe head has not advanced - the channel is incomplete. + l2SafeHead := env.engine.L2Chain().CurrentSafeBlock() + require.Equal(t, uint64(0), l2SafeHead.Number.Uint64()) + + // Time out the channel by mining `ChannelTimeout + 1` empty blocks on L1. + for i := uint64(0); i < tp.ChannelTimeout+1; i++ { + env.miner.ActEmptyBlock(t) + env.miner.ActL1SafeNext(t) + env.miner.ActL1FinalizeNext(t) + } + + // Instruct the sequencer to derive the L2 chain - the channel should now be timed out. + env.sequencer.ActL1HeadSignal(t) + env.sequencer.ActL2PipelineFull(t) + + // Ensure the safe head has still not advanced. + l2SafeHead = env.engine.L2Chain().CurrentSafeBlock() + require.Equal(t, uint64(0), l2SafeHead.Number.Uint64()) + + // Instruct the batcher to submit the blocks to L1 in a new channel, + // submitted across 2 transactions. + for i := 0; i < 2; i++ { + // Buffer half of the L2 chain's blocks. + for j := 0; j < NumL2Blocks/2; j++ { + env.batcher.ActL2BatchBuffer(t) + } + + // Close the channel on the second iteration. + if i == 1 { + env.batcher.ActL2ChannelClose(t) + } + + env.batcher.ActL2BatchSubmit(t) + env.miner.ActL1StartBlock(12)(t) + env.miner.ActL1IncludeTxByHash(env.batcher.LastSubmitted.Hash())(t) + env.miner.ActL1EndBlock(t) + + // Finalize the block with the frame data on L1. + env.miner.ActL1SafeNext(t) + env.miner.ActL1FinalizeNext(t) + } + + // Instruct the sequencer to derive the L2 chain. + env.sequencer.ActL1HeadSignal(t) + env.sequencer.ActL2PipelineFull(t) + + // Ensure the safe head has still advanced to L2 block # NumL2Blocks. + l2SafeHead = env.engine.L2Chain().CurrentSafeBlock() + require.EqualValues(t, NumL2Blocks, l2SafeHead.Number.Uint64()) + + // Run the FPP on L2 block # NumL2Blocks/2. + err := env.RunFaultProofProgram(t, gt, NumL2Blocks/2, inputParams...) + checkResult(gt, err) +} + +func Test_ProgramAction_ChannelTimeout_HonestClaim_Granite(gt *testing.T) { + runChannelTimeoutTest(gt, func(gt *testing.T, err error) { + require.NoError(gt, err, "fault proof program should have succeeded") + }) +} + +func Test_ProgramAction_ChannelTimeout_JunkClaim_Granite(gt *testing.T) { + runChannelTimeoutTest( + gt, + func(gt *testing.T, err error) { + require.ErrorIs(gt, err, claim.ErrClaimNotValid, "fault proof program should have failed") + }, + func(f *FixtureInputs) { + f.L2Claim = common.HexToHash("0xdeadbeef") + }, + ) +} From e9ba6ac07d3af2bc42bcb5d412282df21523cee0 Mon Sep 17 00:00:00 2001 From: clabby Date: Thu, 12 Sep 2024 21:12:25 -0400 Subject: [PATCH 130/264] feat: Add garbage frame tests for `op-program` (#11896) * feat: Add channel timeout tests for `op-program` * typo * assert error * fix comment * feat: Add garbage frame tests for `op-program` * assert error * fix comment --- op-e2e/actions/garbage_channel_out.go | 27 +++- op-e2e/actions/l2_batcher.go | 68 +++------ op-e2e/actions/l2_batcher_test.go | 4 +- op-e2e/actions/proofs/garbage_channel_test.go | 144 ++++++++++++++++++ 4 files changed, 188 insertions(+), 55 deletions(-) create mode 100644 op-e2e/actions/proofs/garbage_channel_test.go diff --git a/op-e2e/actions/garbage_channel_out.go b/op-e2e/actions/garbage_channel_out.go index a24cca7c2c03..d5373755f8fe 100644 --- a/op-e2e/actions/garbage_channel_out.go +++ b/op-e2e/actions/garbage_channel_out.go @@ -36,10 +36,29 @@ var GarbageKinds = []GarbageKind{ MALFORM_RLP, } +func (gk GarbageKind) String() string { + switch gk { + case STRIP_VERSION: + return "STRIP_VERSION" + case RANDOM: + return "RANDOM" + case TRUNCATE_END: + return "TRUNCATE_END" + case DIRTY_APPEND: + return "DIRTY_APPEND" + case INVALID_COMPRESSION: + return "INVALID_COMPRESSION" + case MALFORM_RLP: + return "MALFORM_RLP" + default: + return "UNKNOWN" + } +} + // GarbageChannelCfg is the configuration for a `GarbageChannelOut` type GarbageChannelCfg struct { - useInvalidCompression bool - malformRLP bool + UseInvalidCompression bool + MalformRLP bool } // Writer is the interface shared between `zlib.Writer` and `gzip.Writer` @@ -109,7 +128,7 @@ func NewGarbageChannelOut(cfg *GarbageChannelCfg) (*GarbageChannelOut, error) { // Optionally use zlib or gzip compression var compress Writer - if cfg.useInvalidCompression { + if cfg.UseInvalidCompression { compress, err = gzip.NewWriterLevel(&c.buf, gzip.BestCompression) } else { compress, err = zlib.NewWriterLevel(&c.buf, zlib.BestCompression) @@ -152,7 +171,7 @@ func (co *GarbageChannelOut) AddBlock(rollupCfg *rollup.Config, block *types.Blo if err := rlp.Encode(&buf, batch); err != nil { return err } - if co.cfg.malformRLP { + if co.cfg.MalformRLP { // Malform the RLP by incrementing the length prefix by 1. bufBytes := buf.Bytes() bufBytes[0] += 1 diff --git a/op-e2e/actions/l2_batcher.go b/op-e2e/actions/l2_batcher.go index 42fe7c8b2bcd..75d46f3418ca 100644 --- a/op-e2e/actions/l2_batcher.go +++ b/op-e2e/actions/l2_batcher.go @@ -230,12 +230,11 @@ func (s *L2Batcher) ActL2ChannelClose(t Testing) { require.NoError(t, s.l2ChannelOut.Close(), "must close channel before submitting it") } -// ActL2BatchSubmit constructs a batch tx from previous buffered L2 blocks, and submits it to L1 -func (s *L2Batcher) ActL2BatchSubmit(t Testing, txOpts ...func(tx *types.DynamicFeeTx)) { +func (s *L2Batcher) ReadNextOutputFrame(t Testing) []byte { // Don't run this action if there's no data to submit if s.l2ChannelOut == nil { t.InvalidAction("need to buffer data first, cannot batch submit with empty buffer") - return + return nil } // Collect the output frame data := new(bytes.Buffer) @@ -249,7 +248,15 @@ func (s *L2Batcher) ActL2BatchSubmit(t Testing, txOpts ...func(tx *types.Dynamic t.Fatalf("failed to output channel data to frame: %v", err) } - payload := data.Bytes() + return data.Bytes() +} + +// ActL2BatchSubmit constructs a batch tx from previous buffered L2 blocks, and submits it to L1 +func (s *L2Batcher) ActL2BatchSubmit(t Testing, txOpts ...func(tx *types.DynamicFeeTx)) { + s.ActL2BatchSubmitRaw(t, s.ReadNextOutputFrame(t), txOpts...) +} + +func (s *L2Batcher) ActL2BatchSubmitRaw(t Testing, payload []byte, txOpts ...func(tx *types.DynamicFeeTx)) { if s.l2BatcherCfg.UseAltDA { comm, err := s.l2BatcherCfg.AltDA.SetInput(t.Ctx(), payload) require.NoError(t, err, "failed to set input for altda") @@ -401,27 +408,14 @@ func (s *L2Batcher) ActL2BatchSubmitMultiBlob(t Testing, numBlobs int) { // batch inbox. This *should* cause the batch inbox to reject the blocks // encoded within the frame, even if the blocks themselves are valid. func (s *L2Batcher) ActL2BatchSubmitGarbage(t Testing, kind GarbageKind) { - // Don't run this action if there's no data to submit - if s.l2ChannelOut == nil { - t.InvalidAction("need to buffer data first, cannot batch submit with empty buffer") - return - } - - // Collect the output frame - data := new(bytes.Buffer) - data.WriteByte(derive.DerivationVersion0) - - // subtract one, to account for the version byte - if _, err := s.l2ChannelOut.OutputFrame(data, s.l2BatcherCfg.MaxL1TxSize-1); err == io.EOF { - s.l2ChannelOut = nil - s.l2Submitting = false - } else if err != nil { - s.l2Submitting = false - t.Fatalf("failed to output channel data to frame: %v", err) - } - - outputFrame := data.Bytes() + outputFrame := s.ReadNextOutputFrame(t) + s.ActL2BatchSubmitGarbageRaw(t, outputFrame, kind) +} +// ActL2BatchSubmitGarbageRaw constructs a malformed channel frame from `outputFrame` and submits it to the +// batch inbox. This *should* cause the batch inbox to reject the blocks +// encoded within the frame, even if the blocks themselves are valid. +func (s *L2Batcher) ActL2BatchSubmitGarbageRaw(t Testing, outputFrame []byte, kind GarbageKind) { // Malform the output frame switch kind { // Strip the derivation version byte from the output frame @@ -453,31 +447,7 @@ func (s *L2Batcher) ActL2BatchSubmitGarbage(t Testing, kind GarbageKind) { t.Fatalf("Unexpected garbage kind: %v", kind) } - nonce, err := s.l1.PendingNonceAt(t.Ctx(), s.batcherAddr) - require.NoError(t, err, "need batcher nonce") - - gasTipCap := big.NewInt(2 * params.GWei) - pendingHeader, err := s.l1.HeaderByNumber(t.Ctx(), big.NewInt(-1)) - require.NoError(t, err, "need l1 pending header for gas price estimation") - gasFeeCap := new(big.Int).Add(gasTipCap, new(big.Int).Mul(pendingHeader.BaseFee, big.NewInt(2))) - - rawTx := &types.DynamicFeeTx{ - ChainID: s.rollupCfg.L1ChainID, - Nonce: nonce, - To: &s.rollupCfg.BatchInboxAddress, - GasTipCap: gasTipCap, - GasFeeCap: gasFeeCap, - Data: outputFrame, - } - gas, err := core.IntrinsicGas(rawTx.Data, nil, false, true, true, false) - require.NoError(t, err, "need to compute intrinsic gas") - rawTx.Gas = gas - - tx, err := types.SignNewTx(s.l2BatcherCfg.BatcherKey, s.l1Signer, rawTx) - require.NoError(t, err, "need to sign tx") - - err = s.l1.SendTransaction(t.Ctx(), tx) - require.NoError(t, err, "need to send tx") + s.ActL2BatchSubmitRaw(t, outputFrame) } func (s *L2Batcher) ActBufferAll(t Testing) { diff --git a/op-e2e/actions/l2_batcher_test.go b/op-e2e/actions/l2_batcher_test.go index 88dd393a38df..0b9140020b0b 100644 --- a/op-e2e/actions/l2_batcher_test.go +++ b/op-e2e/actions/l2_batcher_test.go @@ -317,8 +317,8 @@ func GarbageBatch(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // If the garbage kind is `INVALID_COMPRESSION` or `MALFORM_RLP`, use the `actions` packages // modified `ChannelOut`. batcherCfg.GarbageCfg = &GarbageChannelCfg{ - useInvalidCompression: garbageKind == INVALID_COMPRESSION, - malformRLP: garbageKind == MALFORM_RLP, + UseInvalidCompression: garbageKind == INVALID_COMPRESSION, + MalformRLP: garbageKind == MALFORM_RLP, } } diff --git a/op-e2e/actions/proofs/garbage_channel_test.go b/op-e2e/actions/proofs/garbage_channel_test.go new file mode 100644 index 000000000000..c8b44dd45f1c --- /dev/null +++ b/op-e2e/actions/proofs/garbage_channel_test.go @@ -0,0 +1,144 @@ +package proofs + +import ( + "testing" + + "github.com/ethereum-optimism/optimism/op-e2e/actions" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-program/client/claim" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/stretchr/testify/require" +) + +// garbageKinds is a list of garbage kinds to test. We don't use `INVALID_COMPRESSION` and `MALFORM_RLP` because +// they submit malformed frames always, and this test models a valid channel with a single invalid frame in the +// middle. +var garbageKinds = []actions.GarbageKind{ + actions.STRIP_VERSION, + actions.RANDOM, + actions.TRUNCATE_END, + actions.DIRTY_APPEND, +} + +// Run a test that submits garbage channel data in the middle of a channel. +// +// channel format ([]Frame): +// [f[0 - correct] f_x[1 - bad frame] f[1 - correct]] +func runGarbageChannelTest(gt *testing.T, garbageKind actions.GarbageKind, checkResult func(gt *testing.T, err error), inputParams ...FixtureInputParam) { + t := actions.NewDefaultTesting(gt) + tp := NewTestParams(func(tp *e2eutils.TestParams) { + // Set the channel timeout to 10 blocks, 12x lower than the sequencing window. + tp.ChannelTimeout = 10 + }) + dp := NewDeployParams(t, func(dp *e2eutils.DeployParams) { + genesisBlock := hexutil.Uint64(0) + + // Enable Cancun on L1 & Granite on L2 at genesis + dp.DeployConfig.L1CancunTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisRegolithTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisFjordTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisGraniteTimeOffset = &genesisBlock + }) + bCfg := NewBatcherCfg() + env := NewL2FaultProofEnv(t, tp, dp, bCfg) + + includeBatchTx := func(env *L2FaultProofEnv) { + // Instruct the batcher to submit the first channel frame to L1, and include the transaction. + env.miner.ActL1StartBlock(12)(t) + env.miner.ActL1IncludeTxByHash(env.batcher.LastSubmitted.Hash())(t) + env.miner.ActL1EndBlock(t) + + // Finalize the block with the first channel frame on L1. + env.miner.ActL1SafeNext(t) + env.miner.ActL1FinalizeNext(t) + + // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. + env.sequencer.ActL1HeadSignal(t) + env.sequencer.ActL2PipelineFull(t) + } + + const NumL2Blocks = 10 + + // Build NumL2Blocks empty blocks on L2 + for i := 0; i < NumL2Blocks; i++ { + env.sequencer.ActL2StartBlock(t) + env.sequencer.ActL2EndBlock(t) + } + + // Buffer the first half of L2 blocks in the batcher, and submit it. + for i := 0; i < NumL2Blocks/2; i++ { + env.batcher.ActL2BatchBuffer(t) + } + env.batcher.ActL2BatchSubmit(t) + + // Include the batcher transaction. + includeBatchTx(env) + + // Ensure that the safe head has not advanced - the channel is incomplete. + l2SafeHead := env.engine.L2Chain().CurrentSafeBlock() + require.Equal(t, uint64(0), l2SafeHead.Number.Uint64()) + + // Buffer the second half of L2 blocks in the batcher. + for i := 0; i < NumL2Blocks/2; i++ { + env.batcher.ActL2BatchBuffer(t) + } + env.batcher.ActL2ChannelClose(t) + expectedSecondFrame := env.batcher.ReadNextOutputFrame(t) + + // Submit a garbage frame, modified from the expected second frame. + env.batcher.ActL2BatchSubmitGarbageRaw(t, expectedSecondFrame, garbageKind) + // Include the garbage second frame tx + includeBatchTx(env) + + // Ensure that the safe head has not advanced - the channel is incomplete. + l2SafeHead = env.engine.L2Chain().CurrentSafeBlock() + require.Equal(t, uint64(0), l2SafeHead.Number.Uint64()) + + // Submit the correct second frame. + env.batcher.ActL2BatchSubmitRaw(t, expectedSecondFrame) + // Include the corract second frame tx. + includeBatchTx(env) + + // Ensure that the safe head has advanced - the channel is complete. + l2SafeHead = env.engine.L2Chain().CurrentSafeBlock() + require.Equal(t, uint64(NumL2Blocks), l2SafeHead.Number.Uint64()) + + // Run the FPP on L2 block # NumL2Blocks. + err := env.RunFaultProofProgram(t, gt, NumL2Blocks, inputParams...) + checkResult(gt, err) +} + +func Test_ProgramAction_GarbageChannel_HonestClaim_Granite(gt *testing.T) { + for _, garbageKind := range garbageKinds { + gt.Run(garbageKind.String(), func(t *testing.T) { + runGarbageChannelTest( + t, + garbageKind, + func(gt *testing.T, err error) { + require.NoError(gt, err, "fault proof program should not have failed") + }, + ) + }) + } +} + +func Test_ProgramAction_GarbageChannel_JunkClaim_Granite(gt *testing.T) { + for _, garbageKind := range garbageKinds { + gt.Run(garbageKind.String(), func(t *testing.T) { + runGarbageChannelTest( + t, + garbageKind, + func(gt *testing.T, err error) { + require.ErrorIs(gt, err, claim.ErrClaimNotValid, "fault proof program should have failed") + }, + func(f *FixtureInputs) { + f.L2Claim = common.HexToHash("0xdeadbeef") + }, + ) + }) + } +} From 9e1f077f7f9676f08649efbeba3cd633f5ce8280 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Thu, 12 Sep 2024 19:48:05 -0600 Subject: [PATCH 131/264] feat: mintable with permit (#11868) * contracts-bedrock: add permit functionality to mintable erc20 Adds `permit` functionality to `OptimismMintableERC20` tokens that are deployed by the `OptimismMintableERC20Factory`. * feat: max approve permit2 in ERC20Mintable This commit max approves permit2 automatically for all holders of the ERC20 bridge token. This enables all users on OP stack chains to skip an approval step for actions on protocols utilizing permit2 e.g. Uniswap * fix: constants first * semver-lock: update * snapshots: fix * contracts: add natspec * semver-lock: update * contracts-bedrock: fix nits * snapshots: update --------- Co-authored-by: Mark Toda --- packages/contracts-bedrock/semver-lock.json | 8 +- .../snapshots/abi/OptimismMintableERC20.json | 92 ++++++++++++++++++- .../storageLayout/OptimismMintableERC20.json | 14 +++ .../src/universal/OptimismMintableERC20.sol | 49 +++++++--- .../OptimismMintableERC20Factory.sol | 2 +- .../universal/OptimismMintableERC20.t.sol | 14 +++ 6 files changed, 159 insertions(+), 20 deletions(-) diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 1d3f5c04399f..7013535f0ee8 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -208,12 +208,12 @@ "sourceCodeHash": "0xd1479c60087f352385b6d5379ef3cc07839f671d617626b4c94ece91da781ef2" }, "src/universal/OptimismMintableERC20.sol": { - "initCodeHash": "0xfc77e4db406c232d8b84a3f77b939fb08fa27852faa5f4b0d78d998402caf308", - "sourceCodeHash": "0xd7957c662ef03fc0cc3440a6ec6737a55f90b52a977262a260cd99fe96494267" + "initCodeHash": "0x28c88484e1932253d6d12954492ac8a70744dc15c84429089af9944e5b158fd9", + "sourceCodeHash": "0x740b4043436d1b314ee3ba145acfcde60b6abd8416ea594f2b8e890b5d0bce6b" }, "src/universal/OptimismMintableERC20Factory.sol": { - "initCodeHash": "0x1cc94179ce28fb34c8e28b8d2015b95588e93a45730dae9ee7da859a9f66e0e6", - "sourceCodeHash": "0x46d1d4a9ed1b1f4c60d42bf6c9982ffc72cbd759a4aae5246f89ccbb8699c2a1" + "initCodeHash": "0x3ebd2297c0af2856a432daf29d186d0751f7edb1c777abbe136953038cf5d1ba", + "sourceCodeHash": "0xf8425f65eb5520d55710907d67a9d6fa277263285e1b79ba299815d1c76919a3" }, "src/universal/OptimismMintableERC721.sol": { "initCodeHash": "0x5a995fc043f8268a6d5c6284ad85b0de21328cd47277114aeba2c03484deaf91", diff --git a/packages/contracts-bedrock/snapshots/abi/OptimismMintableERC20.json b/packages/contracts-bedrock/snapshots/abi/OptimismMintableERC20.json index 3c6f5e9ab348..5a5763c73962 100644 --- a/packages/contracts-bedrock/snapshots/abi/OptimismMintableERC20.json +++ b/packages/contracts-bedrock/snapshots/abi/OptimismMintableERC20.json @@ -43,6 +43,32 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERMIT2", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [], "name": "REMOTE_TOKEN", @@ -60,12 +86,12 @@ "inputs": [ { "internalType": "address", - "name": "owner", + "name": "_owner", "type": "address" }, { "internalType": "address", - "name": "spender", + "name": "_spender", "type": "address" } ], @@ -272,6 +298,68 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "remoteToken", diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OptimismMintableERC20.json b/packages/contracts-bedrock/snapshots/storageLayout/OptimismMintableERC20.json index 418a98546cf7..2ad020cb1c4f 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/OptimismMintableERC20.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/OptimismMintableERC20.json @@ -33,5 +33,19 @@ "offset": 0, "slot": "4", "type": "string" + }, + { + "bytes": "32", + "label": "_nonces", + "offset": 0, + "slot": "5", + "type": "mapping(address => struct Counters.Counter)" + }, + { + "bytes": "32", + "label": "_PERMIT_TYPEHASH_DEPRECATED_SLOT", + "offset": 0, + "slot": "6", + "type": "bytes32" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol b/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol index dd207caf167f..838a21af5662 100644 --- a/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol +++ b/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol @@ -2,9 +2,11 @@ pragma solidity 0.8.15; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { ERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { ILegacyMintableERC20, IOptimismMintableERC20 } from "src/universal/interfaces/IOptimismMintableERC20.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { Preinstalls } from "src/libraries/Preinstalls.sol"; /// @title OptimismMintableERC20 /// @notice OptimismMintableERC20 is a standard extension of the base ERC20 token contract designed @@ -12,7 +14,7 @@ import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// use an OptimismMintablERC20 as the L2 representation of an L1 token, or vice-versa. /// Designed to be backwards compatible with the older StandardL2ERC20 token which was only /// meant for use on L2. -contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, ERC20, ISemver { +contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, ERC20Permit, ISemver { /// @notice Address of the corresponding version of this token on the remote chain. address public immutable REMOTE_TOKEN; @@ -39,8 +41,16 @@ contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, } /// @notice Semantic version. - /// @custom:semver 1.3.1-beta.1 - string public constant version = "1.3.1-beta.1"; + /// @custom:semver 1.4.0-beta.1 + string public constant version = "1.4.0-beta.1"; + + /// @notice Getter function for the permit2 address. It deterministically deployed + /// so it will always be at the same address. It is also included as a preinstall, + /// so it exists in the genesis state of chains. + /// @return Address of permit2 on this network. + function PERMIT2() public pure returns (address) { + return Preinstalls.Permit2; + } /// @param _bridge Address of the L2 standard bridge. /// @param _remoteToken Address of the corresponding L1 token. @@ -54,12 +64,35 @@ contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, uint8 _decimals ) ERC20(_name, _symbol) + ERC20Permit(_name) { REMOTE_TOKEN = _remoteToken; BRIDGE = _bridge; DECIMALS = _decimals; } + /// @dev Returns the number of decimals used to get its user representation. + /// For example, if `decimals` equals `2`, a balance of `505` tokens should + /// be displayed to a user as `5.05` (`505 / 10 ** 2`). + /// NOTE: This information is only used for _display_ purposes: it in + /// no way affects any of the arithmetic of the contract, including + /// {IERC20-balanceOf} and {IERC20-transfer}. + function decimals() public view override returns (uint8) { + return DECIMALS; + } + + /// @notice Returns the allowance for a spender on the owner's tokens. + /// If the spender is the permit2 address, returns the maximum uint256 value. + /// @param _owner owner of the tokens. + /// @param _spender spender of the tokens. + /// @return Allowance for the spender. + function allowance(address _owner, address _spender) public view override returns (uint256) { + if (_spender == PERMIT2()) { + return type(uint256).max; + } + return super.allowance(_owner, _spender); + } + /// @notice Allows the StandardBridge on this network to mint tokens. /// @param _to Address to mint tokens to. /// @param _amount Amount of tokens to mint. @@ -127,14 +160,4 @@ contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, function bridge() public view returns (address) { return BRIDGE; } - - /// @dev Returns the number of decimals used to get its user representation. - /// For example, if `decimals` equals `2`, a balance of `505` tokens should - /// be displayed to a user as `5.05` (`505 / 10 ** 2`). - /// NOTE: This information is only used for _display_ purposes: it in - /// no way affects any of the arithmetic of the contract, including - /// {IERC20-balanceOf} and {IERC20-transfer}. - function decimals() public view override returns (uint8) { - return DECIMALS; - } } diff --git a/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol b/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol index 790c1f828dfb..6ae271603312 100644 --- a/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol +++ b/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol @@ -49,7 +49,7 @@ contract OptimismMintableERC20Factory is ISemver, Initializable, IOptimismERC20F /// is responsible for deploying OptimismMintableERC20 contracts. /// @notice Semantic version. /// @custom:semver 1.10.1-beta.1 - string public constant version = "1.10.1-beta.1"; + string public constant version = "1.10.1-beta.2"; /// @notice Constructs the OptimismMintableERC20Factory contract. constructor() { diff --git a/packages/contracts-bedrock/test/universal/OptimismMintableERC20.t.sol b/packages/contracts-bedrock/test/universal/OptimismMintableERC20.t.sol index fcacc13a05f7..1e84ce2958cf 100644 --- a/packages/contracts-bedrock/test/universal/OptimismMintableERC20.t.sol +++ b/packages/contracts-bedrock/test/universal/OptimismMintableERC20.t.sol @@ -46,6 +46,20 @@ contract OptimismMintableERC20_Test is Bridge_Initializer { assertEq(L2Token.balanceOf(alice), 100); } + function test_allowance_permit2_max() external view { + assertEq(L2Token.allowance(alice, L2Token.PERMIT2()), type(uint256).max); + } + + function test_permit2_transferFrom() external { + vm.prank(address(l2StandardBridge)); + L2Token.mint(alice, 100); + + assertEq(L2Token.balanceOf(bob), 0); + vm.prank(L2Token.PERMIT2()); + L2Token.transferFrom(alice, bob, 100); + assertEq(L2Token.balanceOf(bob), 100); + } + function test_mint_notBridge_reverts() external { // NOT the bridge vm.expectRevert("OptimismMintableERC20: only bridge can mint and burn"); From 0e2947495d1ea4e64e08e409b466c48177881fc9 Mon Sep 17 00:00:00 2001 From: clabby Date: Thu, 12 Sep 2024 21:59:17 -0400 Subject: [PATCH 132/264] add sequence window expiry test (#11897) --- op-e2e/actions/proofs/env.go | 20 +++-- .../proofs/sequence_window_expiry_test.go | 82 +++++++++++++++++++ 2 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 op-e2e/actions/proofs/sequence_window_expiry_test.go diff --git a/op-e2e/actions/proofs/env.go b/op-e2e/actions/proofs/env.go index 59fc51fdf452..809289d90316 100644 --- a/op-e2e/actions/proofs/env.go +++ b/op-e2e/actions/proofs/env.go @@ -41,13 +41,13 @@ func NewL2FaultProofEnv(t actions.Testing, tp *e2eutils.TestParams, dp *e2eutils miner := actions.NewL1Miner(t, log.New("role", "l1-miner"), sd.L1Cfg) - l1F, err := sources.NewL1Client(miner.RPCClient(), log, nil, sources.L1ClientDefaultConfig(sd.RollupCfg, false, sources.RPCKindStandard)) + l1Cl, err := sources.NewL1Client(miner.RPCClient(), log, nil, sources.L1ClientDefaultConfig(sd.RollupCfg, false, sources.RPCKindStandard)) require.NoError(t, err) engine := actions.NewL2Engine(t, log.New("role", "sequencer-engine"), sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath, actions.EngineWithP2P()) - l2Cl, err := sources.NewEngineClient(engine.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) + l2EngineCl, err := sources.NewEngineClient(engine.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(t, err) - sequencer := actions.NewL2Sequencer(t, log.New("role", "sequencer"), l1F, miner.BlobStore(), altda.Disabled, l2Cl, sd.RollupCfg, 0, cfg.InteropBackend) + sequencer := actions.NewL2Sequencer(t, log.New("role", "sequencer"), l1Cl, miner.BlobStore(), altda.Disabled, l2EngineCl, sd.RollupCfg, 0, cfg.InteropBackend) miner.ActL1SetFeeRecipient(common.Address{0xCA, 0xFE, 0xBA, 0xBE}) sequencer.ActL2PipelineFull(t) engCl := engine.EngineClient(t, sd.RollupCfg) @@ -57,14 +57,22 @@ func NewL2FaultProofEnv(t actions.Testing, tp *e2eutils.TestParams, dp *e2eutils batcher := actions.NewL2Batcher(log, sd.RollupCfg, batcherCfg, sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engCl) addresses := e2eutils.CollectAddresses(sd, dp) - cl := engine.EthClient() + l1EthCl := miner.EthClient() + l2EthCl := engine.EthClient() + l1UserEnv := &actions.BasicUserEnv[*actions.L1Bindings]{ + EthCl: l1EthCl, + Signer: types.LatestSigner(sd.L1Cfg.Config), + AddressCorpora: addresses, + Bindings: actions.NewL1Bindings(t, l1EthCl), + } l2UserEnv := &actions.BasicUserEnv[*actions.L2Bindings]{ - EthCl: cl, + EthCl: l2EthCl, Signer: types.LatestSigner(sd.L2Cfg.Config), AddressCorpora: addresses, - Bindings: actions.NewL2Bindings(t, cl, engine.GethClient()), + Bindings: actions.NewL2Bindings(t, l2EthCl, engine.GethClient()), } alice := actions.NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b))) + alice.L1.SetUserEnv(l1UserEnv) alice.L2.SetUserEnv(l2UserEnv) return &L2FaultProofEnv{ diff --git a/op-e2e/actions/proofs/sequence_window_expiry_test.go b/op-e2e/actions/proofs/sequence_window_expiry_test.go new file mode 100644 index 000000000000..508e08ad4fc0 --- /dev/null +++ b/op-e2e/actions/proofs/sequence_window_expiry_test.go @@ -0,0 +1,82 @@ +package proofs + +import ( + "testing" + + "github.com/ethereum-optimism/optimism/op-e2e/actions" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-program/client/claim" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/stretchr/testify/require" +) + +// Run a test that proves a deposit-only block generated due to sequence window expiry. +func runSequenceWindowExpireTest(gt *testing.T, checkResult func(gt *testing.T, err error), inputParams ...FixtureInputParam) { + t := actions.NewDefaultTesting(gt) + tp := NewTestParams() + dp := NewDeployParams(t, func(dp *e2eutils.DeployParams) { + genesisBlock := hexutil.Uint64(0) + + // Enable Cancun on L1 & Granite on L2 at genesis + dp.DeployConfig.L1CancunTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisRegolithTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisFjordTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisGraniteTimeOffset = &genesisBlock + }) + bCfg := NewBatcherCfg() + env := NewL2FaultProofEnv(t, tp, dp, bCfg) + + // Mine an empty block for gas estimation purposes. + env.miner.ActEmptyBlock(t) + + // Expire the sequence window by building `SequenceWindow + 1` empty blocks on L1. + for i := 0; i < int(tp.SequencerWindowSize)+1; i++ { + env.alice.L1.ActResetTxOpts(t) + env.alice.ActDeposit(t) + + env.miner.ActL1StartBlock(12)(t) + env.miner.ActL1IncludeTx(env.alice.Address())(t) + env.miner.ActL1EndBlock(t) + + env.miner.ActL1SafeNext(t) + env.miner.ActL1FinalizeNext(t) + } + + // Ensure the safe head is still 0. + l2SafeHead := env.engine.L2Chain().CurrentSafeBlock() + require.EqualValues(t, 0, l2SafeHead.Number.Uint64()) + + // Ask the sequencer to derive the deposit-only L2 chain. + env.sequencer.ActL1HeadSignal(t) + env.sequencer.ActL2PipelineFull(t) + + // Ensure the safe head advanced forcefully. + l2SafeHead = env.engine.L2Chain().CurrentSafeBlock() + require.Greater(t, l2SafeHead.Number.Uint64(), uint64(0)) + + // Run the FPP on one of the auto-derived blocks. + err := env.RunFaultProofProgram(t, gt, l2SafeHead.Number.Uint64()/2, inputParams...) + checkResult(gt, err) +} + +func Test_ProgramAction_SequenceWindowExpired_HonestClaim_Granite(gt *testing.T) { + runSequenceWindowExpireTest(gt, func(gt *testing.T, err error) { + require.NoError(gt, err, "fault proof program should have succeeded") + }) +} + +func Test_ProgramAction_SequenceWindowExpired_JunkClaim_Granite(gt *testing.T) { + runSequenceWindowExpireTest( + gt, + func(gt *testing.T, err error) { + require.ErrorIs(gt, err, claim.ErrClaimNotValid, "fault proof program should have failed") + }, + func(f *FixtureInputs) { + f.L2Claim = common.HexToHash("0xdeadbeef") + }, + ) +} From 3dbcee1c312881166bd544fa857f25d86a20bcd2 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Thu, 12 Sep 2024 22:36:21 -0400 Subject: [PATCH 133/264] fix: incorrect import in ManageDrippie.s.sol (#11898) Fixes an incorrect import inside of ManageDrippie.s.sol. Seems to work just fine when forge install is executed but not otherwise. --- .../scripts/periphery/drippie/ManageDrippie.s.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/scripts/periphery/drippie/ManageDrippie.s.sol b/packages/contracts-bedrock/scripts/periphery/drippie/ManageDrippie.s.sol index 903216b3d16a..f37a16f547f9 100644 --- a/packages/contracts-bedrock/scripts/periphery/drippie/ManageDrippie.s.sol +++ b/packages/contracts-bedrock/scripts/periphery/drippie/ManageDrippie.s.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; import { console2 as console } from "forge-std/console2.sol"; import { Script } from "forge-std/Script.sol"; -import { LibString } from "solady/src/utils/LibString.sol"; +import { LibString } from "@solady/utils/LibString.sol"; import { IAutomate as IGelato } from "gelato/interfaces/IAutomate.sol"; import { LibDataTypes as GelatoDataTypes } from "gelato/libraries/LibDataTypes.sol"; From d5957fad716d6b57f7aa02b618959fc445f63df2 Mon Sep 17 00:00:00 2001 From: Inphi Date: Fri, 13 Sep 2024 00:09:41 -0400 Subject: [PATCH 134/264] op-e2e: Setup mt-cannon for tests (#11881) * op-e2e: Use mt-cannon Introduces a `USE_MT_CANNON` env to optionally enables MT-Cannon in op-e2e integration tests * a couple of fixes * fix todo --- .circleci/config.yml | 36 +++++++- Makefile | 4 +- op-e2e/Makefile | 5 +- op-e2e/e2eutils/challenger/helper.go | 7 +- op-e2e/e2eutils/setup.go | 5 ++ .../scripts/deploy/Deploy.s.sol | 86 +++++++++++++++---- .../scripts/libraries/Config.sol | 5 ++ packages/contracts-bedrock/semver-lock.json | 4 +- .../snapshots/abi/MIPS2.json | 13 +++ .../contracts-bedrock/src/cannon/MIPS2.sol | 10 ++- .../src/cannon/interfaces/IMIPS2.sol | 2 + 11 files changed, 149 insertions(+), 28 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8c01d9d9f917..0efd7832b79a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -236,6 +236,12 @@ jobs: - run: name: Copy AltDA allocs to .devnet-altda command: cp -r .devnet/ .devnet-altda-generic/ + - run: + name: Generate MT-Cannon allocs + command: USE_MT_CANNON="true" make devnet-allocs + - run: + name: Copy MT-Cannon allocs to .devnet-mt-cannon + command: cp -r .devnet/ .devnet-mt-cannon/ - run: name: Generate default allocs command: make devnet-allocs @@ -279,6 +285,12 @@ jobs: - ".devnet-altda-generic/allocs-l2-ecotone.json" - ".devnet-altda-generic/allocs-l2-fjord.json" - ".devnet-altda-generic/allocs-l2-granite.json" + - ".devnet-mt-cannon/allocs-l1.json" + - ".devnet-mt-cannon/addresses.json" + - ".devnet-mt-cannon/allocs-l2-delta.json" + - ".devnet-mt-cannon/allocs-l2-ecotone.json" + - ".devnet-mt-cannon/allocs-l2-fjord.json" + - ".devnet-mt-cannon/allocs-l2-granite.json" - "packages/contracts-bedrock/deploy-config/devnetL1.json" - "packages/contracts-bedrock/deployments/devnetL1" - notify-failures-on-develop @@ -928,6 +940,13 @@ jobs: - run: name: Set OP_E2E_USE_ALTDA = true command: echo 'export OP_E2E_USE_ALTDA=true' >> $BASH_ENV + - when: + condition: + equal: ['-mt-cannon', <>] + steps: + - run: + name: Set OP_E2E_USE_MT_CANNON = true + command: echo 'export OP_E2E_USE_MT_CANNON=true' >> $BASH_ENV - check-changed: patterns: op-(.+),cannon,contracts-bedrock - run: @@ -1071,6 +1090,16 @@ jobs: - "op-program/bin/prestate.json" - "op-program/bin/meta.json" - "op-program/bin/prestate-proof.json" + - run: + name: generate cannon-mt prestate + command: make cannon-prestate-mt + - save_cache: + key: cannon-prestate-mt-{{ checksum "./cannon/bin/cannon" }}-{{ checksum "op-program/bin/op-program-client.elf" }} + name: Save MT-Cannon prestate to cache + paths: + - "op-program/bin/prestate-mt.json" + - "op-program/bin/meta-mt.json" + - "op-program/bin/prestate-proof-mt.json" - save_cache: name: Save Go build cache key: golang-build-cache-cannon-prestate-{{ checksum "go.sum" }} @@ -2078,7 +2107,12 @@ workflows: - go-mod-download - contracts-bedrock-build - go-e2e-test: - name: op-e2e-cannon-tests + name: op-e2e-cannon-tests<< matrix.variant >> + matrix: + parameters: + variant: [""] + # TODO(#11893): add mt-cannon to matrix once it's stable + #variant: ["", "-mt-cannon"] module: op-e2e target: test-cannon parallelism: 4 diff --git a/Makefile b/Makefile index 7450895a079a..fb67b2b12864 100644 --- a/Makefile +++ b/Makefile @@ -134,10 +134,12 @@ reproducible-prestate: ## Builds reproducible-prestate binary .PHONY: reproducible-prestate # Include any files required for the devnet to build and run. This appears to be the only one that's actually needed. -DEVNET_CANNON_PRESTATE_FILES := op-program/bin/prestate-proof.json op-program/bin/prestate.json +DEVNET_CANNON_PRESTATE_FILES := op-program/bin/prestate-proof.json op-program/bin/prestate.json op-program/bin/prestate-proof-mt.json op-program/bin/prestate-mt.json + $(DEVNET_CANNON_PRESTATE_FILES): make cannon-prestate + make cannon-prestate-mt cannon-prestate: op-program cannon ## Generates prestate using cannon and op-program ./cannon/bin/cannon load-elf --path op-program/bin/op-program-client.elf --out op-program/bin/prestate.json --meta op-program/bin/meta.json diff --git a/op-e2e/Makefile b/op-e2e/Makefile index bd0cdba73bef..6bf5d616640b 100644 --- a/op-e2e/Makefile +++ b/op-e2e/Makefile @@ -40,8 +40,9 @@ test-devnet: pre-test $(go_test) $(go_test_flags) ./devnet .PHONY: test-devnet -cannon-prestate: +cannon-prestates: make -C .. cannon-prestate + make -C .. cannon-prestate-mt .PHONY: cannon-prestate # We depend on the absolute pre-state generated by cannon to deploy the dispute game contracts. @@ -54,7 +55,7 @@ pre-test: pre-test-cannon pre-test-allocs pre-test-cannon: @if [ ! -e ../op-program/bin ]; then \ - make cannon-prestate; \ + make cannon-prestates; \ fi .PHONY: pre-test-cannon diff --git a/op-e2e/e2eutils/challenger/helper.go b/op-e2e/e2eutils/challenger/helper.go index e79bb56b3304..3b037ef71c6d 100644 --- a/op-e2e/e2eutils/challenger/helper.go +++ b/op-e2e/e2eutils/challenger/helper.go @@ -106,7 +106,12 @@ func applyCannonConfig(c *config.Config, t *testing.T, rollupCfg *rollup.Config, root := FindMonorepoRoot(t) c.Cannon.VmBin = root + "cannon/bin/cannon" c.Cannon.Server = root + "op-program/bin/op-program" - c.CannonAbsolutePreState = root + "op-program/bin/prestate.json" + if e2eutils.UseMTCannon() { + t.Log("Using MT-Cannon absolute prestate") + c.CannonAbsolutePreState = root + "op-program/bin/prestate-mt.bin.gz" + } else { + c.CannonAbsolutePreState = root + "op-program/bin/prestate.json" + } c.Cannon.SnapshotFreq = 10_000_000 genesisBytes, err := json.Marshal(l2Genesis) diff --git a/op-e2e/e2eutils/setup.go b/op-e2e/e2eutils/setup.go index e226b3da8095..a00d3e57d237 100644 --- a/op-e2e/e2eutils/setup.go +++ b/op-e2e/e2eutils/setup.go @@ -249,3 +249,8 @@ func UseAltDA() bool { return (os.Getenv("OP_E2E_USE_ALTDA") == "true" || os.Getenv("DEVNET_ALTDA") == "true") } + +func UseMTCannon() bool { + return (os.Getenv("OP_E2E_USE_MT_CANNON") == "true" || + os.Getenv("USE_MT_CANNON") == "true") +} diff --git a/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol b/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol index b0cdcc4dcfe3..5a5506b00a6f 100644 --- a/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol @@ -38,6 +38,7 @@ import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { MIPS } from "src/cannon/MIPS.sol"; +import { MIPS2 } from "src/cannon/MIPS2.sol"; import { StorageSetter } from "src/universal/StorageSetter.sol"; // Libraries @@ -827,16 +828,32 @@ contract Deploy is Deployer { addr_ = address(preimageOracle); } - /// @notice Deploy Mips + /// @notice Deploy Mips VM. Deploys either MIPS or MIPS2 depending on the environment function deployMips() public broadcast returns (address addr_) { + if (Config.useMultithreadedCannon()) { + addr_ = _deployMips2(); + } else { + addr_ = _deployMips(); + } + save("Mips", address(addr_)); + } + + /// @notice Deploy MIPS + function _deployMips() internal returns (address addr_) { console.log("Deploying Mips implementation"); MIPS mips = new MIPS{ salt: _implSalt() }(IPreimageOracle(mustGetAddress("PreimageOracle"))); - save("Mips", address(mips)); console.log("MIPS deployed at %s", address(mips)); - addr_ = address(mips); } + /// @notice Deploy MIPS2 + function _deployMips2() internal returns (address addr_) { + console.log("Deploying Mips2 implementation"); + MIPS2 mips2 = new MIPS2{ salt: _implSalt() }(IPreimageOracle(mustGetAddress("PreimageOracle"))); + console.log("MIPS2 deployed at %s", address(mips2)); + addr_ = address(mips2); + } + /// @notice Deploy the AnchorStateRegistry function deployAnchorStateRegistry() public broadcast returns (address addr_) { console.log("Deploying AnchorStateRegistry implementation"); @@ -1405,25 +1422,14 @@ contract Deploy is Deployer { }); } - /// @notice Loads the mips absolute prestate from the prestate-proof for devnets otherwise - /// from the config. + /// @notice Load the appropriate mips absolute prestate for devenets depending on config environment. function loadMipsAbsolutePrestate() internal returns (Claim mipsAbsolutePrestate_) { if (block.chainid == Chains.LocalDevnet || block.chainid == Chains.GethDevnet) { - // Fetch the absolute prestate dump - string memory filePath = string.concat(vm.projectRoot(), "/../../op-program/bin/prestate-proof.json"); - string[] memory commands = new string[](3); - commands[0] = "bash"; - commands[1] = "-c"; - commands[2] = string.concat("[[ -f ", filePath, " ]] && echo \"present\""); - if (Process.run(commands).length == 0) { - revert("Cannon prestate dump not found, generate it with `make cannon-prestate` in the monorepo root."); + if (Config.useMultithreadedCannon()) { + return _loadDevnetMtMipsAbsolutePrestate(); + } else { + return _loadDevnetStMipsAbsolutePrestate(); } - commands[2] = string.concat("cat ", filePath, " | jq -r .pre"); - mipsAbsolutePrestate_ = Claim.wrap(abi.decode(Process.run(commands), (bytes32))); - console.log( - "[Cannon Dispute Game] Using devnet MIPS Absolute prestate: %s", - vm.toString(Claim.unwrap(mipsAbsolutePrestate_)) - ); } else { console.log( "[Cannon Dispute Game] Using absolute prestate from config: %x", cfg.faultGameAbsolutePrestate() @@ -1432,6 +1438,48 @@ contract Deploy is Deployer { } } + /// @notice Loads the singlethreaded mips absolute prestate from the prestate-proof for devnets otherwise + /// from the config. + function _loadDevnetStMipsAbsolutePrestate() internal returns (Claim mipsAbsolutePrestate_) { + // Fetch the absolute prestate dump + string memory filePath = string.concat(vm.projectRoot(), "/../../op-program/bin/prestate-proof.json"); + string[] memory commands = new string[](3); + commands[0] = "bash"; + commands[1] = "-c"; + commands[2] = string.concat("[[ -f ", filePath, " ]] && echo \"present\""); + if (Process.run(commands).length == 0) { + revert("Cannon prestate dump not found, generate it with `make cannon-prestate` in the monorepo root."); + } + commands[2] = string.concat("cat ", filePath, " | jq -r .pre"); + mipsAbsolutePrestate_ = Claim.wrap(abi.decode(Process.run(commands), (bytes32))); + console.log( + "[Cannon Dispute Game] Using devnet MIPS Absolute prestate: %s", + vm.toString(Claim.unwrap(mipsAbsolutePrestate_)) + ); + } + + /// @notice Loads the multithreaded mips absolute prestate from the prestate-proof-mt for devnets otherwise + /// from the config. + function _loadDevnetMtMipsAbsolutePrestate() internal returns (Claim mipsAbsolutePrestate_) { + // Fetch the absolute prestate dump + string memory filePath = string.concat(vm.projectRoot(), "/../../op-program/bin/prestate-proof-mt.json"); + string[] memory commands = new string[](3); + commands[0] = "bash"; + commands[1] = "-c"; + commands[2] = string.concat("[[ -f ", filePath, " ]] && echo \"present\""); + if (Process.run(commands).length == 0) { + revert( + "MT-Cannon prestate dump not found, generate it with `make cannon-prestate-mt` in the monorepo root." + ); + } + commands[2] = string.concat("cat ", filePath, " | jq -r .pre"); + mipsAbsolutePrestate_ = Claim.wrap(abi.decode(Process.run(commands), (bytes32))); + console.log( + "[MT-Cannon Dispute Game] Using devnet MIPS2 Absolute prestate: %s", + vm.toString(Claim.unwrap(mipsAbsolutePrestate_)) + ); + } + /// @notice Sets the implementation for the `CANNON` game type in the `DisputeGameFactory` function setCannonFaultGameImplementation(bool _allowUpgrade) public broadcast { console.log("Setting Cannon FaultDisputeGame implementation"); diff --git a/packages/contracts-bedrock/scripts/libraries/Config.sol b/packages/contracts-bedrock/scripts/libraries/Config.sol index d4253113ce8a..06e59e902246 100644 --- a/packages/contracts-bedrock/scripts/libraries/Config.sol +++ b/packages/contracts-bedrock/scripts/libraries/Config.sol @@ -138,6 +138,11 @@ library Config { } } + /// @notice Returns true if multithreaded Cannon is used for the deployment. + function useMultithreadedCannon() internal view returns (bool _enabled) { + _enabled = vm.envOr("USE_MT_CANNON", false); + } + /// @notice Returns the latest fork to use for genesis allocs generation. /// It reads the fork from the environment variable FORK. If it is /// unset, NONE is returned. diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 7013535f0ee8..8da2618e4d8a 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -144,8 +144,8 @@ "sourceCodeHash": "0xee1aef5a502f9491b7b83dab46ea2f0fc286f87ace31edcc1367c840d462bdfe" }, "src/cannon/MIPS2.sol": { - "initCodeHash": "0x3430ef0ee7697e7b98589deffb3a303cd8ce73bdc69df2edc5c957cee7486a72", - "sourceCodeHash": "0xb05a2081aa93881871d08bd95610639dfb64e5d3ce0e8fa5fd212e7ae3c3fe60" + "initCodeHash": "0xeab5f44d7fa7af1072f500c754bb55aa92409a79b2765a66efed47461c0c4049", + "sourceCodeHash": "0xcf180ff2cab8d0a34f3bb19d7145f5bf7f67dd379722ece765d09b38dcfed2f6" }, "src/cannon/PreimageOracle.sol": { "initCodeHash": "0x801e52f9c8439fcf7089575fa93272dfb874641dbfc7d82f36d979c987271c0b", diff --git a/packages/contracts-bedrock/snapshots/abi/MIPS2.json b/packages/contracts-bedrock/snapshots/abi/MIPS2.json index 99ba9373513d..eacce2991e21 100644 --- a/packages/contracts-bedrock/snapshots/abi/MIPS2.json +++ b/packages/contracts-bedrock/snapshots/abi/MIPS2.json @@ -10,6 +10,19 @@ "stateMutability": "nonpayable", "type": "constructor" }, + { + "inputs": [], + "name": "oracle", + "outputs": [ + { + "internalType": "contract IPreimageOracle", + "name": "oracle_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { diff --git a/packages/contracts-bedrock/src/cannon/MIPS2.sol b/packages/contracts-bedrock/src/cannon/MIPS2.sol index 4f9135b801ec..08c7856f7aec 100644 --- a/packages/contracts-bedrock/src/cannon/MIPS2.sol +++ b/packages/contracts-bedrock/src/cannon/MIPS2.sol @@ -52,8 +52,8 @@ contract MIPS2 is ISemver { } /// @notice The semantic version of the MIPS2 contract. - /// @custom:semver 1.0.0-beta.7 - string public constant version = "1.0.0-beta.7"; + /// @custom:semver 1.0.0-beta.8 + string public constant version = "1.0.0-beta.8"; /// @notice The preimage oracle contract. IPreimageOracle internal immutable ORACLE; @@ -78,6 +78,12 @@ contract MIPS2 is ISemver { ORACLE = _oracle; } + /// @notice Getter for the pre-image oracle contract. + /// @return oracle_ The IPreimageOracle contract. + function oracle() external view returns (IPreimageOracle oracle_) { + oracle_ = ORACLE; + } + /// @notice Executes a single step of the multi-threaded vm. /// Will revert if any required input state is missing. /// @param _stateData The encoded state witness data. diff --git a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol index e4f3503b6809..e60b1d876b60 100644 --- a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol +++ b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.0; import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol"; /// @title IMIPS2 /// @notice Interface for the MIPS2 contract. @@ -10,5 +11,6 @@ interface IMIPS2 is ISemver { error InvalidMemoryProof(); error InvalidSecondMemoryProof(); + function oracle() external view returns (IPreimageOracle oracle_); function step(bytes memory _stateData, bytes memory _proof, bytes32 _localContext) external returns (bytes32); } From 0b20d8eb3c0bd87fc67ff32fff653721b2c0c760 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Fri, 13 Sep 2024 15:18:34 +1000 Subject: [PATCH 135/264] op-program: Inject prefetcher instead of setting code in config (#11902) * op-program: Support injecting a Prefetcher creator rather than setting code on the Config object. * op-program: Use an interface for the Prefetcher instead of requiring a concrete type. --- op-e2e/actions/l1_miner.go | 4 +- op-e2e/actions/proofs/channel_timeout_test.go | 2 +- op-e2e/actions/proofs/env.go | 36 +++--- op-e2e/actions/proofs/fixture.go | 4 +- op-e2e/actions/proofs/garbage_channel_test.go | 2 +- .../proofs/sequence_window_expiry_test.go | 2 +- op-e2e/actions/proofs/simple_program_test.go | 4 +- op-e2e/e2eutils/blobs.go | 2 - op-program/host/config/config.go | 12 +- op-program/host/host.go | 103 ++++++++++-------- op-program/host/host_test.go | 2 +- op-program/host/prefetcher/prefetcher.go | 27 ++++- op-program/host/prefetcher/retry.go | 19 ++-- op-program/host/prefetcher/retry_test.go | 3 +- op-program/host/sources/sources.go | 27 ----- 15 files changed, 122 insertions(+), 127 deletions(-) delete mode 100644 op-program/host/sources/sources.go diff --git a/op-e2e/actions/l1_miner.go b/op-e2e/actions/l1_miner.go index 46c9045961bb..e29d09ceb796 100644 --- a/op-e2e/actions/l1_miner.go +++ b/op-e2e/actions/l1_miner.go @@ -3,6 +3,7 @@ package actions import ( "math/big" + "github.com/ethereum-optimism/optimism/op-program/host/prefetcher" "github.com/stretchr/testify/require" "github.com/ethereum/go-ethereum/common" @@ -17,7 +18,6 @@ import ( "github.com/ethereum/go-ethereum/trie" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" - "github.com/ethereum-optimism/optimism/op-program/host/sources" "github.com/ethereum-optimism/optimism/op-service/eth" ) @@ -52,7 +52,7 @@ func NewL1Miner(t Testing, log log.Logger, genesis *core.Genesis) *L1Miner { } } -func (s *L1Miner) BlobStore() sources.L1BlobSource { +func (s *L1Miner) BlobStore() prefetcher.L1BlobSource { return s.blobStore } diff --git a/op-e2e/actions/proofs/channel_timeout_test.go b/op-e2e/actions/proofs/channel_timeout_test.go index 2f3fb555b5d3..10a5c1574cb5 100644 --- a/op-e2e/actions/proofs/channel_timeout_test.go +++ b/op-e2e/actions/proofs/channel_timeout_test.go @@ -119,7 +119,7 @@ func runChannelTimeoutTest(gt *testing.T, checkResult func(gt *testing.T, err er require.EqualValues(t, NumL2Blocks, l2SafeHead.Number.Uint64()) // Run the FPP on L2 block # NumL2Blocks/2. - err := env.RunFaultProofProgram(t, gt, NumL2Blocks/2, inputParams...) + err := env.RunFaultProofProgram(t, NumL2Blocks/2, inputParams...) checkResult(gt, err) } diff --git a/op-e2e/actions/proofs/env.go b/op-e2e/actions/proofs/env.go index 809289d90316..bc618c75ca72 100644 --- a/op-e2e/actions/proofs/env.go +++ b/op-e2e/actions/proofs/env.go @@ -1,8 +1,8 @@ package proofs import ( + "context" "math/rand" - "testing" altda "github.com/ethereum-optimism/optimism/op-alt-da" batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" @@ -10,6 +10,8 @@ import ( "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-program/host" "github.com/ethereum-optimism/optimism/op-program/host/config" + "github.com/ethereum-optimism/optimism/op-program/host/kvstore" + "github.com/ethereum-optimism/optimism/op-program/host/prefetcher" hostTypes "github.com/ethereum-optimism/optimism/op-program/host/types" "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-service/testlog" @@ -90,7 +92,7 @@ func NewL2FaultProofEnv(t actions.Testing, tp *e2eutils.TestParams, dp *e2eutils type FixtureInputParam func(f *FixtureInputs) -func (env *L2FaultProofEnv) RunFaultProofProgram(t actions.Testing, gt *testing.T, l2ClaimBlockNum uint64, fixtureInputParams ...FixtureInputParam) error { +func (env *L2FaultProofEnv) RunFaultProofProgram(t actions.Testing, l2ClaimBlockNum uint64, fixtureInputParams ...FixtureInputParam) error { // Fetch the pre and post output roots for the fault proof. preRoot, err := env.sequencer.RollupClient().OutputAtBlock(t.Ctx(), l2ClaimBlockNum-1) require.NoError(t, err) @@ -116,8 +118,22 @@ func (env *L2FaultProofEnv) RunFaultProofProgram(t actions.Testing, gt *testing. env, fixtureInputs, ) - err = host.FaultProofProgram(t.Ctx(), env.log, programCfg) - tryDumpTestFixture(gt, err, t.Name(), env, programCfg) + withInProcessPrefetcher := host.WithPrefetcher(func(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *config.Config) (host.Prefetcher, error) { + // Set up in-process L1 sources + l1Cl := env.miner.L1Client(t, env.sd.RollupCfg) + l1BlobFetcher := env.miner.BlobStore() + + // Set up in-process L2 source + l2ClCfg := sources.L2ClientDefaultConfig(env.sd.RollupCfg, true) + l2RPC := env.engine.RPCClient() + l2Client, err := host.NewL2Client(l2RPC, env.log, nil, &host.L2ClientConfig{L2ClientConfig: l2ClCfg, L2Head: cfg.L2Head}) + require.NoError(t, err, "failed to create L2 client") + l2DebugCl := &host.L2Source{L2Client: l2Client, DebugClient: sources.NewDebugClient(l2RPC.CallContext)} + + return prefetcher.NewPrefetcher(logger, l1Cl, l1BlobFetcher, l2DebugCl, kv), nil + }) + err = host.FaultProofProgram(t.Ctx(), env.log, programCfg, withInProcessPrefetcher) + tryDumpTestFixture(t, err, t.Name(), env, programCfg) return err } @@ -165,18 +181,6 @@ func NewOpProgramCfg( ) *config.Config { dfault := config.NewConfig(env.sd.RollupCfg, env.sd.L2Cfg.Config, fi.L1Head, fi.L2Head, fi.L2OutputRoot, fi.L2Claim, fi.L2BlockNumber) - // Set up in-process L1 sources - dfault.L1ProcessSource = env.miner.L1Client(t, env.sd.RollupCfg) - dfault.L1BeaconProcessSource = env.miner.BlobStore() - - // Set up in-process L2 source - l2ClCfg := sources.L2ClientDefaultConfig(env.sd.RollupCfg, true) - l2RPC := env.engine.RPCClient() - l2Client, err := host.NewL2Client(l2RPC, env.log, nil, &host.L2ClientConfig{L2ClientConfig: l2ClCfg, L2Head: fi.L2Head}) - require.NoError(t, err, "failed to create L2 client") - l2DebugCl := &host.L2Source{L2Client: l2Client, DebugClient: sources.NewDebugClient(l2RPC.CallContext)} - dfault.L2ProcessSource = l2DebugCl - if dumpFixtures { dfault.DataDir = t.TempDir() dfault.DataFormat = hostTypes.DataFormatPebble diff --git a/op-e2e/actions/proofs/fixture.go b/op-e2e/actions/proofs/fixture.go index 8bc4a875a4c3..1ea0b7f83099 100644 --- a/op-e2e/actions/proofs/fixture.go +++ b/op-e2e/actions/proofs/fixture.go @@ -7,8 +7,8 @@ import ( "os" "os/exec" "path/filepath" - "testing" + "github.com/ethereum-optimism/optimism/op-e2e/actions" "github.com/ethereum-optimism/optimism/op-program/client/claim" "github.com/ethereum-optimism/optimism/op-program/host/config" "github.com/ethereum/go-ethereum/common" @@ -46,7 +46,7 @@ type FixtureInputs struct { // Dumps a `fp-tests` test fixture to disk if the `OP_E2E_DUMP_FIXTURES` environment variable is set. // // [fp-tests]: https://github.com/ethereum-optimism/fp-tests -func tryDumpTestFixture(t *testing.T, result error, name string, env *L2FaultProofEnv, programCfg *config.Config) { +func tryDumpTestFixture(t actions.Testing, result error, name string, env *L2FaultProofEnv, programCfg *config.Config) { if !dumpFixtures { return } diff --git a/op-e2e/actions/proofs/garbage_channel_test.go b/op-e2e/actions/proofs/garbage_channel_test.go index c8b44dd45f1c..f9dec7f4d666 100644 --- a/op-e2e/actions/proofs/garbage_channel_test.go +++ b/op-e2e/actions/proofs/garbage_channel_test.go @@ -108,7 +108,7 @@ func runGarbageChannelTest(gt *testing.T, garbageKind actions.GarbageKind, check require.Equal(t, uint64(NumL2Blocks), l2SafeHead.Number.Uint64()) // Run the FPP on L2 block # NumL2Blocks. - err := env.RunFaultProofProgram(t, gt, NumL2Blocks, inputParams...) + err := env.RunFaultProofProgram(t, NumL2Blocks, inputParams...) checkResult(gt, err) } diff --git a/op-e2e/actions/proofs/sequence_window_expiry_test.go b/op-e2e/actions/proofs/sequence_window_expiry_test.go index 508e08ad4fc0..77f91fe2da50 100644 --- a/op-e2e/actions/proofs/sequence_window_expiry_test.go +++ b/op-e2e/actions/proofs/sequence_window_expiry_test.go @@ -59,7 +59,7 @@ func runSequenceWindowExpireTest(gt *testing.T, checkResult func(gt *testing.T, require.Greater(t, l2SafeHead.Number.Uint64(), uint64(0)) // Run the FPP on one of the auto-derived blocks. - err := env.RunFaultProofProgram(t, gt, l2SafeHead.Number.Uint64()/2, inputParams...) + err := env.RunFaultProofProgram(t, l2SafeHead.Number.Uint64()/2, inputParams...) checkResult(gt, err) } diff --git a/op-e2e/actions/proofs/simple_program_test.go b/op-e2e/actions/proofs/simple_program_test.go index b160045210d5..46de7fd19042 100644 --- a/op-e2e/actions/proofs/simple_program_test.go +++ b/op-e2e/actions/proofs/simple_program_test.go @@ -54,7 +54,7 @@ func Test_ProgramAction_SimpleEmptyChain_HonestClaim_Granite(gt *testing.T) { // Ensure the block is marked as safe before we attempt to fault prove it. require.Equal(t, uint64(1), l2SafeHead.Number.Uint64()) - err := env.RunFaultProofProgram(t, gt, l2SafeHead.Number.Uint64()) + err := env.RunFaultProofProgram(t, l2SafeHead.Number.Uint64()) require.NoError(t, err, "fault proof program failed") } @@ -102,7 +102,7 @@ func Test_ProgramAction_SimpleEmptyChain_JunkClaim_Granite(gt *testing.T) { // Ensure the block is marked as safe before we attempt to fault prove it. require.Equal(t, uint64(1), l2SafeHead.Number.Uint64()) - err := env.RunFaultProofProgram(t, gt, l2SafeHead.Number.Uint64(), func(f *FixtureInputs) { + err := env.RunFaultProofProgram(t, l2SafeHead.Number.Uint64(), func(f *FixtureInputs) { f.L2Claim = common.HexToHash("0xdeadbeef") }) require.Error(t, err, "fault proof program should have failed") diff --git a/op-e2e/e2eutils/blobs.go b/op-e2e/e2eutils/blobs.go index 01256a355a92..ae9ccd562c02 100644 --- a/op-e2e/e2eutils/blobs.go +++ b/op-e2e/e2eutils/blobs.go @@ -9,7 +9,6 @@ import ( "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" - "github.com/ethereum-optimism/optimism/op-program/host/sources" "github.com/ethereum-optimism/optimism/op-service/eth" ) @@ -78,5 +77,4 @@ func (store *BlobsStore) GetBlobSidecars(ctx context.Context, ref eth.L1BlockRef var ( _ derive.L1BlobsFetcher = (*BlobsStore)(nil) - _ sources.L1BlobSource = (*BlobsStore)(nil) ) diff --git a/op-program/host/config/config.go b/op-program/host/config/config.go index 4ef56070c6ac..1478fde5e25d 100644 --- a/op-program/host/config/config.go +++ b/op-program/host/config/config.go @@ -13,7 +13,6 @@ import ( opnode "github.com/ethereum-optimism/optimism/op-node" "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-program/host/flags" - hostSources "github.com/ethereum-optimism/optimism/op-program/host/sources" "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" @@ -74,11 +73,6 @@ type Config struct { // IsCustomChainConfig indicates that the program uses a custom chain configuration IsCustomChainConfig bool - - // Optional process sources. Will be favored over the RPC sources if set. - L1ProcessSource hostSources.L1Source - L1BeaconProcessSource hostSources.L1BlobSource - L2ProcessSource hostSources.L2Source } func (c *Config) Check() error { @@ -119,11 +113,7 @@ func (c *Config) Check() error { } func (c *Config) FetchingEnabled() bool { - return (c.L1URL != "" && c.L2URL != "" && c.L1BeaconURL != "") || c.InProcessSourcesEnabled() -} - -func (c *Config) InProcessSourcesEnabled() bool { - return c.L1ProcessSource != nil && c.L1BeaconProcessSource != nil && c.L2ProcessSource != nil + return c.L1URL != "" && c.L2URL != "" && c.L1BeaconURL != "" } // NewConfig creates a Config with all optional values set to the CLI default value diff --git a/op-program/host/host.go b/op-program/host/host.go index 5cce95d0250c..e71bf6db6564 100644 --- a/op-program/host/host.go +++ b/op-program/host/host.go @@ -16,7 +16,6 @@ import ( "github.com/ethereum-optimism/optimism/op-program/host/flags" "github.com/ethereum-optimism/optimism/op-program/host/kvstore" "github.com/ethereum-optimism/optimism/op-program/host/prefetcher" - hostSources "github.com/ethereum-optimism/optimism/op-program/host/sources" "github.com/ethereum-optimism/optimism/op-program/host/types" opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/client" @@ -31,6 +30,24 @@ type L2Source struct { *sources.DebugClient } +type Prefetcher interface { + Hint(hint string) error + GetPreimage(ctx context.Context, key common.Hash) ([]byte, error) +} +type PrefetcherCreator func(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *config.Config) (Prefetcher, error) + +type creatorsCfg struct { + prefetcher PrefetcherCreator +} + +type ProgramOpt func(c *creatorsCfg) + +func WithPrefetcher(creator PrefetcherCreator) ProgramOpt { + return func(c *creatorsCfg) { + c.prefetcher = creator + } +} + func Main(logger log.Logger, cfg *config.Config) error { if err := cfg.Check(); err != nil { return fmt.Errorf("invalid config: %w", err) @@ -44,7 +61,7 @@ func Main(logger log.Logger, cfg *config.Config) error { if cfg.ServerMode { preimageChan := preimage.ClientPreimageChannel() hinterChan := preimage.ClientHinterChannel() - return PreimageServer(ctx, logger, cfg, preimageChan, hinterChan) + return PreimageServer(ctx, logger, cfg, preimageChan, hinterChan, makeDefaultPrefetcher) } if err := FaultProofProgram(ctx, logger, cfg); err != nil { @@ -55,7 +72,13 @@ func Main(logger log.Logger, cfg *config.Config) error { } // FaultProofProgram is the programmatic entry-point for the fault proof program -func FaultProofProgram(ctx context.Context, logger log.Logger, cfg *config.Config) error { +func FaultProofProgram(ctx context.Context, logger log.Logger, cfg *config.Config, opts ...ProgramOpt) error { + creators := &creatorsCfg{ + prefetcher: makeDefaultPrefetcher, + } + for _, opt := range opts { + opt(creators) + } var ( serverErr chan error pClientRW preimage.FileChannel @@ -92,7 +115,7 @@ func FaultProofProgram(ctx context.Context, logger log.Logger, cfg *config.Confi serverErr = make(chan error) go func() { defer close(serverErr) - serverErr <- PreimageServer(ctx, logger, cfg, pHostRW, hHostRW) + serverErr <- PreimageServer(ctx, logger, cfg, pHostRW, hHostRW, creators.prefetcher) }() var cmd *exec.Cmd @@ -124,7 +147,7 @@ func FaultProofProgram(ctx context.Context, logger log.Logger, cfg *config.Confi // This method will block until both the hinter and preimage handlers complete. // If either returns an error both handlers are stopped. // The supplied preimageChannel and hintChannel will be closed before this function returns. -func PreimageServer(ctx context.Context, logger log.Logger, cfg *config.Config, preimageChannel preimage.FileChannel, hintChannel preimage.FileChannel) error { +func PreimageServer(ctx context.Context, logger log.Logger, cfg *config.Config, preimageChannel preimage.FileChannel, hintChannel preimage.FileChannel, prefetcherCreator PrefetcherCreator) error { var serverDone chan error var hinterDone chan error logger.Info("Starting preimage server") @@ -172,11 +195,11 @@ func PreimageServer(ctx context.Context, logger log.Logger, cfg *config.Config, getPreimage kvstore.PreimageSource hinter preimage.HintHandler ) - if cfg.FetchingEnabled() { - prefetch, err := makePrefetcher(ctx, logger, kv, cfg) - if err != nil { - return fmt.Errorf("failed to create prefetcher: %w", err) - } + prefetch, err := prefetcherCreator(ctx, logger, kv, cfg) + if err != nil { + return fmt.Errorf("failed to create prefetcher: %w", err) + } + if prefetch != nil { getPreimage = func(key common.Hash) ([]byte, error) { return prefetch.GetPreimage(ctx, key) } hinter = prefetch.Hint } else { @@ -205,43 +228,35 @@ func PreimageServer(ctx context.Context, logger log.Logger, cfg *config.Config, } } -func makePrefetcher(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *config.Config) (*prefetcher.Prefetcher, error) { - var l1Cl hostSources.L1Source - var l1BlobFetcher hostSources.L1BlobSource - var l2DebugCl hostSources.L2Source - - if cfg.InProcessSourcesEnabled() { - logger.Debug("Using in-process sources for preimage fetching.") - l1Cl = cfg.L1ProcessSource - l1BlobFetcher = cfg.L1BeaconProcessSource - l2DebugCl = cfg.L2ProcessSource - } else { - logger.Info("Connecting to L1 node", "l1", cfg.L1URL) - l1RPC, err := client.NewRPC(ctx, logger, cfg.L1URL, client.WithDialBackoff(10)) - if err != nil { - return nil, fmt.Errorf("failed to setup L1 RPC: %w", err) - } +func makeDefaultPrefetcher(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *config.Config) (Prefetcher, error) { + if !cfg.FetchingEnabled() { + return nil, nil + } + logger.Info("Connecting to L1 node", "l1", cfg.L1URL) + l1RPC, err := client.NewRPC(ctx, logger, cfg.L1URL, client.WithDialBackoff(10)) + if err != nil { + return nil, fmt.Errorf("failed to setup L1 RPC: %w", err) + } - logger.Info("Connecting to L2 node", "l2", cfg.L2URL) - l2RPC, err := client.NewRPC(ctx, logger, cfg.L2URL, client.WithDialBackoff(10)) - if err != nil { - return nil, fmt.Errorf("failed to setup L2 RPC: %w", err) - } + logger.Info("Connecting to L2 node", "l2", cfg.L2URL) + l2RPC, err := client.NewRPC(ctx, logger, cfg.L2URL, client.WithDialBackoff(10)) + if err != nil { + return nil, fmt.Errorf("failed to setup L2 RPC: %w", err) + } - l1ClCfg := sources.L1ClientDefaultConfig(cfg.Rollup, cfg.L1TrustRPC, cfg.L1RPCKind) - l2ClCfg := sources.L2ClientDefaultConfig(cfg.Rollup, true) - l1Cl, err = sources.NewL1Client(l1RPC, logger, nil, l1ClCfg) - if err != nil { - return nil, fmt.Errorf("failed to create L1 client: %w", err) - } - l1Beacon := sources.NewBeaconHTTPClient(client.NewBasicHTTPClient(cfg.L1BeaconURL, logger)) - l1BlobFetcher = sources.NewL1BeaconClient(l1Beacon, sources.L1BeaconClientConfig{FetchAllSidecars: false}) - l2Cl, err := NewL2Client(l2RPC, logger, nil, &L2ClientConfig{L2ClientConfig: l2ClCfg, L2Head: cfg.L2Head}) - if err != nil { - return nil, fmt.Errorf("failed to create L2 client: %w", err) - } - l2DebugCl = &L2Source{L2Client: l2Cl, DebugClient: sources.NewDebugClient(l2RPC.CallContext)} + l1ClCfg := sources.L1ClientDefaultConfig(cfg.Rollup, cfg.L1TrustRPC, cfg.L1RPCKind) + l2ClCfg := sources.L2ClientDefaultConfig(cfg.Rollup, true) + l1Cl, err := sources.NewL1Client(l1RPC, logger, nil, l1ClCfg) + if err != nil { + return nil, fmt.Errorf("failed to create L1 client: %w", err) + } + l1Beacon := sources.NewBeaconHTTPClient(client.NewBasicHTTPClient(cfg.L1BeaconURL, logger)) + l1BlobFetcher := sources.NewL1BeaconClient(l1Beacon, sources.L1BeaconClientConfig{FetchAllSidecars: false}) + l2Cl, err := NewL2Client(l2RPC, logger, nil, &L2ClientConfig{L2ClientConfig: l2ClCfg, L2Head: cfg.L2Head}) + if err != nil { + return nil, fmt.Errorf("failed to create L2 client: %w", err) } + l2DebugCl := &L2Source{L2Client: l2Cl, DebugClient: sources.NewDebugClient(l2RPC.CallContext)} return prefetcher.NewPrefetcher(logger, l1Cl, l1BlobFetcher, l2DebugCl, kv), nil } diff --git a/op-program/host/host_test.go b/op-program/host/host_test.go index 9dddfe689cfc..c5d63e17ab34 100644 --- a/op-program/host/host_test.go +++ b/op-program/host/host_test.go @@ -37,7 +37,7 @@ func TestServerMode(t *testing.T) { logger := testlog.Logger(t, log.LevelTrace) result := make(chan error) go func() { - result <- PreimageServer(context.Background(), logger, cfg, preimageServer, hintServer) + result <- PreimageServer(context.Background(), logger, cfg, preimageServer, hintServer, makeDefaultPrefetcher) }() pClient := preimage.NewOracleClient(preimageClient) diff --git a/op-program/host/prefetcher/prefetcher.go b/op-program/host/prefetcher/prefetcher.go index d381e6be2385..cb5a52fa88ce 100644 --- a/op-program/host/prefetcher/prefetcher.go +++ b/op-program/host/prefetcher/prefetcher.go @@ -13,7 +13,6 @@ import ( "github.com/ethereum-optimism/optimism/op-program/client/l2" "github.com/ethereum-optimism/optimism/op-program/client/mpt" "github.com/ethereum-optimism/optimism/op-program/host/kvstore" - "github.com/ethereum-optimism/optimism/op-program/host/sources" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -35,16 +34,34 @@ var acceleratedPrecompiles = []common.Address{ common.BytesToAddress([]byte{0x0a}), // KZG Point Evaluation } +type L1Source interface { + InfoByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, error) + InfoAndTxsByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Transactions, error) + FetchReceipts(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Receipts, error) +} + +type L1BlobSource interface { + GetBlobSidecars(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.BlobSidecar, error) + GetBlobs(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.Blob, error) +} + +type L2Source interface { + InfoAndTxsByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Transactions, error) + NodeByHash(ctx context.Context, hash common.Hash) ([]byte, error) + CodeByHash(ctx context.Context, hash common.Hash) ([]byte, error) + OutputByRoot(ctx context.Context, root common.Hash) (eth.Output, error) +} + type Prefetcher struct { logger log.Logger - l1Fetcher sources.L1Source - l1BlobFetcher sources.L1BlobSource - l2Fetcher sources.L2Source + l1Fetcher L1Source + l1BlobFetcher L1BlobSource + l2Fetcher L2Source lastHint string kvStore kvstore.KV } -func NewPrefetcher(logger log.Logger, l1Fetcher sources.L1Source, l1BlobFetcher sources.L1BlobSource, l2Fetcher sources.L2Source, kvStore kvstore.KV) *Prefetcher { +func NewPrefetcher(logger log.Logger, l1Fetcher L1Source, l1BlobFetcher L1BlobSource, l2Fetcher L2Source, kvStore kvstore.KV) *Prefetcher { return &Prefetcher{ logger: logger, l1Fetcher: NewRetryingL1Source(logger, l1Fetcher), diff --git a/op-program/host/prefetcher/retry.go b/op-program/host/prefetcher/retry.go index 98941f710f54..da9a588d8c3a 100644 --- a/op-program/host/prefetcher/retry.go +++ b/op-program/host/prefetcher/retry.go @@ -4,7 +4,6 @@ import ( "context" "math" - "github.com/ethereum-optimism/optimism/op-program/host/sources" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/retry" "github.com/ethereum/go-ethereum/common" @@ -16,11 +15,11 @@ const maxAttempts = math.MaxInt // Succeed or die trying type RetryingL1Source struct { logger log.Logger - source sources.L1Source + source L1Source strategy retry.Strategy } -func NewRetryingL1Source(logger log.Logger, source sources.L1Source) *RetryingL1Source { +func NewRetryingL1Source(logger log.Logger, source L1Source) *RetryingL1Source { return &RetryingL1Source{ logger: logger, source: source, @@ -58,15 +57,15 @@ func (s *RetryingL1Source) FetchReceipts(ctx context.Context, blockHash common.H }) } -var _ sources.L1Source = (*RetryingL1Source)(nil) +var _ L1Source = (*RetryingL1Source)(nil) type RetryingL1BlobSource struct { logger log.Logger - source sources.L1BlobSource + source L1BlobSource strategy retry.Strategy } -func NewRetryingL1BlobSource(logger log.Logger, source sources.L1BlobSource) *RetryingL1BlobSource { +func NewRetryingL1BlobSource(logger log.Logger, source L1BlobSource) *RetryingL1BlobSource { return &RetryingL1BlobSource{ logger: logger, source: source, @@ -94,11 +93,11 @@ func (s *RetryingL1BlobSource) GetBlobs(ctx context.Context, ref eth.L1BlockRef, }) } -var _ sources.L1BlobSource = (*RetryingL1BlobSource)(nil) +var _ L1BlobSource = (*RetryingL1BlobSource)(nil) type RetryingL2Source struct { logger log.Logger - source sources.L2Source + source L2Source strategy retry.Strategy } @@ -143,7 +142,7 @@ func (s *RetryingL2Source) OutputByRoot(ctx context.Context, root common.Hash) ( }) } -func NewRetryingL2Source(logger log.Logger, source sources.L2Source) *RetryingL2Source { +func NewRetryingL2Source(logger log.Logger, source L2Source) *RetryingL2Source { return &RetryingL2Source{ logger: logger, source: source, @@ -151,4 +150,4 @@ func NewRetryingL2Source(logger log.Logger, source sources.L2Source) *RetryingL2 } } -var _ sources.L2Source = (*RetryingL2Source)(nil) +var _ L2Source = (*RetryingL2Source)(nil) diff --git a/op-program/host/prefetcher/retry_test.go b/op-program/host/prefetcher/retry_test.go index dec179fc6276..737635b57d95 100644 --- a/op-program/host/prefetcher/retry_test.go +++ b/op-program/host/prefetcher/retry_test.go @@ -12,7 +12,6 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum-optimism/optimism/op-program/host/sources" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/retry" "github.com/ethereum-optimism/optimism/op-service/testlog" @@ -375,4 +374,4 @@ func (m *MockL2Source) ExpectOutputByRoot(root common.Hash, output eth.Output, e m.Mock.On("OutputByRoot", root).Once().Return(output, &err) } -var _ sources.L2Source = (*MockL2Source)(nil) +var _ L2Source = (*MockL2Source)(nil) diff --git a/op-program/host/sources/sources.go b/op-program/host/sources/sources.go deleted file mode 100644 index 4b6570553c58..000000000000 --- a/op-program/host/sources/sources.go +++ /dev/null @@ -1,27 +0,0 @@ -package sources - -import ( - "context" - - "github.com/ethereum-optimism/optimism/op-service/eth" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" -) - -type L1Source interface { - InfoByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, error) - InfoAndTxsByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Transactions, error) - FetchReceipts(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Receipts, error) -} - -type L1BlobSource interface { - GetBlobSidecars(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.BlobSidecar, error) - GetBlobs(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.Blob, error) -} - -type L2Source interface { - InfoAndTxsByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Transactions, error) - NodeByHash(ctx context.Context, hash common.Hash) ([]byte, error) - CodeByHash(ctx context.Context, hash common.Hash) ([]byte, error) - OutputByRoot(ctx context.Context, root common.Hash) (eth.Output, error) -} From 8b61225d51105b142580d40bde43adde791423b8 Mon Sep 17 00:00:00 2001 From: clabby Date: Fri, 13 Sep 2024 01:47:05 -0400 Subject: [PATCH 136/264] feat: `op-program` actor test API improvements (#11903) * feat: `op-program` actor test API improvements * lint * sort fix * rebase --- op-e2e/actions/proofs/channel_timeout_test.go | 52 ++++------ op-e2e/actions/proofs/env.go | 48 ++++++++- op-e2e/actions/proofs/fixture.go | 17 ++++ op-e2e/actions/proofs/garbage_channel_test.go | 68 +++++-------- op-e2e/actions/proofs/matrix.go | 97 +++++++++++++++++++ .../proofs/sequence_window_expiry_test.go | 54 ++++------- op-e2e/actions/proofs/simple_program_test.go | 91 +++++------------ 7 files changed, 245 insertions(+), 182 deletions(-) create mode 100644 op-e2e/actions/proofs/matrix.go diff --git a/op-e2e/actions/proofs/channel_timeout_test.go b/op-e2e/actions/proofs/channel_timeout_test.go index 10a5c1574cb5..80e0d3b5ec99 100644 --- a/op-e2e/actions/proofs/channel_timeout_test.go +++ b/op-e2e/actions/proofs/channel_timeout_test.go @@ -7,7 +7,6 @@ import ( "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-program/client/claim" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/stretchr/testify/require" ) @@ -20,26 +19,13 @@ import ( // 4. Submit the channel frame data across 2 transactions. // 5. Instruct the sequencer to derive the L2 chain. // 6. Run the FPP on the safe head. -func runChannelTimeoutTest(gt *testing.T, checkResult func(gt *testing.T, err error), inputParams ...FixtureInputParam) { +func runChannelTimeoutTest(gt *testing.T, testCfg *TestCfg[any]) { t := actions.NewDefaultTesting(gt) tp := NewTestParams(func(tp *e2eutils.TestParams) { // Set the channel timeout to 10 blocks, 12x lower than the sequencing window. tp.ChannelTimeout = 10 }) - dp := NewDeployParams(t, func(dp *e2eutils.DeployParams) { - genesisBlock := hexutil.Uint64(0) - - // Enable Cancun on L1 & Granite on L2 at genesis - dp.DeployConfig.L1CancunTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisRegolithTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisFjordTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisGraniteTimeOffset = &genesisBlock - }) - bCfg := NewBatcherCfg() - env := NewL2FaultProofEnv(t, tp, dp, bCfg) + env := NewL2FaultProofEnv(t, testCfg, tp, NewBatcherCfg()) const NumL2Blocks = 10 @@ -119,24 +105,26 @@ func runChannelTimeoutTest(gt *testing.T, checkResult func(gt *testing.T, err er require.EqualValues(t, NumL2Blocks, l2SafeHead.Number.Uint64()) // Run the FPP on L2 block # NumL2Blocks/2. - err := env.RunFaultProofProgram(t, NumL2Blocks/2, inputParams...) - checkResult(gt, err) + env.RunFaultProofProgram(t, NumL2Blocks/2, testCfg.CheckResult, testCfg.InputParams...) } -func Test_ProgramAction_ChannelTimeout_HonestClaim_Granite(gt *testing.T) { - runChannelTimeoutTest(gt, func(gt *testing.T, err error) { - require.NoError(gt, err, "fault proof program should have succeeded") - }) -} +func Test_ProgramAction_ChannelTimeout(gt *testing.T) { + matrix := NewMatrix[any]() + defer matrix.Run(gt) -func Test_ProgramAction_ChannelTimeout_JunkClaim_Granite(gt *testing.T) { - runChannelTimeoutTest( - gt, - func(gt *testing.T, err error) { - require.ErrorIs(gt, err, claim.ErrClaimNotValid, "fault proof program should have failed") - }, - func(f *FixtureInputs) { - f.L2Claim = common.HexToHash("0xdeadbeef") - }, + matrix.AddTestCase( + "HonestClaim", + nil, + LatestForkOnly, + runChannelTimeoutTest, + ExpectNoError(), + ) + matrix.AddTestCase( + "JunkClaim", + nil, + LatestForkOnly, + runChannelTimeoutTest, + ExpectError(claim.ErrClaimNotValid), + WithL2Claim(common.HexToHash("0xdeadbeef")), ) } diff --git a/op-e2e/actions/proofs/env.go b/op-e2e/actions/proofs/env.go index bc618c75ca72..3732096c266c 100644 --- a/op-e2e/actions/proofs/env.go +++ b/op-e2e/actions/proofs/env.go @@ -16,6 +16,7 @@ import ( "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/require" @@ -34,8 +35,30 @@ type L2FaultProofEnv struct { alice *actions.CrossLayerUser } -func NewL2FaultProofEnv(t actions.Testing, tp *e2eutils.TestParams, dp *e2eutils.DeployParams, batcherCfg *actions.BatcherCfg) *L2FaultProofEnv { +func NewL2FaultProofEnv[c any](t actions.Testing, testCfg *TestCfg[c], tp *e2eutils.TestParams, batcherCfg *actions.BatcherCfg) *L2FaultProofEnv { log := testlog.Logger(t, log.LvlDebug) + dp := NewDeployParams(t, func(dp *e2eutils.DeployParams) { + genesisBlock := hexutil.Uint64(0) + + // Enable cancun always + dp.DeployConfig.L1CancunTimeOffset = &genesisBlock + + // Enable L2 feature. + switch testCfg.Hardfork { + case Regolith: + dp.DeployConfig.L2GenesisRegolithTimeOffset = &genesisBlock + case Canyon: + dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisBlock + case Delta: + dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisBlock + case Ecotone: + dp.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisBlock + case Fjord: + dp.DeployConfig.L2GenesisFjordTimeOffset = &genesisBlock + case Granite: + dp.DeployConfig.L2GenesisGraniteTimeOffset = &genesisBlock + } + }) sd := e2eutils.Setup(t, dp, actions.DefaultAlloc) jwtPath := e2eutils.WriteDefaultJWT(t) @@ -92,7 +115,27 @@ func NewL2FaultProofEnv(t actions.Testing, tp *e2eutils.TestParams, dp *e2eutils type FixtureInputParam func(f *FixtureInputs) -func (env *L2FaultProofEnv) RunFaultProofProgram(t actions.Testing, l2ClaimBlockNum uint64, fixtureInputParams ...FixtureInputParam) error { +type CheckResult func(actions.Testing, error) + +func ExpectNoError() CheckResult { + return func(t actions.Testing, err error) { + require.NoError(t, err, "fault proof program should have succeeded") + } +} + +func ExpectError(expectedErr error) CheckResult { + return func(t actions.Testing, err error) { + require.ErrorIs(t, err, expectedErr, "fault proof program should have failed with expected error") + } +} + +func WithL2Claim(claim common.Hash) FixtureInputParam { + return func(f *FixtureInputs) { + f.L2Claim = claim + } +} + +func (env *L2FaultProofEnv) RunFaultProofProgram(t actions.Testing, l2ClaimBlockNum uint64, checkResult CheckResult, fixtureInputParams ...FixtureInputParam) { // Fetch the pre and post output roots for the fault proof. preRoot, err := env.sequencer.RollupClient().OutputAtBlock(t.Ctx(), l2ClaimBlockNum-1) require.NoError(t, err) @@ -134,7 +177,6 @@ func (env *L2FaultProofEnv) RunFaultProofProgram(t actions.Testing, l2ClaimBlock }) err = host.FaultProofProgram(t.Ctx(), env.log, programCfg, withInProcessPrefetcher) tryDumpTestFixture(t, err, t.Name(), env, programCfg) - return err } type TestParam func(p *e2eutils.TestParams) diff --git a/op-e2e/actions/proofs/fixture.go b/op-e2e/actions/proofs/fixture.go index 1ea0b7f83099..cbd30905b2da 100644 --- a/op-e2e/actions/proofs/fixture.go +++ b/op-e2e/actions/proofs/fixture.go @@ -7,6 +7,8 @@ import ( "os" "os/exec" "path/filepath" + "regexp" + "strings" "github.com/ethereum-optimism/optimism/op-e2e/actions" "github.com/ethereum-optimism/optimism/op-program/client/claim" @@ -51,6 +53,7 @@ func tryDumpTestFixture(t actions.Testing, result error, name string, env *L2Fau return } + name = convertToKebabCase(name) rollupCfg := env.sd.RollupCfg l2Genesis := env.sd.L2Cfg @@ -117,3 +120,17 @@ func tryDumpTestFixture(t actions.Testing, result error, name string, env *L2Fau require.NoError(t, cmd.Run(), "Failed to compress witness DB") require.NoError(t, os.RemoveAll(filepath.Join(fixturePath, "witness-db")), "Failed to remove uncompressed witness DB") } + +// Convert to lower kebab case for strings containing `/` +func convertToKebabCase(input string) string { + if !strings.Contains(input, "/") { + return input + } + + // Replace non-alphanumeric characters with underscores + re := regexp.MustCompile(`[^a-zA-Z0-9]+`) + snake := re.ReplaceAllString(input, "-") + + // Convert to lower case + return strings.ToLower(snake) +} diff --git a/op-e2e/actions/proofs/garbage_channel_test.go b/op-e2e/actions/proofs/garbage_channel_test.go index f9dec7f4d666..91ac453337c9 100644 --- a/op-e2e/actions/proofs/garbage_channel_test.go +++ b/op-e2e/actions/proofs/garbage_channel_test.go @@ -1,13 +1,13 @@ package proofs import ( + "fmt" "testing" "github.com/ethereum-optimism/optimism/op-e2e/actions" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-program/client/claim" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/stretchr/testify/require" ) @@ -25,26 +25,13 @@ var garbageKinds = []actions.GarbageKind{ // // channel format ([]Frame): // [f[0 - correct] f_x[1 - bad frame] f[1 - correct]] -func runGarbageChannelTest(gt *testing.T, garbageKind actions.GarbageKind, checkResult func(gt *testing.T, err error), inputParams ...FixtureInputParam) { +func runGarbageChannelTest(gt *testing.T, testCfg *TestCfg[actions.GarbageKind]) { t := actions.NewDefaultTesting(gt) tp := NewTestParams(func(tp *e2eutils.TestParams) { // Set the channel timeout to 10 blocks, 12x lower than the sequencing window. tp.ChannelTimeout = 10 }) - dp := NewDeployParams(t, func(dp *e2eutils.DeployParams) { - genesisBlock := hexutil.Uint64(0) - - // Enable Cancun on L1 & Granite on L2 at genesis - dp.DeployConfig.L1CancunTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisRegolithTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisFjordTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisGraniteTimeOffset = &genesisBlock - }) - bCfg := NewBatcherCfg() - env := NewL2FaultProofEnv(t, tp, dp, bCfg) + env := NewL2FaultProofEnv(t, testCfg, tp, NewBatcherCfg()) includeBatchTx := func(env *L2FaultProofEnv) { // Instruct the batcher to submit the first channel frame to L1, and include the transaction. @@ -90,7 +77,7 @@ func runGarbageChannelTest(gt *testing.T, garbageKind actions.GarbageKind, check expectedSecondFrame := env.batcher.ReadNextOutputFrame(t) // Submit a garbage frame, modified from the expected second frame. - env.batcher.ActL2BatchSubmitGarbageRaw(t, expectedSecondFrame, garbageKind) + env.batcher.ActL2BatchSubmitGarbageRaw(t, expectedSecondFrame, testCfg.Custom) // Include the garbage second frame tx includeBatchTx(env) @@ -108,37 +95,28 @@ func runGarbageChannelTest(gt *testing.T, garbageKind actions.GarbageKind, check require.Equal(t, uint64(NumL2Blocks), l2SafeHead.Number.Uint64()) // Run the FPP on L2 block # NumL2Blocks. - err := env.RunFaultProofProgram(t, NumL2Blocks, inputParams...) - checkResult(gt, err) + env.RunFaultProofProgram(t, NumL2Blocks, testCfg.CheckResult, testCfg.InputParams...) } -func Test_ProgramAction_GarbageChannel_HonestClaim_Granite(gt *testing.T) { - for _, garbageKind := range garbageKinds { - gt.Run(garbageKind.String(), func(t *testing.T) { - runGarbageChannelTest( - t, - garbageKind, - func(gt *testing.T, err error) { - require.NoError(gt, err, "fault proof program should not have failed") - }, - ) - }) - } -} +func Test_ProgramAction_GarbageChannel(gt *testing.T) { + matrix := NewMatrix[actions.GarbageKind]() + defer matrix.Run(gt) -func Test_ProgramAction_GarbageChannel_JunkClaim_Granite(gt *testing.T) { for _, garbageKind := range garbageKinds { - gt.Run(garbageKind.String(), func(t *testing.T) { - runGarbageChannelTest( - t, - garbageKind, - func(gt *testing.T, err error) { - require.ErrorIs(gt, err, claim.ErrClaimNotValid, "fault proof program should have failed") - }, - func(f *FixtureInputs) { - f.L2Claim = common.HexToHash("0xdeadbeef") - }, - ) - }) + matrix.AddTestCase( + fmt.Sprintf("HonestClaim-%s", garbageKind.String()), + garbageKind, + LatestForkOnly, + runGarbageChannelTest, + ExpectNoError(), + ) + matrix.AddTestCase( + fmt.Sprintf("JunkClaim-%s", garbageKind.String()), + garbageKind, + LatestForkOnly, + runGarbageChannelTest, + ExpectError(claim.ErrClaimNotValid), + WithL2Claim(common.HexToHash("0xdeadbeef")), + ) } } diff --git a/op-e2e/actions/proofs/matrix.go b/op-e2e/actions/proofs/matrix.go new file mode 100644 index 000000000000..5814b93838c5 --- /dev/null +++ b/op-e2e/actions/proofs/matrix.go @@ -0,0 +1,97 @@ +package proofs + +import ( + "fmt" + "testing" +) + +type RunTest[cfg any] func(t *testing.T, testCfg *TestCfg[cfg]) + +type TestCfg[cfg any] struct { + Hardfork *Hardfork + CheckResult CheckResult + InputParams []FixtureInputParam + Custom cfg +} + +type TestCase[cfg any] struct { + Name string + Cfg cfg + ForkMatrix ForkMatrix + RunTest RunTest[cfg] + InputParams []FixtureInputParam + CheckResult CheckResult +} + +type TestMatrix[cfg any] struct { + CommonInputParams []FixtureInputParam + TestCases []TestCase[cfg] +} + +func (suite *TestMatrix[cfg]) Run(t *testing.T) { + for _, tc := range suite.TestCases { + for _, fork := range tc.ForkMatrix { + t.Run(fmt.Sprintf("%s-%s", tc.Name, fork.Name), func(t *testing.T) { + testCfg := &TestCfg[cfg]{ + Hardfork: fork, + CheckResult: tc.CheckResult, + InputParams: append(suite.CommonInputParams, tc.InputParams...), + Custom: tc.Cfg, + } + tc.RunTest(t, testCfg) + }) + } + } +} + +func NewMatrix[cfg any]() *TestMatrix[cfg] { + return &TestMatrix[cfg]{} +} + +func (ts *TestMatrix[cfg]) WithCommonInputParams(params ...FixtureInputParam) *TestMatrix[cfg] { + ts.CommonInputParams = params + return ts +} + +func (ts *TestMatrix[cfg]) AddTestCase( + name string, + testCfg cfg, + forkMatrix ForkMatrix, + runTest RunTest[cfg], + checkResult CheckResult, + inputParams ...FixtureInputParam, +) *TestMatrix[cfg] { + ts.TestCases = append(ts.TestCases, TestCase[cfg]{ + Name: name, + Cfg: testCfg, + ForkMatrix: forkMatrix, + RunTest: runTest, + InputParams: inputParams, + CheckResult: checkResult, + }) + return ts +} + +type Hardfork struct { + Name string + Precedence int +} + +type ForkMatrix = []*Hardfork + +// Hardfork definitions +var ( + Regolith = &Hardfork{Name: "Regolith", Precedence: 1} + Canyon = &Hardfork{Name: "Canyon", Precedence: 2} + Delta = &Hardfork{Name: "Delta", Precedence: 3} + Fjord = &Hardfork{Name: "Fjord", Precedence: 4} + Ecotone = &Hardfork{Name: "Ecotone", Precedence: 5} + Granite = &Hardfork{Name: "Granite", Precedence: 6} +) +var Hardforks = ForkMatrix{Regolith, Canyon, Delta, Fjord, Ecotone, Granite} + +var LatestForkOnly = ForkMatrix{Hardforks[len(Hardforks)-1]} + +func NewForkMatrix(forks ...*Hardfork) ForkMatrix { + return append(ForkMatrix{}, forks...) +} diff --git a/op-e2e/actions/proofs/sequence_window_expiry_test.go b/op-e2e/actions/proofs/sequence_window_expiry_test.go index 77f91fe2da50..d62f6795825a 100644 --- a/op-e2e/actions/proofs/sequence_window_expiry_test.go +++ b/op-e2e/actions/proofs/sequence_window_expiry_test.go @@ -4,31 +4,15 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-e2e/actions" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" - "github.com/ethereum-optimism/optimism/op-program/client/claim" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/stretchr/testify/require" ) // Run a test that proves a deposit-only block generated due to sequence window expiry. -func runSequenceWindowExpireTest(gt *testing.T, checkResult func(gt *testing.T, err error), inputParams ...FixtureInputParam) { +func runSequenceWindowExpireTest(gt *testing.T, testCfg *TestCfg[any]) { t := actions.NewDefaultTesting(gt) tp := NewTestParams() - dp := NewDeployParams(t, func(dp *e2eutils.DeployParams) { - genesisBlock := hexutil.Uint64(0) - - // Enable Cancun on L1 & Granite on L2 at genesis - dp.DeployConfig.L1CancunTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisRegolithTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisFjordTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisGraniteTimeOffset = &genesisBlock - }) - bCfg := NewBatcherCfg() - env := NewL2FaultProofEnv(t, tp, dp, bCfg) + env := NewL2FaultProofEnv(t, testCfg, tp, NewBatcherCfg()) // Mine an empty block for gas estimation purposes. env.miner.ActEmptyBlock(t) @@ -59,24 +43,26 @@ func runSequenceWindowExpireTest(gt *testing.T, checkResult func(gt *testing.T, require.Greater(t, l2SafeHead.Number.Uint64(), uint64(0)) // Run the FPP on one of the auto-derived blocks. - err := env.RunFaultProofProgram(t, l2SafeHead.Number.Uint64()/2, inputParams...) - checkResult(gt, err) + env.RunFaultProofProgram(t, l2SafeHead.Number.Uint64()/2, testCfg.CheckResult, testCfg.InputParams...) } -func Test_ProgramAction_SequenceWindowExpired_HonestClaim_Granite(gt *testing.T) { - runSequenceWindowExpireTest(gt, func(gt *testing.T, err error) { - require.NoError(gt, err, "fault proof program should have succeeded") - }) -} +func Test_ProgramAction_SequenceWindowExpired(gt *testing.T) { + matrix := NewMatrix[any]() + defer matrix.Run(gt) -func Test_ProgramAction_SequenceWindowExpired_JunkClaim_Granite(gt *testing.T) { - runSequenceWindowExpireTest( - gt, - func(gt *testing.T, err error) { - require.ErrorIs(gt, err, claim.ErrClaimNotValid, "fault proof program should have failed") - }, - func(f *FixtureInputs) { - f.L2Claim = common.HexToHash("0xdeadbeef") - }, + matrix.AddTestCase( + "HonestClaim", + nil, + LatestForkOnly, + runSequenceWindowExpireTest, + ExpectNoError(), + ) + matrix.AddTestCase( + "JunkClaim", + nil, + LatestForkOnly, + runSequenceWindowExpireTest, + ExpectNoError(), + WithL2Claim(common.HexToHash("0xdeadbeef")), ) } diff --git a/op-e2e/actions/proofs/simple_program_test.go b/op-e2e/actions/proofs/simple_program_test.go index 46de7fd19042..372e20378432 100644 --- a/op-e2e/actions/proofs/simple_program_test.go +++ b/op-e2e/actions/proofs/simple_program_test.go @@ -4,29 +4,14 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-e2e/actions" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-program/client/claim" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/stretchr/testify/require" ) -func Test_ProgramAction_SimpleEmptyChain_HonestClaim_Granite(gt *testing.T) { +func runSimpleProgramTest(gt *testing.T, testCfg *TestCfg[any]) { t := actions.NewDefaultTesting(gt) - tp := NewTestParams() - dp := NewDeployParams(t, func(dp *e2eutils.DeployParams) { - genesisBlock := hexutil.Uint64(0) - - // Enable Cancun on L1 & Granite on L2 at genesis - dp.DeployConfig.L1CancunTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisRegolithTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisFjordTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisGraniteTimeOffset = &genesisBlock - }) - bCfg := NewBatcherCfg() - env := NewL2FaultProofEnv(t, tp, dp, bCfg) + env := NewL2FaultProofEnv(t, testCfg, NewTestParams(), NewBatcherCfg()) // Build an empty block on L2 env.sequencer.ActL2StartBlock(t) @@ -54,56 +39,26 @@ func Test_ProgramAction_SimpleEmptyChain_HonestClaim_Granite(gt *testing.T) { // Ensure the block is marked as safe before we attempt to fault prove it. require.Equal(t, uint64(1), l2SafeHead.Number.Uint64()) - err := env.RunFaultProofProgram(t, l2SafeHead.Number.Uint64()) - require.NoError(t, err, "fault proof program failed") + env.RunFaultProofProgram(t, l2SafeHead.Number.Uint64(), testCfg.CheckResult, testCfg.InputParams...) } -func Test_ProgramAction_SimpleEmptyChain_JunkClaim_Granite(gt *testing.T) { - t := actions.NewDefaultTesting(gt) - tp := NewTestParams() - dp := NewDeployParams(t, func(dp *e2eutils.DeployParams) { - genesisBlock := hexutil.Uint64(0) - - // Enable Cancun on L1 & Granite on L2 at genesis - dp.DeployConfig.L1CancunTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisRegolithTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisFjordTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisGraniteTimeOffset = &genesisBlock - }) - bCfg := NewBatcherCfg() - env := NewL2FaultProofEnv(t, tp, dp, bCfg) - - // Build an empty block on L2 - env.sequencer.ActL2StartBlock(t) - env.sequencer.ActL2EndBlock(t) - - // Instruct the batcher to submit the block to L1, and include the transaction. - env.batcher.ActSubmitAll(t) - env.miner.ActL1StartBlock(12)(t) - env.miner.ActL1IncludeTxByHash(env.batcher.LastSubmitted.Hash())(t) - env.miner.ActL1EndBlock(t) - - // Finalize the block with the batch on L1. - env.miner.ActL1SafeNext(t) - env.miner.ActL1FinalizeNext(t) - - // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. - env.sequencer.ActL1HeadSignal(t) - env.sequencer.ActL2PipelineFull(t) - - l1Head := env.miner.L1Chain().CurrentBlock() - l2SafeHead := env.engine.L2Chain().CurrentSafeBlock() - - // Ensure there is only 1 block on L1. - require.Equal(t, uint64(1), l1Head.Number.Uint64()) - // Ensure the block is marked as safe before we attempt to fault prove it. - require.Equal(t, uint64(1), l2SafeHead.Number.Uint64()) - - err := env.RunFaultProofProgram(t, l2SafeHead.Number.Uint64(), func(f *FixtureInputs) { - f.L2Claim = common.HexToHash("0xdeadbeef") - }) - require.Error(t, err, "fault proof program should have failed") +func Test_ProgramAction_SimpleEmptyChain(gt *testing.T) { + matrix := NewMatrix[any]() + defer matrix.Run(gt) + + matrix.AddTestCase( + "HonestClaim", + nil, + LatestForkOnly, + runSimpleProgramTest, + ExpectNoError(), + ) + matrix.AddTestCase( + "JunkClaim", + nil, + LatestForkOnly, + runSimpleProgramTest, + ExpectError(claim.ErrClaimNotValid), + WithL2Claim(common.HexToHash("0xdeadbeef")), + ) } From d43218599cf1b9abd803d6600d81848f6d2cadc7 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Fri, 13 Sep 2024 17:17:29 +1000 Subject: [PATCH 137/264] op-program: Record the kv format used. (#11900) Automatically use the correct format if it has been recorded. Change the default format to directory. Compatibility with op-challenger is preserved because it now uses the automatic format detection, defaulting to file if not specified (e.g for kona-host). --- .../game/fault/trace/asterisc/provider.go | 9 +-- .../game/fault/trace/cannon/provider.go | 9 +-- .../game/fault/trace/utils/preimage.go | 12 +++- .../game/fault/trace/utils/preimage_test.go | 36 +++++----- op-program/host/config/config.go | 2 +- op-program/host/flags/flags.go | 2 +- op-program/host/host.go | 15 ++-- op-program/host/kvstore/directory.go | 24 +++---- op-program/host/kvstore/directory_test.go | 4 +- op-program/host/kvstore/file.go | 24 +++---- op-program/host/kvstore/file_test.go | 4 +- op-program/host/kvstore/format.go | 69 +++++++++++++++++++ op-program/host/kvstore/format_test.go | 66 ++++++++++++++++++ op-program/host/kvstore/pebble.go | 20 +++--- op-program/host/kvstore/pebble_test.go | 4 +- 15 files changed, 218 insertions(+), 82 deletions(-) create mode 100644 op-program/host/kvstore/format.go create mode 100644 op-program/host/kvstore/format_test.go diff --git a/op-challenger/game/fault/trace/asterisc/provider.go b/op-challenger/game/fault/trace/asterisc/provider.go index 2e9393010364..2ea1b729709e 100644 --- a/op-challenger/game/fault/trace/asterisc/provider.go +++ b/op-challenger/game/fault/trace/asterisc/provider.go @@ -15,6 +15,7 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-program/host/kvstore" + kvtypes "github.com/ethereum-optimism/optimism/op-program/host/types" "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" @@ -44,8 +45,8 @@ func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, vmCfg vm. prestate: asteriscPrestate, generator: vm.NewExecutor(logger, m, cfg, vmCfg, asteriscPrestate, localInputs), gameDepth: gameDepth, - preimageLoader: utils.NewPreimageLoader(func() utils.PreimageSource { - return kvstore.NewFileKV(vm.PreimageDir(dir)) + preimageLoader: utils.NewPreimageLoader(func() (utils.PreimageSource, error) { + return kvstore.NewDiskKV(logger, vm.PreimageDir(dir), kvtypes.DataFormatFile) }), PrestateProvider: prestateProvider, stateConverter: NewStateConverter(), @@ -169,8 +170,8 @@ func NewTraceProviderForTest(logger log.Logger, m vm.Metricer, cfg *config.Confi prestate: cfg.AsteriscAbsolutePreState, generator: vm.NewExecutor(logger, m, cfg.Asterisc, vm.NewOpProgramServerExecutor(), cfg.AsteriscAbsolutePreState, localInputs), gameDepth: gameDepth, - preimageLoader: utils.NewPreimageLoader(func() utils.PreimageSource { - return kvstore.NewFileKV(vm.PreimageDir(dir)) + preimageLoader: utils.NewPreimageLoader(func() (utils.PreimageSource, error) { + return kvstore.NewDiskKV(logger, vm.PreimageDir(dir), kvtypes.DataFormatFile) }), stateConverter: NewStateConverter(), cfg: cfg.Asterisc, diff --git a/op-challenger/game/fault/trace/cannon/provider.go b/op-challenger/game/fault/trace/cannon/provider.go index 4d691e0225b9..823f8c6d814b 100644 --- a/op-challenger/game/fault/trace/cannon/provider.go +++ b/op-challenger/game/fault/trace/cannon/provider.go @@ -10,6 +10,7 @@ import ( "os" "path/filepath" + kvtypes "github.com/ethereum-optimism/optimism/op-program/host/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" @@ -45,8 +46,8 @@ func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, vmCfg vm. prestate: prestate, generator: vm.NewExecutor(logger, m, cfg, vmCfg, prestate, localInputs), gameDepth: gameDepth, - preimageLoader: utils.NewPreimageLoader(func() utils.PreimageSource { - return kvstore.NewFileKV(vm.PreimageDir(dir)) + preimageLoader: utils.NewPreimageLoader(func() (utils.PreimageSource, error) { + return kvstore.NewDiskKV(logger, vm.PreimageDir(dir), kvtypes.DataFormatFile) }), PrestateProvider: prestateProvider, stateConverter: &StateConverter{}, @@ -168,8 +169,8 @@ func NewTraceProviderForTest(logger log.Logger, m vm.Metricer, cfg *config.Confi prestate: cfg.CannonAbsolutePreState, generator: vm.NewExecutor(logger, m, cfg.Cannon, vm.NewOpProgramServerExecutor(), cfg.CannonAbsolutePreState, localInputs), gameDepth: gameDepth, - preimageLoader: utils.NewPreimageLoader(func() utils.PreimageSource { - return kvstore.NewFileKV(vm.PreimageDir(dir)) + preimageLoader: utils.NewPreimageLoader(func() (utils.PreimageSource, error) { + return kvstore.NewDiskKV(logger, vm.PreimageDir(dir), kvtypes.DataFormatFile) }), stateConverter: NewStateConverter(), cfg: cfg.Cannon, diff --git a/op-challenger/game/fault/trace/utils/preimage.go b/op-challenger/game/fault/trace/utils/preimage.go index 6428821ec3fd..5b61a70adb9f 100644 --- a/op-challenger/game/fault/trace/utils/preimage.go +++ b/op-challenger/game/fault/trace/utils/preimage.go @@ -31,7 +31,7 @@ type PreimageSource interface { Close() error } -type PreimageSourceCreator func() PreimageSource +type PreimageSourceCreator func() (PreimageSource, error) type PreimageLoader struct { makeSource PreimageSourceCreator @@ -61,7 +61,10 @@ func (l *PreimageLoader) loadBlobPreimage(proof *ProofData) (*types.PreimageOrac // The key for a blob field element is a keccak hash of commitment++fieldElementIndex. // First retrieve the preimage of the key as a keccak hash so we have the commitment and required field element inputsKey := preimage.Keccak256Key(proof.OracleKey).PreimageKey() - source := l.makeSource() + source, err := l.makeSource() + if err != nil { + return nil, fmt.Errorf("failed to open preimage store: %w", err) + } defer source.Close() inputs, err := source.Get(inputsKey) if err != nil { @@ -111,7 +114,10 @@ func (l *PreimageLoader) loadBlobPreimage(proof *ProofData) (*types.PreimageOrac func (l *PreimageLoader) loadPrecompilePreimage(proof *ProofData) (*types.PreimageOracleData, error) { inputKey := preimage.Keccak256Key(proof.OracleKey).PreimageKey() - source := l.makeSource() + source, err := l.makeSource() + if err != nil { + return nil, fmt.Errorf("failed to open preimage store: %w", err) + } defer source.Close() input, err := source.Get(inputKey) if err != nil { diff --git a/op-challenger/game/fault/trace/utils/preimage_test.go b/op-challenger/game/fault/trace/utils/preimage_test.go index cc4b8fa0d14b..2b5552f28e0c 100644 --- a/op-challenger/game/fault/trace/utils/preimage_test.go +++ b/op-challenger/game/fault/trace/utils/preimage_test.go @@ -21,8 +21,8 @@ import ( func TestPreimageLoader_NoPreimage(t *testing.T) { kv := kvstore.NewMemKV() - loader := NewPreimageLoader(func() PreimageSource { - return kv + loader := NewPreimageLoader(func() (PreimageSource, error) { + return kv, nil }) actual, err := loader.LoadPreimage(&ProofData{}) require.NoError(t, err) @@ -31,8 +31,8 @@ func TestPreimageLoader_NoPreimage(t *testing.T) { func TestPreimageLoader_LocalPreimage(t *testing.T) { kv := kvstore.NewMemKV() - loader := NewPreimageLoader(func() PreimageSource { - return kv + loader := NewPreimageLoader(func() (PreimageSource, error) { + return kv, nil }) proof := &ProofData{ OracleKey: common.Hash{byte(preimage.LocalKeyType), 0xaa, 0xbb}.Bytes(), @@ -55,8 +55,8 @@ func TestPreimageLoader_SimpleTypes(t *testing.T) { keyType := keyType t.Run(fmt.Sprintf("type-%v", keyType), func(t *testing.T) { kv := kvstore.NewMemKV() - loader := NewPreimageLoader(func() PreimageSource { - return kv + loader := NewPreimageLoader(func() (PreimageSource, error) { + return kv, nil }) proof := &ProofData{ OracleKey: common.Hash{byte(keyType), 0xaa, 0xbb}.Bytes(), @@ -99,8 +99,8 @@ func TestPreimageLoader_BlobPreimage(t *testing.T) { t.Run("NoKeyPreimage", func(t *testing.T) { kv := kvstore.NewMemKV() - loader := NewPreimageLoader(func() PreimageSource { - return kv + loader := NewPreimageLoader(func() (PreimageSource, error) { + return kv, nil }) proof := &ProofData{ OracleKey: common.Hash{byte(preimage.BlobKeyType), 0xaf}.Bytes(), @@ -113,8 +113,8 @@ func TestPreimageLoader_BlobPreimage(t *testing.T) { t.Run("InvalidKeyPreimage", func(t *testing.T) { kv := kvstore.NewMemKV() - loader := NewPreimageLoader(func() PreimageSource { - return kv + loader := NewPreimageLoader(func() (PreimageSource, error) { + return kv, nil }) proof := &ProofData{ OracleKey: common.Hash{byte(preimage.BlobKeyType), 0xad}.Bytes(), @@ -128,8 +128,8 @@ func TestPreimageLoader_BlobPreimage(t *testing.T) { t.Run("MissingBlobs", func(t *testing.T) { kv := kvstore.NewMemKV() - loader := NewPreimageLoader(func() PreimageSource { - return kv + loader := NewPreimageLoader(func() (PreimageSource, error) { + return kv, nil }) proof := &ProofData{ OracleKey: common.Hash{byte(preimage.BlobKeyType), 0xae}.Bytes(), @@ -143,8 +143,8 @@ func TestPreimageLoader_BlobPreimage(t *testing.T) { t.Run("Valid", func(t *testing.T) { kv := kvstore.NewMemKV() - loader := NewPreimageLoader(func() PreimageSource { - return kv + loader := NewPreimageLoader(func() (PreimageSource, error) { + return kv, nil }) storeBlob(t, kv, gokzg4844.KZGCommitment(commitment), gokzg4844.Blob(blob)) actual, err := loader.LoadPreimage(proof) @@ -178,16 +178,16 @@ func TestPreimageLoader_PrecompilePreimage(t *testing.T) { t.Run("NoInputPreimage", func(t *testing.T) { kv := kvstore.NewMemKV() - loader := NewPreimageLoader(func() PreimageSource { - return kv + loader := NewPreimageLoader(func() (PreimageSource, error) { + return kv, nil }) _, err := loader.LoadPreimage(proof) require.ErrorIs(t, err, kvstore.ErrNotFound) }) t.Run("Valid", func(t *testing.T) { kv := kvstore.NewMemKV() - loader := NewPreimageLoader(func() PreimageSource { - return kv + loader := NewPreimageLoader(func() (PreimageSource, error) { + return kv, nil }) require.NoError(t, kv.Put(preimage.Keccak256Key(proof.OracleKey).PreimageKey(), input)) actual, err := loader.LoadPreimage(proof) diff --git a/op-program/host/config/config.go b/op-program/host/config/config.go index 1478fde5e25d..c04f959a8b7d 100644 --- a/op-program/host/config/config.go +++ b/op-program/host/config/config.go @@ -138,7 +138,7 @@ func NewConfig( L2ClaimBlockNumber: l2ClaimBlockNum, L1RPCKind: sources.RPCKindStandard, IsCustomChainConfig: isCustomConfig, - DataFormat: types.DataFormatFile, + DataFormat: types.DataFormatDirectory, } } diff --git a/op-program/host/flags/flags.go b/op-program/host/flags/flags.go index c46422876d63..5eb633c7202f 100644 --- a/op-program/host/flags/flags.go +++ b/op-program/host/flags/flags.go @@ -40,7 +40,7 @@ var ( Name: "data.format", Usage: fmt.Sprintf("Format to use for preimage data storage. Available formats: %s", openum.EnumString(types.SupportedDataFormats)), EnvVars: prefixEnvVars("DATA_FORMAT"), - Value: string(types.DataFormatFile), + Value: string(types.DataFormatDirectory), } L2NodeAddr = &cli.StringFlag{ Name: "l2", diff --git a/op-program/host/host.go b/op-program/host/host.go index e71bf6db6564..9a7990c9491e 100644 --- a/op-program/host/host.go +++ b/op-program/host/host.go @@ -16,7 +16,6 @@ import ( "github.com/ethereum-optimism/optimism/op-program/host/flags" "github.com/ethereum-optimism/optimism/op-program/host/kvstore" "github.com/ethereum-optimism/optimism/op-program/host/prefetcher" - "github.com/ethereum-optimism/optimism/op-program/host/types" opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/client" "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" @@ -175,20 +174,14 @@ func PreimageServer(ctx context.Context, logger log.Logger, cfg *config.Config, logger.Info("Using in-memory storage") kv = kvstore.NewMemKV() } else { - logger.Info("Creating disk storage", "datadir", cfg.DataDir, "format", cfg.DataFormat) if err := os.MkdirAll(cfg.DataDir, 0755); err != nil { return fmt.Errorf("creating datadir: %w", err) } - switch cfg.DataFormat { - case types.DataFormatFile: - kv = kvstore.NewFileKV(cfg.DataDir) - case types.DataFormatDirectory: - kv = kvstore.NewDirectoryKV(cfg.DataDir) - case types.DataFormatPebble: - kv = kvstore.NewPebbleKV(cfg.DataDir) - default: - return fmt.Errorf("invalid data format: %s", cfg.DataFormat) + store, err := kvstore.NewDiskKV(logger, cfg.DataDir, cfg.DataFormat) + if err != nil { + return fmt.Errorf("creating kvstore: %w", err) } + kv = store } var ( diff --git a/op-program/host/kvstore/directory.go b/op-program/host/kvstore/directory.go index 28ef957b0f27..4176a6453d64 100644 --- a/op-program/host/kvstore/directory.go +++ b/op-program/host/kvstore/directory.go @@ -12,30 +12,30 @@ import ( "github.com/ethereum/go-ethereum/common" ) -// DirectoryKV is a disk-backed key-value store, every key-value pair is a hex-encoded .txt file, with the value as content. -// DirectoryKV is safe for concurrent use with a single DirectoryKV instance. -// DirectoryKV is safe for concurrent use between different DirectoryKV instances of the same disk directory as long as the +// directoryKV is a disk-backed key-value store, every key-value pair is a hex-encoded .txt file, with the value as content. +// directoryKV is safe for concurrent use with a single directoryKV instance. +// directoryKV is safe for concurrent use between different directoryKV instances of the same disk directory as long as the // file system supports atomic renames. -type DirectoryKV struct { +type directoryKV struct { sync.RWMutex path string } -// NewDirectoryKV creates a DirectoryKV that puts/gets pre-images as files in the given directory path. +// newDirectoryKV creates a directoryKV that puts/gets pre-images as files in the given directory path. // The path must exist, or subsequent Put/Get calls will error when it does not. -func NewDirectoryKV(path string) *DirectoryKV { - return &DirectoryKV{path: path} +func newDirectoryKV(path string) *directoryKV { + return &directoryKV{path: path} } // pathKey returns the file path for the given key. // This is composed of the first characters of the non-0x-prefixed hex key as a directory, and the rest as the file name. -func (d *DirectoryKV) pathKey(k common.Hash) string { +func (d *directoryKV) pathKey(k common.Hash) string { key := k.String() dir, name := key[2:6], key[6:] return path.Join(d.path, dir, name+".txt") } -func (d *DirectoryKV) Put(k common.Hash, v []byte) error { +func (d *directoryKV) Put(k common.Hash, v []byte) error { d.Lock() defer d.Unlock() f, err := openTempFile(d.path, k.String()+".txt.*") @@ -61,7 +61,7 @@ func (d *DirectoryKV) Put(k common.Hash, v []byte) error { return nil } -func (d *DirectoryKV) Get(k common.Hash) ([]byte, error) { +func (d *directoryKV) Get(k common.Hash) ([]byte, error) { d.RLock() defer d.RUnlock() f, err := os.OpenFile(d.pathKey(k), os.O_RDONLY, filePermission) @@ -79,8 +79,8 @@ func (d *DirectoryKV) Get(k common.Hash) ([]byte, error) { return hex.DecodeString(string(dat)) } -func (d *DirectoryKV) Close() error { +func (d *directoryKV) Close() error { return nil } -var _ KV = (*DirectoryKV)(nil) +var _ KV = (*directoryKV)(nil) diff --git a/op-program/host/kvstore/directory_test.go b/op-program/host/kvstore/directory_test.go index efbf0ea20c5a..0a76f5843b53 100644 --- a/op-program/host/kvstore/directory_test.go +++ b/op-program/host/kvstore/directory_test.go @@ -10,7 +10,7 @@ import ( func TestDirectoryKV(t *testing.T) { tmp := t.TempDir() // automatically removed by testing cleanup - kv := NewDirectoryKV(tmp) + kv := newDirectoryKV(tmp) t.Cleanup(func() { // Can't use defer because kvTest runs tests in parallel. require.NoError(t, kv.Close()) }) @@ -20,7 +20,7 @@ func TestDirectoryKV(t *testing.T) { func TestDirectoryKV_CreateMissingDirectory(t *testing.T) { tmp := t.TempDir() dir := filepath.Join(tmp, "data") - kv := NewDirectoryKV(dir) + kv := newDirectoryKV(dir) defer kv.Close() val := []byte{1, 2, 3, 4} key := crypto.Keccak256Hash(val) diff --git a/op-program/host/kvstore/file.go b/op-program/host/kvstore/file.go index 353bcedfe7c4..9116f83df720 100644 --- a/op-program/host/kvstore/file.go +++ b/op-program/host/kvstore/file.go @@ -15,26 +15,26 @@ import ( // read/write mode for user/group/other, not executable. const filePermission = 0666 -// FileKV is a disk-backed key-value store, every key-value pair is a hex-encoded .txt file, with the value as content. -// FileKV is safe for concurrent use with a single FileKV instance. -// FileKV is safe for concurrent use between different FileKV instances of the same disk directory as long as the +// fileKV is a disk-backed key-value store, every key-value pair is a hex-encoded .txt file, with the value as content. +// fileKV is safe for concurrent use with a single fileKV instance. +// fileKV is safe for concurrent use between different fileKV instances of the same disk directory as long as the // file system supports atomic renames. -type FileKV struct { +type fileKV struct { sync.RWMutex path string } -// NewFileKV creates a FileKV that puts/gets pre-images as files in the given directory path. +// newFileKV creates a fileKV that puts/gets pre-images as files in the given directory path. // The path must exist, or subsequent Put/Get calls will error when it does not. -func NewFileKV(path string) *FileKV { - return &FileKV{path: path} +func newFileKV(path string) *fileKV { + return &fileKV{path: path} } -func (d *FileKV) pathKey(k common.Hash) string { +func (d *fileKV) pathKey(k common.Hash) string { return path.Join(d.path, k.String()+".txt") } -func (d *FileKV) Put(k common.Hash, v []byte) error { +func (d *fileKV) Put(k common.Hash, v []byte) error { d.Lock() defer d.Unlock() f, err := openTempFile(d.path, k.String()+".txt.*") @@ -72,7 +72,7 @@ func openTempFile(dir string, nameTemplate string) (*os.File, error) { return f, nil } -func (d *FileKV) Get(k common.Hash) ([]byte, error) { +func (d *fileKV) Get(k common.Hash) ([]byte, error) { d.RLock() defer d.RUnlock() f, err := os.OpenFile(d.pathKey(k), os.O_RDONLY, filePermission) @@ -90,8 +90,8 @@ func (d *FileKV) Get(k common.Hash) ([]byte, error) { return hex.DecodeString(string(dat)) } -func (d *FileKV) Close() error { +func (d *fileKV) Close() error { return nil } -var _ KV = (*FileKV)(nil) +var _ KV = (*fileKV)(nil) diff --git a/op-program/host/kvstore/file_test.go b/op-program/host/kvstore/file_test.go index 7dc34b708cfa..cb96039bc2ce 100644 --- a/op-program/host/kvstore/file_test.go +++ b/op-program/host/kvstore/file_test.go @@ -10,7 +10,7 @@ import ( func TestFileKV(t *testing.T) { tmp := t.TempDir() // automatically removed by testing cleanup - kv := NewFileKV(tmp) + kv := newFileKV(tmp) t.Cleanup(func() { // Can't use defer because kvTest runs tests in parallel. require.NoError(t, kv.Close()) }) @@ -20,7 +20,7 @@ func TestFileKV(t *testing.T) { func TestFileKV_CreateMissingDirectory(t *testing.T) { tmp := t.TempDir() dir := filepath.Join(tmp, "data") - kv := NewFileKV(dir) + kv := newFileKV(dir) defer kv.Close() val := []byte{1, 2, 3, 4} key := crypto.Keccak256Hash(val) diff --git a/op-program/host/kvstore/format.go b/op-program/host/kvstore/format.go new file mode 100644 index 000000000000..08cbc1b18c5d --- /dev/null +++ b/op-program/host/kvstore/format.go @@ -0,0 +1,69 @@ +package kvstore + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "slices" + + "github.com/ethereum-optimism/optimism/op-program/host/types" + "github.com/ethereum/go-ethereum/log" +) + +const formatFilename = "kvformat" + +var ( + ErrFormatUnavailable = errors.New("format unavailable") + ErrUnsupportedFormat = errors.New("unsupported format") +) + +func recordKVFormat(dir string, format types.DataFormat) error { + return os.WriteFile(filepath.Join(dir, formatFilename), []byte(format), 0o644) +} + +func readKVFormat(dir string) (types.DataFormat, error) { + data, err := os.ReadFile(filepath.Join(dir, formatFilename)) + if errors.Is(err, os.ErrNotExist) { + return "", ErrFormatUnavailable + } else if err != nil { + return "", fmt.Errorf("failed to read kv format: %w", err) + } + format := types.DataFormat(data) + if !slices.Contains(types.SupportedDataFormats, format) { + return "", fmt.Errorf("%w: %s", ErrUnsupportedFormat, format) + } + return format, nil +} + +// NewDiskKV creates a new KV implementation. If the specified directly contains an existing KV store +// that has the format recorded, the recorded format is used ensuring compatibility with the existing data. +// If the directory does not contain existing data or doesn't have the format recorded, defaultFormat is used +// which may result in the existing data being unused. +// If the existing data records a format that is not supported, an error is returned. +// The format is automatically recorded if it wasn't previously stored. +func NewDiskKV(logger log.Logger, dir string, defaultFormat types.DataFormat) (KV, error) { + format, err := readKVFormat(dir) + if errors.Is(err, ErrFormatUnavailable) { + format = defaultFormat + logger.Info("Creating disk storage", "datadir", dir, "format", format) + if err := recordKVFormat(dir, format); err != nil { + return nil, fmt.Errorf("failed to record new kv store format: %w", err) + } + } else if err != nil { + return nil, err + } else { + logger.Info("Using existing disk storage", "datadir", dir, "format", format) + } + + switch format { + case types.DataFormatFile: + return newFileKV(dir), nil + case types.DataFormatDirectory: + return newDirectoryKV(dir), nil + case types.DataFormatPebble: + return newPebbleKV(dir), nil + default: + return nil, fmt.Errorf("invalid data format: %s", format) + } +} diff --git a/op-program/host/kvstore/format_test.go b/op-program/host/kvstore/format_test.go new file mode 100644 index 000000000000..8be0368bd09c --- /dev/null +++ b/op-program/host/kvstore/format_test.go @@ -0,0 +1,66 @@ +package kvstore + +import ( + "fmt" + "testing" + + "github.com/ethereum-optimism/optimism/op-program/host/types" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +func TestRecordAndReadKVFormat(t *testing.T) { + for _, format := range types.SupportedDataFormats { + format := format + t.Run(string(format), func(t *testing.T) { + dir := t.TempDir() + require.NoError(t, recordKVFormat(dir, format)) + actual, err := readKVFormat(dir) + require.NoError(t, err) + require.Equal(t, format, actual) + }) + } + + t.Run("Unsupported", func(t *testing.T) { + dir := t.TempDir() + require.NoError(t, recordKVFormat(dir, "nope")) + _, err := readKVFormat(dir) + require.ErrorIs(t, err, ErrUnsupportedFormat) + }) + + t.Run("NotRecorded", func(t *testing.T) { + dir := t.TempDir() + _, err := readKVFormat(dir) + require.ErrorIs(t, err, ErrFormatUnavailable) + }) +} + +func TestNewDiskKV(t *testing.T) { + for _, existingFormat := range types.SupportedDataFormats { + existingFormat := existingFormat + + for _, specifiedFormat := range types.SupportedDataFormats { + specifiedFormat := specifiedFormat + t.Run(fmt.Sprintf("%v->%v", existingFormat, specifiedFormat), func(t *testing.T) { + dir := t.TempDir() + logger := testlog.Logger(t, log.LevelError) + hash := common.Hash{0xaa} + value := []byte{1, 2, 3, 4, 5, 6} + kv1, err := NewDiskKV(logger, dir, existingFormat) + require.NoError(t, err) + require.NoError(t, kv1.Put(hash, value)) + require.NoError(t, kv1.Close()) + + // Should use existing format + kv2, err := NewDiskKV(logger, dir, specifiedFormat) + require.NoError(t, err) + actual, err := kv2.Get(hash) + require.NoError(t, err) + require.Equal(t, value, actual) + require.NoError(t, kv2.Close()) + }) + } + } +} diff --git a/op-program/host/kvstore/pebble.go b/op-program/host/kvstore/pebble.go index fc68d07853c9..5bc7fcc9f23a 100644 --- a/op-program/host/kvstore/pebble.go +++ b/op-program/host/kvstore/pebble.go @@ -10,16 +10,16 @@ import ( "github.com/ethereum/go-ethereum/common" ) -// PebbleKV is a disk-backed key-value store, with PebbleDB as the underlying DBMS. -// PebbleKV is safe for concurrent use with a single PebbleKV instance. -type PebbleKV struct { +// pebbleKV is a disk-backed key-value store, with PebbleDB as the underlying DBMS. +// pebbleKV is safe for concurrent use with a single pebbleKV instance. +type pebbleKV struct { sync.RWMutex db *pebble.DB } -// NewPebbleKV creates a PebbleKV that puts/gets pre-images as files in the given directory path. +// newPebbleKV creates a pebbleKV that puts/gets pre-images as files in the given directory path. // The path must exist, or subsequent Put/Get calls will error when it does not. -func NewPebbleKV(path string) *PebbleKV { +func newPebbleKV(path string) *pebbleKV { opts := &pebble.Options{ Cache: pebble.NewCache(int64(32 * 1024 * 1024)), MaxConcurrentCompactions: runtime.NumCPU, @@ -32,16 +32,16 @@ func NewPebbleKV(path string) *PebbleKV { panic(fmt.Errorf("failed to open pebbledb at %s: %w", path, err)) } - return &PebbleKV{db: db} + return &pebbleKV{db: db} } -func (d *PebbleKV) Put(k common.Hash, v []byte) error { +func (d *pebbleKV) Put(k common.Hash, v []byte) error { d.Lock() defer d.Unlock() return d.db.Set(k.Bytes(), v, pebble.NoSync) } -func (d *PebbleKV) Get(k common.Hash) ([]byte, error) { +func (d *pebbleKV) Get(k common.Hash) ([]byte, error) { d.RLock() defer d.RUnlock() @@ -58,11 +58,11 @@ func (d *PebbleKV) Get(k common.Hash) ([]byte, error) { return ret, nil } -func (d *PebbleKV) Close() error { +func (d *pebbleKV) Close() error { d.Lock() defer d.Unlock() return d.db.Close() } -var _ KV = (*PebbleKV)(nil) +var _ KV = (*pebbleKV)(nil) diff --git a/op-program/host/kvstore/pebble_test.go b/op-program/host/kvstore/pebble_test.go index 28aab0c58248..e009d6797021 100644 --- a/op-program/host/kvstore/pebble_test.go +++ b/op-program/host/kvstore/pebble_test.go @@ -10,7 +10,7 @@ import ( func TestPebbleKV(t *testing.T) { tmp := t.TempDir() // automatically removed by testing cleanup - kv := NewPebbleKV(tmp) + kv := newPebbleKV(tmp) t.Cleanup(func() { // Can't use defer because kvTest runs tests in parallel. require.NoError(t, kv.Close()) }) @@ -20,7 +20,7 @@ func TestPebbleKV(t *testing.T) { func TestPebbleKV_CreateMissingDirectory(t *testing.T) { tmp := t.TempDir() dir := filepath.Join(tmp, "data") - kv := NewPebbleKV(dir) + kv := newPebbleKV(dir) defer kv.Close() val := []byte{1, 2, 3, 4} key := crypto.Keccak256Hash(val) From 3ba35fab6a69214739dd91cdd412f5437cdca4d5 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 13 Sep 2024 13:32:41 -0400 Subject: [PATCH 138/264] feat: Scaffolding for DeployAuthSystemInput (#11889) * feat: Scaffolding for DeployAuthSystemInput * fix: Remove undefined import * feat: Address feedback --- .../scripts/DeployAuthSystem.s.sol | 54 ++++++++++++++++++ .../test/DeployAuthSystem.t.sol | 57 +++++++++++++++++++ .../fixtures/test-deploy-auth-system-in.toml | 11 ++++ 3 files changed, 122 insertions(+) create mode 100644 packages/contracts-bedrock/scripts/DeployAuthSystem.s.sol create mode 100644 packages/contracts-bedrock/test/DeployAuthSystem.t.sol create mode 100644 packages/contracts-bedrock/test/fixtures/test-deploy-auth-system-in.toml diff --git a/packages/contracts-bedrock/scripts/DeployAuthSystem.s.sol b/packages/contracts-bedrock/scripts/DeployAuthSystem.s.sol new file mode 100644 index 000000000000..99b079e3e578 --- /dev/null +++ b/packages/contracts-bedrock/scripts/DeployAuthSystem.s.sol @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Script } from "forge-std/Script.sol"; +import { CommonBase } from "forge-std/Base.sol"; +import { stdToml } from "forge-std/StdToml.sol"; + +import { GnosisSafe as Safe } from "safe-contracts/GnosisSafe.sol"; + +import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; +import { Solarray } from "scripts/libraries/Solarray.sol"; + +// This file follows the pattern of Superchain.s.sol. Refer to that file for more details. +contract DeployAuthSystemInput is CommonBase { + using stdToml for string; + + // Generic safe inputs + // Note: these will need to be replaced with settings specific to the different Safes in the system. + uint256 internal _threshold; + address[] internal _owners; + + function set(bytes4 _sel, uint256 _value) public { + if (_sel == this.threshold.selector) _threshold = _value; + else revert("DeployAuthSystemInput: unknown selector"); + } + + function set(bytes4 _sel, address[] memory _addrs) public { + if (_sel == this.owners.selector) { + require(_owners.length == 0, "DeployAuthSystemInput: owners already set"); + for (uint256 i = 0; i < _addrs.length; i++) { + _owners.push(_addrs[i]); + } + } else { + revert("DeployAuthSystemInput: unknown selector"); + } + } + + function loadInputFile(string memory _infile) public { + string memory toml = vm.readFile(_infile); + + set(this.threshold.selector, toml.readUint(".safe.threshold")); + set(this.owners.selector, toml.readAddressArray(".safe.owners")); + } + + function threshold() public view returns (uint256) { + require(_threshold != 0, "DeployAuthSystemInput: threshold not set"); + return _threshold; + } + + function owners() public view returns (address[] memory) { + require(_owners.length != 0, "DeployAuthSystemInput: owners not set"); + return _owners; + } +} diff --git a/packages/contracts-bedrock/test/DeployAuthSystem.t.sol b/packages/contracts-bedrock/test/DeployAuthSystem.t.sol new file mode 100644 index 000000000000..eca6724d904a --- /dev/null +++ b/packages/contracts-bedrock/test/DeployAuthSystem.t.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Test } from "forge-std/Test.sol"; +import { stdToml } from "forge-std/StdToml.sol"; +import { Solarray } from "scripts/libraries/Solarray.sol"; + +import { DeployAuthSystemInput } from "scripts/DeployAuthSystem.s.sol"; + +contract DeployAuthSystemInput_Test is Test { + DeployAuthSystemInput dasi; + + uint256 threshold = 5; + address[] owners; + + function setUp() public { + dasi = new DeployAuthSystemInput(); + address[] memory _owners = Solarray.addresses( + 0x1111111111111111111111111111111111111111, + 0x2222222222222222222222222222222222222222, + 0x3333333333333333333333333333333333333333, + 0x4444444444444444444444444444444444444444, + 0x5555555555555555555555555555555555555555, + 0x6666666666666666666666666666666666666666, + 0x7777777777777777777777777777777777777777 + ); + + for (uint256 i = 0; i < _owners.length; i++) { + owners.push(_owners[i]); + } + } + + function test_loadInputFile_succeeds() public { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/test-deploy-auth-system-in.toml"); + + dasi.loadInputFile(path); + + assertEq(threshold, dasi.threshold(), "100"); + assertEq(owners.length, dasi.owners().length, "200"); + } + + function test_getters_whenNotSet_revert() public { + vm.expectRevert("DeployAuthSystemInput: threshold not set"); + dasi.threshold(); + + vm.expectRevert("DeployAuthSystemInput: owners not set"); + dasi.owners(); + } + + function test_setters_ownerAlreadySet_revert() public { + dasi.set(dasi.owners.selector, owners); + + vm.expectRevert("DeployAuthSystemInput: owners already set"); + dasi.set(dasi.owners.selector, owners); + } +} diff --git a/packages/contracts-bedrock/test/fixtures/test-deploy-auth-system-in.toml b/packages/contracts-bedrock/test/fixtures/test-deploy-auth-system-in.toml new file mode 100644 index 000000000000..4f0df83e1af2 --- /dev/null +++ b/packages/contracts-bedrock/test/fixtures/test-deploy-auth-system-in.toml @@ -0,0 +1,11 @@ +[safe] +threshold = 5 +owners = [ + "0x1111111111111111111111111111111111111111", + "0x2222222222222222222222222222222222222222", + "0x3333333333333333333333333333333333333333", + "0x4444444444444444444444444444444444444444", + "0x5555555555555555555555555555555555555555", + "0x6666666666666666666666666666666666666666", + "0x7777777777777777777777777777777777777777" +] From 3056348b21a07e584225310bbc27f1adce5ca2a9 Mon Sep 17 00:00:00 2001 From: protolambda Date: Fri, 13 Sep 2024 14:01:58 -0600 Subject: [PATCH 139/264] interop: interopgen v2 using OPSM (#11702) * op-chain-ops/interopgen: OPSM powered interop genesis * ci: make forge scripts available to op-e2e * op-chain-ops: address interopgen review comments --- .circleci/config.yml | 4 +- op-chain-ops/genesis/config.go | 12 +- op-chain-ops/genesis/withdrawal_network.go | 7 + op-chain-ops/interopgen/configs.go | 108 ++++++ op-chain-ops/interopgen/deploy.go | 338 ++++++++++++++++++ .../interopgen/deployers/implementations.go | 101 ++++++ .../interopgen/deployers/l2genesis.go | 55 +++ op-chain-ops/interopgen/deployers/opchain.go | 87 +++++ .../interopgen/deployers/preinstalls.go | 24 ++ .../interopgen/deployers/superchain.go | 70 ++++ op-chain-ops/interopgen/deployments.go | 68 ++++ op-chain-ops/interopgen/outputs.go | 21 ++ op-chain-ops/interopgen/recipe.go | 272 ++++++++++++++ op-e2e/interop_recipe_test.go | 46 +++ .../scripts/DeployImplementations.s.sol | 4 +- .../contracts-bedrock/scripts/L2Genesis.s.sol | 56 ++- .../scripts/SetPreinstalls.s.sol | 50 +++ packages/contracts-bedrock/semver-lock.json | 4 +- .../src/L1/SystemConfigInterop.sol | 2 +- 19 files changed, 1281 insertions(+), 48 deletions(-) create mode 100644 op-chain-ops/interopgen/configs.go create mode 100644 op-chain-ops/interopgen/deploy.go create mode 100644 op-chain-ops/interopgen/deployers/implementations.go create mode 100644 op-chain-ops/interopgen/deployers/l2genesis.go create mode 100644 op-chain-ops/interopgen/deployers/opchain.go create mode 100644 op-chain-ops/interopgen/deployers/preinstalls.go create mode 100644 op-chain-ops/interopgen/deployers/superchain.go create mode 100644 op-chain-ops/interopgen/deployments.go create mode 100644 op-chain-ops/interopgen/outputs.go create mode 100644 op-chain-ops/interopgen/recipe.go create mode 100644 op-e2e/interop_recipe_test.go create mode 100644 packages/contracts-bedrock/scripts/SetPreinstalls.s.sol diff --git a/.circleci/config.yml b/.circleci/config.yml index 0efd7832b79a..d96b1051514a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1591,8 +1591,8 @@ workflows: - contracts-bedrock-build: name: contracts-bedrock-build build_command: | - forge build --skip test --skip scripts - forge build ./scripts/deploy/Deploy.s.sol + # Note: scripts are included, to be available to op-e2e + forge build --skip test - contracts-bedrock-tests: # Test everything except PreimageOracle.t.sol since it's slow. name: contracts-bedrock-tests diff --git a/op-chain-ops/genesis/config.go b/op-chain-ops/genesis/config.go index 0fc628727fe6..9b71fa6649a9 100644 --- a/op-chain-ops/genesis/config.go +++ b/op-chain-ops/genesis/config.go @@ -230,9 +230,9 @@ type GasPriceOracleDeployConfig struct { // Deprecated: Since Ecotone, this field is superseded by GasPriceOracleBaseFeeScalar and GasPriceOracleBlobBaseFeeScalar. GasPriceOracleScalar uint64 `json:"gasPriceOracleScalar"` // GasPriceOracleBaseFeeScalar represents the value of the base fee scalar used for fee calculations. - GasPriceOracleBaseFeeScalar uint32 `json:"gasPriceOracleBaseFeeScalar"` + GasPriceOracleBaseFeeScalar uint32 `json:"gasPriceOracleBaseFeeScalar" evm:"basefeeScalar"` // GasPriceOracleBlobBaseFeeScalar represents the value of the blob base fee scalar used for fee calculations. - GasPriceOracleBlobBaseFeeScalar uint32 `json:"gasPriceOracleBlobBaseFeeScalar"` + GasPriceOracleBlobBaseFeeScalar uint32 `json:"gasPriceOracleBlobBaseFeeScalar" evm:"blobbasefeeScalar"` } var _ ConfigChecker = (*GasPriceOracleDeployConfig)(nil) @@ -282,7 +282,7 @@ func (d *GasTokenDeployConfig) Check(log log.Logger) error { // OperatorDeployConfig configures the hot-key addresses for operations such as sequencing and batch-submission. type OperatorDeployConfig struct { // P2PSequencerAddress is the address of the key the sequencer uses to sign blocks on the P2P layer. - P2PSequencerAddress common.Address `json:"p2pSequencerAddress"` + P2PSequencerAddress common.Address `json:"p2pSequencerAddress" evm:"p2pSequencerAddress"` // BatchSenderAddress represents the initial sequencer account that authorizes batches. // Transactions sent from this account to the batch inbox address are considered valid. BatchSenderAddress common.Address `json:"batchSenderAddress"` @@ -627,7 +627,7 @@ type OutputOracleDeployConfig struct { L2OutputOracleSubmissionInterval uint64 `json:"l2OutputOracleSubmissionInterval"` // L2OutputOracleStartingTimestamp is the starting timestamp for the L2OutputOracle. // MUST be the same as the timestamp of the L2OO start block. - L2OutputOracleStartingTimestamp int `json:"l2OutputOracleStartingTimestamp"` + L2OutputOracleStartingTimestamp int64 `json:"l2OutputOracleStartingTimestamp"` // L2OutputOracleStartingBlockNumber is the starting block number for the L2OutputOracle. // Must be greater than or equal to the first Bedrock block. The first L2 output will correspond // to this value plus the submission interval. @@ -808,7 +808,7 @@ type DeployConfig struct { // The L2 genesis timestamp does not affect the initial L2 account state: // the storage of the L1Block contract at genesis is zeroed, since the adoption of // the L2-genesis allocs-generation through solidity script. - L1StartingBlockTag *MarshalableRPCBlockNumberOrHash `json:"l1StartingBlockTag"` + L1StartingBlockTag *MarshalableRPCBlockNumberOrHash `json:"l1StartingBlockTag" evm:"-"` // L1 contracts configuration. // The deployer of the contracts chooses which sub-systems to deploy. @@ -820,7 +820,7 @@ type DeployConfig struct { L1DependenciesConfig // Legacy, ignored, here for strict-JSON decoding to be accepted. - LegacyDeployConfig + LegacyDeployConfig `evm:"-"` } // Copy will deeply copy the DeployConfig. This does a JSON roundtrip to copy diff --git a/op-chain-ops/genesis/withdrawal_network.go b/op-chain-ops/genesis/withdrawal_network.go index f52f12d5558d..6aa753d36bd8 100644 --- a/op-chain-ops/genesis/withdrawal_network.go +++ b/op-chain-ops/genesis/withdrawal_network.go @@ -4,6 +4,8 @@ import ( "encoding/json" "fmt" "strconv" + + "github.com/holiman/uint256" ) // WithdrawalNetwork represents the network that withdrawals are sent to. @@ -32,6 +34,11 @@ func (w *WithdrawalNetwork) ToUint8() uint8 { } } +func (w WithdrawalNetwork) ToABI() []byte { + out := uint256.NewInt(uint64(w.ToUint8())).Bytes32() + return out[:] +} + // FromUint8 converts a uint8 to a WithdrawalNetwork. func FromUint8(i uint8) WithdrawalNetwork { switch i { diff --git a/op-chain-ops/interopgen/configs.go b/op-chain-ops/interopgen/configs.go new file mode 100644 index 000000000000..0bc939ec0351 --- /dev/null +++ b/op-chain-ops/interopgen/configs.go @@ -0,0 +1,108 @@ +package interopgen + +import ( + "errors" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" +) + +type L1Config struct { + ChainID *big.Int + genesis.DevL1DeployConfig + Prefund map[common.Address]*big.Int +} + +func (c *L1Config) Check(log log.Logger) error { + if c.ChainID == nil { + return errors.New("missing L1 chain ID") + } + // nothing to check on c.DevL1DeployConfig + return nil +} + +type SuperFaultProofConfig struct { + WithdrawalDelaySeconds *big.Int + MinProposalSizeBytes *big.Int + ChallengePeriodSeconds *big.Int + ProofMaturityDelaySeconds *big.Int + DisputeGameFinalityDelaySeconds *big.Int +} + +type OPSMImplementationsConfig struct { + Release string + + FaultProof SuperFaultProofConfig + + UseInterop bool // to deploy Interop implementation contracts, instead of the regular ones. +} + +type SuperchainConfig struct { + Deployer common.Address + + ProxyAdminOwner common.Address + ProtocolVersionsOwner common.Address + + Paused bool + + Implementations OPSMImplementationsConfig + + genesis.SuperchainL1DeployConfig +} + +func (c *SuperchainConfig) Check(log log.Logger) error { + if c.Deployer == (common.Address{}) { + return errors.New("missing superchain deployer address") + } + if c.ProxyAdminOwner == (common.Address{}) { + return errors.New("missing superchain ProxyAdminOwner address") + } + if err := c.SuperchainL1DeployConfig.Check(log); err != nil { + return err + } + return nil +} + +type L2Config struct { + Deployer common.Address // account used to deploy contracts to L2 + Proposer common.Address + Challenger common.Address + SystemConfigOwner common.Address + genesis.L2InitializationConfig + Prefund map[common.Address]*big.Int +} + +func (c *L2Config) Check(log log.Logger) error { + if c.Deployer == (common.Address{}) { + return errors.New("missing L2 deployer address") + } + if err := c.L2InitializationConfig.Check(log); err != nil { + return err + } + return nil +} + +type WorldConfig struct { + L1 *L1Config + Superchain *SuperchainConfig + L2s map[string]*L2Config +} + +func (c *WorldConfig) Check(log log.Logger) error { + if err := c.L1.Check(log); err != nil { + return fmt.Errorf("invalid L1 config: %w", err) + } + if err := c.Superchain.Check(log); err != nil { + return fmt.Errorf("invalid Superchain config: %w", err) + } + for l2ChainID, l2Cfg := range c.L2s { + if err := l2Cfg.Check(log.New("l2", &l2ChainID)); err != nil { + return fmt.Errorf("invalid L2 (chain ID %s) config: %w", l2ChainID, err) + } + } + return nil +} diff --git a/op-chain-ops/interopgen/deploy.go b/op-chain-ops/interopgen/deploy.go new file mode 100644 index 000000000000..fc77cf53ed06 --- /dev/null +++ b/op-chain-ops/interopgen/deploy.go @@ -0,0 +1,338 @@ +package interopgen + +import ( + "errors" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" + "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" + "github.com/ethereum-optimism/optimism/op-chain-ops/genesis/beacondeposit" + "github.com/ethereum-optimism/optimism/op-chain-ops/interopgen/deployers" + "github.com/ethereum-optimism/optimism/op-chain-ops/script" +) + +var ( + // sysGenesisDeployer is used as tx.origin/msg.sender on system genesis script calls. + // At the end we verify none of the deployed contracts persist (there may be temporary ones, to insert bytecode). + sysGenesisDeployer = common.Address(crypto.Keccak256([]byte("System genesis deployer"))[12:]) +) + +func Deploy(logger log.Logger, fa *foundry.ArtifactsFS, srcFS *foundry.SourceMapFS, cfg *WorldConfig) (*WorldDeployment, *WorldOutput, error) { + // Sanity check all L2s have consistent chain ID and attach to the same L1 + for id, l2Cfg := range cfg.L2s { + if fmt.Sprintf("%d", l2Cfg.L2ChainID) != id { + return nil, nil, fmt.Errorf("chain L2 %s declared different L2 chain ID %d in config", id, l2Cfg.L2ChainID) + } + if !cfg.L1.ChainID.IsUint64() || cfg.L1.ChainID.Uint64() != l2Cfg.L1ChainID { + return nil, nil, fmt.Errorf("chain L2 %s declared different L1 chain ID %d in config than global %d", id, l2Cfg.L1ChainID, cfg.L1.ChainID) + } + } + + deployments := &WorldDeployment{ + L2s: make(map[string]*L2Deployment), + } + + l1Host := createL1(logger, fa, srcFS, cfg.L1) + if err := l1Host.EnableCheats(); err != nil { + return nil, nil, fmt.Errorf("failed to enable cheats in L1 state: %w", err) + } + + l1Deployment, err := prepareInitialL1(l1Host, cfg.L1) + if err != nil { + return nil, nil, fmt.Errorf("failed to deploy initial L1 content: %w", err) + } + deployments.L1 = l1Deployment + + superDeployment, err := deploySuperchainToL1(l1Host, cfg.Superchain) + if err != nil { + return nil, nil, fmt.Errorf("failed to deploy superchain to L1: %w", err) + } + deployments.Superchain = superDeployment + + // We deploy contracts for each L2 to the L1 + // because we need to compute the genesis block hash + // to put into the L2 genesis configs, and can thus not mutate the L1 state + // after creating the final config for any particular L2. Will add comments. + + for l2ChainID, l2Cfg := range cfg.L2s { + l2Deployment, err := deployL2ToL1(l1Host, cfg.Superchain, superDeployment, l2Cfg) + if err != nil { + return nil, nil, fmt.Errorf("failed to deploy L2 %d to L1: %w", &l2ChainID, err) + } + deployments.L2s[l2ChainID] = l2Deployment + } + + out := &WorldOutput{ + L2s: make(map[string]*L2Output), + } + l1Out, err := completeL1(l1Host, cfg.L1) + if err != nil { + return nil, nil, fmt.Errorf("failed to complete L1: %w", err) + } + out.L1 = l1Out + + // Now that the L1 does not change anymore we can compute the L1 genesis block, to anchor all the L2s to. + l1GenesisBlock := l1Out.Genesis.ToBlock() + genesisTimestamp := l1Out.Genesis.Timestamp + + for l2ChainID, l2Cfg := range cfg.L2s { + l2Host := createL2(logger, fa, srcFS, l2Cfg, genesisTimestamp) + if err := l2Host.EnableCheats(); err != nil { + return nil, nil, fmt.Errorf("failed to enable cheats in L2 state %s: %w", l2ChainID, err) + } + if err := genesisL2(l2Host, l2Cfg, deployments.L2s[l2ChainID]); err != nil { + return nil, nil, fmt.Errorf("failed to apply genesis data to L2 %s: %w", l2ChainID, err) + } + l2Out, err := completeL2(l2Host, l2Cfg, l1GenesisBlock, deployments.L2s[l2ChainID]) + if err != nil { + return nil, nil, fmt.Errorf("failed to complete L2 %s: %w", l2ChainID, err) + } + out.L2s[l2ChainID] = l2Out + } + return deployments, out, nil +} + +func createL1(logger log.Logger, fa *foundry.ArtifactsFS, srcFS *foundry.SourceMapFS, cfg *L1Config) *script.Host { + l1Context := script.Context{ + ChainID: cfg.ChainID, + Sender: sysGenesisDeployer, + Origin: sysGenesisDeployer, + FeeRecipient: common.Address{}, + GasLimit: script.DefaultFoundryGasLimit, + BlockNum: uint64(cfg.L1GenesisBlockNumber), + Timestamp: uint64(cfg.L1GenesisBlockTimestamp), + PrevRandao: cfg.L1GenesisBlockMixHash, + BlobHashes: nil, + } + l1Host := script.NewHost(logger.New("role", "l1", "chain", cfg.ChainID), fa, srcFS, l1Context) + return l1Host +} + +func createL2(logger log.Logger, fa *foundry.ArtifactsFS, srcFS *foundry.SourceMapFS, l2Cfg *L2Config, genesisTimestamp uint64) *script.Host { + l2Context := script.Context{ + ChainID: new(big.Int).SetUint64(l2Cfg.L2ChainID), + Sender: sysGenesisDeployer, + Origin: sysGenesisDeployer, + FeeRecipient: common.Address{}, + GasLimit: script.DefaultFoundryGasLimit, + BlockNum: uint64(l2Cfg.L2GenesisBlockNumber), + Timestamp: genesisTimestamp, + PrevRandao: l2Cfg.L2GenesisBlockMixHash, + BlobHashes: nil, + } + l2Host := script.NewHost(logger.New("role", "l2", "chain", l2Cfg.L2ChainID), fa, srcFS, l2Context) + l2Host.SetEnvVar("OUTPUT_MODE", "none") // we don't use the cheatcode, but capture the state outside of EVM execution + l2Host.SetEnvVar("FORK", "granite") // latest fork + return l2Host +} + +// prepareInitialL1 deploys basics such as preinstalls to L1 (incl. EIP-4788) +func prepareInitialL1(l1Host *script.Host, cfg *L1Config) (*L1Deployment, error) { + l1Host.SetTxOrigin(sysGenesisDeployer) + + if err := deployers.InsertPreinstalls(l1Host); err != nil { + return nil, fmt.Errorf("failed to install preinstalls in L1: %w", err) + } + // No global contracts inserted at this point. + // All preinstalls have known constant addresses. + return &L1Deployment{}, nil +} + +func deploySuperchainToL1(l1Host *script.Host, superCfg *SuperchainConfig) (*SuperchainDeployment, error) { + l1Host.SetTxOrigin(superCfg.Deployer) + + superDeployment, err := deployers.DeploySuperchain(l1Host, &deployers.DeploySuperchainInput{ + ProxyAdminOwner: superCfg.ProxyAdminOwner, + ProtocolVersionsOwner: superCfg.ProtocolVersionsOwner, + Guardian: superCfg.SuperchainConfigGuardian, + Paused: superCfg.Paused, + RequiredProtocolVersion: superCfg.RequiredProtocolVersion, + RecommendedProtocolVersion: superCfg.RecommendedProtocolVersion, + }) + if err != nil { + return nil, fmt.Errorf("failed to deploy Superchain contracts: %w", err) + } + + implementationsDeployment, err := deployers.DeployImplementations(l1Host, &deployers.DeployImplementationsInput{ + WithdrawalDelaySeconds: superCfg.Implementations.FaultProof.WithdrawalDelaySeconds, + MinProposalSizeBytes: superCfg.Implementations.FaultProof.MinProposalSizeBytes, + ChallengePeriodSeconds: superCfg.Implementations.FaultProof.ChallengePeriodSeconds, + ProofMaturityDelaySeconds: superCfg.Implementations.FaultProof.ProofMaturityDelaySeconds, + DisputeGameFinalityDelaySeconds: superCfg.Implementations.FaultProof.DisputeGameFinalityDelaySeconds, + Release: superCfg.Implementations.Release, + SuperchainConfigProxy: superDeployment.SuperchainConfigProxy, + ProtocolVersionsProxy: superDeployment.ProtocolVersionsProxy, + UseInterop: superCfg.Implementations.UseInterop, + }) + if err != nil { + return nil, fmt.Errorf("failed to deploy Implementations contracts: %w", err) + } + + // Collect deployment addresses + // This could all be automatic once we have better output-contract typing/scripting + return &SuperchainDeployment{ + Implementations: Implementations(*implementationsDeployment), + ProxyAdmin: superDeployment.SuperchainProxyAdmin, + ProtocolVersions: superDeployment.ProtocolVersionsImpl, + ProtocolVersionsProxy: superDeployment.ProtocolVersionsProxy, + SuperchainConfig: superDeployment.SuperchainConfigImpl, + SuperchainConfigProxy: superDeployment.SuperchainConfigProxy, + }, nil +} + +func deployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployment *SuperchainDeployment, cfg *L2Config) (*L2Deployment, error) { + if cfg.UseAltDA { + return nil, errors.New("alt-da mode not supported yet") + } + + l1Host.SetTxOrigin(cfg.Deployer) + + output, err := deployers.DeployOPChain(l1Host, &deployers.DeployOPChainInput{ + OpChainProxyAdminOwner: cfg.ProxyAdminOwner, + SystemConfigOwner: cfg.SystemConfigOwner, + Batcher: cfg.BatchSenderAddress, + UnsafeBlockSigner: cfg.P2PSequencerAddress, + Proposer: cfg.Proposer, + Challenger: cfg.Challenger, + BasefeeScalar: cfg.GasPriceOracleBaseFeeScalar, + BlobBaseFeeScalar: cfg.GasPriceOracleBlobBaseFeeScalar, + L2ChainId: new(big.Int).SetUint64(cfg.L2ChainID), + Opsm: superDeployment.Opsm, + }) + if err != nil { + return nil, fmt.Errorf("failed to deploy L2 OP chain: %w", err) + } + + // Collect deployment addresses + return &L2Deployment{ + L2OpchainDeployment: L2OpchainDeployment(*output), + }, nil +} + +func genesisL2(l2Host *script.Host, cfg *L2Config, deployment *L2Deployment) error { + if err := deployers.L2Genesis(l2Host, &deployers.L2GenesisInput{ + L1Deployments: deployers.L1Deployments{ + L1CrossDomainMessengerProxy: deployment.L1CrossDomainMessengerProxy, + L1StandardBridgeProxy: deployment.L1StandardBridgeProxy, + L1ERC721BridgeProxy: deployment.L1ERC721BridgeProxy, + }, + L2Config: cfg.L2InitializationConfig, + }); err != nil { + return fmt.Errorf("failed L2 genesis: %w", err) + } + + return nil +} + +func completeL1(l1Host *script.Host, cfg *L1Config) (*L1Output, error) { + l1Genesis, err := genesis.NewL1Genesis(&genesis.DeployConfig{ + L2InitializationConfig: genesis.L2InitializationConfig{ + L2CoreDeployConfig: genesis.L2CoreDeployConfig{ + L1ChainID: cfg.ChainID.Uint64(), + }, + }, + DevL1DeployConfig: cfg.DevL1DeployConfig, + }) + if err != nil { + return nil, fmt.Errorf("failed to build L1 genesis template: %w", err) + } + allocs, err := l1Host.StateDump() + if err != nil { + return nil, fmt.Errorf("failed to dump L1 state: %w", err) + } + + // Sanity check that the default deployer didn't include anything, + // and make sure it's not in the state. + if err := ensureNoDeployed(allocs, sysGenesisDeployer); err != nil { + return nil, fmt.Errorf("unexpected deployed account content by L1 genesis deployer: %w", err) + } + + for addr, amount := range cfg.Prefund { + acc := allocs.Accounts[addr] + acc.Balance = amount + allocs.Accounts[addr] = acc + } + + l1Genesis.Alloc = allocs.Accounts + + // Insert an empty beaconchain deposit contract with valid empty-tree prestate. + // This is part of dev-genesis, but not part of scripts yet. + beaconDepositAddr := common.HexToAddress("0x1111111111111111111111111111111111111111") + if err := beacondeposit.InsertEmptyBeaconDepositContract(l1Genesis, beaconDepositAddr); err != nil { + return nil, fmt.Errorf("failed to insert beacon deposit contract into L1 dev genesis: %w", err) + } + + return &L1Output{ + Genesis: l1Genesis, + }, nil +} + +func completeL2(l2Host *script.Host, cfg *L2Config, l1Block *types.Block, deployment *L2Deployment) (*L2Output, error) { + deployCfg := &genesis.DeployConfig{ + L2InitializationConfig: cfg.L2InitializationConfig, + L1DependenciesConfig: genesis.L1DependenciesConfig{ + L1StandardBridgeProxy: deployment.L1StandardBridgeProxy, + L1CrossDomainMessengerProxy: deployment.L1CrossDomainMessengerProxy, + L1ERC721BridgeProxy: deployment.L1ERC721BridgeProxy, + SystemConfigProxy: deployment.SystemConfigProxy, + OptimismPortalProxy: deployment.OptimismPortalProxy, + DAChallengeProxy: common.Address{}, // unsupported for now + }, + } + // l1Block is used to determine genesis time. + l2Genesis, err := genesis.NewL2Genesis(deployCfg, l1Block) + if err != nil { + return nil, fmt.Errorf("failed to build L2 genesis config: %w", err) + } + + allocs, err := l2Host.StateDump() + if err != nil { + return nil, fmt.Errorf("failed to dump L1 state: %w", err) + } + + // Sanity check that the default deployer didn't include anything, + // and make sure it's not in the state. + if err := ensureNoDeployed(allocs, sysGenesisDeployer); err != nil { + return nil, fmt.Errorf("unexpected deployed account content by L2 genesis deployer: %w", err) + } + + for addr, amount := range cfg.Prefund { + acc := allocs.Accounts[addr] + acc.Balance = amount + allocs.Accounts[addr] = acc + } + + l2Genesis.Alloc = allocs.Accounts + l2GenesisBlock := l2Genesis.ToBlock() + + rollupCfg, err := deployCfg.RollupConfig(l1Block, l2GenesisBlock.Hash(), l2GenesisBlock.NumberU64()) + if err != nil { + return nil, fmt.Errorf("failed to build L2 rollup config: %w", err) + } + return &L2Output{ + Genesis: l2Genesis, + RollupCfg: rollupCfg, + }, nil +} + +// ensureNoDeployed checks that non of the contracts that +// could have been deployed by the given deployer address are around. +// And removes deployer from the allocs. +func ensureNoDeployed(allocs *foundry.ForgeAllocs, deployer common.Address) error { + // Sanity check we have no deploy output that's not meant to be there. + for i := uint64(0); i <= allocs.Accounts[deployer].Nonce; i++ { + addr := crypto.CreateAddress(deployer, i) + if _, ok := allocs.Accounts[addr]; ok { + return fmt.Errorf("system deployer output %s (deployed with nonce %d) was not cleaned up", addr, i) + } + } + // Don't include the deployer account + delete(allocs.Accounts, deployer) + return nil +} diff --git a/op-chain-ops/interopgen/deployers/implementations.go b/op-chain-ops/interopgen/deployers/implementations.go new file mode 100644 index 000000000000..a9baf7718598 --- /dev/null +++ b/op-chain-ops/interopgen/deployers/implementations.go @@ -0,0 +1,101 @@ +package deployers + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + + "github.com/ethereum-optimism/optimism/op-chain-ops/script" +) + +type DeployImplementationsInput struct { + WithdrawalDelaySeconds *big.Int + MinProposalSizeBytes *big.Int + ChallengePeriodSeconds *big.Int + ProofMaturityDelaySeconds *big.Int + DisputeGameFinalityDelaySeconds *big.Int + // Release version to set OPSM implementations for, of the format `op-contracts/vX.Y.Z`. + Release string + SuperchainConfigProxy common.Address + ProtocolVersionsProxy common.Address + UseInterop bool // if true, deploy Interop implementations +} + +func (input *DeployImplementationsInput) InputSet() bool { + return true +} + +type DeployImplementationsOutput struct { + Opsm common.Address + DelayedWETHImpl common.Address + OptimismPortalImpl common.Address + PreimageOracleSingleton common.Address + MipsSingleton common.Address + SystemConfigImpl common.Address + L1CrossDomainMessengerImpl common.Address + L1ERC721BridgeImpl common.Address + L1StandardBridgeImpl common.Address + OptimismMintableERC20FactoryImpl common.Address + DisputeGameFactoryImpl common.Address +} + +func (output *DeployImplementationsOutput) CheckOutput() error { + return nil +} + +type DeployImplementationsScript struct { + Run func(input, output common.Address) error +} + +func DeployImplementations(l1Host *script.Host, input *DeployImplementationsInput) (*DeployImplementationsOutput, error) { + output := &DeployImplementationsOutput{} + inputAddr := l1Host.NewScriptAddress() + outputAddr := l1Host.NewScriptAddress() + + cleanupInput, err := script.WithPrecompileAtAddress[*DeployImplementationsInput](l1Host, inputAddr, input) + if err != nil { + return nil, fmt.Errorf("failed to insert DeployImplementationsInput precompile: %w", err) + } + defer cleanupInput() + + cleanupOutput, err := script.WithPrecompileAtAddress[*DeployImplementationsOutput](l1Host, outputAddr, output, + script.WithFieldSetter[*DeployImplementationsOutput]) + if err != nil { + return nil, fmt.Errorf("failed to insert DeployImplementationsOutput precompile: %w", err) + } + defer cleanupOutput() + + implContract := "DeployImplementations" + if input.UseInterop { + implContract = "DeployImplementationsInterop" + } + deployScript, cleanupDeploy, err := script.WithScript[DeployImplementationsScript](l1Host, "DeployImplementations.s.sol", implContract) + if err != nil { + return nil, fmt.Errorf("failed to load %s script: %w", implContract, err) + } + defer cleanupDeploy() + + opsmContract := "OPStackManager" + if input.UseInterop { + opsmContract = "OPStackManagerInterop" + } + if err := l1Host.RememberOnLabel("OPStackManager", opsmContract+".sol", opsmContract); err != nil { + return nil, fmt.Errorf("failed to link OPStackManager label: %w", err) + } + + // So we can see in detail where the SystemConfig interop initializer fails + sysConfig := "SystemConfig" + if input.UseInterop { + sysConfig = "SystemConfigInterop" + } + if err := l1Host.RememberOnLabel("SystemConfigImpl", sysConfig+".sol", sysConfig); err != nil { + return nil, fmt.Errorf("failed to link SystemConfig label: %w", err) + } + + if err := deployScript.Run(inputAddr, outputAddr); err != nil { + return nil, fmt.Errorf("failed to run %s script: %w", implContract, err) + } + + return output, nil +} diff --git a/op-chain-ops/interopgen/deployers/l2genesis.go b/op-chain-ops/interopgen/deployers/l2genesis.go new file mode 100644 index 000000000000..a80f4f69d74b --- /dev/null +++ b/op-chain-ops/interopgen/deployers/l2genesis.go @@ -0,0 +1,55 @@ +package deployers + +import ( + "fmt" + + "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" + "github.com/ethereum-optimism/optimism/op-chain-ops/script" + "github.com/ethereum/go-ethereum/common" +) + +var ( + // address(uint160(uint256(keccak256(abi.encode("optimism.deployconfig"))))) - not a simple hash, due to ABI encode + deployConfigAddr = common.HexToAddress("0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c") +) + +type L1Deployments struct { + L1CrossDomainMessengerProxy common.Address + L1StandardBridgeProxy common.Address + L1ERC721BridgeProxy common.Address +} + +type L2GenesisInput struct { + L1Deployments L1Deployments + L2Config genesis.L2InitializationConfig +} + +type L2GenesisScript struct { + RunWithEnv func() error +} + +func L2Genesis(l2Host *script.Host, input *L2GenesisInput) error { + l2Host.SetEnvVar("L2GENESIS_L1CrossDomainMessengerProxy", input.L1Deployments.L1CrossDomainMessengerProxy.String()) + l2Host.SetEnvVar("L2GENESIS_L1StandardBridgeProxy", input.L1Deployments.L1StandardBridgeProxy.String()) + l2Host.SetEnvVar("L2GENESIS_L1ERC721BridgeProxy", input.L1Deployments.L1ERC721BridgeProxy.String()) + + deployConfig := &genesis.DeployConfig{ + L2InitializationConfig: input.L2Config, + } + cleanupDeployConfig, err := script.WithPrecompileAtAddress[*genesis.DeployConfig](l2Host, deployConfigAddr, deployConfig, script.WithFieldsOnly[*genesis.DeployConfig]) + if err != nil { + return fmt.Errorf("failed to insert DeployConfig precompile: %w", err) + } + defer cleanupDeployConfig() + + l2GenesisScript, cleanupL2Genesis, err := script.WithScript[L2GenesisScript](l2Host, "L2Genesis.s.sol", "L2Genesis") + if err != nil { + return fmt.Errorf("failed to load L2Genesis script: %w", err) + } + defer cleanupL2Genesis() + + if err := l2GenesisScript.RunWithEnv(); err != nil { + return fmt.Errorf("failed to run L2 genesis script: %w", err) + } + return nil +} diff --git a/op-chain-ops/interopgen/deployers/opchain.go b/op-chain-ops/interopgen/deployers/opchain.go new file mode 100644 index 000000000000..184ccc946bf0 --- /dev/null +++ b/op-chain-ops/interopgen/deployers/opchain.go @@ -0,0 +1,87 @@ +package deployers + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + + "github.com/ethereum-optimism/optimism/op-chain-ops/script" +) + +type DeployOPChainInput struct { + OpChainProxyAdminOwner common.Address + SystemConfigOwner common.Address + Batcher common.Address + UnsafeBlockSigner common.Address + Proposer common.Address + Challenger common.Address + + BasefeeScalar uint32 + BlobBaseFeeScalar uint32 + L2ChainId *big.Int + Opsm common.Address +} + +func (input *DeployOPChainInput) InputSet() bool { + return true +} + +type DeployOPChainOutput struct { + OpChainProxyAdmin common.Address + AddressManager common.Address + L1ERC721BridgeProxy common.Address + SystemConfigProxy common.Address + OptimismMintableERC20FactoryProxy common.Address + L1StandardBridgeProxy common.Address + L1CrossDomainMessengerProxy common.Address + // Fault proof contracts below. + OptimismPortalProxy common.Address + DisputeGameFactoryProxy common.Address + DisputeGameFactoryImpl common.Address + AnchorStateRegistryProxy common.Address + AnchorStateRegistryImpl common.Address + FaultDisputeGame common.Address + PermissionedDisputeGame common.Address + DelayedWETHPermissionedGameProxy common.Address + DelayedWETHPermissionlessGameProxy common.Address +} + +func (output *DeployOPChainOutput) CheckOutput() error { + return nil +} + +type DeployOPChainScript struct { + Run func(input, output common.Address) error +} + +func DeployOPChain(l1Host *script.Host, input *DeployOPChainInput) (*DeployOPChainOutput, error) { + output := &DeployOPChainOutput{} + inputAddr := l1Host.NewScriptAddress() + outputAddr := l1Host.NewScriptAddress() + + cleanupInput, err := script.WithPrecompileAtAddress[*DeployOPChainInput](l1Host, inputAddr, input) + if err != nil { + return nil, fmt.Errorf("failed to insert DeployOPChainInput precompile: %w", err) + } + defer cleanupInput() + + cleanupOutput, err := script.WithPrecompileAtAddress[*DeployOPChainOutput](l1Host, outputAddr, output, + script.WithFieldSetter[*DeployOPChainOutput]) + if err != nil { + return nil, fmt.Errorf("failed to insert DeployOPChainOutput precompile: %w", err) + } + defer cleanupOutput() + + deployScript, cleanupDeploy, err := script.WithScript[DeployOPChainScript](l1Host, "DeployOPChain.s.sol", "DeployOPChain") + if err != nil { + return nil, fmt.Errorf("failed to load DeployOPChain script: %w", err) + } + defer cleanupDeploy() + + if err := deployScript.Run(inputAddr, outputAddr); err != nil { + return nil, fmt.Errorf("failed to run DeployOPChain script: %w", err) + } + + return output, nil +} diff --git a/op-chain-ops/interopgen/deployers/preinstalls.go b/op-chain-ops/interopgen/deployers/preinstalls.go new file mode 100644 index 000000000000..8a4dca1af26d --- /dev/null +++ b/op-chain-ops/interopgen/deployers/preinstalls.go @@ -0,0 +1,24 @@ +package deployers + +import ( + "fmt" + + "github.com/ethereum-optimism/optimism/op-chain-ops/script" +) + +type PreinstallsScript struct { + SetPreinstalls func() error +} + +func InsertPreinstalls(host *script.Host) error { + l2GenesisScript, cleanupL2Genesis, err := script.WithScript[PreinstallsScript](host, "SetPreinstalls.s.sol", "SetPreinstalls") + if err != nil { + return fmt.Errorf("failed to load SetPreinstalls script: %w", err) + } + defer cleanupL2Genesis() + + if err := l2GenesisScript.SetPreinstalls(); err != nil { + return fmt.Errorf("failed to set preinstalls: %w", err) + } + return nil +} diff --git a/op-chain-ops/interopgen/deployers/superchain.go b/op-chain-ops/interopgen/deployers/superchain.go new file mode 100644 index 000000000000..60e9805d6711 --- /dev/null +++ b/op-chain-ops/interopgen/deployers/superchain.go @@ -0,0 +1,70 @@ +package deployers + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/params" + + "github.com/ethereum-optimism/optimism/op-chain-ops/script" +) + +type DeploySuperchainInput struct { + ProxyAdminOwner common.Address // TODO(#11783): also used as interop-dependency-set owner + ProtocolVersionsOwner common.Address + Guardian common.Address + Paused bool + RequiredProtocolVersion params.ProtocolVersion + RecommendedProtocolVersion params.ProtocolVersion +} + +func (input *DeploySuperchainInput) InputSet() bool { + return true +} + +type DeploySuperchainOutput struct { + SuperchainProxyAdmin common.Address + SuperchainConfigImpl common.Address + SuperchainConfigProxy common.Address + ProtocolVersionsImpl common.Address + ProtocolVersionsProxy common.Address +} + +func (output *DeploySuperchainOutput) CheckOutput() error { + return nil +} + +type DeploySuperchainScript struct { + Run func(input, output common.Address) error +} + +func DeploySuperchain(l1Host *script.Host, input *DeploySuperchainInput) (*DeploySuperchainOutput, error) { + output := &DeploySuperchainOutput{} + inputAddr := l1Host.NewScriptAddress() + outputAddr := l1Host.NewScriptAddress() + + cleanupInput, err := script.WithPrecompileAtAddress[*DeploySuperchainInput](l1Host, inputAddr, input) + if err != nil { + return nil, fmt.Errorf("failed to insert DeploySuperchainInput precompile: %w", err) + } + defer cleanupInput() + + cleanupOutput, err := script.WithPrecompileAtAddress[*DeploySuperchainOutput](l1Host, outputAddr, output, + script.WithFieldSetter[*DeploySuperchainOutput]) + if err != nil { + return nil, fmt.Errorf("failed to insert DeploySuperchainOutput precompile: %w", err) + } + defer cleanupOutput() + + deployScript, cleanupDeploy, err := script.WithScript[DeploySuperchainScript](l1Host, "DeploySuperchain.s.sol", "DeploySuperchain") + if err != nil { + return nil, fmt.Errorf("failed to load DeploySuperchain script: %w", err) + } + defer cleanupDeploy() + + if err := deployScript.Run(inputAddr, outputAddr); err != nil { + return nil, fmt.Errorf("failed to run DeploySuperchain script: %w", err) + } + + return output, nil +} diff --git a/op-chain-ops/interopgen/deployments.go b/op-chain-ops/interopgen/deployments.go new file mode 100644 index 000000000000..d360ad9292fe --- /dev/null +++ b/op-chain-ops/interopgen/deployments.go @@ -0,0 +1,68 @@ +package interopgen + +import ( + "github.com/ethereum/go-ethereum/common" +) + +type L1Deployment struct { + // No global deployed contracts that aren't part of the superchain, yet. +} + +type Implementations struct { + Opsm common.Address `json:"OPSM"` // not proxied + DelayedWETHImpl common.Address `json:"DelayedWETHImpl"` + OptimismPortalImpl common.Address `json:"OptimismPortalImpl"` + PreimageOracleSingleton common.Address `json:"PreimageOracleSingleton"` + MipsSingleton common.Address `json:"MipsSingleton"` + SystemConfigImpl common.Address `json:"SystemConfigImpl"` + L1CrossDomainMessengerImpl common.Address `json:"L1CrossDomainMessengerImpl"` + L1ERC721BridgeImpl common.Address `json:"L1ERC721BridgeImpl"` + L1StandardBridgeImpl common.Address `json:"L1StandardBridgeImpl"` + OptimismMintableERC20FactoryImpl common.Address `json:"OptimismMintableERC20FactoryImpl"` + DisputeGameFactoryImpl common.Address `json:"DisputeGameFactoryImpl"` +} + +type SuperchainDeployment struct { + Implementations + + ProxyAdmin common.Address `json:"ProxyAdmin"` + + ProtocolVersions common.Address `json:"ProtocolVersions"` + ProtocolVersionsProxy common.Address `json:"ProtocolVersionsProxy"` + + SuperchainConfig common.Address `json:"SuperchainConfig"` + SuperchainConfigProxy common.Address `json:"SuperchainConfigProxy"` +} + +type L2OpchainDeployment struct { + OpChainProxyAdmin common.Address `json:"OpChainProxyAdmin"` + AddressManager common.Address `json:"AddressManager"` + L1ERC721BridgeProxy common.Address `json:"L1ERC721BridgeProxy"` + SystemConfigProxy common.Address `json:"SystemConfigProxy"` + OptimismMintableERC20FactoryProxy common.Address `json:"OptimismMintableERC20FactoryProxy"` + L1StandardBridgeProxy common.Address `json:"L1StandardBridgeProxy"` + L1CrossDomainMessengerProxy common.Address `json:"L1CrossDomainMessengerProxy"` + // Fault proof contracts below. + OptimismPortalProxy common.Address `json:"OptimismPortalProxy"` + DisputeGameFactoryProxy common.Address `json:"DisputeGameFactoryProxy"` + DisputeGameFactoryImpl common.Address `json:"DisputeGameFactoryImpl"` + AnchorStateRegistryProxy common.Address `json:"AnchorStateRegistryProxy"` + AnchorStateRegistryImpl common.Address `json:"AnchorStateRegistryImpl"` + FaultDisputeGame common.Address `json:"FaultDisputeGame"` + PermissionedDisputeGame common.Address `json:"PermissionedDisputeGame"` + DelayedWETHPermissionedGameProxy common.Address `json:"DelayedWETHPermissionedGameProxy"` + DelayedWETHPermissionlessGameProxy common.Address `json:"DelayedWETHPermissionlessGameProxy"` +} + +type L2Deployment struct { + L2OpchainDeployment + + // In the future this may contain optional extras, + // e.g. a Safe that will own the L2 chain contracts +} + +type WorldDeployment struct { + L1 *L1Deployment `json:"L1"` + Superchain *SuperchainDeployment `json:"Superchain"` + L2s map[string]*L2Deployment `json:"L2s"` +} diff --git a/op-chain-ops/interopgen/outputs.go b/op-chain-ops/interopgen/outputs.go new file mode 100644 index 000000000000..c0543ab06293 --- /dev/null +++ b/op-chain-ops/interopgen/outputs.go @@ -0,0 +1,21 @@ +package interopgen + +import ( + "github.com/ethereum/go-ethereum/core" + + "github.com/ethereum-optimism/optimism/op-node/rollup" +) + +type L1Output struct { + Genesis *core.Genesis +} + +type L2Output struct { + Genesis *core.Genesis + RollupCfg *rollup.Config +} + +type WorldOutput struct { + L1 *L1Output + L2s map[string]*L2Output +} diff --git a/op-chain-ops/interopgen/recipe.go b/op-chain-ops/interopgen/recipe.go new file mode 100644 index 000000000000..a1761f9f0dc8 --- /dev/null +++ b/op-chain-ops/interopgen/recipe.go @@ -0,0 +1,272 @@ +package interopgen + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/params" + + "github.com/ethereum-optimism/optimism/op-chain-ops/devkeys" + "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" +) + +type InteropDevRecipe struct { + L1ChainID uint64 + L2ChainIDs []uint64 + GenesisTimestamp uint64 +} + +func (r *InteropDevRecipe) Build(addrs devkeys.Addresses) (*WorldConfig, error) { + // L1 genesis + l1Cfg := &L1Config{ + ChainID: new(big.Int).SetUint64(r.L1ChainID), + DevL1DeployConfig: genesis.DevL1DeployConfig{ + L1BlockTime: 6, + L1GenesisBlockTimestamp: hexutil.Uint64(r.GenesisTimestamp), + L1GenesisBlockGasLimit: 30_000_000, + }, + Prefund: make(map[common.Address]*big.Int), + } + + // TODO(#11887): consider making the number of prefunded keys configurable. + l1Users := devkeys.ChainUserKeys(l1Cfg.ChainID) + for i := uint64(0); i < 20; i++ { + userAddr, err := addrs.Address(l1Users(i)) + if err != nil { + return nil, fmt.Errorf("failed to get L1 user addr %d: %w", i, err) + } + l1Cfg.Prefund[userAddr] = Ether(10_000_000) + } + + superchainOps := devkeys.SuperchainOperatorKeys(l1Cfg.ChainID) + + superchainDeployer, err := addrs.Address(superchainOps(devkeys.SuperchainDeployerKey)) + if err != nil { + return nil, err + } + superchainProxyAdmin, err := addrs.Address(superchainOps(devkeys.SuperchainProxyAdminOwner)) + if err != nil { + return nil, err + } + superchainProtocolVersionsOwner, err := addrs.Address(superchainOps(devkeys.SuperchainProtocolVersionsOwner)) + if err != nil { + return nil, err + } + superchainConfigGuardian, err := addrs.Address(superchainOps(devkeys.SuperchainConfigGuardianKey)) + if err != nil { + return nil, err + } + l1Cfg.Prefund[superchainDeployer] = Ether(10_000_000) + l1Cfg.Prefund[superchainProxyAdmin] = Ether(10_000_000) + l1Cfg.Prefund[superchainConfigGuardian] = Ether(10_000_000) + superchainCfg := &SuperchainConfig{ + ProxyAdminOwner: superchainProxyAdmin, + ProtocolVersionsOwner: superchainProtocolVersionsOwner, + Deployer: superchainDeployer, + Implementations: OPSMImplementationsConfig{ + Release: "op-contracts/0.0.1", + FaultProof: SuperFaultProofConfig{ + WithdrawalDelaySeconds: big.NewInt(604800), + MinProposalSizeBytes: big.NewInt(10000), + ChallengePeriodSeconds: big.NewInt(120), + ProofMaturityDelaySeconds: big.NewInt(12), + DisputeGameFinalityDelaySeconds: big.NewInt(6), + }, + UseInterop: true, + }, + SuperchainL1DeployConfig: genesis.SuperchainL1DeployConfig{ + RequiredProtocolVersion: params.OPStackSupport, + RecommendedProtocolVersion: params.OPStackSupport, + SuperchainConfigGuardian: superchainConfigGuardian, + }, + } + world := &WorldConfig{ + L1: l1Cfg, + Superchain: superchainCfg, + L2s: make(map[string]*L2Config), + } + for _, l2ChainID := range r.L2ChainIDs { + l2Cfg, err := InteropL2DevConfig(r.L1ChainID, l2ChainID, addrs) + if err != nil { + return nil, fmt.Errorf("failed to generate L2 config for chain %d: %w", l2ChainID, err) + } + if err := prefundL2Accounts(l1Cfg, l2Cfg, addrs); err != nil { + return nil, fmt.Errorf("failed to prefund addresses on L1 for L2 chain %d: %w", l2ChainID, err) + } + world.L2s[fmt.Sprintf("%d", l2ChainID)] = l2Cfg + } + return world, nil +} + +func prefundL2Accounts(l1Cfg *L1Config, l2Cfg *L2Config, addrs devkeys.Addresses) error { + l1Cfg.Prefund[l2Cfg.BatchSenderAddress] = Ether(10_000_000) + l1Cfg.Prefund[l2Cfg.Deployer] = Ether(10_000_000) + l1Cfg.Prefund[l2Cfg.FinalSystemOwner] = Ether(10_000_000) + proposer, err := addrs.Address(devkeys.ChainOperatorKey{ + ChainID: new(big.Int).SetUint64(l2Cfg.L2ChainID), + Role: devkeys.ProposerRole, + }) + if err != nil { + return err + } + l1Cfg.Prefund[proposer] = Ether(10_000_000) + challenger, err := addrs.Address(devkeys.ChainOperatorKey{ + ChainID: new(big.Int).SetUint64(l2Cfg.L2ChainID), + Role: devkeys.ChallengerRole, + }) + if err != nil { + return err + } + l1Cfg.Prefund[challenger] = Ether(10_000_000) + return nil +} + +func InteropL2DevConfig(l1ChainID, l2ChainID uint64, addrs devkeys.Addresses) (*L2Config, error) { + // Padded chain ID, hex encoded, prefixed with 0xff like inboxes, then 0x02 to signify devnet. + batchInboxAddress := common.HexToAddress(fmt.Sprintf("0xff02%016x", l2ChainID)) + chainOps := devkeys.ChainOperatorKeys(new(big.Int).SetUint64(l2ChainID)) + + deployer, err := addrs.Address(chainOps(devkeys.DeployerRole)) + if err != nil { + return nil, err + } + l1ProxyAdminOwner, err := addrs.Address(chainOps(devkeys.L1ProxyAdminOwnerRole)) + if err != nil { + return nil, err + } + l2ProxyAdminOwner, err := addrs.Address(chainOps(devkeys.L2ProxyAdminOwnerRole)) + if err != nil { + return nil, err + } + baseFeeVaultRecipient, err := addrs.Address(chainOps(devkeys.BaseFeeVaultRecipientRole)) + if err != nil { + return nil, err + } + l1FeeVaultRecipient, err := addrs.Address(chainOps(devkeys.L1FeeVaultRecipientRole)) + if err != nil { + return nil, err + } + sequencerFeeVaultRecipient, err := addrs.Address(chainOps(devkeys.SequencerFeeVaultRecipientRole)) + if err != nil { + return nil, err + } + sequencerP2P, err := addrs.Address(chainOps(devkeys.SequencerP2PRole)) + if err != nil { + return nil, err + } + batcher, err := addrs.Address(chainOps(devkeys.BatcherRole)) + if err != nil { + return nil, err + } + proposer, err := addrs.Address(chainOps(devkeys.ProposerRole)) + if err != nil { + return nil, err + } + challenger, err := addrs.Address(chainOps(devkeys.ChallengerRole)) + if err != nil { + return nil, err + } + systemConfigOwner, err := addrs.Address(chainOps(devkeys.SystemConfigOwner)) + if err != nil { + return nil, err + } + + l2Cfg := &L2Config{ + Deployer: deployer, + Proposer: proposer, + Challenger: challenger, + SystemConfigOwner: systemConfigOwner, + L2InitializationConfig: genesis.L2InitializationConfig{ + DevDeployConfig: genesis.DevDeployConfig{ + FundDevAccounts: true, + }, + L2GenesisBlockDeployConfig: genesis.L2GenesisBlockDeployConfig{ + L2GenesisBlockGasLimit: 30_000_000, + L2GenesisBlockBaseFeePerGas: (*hexutil.Big)(big.NewInt(params.InitialBaseFee)), + }, + OwnershipDeployConfig: genesis.OwnershipDeployConfig{ + ProxyAdminOwner: l2ProxyAdminOwner, + FinalSystemOwner: l1ProxyAdminOwner, + }, + L2VaultsDeployConfig: genesis.L2VaultsDeployConfig{ + BaseFeeVaultRecipient: baseFeeVaultRecipient, + L1FeeVaultRecipient: l1FeeVaultRecipient, + SequencerFeeVaultRecipient: sequencerFeeVaultRecipient, + BaseFeeVaultMinimumWithdrawalAmount: (*hexutil.Big)(Ether(10)), + L1FeeVaultMinimumWithdrawalAmount: (*hexutil.Big)(Ether(10)), + SequencerFeeVaultMinimumWithdrawalAmount: (*hexutil.Big)(Ether(10)), + BaseFeeVaultWithdrawalNetwork: "remote", + L1FeeVaultWithdrawalNetwork: "remote", + SequencerFeeVaultWithdrawalNetwork: "remote", + }, + GovernanceDeployConfig: genesis.GovernanceDeployConfig{ + EnableGovernance: false, + }, + GasPriceOracleDeployConfig: genesis.GasPriceOracleDeployConfig{ + GasPriceOracleBaseFeeScalar: 1368, + GasPriceOracleBlobBaseFeeScalar: 810949, + }, + GasTokenDeployConfig: genesis.GasTokenDeployConfig{ + UseCustomGasToken: false, + }, + OperatorDeployConfig: genesis.OperatorDeployConfig{ + P2PSequencerAddress: sequencerP2P, + BatchSenderAddress: batcher, + }, + EIP1559DeployConfig: genesis.EIP1559DeployConfig{ + EIP1559Elasticity: 6, + EIP1559Denominator: 50, + EIP1559DenominatorCanyon: 250, + }, + UpgradeScheduleDeployConfig: genesis.UpgradeScheduleDeployConfig{ + L2GenesisRegolithTimeOffset: new(hexutil.Uint64), + L2GenesisCanyonTimeOffset: new(hexutil.Uint64), + L2GenesisDeltaTimeOffset: new(hexutil.Uint64), + L2GenesisEcotoneTimeOffset: new(hexutil.Uint64), + L2GenesisFjordTimeOffset: new(hexutil.Uint64), + L2GenesisGraniteTimeOffset: new(hexutil.Uint64), + L2GenesisInteropTimeOffset: new(hexutil.Uint64), + L1CancunTimeOffset: new(hexutil.Uint64), + UseInterop: true, + }, + L2CoreDeployConfig: genesis.L2CoreDeployConfig{ + L1ChainID: l1ChainID, + L2ChainID: l2ChainID, + L2BlockTime: 2, + FinalizationPeriodSeconds: 2, // instant output finalization + MaxSequencerDrift: 300, + SequencerWindowSize: 200, + ChannelTimeoutBedrock: 120, + BatchInboxAddress: batchInboxAddress, + SystemConfigStartBlock: 0, + }, + AltDADeployConfig: genesis.AltDADeployConfig{ + UseAltDA: false, + }, + }, + Prefund: make(map[common.Address]*big.Int), + } + + // TODO(#11887): consider making the number of prefunded keys configurable. + l2Users := devkeys.ChainUserKeys(new(big.Int).SetUint64(l2ChainID)) + for i := uint64(0); i < 20; i++ { + userAddr, err := addrs.Address(l2Users(i)) + if err != nil { + return nil, fmt.Errorf("failed to get L2 user addr %d: %w", i, err) + } + l2Cfg.Prefund[userAddr] = Ether(10_000_000) + } + + l2Cfg.Prefund[l2ProxyAdminOwner] = Ether(10_000_000) + + return l2Cfg, nil +} + +var etherScalar = new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil) + +// Ether converts a uint64 Ether amount into a *big.Int amount in wei units, for allocating test balances. +func Ether(v uint64) *big.Int { + return new(big.Int).Mul(new(big.Int).SetUint64(v), etherScalar) +} diff --git a/op-e2e/interop_recipe_test.go b/op-e2e/interop_recipe_test.go new file mode 100644 index 000000000000..a7a5b9ee3466 --- /dev/null +++ b/op-e2e/interop_recipe_test.go @@ -0,0 +1,46 @@ +package op_e2e + +import ( + "encoding/json" + "os" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-chain-ops/devkeys" + "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" + "github.com/ethereum-optimism/optimism/op-chain-ops/interopgen" + "github.com/ethereum-optimism/optimism/op-service/testlog" +) + +func TestInteropDevRecipe(t *testing.T) { + InitParallel(t) + + rec := interopgen.InteropDevRecipe{ + L1ChainID: 900100, + L2ChainIDs: []uint64{900200, 900201}, + GenesisTimestamp: uint64(1234567), + } + hd, err := devkeys.NewMnemonicDevKeys(devkeys.TestMnemonic) + require.NoError(t, err) + worldCfg, err := rec.Build(hd) + require.NoError(t, err) + + logger := testlog.Logger(t, log.LevelDebug) + require.NoError(t, worldCfg.Check(logger)) + + fa := foundry.OpenArtifactsDir("../packages/contracts-bedrock/forge-artifacts") + srcFS := foundry.NewSourceMapFS(os.DirFS("../packages/contracts-bedrock")) + + worldDeployment, worldOutput, err := interopgen.Deploy(logger, fa, srcFS, worldCfg) + require.NoError(t, err) + enc := json.NewEncoder(os.Stdout) + enc.SetIndent(" ", " ") + require.NoError(t, enc.Encode(worldDeployment)) + logger.Info("L1 output", "accounts", len(worldOutput.L1.Genesis.Alloc)) + for id, l2Output := range worldOutput.L2s { + logger.Info("L2 output", "chain", &id, "accounts", len(l2Output.Genesis.Alloc)) + } +} diff --git a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol index 4db20bab5871..49de2bc2e7da 100644 --- a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol +++ b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol @@ -372,7 +372,7 @@ contract DeployImplementations is Script { vm.broadcast(msg.sender); SystemConfig systemConfigImpl = new SystemConfig(); - vm.label(address(systemConfigImpl), "systemConfigImpl"); + vm.label(address(systemConfigImpl), "SystemConfigImpl"); _dio.set(_dio.systemConfigImpl.selector, address(systemConfigImpl)); } @@ -612,7 +612,7 @@ contract DeployImplementationsInterop is DeployImplementations { vm.broadcast(msg.sender); SystemConfigInterop systemConfigImpl = new SystemConfigInterop(); - vm.label(address(systemConfigImpl), "systemConfigImpl"); + vm.label(address(systemConfigImpl), "SystemConfigImpl"); _dio.set(_dio.systemConfigImpl.selector, address(systemConfigImpl)); } diff --git a/packages/contracts-bedrock/scripts/L2Genesis.s.sol b/packages/contracts-bedrock/scripts/L2Genesis.s.sol index 2dccb76e5118..2695a7dcc892 100644 --- a/packages/contracts-bedrock/scripts/L2Genesis.s.sol +++ b/packages/contracts-bedrock/scripts/L2Genesis.s.sol @@ -12,6 +12,7 @@ import { Config, OutputMode, OutputModeUtils, Fork, ForkUtils, LATEST_FORK } fro import { Artifacts } from "scripts/Artifacts.s.sol"; import { DeployConfig } from "scripts/deploy/DeployConfig.s.sol"; import { Process } from "scripts/libraries/Process.sol"; +import { SetPreinstalls } from "scripts/SetPreinstalls.s.sol"; // Contracts import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol"; @@ -131,6 +132,21 @@ contract L2Genesis is Deployer { runWithOptions(OutputMode.ALL, LATEST_FORK, artifactDependencies()); } + /// @notice This is used by new experimental interop deploy tooling. + function runWithEnv() public { + // The setUp() is skipped (since we insert a custom DeployConfig, and do not use Artifacts) + deployer = makeAddr("deployer"); + runWithOptions( + OutputMode.NONE, + Config.fork(), + L1Dependencies({ + l1CrossDomainMessengerProxy: payable(vm.envAddress("L2GENESIS_L1CrossDomainMessengerProxy")), + l1StandardBridgeProxy: payable(vm.envAddress("L2GENESIS_L1StandardBridgeProxy")), + l1ERC721BridgeProxy: payable(vm.envAddress("L2GENESIS_L1ERC721BridgeProxy")) + }) + ); + } + /// @notice This is used by foundry tests to enable the latest fork with the /// given L1 dependencies. function runWithLatestLocal(L1Dependencies memory _l1Dependencies) public { @@ -540,30 +556,11 @@ contract L2Genesis is Deployer { } /// @notice Sets all the preinstalls. - /// Warning: the creator-accounts of the preinstall contracts have 0 nonce values. - /// When performing a regular user-initiated contract-creation of a preinstall, - /// the creation will fail (but nonce will be bumped and not blocked). - /// The preinstalls themselves are all inserted with a nonce of 1, reflecting regular user execution. - function setPreinstalls() internal { - _setPreinstallCode(Preinstalls.MultiCall3); - _setPreinstallCode(Preinstalls.Create2Deployer); - _setPreinstallCode(Preinstalls.Safe_v130); - _setPreinstallCode(Preinstalls.SafeL2_v130); - _setPreinstallCode(Preinstalls.MultiSendCallOnly_v130); - _setPreinstallCode(Preinstalls.SafeSingletonFactory); - _setPreinstallCode(Preinstalls.DeterministicDeploymentProxy); - _setPreinstallCode(Preinstalls.MultiSend_v130); - _setPreinstallCode(Preinstalls.Permit2); - _setPreinstallCode(Preinstalls.SenderCreator_v060); // ERC 4337 v0.6.0 - _setPreinstallCode(Preinstalls.EntryPoint_v060); // ERC 4337 v0.6.0 - _setPreinstallCode(Preinstalls.SenderCreator_v070); // ERC 4337 v0.7.0 - _setPreinstallCode(Preinstalls.EntryPoint_v070); // ERC 4337 v0.7.0 - _setPreinstallCode(Preinstalls.BeaconBlockRoots); - _setPreinstallCode(Preinstalls.CreateX); - // 4788 sender nonce must be incremented, since it's part of later upgrade-transactions. - // For the upgrade-tx to not create a contract that conflicts with an already-existing copy, - // the nonce must be bumped. - vm.setNonce(Preinstalls.BeaconBlockRootsSender, 1); + function setPreinstalls() public { + address tmpSetPreinstalls = address(uint160(uint256(keccak256("SetPreinstalls")))); + vm.etch(tmpSetPreinstalls, vm.getDeployedCode("SetPreinstalls.s.sol:SetPreinstalls")); + SetPreinstalls(tmpSetPreinstalls).setPreinstalls(); + vm.etch(tmpSetPreinstalls, ""); } /// @notice Activate Ecotone network upgrade. @@ -590,17 +587,6 @@ contract L2Genesis is Deployer { return impl; } - /// @notice Sets the bytecode in state - function _setPreinstallCode(address _addr) internal { - string memory cname = Preinstalls.getName(_addr); - console.log("Setting %s preinstall code at: %s", cname, _addr); - vm.etch(_addr, Preinstalls.getDeployedCode(_addr, cfg.l2ChainID())); - // during testing in a shared L1/L2 account namespace some preinstalls may already have been inserted and used. - if (vm.getNonce(_addr) == 0) { - vm.setNonce(_addr, 1); - } - } - /// @notice Writes the genesis allocs, i.e. the state dump, to disk function writeGenesisAllocs(string memory _path) public { /// Reset so its not included state dump diff --git a/packages/contracts-bedrock/scripts/SetPreinstalls.s.sol b/packages/contracts-bedrock/scripts/SetPreinstalls.s.sol new file mode 100644 index 000000000000..46e68a17c941 --- /dev/null +++ b/packages/contracts-bedrock/scripts/SetPreinstalls.s.sol @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Script } from "forge-std/Script.sol"; +import { console2 as console } from "forge-std/console2.sol"; + +import { Preinstalls } from "src/libraries/Preinstalls.sol"; + +/// @title SetPreinstalls +/// @notice Sets all preinstalls in the VM state. There is no default "run()" entrypoint, +/// as this is used in L2Genesis.s.sol, and standalone in the Go test setup for L1 state. +contract SetPreinstalls is Script { + /// @notice Sets all the preinstalls. + /// Warning: the creator-accounts of the preinstall contracts have 0 nonce values. + /// When performing a regular user-initiated contract-creation of a preinstall, + /// the creation will fail (but nonce will be bumped and not blocked). + /// The preinstalls themselves are all inserted with a nonce of 1, reflecting regular user execution. + function setPreinstalls() public { + _setPreinstallCode(Preinstalls.MultiCall3); + _setPreinstallCode(Preinstalls.Create2Deployer); + _setPreinstallCode(Preinstalls.Safe_v130); + _setPreinstallCode(Preinstalls.SafeL2_v130); + _setPreinstallCode(Preinstalls.MultiSendCallOnly_v130); + _setPreinstallCode(Preinstalls.SafeSingletonFactory); + _setPreinstallCode(Preinstalls.DeterministicDeploymentProxy); + _setPreinstallCode(Preinstalls.MultiSend_v130); + _setPreinstallCode(Preinstalls.Permit2); + _setPreinstallCode(Preinstalls.SenderCreator_v060); // ERC 4337 v0.6.0 + _setPreinstallCode(Preinstalls.EntryPoint_v060); // ERC 4337 v0.6.0 + _setPreinstallCode(Preinstalls.SenderCreator_v070); // ERC 4337 v0.7.0 + _setPreinstallCode(Preinstalls.EntryPoint_v070); // ERC 4337 v0.7.0 + _setPreinstallCode(Preinstalls.BeaconBlockRoots); + _setPreinstallCode(Preinstalls.CreateX); + // 4788 sender nonce must be incremented, since it's part of later upgrade-transactions. + // For the upgrade-tx to not create a contract that conflicts with an already-existing copy, + // the nonce must be bumped. + vm.setNonce(Preinstalls.BeaconBlockRootsSender, 1); + } + + /// @notice Sets the bytecode in state + function _setPreinstallCode(address _addr) internal { + string memory cname = Preinstalls.getName(_addr); + console.log("Setting %s preinstall code at: %s", cname, _addr); + vm.etch(_addr, Preinstalls.getDeployedCode(_addr, block.chainid)); + // during testing in a shared L1/L2 account namespace some preinstalls may already have been inserted and used. + if (vm.getNonce(_addr) == 0) { + vm.setNonce(_addr, 1); + } + } +} diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 8da2618e4d8a..966fdf33a6bb 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -60,8 +60,8 @@ "sourceCodeHash": "0x06a50ac992175fdb434b13e8461893e83862c23ce399e697e6e8109728ad1a3d" }, "src/L1/SystemConfigInterop.sol": { - "initCodeHash": "0xc5a3ffc59dd7bf1ef238087414cfa04b37f0d83fc9a4f5e6d62a1059a23359f3", - "sourceCodeHash": "0xd7b6ebf03ead541917b1bdfcf1293ca3c8a8e3865b8a8548bee69956a4ce71cc" + "initCodeHash": "0x1f500e310170769ffc747e08ad1d5b0de4b0f58534001bc4d4d563ec058bb331", + "sourceCodeHash": "0xcb6008cb49a06f87eb5b6cb4651e5e4aafe0b1f33000eccd165226c04f6b63c6" }, "src/L2/BaseFeeVault.sol": { "initCodeHash": "0x3bfcd57e25ad54b66c374f63e24e33a6cf107044aa8f5f69ef21202c380b5c5b", diff --git a/packages/contracts-bedrock/src/L1/SystemConfigInterop.sol b/packages/contracts-bedrock/src/L1/SystemConfigInterop.sol index f948459f5e38..ee5b052e04ec 100644 --- a/packages/contracts-bedrock/src/L1/SystemConfigInterop.sol +++ b/packages/contracts-bedrock/src/L1/SystemConfigInterop.sol @@ -52,8 +52,8 @@ contract SystemConfigInterop is SystemConfig { address _dependencyManager ) external - initializer { + // This method has an initializer modifier, and will revert if already initialized. initialize({ _owner: _owner, _basefeeScalar: _basefeeScalar, From c8d6dbb4b332d74225062acfd84d1191a6f1b832 Mon Sep 17 00:00:00 2001 From: mbaxter Date: Fri, 13 Sep 2024 16:57:35 -0400 Subject: [PATCH 140/264] cannon: Handle preimage bounds checks consistently (#11911) * cannon: Handle preimage bounds checks consistently * cannon: Cleanup stray comment --- cannon/mipsevm/exec/preimage.go | 4 +- .../multithreaded/testutil/expectations.go | 14 ++-- cannon/mipsevm/tests/evm_common_test.go | 82 +++++++++++++++++++ cannon/mipsevm/testutil/mips.go | 71 ++++++++++------ cannon/mipsevm/testutil/state.go | 15 ++++ .../contracts-bedrock/test/cannon/MIPS.t.sol | 9 +- 6 files changed, 160 insertions(+), 35 deletions(-) diff --git a/cannon/mipsevm/exec/preimage.go b/cannon/mipsevm/exec/preimage.go index 117ebeb810cc..15c1f98e9530 100644 --- a/cannon/mipsevm/exec/preimage.go +++ b/cannon/mipsevm/exec/preimage.go @@ -57,8 +57,8 @@ func (p *TrackingPreimageOracleReader) ReadPreimage(key [32]byte, offset uint32) p.lastPreimage = preimage } p.lastPreimageOffset = offset - if offset > uint32(len(preimage)) { - return + if offset >= uint32(len(preimage)) { + panic("Preimage offset out-of-bounds") } datLen = uint32(copy(dat[:], preimage[offset:])) return diff --git a/cannon/mipsevm/multithreaded/testutil/expectations.go b/cannon/mipsevm/multithreaded/testutil/expectations.go index 56b5ee747c76..24158be8e235 100644 --- a/cannon/mipsevm/multithreaded/testutil/expectations.go +++ b/cannon/mipsevm/multithreaded/testutil/expectations.go @@ -22,6 +22,7 @@ type ExpectedMTState struct { Step uint64 LastHint hexutil.Bytes MemoryRoot common.Hash + expectedMemory *memory.Memory // Threading-related expectations StepsSinceLastContextSwitch uint64 Wakeup uint32 @@ -34,7 +35,6 @@ type ExpectedMTState struct { prestateActiveThreadOrig ExpectedThreadState // Cached for internal use ActiveThreadId uint32 threadExpectations map[uint32]*ExpectedThreadState - memoryExpectations *memory.Memory } type ExpectedThreadState struct { @@ -83,7 +83,7 @@ func NewExpectedMTState(fromState *multithreaded.State) *ExpectedMTState { prestateActiveThreadOrig: *newExpectedThreadState(currentThread), // Cache prestate thread for internal use ActiveThreadId: currentThread.ThreadId, threadExpectations: expectedThreads, - memoryExpectations: fromState.Memory.Copy(), + expectedMemory: fromState.Memory.Copy(), } } @@ -113,14 +113,14 @@ func (e *ExpectedMTState) ExpectStep() { } func (e *ExpectedMTState) ExpectMemoryWrite(addr uint32, val uint32) { - e.memoryExpectations.SetMemory(addr, val) - e.MemoryRoot = e.memoryExpectations.MerkleRoot() + e.expectedMemory.SetMemory(addr, val) + e.MemoryRoot = e.expectedMemory.MerkleRoot() } func (e *ExpectedMTState) ExpectMemoryWriteMultiple(addr uint32, val uint32, addr2 uint32, val2 uint32) { - e.memoryExpectations.SetMemory(addr, val) - e.memoryExpectations.SetMemory(addr2, val) - e.MemoryRoot = e.memoryExpectations.MerkleRoot() + e.expectedMemory.SetMemory(addr, val) + e.expectedMemory.SetMemory(addr2, val) + e.MemoryRoot = e.expectedMemory.MerkleRoot() } func (e *ExpectedMTState) ExpectPreemption(preState *multithreaded.State) { diff --git a/cannon/mipsevm/tests/evm_common_test.go b/cannon/mipsevm/tests/evm_common_test.go index ea6c7b2de957..9c4619fb2fc2 100644 --- a/cannon/mipsevm/tests/evm_common_test.go +++ b/cannon/mipsevm/tests/evm_common_test.go @@ -2,6 +2,7 @@ package tests import ( "bytes" + "encoding/binary" "fmt" "io" "os" @@ -12,12 +13,14 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/require" "github.com/ethereum-optimism/optimism/cannon/mipsevm/exec" "github.com/ethereum-optimism/optimism/cannon/mipsevm/memory" "github.com/ethereum-optimism/optimism/cannon/mipsevm/program" "github.com/ethereum-optimism/optimism/cannon/mipsevm/testutil" + preimage "github.com/ethereum-optimism/optimism/op-preimage" ) func TestEVM(t *testing.T) { @@ -227,6 +230,85 @@ func TestEVM_MMap(t *testing.T) { } } +func TestEVM_SysRead_Preimage(t *testing.T) { + var tracer *tracing.Hooks + + preimageValue := make([]byte, 0, 8) + preimageValue = binary.BigEndian.AppendUint32(preimageValue, 0x12_34_56_78) + preimageValue = binary.BigEndian.AppendUint32(preimageValue, 0x98_76_54_32) + + versions := GetMipsVersionTestCases(t) + + cases := []struct { + name string + addr uint32 + count uint32 + writeLen uint32 + preimageOffset uint32 + prestateMem uint32 + postateMem uint32 + shouldPanic bool + }{ + {name: "Aligned addr, write 1 byte", addr: 0x00_00_FF_00, count: 1, writeLen: 1, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x12_FF_FF_FF}, + {name: "Aligned addr, write 2 byte", addr: 0x00_00_FF_00, count: 2, writeLen: 2, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x12_34_FF_FF}, + {name: "Aligned addr, write 3 byte", addr: 0x00_00_FF_00, count: 3, writeLen: 3, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x12_34_56_FF}, + {name: "Aligned addr, write 4 byte", addr: 0x00_00_FF_00, count: 4, writeLen: 4, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x12_34_56_78}, + {name: "1-byte misaligned addr, write 1 byte", addr: 0x00_00_FF_01, count: 1, writeLen: 1, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_12_FF_FF}, + {name: "1-byte misaligned addr, write 2 byte", addr: 0x00_00_FF_01, count: 2, writeLen: 2, preimageOffset: 9, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_34_56_FF}, + {name: "1-byte misaligned addr, write 3 byte", addr: 0x00_00_FF_01, count: 3, writeLen: 3, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_12_34_56}, + {name: "2-byte misaligned addr, write 1 byte", addr: 0x00_00_FF_02, count: 1, writeLen: 1, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_12_FF}, + {name: "2-byte misaligned addr, write 2 byte", addr: 0x00_00_FF_02, count: 2, writeLen: 2, preimageOffset: 12, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_98_76}, + {name: "3-byte misaligned addr, write 1 byte", addr: 0x00_00_FF_03, count: 1, writeLen: 1, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_FF_12}, + {name: "Count of 0", addr: 0x00_00_FF_03, count: 0, writeLen: 0, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_FF_FF}, + {name: "Count greater than 4", addr: 0x00_00_FF_00, count: 15, writeLen: 4, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x12_34_56_78}, + {name: "Count greater than 4, unaligned", addr: 0x00_00_FF_01, count: 15, writeLen: 3, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_12_34_56}, + {name: "Offset at last byte", addr: 0x00_00_FF_00, count: 4, writeLen: 1, preimageOffset: 15, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x32_FF_FF_FF}, + {name: "Offset just out of bounds", addr: 0x00_00_FF_00, count: 4, writeLen: 0, preimageOffset: 16, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_FF_FF, shouldPanic: true}, + {name: "Offset out of bounds", addr: 0x00_00_FF_00, count: 4, writeLen: 0, preimageOffset: 17, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_FF_FF, shouldPanic: true}, + } + for i, c := range cases { + for _, v := range versions { + tName := fmt.Sprintf("%v (%v)", c.name, v.Name) + t.Run(tName, func(t *testing.T) { + effAddr := 0xFFffFFfc & c.addr + preimageKey := preimage.Keccak256Key(crypto.Keccak256Hash(preimageValue)).PreimageKey() + oracle := testutil.StaticOracle(t, preimageValue) + goVm := v.VMFactory(oracle, os.Stdout, os.Stderr, testutil.CreateLogger(), testutil.WithRandomization(int64(i)), testutil.WithPreimageKey(preimageKey), testutil.WithPreimageOffset(c.preimageOffset)) + state := goVm.GetState() + step := state.GetStep() + + // Set up state + state.GetRegistersRef()[2] = exec.SysRead + state.GetRegistersRef()[4] = exec.FdPreimageRead + state.GetRegistersRef()[5] = c.addr + state.GetRegistersRef()[6] = c.count + state.GetMemory().SetMemory(state.GetPC(), syscallInsn) + state.GetMemory().SetMemory(effAddr, c.prestateMem) + + // Setup expectations + expected := testutil.NewExpectedState(state) + expected.ExpectStep() + expected.Registers[2] = c.writeLen + expected.Registers[7] = 0 // no error + expected.PreimageOffset += c.writeLen + expected.ExpectMemoryWrite(effAddr, c.postateMem) + + if c.shouldPanic { + require.Panics(t, func() { _, _ = goVm.Step(true) }) + testutil.AssertPreimageOracleReverts(t, preimageKey, preimageValue, c.preimageOffset, v.Contracts, tracer) + } else { + stepWitness, err := goVm.Step(true) + require.NoError(t, err) + + // Check expectations + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, tracer) + } + }) + } + } +} + func TestEVMSysWriteHint(t *testing.T) { var tracer *tracing.Hooks diff --git a/cannon/mipsevm/testutil/mips.go b/cannon/mipsevm/testutil/mips.go index ac9d8b2b3092..33ada41869d7 100644 --- a/cannon/mipsevm/testutil/mips.go +++ b/cannon/mipsevm/testutil/mips.go @@ -21,19 +21,24 @@ import ( ) type MIPSEVM struct { + sender vm.AccountRef + startingGas uint64 env *vm.EVM evmState *state.StateDB addrs *Addresses localOracle mipsevm.PreimageOracle artifacts *Artifacts // Track step execution for logging purposes - lastStep uint64 - lastStepInput []byte + lastStep uint64 + lastStepInput []byte + lastPreimageOracleInput []byte } func NewMIPSEVM(contracts *ContractMetadata) *MIPSEVM { env, evmState := NewEVMEnv(contracts) - return &MIPSEVM{env, evmState, contracts.Addresses, nil, contracts.Artifacts, math.MaxUint64, nil} + sender := vm.AccountRef{0x13, 0x37} + startingGas := uint64(30_000_000) + return &MIPSEVM{sender, startingGas, env, evmState, contracts.Addresses, nil, contracts.Artifacts, math.MaxUint64, nil, nil} } func (m *MIPSEVM) SetTracer(tracer *tracing.Hooks) { @@ -52,23 +57,23 @@ func (m *MIPSEVM) SetSourceMapTracer(t *testing.T, version MipsVersion) { func (m *MIPSEVM) Step(t *testing.T, stepWitness *mipsevm.StepWitness, step uint64, stateHashFn mipsevm.HashFn) []byte { m.lastStep = step m.lastStepInput = nil - sender := common.Address{0x13, 0x37} - startingGas := uint64(30_000_000) + m.lastPreimageOracleInput = nil // we take a snapshot so we can clean up the state, and isolate the logs of this instruction run. snap := m.env.StateDB.Snapshot() if stepWitness.HasPreimage() { t.Logf("reading preimage key %x at offset %d", stepWitness.PreimageKey, stepWitness.PreimageOffset) - poInput, err := EncodePreimageOracleInput(t, stepWitness, mipsevm.LocalContext{}, m.localOracle, m.artifacts.Oracle) + poInput, err := m.encodePreimageOracleInput(t, stepWitness.PreimageKey, stepWitness.PreimageValue, stepWitness.PreimageOffset, mipsevm.LocalContext{}) + m.lastPreimageOracleInput = poInput require.NoError(t, err, "encode preimage oracle input") - _, leftOverGas, err := m.env.Call(vm.AccountRef(sender), m.addrs.Oracle, poInput, startingGas, common.U2560) - require.NoErrorf(t, err, "evm should not fail, took %d gas", startingGas-leftOverGas) + _, leftOverGas, err := m.env.Call(m.sender, m.addrs.Oracle, poInput, m.startingGas, common.U2560) + require.NoErrorf(t, err, "evm should not fail, took %d gas", m.startingGas-leftOverGas) } input := EncodeStepInput(t, stepWitness, mipsevm.LocalContext{}, m.artifacts.MIPS) m.lastStepInput = input - ret, leftOverGas, err := m.env.Call(vm.AccountRef(sender), m.addrs.MIPS, input, startingGas, common.U2560) + ret, leftOverGas, err := m.env.Call(m.sender, m.addrs.MIPS, input, m.startingGas, common.U2560) require.NoError(t, err, "evm should not fail") require.Len(t, ret, 32, "expecting 32-byte state hash") // remember state hash, to check it against state @@ -82,7 +87,7 @@ func (m *MIPSEVM) Step(t *testing.T, stepWitness *mipsevm.StepWitness, step uint require.Equal(t, stateHash, postHash, "logged state must be accurate") m.env.StateDB.RevertToSnapshot(snap) - t.Logf("EVM step %d took %d gas, and returned stateHash %s", step, startingGas-leftOverGas, postHash) + t.Logf("EVM step %d took %d gas, and returned stateHash %s", step, m.startingGas-leftOverGas, postHash) return evmPost } @@ -92,46 +97,48 @@ func EncodeStepInput(t *testing.T, wit *mipsevm.StepWitness, localContext mipsev return input } -func EncodePreimageOracleInput(t *testing.T, wit *mipsevm.StepWitness, localContext mipsevm.LocalContext, localOracle mipsevm.PreimageOracle, oracle *foundry.Artifact) ([]byte, error) { - if wit.PreimageKey == ([32]byte{}) { +func (m *MIPSEVM) encodePreimageOracleInput(t *testing.T, preimageKey [32]byte, preimageValue []byte, preimageOffset uint32, localContext mipsevm.LocalContext) ([]byte, error) { + if preimageKey == ([32]byte{}) { return nil, errors.New("cannot encode pre-image oracle input, witness has no pre-image to proof") } + localOracle := m.localOracle + oracle := m.artifacts.Oracle - switch preimage.KeyType(wit.PreimageKey[0]) { + switch preimage.KeyType(preimageKey[0]) { case preimage.LocalKeyType: - if len(wit.PreimageValue) > 32+8 { - return nil, fmt.Errorf("local pre-image exceeds maximum size of 32 bytes with key 0x%x", wit.PreimageKey) + if len(preimageValue) > 32+8 { + return nil, fmt.Errorf("local pre-image exceeds maximum size of 32 bytes with key 0x%x", preimageKey) } - preimagePart := wit.PreimageValue[8:] + preimagePart := preimageValue[8:] var tmp [32]byte copy(tmp[:], preimagePart) input, err := oracle.ABI.Pack("loadLocalData", - new(big.Int).SetBytes(wit.PreimageKey[1:]), + new(big.Int).SetBytes(preimageKey[1:]), localContext, tmp, new(big.Int).SetUint64(uint64(len(preimagePart))), - new(big.Int).SetUint64(uint64(wit.PreimageOffset)), + new(big.Int).SetUint64(uint64(preimageOffset)), ) require.NoError(t, err) return input, nil case preimage.Keccak256KeyType: input, err := oracle.ABI.Pack( "loadKeccak256PreimagePart", - new(big.Int).SetUint64(uint64(wit.PreimageOffset)), - wit.PreimageValue[8:]) + new(big.Int).SetUint64(uint64(preimageOffset)), + preimageValue[8:]) require.NoError(t, err) return input, nil case preimage.PrecompileKeyType: if localOracle == nil { return nil, errors.New("local oracle is required for precompile preimages") } - preimage := localOracle.GetPreimage(preimage.Keccak256Key(wit.PreimageKey).PreimageKey()) + preimage := localOracle.GetPreimage(preimage.Keccak256Key(preimageKey).PreimageKey()) precompile := common.BytesToAddress(preimage[:20]) requiredGas := binary.BigEndian.Uint64(preimage[20:28]) callInput := preimage[28:] input, err := oracle.ABI.Pack( "loadPrecompilePreimagePart", - new(big.Int).SetUint64(uint64(wit.PreimageOffset)), + new(big.Int).SetUint64(uint64(preimageOffset)), precompile, requiredGas, callInput, @@ -140,15 +147,23 @@ func EncodePreimageOracleInput(t *testing.T, wit *mipsevm.StepWitness, localCont return input, nil default: return nil, fmt.Errorf("unsupported pre-image type %d, cannot prepare preimage with key %x offset %d for oracle", - wit.PreimageKey[0], wit.PreimageKey, wit.PreimageOffset) + preimageKey[0], preimageKey, preimageOffset) } } +func (m *MIPSEVM) assertPreimageOracleReverts(t *testing.T, preimageKey [32]byte, preimageValue []byte, preimageOffset uint32) { + poInput, err := m.encodePreimageOracleInput(t, preimageKey, preimageValue, preimageOffset, mipsevm.LocalContext{}) + require.NoError(t, err, "encode preimage oracle input") + _, _, evmErr := m.env.Call(m.sender, m.addrs.Oracle, poInput, m.startingGas, common.U2560) + + require.ErrorContains(t, evmErr, "execution reverted") +} + func LogStepFailureAtCleanup(t *testing.T, mipsEvm *MIPSEVM) { t.Cleanup(func() { if t.Failed() { // Note: For easier debugging of a failing step, see MIPS.t.sol#test_step_debug_succeeds() - t.Logf("Failed while executing step %d with input: %x", mipsEvm.lastStep, mipsEvm.lastStepInput) + t.Logf("Failed while executing step %d with\n\tstep input: %x\n\tpreimageOracle input: %x", mipsEvm.lastStep, mipsEvm.lastStepInput, mipsEvm.lastPreimageOracleInput) } }) } @@ -184,3 +199,11 @@ func AssertEVMReverts(t *testing.T, state mipsevm.FPVMState, contracts *Contract logs := evmState.Logs() require.Equal(t, 0, len(logs)) } + +func AssertPreimageOracleReverts(t *testing.T, preimageKey [32]byte, preimageValue []byte, preimageOffset uint32, contracts *ContractMetadata, tracer *tracing.Hooks) { + evm := NewMIPSEVM(contracts) + evm.SetTracer(tracer) + LogStepFailureAtCleanup(t, evm) + + evm.assertPreimageOracleReverts(t, preimageKey, preimageValue, preimageOffset) +} diff --git a/cannon/mipsevm/testutil/state.go b/cannon/mipsevm/testutil/state.go index 3b912c8dd067..3aee7a4539c5 100644 --- a/cannon/mipsevm/testutil/state.go +++ b/cannon/mipsevm/testutil/state.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ethereum-optimism/optimism/cannon/mipsevm" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/memory" ) func CopyRegisters(state mipsevm.FPVMState) *[32]uint32 { @@ -115,6 +116,7 @@ type ExpectedState struct { LastHint hexutil.Bytes Registers [32]uint32 MemoryRoot common.Hash + expectedMemory *memory.Memory } func NewExpectedState(fromState mipsevm.FPVMState) *ExpectedState { @@ -132,9 +134,22 @@ func NewExpectedState(fromState mipsevm.FPVMState) *ExpectedState { LastHint: fromState.GetLastHint(), Registers: *fromState.GetRegistersRef(), MemoryRoot: fromState.GetMemory().MerkleRoot(), + expectedMemory: fromState.GetMemory().Copy(), } } +func (e *ExpectedState) ExpectStep() { + // Set some standard expectations for a normal step + e.Step += 1 + e.PC += 4 + e.NextPC += 4 +} + +func (e *ExpectedState) ExpectMemoryWrite(addr uint32, val uint32) { + e.expectedMemory.SetMemory(addr, val) + e.MemoryRoot = e.expectedMemory.MerkleRoot() +} + type StateValidationFlags int // TODO(cp-983) - Remove these validation hacks diff --git a/packages/contracts-bedrock/test/cannon/MIPS.t.sol b/packages/contracts-bedrock/test/cannon/MIPS.t.sol index db74c713de07..9aafbdb5421d 100644 --- a/packages/contracts-bedrock/test/cannon/MIPS.t.sol +++ b/packages/contracts-bedrock/test/cannon/MIPS.t.sol @@ -27,10 +27,15 @@ contract MIPS_Test is CommonTest { /// For example, in cannon/mipsevm/evm_test.go step input can be pulled here: /// https://github.com/ethereum-optimism/optimism/blob/1f64dd6db5561f3bb76ed1d1ffdaff0cde9b7c4b/cannon/mipsevm/evm_test.go#L80-L80 function test_step_debug_succeeds() external { + bytes memory oracleInput = + hex"e15926110000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000081234567898765432000000000000000000000000000000000000000000000000"; + (bool oracleSuccess,) = address(oracle).call(oracleInput); + assertTrue(oracleSuccess); + bytes memory input = - hex"e14ced3200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e29d9267b33909f55f0cac54cca6427fc17fe0b9efe6c34350ca86605145633fe60000000000000000000000000000000000000000000000000000000000000000000000000008a82c0008a8300000000000000000050000000000000000000000000a000000000008a82c0000000000000000000000007fffd00400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007fffd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007008fbc00601000ffbd00000000afbffffc27bdfffcafbf000027bdfff4afa400048fb000408fb100448fb200488fb3004c8fb400508fb600548fb800588fb9005caf0ea4ff7928d10f76bc70a73c867e2c9232b35112b060285aedb7b33533e5253d8c8392c902f20c8314d10a807c7bc5de8126736a03c2bdb47667bbfa710375ac2064c969079ba2acbb688f31cd2bdd4cbe18111a8e733c487884d541f1366231e3c23a71546c755f18517db871301ffe7b08676258520720f4cb2fcc23642ddb778fcfd0cfc38a190d5b8bf0bea4e1ce7d2f35d6a068b94cf6d925e0a024d571f505296c77e19f2ea496d88d90cd342189bdedb389ac959bb9b82db9e324d150eb233dbfa0746469950cec5d4f6360fa49f835403946268bf6fa7472bc4a1320e6a7387a6272dcbf4f8280ff680ccedd4b79f02c78eaef3218c1e78f9e266b3b1c7c1c24e7d04470d63c4e1df858f2e7bf9c7cdad07ed51bc383f80a4d3ded70f2c60642ed3c85483b60ea68b5ed606b2f84d90ac876c01c4d01ba58c431390bd20a29a10d408854c7f62a262860ebd3e4af402fa2dcc0662dfa36fd3e85cbab4da3e3d0907392666337a62e5a663c04bc0a3e16d559f825ba2d40a1c81f4d3844b6cfb2e084a80eb9338fad62b25cf83f4738b5c4df1a0ef019e8ebb9d03d8c7e091f91c853d19da08da2245b01b806c73dc0b200672d04e78982eaed71ea20929c6c472715d5c74a31176a5663348a3c02c89ff5edb7cf3041110e8fe44e2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd95a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3774df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6834d8ef8faaf96b7b45235297538a266eb882b8b5680f621aab3417d43cdc2eb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3021ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a193440eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968a60155a81a637d8581c4d275380f7dd05bd2dd27ac3fb7ca905e7aec4e0a1cd99867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756afcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8923490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99cc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8beccda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d22733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd95a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3774df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619eff0eb509051ae684fe17ee4373a3c82e88f970dab89cc0915d21b63cb96415cc2b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0"; + hex"e14ced3200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e2d0637506e48299469d82d71a947c6771e7d3eaa3db30b44b30b3ac6ba6596c79029df7322a2404a59aebdffb81ab72dd22cc4459131675e63231b2c693676cf100000008f1f85ff4f1f85ff82ad7bda1e5acea1049e0bfd000001f5b0412ffd341c045e665389becadf100000fa3c64fbd7f000000050000ff00000000015b3d97166d1aec28829f3dd43d8cf1f9358e4103b16d09d466e2c7c048ea3ba1aef3141e700270581aa0b75b50e34fc926bb2d83bb3938f8506d442d5e545ba3a5d214515c11955d8ad50cfb04a6a0e484a2a29f1d688138c1883f289a45a6d5d9c37ebe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3021ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a193440eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f839867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756afcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8923490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99cc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8beccda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d22733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd95a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3774df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618df7a66599e9dd7409a7d8de62e29bea7821f0f19cfb783952bff507c87eba2365ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3021ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a193440eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f839867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756afcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8923490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99cc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8beccda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d22733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd95a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3774df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d53cee4e252442dad999b85c644aa0a6fd8bca90f35f1a5ae696cb8d9eb5a35be"; (bool success, bytes memory retVal) = address(mips).call(input); - bytes memory expectedRetVal = hex"03611b9f88f952fea10b9330e85fbe7b8ddd0d457d3f31e647434a5330789212"; + bytes memory expectedRetVal = hex"03dacdac4e61d89774a305dd0828063706ad878bb6353c0c2cd787d1e5cddd67"; assertTrue(success); assertEq(retVal.length, 32, "Expect a bytes32 hash of the post-state to be returned"); From f70248a0ace5375d578e99697df7a5a1bd2d20ee Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 13 Sep 2024 18:07:38 -0400 Subject: [PATCH 141/264] feat: Scaffolding for DeployAuthSystemInput (#11890) * feat: Scaffolding for DeployAuthSystemInput * feat: Scaffolding for DeployAuthSystem Output * feat: Address feedback and remove comments --- .../scripts/DeployAuthSystem.s.sol | 24 +++++++ .../test/DeployAuthSystem.t.sol | 63 ++++++++++++++++++- .../fixtures/test-deploy-auth-system-out.toml | 1 + 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 packages/contracts-bedrock/test/fixtures/test-deploy-auth-system-out.toml diff --git a/packages/contracts-bedrock/scripts/DeployAuthSystem.s.sol b/packages/contracts-bedrock/scripts/DeployAuthSystem.s.sol index 99b079e3e578..13ac34ea48c8 100644 --- a/packages/contracts-bedrock/scripts/DeployAuthSystem.s.sol +++ b/packages/contracts-bedrock/scripts/DeployAuthSystem.s.sol @@ -52,3 +52,27 @@ contract DeployAuthSystemInput is CommonBase { return _owners; } } + +contract DeployAuthSystemOutput is CommonBase { + Safe internal _safe; + + function set(bytes4 sel, address _address) public { + if (sel == this.safe.selector) _safe = Safe(payable(_address)); + else revert("DeployAuthSystemOutput: unknown selector"); + } + + function writeOutputFile(string memory _outfile) public { + string memory out = vm.serializeAddress("outfile", "safe", address(this.safe())); + vm.writeToml(out, _outfile); + } + + function checkOutput() public view { + address[] memory addrs = Solarray.addresses(address(this.safe())); + DeployUtils.assertValidContractAddresses(addrs); + } + + function safe() public view returns (Safe) { + DeployUtils.assertValidContractAddress(address(_safe)); + return _safe; + } +} diff --git a/packages/contracts-bedrock/test/DeployAuthSystem.t.sol b/packages/contracts-bedrock/test/DeployAuthSystem.t.sol index eca6724d904a..60eb27ba1c3a 100644 --- a/packages/contracts-bedrock/test/DeployAuthSystem.t.sol +++ b/packages/contracts-bedrock/test/DeployAuthSystem.t.sol @@ -5,7 +5,7 @@ import { Test } from "forge-std/Test.sol"; import { stdToml } from "forge-std/StdToml.sol"; import { Solarray } from "scripts/libraries/Solarray.sol"; -import { DeployAuthSystemInput } from "scripts/DeployAuthSystem.s.sol"; +import { DeployAuthSystemInput, DeployAuthSystemOutput } from "scripts/DeployAuthSystem.s.sol"; contract DeployAuthSystemInput_Test is Test { DeployAuthSystemInput dasi; @@ -55,3 +55,64 @@ contract DeployAuthSystemInput_Test is Test { dasi.set(dasi.owners.selector, owners); } } + +contract DeployAuthSystemOutput_Test is Test { + using stdToml for string; + + DeployAuthSystemOutput daso; + + function setUp() public { + daso = new DeployAuthSystemOutput(); + } + + function test_set_succeeds() public { + address safeAddr = makeAddr("safe"); + + // Ensure the address has code, since it's expected to be a contract + vm.etch(safeAddr, hex"01"); + + // Set the output data + daso.set(daso.safe.selector, safeAddr); + + // Compare the test data to the getter method + assertEq(safeAddr, address(daso.safe()), "100"); + } + + function test_getter_whenNotSet_reverts() public { + vm.expectRevert("DeployUtils: zero address"); + daso.safe(); + } + + function test_getter_whenAddrHasNoCode_reverts() public { + address emptyAddr = makeAddr("emptyAddr"); + bytes memory expectedErr = bytes(string.concat("DeployUtils: no code at ", vm.toString(emptyAddr))); + + daso.set(daso.safe.selector, emptyAddr); + vm.expectRevert(expectedErr); + daso.safe(); + } + + function test_writeOutputFile_succeeds() public { + string memory root = vm.projectRoot(); + + // Use the expected data from the test fixture. + string memory expOutPath = string.concat(root, "/test/fixtures/test-deploy-auth-system-out.toml"); + string memory expOutToml = vm.readFile(expOutPath); + + address expSafe = expOutToml.readAddress(".safe"); + + // Etch code at each address so the code checks pass when settings values. + vm.etch(expSafe, hex"01"); + + daso.set(daso.safe.selector, expSafe); + + string memory actOutPath = string.concat(root, "/.testdata/test-deploy-auth-system-output.toml"); + daso.writeOutputFile(actOutPath); + string memory actOutToml = vm.readFile(actOutPath); + + // Clean up before asserting so that we don't leave any files behind. + vm.removeFile(actOutPath); + + assertEq(expOutToml, actOutToml); + } +} diff --git a/packages/contracts-bedrock/test/fixtures/test-deploy-auth-system-out.toml b/packages/contracts-bedrock/test/fixtures/test-deploy-auth-system-out.toml new file mode 100644 index 000000000000..35465cae1942 --- /dev/null +++ b/packages/contracts-bedrock/test/fixtures/test-deploy-auth-system-out.toml @@ -0,0 +1 @@ +safe = "0xDC93f9959c0F9c3849461B6468B4592a19567E09" From 5e14a61547a45eef2ebeba677aee4a049f106ed8 Mon Sep 17 00:00:00 2001 From: Axel Kingsley Date: Fri, 13 Sep 2024 18:08:06 -0500 Subject: [PATCH 142/264] Interop: SuperSystem for E2E Tests (#11850) * op-e2e: interop test setup (work in progress) * op-e2e: interop test setup * organization and comment updates * refactor creation code into WIP system2 * save secrets per L2 * Add SuperSystem Interface ; Add Users and Transactions * Further Refactoring ; Fix Test * Add Supervisor * Add Supervisor Client * Comment out Proposer * Add AddL2RPC to Supervisor Client * Fully link Supervisor and OP Node in E2E Test * correct RPC call supervisor_checkBlock * Make EOF acceptable for backend check * final structure names * Change unused functions to _ for linter * fix import order * Add Github Issue Numbers to TODOs * tynes comments: add World Resource as configurable --------- Co-authored-by: protolambda --- op-e2e/e2eutils/setuputils/utils.go | 31 + op-e2e/interop/interop_test.go | 85 +++ op-e2e/interop/supersystem.go | 616 ++++++++++++++++++ op-e2e/sequencer_failover_setup.go | 3 +- op-e2e/setup.go | 27 +- op-e2e/tx_helper.go | 10 +- op-service/sources/supervisor_client.go | 21 +- op-supervisor/supervisor/backend/backend.go | 10 +- .../backend/source/chain_processor.go | 3 + op-supervisor/supervisor/service.go | 10 +- 10 files changed, 784 insertions(+), 32 deletions(-) create mode 100644 op-e2e/e2eutils/setuputils/utils.go create mode 100644 op-e2e/interop/interop_test.go create mode 100644 op-e2e/interop/supersystem.go diff --git a/op-e2e/e2eutils/setuputils/utils.go b/op-e2e/e2eutils/setuputils/utils.go new file mode 100644 index 000000000000..9c82f3a5602d --- /dev/null +++ b/op-e2e/e2eutils/setuputils/utils.go @@ -0,0 +1,31 @@ +package setuputils + +import ( + "crypto/ecdsa" + "time" + + "github.com/ethereum/go-ethereum/common/hexutil" + + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-service/endpoint" + "github.com/ethereum-optimism/optimism/op-service/txmgr" +) + +func hexPriv(in *ecdsa.PrivateKey) string { + b := e2eutils.EncodePrivKey(in) + return hexutil.Encode(b) +} + +func NewTxMgrConfig(l1Addr endpoint.RPC, privKey *ecdsa.PrivateKey) txmgr.CLIConfig { + return txmgr.CLIConfig{ + L1RPCURL: l1Addr.RPC(), + PrivateKey: hexPriv(privKey), + NumConfirmations: 1, + SafeAbortNonceTooLowCount: 3, + FeeLimitMultiplier: 5, + ResubmissionTimeout: 3 * time.Second, + ReceiptQueryInterval: 50 * time.Millisecond, + NetworkTimeout: 2 * time.Second, + TxNotInMempoolTimeout: 2 * time.Minute, + } +} diff --git a/op-e2e/interop/interop_test.go b/op-e2e/interop/interop_test.go new file mode 100644 index 000000000000..04f0081e5f3f --- /dev/null +++ b/op-e2e/interop/interop_test.go @@ -0,0 +1,85 @@ +package interop + +import ( + "context" + "math/big" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-chain-ops/interopgen" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + "github.com/stretchr/testify/require" +) + +// TestInteropTrivial tests a simple interop scenario +// Chains A and B exist, but no messages are sent between them +// and in fact no event-logs are emitted by either chain at all. +// A transaction is sent from Alice to Bob on Chain A. +// The balance of Bob on Chain A is checked before and after the tx. +// The balance of Bob on Chain B is checked after the tx. +func TestInteropTrivial(t *testing.T) { + recipe := interopgen.InteropDevRecipe{ + L1ChainID: 900100, + L2ChainIDs: []uint64{900200, 900201}, + GenesisTimestamp: uint64(time.Now().Unix() + 3), // start chain 3 seconds from now + } + worldResources := worldResourcePaths{ + foundryArtifacts: "../../packages/contracts-bedrock/forge-artifacts", + sourceMap: "../../packages/contracts-bedrock", + } + + // create a super system from the recipe + // and get the L2 IDs for use in the test + s2 := NewSuperSystem(t, &recipe, worldResources) + ids := s2.L2IDs() + + // chainA is the first L2 chain + chainA := ids[0] + // chainB is the second L2 chain + chainB := ids[1] + + // create two users on all L2 chains + s2.AddUser("Alice") + s2.AddUser("Bob") + + bobAddr := s2.Address(chainA, "Bob") + + // check the balance of Bob + clientA := s2.L2GethClient(chainA) + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + bobBalance, err := clientA.BalanceAt(ctx, bobAddr, nil) + require.NoError(t, err) + expectedBalance, _ := big.NewInt(0).SetString("10000000000000000000000000", 10) + require.Equal(t, expectedBalance, bobBalance) + + // send a tx from Alice to Bob + s2.SendL2Tx( + chainA, + "Alice", + func(l2Opts *op_e2e.TxOpts) { + l2Opts.ToAddr = &bobAddr + l2Opts.Value = big.NewInt(1000000) + l2Opts.GasFeeCap = big.NewInt(1_000_000_000) + l2Opts.GasTipCap = big.NewInt(1_000_000_000) + }, + ) + + // check the balance of Bob after the tx + ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + bobBalance, err = clientA.BalanceAt(ctx, bobAddr, nil) + require.NoError(t, err) + expectedBalance, _ = big.NewInt(0).SetString("10000000000000000001000000", 10) + require.Equal(t, expectedBalance, bobBalance) + + // check that the balance of Bob on ChainB hasn't changed + bobAddrB := s2.Address(chainB, "Bob") + clientB := s2.L2GethClient(chainB) + ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + bobBalance, err = clientB.BalanceAt(ctx, bobAddrB, nil) + require.NoError(t, err) + expectedBalance, _ = big.NewInt(0).SetString("10000000000000000000000000", 10) + require.Equal(t, expectedBalance, bobBalance) +} diff --git a/op-e2e/interop/supersystem.go b/op-e2e/interop/supersystem.go new file mode 100644 index 000000000000..c33ac9affc82 --- /dev/null +++ b/op-e2e/interop/supersystem.go @@ -0,0 +1,616 @@ +package interop + +import ( + "context" + "crypto/ecdsa" + "math/big" + "os" + "path" + "path/filepath" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rpc" + + bss "github.com/ethereum-optimism/optimism/op-batcher/batcher" + batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" + "github.com/ethereum-optimism/optimism/op-chain-ops/devkeys" + "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" + "github.com/ethereum-optimism/optimism/op-chain-ops/interopgen" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/fakebeacon" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/opnode" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/services" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/setuputils" + "github.com/ethereum-optimism/optimism/op-node/node" + "github.com/ethereum-optimism/optimism/op-node/p2p" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/ethereum-optimism/optimism/op-node/rollup/driver" + "github.com/ethereum-optimism/optimism/op-node/rollup/sync" + l2os "github.com/ethereum-optimism/optimism/op-proposer/proposer" + "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/clock" + "github.com/ethereum-optimism/optimism/op-service/dial" + "github.com/ethereum-optimism/optimism/op-service/endpoint" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum-optimism/optimism/op-service/metrics" + "github.com/ethereum-optimism/optimism/op-service/oppprof" + oprpc "github.com/ethereum-optimism/optimism/op-service/rpc" + "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/ethereum-optimism/optimism/op-service/testlog" + supervisorConfig "github.com/ethereum-optimism/optimism/op-supervisor/config" + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor" +) + +// SuperSystem is an interface for the system (collection of connected resources) +// it provides a way to get the resources for a network by network ID +// and provides a way to get the list of network IDs +// this is useful for testing multiple network backends, +// for example, interopE2ESystem is the default implementation, but a shim to +// kurtosis or another testing framework could be implemented +type SuperSystem interface { + // get the supervisor + Supervisor() *supervisor.SupervisorService + // get the supervisor client + SupervisorClient() *sources.SupervisorClient + // get the batcher for a network + Batcher(network string) *bss.BatcherService + // get the proposer for a network + Proposer(network string) *l2os.ProposerService + // get the opnode for a network + OpNode(network string) *opnode.Opnode + // get the geth instance for a network + L2Geth(network string) *geth.GethInstance + // get the L2 geth client for a network + L2GethClient(network string) *ethclient.Client + // get the secret for a network and role + L2OperatorKey(network string, role devkeys.ChainOperatorRole) ecdsa.PrivateKey + // get the list of network IDs + L2IDs() []string + // register a username to an account on all L2s + AddUser(username string) + // get the user key for a user on an L2 + UserKey(id, username string) ecdsa.PrivateKey + // send a transaction on an L2 on the given network, from the given user + SendL2Tx(network string, username string, applyTxOpts op_e2e.TxOptsFn) *types.Receipt + // get the address for a user on an L2 + Address(network string, username string) common.Address +} + +// NewSuperSystem creates a new SuperSystem from a recipe. It creates an interopE2ESystem. +func NewSuperSystem(t *testing.T, recipe *interopgen.InteropDevRecipe, w worldResourcePaths) SuperSystem { + s2 := &interopE2ESystem{recipe: recipe} + s2.prepare(t, w) + return s2 +} + +// interopE2ESystem implements the SuperSystem interface +// it prepares network resources and provides access to them +// the functionality is broken down into smaller functions so that +// the system can be prepared iteratively if desired +type interopE2ESystem struct { + t *testing.T + recipe *interopgen.InteropDevRecipe + logger log.Logger + hdWallet *devkeys.MnemonicDevKeys + worldDeployment *interopgen.WorldDeployment + worldOutput *interopgen.WorldOutput + beacon *fakebeacon.FakeBeacon + l1 *geth.GethInstance + l2s map[string]l2Set + l2GethClients map[string]*ethclient.Client + supervisor *supervisor.SupervisorService + superClient *sources.SupervisorClient +} + +// l2Set is a set of resources for an L2 chain +type l2Set struct { + chainID *big.Int + opNode *opnode.Opnode + l2Geth *geth.GethInstance + proposer *l2os.ProposerService + batcher *bss.BatcherService + operatorKeys map[devkeys.ChainOperatorRole]ecdsa.PrivateKey + userKeys map[string]ecdsa.PrivateKey +} + +// prepareHDWallet creates a new HD wallet to derive keys from +func (s *interopE2ESystem) prepareHDWallet() *devkeys.MnemonicDevKeys { + hdWallet, err := devkeys.NewMnemonicDevKeys(devkeys.TestMnemonic) + require.NoError(s.t, err) + return hdWallet +} + +type worldResourcePaths struct { + foundryArtifacts string + sourceMap string +} + +// prepareWorld creates the world configuration from the recipe and deploys it +func (s *interopE2ESystem) prepareWorld(w worldResourcePaths) (*interopgen.WorldDeployment, *interopgen.WorldOutput) { + // Build the world configuration from the recipe and the HD wallet + worldCfg, err := s.recipe.Build(s.hdWallet) + require.NoError(s.t, err) + + // create a logger for the world configuration + logger := s.logger.New("role", "world") + require.NoError(s.t, worldCfg.Check(logger)) + + // create the foundry artifacts and source map + foundryArtifacts := foundry.OpenArtifactsDir(w.foundryArtifacts) + sourceMap := foundry.NewSourceMapFS(os.DirFS(w.sourceMap)) + + // deploy the world, using the logger, foundry artifacts, source map, and world configuration + worldDeployment, worldOutput, err := interopgen.Deploy(logger, foundryArtifacts, sourceMap, worldCfg) + require.NoError(s.t, err) + + return worldDeployment, worldOutput +} + +// prepareL1 creates the L1 chain resources +func (s *interopE2ESystem) prepareL1() (*fakebeacon.FakeBeacon, *geth.GethInstance) { + // Create a fake Beacon node to hold on to blobs created by the L1 miner, and to serve them to L2 + genesisTimestampL1 := s.worldOutput.L1.Genesis.Timestamp + blockTimeL1 := uint64(6) + blobPath := s.t.TempDir() + bcn := fakebeacon.NewBeacon(s.logger.New("role", "l1_cl"), + filepath.Join(blobPath, "l1_cl"), genesisTimestampL1, blockTimeL1) + s.t.Cleanup(func() { + _ = bcn.Close() + }) + require.NoError(s.t, bcn.Start("127.0.0.1:0")) + beaconApiAddr := bcn.BeaconAddr() + require.NotEmpty(s.t, beaconApiAddr, "beacon API listener must be up") + + l1FinalizedDistance := uint64(3) + l1Clock := clock.SystemClock + // Start the L1 chain + l1Geth, err := geth.InitL1( + blockTimeL1, + l1FinalizedDistance, + s.worldOutput.L1.Genesis, + l1Clock, + filepath.Join(blobPath, "l1_el"), + bcn) + + require.NoError(s.t, err) + require.NoError(s.t, l1Geth.Node.Start()) + s.t.Cleanup(func() { + _ = l1Geth.Close() + }) + return bcn, l1Geth +} + +// newOperatorKeysForL2 creates the operator keys for an L2 chain +// it uses an L2Output to determine the chain ID and configuration, +// and then makes a key for each operator role [SequencerP2PRole, ProposerRole, BatcherRole] +func (s *interopE2ESystem) newOperatorKeysForL2(l2Out *interopgen.L2Output) map[devkeys.ChainOperatorRole]ecdsa.PrivateKey { + // Create operatorKeys for the L2 chain actors + operatorKeys := map[devkeys.ChainOperatorRole]ecdsa.PrivateKey{} + // create the sequencer P2P secret + seqP2PSecret, err := s.hdWallet.Secret(devkeys.ChainOperatorKey{ + ChainID: l2Out.Genesis.Config.ChainID, + Role: devkeys.SequencerP2PRole, + }) + require.NoError(s.t, err) + operatorKeys[devkeys.SequencerP2PRole] = *seqP2PSecret + // create the proposer secret + proposerSecret, err := s.hdWallet.Secret(devkeys.ChainOperatorKey{ + ChainID: l2Out.Genesis.Config.ChainID, + Role: devkeys.ProposerRole, + }) + require.NoError(s.t, err) + operatorKeys[devkeys.ProposerRole] = *proposerSecret + // create the batcher secret + batcherSecret, err := s.hdWallet.Secret(devkeys.ChainOperatorKey{ + ChainID: l2Out.Genesis.Config.ChainID, + Role: devkeys.BatcherRole, + }) + require.NoError(s.t, err) + operatorKeys[devkeys.BatcherRole] = *batcherSecret + return operatorKeys +} + +// newGethForL2 creates a new Geth instance for an L2 chain +func (s *interopE2ESystem) newGethForL2(id string, l2Out *interopgen.L2Output) *geth.GethInstance { + jwtPath := writeDefaultJWT(s.t) + name := "l2-" + id + l2Geth, err := geth.InitL2(name, l2Out.Genesis, jwtPath) + require.NoError(s.t, err) + require.NoError(s.t, l2Geth.Node.Start()) + s.t.Cleanup(func() { + _ = l2Geth.Close() + }) + return l2Geth +} + +// newNodeForL2 creates a new Opnode for an L2 chain +func (s *interopE2ESystem) newNodeForL2( + id string, + l2Out *interopgen.L2Output, + operatorKeys map[devkeys.ChainOperatorRole]ecdsa.PrivateKey, + l2Geth *geth.GethInstance, +) *opnode.Opnode { + logger := s.logger.New("role", "op-node-"+id) + p2pKey := operatorKeys[devkeys.SequencerP2PRole] + nodeCfg := &node.Config{ + L1: &node.PreparedL1Endpoint{ + Client: client.NewBaseRPCClient(endpoint.DialRPC( + endpoint.PreferAnyRPC, + s.l1.UserRPC(), + mustDial(s.t, logger))), + TrustRPC: false, + RPCProviderKind: sources.RPCKindDebugGeth, + }, + L2: &node.L2EndpointConfig{ + L2EngineAddr: l2Geth.AuthRPC().RPC(), + L2EngineJWTSecret: testingJWTSecret, + }, + Beacon: &node.L1BeaconEndpointConfig{ + BeaconAddr: s.beacon.BeaconAddr(), + }, + Driver: driver.Config{ + SequencerEnabled: true, + }, + Rollup: *l2Out.RollupCfg, + P2PSigner: &p2p.PreparedSigner{ + Signer: p2p.NewLocalSigner(&p2pKey)}, + RPC: node.RPCConfig{ + ListenAddr: "127.0.0.1", + ListenPort: 0, + EnableAdmin: true, + }, + Supervisor: &node.SupervisorEndpointConfig{ + SupervisorAddr: s.supervisor.RPC(), + }, + P2P: nil, // disabled P2P setup for now + L1EpochPollInterval: time.Second * 2, + RuntimeConfigReloadInterval: 0, + Tracer: nil, + Sync: sync.Config{ + SyncMode: sync.CLSync, + SkipSyncStartCheck: false, + SupportsPostFinalizationELSync: false, + }, + ConfigPersistence: node.DisabledConfigPersistence{}, + } + opNode, err := opnode.NewOpnode(logger.New("service", "op-node"), + nodeCfg, func(err error) { + s.t.Error(err) + }) + require.NoError(s.t, err) + s.t.Cleanup(func() { + ctx, cancel := context.WithCancel(context.Background()) + cancel() // force-quit + _ = opNode.Stop(ctx) + }) + return opNode +} + +// newProposerForL2 creates a new Proposer for an L2 chain +// it is currently unused, as the generated world does not have a DisputeGameFactoryProxy +// TODO(#11888): name this function "newProposerForL2" and use it in the prepareL2s function when the DisputeGameFactoryProxy is available +func (s *interopE2ESystem) _( + id string, + operatorKeys map[devkeys.ChainOperatorRole]ecdsa.PrivateKey, + opNode *opnode.Opnode, +) *l2os.ProposerService { + proposerSecret := operatorKeys[devkeys.ProposerRole] + logger := s.logger.New("role", "proposer"+id) + proposerCLIConfig := &l2os.CLIConfig{ + L1EthRpc: s.l1.UserRPC().RPC(), + RollupRpc: opNode.UserRPC().RPC(), + DGFAddress: s.worldDeployment.L2s[id].DisputeGameFactoryProxy.Hex(), + ProposalInterval: 6 * time.Second, + DisputeGameType: 254, // Fast game type + PollInterval: 500 * time.Millisecond, + TxMgrConfig: setuputils.NewTxMgrConfig(s.l1.UserRPC(), &proposerSecret), + AllowNonFinalized: false, + LogConfig: oplog.CLIConfig{ + Level: log.LvlInfo, + Format: oplog.FormatText, + }, + } + proposer, err := l2os.ProposerServiceFromCLIConfig( + context.Background(), + "0.0.1", + proposerCLIConfig, + logger.New("service", "proposer")) + require.NoError(s.t, err, "must start proposer") + require.NoError(s.t, proposer.Start(context.Background())) + s.t.Cleanup(func() { + ctx, cancel := context.WithCancel(context.Background()) + cancel() // force-quit + _ = proposer.Stop(ctx) + }) + return proposer +} + +// newBatcherForL2 creates a new Batcher for an L2 chain +func (s *interopE2ESystem) newBatcherForL2( + id string, + operatorKeys map[devkeys.ChainOperatorRole]ecdsa.PrivateKey, + l2Geth *geth.GethInstance, + opNode *opnode.Opnode, +) *bss.BatcherService { + batcherSecret := operatorKeys[devkeys.BatcherRole] + logger := s.logger.New("role", "batcher"+id) + batcherCLIConfig := &bss.CLIConfig{ + L1EthRpc: s.l1.UserRPC().RPC(), + L2EthRpc: l2Geth.UserRPC().RPC(), + RollupRpc: opNode.UserRPC().RPC(), + MaxPendingTransactions: 1, + MaxChannelDuration: 1, + MaxL1TxSize: 120_000, + TestUseMaxTxSizeForBlobs: false, + TargetNumFrames: 1, + ApproxComprRatio: 0.4, + SubSafetyMargin: 4, + PollInterval: 50 * time.Millisecond, + TxMgrConfig: setuputils.NewTxMgrConfig(s.l1.UserRPC(), &batcherSecret), + LogConfig: oplog.CLIConfig{ + Level: log.LevelInfo, + Format: oplog.FormatText, + }, + Stopped: false, + BatchType: derive.SpanBatchType, + MaxBlocksPerSpanBatch: 10, + DataAvailabilityType: batcherFlags.CalldataType, + CompressionAlgo: derive.Brotli, + } + batcher, err := bss.BatcherServiceFromCLIConfig( + context.Background(), "0.0.1", batcherCLIConfig, + logger.New("service", "batcher")) + require.NoError(s.t, err) + require.NoError(s.t, batcher.Start(context.Background())) + s.t.Cleanup(func() { + ctx, cancel := context.WithCancel(context.Background()) + cancel() // force-quit + _ = batcher.Stop(ctx) + }) + return batcher +} + +// newL2 creates a new L2, starting with the L2Output from the world configuration +// and iterating through the resources needed for the L2. +// it returns a l2Set with the resources for the L2 +func (s *interopE2ESystem) newL2(id string, l2Out *interopgen.L2Output) l2Set { + operatorKeys := s.newOperatorKeysForL2(l2Out) + l2Geth := s.newGethForL2(id, l2Out) + opNode := s.newNodeForL2(id, l2Out, operatorKeys, l2Geth) + // TODO(#11886): proposer does not work with the generated world as there is no DisputeGameFactoryProxy + //proposer := s.newProposerForL2(id, operatorKeys, opNode) + batcher := s.newBatcherForL2(id, operatorKeys, l2Geth, opNode) + + return l2Set{ + chainID: l2Out.Genesis.Config.ChainID, + opNode: opNode, + l2Geth: l2Geth, + proposer: nil, + batcher: batcher, + operatorKeys: operatorKeys, + userKeys: make(map[string]ecdsa.PrivateKey), + } +} + +// prepareSupervisor creates a new supervisor for the system +func (s *interopE2ESystem) prepareSupervisor() *supervisor.SupervisorService { + logger := s.logger.New("role", "supervisor") + cfg := supervisorConfig.Config{ + MetricsConfig: metrics.CLIConfig{ + Enabled: false, + }, + PprofConfig: oppprof.CLIConfig{ + ListenEnabled: false, + }, + LogConfig: oplog.CLIConfig{ + Level: log.LevelTrace, + Format: oplog.FormatText, + }, + RPC: oprpc.CLIConfig{ + ListenAddr: "127.0.0.1", + ListenPort: 0, + EnableAdmin: true, + }, + L2RPCs: []string{}, + Datadir: path.Join(s.t.TempDir(), "supervisor"), + } + for id := range s.l2s { + cfg.L2RPCs = append(cfg.L2RPCs, s.l2s[id].l2Geth.UserRPC().RPC()) + } + // Create the supervisor with the configuration + super, err := supervisor.SupervisorFromConfig(context.Background(), &cfg, logger) + require.NoError(s.t, err) + // Start the supervisor + err = super.Start(context.Background()) + require.NoError(s.t, err) + s.t.Cleanup(func() { + ctx, cancel := context.WithCancel(context.Background()) + cancel() // force-quit + _ = super.Stop(ctx) + }) + return super +} + +// SupervisorClient returns the supervisor client for the system, creating it if it doesn't exist +func (s *interopE2ESystem) SupervisorClient() *sources.SupervisorClient { + if s.superClient != nil { + return s.superClient + } + cl, err := client.NewRPC(context.Background(), s.logger, s.supervisor.RPC()) + require.NoError(s.t, err, "failed to dial supervisor RPC") + superClient := sources.NewSupervisorClient(cl) + s.superClient = superClient + return superClient +} + +// prepare sets up the system for testing +// components are built iteratively, so that they can be reused or modified +// their creation can't be safely skipped or reordered at this time +func (s *interopE2ESystem) prepare(t *testing.T, w worldResourcePaths) { + s.t = t + s.logger = testlog.Logger(s.t, log.LevelInfo) + s.hdWallet = s.prepareHDWallet() + s.worldDeployment, s.worldOutput = s.prepareWorld(w) + + // the supervisor and client are created first so that the L2s can use the supervisor + s.supervisor = s.prepareSupervisor() + + s.beacon, s.l1 = s.prepareL1() + s.l2s = s.prepareL2s() + + // add the L2 RPCs to the supervisor now that the L2s are created + for _, l2 := range s.l2s { + err := s.SupervisorClient().AddL2RPC(context.Background(), l2.l2Geth.UserRPC().RPC()) + require.NoError(s.t, err, "failed to add L2 RPC to supervisor") + } +} + +// AddUser adds a user to the system by creating a user key for each L2. +// each user key is stored in the L2's userKeys map. +// because all user maps start empty, a users index should be the same for all L2s, +// but if in the future these maps can diverge, the indexes for username would also diverge +// NOTE: The first 20 accounts are implicitly funded by the Recipe's World Deployment +// see: op-chain-ops/interopgen/recipe.go +// TODO(#11887): make the funded account quantity specified in the recipe so SuperSystems can know which accounts are funded +func (s *interopE2ESystem) AddUser(username string) { + for id, l2 := range s.l2s { + bigID, _ := big.NewInt(0).SetString(id, 10) + userSecret, _ := s.hdWallet.Secret( + devkeys.ChainUserKey{ + ChainID: bigID, + Index: uint64(len(l2.userKeys)), + }, + ) + l2.userKeys[username] = *userSecret + } +} + +// UserKey returns the user key for a user on an L2 +func (s *interopE2ESystem) UserKey(id, username string) ecdsa.PrivateKey { + return s.l2s[id].userKeys[username] +} + +// Address returns the address for a user on an L2 +func (s *interopE2ESystem) Address(id, username string) common.Address { + secret := s.UserKey(id, username) + require.NotNil(s.t, secret, "no secret found for user %s", username) + return crypto.PubkeyToAddress(secret.PublicKey) +} + +// prepareL2s creates the L2s for the system, returning a map of L2s +func (s *interopE2ESystem) prepareL2s() map[string]l2Set { + l2s := make(map[string]l2Set) + for id, l2Out := range s.worldOutput.L2s { + l2s[id] = s.newL2(id, l2Out) + } + return l2s +} + +func (s *interopE2ESystem) L2GethClient(id string) *ethclient.Client { + // guard: check if the client already exists and return it in that case + nodeClient, ok := s.l2GethClients[id] + if ok { + return nodeClient + } + // create a new client for the L2 from the L2's geth instance + var ethClient services.EthInstance = s.L2Geth(id) + rpcEndpoint := ethClient.UserRPC() + rpcCl := endpoint.DialRPC( + endpoint.PreferAnyRPC, + rpcEndpoint, + func(v string) *rpc.Client { + logger := testlog.Logger(s.t, log.LevelInfo).New("node", id) + cl, err := dial.DialRPCClientWithTimeout(context.Background(), 30*time.Second, logger, v) + require.NoError(s.t, err, "failed to dial eth node instance %s", id) + return cl + }) + nodeClient = ethclient.NewClient(rpcCl) + // register the client so it can be reused + s.addL2GethClient(id, nodeClient) + return nodeClient +} + +func (sys *interopE2ESystem) addL2GethClient(name string, client *ethclient.Client) { + if sys.l2GethClients == nil { + sys.l2GethClients = make(map[string]*ethclient.Client) + } + sys.l2GethClients[name] = client +} + +// getter functions for L1 entities +func (s *interopE2ESystem) Supervisor() *supervisor.SupervisorService { + return s.supervisor +} + +// gettter functions for the individual L2s +func (s *interopE2ESystem) Batcher(id string) *bss.BatcherService { + return s.l2s[id].batcher +} +func (s *interopE2ESystem) Proposer(id string) *l2os.ProposerService { + return s.l2s[id].proposer +} +func (s *interopE2ESystem) OpNode(id string) *opnode.Opnode { + return s.l2s[id].opNode +} +func (s *interopE2ESystem) L2Geth(id string) *geth.GethInstance { + return s.l2s[id].l2Geth +} +func (s *interopE2ESystem) L2OperatorKey(id string, role devkeys.ChainOperatorRole) ecdsa.PrivateKey { + return s.l2s[id].operatorKeys[role] +} + +// L2IDs returns the list of L2 IDs, which are the keys of the L2s map +func (s *interopE2ESystem) L2IDs() []string { + ids := make([]string, 0, len(s.l2s)) + for id := range s.l2s { + ids = append(ids, id) + } + return ids +} + +// SendL2Tx sends an L2 transaction to the L2 with the given ID. +// it acts as a wrapper around op-e2e.SendL2TxWithID +// and uses the L2's chain ID, username key, and geth client. +func (s *interopE2ESystem) SendL2Tx( + id string, + sender string, + applyTxOpts op_e2e.TxOptsFn, +) *types.Receipt { + senderSecret := s.UserKey(id, sender) + require.NotNil(s.t, senderSecret, "no secret found for sender %s", sender) + return op_e2e.SendL2TxWithID( + s.t, + s.l2s[id].chainID, + s.L2GethClient(id), + &senderSecret, + applyTxOpts) +} + +func mustDial(t *testing.T, logger log.Logger) func(v string) *rpc.Client { + return func(v string) *rpc.Client { + cl, err := dial.DialRPCClientWithTimeout(context.Background(), 30*time.Second, logger, v) + require.NoError(t, err, "failed to dial") + return cl + } +} + +var testingJWTSecret = [32]byte{123} + +func writeDefaultJWT(t testing.TB) string { + // Sadly the geth node config cannot load JWT secret from memory, it has to be a file + jwtPath := path.Join(t.TempDir(), "jwt_secret") + if err := os.WriteFile(jwtPath, []byte(hexutil.Encode(testingJWTSecret[:])), 0o600); err != nil { + t.Fatalf("failed to prepare jwt file for geth: %v", err) + } + return jwtPath +} diff --git a/op-e2e/sequencer_failover_setup.go b/op-e2e/sequencer_failover_setup.go index 890c6269bdf1..77f8ef442d81 100644 --- a/op-e2e/sequencer_failover_setup.go +++ b/op-e2e/sequencer_failover_setup.go @@ -18,6 +18,7 @@ import ( con "github.com/ethereum-optimism/optimism/op-conductor/conductor" "github.com/ethereum-optimism/optimism/op-conductor/consensus" conrpc "github.com/ethereum-optimism/optimism/op-conductor/rpc" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/setuputils" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" rollupNode "github.com/ethereum-optimism/optimism/op-node/node" "github.com/ethereum-optimism/optimism/op-node/rollup" @@ -291,7 +292,7 @@ func setupBatcher(t *testing.T, sys *System, conductors map[string]*conductor) { ApproxComprRatio: 0.4, SubSafetyMargin: 4, PollInterval: 1 * time.Second, - TxMgrConfig: newTxMgrConfig(sys.EthInstances["l1"].UserRPC().RPC(), sys.Cfg.Secrets.Batcher), + TxMgrConfig: setuputils.NewTxMgrConfig(sys.EthInstances["l1"].UserRPC(), sys.Cfg.Secrets.Batcher), LogConfig: oplog.CLIConfig{ Level: log.LevelDebug, Format: oplog.FormatText, diff --git a/op-e2e/setup.go b/op-e2e/setup.go index ab2218b097d4..df7051c50626 100644 --- a/op-e2e/setup.go +++ b/op-e2e/setup.go @@ -50,6 +50,7 @@ import ( "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/opnode" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/services" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/setuputils" "github.com/ethereum-optimism/optimism/op-node/chaincfg" rollupNode "github.com/ethereum-optimism/optimism/op-node/node" "github.com/ethereum-optimism/optimism/op-node/p2p" @@ -68,7 +69,6 @@ import ( "github.com/ethereum-optimism/optimism/op-service/predeploys" "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-service/testlog" - "github.com/ethereum-optimism/optimism/op-service/txmgr" ) const ( @@ -82,20 +82,6 @@ var ( genesisTime = hexutil.Uint64(0) ) -func newTxMgrConfig(l1Addr string, privKey *ecdsa.PrivateKey) txmgr.CLIConfig { - return txmgr.CLIConfig{ - L1RPCURL: l1Addr, - PrivateKey: hexPriv(privKey), - NumConfirmations: 1, - SafeAbortNonceTooLowCount: 3, - FeeLimitMultiplier: 5, - ResubmissionTimeout: 3 * time.Second, - ReceiptQueryInterval: 50 * time.Millisecond, - NetworkTimeout: 2 * time.Second, - TxNotInMempoolTimeout: 2 * time.Minute, - } -} - func DefaultSystemConfig(t testing.TB) SystemConfig { config.ExternalL2TestParms.SkipIfNecessary(t) @@ -789,7 +775,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste ProposalInterval: 6 * time.Second, DisputeGameType: 254, // Fast game type PollInterval: 500 * time.Millisecond, - TxMgrConfig: newTxMgrConfig(sys.EthInstances[RoleL1].UserRPC().RPC(), cfg.Secrets.Proposer), + TxMgrConfig: setuputils.NewTxMgrConfig(sys.EthInstances[RoleL1].UserRPC(), cfg.Secrets.Proposer), AllowNonFinalized: cfg.NonFinalizedProposals, LogConfig: oplog.CLIConfig{ Level: log.LvlInfo, @@ -802,7 +788,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste RollupRpc: sys.RollupNodes[RoleSeq].UserRPC().RPC(), L2OOAddress: config.L1Deployments.L2OutputOracleProxy.Hex(), PollInterval: 500 * time.Millisecond, - TxMgrConfig: newTxMgrConfig(sys.EthInstances[RoleL1].UserRPC().RPC(), cfg.Secrets.Proposer), + TxMgrConfig: setuputils.NewTxMgrConfig(sys.EthInstances[RoleL1].UserRPC(), cfg.Secrets.Proposer), AllowNonFinalized: cfg.NonFinalizedProposals, LogConfig: oplog.CLIConfig{ Level: log.LvlInfo, @@ -865,7 +851,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste ApproxComprRatio: 0.4, SubSafetyMargin: 4, PollInterval: 50 * time.Millisecond, - TxMgrConfig: newTxMgrConfig(sys.EthInstances[RoleL1].UserRPC().RPC(), cfg.Secrets.Batcher), + TxMgrConfig: setuputils.NewTxMgrConfig(sys.EthInstances[RoleL1].UserRPC(), cfg.Secrets.Batcher), LogConfig: oplog.CLIConfig{ Level: log.LevelInfo, Format: oplog.FormatText, @@ -984,11 +970,6 @@ func (cfg SystemConfig) L2ChainIDBig() *big.Int { return new(big.Int).SetUint64(cfg.DeployConfig.L2ChainID) } -func hexPriv(in *ecdsa.PrivateKey) string { - b := e2eutils.EncodePrivKey(in) - return hexutil.Encode(b) -} - func (sys *System) RollupClient(name string) *sources.RollupClient { rollupClient, ok := sys.rollupClients[name] if ok { diff --git a/op-e2e/tx_helper.go b/op-e2e/tx_helper.go index 2a398728689c..86885bb862f9 100644 --- a/op-e2e/tx_helper.go +++ b/op-e2e/tx_helper.go @@ -84,11 +84,11 @@ func defaultDepositTxOpts(opts *bind.TransactOpts) *DepositTxOpts { // The supplied privKey is used to specify the account to send from and the transaction is sent to the supplied l2Client // Transaction options and expected status can be configured in the applyTxOpts function by modifying the supplied TxOpts // Will verify that the transaction is included with the expected status on l2Client and any clients added to TxOpts.VerifyClients -func SendL2Tx(t *testing.T, cfg SystemConfig, l2Client *ethclient.Client, privKey *ecdsa.PrivateKey, applyTxOpts TxOptsFn) *types.Receipt { +func SendL2TxWithID(t *testing.T, chainID *big.Int, l2Client *ethclient.Client, privKey *ecdsa.PrivateKey, applyTxOpts TxOptsFn) *types.Receipt { opts := defaultTxOpts() applyTxOpts(opts) - tx := types.MustSignNewTx(privKey, types.LatestSignerForChainID(cfg.L2ChainIDBig()), &types.DynamicFeeTx{ - ChainID: cfg.L2ChainIDBig(), + tx := types.MustSignNewTx(privKey, types.LatestSignerForChainID(chainID), &types.DynamicFeeTx{ + ChainID: chainID, Nonce: opts.Nonce, // Already have deposit To: opts.ToAddr, Value: opts.Value, @@ -115,6 +115,10 @@ func SendL2Tx(t *testing.T, cfg SystemConfig, l2Client *ethclient.Client, privKe return receipt } +func SendL2Tx(t *testing.T, cfg SystemConfig, l2Client *ethclient.Client, privKey *ecdsa.PrivateKey, applyTxOpts TxOptsFn) *types.Receipt { + return SendL2TxWithID(t, cfg.L2ChainIDBig(), l2Client, privKey, applyTxOpts) +} + type TxOptsFn func(opts *TxOpts) type TxOpts struct { diff --git a/op-service/sources/supervisor_client.go b/op-service/sources/supervisor_client.go index a13ea4782471..0b0b7a99b2f0 100644 --- a/op-service/sources/supervisor_client.go +++ b/op-service/sources/supervisor_client.go @@ -21,10 +21,29 @@ func NewSupervisorClient(client client.RPC) *SupervisorClient { } } +func (cl *SupervisorClient) AddL2RPC( + ctx context.Context, + rpc string, +) error { + var result error + err := cl.client.CallContext( + ctx, + &result, + "admin_addL2RPC", + rpc) + if err != nil { + return fmt.Errorf("failed to Add L2 to Supervisor (rpc: %s): %w", rpc, err) + } + return result +} + func (cl *SupervisorClient) CheckBlock(ctx context.Context, chainID types.ChainID, blockHash common.Hash, blockNumber uint64) (types.SafetyLevel, error) { var result types.SafetyLevel - err := cl.client.CallContext(ctx, &result, "interop_checkBlock", + err := cl.client.CallContext( + ctx, + &result, + "supervisor_checkBlock", (*hexutil.U256)(&chainID), blockHash, hexutil.Uint64(blockNumber)) if err != nil { return types.Unsafe, fmt.Errorf("failed to check Block %s:%d (chain %s): %w", blockHash, blockNumber, chainID, err) diff --git a/op-supervisor/supervisor/backend/backend.go b/op-supervisor/supervisor/backend/backend.go index ffc2c97e165c..7b4db31db205 100644 --- a/op-supervisor/supervisor/backend/backend.go +++ b/op-supervisor/supervisor/backend/backend.go @@ -25,7 +25,6 @@ import ( ) type SupervisorBackend struct { - ctx context.Context started atomic.Bool logger log.Logger m Metrics @@ -82,7 +81,7 @@ func NewSupervisorBackend(ctx context.Context, logger log.Logger, m Metrics, cfg // it does not expect to be called after the backend has been started func (su *SupervisorBackend) addFromRPC(ctx context.Context, logger log.Logger, rpc string) error { // create the rpc client, which yields the chain id - rpcClient, chainID, err := createRpcClient(su.ctx, logger, rpc) + rpcClient, chainID, err := createRpcClient(ctx, logger, rpc) if err != nil { return err } @@ -173,9 +172,11 @@ func (su *SupervisorBackend) AddL2RPC(ctx context.Context, rpc string) error { if err := su.Stop(ctx); err != nil { return fmt.Errorf("failed to stop backend: %w", err) } + su.logger.Info("temporarily stopped the backend to add a new L2 RPC", "rpc", rpc) if err := su.addFromRPC(ctx, su.logger, rpc); err != nil { return fmt.Errorf("failed to add chain monitor: %w", err) } + su.logger.Info("added the new L2 RPC, starting supervisor again", "rpc", rpc) return su.Start(ctx) } @@ -231,7 +232,10 @@ func (su *SupervisorBackend) CheckBlock(chainID *hexutil.U256, blockHash common. safest := types.CrossUnsafe // find the last log index in the block i, err := su.db.LastLogInBlock(types.ChainID(*chainID), uint64(blockNumber)) - if err != nil { + // TODO(#11836) checking for EOF as a non-error case is a bit of a code smell + // and could potentially be incorrect if the given block number is intentionally far in the future + if err != nil && !errors.Is(err, io.EOF) { + su.logger.Error("failed to scan block", "err", err) return types.Invalid, fmt.Errorf("failed to scan block: %w", err) } // at this point we have the extent of the block, and we can check if it is safe by various criteria diff --git a/op-supervisor/supervisor/backend/source/chain_processor.go b/op-supervisor/supervisor/backend/source/chain_processor.go index b2f60af904bf..714d9f2e4a6d 100644 --- a/op-supervisor/supervisor/backend/source/chain_processor.go +++ b/op-supervisor/supervisor/backend/source/chain_processor.go @@ -49,10 +49,13 @@ func NewChainProcessor(log log.Logger, client BlockByNumberSource, chain types.C } func (s *ChainProcessor) OnNewHead(ctx context.Context, head eth.L1BlockRef) { + s.log.Debug("Processing chain", "chain", s.chain, "head", head) if head.Number <= s.lastBlock.Number { + s.log.Info("head is not newer than last processed block", "head", head, "lastBlock", s.lastBlock) return } for s.lastBlock.Number+1 < head.Number { + s.log.Debug("Filling in skipped block", "chain", s.chain, "lastBlock", s.lastBlock, "head", head) blockNum := s.lastBlock.Number + 1 nextBlock, err := s.client.L1BlockRefByNumber(ctx, blockNum) if err != nil { diff --git a/op-supervisor/supervisor/service.go b/op-supervisor/supervisor/service.go index aecd90ad2fba..47fcb3e9ec23 100644 --- a/op-supervisor/supervisor/service.go +++ b/op-supervisor/supervisor/service.go @@ -164,6 +164,7 @@ func (su *SupervisorService) Start(ctx context.Context) error { } su.metrics.RecordUp() + su.log.Info("JSON-RPC Server started", "endpoint", su.rpcServer.Endpoint()) return nil } @@ -171,7 +172,7 @@ func (su *SupervisorService) Stop(ctx context.Context) error { if !su.closing.CompareAndSwap(false, true) { return nil // already closing } - + su.log.Info("Stopping JSON-RPC server") var result error if su.rpcServer != nil { if err := su.rpcServer.Stop(); err != nil { @@ -193,9 +194,16 @@ func (su *SupervisorService) Stop(ctx context.Context) error { result = errors.Join(result, fmt.Errorf("failed to stop metrics server: %w", err)) } } + su.log.Info("JSON-RPC server stopped") return result } func (su *SupervisorService) Stopped() bool { return su.closing.Load() } + +func (su *SupervisorService) RPC() string { + // the RPC endpoint is assumed to be HTTP + // TODO(#11032): make this flexible for ws if the server supports it + return "http://" + su.rpcServer.Endpoint() +} From 6cf35daa3bcf760f1b3927514e438caf087bfc17 Mon Sep 17 00:00:00 2001 From: Blaine Malone Date: Fri, 13 Sep 2024 20:24:10 -0400 Subject: [PATCH 143/264] feat: Front OPSM with Proxy and Initialize (#11875) * fix: getting stack underflow error. * feat: adding proxy infront of OPStackManager. * fix: PR comments, we're landing on using the initialize function over setRelease. * fix: rename function. * fix: nit * fix: infering proxy admin from superchain config. * fix: ran command: just pre-pr-no-build * fix: nits * fix: using CommonBase in DeployImplementations.s.sol. * op-chain-ops: pass superchain proxy admin address as input to deployments script --------- Co-authored-by: Matt Solomon Co-authored-by: protolambda --- op-chain-ops/interopgen/deploy.go | 1 + .../interopgen/deployers/implementations.go | 1 + .../scripts/DeployImplementations.s.sol | 75 ++++--- .../scripts/DeployOPChain.s.sol | 1 + .../scripts/libraries/DeployUtils.sol | 12 ++ packages/contracts-bedrock/semver-lock.json | 4 +- .../snapshots/abi/OPStackManager.json | 183 ++++++++++-------- .../snapshots/abi/OPStackManagerInterop.json | 183 ++++++++++-------- .../storageLayout/OPStackManager.json | 22 ++- .../storageLayout/OPStackManagerInterop.json | 22 ++- .../src/L1/OPStackManager.sol | 61 +++--- .../src/L1/OPStackManagerInterop.sol | 7 +- .../test/DeployImplementations.t.sol | 25 ++- .../test/L1/OPStackManager.t.sol | 21 +- packages/contracts-bedrock/test/Specs.t.sol | 4 +- .../test/vendor/Initializable.t.sol | 5 +- 16 files changed, 384 insertions(+), 243 deletions(-) diff --git a/op-chain-ops/interopgen/deploy.go b/op-chain-ops/interopgen/deploy.go index fc77cf53ed06..89982a876337 100644 --- a/op-chain-ops/interopgen/deploy.go +++ b/op-chain-ops/interopgen/deploy.go @@ -168,6 +168,7 @@ func deploySuperchainToL1(l1Host *script.Host, superCfg *SuperchainConfig) (*Sup Release: superCfg.Implementations.Release, SuperchainConfigProxy: superDeployment.SuperchainConfigProxy, ProtocolVersionsProxy: superDeployment.ProtocolVersionsProxy, + SuperchainProxyAdmin: superDeployment.SuperchainProxyAdmin, UseInterop: superCfg.Implementations.UseInterop, }) if err != nil { diff --git a/op-chain-ops/interopgen/deployers/implementations.go b/op-chain-ops/interopgen/deployers/implementations.go index a9baf7718598..29a1fb6dee99 100644 --- a/op-chain-ops/interopgen/deployers/implementations.go +++ b/op-chain-ops/interopgen/deployers/implementations.go @@ -19,6 +19,7 @@ type DeployImplementationsInput struct { Release string SuperchainConfigProxy common.Address ProtocolVersionsProxy common.Address + SuperchainProxyAdmin common.Address UseInterop bool // if true, deploy Interop implementations } diff --git a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol index 49de2bc2e7da..f68db7511f5a 100644 --- a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol +++ b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.15; import { Script } from "forge-std/Script.sol"; +import { CommonBase } from "forge-std/Base.sol"; import { LibString } from "@solady/utils/LibString.sol"; @@ -37,7 +38,7 @@ import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; import { Solarray } from "scripts/libraries/Solarray.sol"; // See DeploySuperchain.s.sol for detailed comments on the script architecture used here. -contract DeployImplementationsInput { +contract DeployImplementationsInput is CommonBase { uint256 internal _withdrawalDelaySeconds; uint256 internal _minProposalSizeBytes; uint256 internal _challengePeriodSeconds; @@ -130,6 +131,15 @@ contract DeployImplementationsInput { require(address(_protocolVersionsProxy) != address(0), "DeployImplementationsInput: not set"); return _protocolVersionsProxy; } + + function superchainProxyAdmin() public returns (ProxyAdmin) { + SuperchainConfig proxy = this.superchainConfigProxy(); + // Can infer the superchainProxyAdmin from the superchainConfigProxy. + vm.prank(address(0)); + ProxyAdmin proxyAdmin = ProxyAdmin(Proxy(payable(address(proxy))).admin()); + require(address(proxyAdmin) != address(0), "DeployImplementationsInput: not set"); + return proxyAdmin; + } } contract DeployImplementationsOutput { @@ -169,7 +179,7 @@ contract DeployImplementationsOutput { require(false, "DeployImplementationsOutput: not implemented"); } - function checkOutput() public view { + function checkOutput() public { address[] memory addrs = Solarray.addresses( address(this.opsm()), address(this.optimismPortalImpl()), @@ -186,8 +196,9 @@ contract DeployImplementationsOutput { DeployUtils.assertValidContractAddresses(addrs); } - function opsm() public view returns (OPStackManager) { + function opsm() public returns (OPStackManager) { DeployUtils.assertValidContractAddress(address(_opsm)); + DeployUtils.assertImplementationSet(address(_opsm)); return _opsm; } @@ -292,24 +303,34 @@ contract DeployImplementations is Script { }); } + // Deploy and initialize a proxied OPStackManager. function createOPSMContract( DeployImplementationsInput _dii, DeployImplementationsOutput, - OPStackManager.Blueprints memory blueprints + OPStackManager.Blueprints memory blueprints, + string memory release, + OPStackManager.ImplementationSetter[] memory setters ) internal virtual - returns (OPStackManager opsm_) + returns (OPStackManager opsmProxy_) { SuperchainConfig superchainConfigProxy = _dii.superchainConfigProxy(); ProtocolVersions protocolVersionsProxy = _dii.protocolVersionsProxy(); + ProxyAdmin proxyAdmin = _dii.superchainProxyAdmin(); - vm.broadcast(msg.sender); - opsm_ = new OPStackManager({ - _superchainConfig: superchainConfigProxy, - _protocolVersions: protocolVersionsProxy, - _blueprints: blueprints - }); + vm.startBroadcast(msg.sender); + Proxy proxy = new Proxy(address(msg.sender)); + OPStackManager opsm = new OPStackManager(superchainConfigProxy, protocolVersionsProxy); + + OPStackManager.InitializerInputs memory initializerInputs = + OPStackManager.InitializerInputs(blueprints, setters, release, true); + proxy.upgradeToAndCall(address(opsm), abi.encodeWithSelector(opsm.initialize.selector, initializerInputs)); + + proxy.changeAdmin(address(proxyAdmin)); // transfer ownership of Proxy contract to the ProxyAdmin contract + vm.stopBroadcast(); + + opsmProxy_ = OPStackManager(address(proxy)); } function deployOPStackManager(DeployImplementationsInput _dii, DeployImplementationsOutput _dio) public virtual { @@ -329,9 +350,6 @@ contract DeployImplementations is Script { vm.stopBroadcast(); // forgefmt: disable-end - // This call contains a broadcast to deploy OPSM. - OPStackManager opsm = createOPSMContract(_dii, _dio, blueprints); - OPStackManager.ImplementationSetter[] memory setters = new OPStackManager.ImplementationSetter[](6); setters[0] = OPStackManager.ImplementationSetter({ name: "L1ERC721Bridge", @@ -359,8 +377,8 @@ contract DeployImplementations is Script { info: OPStackManager.Implementation(address(_dio.l1StandardBridgeImpl()), L1StandardBridge.initialize.selector) }); - vm.broadcast(msg.sender); - opsm.setRelease({ _release: release, _isLatest: true, _setters: setters }); + // This call contains a broadcast to deploy OPSM which is proxied. + OPStackManager opsm = createOPSMContract(_dii, _dio, blueprints, release, setters); vm.label(address(opsm), "OPStackManager"); _dio.set(_dio.opsm.selector, address(opsm)); @@ -571,21 +589,30 @@ contract DeployImplementationsInterop is DeployImplementations { function createOPSMContract( DeployImplementationsInput _dii, DeployImplementationsOutput, - OPStackManager.Blueprints memory blueprints + OPStackManager.Blueprints memory blueprints, + string memory release, + OPStackManager.ImplementationSetter[] memory setters ) internal override - returns (OPStackManager opsm_) + returns (OPStackManager opsmProxy_) { SuperchainConfig superchainConfigProxy = _dii.superchainConfigProxy(); ProtocolVersions protocolVersionsProxy = _dii.protocolVersionsProxy(); + ProxyAdmin proxyAdmin = _dii.superchainProxyAdmin(); - vm.broadcast(msg.sender); - opsm_ = new OPStackManagerInterop({ - _superchainConfig: superchainConfigProxy, - _protocolVersions: protocolVersionsProxy, - _blueprints: blueprints - }); + vm.startBroadcast(msg.sender); + Proxy proxy = new Proxy(address(msg.sender)); + OPStackManager opsm = new OPStackManagerInterop(superchainConfigProxy, protocolVersionsProxy); + + OPStackManager.InitializerInputs memory initializerInputs = + OPStackManager.InitializerInputs(blueprints, setters, release, true); + proxy.upgradeToAndCall(address(opsm), abi.encodeWithSelector(opsm.initialize.selector, initializerInputs)); + + proxy.changeAdmin(address(proxyAdmin)); // transfer ownership of Proxy contract to the ProxyAdmin contract + vm.stopBroadcast(); + + opsmProxy_ = OPStackManagerInterop(address(proxy)); } function deployOptimismPortalImpl( diff --git a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol index 9aac4aefc5c2..fa306edbd3dd 100644 --- a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol @@ -115,6 +115,7 @@ contract DeployOPChainInput { return _l2ChainId; } + // TODO: Check that opsm is proxied and it has an implementation. function opsm() public view returns (OPStackManager) { require(address(_opsm) != address(0), "DeployOPChainInput: not set"); return _opsm; diff --git a/packages/contracts-bedrock/scripts/libraries/DeployUtils.sol b/packages/contracts-bedrock/scripts/libraries/DeployUtils.sol index d690f0b6df6d..d0346ea0d72d 100644 --- a/packages/contracts-bedrock/scripts/libraries/DeployUtils.sol +++ b/packages/contracts-bedrock/scripts/libraries/DeployUtils.sol @@ -1,9 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +import { Proxy } from "src/universal/Proxy.sol"; import { LibString } from "@solady/utils/LibString.sol"; +import { Vm } from "forge-std/Vm.sol"; library DeployUtils { + Vm internal constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + // This takes a sender and an identifier and returns a deterministic address based on the two. // The result is used to etch the input and output contracts to a deterministic address based on // those two values, where the identifier represents the input or output contract, such as @@ -18,6 +22,14 @@ library DeployUtils { require(_who.code.length > 0, string.concat("DeployUtils: no code at ", LibString.toHexStringChecksummed(_who))); } + function assertImplementationSet(address _proxy) internal { + // We prank as the zero address due to the Proxy's `proxyCallIfNotAdmin` modifier. + // Pranking inside this function also means it can no longer be considered `view`. + vm.prank(address(0)); + address implementation = Proxy(payable(_proxy)).implementation(); + assertValidContractAddress(implementation); + } + function assertValidContractAddresses(address[] memory _addrs) internal view { // Assert that all addresses are non-zero and have code. // We use LibString to avoid the need for adding cheatcodes to this contract. diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 966fdf33a6bb..8e5def6450d1 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -32,8 +32,8 @@ "sourceCodeHash": "0xde4df0f9633dc0cdb1c9f634003ea5b0f7c5c1aebc407bc1b2f44c0ecf938649" }, "src/L1/OPStackManager.sol": { - "initCodeHash": "0xe1eab75651e3d81ad20ca01b1e7d373b25d716ee5f8841a56e56b4531a6e0e70", - "sourceCodeHash": "0x5182a2678dadb200dd255ecdfa395e5f7b1e1e27288e78ddf8802ab51ed2dd81" + "initCodeHash": "0x8081ca5dd48497b74758d1425ad6f025d6fd3cb144b4c5d4335b9a04e78b8474", + "sourceCodeHash": "0xb5fb50a9ddf8c0aee6d0e545f8ef4528f27698f3522cab744cd44ffaef6364d2" }, "src/L1/OptimismPortal.sol": { "initCodeHash": "0xb7a7a28d5b3b88334e7cb4bc1c5fbbf9f691d934e907a2fed6a30e461eb1c0f6", diff --git a/packages/contracts-bedrock/snapshots/abi/OPStackManager.json b/packages/contracts-bedrock/snapshots/abi/OPStackManager.json index 8180e2799c96..00cc5980be0a 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPStackManager.json +++ b/packages/contracts-bedrock/snapshots/abi/OPStackManager.json @@ -10,38 +10,6 @@ "internalType": "contract ProtocolVersions", "name": "_protocolVersions", "type": "address" - }, - { - "components": [ - { - "internalType": "address", - "name": "addressManager", - "type": "address" - }, - { - "internalType": "address", - "name": "proxy", - "type": "address" - }, - { - "internalType": "address", - "name": "proxyAdmin", - "type": "address" - }, - { - "internalType": "address", - "name": "l1ChugSplashProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "resolvedDelegateProxy", - "type": "address" - } - ], - "internalType": "struct OPStackManager.Blueprints", - "name": "_blueprints", - "type": "tuple" } ], "stateMutability": "nonpayable", @@ -271,6 +239,92 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "addressManager", + "type": "address" + }, + { + "internalType": "address", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "proxyAdmin", + "type": "address" + }, + { + "internalType": "address", + "name": "l1ChugSplashProxy", + "type": "address" + }, + { + "internalType": "address", + "name": "resolvedDelegateProxy", + "type": "address" + } + ], + "internalType": "struct OPStackManager.Blueprints", + "name": "blueprints", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "components": [ + { + "internalType": "address", + "name": "logic", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "initializer", + "type": "bytes4" + } + ], + "internalType": "struct OPStackManager.Implementation", + "name": "info", + "type": "tuple" + } + ], + "internalType": "struct OPStackManager.ImplementationSetter[]", + "name": "setters", + "type": "tuple[]" + }, + { + "internalType": "string", + "name": "release", + "type": "string" + }, + { + "internalType": "bool", + "name": "isLatest", + "type": "bool" + } + ], + "internalType": "struct OPStackManager.InitializerInputs", + "name": "_initializerInputs", + "type": "tuple" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "latestRelease", @@ -297,53 +351,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "string", - "name": "_release", - "type": "string" - }, - { - "internalType": "bool", - "name": "_isLatest", - "type": "bool" - }, - { - "components": [ - { - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "components": [ - { - "internalType": "address", - "name": "logic", - "type": "address" - }, - { - "internalType": "bytes4", - "name": "initializer", - "type": "bytes4" - } - ], - "internalType": "struct OPStackManager.Implementation", - "name": "info", - "type": "tuple" - } - ], - "internalType": "struct OPStackManager.ImplementationSetter[]", - "name": "_setters", - "type": "tuple[]" - } - ], - "name": "setRelease", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [], "name": "superchainConfig", @@ -408,6 +415,19 @@ "name": "Deployed", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, { "inputs": [ { @@ -477,6 +497,11 @@ "name": "InvalidRoleAddress", "type": "error" }, + { + "inputs": [], + "name": "LatestReleaseNotSet", + "type": "error" + }, { "inputs": [], "name": "NotABlueprint", diff --git a/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json b/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json index 8180e2799c96..00cc5980be0a 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json +++ b/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json @@ -10,38 +10,6 @@ "internalType": "contract ProtocolVersions", "name": "_protocolVersions", "type": "address" - }, - { - "components": [ - { - "internalType": "address", - "name": "addressManager", - "type": "address" - }, - { - "internalType": "address", - "name": "proxy", - "type": "address" - }, - { - "internalType": "address", - "name": "proxyAdmin", - "type": "address" - }, - { - "internalType": "address", - "name": "l1ChugSplashProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "resolvedDelegateProxy", - "type": "address" - } - ], - "internalType": "struct OPStackManager.Blueprints", - "name": "_blueprints", - "type": "tuple" } ], "stateMutability": "nonpayable", @@ -271,6 +239,92 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "addressManager", + "type": "address" + }, + { + "internalType": "address", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "proxyAdmin", + "type": "address" + }, + { + "internalType": "address", + "name": "l1ChugSplashProxy", + "type": "address" + }, + { + "internalType": "address", + "name": "resolvedDelegateProxy", + "type": "address" + } + ], + "internalType": "struct OPStackManager.Blueprints", + "name": "blueprints", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "components": [ + { + "internalType": "address", + "name": "logic", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "initializer", + "type": "bytes4" + } + ], + "internalType": "struct OPStackManager.Implementation", + "name": "info", + "type": "tuple" + } + ], + "internalType": "struct OPStackManager.ImplementationSetter[]", + "name": "setters", + "type": "tuple[]" + }, + { + "internalType": "string", + "name": "release", + "type": "string" + }, + { + "internalType": "bool", + "name": "isLatest", + "type": "bool" + } + ], + "internalType": "struct OPStackManager.InitializerInputs", + "name": "_initializerInputs", + "type": "tuple" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "latestRelease", @@ -297,53 +351,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "string", - "name": "_release", - "type": "string" - }, - { - "internalType": "bool", - "name": "_isLatest", - "type": "bool" - }, - { - "components": [ - { - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "components": [ - { - "internalType": "address", - "name": "logic", - "type": "address" - }, - { - "internalType": "bytes4", - "name": "initializer", - "type": "bytes4" - } - ], - "internalType": "struct OPStackManager.Implementation", - "name": "info", - "type": "tuple" - } - ], - "internalType": "struct OPStackManager.ImplementationSetter[]", - "name": "_setters", - "type": "tuple[]" - } - ], - "name": "setRelease", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [], "name": "superchainConfig", @@ -408,6 +415,19 @@ "name": "Deployed", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, { "inputs": [ { @@ -477,6 +497,11 @@ "name": "InvalidRoleAddress", "type": "error" }, + { + "inputs": [], + "name": "LatestReleaseNotSet", + "type": "error" + }, { "inputs": [], "name": "NotABlueprint", diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OPStackManager.json b/packages/contracts-bedrock/snapshots/storageLayout/OPStackManager.json index 3ef385443c3d..e19eff235994 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/OPStackManager.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/OPStackManager.json @@ -1,30 +1,44 @@ [ + { + "bytes": "1", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "bool" + }, { "bytes": "160", "label": "blueprint", "offset": 0, - "slot": "0", + "slot": "1", "type": "struct OPStackManager.Blueprints" }, { "bytes": "32", "label": "latestRelease", "offset": 0, - "slot": "5", + "slot": "6", "type": "string" }, { "bytes": "32", "label": "implementations", "offset": 0, - "slot": "6", + "slot": "7", "type": "mapping(string => mapping(string => struct OPStackManager.Implementation))" }, { "bytes": "32", "label": "systemConfigs", "offset": 0, - "slot": "7", + "slot": "8", "type": "mapping(uint256 => contract SystemConfig)" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OPStackManagerInterop.json b/packages/contracts-bedrock/snapshots/storageLayout/OPStackManagerInterop.json index 3ef385443c3d..e19eff235994 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/OPStackManagerInterop.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/OPStackManagerInterop.json @@ -1,30 +1,44 @@ [ + { + "bytes": "1", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "bool" + }, { "bytes": "160", "label": "blueprint", "offset": 0, - "slot": "0", + "slot": "1", "type": "struct OPStackManager.Blueprints" }, { "bytes": "32", "label": "latestRelease", "offset": 0, - "slot": "5", + "slot": "6", "type": "string" }, { "bytes": "32", "label": "implementations", "offset": 0, - "slot": "6", + "slot": "7", "type": "mapping(string => mapping(string => struct OPStackManager.Implementation))" }, { "bytes": "32", "label": "systemConfigs", "offset": 0, - "slot": "7", + "slot": "8", "type": "mapping(uint256 => contract SystemConfig)" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/src/L1/OPStackManager.sol b/packages/contracts-bedrock/src/L1/OPStackManager.sol index 5c96cd6aeb8b..29413e6388a8 100644 --- a/packages/contracts-bedrock/src/L1/OPStackManager.sol +++ b/packages/contracts-bedrock/src/L1/OPStackManager.sol @@ -3,9 +3,13 @@ pragma solidity 0.8.15; import { Blueprint } from "src/libraries/Blueprint.sol"; +import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; + import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { Proxy } from "src/universal/Proxy.sol"; import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol"; import { ResolvedDelegateProxy } from "src/legacy/ResolvedDelegateProxy.sol"; @@ -29,7 +33,7 @@ import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; /// @custom:proxied true -contract OPStackManager is ISemver { +contract OPStackManager is ISemver, Initializable { // -------- Structs -------- /// @notice Represents the roles that can be set when deploying a standard OP Stack chain. @@ -97,6 +101,15 @@ contract OPStackManager is ISemver { address resolvedDelegateProxy; } + /// @notice Inputs required when initializing the OPStackManager. To avoid 'StackTooDeep' errors, + /// all necessary inputs (excluding immutables) for initialization are bundled together in this struct. + struct InitializerInputs { + Blueprints blueprints; + ImplementationSetter[] setters; + string release; + bool isLatest; + } + // -------- Constants and Variables -------- /// @custom:semver 1.0.0-beta.3 @@ -110,7 +123,8 @@ contract OPStackManager is ISemver { /// @notice Addresses of the Blueprint contracts. /// This is internal because if public the autogenerated getter method would return a tuple of - /// addresses, but we want it to return a struct. + /// addresses, but we want it to return a struct. This is also set via `initialize` because + /// we can't make this an immutable variable as it is a non-value type. Blueprints internal blueprint; /// @notice The latest release of the OP Stack Manager, as a string of the format `op-contracts/vX.Y.Z`. @@ -149,46 +163,35 @@ contract OPStackManager is ISemver { /// @notice Thrown when a role's address is not valid. error InvalidRoleAddress(string role); + /// @notice Thrown when the latest release is not set upon initialization. + error LatestReleaseNotSet(); + // -------- Methods -------- - /// @notice OPSM is intended to be proxied when used in production. Since we are initially - /// focused on an OPSM version that unblocks interop, we are not proxying OPSM for simplicity. - /// Later, we will `_disableInitializers` in the constructor and replace any constructor logic - /// with an `initialize` function, which will be a breaking change to the OPSM interface. - constructor(SuperchainConfig _superchainConfig, ProtocolVersions _protocolVersions, Blueprints memory _blueprints) { - // TODO uncomment these as we add more validations to this contract, currently this will break a few tests. - // assertValidContractAddress(address(_superchainConfig)); - // assertValidContractAddress(address(_protocolVersions)); - // assertValidContractAddress(_blueprints.addressManager); - // assertValidContractAddress(_blueprints.proxy); - // assertValidContractAddress(_blueprints.proxyAdmin); - // assertValidContractAddress(_blueprints.l1ChugSplashProxy); - // assertValidContractAddress(_blueprints.resolvedDelegateProxy); + /// @notice OPSM is proxied. Therefore the `initialize` function replaces most constructor logic for this contract. + constructor(SuperchainConfig _superchainConfig, ProtocolVersions _protocolVersions) { + assertValidContractAddress(address(_superchainConfig)); + assertValidContractAddress(address(_protocolVersions)); superchainConfig = _superchainConfig; protocolVersions = _protocolVersions; - blueprint = _blueprints; + _disableInitializers(); } - /// @notice Callable by the OPSM owner to release a set of implementation contracts for a given - /// release version. This must be called with `_isLatest` set to true before any chains can be deployed. - /// @param _release The release version to set implementations for, of the format `op-contracts/vX.Y.Z`. - /// @param _isLatest Whether the release version is the latest released version. This is - /// significant because the latest version is used to deploy chains in the `deploy` function. - /// @param _setters The set of implementations to set for the release version. - function setRelease(string memory _release, bool _isLatest, ImplementationSetter[] calldata _setters) external { - // TODO Add auth to this method. + function initialize(InitializerInputs memory _initializerInputs) public initializer { + if (_initializerInputs.isLatest) latestRelease = _initializerInputs.release; + if (keccak256(bytes(latestRelease)) == keccak256("")) revert LatestReleaseNotSet(); - if (_isLatest) latestRelease = _release; - - for (uint256 i = 0; i < _setters.length; i++) { - ImplementationSetter calldata setter = _setters[i]; - Implementation storage impl = implementations[_release][setter.name]; + for (uint256 i = 0; i < _initializerInputs.setters.length; i++) { + ImplementationSetter memory setter = _initializerInputs.setters[i]; + Implementation storage impl = implementations[_initializerInputs.release][setter.name]; if (impl.logic != address(0)) revert AlreadyReleased(); impl.initializer = setter.info.initializer; impl.logic = setter.info.logic; } + + blueprint = _initializerInputs.blueprints; } function deploy(DeployInput calldata _input) external returns (DeployOutput memory) { diff --git a/packages/contracts-bedrock/src/L1/OPStackManagerInterop.sol b/packages/contracts-bedrock/src/L1/OPStackManagerInterop.sol index e9fa44c90f9b..53d33fc9522d 100644 --- a/packages/contracts-bedrock/src/L1/OPStackManagerInterop.sol +++ b/packages/contracts-bedrock/src/L1/OPStackManagerInterop.sol @@ -8,14 +8,13 @@ import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { SystemConfigInterop } from "src/L1/SystemConfigInterop.sol"; -/// @custom:proxied TODO this is not proxied yet. +/// @custom:proxied true contract OPStackManagerInterop is OPStackManager { constructor( SuperchainConfig _superchainConfig, - ProtocolVersions _protocolVersions, - Blueprints memory _blueprints + ProtocolVersions _protocolVersions ) - OPStackManager(_superchainConfig, _protocolVersions, _blueprints) + OPStackManager(_superchainConfig, _protocolVersions) { } // The `SystemConfigInterop` contract has an extra `address _dependencyManager` argument diff --git a/packages/contracts-bedrock/test/DeployImplementations.t.sol b/packages/contracts-bedrock/test/DeployImplementations.t.sol index 4b00813836ee..5a713999495b 100644 --- a/packages/contracts-bedrock/test/DeployImplementations.t.sol +++ b/packages/contracts-bedrock/test/DeployImplementations.t.sol @@ -17,6 +17,8 @@ import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; +import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; +import { Proxy } from "src/universal/Proxy.sol"; import { DeployImplementationsInput, @@ -89,7 +91,12 @@ contract DeployImplementationsOutput_Test is Test { } function test_set_succeeds() public { - OPStackManager opsm = OPStackManager(makeAddr("opsm")); + Proxy opsmProxy = new Proxy(address(0)); + address opsmImpl = address(makeAddr("opsm")); + vm.prank(address(0)); + opsmProxy.upgradeTo(opsmImpl); + + OPStackManager opsm = OPStackManager(address(opsmProxy)); OptimismPortal2 optimismPortalImpl = OptimismPortal2(payable(makeAddr("optimismPortalImpl"))); DelayedWETH delayedWETHImpl = DelayedWETH(payable(makeAddr("delayedWETHImpl"))); PreimageOracle preimageOracleSingleton = PreimageOracle(makeAddr("preimageOracleSingleton")); @@ -103,7 +110,8 @@ contract DeployImplementationsOutput_Test is Test { OptimismMintableERC20Factory(makeAddr("optimismMintableERC20FactoryImpl")); DisputeGameFactory disputeGameFactoryImpl = DisputeGameFactory(makeAddr("disputeGameFactoryImpl")); - vm.etch(address(opsm), hex"01"); + vm.etch(address(opsmProxy), address(opsmProxy).code); + vm.etch(address(opsmImpl), hex"01"); vm.etch(address(optimismPortalImpl), hex"01"); vm.etch(address(delayedWETHImpl), hex"01"); vm.etch(address(preimageOracleSingleton), hex"01"); @@ -255,9 +263,20 @@ contract DeployImplementations_Test is Test { proofMaturityDelaySeconds = uint256(hash(_seed, 3)); disputeGameFinalityDelaySeconds = uint256(hash(_seed, 4)); release = string(bytes.concat(hash(_seed, 5))); - superchainConfigProxy = SuperchainConfig(address(uint160(uint256(hash(_seed, 6))))); protocolVersionsProxy = ProtocolVersions(address(uint160(uint256(hash(_seed, 7))))); + // Must configure the ProxyAdmin contract which is used to upgrade the OPSM's proxy contract. + ProxyAdmin superchainProxyAdmin = new ProxyAdmin(msg.sender); + superchainConfigProxy = SuperchainConfig(address(new Proxy(payable(address(superchainProxyAdmin))))); + + SuperchainConfig superchainConfigImpl = SuperchainConfig(address(uint160(uint256(hash(_seed, 6))))); + vm.prank(address(superchainProxyAdmin)); + Proxy(payable(address(superchainConfigProxy))).upgradeTo(address(superchainConfigImpl)); + + vm.etch(address(superchainProxyAdmin), address(superchainProxyAdmin).code); + vm.etch(address(superchainConfigProxy), address(superchainConfigProxy).code); + vm.etch(address(protocolVersionsProxy), hex"01"); + dii.set(dii.withdrawalDelaySeconds.selector, withdrawalDelaySeconds); dii.set(dii.minProposalSizeBytes.selector, minProposalSizeBytes); dii.set(dii.challengePeriodSeconds.selector, challengePeriodSeconds); diff --git a/packages/contracts-bedrock/test/L1/OPStackManager.t.sol b/packages/contracts-bedrock/test/L1/OPStackManager.t.sol index 4d5929021b5d..289911b06c05 100644 --- a/packages/contracts-bedrock/test/L1/OPStackManager.t.sol +++ b/packages/contracts-bedrock/test/L1/OPStackManager.t.sol @@ -14,10 +14,9 @@ import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; contract OPStackManager_Harness is OPStackManager { constructor( SuperchainConfig _superchainConfig, - ProtocolVersions _protocolVersions, - Blueprints memory _blueprints + ProtocolVersions _protocolVersions ) - OPStackManager(_superchainConfig, _protocolVersions, _blueprints) + OPStackManager(_superchainConfig, _protocolVersions) { } function chainIdToBatchInboxAddress_exposed(uint256 l2ChainId) public pure returns (address) { @@ -92,16 +91,14 @@ contract OPStackManager_InternalMethods_Test is Test { OPStackManager_Harness opsmHarness; function setUp() public { + SuperchainConfig superchainConfigProxy = SuperchainConfig(makeAddr("superchainConfig")); + ProtocolVersions protocolVersionsProxy = ProtocolVersions(makeAddr("protocolVersions")); + vm.etch(address(superchainConfigProxy), hex"01"); + vm.etch(address(protocolVersionsProxy), hex"01"); + opsmHarness = new OPStackManager_Harness({ - _superchainConfig: SuperchainConfig(makeAddr("superchainConfig")), - _protocolVersions: ProtocolVersions(makeAddr("protocolVersions")), - _blueprints: OPStackManager.Blueprints({ - addressManager: makeAddr("addressManager"), - proxy: makeAddr("proxy"), - proxyAdmin: makeAddr("proxyAdmin"), - l1ChugSplashProxy: makeAddr("l1ChugSplashProxy"), - resolvedDelegateProxy: makeAddr("resolvedDelegateProxy") - }) + _superchainConfig: superchainConfigProxy, + _protocolVersions: protocolVersionsProxy }); } diff --git a/packages/contracts-bedrock/test/Specs.t.sol b/packages/contracts-bedrock/test/Specs.t.sol index 15e20f4d01f1..e9217d655074 100644 --- a/packages/contracts-bedrock/test/Specs.t.sol +++ b/packages/contracts-bedrock/test/Specs.t.sol @@ -843,7 +843,7 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "OPStackManager", _sel: _getSel("latestRelease()") }); _addSpec({ _name: "OPStackManager", _sel: _getSel("implementations(string,string)") }); _addSpec({ _name: "OPStackManager", _sel: _getSel("systemConfigs(uint256)") }); - _addSpec({ _name: "OPStackManager", _sel: OPStackManager.setRelease.selector }); + _addSpec({ _name: "OPStackManager", _sel: OPStackManager.initialize.selector }); _addSpec({ _name: "OPStackManager", _sel: OPStackManager.deploy.selector }); _addSpec({ _name: "OPStackManager", _sel: OPStackManager.blueprints.selector }); @@ -854,7 +854,7 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "OPStackManagerInterop", _sel: _getSel("latestRelease()") }); _addSpec({ _name: "OPStackManagerInterop", _sel: _getSel("implementations(string,string)") }); _addSpec({ _name: "OPStackManagerInterop", _sel: _getSel("systemConfigs(uint256)") }); - _addSpec({ _name: "OPStackManagerInterop", _sel: OPStackManager.setRelease.selector }); + _addSpec({ _name: "OPStackManagerInterop", _sel: OPStackManager.initialize.selector }); _addSpec({ _name: "OPStackManagerInterop", _sel: OPStackManager.deploy.selector }); _addSpec({ _name: "OPStackManagerInterop", _sel: OPStackManager.blueprints.selector }); diff --git a/packages/contracts-bedrock/test/vendor/Initializable.t.sol b/packages/contracts-bedrock/test/vendor/Initializable.t.sol index df9231a27627..f6ef25608e34 100644 --- a/packages/contracts-bedrock/test/vendor/Initializable.t.sol +++ b/packages/contracts-bedrock/test/vendor/Initializable.t.sol @@ -400,7 +400,7 @@ contract Initializer_Test is Bridge_Initializer { /// 3. The `initialize()` function of each contract cannot be called again. function test_cannotReinitialize_succeeds() public { // Collect exclusions. - string[] memory excludes = new string[](6); + string[] memory excludes = new string[](8); // TODO: Neither of these contracts are labeled properly in the deployment script. Both are // currently being labeled as their non-interop versions. Remove these exclusions once // the deployment script is fixed. @@ -416,6 +416,9 @@ contract Initializer_Test is Bridge_Initializer { // don't work properly. Remove these exclusions once the deployment script is fixed. excludes[4] = "src/dispute/FaultDisputeGame.sol"; excludes[5] = "src/dispute/PermissionedDisputeGame.sol"; + // TODO: Eventually remove this exclusion. Same reason as above dispute contracts. + excludes[6] = "src/L1/OPStackManager.sol"; + excludes[7] = "src/L1/OPStackManagerInterop.sol"; // Get all contract names in the src directory, minus the excluded contracts. string[] memory contractNames = ForgeArtifacts.getContractNames("src/*", excludes); From 8341f340d8a516509605fb98af1818772f358ccd Mon Sep 17 00:00:00 2001 From: Blaine Malone Date: Sat, 14 Sep 2024 21:59:46 -0400 Subject: [PATCH 144/264] fix: Additional DeployImplementations.s.sol tests (#11914) * fix: Additional testing for inferring proxy admin from superchain config. * Apply suggestions from code review --------- Co-authored-by: Matt Solomon --- .../test/DeployImplementations.t.sol | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/contracts-bedrock/test/DeployImplementations.t.sol b/packages/contracts-bedrock/test/DeployImplementations.t.sol index 5a713999495b..078ccf23c4f9 100644 --- a/packages/contracts-bedrock/test/DeployImplementations.t.sol +++ b/packages/contracts-bedrock/test/DeployImplementations.t.sol @@ -80,6 +80,30 @@ contract DeployImplementationsInput_Test is Test { vm.expectRevert("DeployImplementationsInput: not set"); dii.protocolVersionsProxy(); + + vm.expectRevert("DeployImplementationsInput: not set"); + dii.superchainProxyAdmin(); + } + + function test_superchainProxyAdmin_whenNotSet_reverts() public { + vm.expectRevert("DeployImplementationsInput: not set"); + dii.superchainProxyAdmin(); + + dii.set(dii.superchainConfigProxy.selector, address(superchainConfigProxy)); + vm.expectRevert(); + dii.superchainProxyAdmin(); + + Proxy noAdminProxy = new Proxy(address(0)); + dii.set(dii.superchainConfigProxy.selector, address(noAdminProxy)); + vm.expectRevert("DeployImplementationsInput: not set"); + dii.superchainProxyAdmin(); + } + + function test_superchainProxyAdmin_succeeds() public { + Proxy proxyWithAdminSet = new Proxy(msg.sender); + dii.set(dii.superchainConfigProxy.selector, address(proxyWithAdminSet)); + ProxyAdmin proxyAdmin = dii.superchainProxyAdmin(); + assertEq(address(msg.sender), address(proxyAdmin), "100"); } } @@ -297,6 +321,7 @@ contract DeployImplementations_Test is Test { assertEq(release, dii.release(), "525"); assertEq(address(superchainConfigProxy), address(dii.superchainConfigProxy()), "550"); assertEq(address(protocolVersionsProxy), address(dii.protocolVersionsProxy()), "575"); + assertEq(address(superchainProxyAdmin), address(dii.superchainProxyAdmin()), "580"); // Architecture assertions. assertEq(address(dio.mipsSingleton().oracle()), address(dio.preimageOracleSingleton()), "600"); From 92ed64e171c6eb9c6a080c626640e8836f0653cc Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Sun, 15 Sep 2024 00:15:26 -0600 Subject: [PATCH 145/264] Use the deterministic deployer when broadcasting with CREATE2 (#11915) --- op-chain-ops/script/deterministic.go | 9 +++++++++ op-chain-ops/script/prank.go | 7 +++++++ op-chain-ops/script/script.go | 14 ++++++++++++++ op-chain-ops/script/script_test.go | 10 ++++++---- 4 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 op-chain-ops/script/deterministic.go diff --git a/op-chain-ops/script/deterministic.go b/op-chain-ops/script/deterministic.go new file mode 100644 index 000000000000..c7b02632a55e --- /dev/null +++ b/op-chain-ops/script/deterministic.go @@ -0,0 +1,9 @@ +package script + +import "github.com/ethereum/go-ethereum/common" + +var ( + // DeterministicDeployerAddress is the address of the deterministic deployer Forge uses + // to provide deterministic contract addresses. + DeterministicDeployerAddress = common.HexToAddress("0x4e59b44847b379578588920ca78fbf26c0b4956c") +) diff --git a/op-chain-ops/script/prank.go b/op-chain-ops/script/prank.go index eaf611e9e85d..b6a68f4c44b1 100644 --- a/op-chain-ops/script/prank.go +++ b/op-chain-ops/script/prank.go @@ -54,6 +54,13 @@ func (h *Host) handleCaller(caller vm.ContractRef) vm.ContractRef { if len(h.callStack) > 0 { parentCallFrame := h.callStack[len(h.callStack)-1] if parentCallFrame.Prank != nil && caller.Address() != VMAddr { // pranks do not apply to the cheatcode precompile + if parentCallFrame.Prank.Broadcast && parentCallFrame.LastOp == vm.CREATE2 && h.useCreate2Deployer { + return &prankRef{ + prank: DeterministicDeployerAddress, + ref: caller, + } + } + if parentCallFrame.Prank.Sender != nil { return &prankRef{ prank: *parentCallFrame.Prank.Sender, diff --git a/op-chain-ops/script/script.go b/op-chain-ops/script/script.go index 690ec6fdec65..5bbc0942a52b 100644 --- a/op-chain-ops/script/script.go +++ b/op-chain-ops/script/script.go @@ -105,6 +105,10 @@ type Host struct { // and prepare the ephemeral tx context again, // to make gas accounting of a broadcast sub-call more accurate. isolateBroadcasts bool + + // useCreate2Deployer uses the Create2Deployer for broadcasted + // create2 calls. + useCreate2Deployer bool } type HostOption func(h *Host) @@ -132,6 +136,16 @@ func WithIsolatedBroadcasts() HostOption { } } +// WithCreate2Deployer proxies each CREATE2 call through the CREATE2 deployer +// contract located at 0x4e59b44847b379578588920cA78FbF26c0B4956C. This is the Arachnid +// Create2Deployer contract Forge uses. See https://github.com/Arachnid/deterministic-deployment-proxy +// for the implementation. +func WithCreate2Deployer() HostOption { + return func(h *Host) { + h.useCreate2Deployer = true + } +} + // NewHost creates a Host that can load contracts from the given Artifacts FS, // and with an EVM initialized to the given executionContext. // Optionally src-map loading may be enabled, by providing a non-nil srcFS to read sources from. diff --git a/op-chain-ops/script/script_test.go b/op-chain-ops/script/script_test.go index 55dd70ff2eec..53415d1f0583 100644 --- a/op-chain-ops/script/script_test.go +++ b/op-chain-ops/script/script_test.go @@ -117,8 +117,8 @@ func TestScriptBroadcast(t *testing.T) { Nonce: 0, // first action of 0x123456 }, { - From: cafeAddr, - To: crypto.CreateAddress2(cafeAddr, salt, crypto.Keccak256(expectedInitCode)), + From: DeterministicDeployerAddress, + To: crypto.CreateAddress2(DeterministicDeployerAddress, salt, crypto.Keccak256(expectedInitCode)), Input: expectedInitCode, Value: (*hexutil.U256)(uint256.NewInt(0)), Type: BroadcastCreate2, @@ -141,7 +141,7 @@ func TestScriptBroadcast(t *testing.T) { hook := func(broadcast Broadcast) { broadcasts = append(broadcasts, broadcast) } - h := NewHost(logger, af, nil, DefaultContext, WithBroadcastHook(hook)) + h := NewHost(logger, af, nil, DefaultContext, WithBroadcastHook(hook), WithCreate2Deployer()) addr, err := h.LoadContract("ScriptExample.s.sol", "ScriptExample") require.NoError(t, err) @@ -164,5 +164,7 @@ func TestScriptBroadcast(t *testing.T) { require.EqualValues(t, 0, h.GetNonce(senderAddr)) require.EqualValues(t, 3, h.GetNonce(scriptAddr)) require.EqualValues(t, 2, h.GetNonce(coffeeAddr)) - require.EqualValues(t, 1, h.GetNonce(cafeAddr)) + // This is zero because the deterministic deployer is the + // address that actually deploys the contract using CREATE2. + require.EqualValues(t, 0, h.GetNonce(cafeAddr)) } From ac443ef0146b6c71d3460d3aba2f67cddd8c04c4 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Mon, 16 Sep 2024 14:24:29 +1000 Subject: [PATCH 146/264] op-e2e: Separate helpers for proofs action tests into a new package (#11920) * op-e2e: Move action test helpers for proofs to a separate package. * op-e2e: Use helpers package under proofs rather than a completely separate package tree for helpers. --- op-e2e/actions/proofs/channel_timeout_test.go | 77 ++++++++++--------- op-e2e/actions/proofs/garbage_channel_test.go | 59 +++++++------- op-e2e/actions/proofs/{ => helpers}/env.go | 34 ++++---- .../actions/proofs/{ => helpers}/fixture.go | 2 +- op-e2e/actions/proofs/{ => helpers}/matrix.go | 2 +- .../proofs/sequence_window_expiry_test.go | 43 ++++++----- op-e2e/actions/proofs/simple_program_test.go | 41 +++++----- 7 files changed, 131 insertions(+), 127 deletions(-) rename op-e2e/actions/proofs/{ => helpers}/env.go (92%) rename op-e2e/actions/proofs/{ => helpers}/fixture.go (99%) rename op-e2e/actions/proofs/{ => helpers}/matrix.go (99%) diff --git a/op-e2e/actions/proofs/channel_timeout_test.go b/op-e2e/actions/proofs/channel_timeout_test.go index 80e0d3b5ec99..9bee473f188b 100644 --- a/op-e2e/actions/proofs/channel_timeout_test.go +++ b/op-e2e/actions/proofs/channel_timeout_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-e2e/actions" + "github.com/ethereum-optimism/optimism/op-e2e/actions/proofs/helpers" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-program/client/claim" "github.com/ethereum/go-ethereum/common" @@ -19,58 +20,58 @@ import ( // 4. Submit the channel frame data across 2 transactions. // 5. Instruct the sequencer to derive the L2 chain. // 6. Run the FPP on the safe head. -func runChannelTimeoutTest(gt *testing.T, testCfg *TestCfg[any]) { +func runChannelTimeoutTest(gt *testing.T, testCfg *helpers.TestCfg[any]) { t := actions.NewDefaultTesting(gt) - tp := NewTestParams(func(tp *e2eutils.TestParams) { + tp := helpers.NewTestParams(func(tp *e2eutils.TestParams) { // Set the channel timeout to 10 blocks, 12x lower than the sequencing window. tp.ChannelTimeout = 10 }) - env := NewL2FaultProofEnv(t, testCfg, tp, NewBatcherCfg()) + env := helpers.NewL2FaultProofEnv(t, testCfg, tp, helpers.NewBatcherCfg()) const NumL2Blocks = 10 // Build NumL2Blocks empty blocks on L2 for i := 0; i < NumL2Blocks; i++ { - env.sequencer.ActL2StartBlock(t) - env.sequencer.ActL2EndBlock(t) + env.Sequencer.ActL2StartBlock(t) + env.Sequencer.ActL2EndBlock(t) } // Buffer the first half of L2 blocks in the batcher, and submit it. for i := 0; i < NumL2Blocks/2; i++ { - env.batcher.ActL2BatchBuffer(t) + env.Batcher.ActL2BatchBuffer(t) } - env.batcher.ActL2BatchSubmit(t) + env.Batcher.ActL2BatchSubmit(t) // Instruct the batcher to submit the first channel frame to L1, and include the transaction. - env.miner.ActL1StartBlock(12)(t) - env.miner.ActL1IncludeTxByHash(env.batcher.LastSubmitted.Hash())(t) - env.miner.ActL1EndBlock(t) + env.Miner.ActL1StartBlock(12)(t) + env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t) + env.Miner.ActL1EndBlock(t) // Finalize the block with the first channel frame on L1. - env.miner.ActL1SafeNext(t) - env.miner.ActL1FinalizeNext(t) + env.Miner.ActL1SafeNext(t) + env.Miner.ActL1FinalizeNext(t) // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. - env.sequencer.ActL1HeadSignal(t) - env.sequencer.ActL2PipelineFull(t) + env.Sequencer.ActL1HeadSignal(t) + env.Sequencer.ActL2PipelineFull(t) // Ensure that the safe head has not advanced - the channel is incomplete. - l2SafeHead := env.engine.L2Chain().CurrentSafeBlock() + l2SafeHead := env.Engine.L2Chain().CurrentSafeBlock() require.Equal(t, uint64(0), l2SafeHead.Number.Uint64()) // Time out the channel by mining `ChannelTimeout + 1` empty blocks on L1. for i := uint64(0); i < tp.ChannelTimeout+1; i++ { - env.miner.ActEmptyBlock(t) - env.miner.ActL1SafeNext(t) - env.miner.ActL1FinalizeNext(t) + env.Miner.ActEmptyBlock(t) + env.Miner.ActL1SafeNext(t) + env.Miner.ActL1FinalizeNext(t) } // Instruct the sequencer to derive the L2 chain - the channel should now be timed out. - env.sequencer.ActL1HeadSignal(t) - env.sequencer.ActL2PipelineFull(t) + env.Sequencer.ActL1HeadSignal(t) + env.Sequencer.ActL2PipelineFull(t) // Ensure the safe head has still not advanced. - l2SafeHead = env.engine.L2Chain().CurrentSafeBlock() + l2SafeHead = env.Engine.L2Chain().CurrentSafeBlock() require.Equal(t, uint64(0), l2SafeHead.Number.Uint64()) // Instruct the batcher to submit the blocks to L1 in a new channel, @@ -78,30 +79,30 @@ func runChannelTimeoutTest(gt *testing.T, testCfg *TestCfg[any]) { for i := 0; i < 2; i++ { // Buffer half of the L2 chain's blocks. for j := 0; j < NumL2Blocks/2; j++ { - env.batcher.ActL2BatchBuffer(t) + env.Batcher.ActL2BatchBuffer(t) } // Close the channel on the second iteration. if i == 1 { - env.batcher.ActL2ChannelClose(t) + env.Batcher.ActL2ChannelClose(t) } - env.batcher.ActL2BatchSubmit(t) - env.miner.ActL1StartBlock(12)(t) - env.miner.ActL1IncludeTxByHash(env.batcher.LastSubmitted.Hash())(t) - env.miner.ActL1EndBlock(t) + env.Batcher.ActL2BatchSubmit(t) + env.Miner.ActL1StartBlock(12)(t) + env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t) + env.Miner.ActL1EndBlock(t) // Finalize the block with the frame data on L1. - env.miner.ActL1SafeNext(t) - env.miner.ActL1FinalizeNext(t) + env.Miner.ActL1SafeNext(t) + env.Miner.ActL1FinalizeNext(t) } // Instruct the sequencer to derive the L2 chain. - env.sequencer.ActL1HeadSignal(t) - env.sequencer.ActL2PipelineFull(t) + env.Sequencer.ActL1HeadSignal(t) + env.Sequencer.ActL2PipelineFull(t) // Ensure the safe head has still advanced to L2 block # NumL2Blocks. - l2SafeHead = env.engine.L2Chain().CurrentSafeBlock() + l2SafeHead = env.Engine.L2Chain().CurrentSafeBlock() require.EqualValues(t, NumL2Blocks, l2SafeHead.Number.Uint64()) // Run the FPP on L2 block # NumL2Blocks/2. @@ -109,22 +110,22 @@ func runChannelTimeoutTest(gt *testing.T, testCfg *TestCfg[any]) { } func Test_ProgramAction_ChannelTimeout(gt *testing.T) { - matrix := NewMatrix[any]() + matrix := helpers.NewMatrix[any]() defer matrix.Run(gt) matrix.AddTestCase( "HonestClaim", nil, - LatestForkOnly, + helpers.LatestForkOnly, runChannelTimeoutTest, - ExpectNoError(), + helpers.ExpectNoError(), ) matrix.AddTestCase( "JunkClaim", nil, - LatestForkOnly, + helpers.LatestForkOnly, runChannelTimeoutTest, - ExpectError(claim.ErrClaimNotValid), - WithL2Claim(common.HexToHash("0xdeadbeef")), + helpers.ExpectError(claim.ErrClaimNotValid), + helpers.WithL2Claim(common.HexToHash("0xdeadbeef")), ) } diff --git a/op-e2e/actions/proofs/garbage_channel_test.go b/op-e2e/actions/proofs/garbage_channel_test.go index 91ac453337c9..06c888582a05 100644 --- a/op-e2e/actions/proofs/garbage_channel_test.go +++ b/op-e2e/actions/proofs/garbage_channel_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-e2e/actions" + "github.com/ethereum-optimism/optimism/op-e2e/actions/proofs/helpers" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-program/client/claim" "github.com/ethereum/go-ethereum/common" @@ -25,73 +26,73 @@ var garbageKinds = []actions.GarbageKind{ // // channel format ([]Frame): // [f[0 - correct] f_x[1 - bad frame] f[1 - correct]] -func runGarbageChannelTest(gt *testing.T, testCfg *TestCfg[actions.GarbageKind]) { +func runGarbageChannelTest(gt *testing.T, testCfg *helpers.TestCfg[actions.GarbageKind]) { t := actions.NewDefaultTesting(gt) - tp := NewTestParams(func(tp *e2eutils.TestParams) { + tp := helpers.NewTestParams(func(tp *e2eutils.TestParams) { // Set the channel timeout to 10 blocks, 12x lower than the sequencing window. tp.ChannelTimeout = 10 }) - env := NewL2FaultProofEnv(t, testCfg, tp, NewBatcherCfg()) + env := helpers.NewL2FaultProofEnv(t, testCfg, tp, helpers.NewBatcherCfg()) - includeBatchTx := func(env *L2FaultProofEnv) { + includeBatchTx := func(env *helpers.L2FaultProofEnv) { // Instruct the batcher to submit the first channel frame to L1, and include the transaction. - env.miner.ActL1StartBlock(12)(t) - env.miner.ActL1IncludeTxByHash(env.batcher.LastSubmitted.Hash())(t) - env.miner.ActL1EndBlock(t) + env.Miner.ActL1StartBlock(12)(t) + env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t) + env.Miner.ActL1EndBlock(t) // Finalize the block with the first channel frame on L1. - env.miner.ActL1SafeNext(t) - env.miner.ActL1FinalizeNext(t) + env.Miner.ActL1SafeNext(t) + env.Miner.ActL1FinalizeNext(t) // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. - env.sequencer.ActL1HeadSignal(t) - env.sequencer.ActL2PipelineFull(t) + env.Sequencer.ActL1HeadSignal(t) + env.Sequencer.ActL2PipelineFull(t) } const NumL2Blocks = 10 // Build NumL2Blocks empty blocks on L2 for i := 0; i < NumL2Blocks; i++ { - env.sequencer.ActL2StartBlock(t) - env.sequencer.ActL2EndBlock(t) + env.Sequencer.ActL2StartBlock(t) + env.Sequencer.ActL2EndBlock(t) } // Buffer the first half of L2 blocks in the batcher, and submit it. for i := 0; i < NumL2Blocks/2; i++ { - env.batcher.ActL2BatchBuffer(t) + env.Batcher.ActL2BatchBuffer(t) } - env.batcher.ActL2BatchSubmit(t) + env.Batcher.ActL2BatchSubmit(t) // Include the batcher transaction. includeBatchTx(env) // Ensure that the safe head has not advanced - the channel is incomplete. - l2SafeHead := env.engine.L2Chain().CurrentSafeBlock() + l2SafeHead := env.Engine.L2Chain().CurrentSafeBlock() require.Equal(t, uint64(0), l2SafeHead.Number.Uint64()) // Buffer the second half of L2 blocks in the batcher. for i := 0; i < NumL2Blocks/2; i++ { - env.batcher.ActL2BatchBuffer(t) + env.Batcher.ActL2BatchBuffer(t) } - env.batcher.ActL2ChannelClose(t) - expectedSecondFrame := env.batcher.ReadNextOutputFrame(t) + env.Batcher.ActL2ChannelClose(t) + expectedSecondFrame := env.Batcher.ReadNextOutputFrame(t) // Submit a garbage frame, modified from the expected second frame. - env.batcher.ActL2BatchSubmitGarbageRaw(t, expectedSecondFrame, testCfg.Custom) + env.Batcher.ActL2BatchSubmitGarbageRaw(t, expectedSecondFrame, testCfg.Custom) // Include the garbage second frame tx includeBatchTx(env) // Ensure that the safe head has not advanced - the channel is incomplete. - l2SafeHead = env.engine.L2Chain().CurrentSafeBlock() + l2SafeHead = env.Engine.L2Chain().CurrentSafeBlock() require.Equal(t, uint64(0), l2SafeHead.Number.Uint64()) // Submit the correct second frame. - env.batcher.ActL2BatchSubmitRaw(t, expectedSecondFrame) + env.Batcher.ActL2BatchSubmitRaw(t, expectedSecondFrame) // Include the corract second frame tx. includeBatchTx(env) // Ensure that the safe head has advanced - the channel is complete. - l2SafeHead = env.engine.L2Chain().CurrentSafeBlock() + l2SafeHead = env.Engine.L2Chain().CurrentSafeBlock() require.Equal(t, uint64(NumL2Blocks), l2SafeHead.Number.Uint64()) // Run the FPP on L2 block # NumL2Blocks. @@ -99,24 +100,24 @@ func runGarbageChannelTest(gt *testing.T, testCfg *TestCfg[actions.GarbageKind]) } func Test_ProgramAction_GarbageChannel(gt *testing.T) { - matrix := NewMatrix[actions.GarbageKind]() + matrix := helpers.NewMatrix[actions.GarbageKind]() defer matrix.Run(gt) for _, garbageKind := range garbageKinds { matrix.AddTestCase( fmt.Sprintf("HonestClaim-%s", garbageKind.String()), garbageKind, - LatestForkOnly, + helpers.LatestForkOnly, runGarbageChannelTest, - ExpectNoError(), + helpers.ExpectNoError(), ) matrix.AddTestCase( fmt.Sprintf("JunkClaim-%s", garbageKind.String()), garbageKind, - LatestForkOnly, + helpers.LatestForkOnly, runGarbageChannelTest, - ExpectError(claim.ErrClaimNotValid), - WithL2Claim(common.HexToHash("0xdeadbeef")), + helpers.ExpectError(claim.ErrClaimNotValid), + helpers.WithL2Claim(common.HexToHash("0xdeadbeef")), ) } } diff --git a/op-e2e/actions/proofs/env.go b/op-e2e/actions/proofs/helpers/env.go similarity index 92% rename from op-e2e/actions/proofs/env.go rename to op-e2e/actions/proofs/helpers/env.go index 3732096c266c..50fecbb94fb2 100644 --- a/op-e2e/actions/proofs/env.go +++ b/op-e2e/actions/proofs/helpers/env.go @@ -1,4 +1,4 @@ -package proofs +package helpers import ( "context" @@ -25,14 +25,14 @@ import ( // L2FaultProofEnv is a test harness for a fault provable L2 chain. type L2FaultProofEnv struct { log log.Logger - batcher *actions.L2Batcher - sequencer *actions.L2Sequencer - engine *actions.L2Engine + Batcher *actions.L2Batcher + Sequencer *actions.L2Sequencer + Engine *actions.L2Engine engCl *sources.EngineClient sd *e2eutils.SetupData dp *e2eutils.DeployParams - miner *actions.L1Miner - alice *actions.CrossLayerUser + Miner *actions.L1Miner + Alice *actions.CrossLayerUser } func NewL2FaultProofEnv[c any](t actions.Testing, testCfg *TestCfg[c], tp *e2eutils.TestParams, batcherCfg *actions.BatcherCfg) *L2FaultProofEnv { @@ -102,14 +102,14 @@ func NewL2FaultProofEnv[c any](t actions.Testing, testCfg *TestCfg[c], tp *e2eut return &L2FaultProofEnv{ log: log, - batcher: batcher, - sequencer: sequencer, - engine: engine, + Batcher: batcher, + Sequencer: sequencer, + Engine: engine, engCl: engCl, sd: sd, dp: dp, - miner: miner, - alice: alice, + Miner: miner, + Alice: alice, } } @@ -137,11 +137,11 @@ func WithL2Claim(claim common.Hash) FixtureInputParam { func (env *L2FaultProofEnv) RunFaultProofProgram(t actions.Testing, l2ClaimBlockNum uint64, checkResult CheckResult, fixtureInputParams ...FixtureInputParam) { // Fetch the pre and post output roots for the fault proof. - preRoot, err := env.sequencer.RollupClient().OutputAtBlock(t.Ctx(), l2ClaimBlockNum-1) + preRoot, err := env.Sequencer.RollupClient().OutputAtBlock(t.Ctx(), l2ClaimBlockNum-1) require.NoError(t, err) - claimRoot, err := env.sequencer.RollupClient().OutputAtBlock(t.Ctx(), l2ClaimBlockNum) + claimRoot, err := env.Sequencer.RollupClient().OutputAtBlock(t.Ctx(), l2ClaimBlockNum) require.NoError(t, err) - l1Head := env.miner.L1Chain().CurrentBlock() + l1Head := env.Miner.L1Chain().CurrentBlock() fixtureInputs := &FixtureInputs{ L2BlockNumber: l2ClaimBlockNum, @@ -163,12 +163,12 @@ func (env *L2FaultProofEnv) RunFaultProofProgram(t actions.Testing, l2ClaimBlock ) withInProcessPrefetcher := host.WithPrefetcher(func(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *config.Config) (host.Prefetcher, error) { // Set up in-process L1 sources - l1Cl := env.miner.L1Client(t, env.sd.RollupCfg) - l1BlobFetcher := env.miner.BlobStore() + l1Cl := env.Miner.L1Client(t, env.sd.RollupCfg) + l1BlobFetcher := env.Miner.BlobStore() // Set up in-process L2 source l2ClCfg := sources.L2ClientDefaultConfig(env.sd.RollupCfg, true) - l2RPC := env.engine.RPCClient() + l2RPC := env.Engine.RPCClient() l2Client, err := host.NewL2Client(l2RPC, env.log, nil, &host.L2ClientConfig{L2ClientConfig: l2ClCfg, L2Head: cfg.L2Head}) require.NoError(t, err, "failed to create L2 client") l2DebugCl := &host.L2Source{L2Client: l2Client, DebugClient: sources.NewDebugClient(l2RPC.CallContext)} diff --git a/op-e2e/actions/proofs/fixture.go b/op-e2e/actions/proofs/helpers/fixture.go similarity index 99% rename from op-e2e/actions/proofs/fixture.go rename to op-e2e/actions/proofs/helpers/fixture.go index cbd30905b2da..22c5590b9955 100644 --- a/op-e2e/actions/proofs/fixture.go +++ b/op-e2e/actions/proofs/helpers/fixture.go @@ -1,4 +1,4 @@ -package proofs +package helpers import ( "encoding/json" diff --git a/op-e2e/actions/proofs/matrix.go b/op-e2e/actions/proofs/helpers/matrix.go similarity index 99% rename from op-e2e/actions/proofs/matrix.go rename to op-e2e/actions/proofs/helpers/matrix.go index 5814b93838c5..7f3e810e86b6 100644 --- a/op-e2e/actions/proofs/matrix.go +++ b/op-e2e/actions/proofs/helpers/matrix.go @@ -1,4 +1,4 @@ -package proofs +package helpers import ( "fmt" diff --git a/op-e2e/actions/proofs/sequence_window_expiry_test.go b/op-e2e/actions/proofs/sequence_window_expiry_test.go index d62f6795825a..68a949a10b3f 100644 --- a/op-e2e/actions/proofs/sequence_window_expiry_test.go +++ b/op-e2e/actions/proofs/sequence_window_expiry_test.go @@ -4,42 +4,43 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-e2e/actions" + "github.com/ethereum-optimism/optimism/op-e2e/actions/proofs/helpers" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" ) // Run a test that proves a deposit-only block generated due to sequence window expiry. -func runSequenceWindowExpireTest(gt *testing.T, testCfg *TestCfg[any]) { +func runSequenceWindowExpireTest(gt *testing.T, testCfg *helpers.TestCfg[any]) { t := actions.NewDefaultTesting(gt) - tp := NewTestParams() - env := NewL2FaultProofEnv(t, testCfg, tp, NewBatcherCfg()) + tp := helpers.NewTestParams() + env := helpers.NewL2FaultProofEnv(t, testCfg, tp, helpers.NewBatcherCfg()) // Mine an empty block for gas estimation purposes. - env.miner.ActEmptyBlock(t) + env.Miner.ActEmptyBlock(t) // Expire the sequence window by building `SequenceWindow + 1` empty blocks on L1. for i := 0; i < int(tp.SequencerWindowSize)+1; i++ { - env.alice.L1.ActResetTxOpts(t) - env.alice.ActDeposit(t) + env.Alice.L1.ActResetTxOpts(t) + env.Alice.ActDeposit(t) - env.miner.ActL1StartBlock(12)(t) - env.miner.ActL1IncludeTx(env.alice.Address())(t) - env.miner.ActL1EndBlock(t) + env.Miner.ActL1StartBlock(12)(t) + env.Miner.ActL1IncludeTx(env.Alice.Address())(t) + env.Miner.ActL1EndBlock(t) - env.miner.ActL1SafeNext(t) - env.miner.ActL1FinalizeNext(t) + env.Miner.ActL1SafeNext(t) + env.Miner.ActL1FinalizeNext(t) } // Ensure the safe head is still 0. - l2SafeHead := env.engine.L2Chain().CurrentSafeBlock() + l2SafeHead := env.Engine.L2Chain().CurrentSafeBlock() require.EqualValues(t, 0, l2SafeHead.Number.Uint64()) // Ask the sequencer to derive the deposit-only L2 chain. - env.sequencer.ActL1HeadSignal(t) - env.sequencer.ActL2PipelineFull(t) + env.Sequencer.ActL1HeadSignal(t) + env.Sequencer.ActL2PipelineFull(t) // Ensure the safe head advanced forcefully. - l2SafeHead = env.engine.L2Chain().CurrentSafeBlock() + l2SafeHead = env.Engine.L2Chain().CurrentSafeBlock() require.Greater(t, l2SafeHead.Number.Uint64(), uint64(0)) // Run the FPP on one of the auto-derived blocks. @@ -47,22 +48,22 @@ func runSequenceWindowExpireTest(gt *testing.T, testCfg *TestCfg[any]) { } func Test_ProgramAction_SequenceWindowExpired(gt *testing.T) { - matrix := NewMatrix[any]() + matrix := helpers.NewMatrix[any]() defer matrix.Run(gt) matrix.AddTestCase( "HonestClaim", nil, - LatestForkOnly, + helpers.LatestForkOnly, runSequenceWindowExpireTest, - ExpectNoError(), + helpers.ExpectNoError(), ) matrix.AddTestCase( "JunkClaim", nil, - LatestForkOnly, + helpers.LatestForkOnly, runSequenceWindowExpireTest, - ExpectNoError(), - WithL2Claim(common.HexToHash("0xdeadbeef")), + helpers.ExpectNoError(), + helpers.WithL2Claim(common.HexToHash("0xdeadbeef")), ) } diff --git a/op-e2e/actions/proofs/simple_program_test.go b/op-e2e/actions/proofs/simple_program_test.go index 372e20378432..2d7360bb94af 100644 --- a/op-e2e/actions/proofs/simple_program_test.go +++ b/op-e2e/actions/proofs/simple_program_test.go @@ -4,35 +4,36 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-e2e/actions" + "github.com/ethereum-optimism/optimism/op-e2e/actions/proofs/helpers" "github.com/ethereum-optimism/optimism/op-program/client/claim" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" ) -func runSimpleProgramTest(gt *testing.T, testCfg *TestCfg[any]) { +func runSimpleProgramTest(gt *testing.T, testCfg *helpers.TestCfg[any]) { t := actions.NewDefaultTesting(gt) - env := NewL2FaultProofEnv(t, testCfg, NewTestParams(), NewBatcherCfg()) + env := helpers.NewL2FaultProofEnv(t, testCfg, helpers.NewTestParams(), helpers.NewBatcherCfg()) // Build an empty block on L2 - env.sequencer.ActL2StartBlock(t) - env.sequencer.ActL2EndBlock(t) + env.Sequencer.ActL2StartBlock(t) + env.Sequencer.ActL2EndBlock(t) // Instruct the batcher to submit the block to L1, and include the transaction. - env.batcher.ActSubmitAll(t) - env.miner.ActL1StartBlock(12)(t) - env.miner.ActL1IncludeTxByHash(env.batcher.LastSubmitted.Hash())(t) - env.miner.ActL1EndBlock(t) + env.Batcher.ActSubmitAll(t) + env.Miner.ActL1StartBlock(12)(t) + env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t) + env.Miner.ActL1EndBlock(t) // Finalize the block with the batch on L1. - env.miner.ActL1SafeNext(t) - env.miner.ActL1FinalizeNext(t) + env.Miner.ActL1SafeNext(t) + env.Miner.ActL1FinalizeNext(t) // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. - env.sequencer.ActL1HeadSignal(t) - env.sequencer.ActL2PipelineFull(t) + env.Sequencer.ActL1HeadSignal(t) + env.Sequencer.ActL2PipelineFull(t) - l1Head := env.miner.L1Chain().CurrentBlock() - l2SafeHead := env.engine.L2Chain().CurrentSafeBlock() + l1Head := env.Miner.L1Chain().CurrentBlock() + l2SafeHead := env.Engine.L2Chain().CurrentSafeBlock() // Ensure there is only 1 block on L1. require.Equal(t, uint64(1), l1Head.Number.Uint64()) @@ -43,22 +44,22 @@ func runSimpleProgramTest(gt *testing.T, testCfg *TestCfg[any]) { } func Test_ProgramAction_SimpleEmptyChain(gt *testing.T) { - matrix := NewMatrix[any]() + matrix := helpers.NewMatrix[any]() defer matrix.Run(gt) matrix.AddTestCase( "HonestClaim", nil, - LatestForkOnly, + helpers.LatestForkOnly, runSimpleProgramTest, - ExpectNoError(), + helpers.ExpectNoError(), ) matrix.AddTestCase( "JunkClaim", nil, - LatestForkOnly, + helpers.LatestForkOnly, runSimpleProgramTest, - ExpectError(claim.ErrClaimNotValid), - WithL2Claim(common.HexToHash("0xdeadbeef")), + helpers.ExpectError(claim.ErrClaimNotValid), + helpers.WithL2Claim(common.HexToHash("0xdeadbeef")), ) } From 4af1fe6e39c31c7321098bdf0bf49d1d1d7ad66e Mon Sep 17 00:00:00 2001 From: mbaxter Date: Mon, 16 Sep 2024 14:21:26 -0400 Subject: [PATCH 147/264] cannon: Implement thread-safe ll and sc operations (#11906) * cannon: Extract RMW op handling from shared logic * cannon: Add more test cases of LL/SC behavior * cannon: Cut ll/sc-related logic from common mips code * cannon: Setup mips helpers to return memory modification info * cannon: Add new fields to track reserved memory * cannon: Add a boolean field indicating whether an ll reservation is active * cannon: Implement ll/sc for MTCannon * cannon: Add modified sysRead tests for MTCannon * cannon: Test store operations cleare memory reservations * cannon: Update SysClockGettime to clear ll memory reservation * cannon: Fix slither warning - initialize variable * cannon: Bump MIP2.sol version * cannon: Run semver, snapshot tasks * cannon: Cut unused log msg * cannon: Add new error to MIPS interfaces * cannon: Cut stale TODO --- cannon/mipsevm/exec/mips_instructions.go | 46 +- cannon/mipsevm/exec/mips_syscalls.go | 6 +- cannon/mipsevm/multithreaded/mips.go | 74 ++- cannon/mipsevm/multithreaded/state.go | 58 +- cannon/mipsevm/multithreaded/state_test.go | 13 +- .../multithreaded/testutil/expectations.go | 45 +- .../testutil/expectations_test.go | 3 + .../multithreaded/testutil/mutators.go | 11 +- cannon/mipsevm/singlethreaded/mips.go | 37 +- cannon/mipsevm/tests/evm_common_test.go | 82 --- .../mipsevm/tests/evm_multithreaded_test.go | 514 ++++++++++++++++-- .../mipsevm/tests/evm_singlethreaded_test.go | 196 +++++++ packages/contracts-bedrock/semver-lock.json | 8 +- .../contracts-bedrock/snapshots/abi/MIPS.json | 5 + .../snapshots/abi/MIPS2.json | 5 + .../contracts-bedrock/src/cannon/MIPS.sol | 59 +- .../contracts-bedrock/src/cannon/MIPS2.sol | 138 ++++- .../src/cannon/interfaces/IMIPS.sol | 1 + .../src/cannon/interfaces/IMIPS2.sol | 1 + .../src/cannon/libraries/CannonErrors.sol | 3 + .../src/cannon/libraries/MIPSInstructions.sol | 158 +++--- .../src/cannon/libraries/MIPSSyscalls.sol | 20 +- .../contracts-bedrock/test/cannon/MIPS2.t.sol | 71 ++- 23 files changed, 1234 insertions(+), 320 deletions(-) create mode 100644 cannon/mipsevm/tests/evm_singlethreaded_test.go diff --git a/cannon/mipsevm/exec/mips_instructions.go b/cannon/mipsevm/exec/mips_instructions.go index d016dd2c07e0..aec14192df93 100644 --- a/cannon/mipsevm/exec/mips_instructions.go +++ b/cannon/mipsevm/exec/mips_instructions.go @@ -5,6 +5,11 @@ import ( "github.com/ethereum-optimism/optimism/cannon/mipsevm/memory" ) +const ( + OpLoadLinked = 0x30 + OpStoreConditional = 0x38 +) + func GetInstructionDetails(pc uint32, memory *memory.Memory) (insn, opcode, fun uint32) { insn = memory.GetMemory(pc) opcode = insn >> 26 // First 6-bits @@ -13,7 +18,7 @@ func GetInstructionDetails(pc uint32, memory *memory.Memory) (insn, opcode, fun return insn, opcode, fun } -func ExecMipsCoreStepLogic(cpu *mipsevm.CpuScalars, registers *[32]uint32, memory *memory.Memory, insn, opcode, fun uint32, memTracker MemTracker, stackTracker StackTracker) error { +func ExecMipsCoreStepLogic(cpu *mipsevm.CpuScalars, registers *[32]uint32, memory *memory.Memory, insn, opcode, fun uint32, memTracker MemTracker, stackTracker StackTracker) (memUpdated bool, memAddr uint32, err error) { // j-type j/jal if opcode == 2 || opcode == 3 { linkReg := uint32(0) @@ -23,7 +28,8 @@ func ExecMipsCoreStepLogic(cpu *mipsevm.CpuScalars, registers *[32]uint32, memor // Take top 4 bits of the next PC (its 256 MB region), and concatenate with the 26-bit offset target := (cpu.NextPC & 0xF0000000) | ((insn & 0x03FFFFFF) << 2) stackTracker.PushStack(cpu.PC, target) - return HandleJump(cpu, registers, linkReg, target) + err = HandleJump(cpu, registers, linkReg, target) + return } // register fetch @@ -57,7 +63,8 @@ func ExecMipsCoreStepLogic(cpu *mipsevm.CpuScalars, registers *[32]uint32, memor } if (opcode >= 4 && opcode < 8) || opcode == 1 { - return HandleBranch(cpu, registers, opcode, insn, rtReg, rs) + err = HandleBranch(cpu, registers, opcode, insn, rtReg, rs) + return } storeAddr := uint32(0xFF_FF_FF_FF) @@ -70,7 +77,7 @@ func ExecMipsCoreStepLogic(cpu *mipsevm.CpuScalars, registers *[32]uint32, memor addr := rs & 0xFFFFFFFC memTracker.TrackMemAccess(addr) mem = memory.GetMemory(addr) - if opcode >= 0x28 && opcode != 0x30 { + if opcode >= 0x28 { // store storeAddr = addr // store opcodes don't write back to a register @@ -90,36 +97,42 @@ func ExecMipsCoreStepLogic(cpu *mipsevm.CpuScalars, registers *[32]uint32, memor } else { stackTracker.PopStack() } - return HandleJump(cpu, registers, linkReg, rs) + err = HandleJump(cpu, registers, linkReg, rs) + return } if fun == 0xa { // movz - return HandleRd(cpu, registers, rdReg, rs, rt == 0) + err = HandleRd(cpu, registers, rdReg, rs, rt == 0) + return } if fun == 0xb { // movn - return HandleRd(cpu, registers, rdReg, rs, rt != 0) + err = HandleRd(cpu, registers, rdReg, rs, rt != 0) + return } // lo and hi registers // can write back if fun >= 0x10 && fun < 0x1c { - return HandleHiLo(cpu, registers, fun, rs, rt, rdReg) + err = HandleHiLo(cpu, registers, fun, rs, rt, rdReg) + return } } - // store conditional, write a 1 to rt - if opcode == 0x38 && rtReg != 0 { - registers[rtReg] = 1 - } - // write memory if storeAddr != 0xFF_FF_FF_FF { memTracker.TrackMemAccess(storeAddr) memory.SetMemory(storeAddr, val) + memUpdated = true + memAddr = storeAddr } // write back the value to destination register - return HandleRd(cpu, registers, rdReg, val, true) + err = HandleRd(cpu, registers, rdReg, val, true) + return +} + +func SignExtendImmediate(insn uint32) uint32 { + return SignExtend(insn&0xFFFF, 16) } func ExecuteMipsInstruction(insn, opcode, fun, rs, rt, mem uint32) uint32 { @@ -272,10 +285,6 @@ func ExecuteMipsInstruction(insn, opcode, fun, rs, rt, mem uint32) uint32 { val := rt << (24 - (rs&3)*8) mask := uint32(0xFFFFFFFF) << (24 - (rs&3)*8) return (mem & ^mask) | val - case 0x30: // ll - return mem - case 0x38: // sc - return rt default: panic("invalid instruction") } @@ -382,6 +391,7 @@ func HandleRd(cpu *mipsevm.CpuScalars, registers *[32]uint32, storeReg uint32, v panic("invalid register") } if storeReg != 0 && conditional { + // Register 0 is a special register that always holds a value of 0 registers[storeReg] = val } cpu.PC = cpu.NextPC diff --git a/cannon/mipsevm/exec/mips_syscalls.go b/cannon/mipsevm/exec/mips_syscalls.go index 33a8e489bdb7..71a14e4fe5e2 100644 --- a/cannon/mipsevm/exec/mips_syscalls.go +++ b/cannon/mipsevm/exec/mips_syscalls.go @@ -187,7 +187,7 @@ func HandleSysMmap(a0, a1, heap uint32) (v0, v1, newHeap uint32) { return v0, v1, newHeap } -func HandleSysRead(a0, a1, a2 uint32, preimageKey [32]byte, preimageOffset uint32, preimageReader PreimageReader, memory *memory.Memory, memTracker MemTracker) (v0, v1, newPreimageOffset uint32) { +func HandleSysRead(a0, a1, a2 uint32, preimageKey [32]byte, preimageOffset uint32, preimageReader PreimageReader, memory *memory.Memory, memTracker MemTracker) (v0, v1, newPreimageOffset uint32, memUpdated bool, memAddr uint32) { // args: a0 = fd, a1 = addr, a2 = count // returns: v0 = read, v1 = err code v0 = uint32(0) @@ -215,6 +215,8 @@ func HandleSysRead(a0, a1, a2 uint32, preimageKey [32]byte, preimageOffset uint3 binary.BigEndian.PutUint32(outMem[:], mem) copy(outMem[alignment:], dat[:datLen]) memory.SetMemory(effAddr, binary.BigEndian.Uint32(outMem[:])) + memUpdated = true + memAddr = effAddr newPreimageOffset += datLen v0 = datLen //fmt.Printf("read %d pre-image bytes, new offset: %d, eff addr: %08x mem: %08x\n", datLen, m.state.PreimageOffset, effAddr, outMem) @@ -226,7 +228,7 @@ func HandleSysRead(a0, a1, a2 uint32, preimageKey [32]byte, preimageOffset uint3 v1 = MipsEBADF } - return v0, v1, newPreimageOffset + return v0, v1, newPreimageOffset, memUpdated, memAddr } func HandleSysWrite(a0, a1, a2 uint32, lastHint hexutil.Bytes, preimageKey [32]byte, preimageOffset uint32, oracle mipsevm.PreimageOracle, memory *memory.Memory, memTracker MemTracker, stdOut, stdErr io.Writer) (v0, v1 uint32, newLastHint hexutil.Bytes, newPreimageKey common.Hash, newPreimageOffset uint32) { diff --git a/cannon/mipsevm/multithreaded/mips.go b/cannon/mipsevm/multithreaded/mips.go index 73eb33c03a81..89ecadd01366 100644 --- a/cannon/mipsevm/multithreaded/mips.go +++ b/cannon/mipsevm/multithreaded/mips.go @@ -75,8 +75,13 @@ func (m *InstrumentedState) handleSyscall() error { return nil case exec.SysRead: var newPreimageOffset uint32 - v0, v1, newPreimageOffset = exec.HandleSysRead(a0, a1, a2, m.state.PreimageKey, m.state.PreimageOffset, m.preimageOracle, m.state.Memory, m.memoryTracker) + var memUpdated bool + var memAddr uint32 + v0, v1, newPreimageOffset, memUpdated, memAddr = exec.HandleSysRead(a0, a1, a2, m.state.PreimageKey, m.state.PreimageOffset, m.preimageOracle, m.state.Memory, m.memoryTracker) m.state.PreimageOffset = newPreimageOffset + if memUpdated { + m.handleMemoryUpdate(memAddr) + } case exec.SysWrite: var newLastHint hexutil.Bytes var newPreimageKey common.Hash @@ -158,8 +163,10 @@ func (m *InstrumentedState) handleSyscall() error { effAddr := a1 & 0xFFffFFfc m.memoryTracker.TrackMemAccess(effAddr) m.state.Memory.SetMemory(effAddr, secs) + m.handleMemoryUpdate(effAddr) m.memoryTracker.TrackMemAccess2(effAddr + 4) m.state.Memory.SetMemory(effAddr+4, nsecs) + m.handleMemoryUpdate(effAddr + 4) default: v0 = exec.SysErrorSignal v1 = exec.MipsEINVAL @@ -286,8 +293,71 @@ func (m *InstrumentedState) mipsStep() error { return m.handleSyscall() } + // Handle RMW (read-modify-write) ops + if opcode == exec.OpLoadLinked || opcode == exec.OpStoreConditional { + return m.handleRMWOps(insn, opcode) + } + // Exec the rest of the step logic - return exec.ExecMipsCoreStepLogic(m.state.getCpuRef(), m.state.GetRegistersRef(), m.state.Memory, insn, opcode, fun, m.memoryTracker, m.stackTracker) + memUpdated, memAddr, err := exec.ExecMipsCoreStepLogic(m.state.getCpuRef(), m.state.GetRegistersRef(), m.state.Memory, insn, opcode, fun, m.memoryTracker, m.stackTracker) + if err != nil { + return err + } + if memUpdated { + m.handleMemoryUpdate(memAddr) + } + + return nil +} + +func (m *InstrumentedState) handleMemoryUpdate(memAddr uint32) { + if memAddr == m.state.LLAddress { + // Reserved address was modified, clear the reservation + m.clearLLMemoryReservation() + } +} + +func (m *InstrumentedState) clearLLMemoryReservation() { + m.state.LLReservationActive = false + m.state.LLAddress = 0 + m.state.LLOwnerThread = 0 +} + +// handleRMWOps handles LL and SC operations which provide the primitives to implement read-modify-write operations +func (m *InstrumentedState) handleRMWOps(insn, opcode uint32) error { + baseReg := (insn >> 21) & 0x1F + base := m.state.GetRegistersRef()[baseReg] + rtReg := (insn >> 16) & 0x1F + offset := exec.SignExtendImmediate(insn) + + effAddr := (base + offset) & 0xFFFFFFFC + m.memoryTracker.TrackMemAccess(effAddr) + mem := m.state.Memory.GetMemory(effAddr) + + var retVal uint32 + threadId := m.state.GetCurrentThread().ThreadId + if opcode == exec.OpLoadLinked { + retVal = mem + m.state.LLReservationActive = true + m.state.LLAddress = effAddr + m.state.LLOwnerThread = threadId + } else if opcode == exec.OpStoreConditional { + // Check if our memory reservation is still intact + if m.state.LLReservationActive && m.state.LLOwnerThread == threadId && m.state.LLAddress == effAddr { + // Complete atomic update: set memory and return 1 for success + m.clearLLMemoryReservation() + rt := m.state.GetRegistersRef()[rtReg] + m.state.Memory.SetMemory(effAddr, rt) + retVal = 1 + } else { + // Atomic update failed, return 0 for failure + retVal = 0 + } + } else { + panic(fmt.Sprintf("Invalid instruction passed to handleRMWOps (opcode %08x)", opcode)) + } + + return exec.HandleRd(m.state.getCpuRef(), m.state.GetRegistersRef(), rtReg, retVal, true) } func (m *InstrumentedState) onWaitComplete(thread *ThreadState, isTimedOut bool) { diff --git a/cannon/mipsevm/multithreaded/state.go b/cannon/mipsevm/multithreaded/state.go index d0bf4bf5dd82..f93a99564958 100644 --- a/cannon/mipsevm/multithreaded/state.go +++ b/cannon/mipsevm/multithreaded/state.go @@ -5,7 +5,6 @@ import ( "fmt" "io" - "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" @@ -14,16 +13,20 @@ import ( "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/cannon/mipsevm/exec" "github.com/ethereum-optimism/optimism/cannon/mipsevm/memory" + "github.com/ethereum-optimism/optimism/cannon/serialize" ) // STATE_WITNESS_SIZE is the size of the state witness encoding in bytes. -const STATE_WITNESS_SIZE = 163 +const STATE_WITNESS_SIZE = 172 const ( MEMROOT_WITNESS_OFFSET = 0 PREIMAGE_KEY_WITNESS_OFFSET = MEMROOT_WITNESS_OFFSET + 32 PREIMAGE_OFFSET_WITNESS_OFFSET = PREIMAGE_KEY_WITNESS_OFFSET + 32 HEAP_WITNESS_OFFSET = PREIMAGE_OFFSET_WITNESS_OFFSET + 4 - EXITCODE_WITNESS_OFFSET = HEAP_WITNESS_OFFSET + 4 + LL_RESERVATION_ACTIVE_OFFSET = HEAP_WITNESS_OFFSET + 4 + LL_ADDRESS_OFFSET = LL_RESERVATION_ACTIVE_OFFSET + 1 + LL_OWNER_THREAD_OFFSET = LL_ADDRESS_OFFSET + 4 + EXITCODE_WITNESS_OFFSET = LL_OWNER_THREAD_OFFSET + 4 EXITED_WITNESS_OFFSET = EXITCODE_WITNESS_OFFSET + 1 STEP_WITNESS_OFFSET = EXITED_WITNESS_OFFSET + 1 STEPS_SINCE_CONTEXT_SWITCH_WITNESS_OFFSET = STEP_WITNESS_OFFSET + 8 @@ -40,7 +43,10 @@ type State struct { PreimageKey common.Hash PreimageOffset uint32 // note that the offset includes the 8-byte length prefix - Heap uint32 // to handle mmap growth + Heap uint32 // to handle mmap growth + LLReservationActive bool // Whether there is an active memory reservation initiated via the LL (load linked) op + LLAddress uint32 // The "linked" memory address reserved via the LL (load linked) op + LLOwnerThread uint32 // The id of the thread that holds the reservation on LLAddress ExitCode uint8 Exited bool @@ -64,16 +70,19 @@ func CreateEmptyState() *State { initThread := CreateEmptyThread() return &State{ - Memory: memory.NewMemory(), - Heap: 0, - ExitCode: 0, - Exited: false, - Step: 0, - Wakeup: exec.FutexEmptyAddr, - TraverseRight: false, - LeftThreadStack: []*ThreadState{initThread}, - RightThreadStack: []*ThreadState{}, - NextThreadId: initThread.ThreadId + 1, + Memory: memory.NewMemory(), + Heap: 0, + LLReservationActive: false, + LLAddress: 0, + LLOwnerThread: 0, + ExitCode: 0, + Exited: false, + Step: 0, + Wakeup: exec.FutexEmptyAddr, + TraverseRight: false, + LeftThreadStack: []*ThreadState{initThread}, + RightThreadStack: []*ThreadState{}, + NextThreadId: initThread.ThreadId + 1, } } @@ -187,6 +196,9 @@ func (s *State) EncodeWitness() ([]byte, common.Hash) { out = append(out, s.PreimageKey[:]...) out = binary.BigEndian.AppendUint32(out, s.PreimageOffset) out = binary.BigEndian.AppendUint32(out, s.Heap) + out = mipsevm.AppendBoolToWitness(out, s.LLReservationActive) + out = binary.BigEndian.AppendUint32(out, s.LLAddress) + out = binary.BigEndian.AppendUint32(out, s.LLOwnerThread) out = append(out, s.ExitCode) out = mipsevm.AppendBoolToWitness(out, s.Exited) @@ -264,6 +276,15 @@ func (s *State) Serialize(out io.Writer) error { if err := bout.WriteUInt(s.Heap); err != nil { return err } + if err := bout.WriteBool(s.LLReservationActive); err != nil { + return err + } + if err := bout.WriteUInt(s.LLAddress); err != nil { + return err + } + if err := bout.WriteUInt(s.LLOwnerThread); err != nil { + return err + } if err := bout.WriteUInt(s.ExitCode); err != nil { return err } @@ -324,6 +345,15 @@ func (s *State) Deserialize(in io.Reader) error { if err := bin.ReadUInt(&s.Heap); err != nil { return err } + if err := bin.ReadBool(&s.LLReservationActive); err != nil { + return err + } + if err := bin.ReadUInt(&s.LLAddress); err != nil { + return err + } + if err := bin.ReadUInt(&s.LLOwnerThread); err != nil { + return err + } if err := bin.ReadUInt(&s.ExitCode); err != nil { return err } diff --git a/cannon/mipsevm/multithreaded/state_test.go b/cannon/mipsevm/multithreaded/state_test.go index 7aa3580f58ff..6d776632bf0f 100644 --- a/cannon/mipsevm/multithreaded/state_test.go +++ b/cannon/mipsevm/multithreaded/state_test.go @@ -6,7 +6,6 @@ import ( "encoding/json" "testing" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/memory" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" @@ -15,6 +14,7 @@ import ( "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/cannon/mipsevm/exec" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/memory" "github.com/ethereum-optimism/optimism/cannon/mipsevm/program" ) @@ -42,6 +42,8 @@ func TestState_EncodeWitness(t *testing.T) { } heap := uint32(12) + llAddress := uint32(55) + llThreadOwner := uint32(99) preimageKey := crypto.Keccak256Hash([]byte{1, 2, 3, 4}) preimageOffset := uint32(24) step := uint64(33) @@ -53,6 +55,9 @@ func TestState_EncodeWitness(t *testing.T) { state.PreimageKey = preimageKey state.PreimageOffset = preimageOffset state.Heap = heap + state.LLReservationActive = true + state.LLAddress = llAddress + state.LLOwnerThread = llThreadOwner state.Step = step state.StepsSinceLastContextSwitch = stepsSinceContextSwitch @@ -66,6 +71,9 @@ func TestState_EncodeWitness(t *testing.T) { setWitnessField(expectedWitness, PREIMAGE_KEY_WITNESS_OFFSET, preimageKey[:]) setWitnessField(expectedWitness, PREIMAGE_OFFSET_WITNESS_OFFSET, []byte{0, 0, 0, byte(preimageOffset)}) setWitnessField(expectedWitness, HEAP_WITNESS_OFFSET, []byte{0, 0, 0, byte(heap)}) + setWitnessField(expectedWitness, LL_RESERVATION_ACTIVE_OFFSET, []byte{1}) + setWitnessField(expectedWitness, LL_ADDRESS_OFFSET, []byte{0, 0, 0, byte(llAddress)}) + setWitnessField(expectedWitness, LL_OWNER_THREAD_OFFSET, []byte{0, 0, 0, byte(llThreadOwner)}) setWitnessField(expectedWitness, EXITCODE_WITNESS_OFFSET, []byte{c.exitCode}) if c.exited { setWitnessField(expectedWitness, EXITED_WITNESS_OFFSET, []byte{1}) @@ -176,6 +184,9 @@ func TestSerializeStateRoundTrip(t *testing.T) { PreimageKey: common.Hash{0xFF}, PreimageOffset: 5, Heap: 0xc0ffee, + LLReservationActive: true, + LLAddress: 0x12345678, + LLOwnerThread: 0x02, ExitCode: 1, Exited: true, Step: 0xdeadbeef, diff --git a/cannon/mipsevm/multithreaded/testutil/expectations.go b/cannon/mipsevm/multithreaded/testutil/expectations.go index 24158be8e235..559ed2de8c4f 100644 --- a/cannon/mipsevm/multithreaded/testutil/expectations.go +++ b/cannon/mipsevm/multithreaded/testutil/expectations.go @@ -14,15 +14,18 @@ import ( // ExpectedMTState is a test utility that basically stores a copy of a state that can be explicitly mutated // to define an expected post-state. The post-state is then validated with ExpectedMTState.Validate(t, postState) type ExpectedMTState struct { - PreimageKey common.Hash - PreimageOffset uint32 - Heap uint32 - ExitCode uint8 - Exited bool - Step uint64 - LastHint hexutil.Bytes - MemoryRoot common.Hash - expectedMemory *memory.Memory + PreimageKey common.Hash + PreimageOffset uint32 + Heap uint32 + LLReservationActive bool + LLAddress uint32 + LLOwnerThread uint32 + ExitCode uint8 + Exited bool + Step uint64 + LastHint hexutil.Bytes + MemoryRoot common.Hash + expectedMemory *memory.Memory // Threading-related expectations StepsSinceLastContextSwitch uint64 Wakeup uint32 @@ -62,14 +65,17 @@ func NewExpectedMTState(fromState *multithreaded.State) *ExpectedMTState { return &ExpectedMTState{ // General Fields - PreimageKey: fromState.GetPreimageKey(), - PreimageOffset: fromState.GetPreimageOffset(), - Heap: fromState.GetHeap(), - ExitCode: fromState.GetExitCode(), - Exited: fromState.GetExited(), - Step: fromState.GetStep(), - LastHint: fromState.GetLastHint(), - MemoryRoot: fromState.GetMemory().MerkleRoot(), + PreimageKey: fromState.GetPreimageKey(), + PreimageOffset: fromState.GetPreimageOffset(), + Heap: fromState.GetHeap(), + LLReservationActive: fromState.LLReservationActive, + LLAddress: fromState.LLAddress, + LLOwnerThread: fromState.LLOwnerThread, + ExitCode: fromState.GetExitCode(), + Exited: fromState.GetExited(), + Step: fromState.GetStep(), + LastHint: fromState.GetLastHint(), + MemoryRoot: fromState.GetMemory().MerkleRoot(), // Thread-related global fields StepsSinceLastContextSwitch: fromState.StepsSinceLastContextSwitch, Wakeup: fromState.Wakeup, @@ -119,7 +125,7 @@ func (e *ExpectedMTState) ExpectMemoryWrite(addr uint32, val uint32) { func (e *ExpectedMTState) ExpectMemoryWriteMultiple(addr uint32, val uint32, addr2 uint32, val2 uint32) { e.expectedMemory.SetMemory(addr, val) - e.expectedMemory.SetMemory(addr2, val) + e.expectedMemory.SetMemory(addr2, val2) e.MemoryRoot = e.expectedMemory.MerkleRoot() } @@ -168,6 +174,9 @@ func (e *ExpectedMTState) Validate(t require.TestingT, actualState *multithreade require.Equalf(t, e.PreimageKey, actualState.GetPreimageKey(), "Expect preimageKey = %v", e.PreimageKey) require.Equalf(t, e.PreimageOffset, actualState.GetPreimageOffset(), "Expect preimageOffset = %v", e.PreimageOffset) require.Equalf(t, e.Heap, actualState.GetHeap(), "Expect heap = 0x%x", e.Heap) + require.Equalf(t, e.LLReservationActive, actualState.LLReservationActive, "Expect LLReservationActive = %v", e.LLReservationActive) + require.Equalf(t, e.LLAddress, actualState.LLAddress, "Expect LLAddress = 0x%x", e.LLAddress) + require.Equalf(t, e.LLOwnerThread, actualState.LLOwnerThread, "Expect LLOwnerThread = %v", e.LLOwnerThread) require.Equalf(t, e.ExitCode, actualState.GetExitCode(), "Expect exitCode = 0x%x", e.ExitCode) require.Equalf(t, e.Exited, actualState.GetExited(), "Expect exited = %v", e.Exited) require.Equalf(t, e.Step, actualState.GetStep(), "Expect step = %d", e.Step) diff --git a/cannon/mipsevm/multithreaded/testutil/expectations_test.go b/cannon/mipsevm/multithreaded/testutil/expectations_test.go index 15cba8b00469..a40e15e0f8d5 100644 --- a/cannon/mipsevm/multithreaded/testutil/expectations_test.go +++ b/cannon/mipsevm/multithreaded/testutil/expectations_test.go @@ -28,6 +28,9 @@ func TestValidate_shouldCatchMutations(t *testing.T) { {name: "PreimageKey", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.PreimageKey = emptyHash }}, {name: "PreimageOffset", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.PreimageOffset += 1 }}, {name: "Heap", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.Heap += 1 }}, + {name: "LLReservationActive", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.LLReservationActive = !e.LLReservationActive }}, + {name: "LLAddress", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.LLAddress += 1 }}, + {name: "LLOwnerThread", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.LLOwnerThread += 1 }}, {name: "ExitCode", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.ExitCode += 1 }}, {name: "Exited", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.Exited = !e.Exited }}, {name: "Step", mut: func(e *ExpectedMTState, st *multithreaded.State) { e.Step += 1 }}, diff --git a/cannon/mipsevm/multithreaded/testutil/mutators.go b/cannon/mipsevm/multithreaded/testutil/mutators.go index 30a97691609e..529f496f950f 100644 --- a/cannon/mipsevm/multithreaded/testutil/mutators.go +++ b/cannon/mipsevm/multithreaded/testutil/mutators.go @@ -1,6 +1,7 @@ package testutil import ( + "math" "math/rand" "github.com/ethereum/go-ethereum/common" @@ -28,11 +29,19 @@ func (m *StateMutatorMultiThreaded) Randomize(randSeed int64) { m.state.PreimageKey = testutil.RandHash(r) m.state.PreimageOffset = r.Uint32() - m.state.Heap = r.Uint32() m.state.Step = step m.state.LastHint = testutil.RandHint(r) m.state.StepsSinceLastContextSwitch = uint64(r.Intn(exec.SchedQuantum)) + // Randomize memory-related fields + halfMemory := math.MaxUint32 / 2 + m.state.Heap = uint32(r.Intn(halfMemory) + halfMemory) + m.state.LLReservationActive = r.Intn(2) == 1 + if m.state.LLReservationActive { + m.state.LLAddress = uint32(r.Intn(halfMemory)) + m.state.LLOwnerThread = uint32(r.Intn(10)) + } + // Randomize threads activeStackThreads := r.Intn(2) + 1 inactiveStackThreads := r.Intn(3) diff --git a/cannon/mipsevm/singlethreaded/mips.go b/cannon/mipsevm/singlethreaded/mips.go index 48a25e084291..a88d0c66b0e6 100644 --- a/cannon/mipsevm/singlethreaded/mips.go +++ b/cannon/mipsevm/singlethreaded/mips.go @@ -1,6 +1,8 @@ package singlethreaded import ( + "fmt" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -30,7 +32,7 @@ func (m *InstrumentedState) handleSyscall() error { return nil case exec.SysRead: var newPreimageOffset uint32 - v0, v1, newPreimageOffset = exec.HandleSysRead(a0, a1, a2, m.state.PreimageKey, m.state.PreimageOffset, m.preimageOracle, m.state.Memory, m.memoryTracker) + v0, v1, newPreimageOffset, _, _ = exec.HandleSysRead(a0, a1, a2, m.state.PreimageKey, m.state.PreimageOffset, m.preimageOracle, m.state.Memory, m.memoryTracker) m.state.PreimageOffset = newPreimageOffset case exec.SysWrite: var newLastHint hexutil.Bytes @@ -62,6 +64,37 @@ func (m *InstrumentedState) mipsStep() error { return m.handleSyscall() } + // Handle RMW (read-modify-write) ops + if opcode == exec.OpLoadLinked || opcode == exec.OpStoreConditional { + return m.handleRMWOps(insn, opcode) + } + // Exec the rest of the step logic - return exec.ExecMipsCoreStepLogic(&m.state.Cpu, &m.state.Registers, m.state.Memory, insn, opcode, fun, m.memoryTracker, m.stackTracker) + _, _, err := exec.ExecMipsCoreStepLogic(&m.state.Cpu, &m.state.Registers, m.state.Memory, insn, opcode, fun, m.memoryTracker, m.stackTracker) + return err +} + +// handleRMWOps handles LL and SC operations which provide the primitives to implement read-modify-write operations +func (m *InstrumentedState) handleRMWOps(insn, opcode uint32) error { + baseReg := (insn >> 21) & 0x1F + base := m.state.Registers[baseReg] + rtReg := (insn >> 16) & 0x1F + offset := exec.SignExtendImmediate(insn) + + effAddr := (base + offset) & 0xFFFFFFFC + m.memoryTracker.TrackMemAccess(effAddr) + mem := m.state.Memory.GetMemory(effAddr) + + var retVal uint32 + if opcode == exec.OpLoadLinked { + retVal = mem + } else if opcode == exec.OpStoreConditional { + rt := m.state.Registers[rtReg] + m.state.Memory.SetMemory(effAddr, rt) + retVal = 1 // 1 for success + } else { + panic(fmt.Sprintf("Invalid instruction passed to handleRMWOps (opcode %08x)", opcode)) + } + + return exec.HandleRd(&m.state.Cpu, &m.state.Registers, rtReg, retVal, true) } diff --git a/cannon/mipsevm/tests/evm_common_test.go b/cannon/mipsevm/tests/evm_common_test.go index 9c4619fb2fc2..ea6c7b2de957 100644 --- a/cannon/mipsevm/tests/evm_common_test.go +++ b/cannon/mipsevm/tests/evm_common_test.go @@ -2,7 +2,6 @@ package tests import ( "bytes" - "encoding/binary" "fmt" "io" "os" @@ -13,14 +12,12 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/tracing" - "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/require" "github.com/ethereum-optimism/optimism/cannon/mipsevm/exec" "github.com/ethereum-optimism/optimism/cannon/mipsevm/memory" "github.com/ethereum-optimism/optimism/cannon/mipsevm/program" "github.com/ethereum-optimism/optimism/cannon/mipsevm/testutil" - preimage "github.com/ethereum-optimism/optimism/op-preimage" ) func TestEVM(t *testing.T) { @@ -230,85 +227,6 @@ func TestEVM_MMap(t *testing.T) { } } -func TestEVM_SysRead_Preimage(t *testing.T) { - var tracer *tracing.Hooks - - preimageValue := make([]byte, 0, 8) - preimageValue = binary.BigEndian.AppendUint32(preimageValue, 0x12_34_56_78) - preimageValue = binary.BigEndian.AppendUint32(preimageValue, 0x98_76_54_32) - - versions := GetMipsVersionTestCases(t) - - cases := []struct { - name string - addr uint32 - count uint32 - writeLen uint32 - preimageOffset uint32 - prestateMem uint32 - postateMem uint32 - shouldPanic bool - }{ - {name: "Aligned addr, write 1 byte", addr: 0x00_00_FF_00, count: 1, writeLen: 1, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x12_FF_FF_FF}, - {name: "Aligned addr, write 2 byte", addr: 0x00_00_FF_00, count: 2, writeLen: 2, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x12_34_FF_FF}, - {name: "Aligned addr, write 3 byte", addr: 0x00_00_FF_00, count: 3, writeLen: 3, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x12_34_56_FF}, - {name: "Aligned addr, write 4 byte", addr: 0x00_00_FF_00, count: 4, writeLen: 4, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x12_34_56_78}, - {name: "1-byte misaligned addr, write 1 byte", addr: 0x00_00_FF_01, count: 1, writeLen: 1, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_12_FF_FF}, - {name: "1-byte misaligned addr, write 2 byte", addr: 0x00_00_FF_01, count: 2, writeLen: 2, preimageOffset: 9, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_34_56_FF}, - {name: "1-byte misaligned addr, write 3 byte", addr: 0x00_00_FF_01, count: 3, writeLen: 3, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_12_34_56}, - {name: "2-byte misaligned addr, write 1 byte", addr: 0x00_00_FF_02, count: 1, writeLen: 1, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_12_FF}, - {name: "2-byte misaligned addr, write 2 byte", addr: 0x00_00_FF_02, count: 2, writeLen: 2, preimageOffset: 12, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_98_76}, - {name: "3-byte misaligned addr, write 1 byte", addr: 0x00_00_FF_03, count: 1, writeLen: 1, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_FF_12}, - {name: "Count of 0", addr: 0x00_00_FF_03, count: 0, writeLen: 0, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_FF_FF}, - {name: "Count greater than 4", addr: 0x00_00_FF_00, count: 15, writeLen: 4, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x12_34_56_78}, - {name: "Count greater than 4, unaligned", addr: 0x00_00_FF_01, count: 15, writeLen: 3, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_12_34_56}, - {name: "Offset at last byte", addr: 0x00_00_FF_00, count: 4, writeLen: 1, preimageOffset: 15, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x32_FF_FF_FF}, - {name: "Offset just out of bounds", addr: 0x00_00_FF_00, count: 4, writeLen: 0, preimageOffset: 16, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_FF_FF, shouldPanic: true}, - {name: "Offset out of bounds", addr: 0x00_00_FF_00, count: 4, writeLen: 0, preimageOffset: 17, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_FF_FF, shouldPanic: true}, - } - for i, c := range cases { - for _, v := range versions { - tName := fmt.Sprintf("%v (%v)", c.name, v.Name) - t.Run(tName, func(t *testing.T) { - effAddr := 0xFFffFFfc & c.addr - preimageKey := preimage.Keccak256Key(crypto.Keccak256Hash(preimageValue)).PreimageKey() - oracle := testutil.StaticOracle(t, preimageValue) - goVm := v.VMFactory(oracle, os.Stdout, os.Stderr, testutil.CreateLogger(), testutil.WithRandomization(int64(i)), testutil.WithPreimageKey(preimageKey), testutil.WithPreimageOffset(c.preimageOffset)) - state := goVm.GetState() - step := state.GetStep() - - // Set up state - state.GetRegistersRef()[2] = exec.SysRead - state.GetRegistersRef()[4] = exec.FdPreimageRead - state.GetRegistersRef()[5] = c.addr - state.GetRegistersRef()[6] = c.count - state.GetMemory().SetMemory(state.GetPC(), syscallInsn) - state.GetMemory().SetMemory(effAddr, c.prestateMem) - - // Setup expectations - expected := testutil.NewExpectedState(state) - expected.ExpectStep() - expected.Registers[2] = c.writeLen - expected.Registers[7] = 0 // no error - expected.PreimageOffset += c.writeLen - expected.ExpectMemoryWrite(effAddr, c.postateMem) - - if c.shouldPanic { - require.Panics(t, func() { _, _ = goVm.Step(true) }) - testutil.AssertPreimageOracleReverts(t, preimageKey, preimageValue, c.preimageOffset, v.Contracts, tracer) - } else { - stepWitness, err := goVm.Step(true) - require.NoError(t, err) - - // Check expectations - expected.Validate(t, state) - testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, tracer) - } - }) - } - } -} - func TestEVMSysWriteHint(t *testing.T) { var tracer *tracing.Hooks diff --git a/cannon/mipsevm/tests/evm_multithreaded_test.go b/cannon/mipsevm/tests/evm_multithreaded_test.go index 480dee57dfbb..f7ead804c707 100644 --- a/cannon/mipsevm/tests/evm_multithreaded_test.go +++ b/cannon/mipsevm/tests/evm_multithreaded_test.go @@ -1,6 +1,7 @@ package tests import ( + "encoding/binary" "fmt" "os" "slices" @@ -8,6 +9,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/require" "golang.org/x/exp/maps" @@ -16,8 +18,375 @@ import ( "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" mttestutil "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded/testutil" "github.com/ethereum-optimism/optimism/cannon/mipsevm/testutil" + preimage "github.com/ethereum-optimism/optimism/op-preimage" ) +func TestEVM_MT_LL(t *testing.T) { + var tracer *tracing.Hooks + + cases := []struct { + name string + base uint32 + offset int + value uint32 + effAddr uint32 + rtReg int + }{ + {name: "Aligned effAddr", base: 0x00_00_00_01, offset: 0x0133, value: 0xABCD, effAddr: 0x00_00_01_34, rtReg: 5}, + {name: "Aligned effAddr, signed extended", base: 0x00_00_00_01, offset: 0xFF33, value: 0xABCD, effAddr: 0xFF_FF_FF_34, rtReg: 5}, + {name: "Unaligned effAddr", base: 0xFF_12_00_01, offset: 0x3401, value: 0xABCD, effAddr: 0xFF_12_34_00, rtReg: 5}, + {name: "Unaligned effAddr, sign extended w overflow", base: 0xFF_12_00_01, offset: 0x8401, value: 0xABCD, effAddr: 0xFF_11_84_00, rtReg: 5}, + {name: "Return register set to 0", base: 0xFF_12_00_01, offset: 0x8401, value: 0xABCD, effAddr: 0xFF_11_84_00, rtReg: 0}, + } + for i, c := range cases { + for _, withExistingReservation := range []bool{true, false} { + tName := fmt.Sprintf("%v (withExistingReservation = %v)", c.name, withExistingReservation) + t.Run(tName, func(t *testing.T) { + rtReg := c.rtReg + baseReg := 6 + pc := uint32(0x44) + insn := uint32((0b11_0000 << 26) | (baseReg & 0x1F << 21) | (rtReg & 0x1F << 16) | (0xFFFF & c.offset)) + goVm, state, contracts := setup(t, i, nil) + step := state.GetStep() + + // Set up state + state.GetCurrentThread().Cpu.PC = pc + state.GetCurrentThread().Cpu.NextPC = pc + 4 + state.GetMemory().SetMemory(pc, insn) + state.GetMemory().SetMemory(c.effAddr, c.value) + state.GetRegistersRef()[baseReg] = c.base + if withExistingReservation { + state.LLReservationActive = true + state.LLAddress = c.effAddr + uint32(4) + state.LLOwnerThread = 123 + } else { + state.LLReservationActive = false + state.LLAddress = 0 + state.LLOwnerThread = 0 + } + + // Set up expectations + expected := mttestutil.NewExpectedMTState(state) + expected.ExpectStep() + expected.LLReservationActive = true + expected.LLAddress = c.effAddr + expected.LLOwnerThread = state.GetCurrentThread().ThreadId + if rtReg != 0 { + expected.ActiveThread().Registers[rtReg] = c.value + } + + stepWitness, err := goVm.Step(true) + require.NoError(t, err) + + // Check expectations + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) + }) + } + } +} + +func TestEVM_MT_SC(t *testing.T) { + var tracer *tracing.Hooks + + llVariations := []struct { + name string + llReservationActive bool + matchThreadId bool + matchEffAddr bool + shouldSucceed bool + }{ + {name: "should succeed", llReservationActive: true, matchThreadId: true, matchEffAddr: true, shouldSucceed: true}, + {name: "mismatch addr", llReservationActive: true, matchThreadId: false, matchEffAddr: true, shouldSucceed: false}, + {name: "mismatched thread", llReservationActive: true, matchThreadId: true, matchEffAddr: false, shouldSucceed: false}, + {name: "mismatched addr & thread", llReservationActive: true, matchThreadId: false, matchEffAddr: false, shouldSucceed: false}, + {name: "no active reservation", llReservationActive: false, matchThreadId: true, matchEffAddr: true, shouldSucceed: false}, + } + + cases := []struct { + name string + base uint32 + offset int + value uint32 + effAddr uint32 + rtReg int + threadId uint32 + }{ + {name: "Aligned effAddr", base: 0x00_00_00_01, offset: 0x0133, value: 0xABCD, effAddr: 0x00_00_01_34, rtReg: 5, threadId: 4}, + {name: "Aligned effAddr, signed extended", base: 0x00_00_00_01, offset: 0xFF33, value: 0xABCD, effAddr: 0xFF_FF_FF_34, rtReg: 5, threadId: 4}, + {name: "Unaligned effAddr", base: 0xFF_12_00_01, offset: 0x3401, value: 0xABCD, effAddr: 0xFF_12_34_00, rtReg: 5, threadId: 4}, + {name: "Unaligned effAddr, sign extended w overflow", base: 0xFF_12_00_01, offset: 0x8401, value: 0xABCD, effAddr: 0xFF_11_84_00, rtReg: 5, threadId: 4}, + {name: "Return register set to 0", base: 0xFF_12_00_01, offset: 0x8401, value: 0xABCD, effAddr: 0xFF_11_84_00, rtReg: 0, threadId: 4}, + {name: "Zero valued ll args", base: 0x00_00_00_00, offset: 0x0, value: 0xABCD, effAddr: 0x00_00_00_00, rtReg: 5, threadId: 0}, + } + for i, c := range cases { + for _, v := range llVariations { + tName := fmt.Sprintf("%v (%v)", c.name, v.name) + t.Run(tName, func(t *testing.T) { + rtReg := c.rtReg + baseReg := 6 + pc := uint32(0x44) + insn := uint32((0b11_1000 << 26) | (baseReg & 0x1F << 21) | (rtReg & 0x1F << 16) | (0xFFFF & c.offset)) + goVm, state, contracts := setup(t, i, nil) + mttestutil.InitializeSingleThread(i*23456, state, i%2 == 1) + step := state.GetStep() + + // Define LL-related params + var llAddress, llOwnerThread uint32 + if v.matchEffAddr { + llAddress = c.effAddr + } else { + llAddress = c.effAddr + 4 + } + if v.matchThreadId { + llOwnerThread = c.threadId + } else { + llOwnerThread = c.threadId + 1 + } + + // Setup state + state.GetCurrentThread().ThreadId = c.threadId + state.GetCurrentThread().Cpu.PC = pc + state.GetCurrentThread().Cpu.NextPC = pc + 4 + state.GetMemory().SetMemory(pc, insn) + state.GetRegistersRef()[baseReg] = c.base + state.GetRegistersRef()[rtReg] = c.value + state.LLReservationActive = v.llReservationActive + state.LLAddress = llAddress + state.LLOwnerThread = llOwnerThread + + // Setup expectations + expected := mttestutil.NewExpectedMTState(state) + expected.ExpectStep() + var retVal uint32 + if v.shouldSucceed { + retVal = 1 + expected.ExpectMemoryWrite(c.effAddr, c.value) + expected.LLReservationActive = false + expected.LLAddress = 0 + expected.LLOwnerThread = 0 + } else { + retVal = 0 + } + if rtReg != 0 { + expected.ActiveThread().Registers[rtReg] = retVal + } + + stepWitness, err := goVm.Step(true) + require.NoError(t, err) + + // Check expectations + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) + }) + } + } +} + +func TestEVM_MT_SysRead_Preimage(t *testing.T) { + var tracer *tracing.Hooks + + preimageValue := make([]byte, 0, 8) + preimageValue = binary.BigEndian.AppendUint32(preimageValue, 0x12_34_56_78) + preimageValue = binary.BigEndian.AppendUint32(preimageValue, 0x98_76_54_32) + + llVariations := []struct { + name string + llReservationActive bool + matchThreadId bool + matchEffAddr bool + shouldClearReservation bool + }{ + {name: "matching reservation", llReservationActive: true, matchThreadId: true, matchEffAddr: true, shouldClearReservation: true}, + {name: "matching reservation, diff thread", llReservationActive: true, matchThreadId: false, matchEffAddr: true, shouldClearReservation: true}, + {name: "mismatched reservation", llReservationActive: true, matchThreadId: true, matchEffAddr: false, shouldClearReservation: false}, + {name: "mismatched reservation", llReservationActive: true, matchThreadId: false, matchEffAddr: false, shouldClearReservation: false}, + {name: "no reservation, matching addr", llReservationActive: false, matchThreadId: true, matchEffAddr: true, shouldClearReservation: true}, + {name: "no reservation, mismatched addr", llReservationActive: false, matchThreadId: true, matchEffAddr: false, shouldClearReservation: false}, + } + + cases := []struct { + name string + addr uint32 + count uint32 + writeLen uint32 + preimageOffset uint32 + prestateMem uint32 + postateMem uint32 + shouldPanic bool + }{ + {name: "Aligned addr, write 1 byte", addr: 0x00_00_FF_00, count: 1, writeLen: 1, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x12_FF_FF_FF}, + {name: "Aligned addr, write 2 byte", addr: 0x00_00_FF_00, count: 2, writeLen: 2, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x12_34_FF_FF}, + {name: "Aligned addr, write 3 byte", addr: 0x00_00_FF_00, count: 3, writeLen: 3, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x12_34_56_FF}, + {name: "Aligned addr, write 4 byte", addr: 0x00_00_FF_00, count: 4, writeLen: 4, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x12_34_56_78}, + {name: "1-byte misaligned addr, write 1 byte", addr: 0x00_00_FF_01, count: 1, writeLen: 1, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_12_FF_FF}, + {name: "1-byte misaligned addr, write 2 byte", addr: 0x00_00_FF_01, count: 2, writeLen: 2, preimageOffset: 9, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_34_56_FF}, + {name: "1-byte misaligned addr, write 3 byte", addr: 0x00_00_FF_01, count: 3, writeLen: 3, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_12_34_56}, + {name: "2-byte misaligned addr, write 1 byte", addr: 0x00_00_FF_02, count: 1, writeLen: 1, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_12_FF}, + {name: "2-byte misaligned addr, write 2 byte", addr: 0x00_00_FF_02, count: 2, writeLen: 2, preimageOffset: 12, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_98_76}, + {name: "3-byte misaligned addr, write 1 byte", addr: 0x00_00_FF_03, count: 1, writeLen: 1, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_FF_12}, + {name: "Count of 0", addr: 0x00_00_FF_03, count: 0, writeLen: 0, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_FF_FF}, + {name: "Count greater than 4", addr: 0x00_00_FF_00, count: 15, writeLen: 4, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x12_34_56_78}, + {name: "Count greater than 4, unaligned", addr: 0x00_00_FF_01, count: 15, writeLen: 3, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_12_34_56}, + {name: "Offset at last byte", addr: 0x00_00_FF_00, count: 4, writeLen: 1, preimageOffset: 15, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x32_FF_FF_FF}, + {name: "Offset just out of bounds", addr: 0x00_00_FF_00, count: 4, writeLen: 0, preimageOffset: 16, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_FF_FF, shouldPanic: true}, + {name: "Offset out of bounds", addr: 0x00_00_FF_00, count: 4, writeLen: 0, preimageOffset: 17, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_FF_FF, shouldPanic: true}, + } + for i, c := range cases { + for _, v := range llVariations { + tName := fmt.Sprintf("%v (%v)", c.name, v.name) + t.Run(tName, func(t *testing.T) { + effAddr := 0xFFffFFfc & c.addr + preimageKey := preimage.Keccak256Key(crypto.Keccak256Hash(preimageValue)).PreimageKey() + oracle := testutil.StaticOracle(t, preimageValue) + goVm, state, contracts := setup(t, i, oracle) + step := state.GetStep() + + // Define LL-related params + var llAddress, llOwnerThread uint32 + if v.matchEffAddr { + llAddress = effAddr + } else { + llAddress = effAddr + 4 + } + if v.matchThreadId { + llOwnerThread = state.GetCurrentThread().ThreadId + } else { + llOwnerThread = state.GetCurrentThread().ThreadId + 1 + } + + // Set up state + state.PreimageKey = preimageKey + state.PreimageOffset = c.preimageOffset + state.GetRegistersRef()[2] = exec.SysRead + state.GetRegistersRef()[4] = exec.FdPreimageRead + state.GetRegistersRef()[5] = c.addr + state.GetRegistersRef()[6] = c.count + state.GetMemory().SetMemory(state.GetPC(), syscallInsn) + state.LLReservationActive = v.llReservationActive + state.LLAddress = llAddress + state.LLOwnerThread = llOwnerThread + state.GetMemory().SetMemory(effAddr, c.prestateMem) + + // Setup expectations + expected := mttestutil.NewExpectedMTState(state) + expected.ExpectStep() + expected.ActiveThread().Registers[2] = c.writeLen + expected.ActiveThread().Registers[7] = 0 // no error + expected.PreimageOffset += c.writeLen + expected.ExpectMemoryWrite(effAddr, c.postateMem) + if v.shouldClearReservation { + expected.LLReservationActive = false + expected.LLAddress = 0 + expected.LLOwnerThread = 0 + } + + if c.shouldPanic { + require.Panics(t, func() { _, _ = goVm.Step(true) }) + testutil.AssertPreimageOracleReverts(t, preimageKey, preimageValue, c.preimageOffset, contracts, tracer) + } else { + stepWitness, err := goVm.Step(true) + require.NoError(t, err) + + // Check expectations + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) + } + }) + } + } +} + +func TestEVM_MT_StoreOpsClearMemReservation(t *testing.T) { + var tracer *tracing.Hooks + + llVariations := []struct { + name string + llReservationActive bool + matchThreadId bool + matchEffAddr bool + shouldClearReservation bool + }{ + {name: "matching reservation", llReservationActive: true, matchThreadId: true, matchEffAddr: true, shouldClearReservation: true}, + {name: "matching reservation, diff thread", llReservationActive: true, matchThreadId: false, matchEffAddr: true, shouldClearReservation: true}, + {name: "mismatched reservation", llReservationActive: true, matchThreadId: true, matchEffAddr: false, shouldClearReservation: false}, + {name: "mismatched reservation, diff thread", llReservationActive: true, matchThreadId: false, matchEffAddr: false, shouldClearReservation: false}, + {name: "no reservation, matching addr", llReservationActive: false, matchThreadId: true, matchEffAddr: true, shouldClearReservation: true}, + {name: "no reservation, mismatched addr", llReservationActive: false, matchThreadId: true, matchEffAddr: false, shouldClearReservation: false}, + } + + pc := uint32(0x04) + rt := uint32(0x12_34_56_78) + baseReg := 5 + rtReg := 6 + cases := []struct { + name string + opcode int + offset int + base uint32 + effAddr uint32 + preMem uint32 + postMem uint32 + }{ + {name: "Store byte", opcode: 0b10_1000, base: 0xFF_00_00_04, offset: 0xFF_00_00_08, effAddr: 0xFF_00_00_0C, preMem: 0xFF_FF_FF_FF, postMem: 0x78_FF_FF_FF}, + {name: "Store halfword", opcode: 0b10_1001, base: 0xFF_00_00_04, offset: 0xFF_00_00_08, effAddr: 0xFF_00_00_0C, preMem: 0xFF_FF_FF_FF, postMem: 0x56_78_FF_FF}, + {name: "Store word left", opcode: 0b10_1010, base: 0xFF_00_00_04, offset: 0xFF_00_00_08, effAddr: 0xFF_00_00_0C, preMem: 0xFF_FF_FF_FF, postMem: 0x12_34_56_78}, + {name: "Store word", opcode: 0b10_1011, base: 0xFF_00_00_04, offset: 0xFF_00_00_08, effAddr: 0xFF_00_00_0C, preMem: 0xFF_FF_FF_FF, postMem: 0x12_34_56_78}, + {name: "Store word right", opcode: 0b10_1110, base: 0xFF_00_00_04, offset: 0xFF_00_00_08, effAddr: 0xFF_00_00_0C, preMem: 0xFF_FF_FF_FF, postMem: 0x78_FF_FF_FF}, + } + for i, c := range cases { + for _, v := range llVariations { + tName := fmt.Sprintf("%v (%v)", c.name, v.name) + t.Run(tName, func(t *testing.T) { + insn := uint32((c.opcode << 26) | (baseReg & 0x1F << 21) | (rtReg & 0x1F << 16) | (0xFFFF & c.offset)) + goVm, state, contracts := setup(t, i, nil) + step := state.GetStep() + + // Define LL-related params + var llAddress, llOwnerThread uint32 + if v.matchEffAddr { + llAddress = c.effAddr + } else { + llAddress = c.effAddr + 4 + } + if v.matchThreadId { + llOwnerThread = state.GetCurrentThread().ThreadId + } else { + llOwnerThread = state.GetCurrentThread().ThreadId + 1 + } + + // Setup state + state.GetCurrentThread().Cpu.PC = pc + state.GetCurrentThread().Cpu.NextPC = pc + 4 + state.GetRegistersRef()[rtReg] = rt + state.GetRegistersRef()[baseReg] = c.base + state.GetMemory().SetMemory(state.GetPC(), insn) + state.GetMemory().SetMemory(c.effAddr, c.preMem) + state.LLReservationActive = v.llReservationActive + state.LLAddress = llAddress + state.LLOwnerThread = llOwnerThread + + // Setup expectations + expected := mttestutil.NewExpectedMTState(state) + expected.ExpectStep() + expected.ExpectMemoryWrite(c.effAddr, c.postMem) + if v.shouldClearReservation { + expected.LLReservationActive = false + expected.LLAddress = 0 + expected.LLOwnerThread = 0 + } + + stepWitness, err := goVm.Step(true) + require.NoError(t, err) + + // Check expectations + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) + }) + } + } +} + func TestEVM_SysClone_FlagHandling(t *testing.T) { contracts := testutil.TestContractsSetup(t, testutil.MipsMultithreaded) var tracer *tracing.Hooks @@ -92,7 +461,7 @@ func TestEVM_SysClone_Successful(t *testing.T) { t.Run(c.name, func(t *testing.T) { stackPtr := uint32(100) - goVm, state, contracts := setup(t, i) + goVm, state, contracts := setup(t, i, nil) mttestutil.InitializeSingleThread(i*333, state, c.traverseRight) state.Memory.SetMemory(state.GetPC(), syscallInsn) state.GetRegistersRef()[2] = exec.SysClone // the syscall number @@ -153,7 +522,7 @@ func TestEVM_SysGetTID(t *testing.T) { for i, c := range cases { t.Run(c.name, func(t *testing.T) { - goVm, state, contracts := setup(t, i*789) + goVm, state, contracts := setup(t, i*789, nil) mttestutil.InitializeSingleThread(i*789, state, false) state.GetCurrentThread().ThreadId = c.threadId @@ -197,7 +566,7 @@ func TestEVM_SysExit(t *testing.T) { t.Run(c.name, func(t *testing.T) { exitCode := uint8(3) - goVm, state, contracts := setup(t, i*133) + goVm, state, contracts := setup(t, i*133, nil) mttestutil.SetupThreads(int64(i*1111), state, i%2 == 0, c.threadCount, 0) state.Memory.SetMemory(state.GetPC(), syscallInsn) @@ -245,7 +614,7 @@ func TestEVM_PopExitedThread(t *testing.T) { for i, c := range cases { t.Run(c.name, func(t *testing.T) { - goVm, state, contracts := setup(t, i*133) + goVm, state, contracts := setup(t, i*133, nil) mttestutil.SetupThreads(int64(i*222), state, c.traverseRight, c.activeStackThreadCount, 1) step := state.Step @@ -300,7 +669,7 @@ func TestEVM_SysFutex_WaitPrivate(t *testing.T) { for i, c := range cases { t.Run(c.name, func(t *testing.T) { - goVm, state, contracts := setup(t, i*1234) + goVm, state, contracts := setup(t, i*1234, nil) step := state.GetStep() state.Memory.SetMemory(state.GetPC(), syscallInsn) @@ -363,7 +732,7 @@ func TestEVM_SysFutex_WakePrivate(t *testing.T) { for i, c := range cases { t.Run(c.name, func(t *testing.T) { - goVm, state, contracts := setup(t, i*1122) + goVm, state, contracts := setup(t, i*1122, nil) mttestutil.SetupThreads(int64(i*2244), state, c.traverseRight, c.activeThreadCount, c.inactiveThreadCount) step := state.Step @@ -449,7 +818,7 @@ func TestEVM_SysFutex_UnsupportedOp(t *testing.T) { for name, op := range unsupportedFutexOps { t.Run(name, func(t *testing.T) { - goVm, state, contracts := setup(t, int(op)) + goVm, state, contracts := setup(t, int(op), nil) step := state.GetStep() state.Memory.SetMemory(state.GetPC(), syscallInsn) @@ -504,7 +873,7 @@ func runPreemptSyscall(t *testing.T, syscallName string, syscallNum uint32) { for _, traverseRight := range []bool{true, false} { testName := fmt.Sprintf("%v: %v (traverseRight = %v)", syscallName, c.name, traverseRight) t.Run(testName, func(t *testing.T) { - goVm, state, contracts := setup(t, i*789) + goVm, state, contracts := setup(t, i*789, nil) mttestutil.SetupThreads(int64(i*3259), state, traverseRight, c.activeThreads, c.inactiveThreads) state.Memory.SetMemory(state.GetPC(), syscallInsn) @@ -535,7 +904,7 @@ func runPreemptSyscall(t *testing.T, syscallName string, syscallNum uint32) { func TestEVM_SysOpen(t *testing.T) { var tracer *tracing.Hooks - goVm, state, contracts := setup(t, 5512) + goVm, state, contracts := setup(t, 5512, nil) state.Memory.SetMemory(state.GetPC(), syscallInsn) state.GetRegistersRef()[2] = exec.SysOpen // Set syscall number @@ -560,7 +929,7 @@ func TestEVM_SysOpen(t *testing.T) { func TestEVM_SysGetPID(t *testing.T) { var tracer *tracing.Hooks - goVm, state, contracts := setup(t, 1929) + goVm, state, contracts := setup(t, 1929, nil) state.Memory.SetMemory(state.GetPC(), syscallInsn) state.GetRegistersRef()[2] = exec.SysGetpid // Set syscall number @@ -594,6 +963,25 @@ func TestEVM_SysClockGettimeRealtime(t *testing.T) { func testEVM_SysClockGettime(t *testing.T, clkid uint32) { var tracer *tracing.Hooks + llVariations := []struct { + name string + llReservationActive bool + matchThreadId bool + matchEffAddr bool + matchEffAddr2 bool + shouldClearReservation bool + }{ + {name: "matching reservation", llReservationActive: true, matchThreadId: true, matchEffAddr: true, shouldClearReservation: true}, + {name: "matching reservation, 2nd word", llReservationActive: true, matchThreadId: true, matchEffAddr2: true, shouldClearReservation: true}, + {name: "matching reservation, diff thread", llReservationActive: true, matchThreadId: false, matchEffAddr: true, shouldClearReservation: true}, + {name: "matching reservation, diff thread, 2nd word", llReservationActive: true, matchThreadId: false, matchEffAddr2: true, shouldClearReservation: true}, + {name: "mismatched reservation", llReservationActive: true, matchThreadId: true, matchEffAddr: false, shouldClearReservation: false}, + {name: "mismatched reservation, diff thread", llReservationActive: true, matchThreadId: false, matchEffAddr: false, shouldClearReservation: false}, + {name: "no reservation, matching addr", llReservationActive: false, matchThreadId: true, matchEffAddr: true, shouldClearReservation: true}, + {name: "no reservation, matching addr2", llReservationActive: false, matchThreadId: true, matchEffAddr2: true, shouldClearReservation: true}, + {name: "no reservation, mismatched addr", llReservationActive: false, matchThreadId: true, matchEffAddr: false, shouldClearReservation: false}, + } + cases := []struct { name string timespecAddr uint32 @@ -601,45 +989,73 @@ func testEVM_SysClockGettime(t *testing.T, clkid uint32) { {"aligned timespec address", 0x1000}, {"unaligned timespec address", 0x1003}, } - for _, c := range cases { - t.Run(c.name, func(t *testing.T) { - goVm, state, contracts := setup(t, 2101) + for i, c := range cases { + for _, v := range llVariations { + tName := fmt.Sprintf("%v (%v)", c.name, v.name) + t.Run(tName, func(t *testing.T) { + goVm, state, contracts := setup(t, 2101, nil) + mttestutil.InitializeSingleThread(2101+i, state, i%2 == 1) + effAddr := c.timespecAddr & 0xFFffFFfc + effAddr2 := effAddr + 4 + step := state.Step - state.Memory.SetMemory(state.GetPC(), syscallInsn) - state.GetRegistersRef()[2] = exec.SysClockGetTime // Set syscall number - state.GetRegistersRef()[4] = clkid // a0 - state.GetRegistersRef()[5] = c.timespecAddr // a1 - step := state.Step + // Define LL-related params + var llAddress, llOwnerThread uint32 + if v.matchEffAddr { + llAddress = effAddr + } else if v.matchEffAddr2 { + llAddress = effAddr2 + } else { + llAddress = effAddr2 + 8 + } + if v.matchThreadId { + llOwnerThread = state.GetCurrentThread().ThreadId + } else { + llOwnerThread = state.GetCurrentThread().ThreadId + 1 + } - expected := mttestutil.NewExpectedMTState(state) - expected.ExpectStep() - expected.ActiveThread().Registers[2] = 0 - expected.ActiveThread().Registers[7] = 0 - next := state.Step + 1 - var secs, nsecs uint32 - if clkid == exec.ClockGettimeMonotonicFlag { - secs = uint32(next / exec.HZ) - nsecs = uint32((next % exec.HZ) * (1_000_000_000 / exec.HZ)) - } - effAddr := c.timespecAddr & 0xFFffFFfc - expected.ExpectMemoryWrite(effAddr, secs) - expected.ExpectMemoryWrite(effAddr+4, nsecs) + state.Memory.SetMemory(state.GetPC(), syscallInsn) + state.GetRegistersRef()[2] = exec.SysClockGetTime // Set syscall number + state.GetRegistersRef()[4] = clkid // a0 + state.GetRegistersRef()[5] = c.timespecAddr // a1 + state.LLReservationActive = v.llReservationActive + state.LLAddress = llAddress + state.LLOwnerThread = llOwnerThread - var err error - var stepWitness *mipsevm.StepWitness - stepWitness, err = goVm.Step(true) - require.NoError(t, err) + expected := mttestutil.NewExpectedMTState(state) + expected.ExpectStep() + expected.ActiveThread().Registers[2] = 0 + expected.ActiveThread().Registers[7] = 0 + next := state.Step + 1 + var secs, nsecs uint32 + if clkid == exec.ClockGettimeMonotonicFlag { + secs = uint32(next / exec.HZ) + nsecs = uint32((next % exec.HZ) * (1_000_000_000 / exec.HZ)) + } + expected.ExpectMemoryWrite(effAddr, secs) + expected.ExpectMemoryWrite(effAddr2, nsecs) + if v.shouldClearReservation { + expected.LLReservationActive = false + expected.LLAddress = 0 + expected.LLOwnerThread = 0 + } - // Validate post-state - expected.Validate(t, state) - testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) - }) + var err error + var stepWitness *mipsevm.StepWitness + stepWitness, err = goVm.Step(true) + require.NoError(t, err) + + // Validate post-state + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer) + }) + } } } func TestEVM_SysClockGettimeNonMonotonic(t *testing.T) { var tracer *tracing.Hooks - goVm, state, contracts := setup(t, 2101) + goVm, state, contracts := setup(t, 2101, nil) timespecAddr := uint32(0x1000) state.Memory.SetMemory(state.GetPC(), syscallInsn) @@ -700,7 +1116,7 @@ func TestEVM_NoopSyscall(t *testing.T) { var tracer *tracing.Hooks for noopName, noopVal := range NoopSyscalls { t.Run(noopName, func(t *testing.T) { - goVm, state, contracts := setup(t, int(noopVal)) + goVm, state, contracts := setup(t, int(noopVal), nil) state.Memory.SetMemory(state.GetPC(), syscallInsn) state.GetRegistersRef()[2] = noopVal // Set syscall number @@ -747,7 +1163,7 @@ func TestEVM_UnsupportedSyscall(t *testing.T) { syscallNum := syscallNum t.Run(testName, func(t *testing.T) { t.Parallel() - goVm, state, contracts := setup(t, i*3434) + goVm, state, contracts := setup(t, i*3434, nil) // Setup basic getThreadId syscall instruction state.Memory.SetMemory(state.GetPC(), syscallInsn) state.GetRegistersRef()[2] = syscallNum @@ -794,7 +1210,7 @@ func TestEVM_NormalTraversalStep_HandleWaitingThread(t *testing.T) { require.Fail(t, "Invalid test case - cannot expect a timeout with no wakeup") } - goVm, state, contracts := setup(t, i) + goVm, state, contracts := setup(t, i, nil) mttestutil.SetupThreads(int64(i*101), state, traverseRight, c.activeStackSize, c.otherStackSize) state.Step = c.step @@ -856,7 +1272,7 @@ func TestEVM_NormalTraversal_Full(t *testing.T) { testName := fmt.Sprintf("%v (traverseRight = %v)", c.name, traverseRight) t.Run(testName, func(t *testing.T) { // Setup - goVm, state, contracts := setup(t, i*789) + goVm, state, contracts := setup(t, i*789, nil) mttestutil.SetupThreads(int64(i*2947), state, traverseRight, c.threadCount, 0) // Put threads into a waiting state so that we just traverse through them for _, thread := range mttestutil.GetAllThreads(state) { @@ -926,7 +1342,7 @@ func TestEVM_WakeupTraversalStep(t *testing.T) { for i, c := range cases { t.Run(c.name, func(t *testing.T) { - goVm, state, contracts := setup(t, i*2000) + goVm, state, contracts := setup(t, i*2000, nil) mttestutil.SetupThreads(int64(i*101), state, c.traverseRight, c.activeStackSize, c.otherStackSize) step := state.Step @@ -974,7 +1390,7 @@ func TestEVM_WakeupTraversal_Full(t *testing.T) { for i, c := range cases { t.Run(c.name, func(t *testing.T) { // Setup - goVm, state, contracts := setup(t, i*789) + goVm, state, contracts := setup(t, i*789, nil) mttestutil.SetupThreads(int64(i*2947), state, false, c.threadCount, 0) state.Wakeup = 0x08 step := state.Step @@ -1028,7 +1444,7 @@ func TestEVM_SchedQuantumThreshold(t *testing.T) { for i, c := range cases { t.Run(c.name, func(t *testing.T) { - goVm, state, contracts := setup(t, i*789) + goVm, state, contracts := setup(t, i*789, nil) // Setup basic getThreadId syscall instruction state.Memory.SetMemory(state.GetPC(), syscallInsn) state.GetRegistersRef()[2] = exec.SysGetTID // Set syscall number @@ -1060,9 +1476,9 @@ func TestEVM_SchedQuantumThreshold(t *testing.T) { } } -func setup(t require.TestingT, randomSeed int) (mipsevm.FPVM, *multithreaded.State, *testutil.ContractMetadata) { +func setup(t require.TestingT, randomSeed int, preimageOracle mipsevm.PreimageOracle) (mipsevm.FPVM, *multithreaded.State, *testutil.ContractMetadata) { v := GetMultiThreadedTestCase(t) - vm := v.VMFactory(nil, os.Stdout, os.Stderr, testutil.CreateLogger(), testutil.WithRandomization(int64(randomSeed))) + vm := v.VMFactory(preimageOracle, os.Stdout, os.Stderr, testutil.CreateLogger(), testutil.WithRandomization(int64(randomSeed))) state := mttestutil.GetMtState(t, vm) return vm, state, v.Contracts diff --git a/cannon/mipsevm/tests/evm_singlethreaded_test.go b/cannon/mipsevm/tests/evm_singlethreaded_test.go new file mode 100644 index 000000000000..32cad32cc00e --- /dev/null +++ b/cannon/mipsevm/tests/evm_singlethreaded_test.go @@ -0,0 +1,196 @@ +package tests + +import ( + "encoding/binary" + "os" + "testing" + + "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/require" + + "github.com/ethereum-optimism/optimism/cannon/mipsevm/exec" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/memory" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/testutil" + preimage "github.com/ethereum-optimism/optimism/op-preimage" +) + +func TestEVM_LL(t *testing.T) { + var tracer *tracing.Hooks + + cases := []struct { + name string + base uint32 + offset int + value uint32 + effAddr uint32 + rtReg int + }{ + {name: "Aligned effAddr", base: 0x00_00_00_01, offset: 0x0133, value: 0xABCD, effAddr: 0x00_00_01_34, rtReg: 5}, + {name: "Aligned effAddr, signed extended", base: 0x00_00_00_01, offset: 0xFF33, value: 0xABCD, effAddr: 0xFF_FF_FF_34, rtReg: 5}, + {name: "Unaligned effAddr", base: 0xFF_12_00_01, offset: 0x3401, value: 0xABCD, effAddr: 0xFF_12_34_00, rtReg: 5}, + {name: "Unaligned effAddr, sign extended w overflow", base: 0xFF_12_00_01, offset: 0x8401, value: 0xABCD, effAddr: 0xFF_11_84_00, rtReg: 5}, + {name: "Return register set to 0", base: 0x00_00_00_01, offset: 0x0133, value: 0xABCD, effAddr: 0x00_00_01_34, rtReg: 0}, + } + v := GetSingleThreadedTestCase(t) + for i, c := range cases { + t.Run(c.name, func(t *testing.T) { + rtReg := c.rtReg + baseReg := 6 + pc := uint32(0x44) + insn := uint32((0b11_0000 << 26) | (baseReg & 0x1F << 21) | (rtReg & 0x1F << 16) | (0xFFFF & c.offset)) + goVm := v.VMFactory(nil, os.Stdout, os.Stderr, testutil.CreateLogger(), testutil.WithRandomization(int64(i)), testutil.WithPC(pc), testutil.WithNextPC(pc+4)) + state := goVm.GetState() + state.GetMemory().SetMemory(pc, insn) + state.GetMemory().SetMemory(c.effAddr, c.value) + state.GetRegistersRef()[baseReg] = c.base + step := state.GetStep() + + // Setup expectations + expected := testutil.NewExpectedState(state) + expected.Step += 1 + expected.PC = pc + 4 + expected.NextPC = pc + 8 + if rtReg != 0 { + expected.Registers[rtReg] = c.value + } + + stepWitness, err := goVm.Step(true) + require.NoError(t, err) + + // Check expectations + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, tracer) + }) + } +} + +func TestEVM_SC(t *testing.T) { + var tracer *tracing.Hooks + + cases := []struct { + name string + base uint32 + offset int + value uint32 + effAddr uint32 + rtReg int + }{ + {name: "Aligned effAddr", base: 0x00_00_00_01, offset: 0x0133, value: 0xABCD, effAddr: 0x00_00_01_34, rtReg: 5}, + {name: "Aligned effAddr, signed extended", base: 0x00_00_00_01, offset: 0xFF33, value: 0xABCD, effAddr: 0xFF_FF_FF_34, rtReg: 5}, + {name: "Unaligned effAddr", base: 0xFF_12_00_01, offset: 0x3401, value: 0xABCD, effAddr: 0xFF_12_34_00, rtReg: 5}, + {name: "Unaligned effAddr, sign extended w overflow", base: 0xFF_12_00_01, offset: 0x8401, value: 0xABCD, effAddr: 0xFF_11_84_00, rtReg: 5}, + {name: "Return register set to 0", base: 0xFF_12_00_01, offset: 0x8401, value: 0xABCD, effAddr: 0xFF_11_84_00, rtReg: 0}, + } + v := GetSingleThreadedTestCase(t) + for i, c := range cases { + t.Run(c.name, func(t *testing.T) { + rtReg := c.rtReg + baseReg := 6 + pc := uint32(0x44) + insn := uint32((0b11_1000 << 26) | (baseReg & 0x1F << 21) | (rtReg & 0x1F << 16) | (0xFFFF & c.offset)) + goVm := v.VMFactory(nil, os.Stdout, os.Stderr, testutil.CreateLogger(), testutil.WithRandomization(int64(i)), testutil.WithPC(pc), testutil.WithNextPC(pc+4)) + state := goVm.GetState() + state.GetMemory().SetMemory(pc, insn) + state.GetRegistersRef()[baseReg] = c.base + state.GetRegistersRef()[rtReg] = c.value + step := state.GetStep() + + // Setup expectations + expected := testutil.NewExpectedState(state) + expected.Step += 1 + expected.PC = pc + 4 + expected.NextPC = pc + 8 + expectedMemory := memory.NewMemory() + expectedMemory.SetMemory(pc, insn) + expectedMemory.SetMemory(c.effAddr, c.value) + expected.MemoryRoot = expectedMemory.MerkleRoot() + if rtReg != 0 { + expected.Registers[rtReg] = 1 // 1 for success + } + + stepWitness, err := goVm.Step(true) + require.NoError(t, err) + + // Check expectations + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, tracer) + }) + } +} + +func TestEVM_SysRead_Preimage(t *testing.T) { + var tracer *tracing.Hooks + + preimageValue := make([]byte, 0, 8) + preimageValue = binary.BigEndian.AppendUint32(preimageValue, 0x12_34_56_78) + preimageValue = binary.BigEndian.AppendUint32(preimageValue, 0x98_76_54_32) + + v := GetSingleThreadedTestCase(t) + + cases := []struct { + name string + addr uint32 + count uint32 + writeLen uint32 + preimageOffset uint32 + prestateMem uint32 + postateMem uint32 + shouldPanic bool + }{ + {name: "Aligned addr, write 1 byte", addr: 0x00_00_FF_00, count: 1, writeLen: 1, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x12_FF_FF_FF}, + {name: "Aligned addr, write 2 byte", addr: 0x00_00_FF_00, count: 2, writeLen: 2, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x12_34_FF_FF}, + {name: "Aligned addr, write 3 byte", addr: 0x00_00_FF_00, count: 3, writeLen: 3, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x12_34_56_FF}, + {name: "Aligned addr, write 4 byte", addr: 0x00_00_FF_00, count: 4, writeLen: 4, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x12_34_56_78}, + {name: "1-byte misaligned addr, write 1 byte", addr: 0x00_00_FF_01, count: 1, writeLen: 1, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_12_FF_FF}, + {name: "1-byte misaligned addr, write 2 byte", addr: 0x00_00_FF_01, count: 2, writeLen: 2, preimageOffset: 9, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_34_56_FF}, + {name: "1-byte misaligned addr, write 3 byte", addr: 0x00_00_FF_01, count: 3, writeLen: 3, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_12_34_56}, + {name: "2-byte misaligned addr, write 1 byte", addr: 0x00_00_FF_02, count: 1, writeLen: 1, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_12_FF}, + {name: "2-byte misaligned addr, write 2 byte", addr: 0x00_00_FF_02, count: 2, writeLen: 2, preimageOffset: 12, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_98_76}, + {name: "3-byte misaligned addr, write 1 byte", addr: 0x00_00_FF_03, count: 1, writeLen: 1, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_FF_12}, + {name: "Count of 0", addr: 0x00_00_FF_03, count: 0, writeLen: 0, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_FF_FF}, + {name: "Count greater than 4", addr: 0x00_00_FF_00, count: 15, writeLen: 4, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x12_34_56_78}, + {name: "Count greater than 4, unaligned", addr: 0x00_00_FF_01, count: 15, writeLen: 3, preimageOffset: 8, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_12_34_56}, + {name: "Offset at last byte", addr: 0x00_00_FF_00, count: 4, writeLen: 1, preimageOffset: 15, prestateMem: 0xFF_FF_FF_FF, postateMem: 0x32_FF_FF_FF}, + {name: "Offset just out of bounds", addr: 0x00_00_FF_00, count: 4, writeLen: 0, preimageOffset: 16, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_FF_FF, shouldPanic: true}, + {name: "Offset out of bounds", addr: 0x00_00_FF_00, count: 4, writeLen: 0, preimageOffset: 17, prestateMem: 0xFF_FF_FF_FF, postateMem: 0xFF_FF_FF_FF, shouldPanic: true}, + } + for i, c := range cases { + t.Run(c.name, func(t *testing.T) { + effAddr := 0xFFffFFfc & c.addr + preimageKey := preimage.Keccak256Key(crypto.Keccak256Hash(preimageValue)).PreimageKey() + oracle := testutil.StaticOracle(t, preimageValue) + goVm := v.VMFactory(oracle, os.Stdout, os.Stderr, testutil.CreateLogger(), testutil.WithRandomization(int64(i)), testutil.WithPreimageKey(preimageKey), testutil.WithPreimageOffset(c.preimageOffset)) + state := goVm.GetState() + step := state.GetStep() + + // Set up state + state.GetRegistersRef()[2] = exec.SysRead + state.GetRegistersRef()[4] = exec.FdPreimageRead + state.GetRegistersRef()[5] = c.addr + state.GetRegistersRef()[6] = c.count + state.GetMemory().SetMemory(state.GetPC(), syscallInsn) + state.GetMemory().SetMemory(effAddr, c.prestateMem) + + // Setup expectations + expected := testutil.NewExpectedState(state) + expected.ExpectStep() + expected.Registers[2] = c.writeLen + expected.Registers[7] = 0 // no error + expected.PreimageOffset += c.writeLen + expected.ExpectMemoryWrite(effAddr, c.postateMem) + + if c.shouldPanic { + require.Panics(t, func() { _, _ = goVm.Step(true) }) + testutil.AssertPreimageOracleReverts(t, preimageKey, preimageValue, c.preimageOffset, v.Contracts, tracer) + } else { + stepWitness, err := goVm.Step(true) + require.NoError(t, err) + + // Check expectations + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, tracer) + } + }) + } +} diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 8e5def6450d1..fc7c5aa8be86 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -140,12 +140,12 @@ "sourceCodeHash": "0x3f7bd622a788b8d00fe1631b14b761488eedccf56879f7ea2d610dd5ce81efbe" }, "src/cannon/MIPS.sol": { - "initCodeHash": "0x6add59adb849ec02e13b33df7efd439ca80f6a8ceefdf69ebcb0963c0167da23", - "sourceCodeHash": "0xee1aef5a502f9491b7b83dab46ea2f0fc286f87ace31edcc1367c840d462bdfe" + "initCodeHash": "0x4043f262804931bbbbecff64f87f2d0bdc4554b4d0a8b22df8fff940e8d239bf", + "sourceCodeHash": "0xba4674e1846afbbc708877332a38dfabd4b8d1e48ce07d8ebf0a45c9f27f16b0" }, "src/cannon/MIPS2.sol": { - "initCodeHash": "0xeab5f44d7fa7af1072f500c754bb55aa92409a79b2765a66efed47461c0c4049", - "sourceCodeHash": "0xcf180ff2cab8d0a34f3bb19d7145f5bf7f67dd379722ece765d09b38dcfed2f6" + "initCodeHash": "0xdaed5d70cc84a53f224c28f24f8eef26d5d53dfba9fdc4f1b28c3b231b974e53", + "sourceCodeHash": "0x4026eb7ae7b303ec4c3c2880e14e260dbcfc0b4290459bcd22994cfed8655f80" }, "src/cannon/PreimageOracle.sol": { "initCodeHash": "0x801e52f9c8439fcf7089575fa93272dfb874641dbfc7d82f36d979c987271c0b", diff --git a/packages/contracts-bedrock/snapshots/abi/MIPS.json b/packages/contracts-bedrock/snapshots/abi/MIPS.json index 7741a95c6260..afdc8c355ddc 100644 --- a/packages/contracts-bedrock/snapshots/abi/MIPS.json +++ b/packages/contracts-bedrock/snapshots/abi/MIPS.json @@ -69,5 +69,10 @@ "inputs": [], "name": "InvalidMemoryProof", "type": "error" + }, + { + "inputs": [], + "name": "InvalidRMWInstruction", + "type": "error" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/MIPS2.json b/packages/contracts-bedrock/snapshots/abi/MIPS2.json index eacce2991e21..2294e23e754e 100644 --- a/packages/contracts-bedrock/snapshots/abi/MIPS2.json +++ b/packages/contracts-bedrock/snapshots/abi/MIPS2.json @@ -75,6 +75,11 @@ "name": "InvalidMemoryProof", "type": "error" }, + { + "inputs": [], + "name": "InvalidRMWInstruction", + "type": "error" + }, { "inputs": [], "name": "InvalidSecondMemoryProof", diff --git a/packages/contracts-bedrock/src/cannon/MIPS.sol b/packages/contracts-bedrock/src/cannon/MIPS.sol index 8c2f1465756c..f1d216c8e6de 100644 --- a/packages/contracts-bedrock/src/cannon/MIPS.sol +++ b/packages/contracts-bedrock/src/cannon/MIPS.sol @@ -8,6 +8,7 @@ import { MIPSInstructions as ins } from "src/cannon/libraries/MIPSInstructions.s import { MIPSSyscalls as sys } from "src/cannon/libraries/MIPSSyscalls.sol"; import { MIPSState as st } from "src/cannon/libraries/MIPSState.sol"; import { MIPSMemory } from "src/cannon/libraries/MIPSMemory.sol"; +import { InvalidRMWInstruction } from "src/cannon/libraries/CannonErrors.sol"; /// @title MIPS /// @notice The MIPS contract emulates a single MIPS instruction. @@ -44,8 +45,8 @@ contract MIPS is ISemver { } /// @notice The semantic version of the MIPS contract. - /// @custom:semver 1.1.1-beta.3 - string public constant version = "1.1.1-beta.3"; + /// @custom:semver 1.1.1-beta.4 + string public constant version = "1.1.1-beta.4"; /// @notice The preimage oracle contract. IPreimageOracle internal immutable ORACLE; @@ -178,7 +179,7 @@ contract MIPS is ISemver { proofOffset: MIPSMemory.memoryProofOffset(STEP_PROOF_OFFSET, 1), memRoot: state.memRoot }); - (v0, v1, state.preimageOffset, state.memRoot) = sys.handleSysRead(args); + (v0, v1, state.preimageOffset, state.memRoot,,) = sys.handleSysRead(args); } else if (syscall_no == sys.SYS_WRITE) { (v0, v1, state.preimageKey, state.preimageOffset) = sys.handleSysWrite({ _a0: a0, @@ -291,23 +292,59 @@ contract MIPS is ISemver { return handleSyscall(_localContext); } + // Handle RMW (read-modify-write) ops + if (opcode == ins.OP_LOAD_LINKED || opcode == ins.OP_STORE_CONDITIONAL) { + return handleRMWOps(state, insn, opcode); + } + // Exec the rest of the step logic st.CpuScalars memory cpu = getCpuScalars(state); - (state.memRoot) = ins.execMipsCoreStepLogic({ - _cpu: cpu, - _registers: state.registers, - _memRoot: state.memRoot, - _memProofOffset: MIPSMemory.memoryProofOffset(STEP_PROOF_OFFSET, 1), - _insn: insn, - _opcode: opcode, - _fun: fun + ins.CoreStepLogicParams memory coreStepArgs = ins.CoreStepLogicParams({ + cpu: cpu, + registers: state.registers, + memRoot: state.memRoot, + memProofOffset: MIPSMemory.memoryProofOffset(STEP_PROOF_OFFSET, 1), + insn: insn, + opcode: opcode, + fun: fun }); + (state.memRoot,,) = ins.execMipsCoreStepLogic(coreStepArgs); setStateCpuScalars(state, cpu); return outputState(); } } + function handleRMWOps(State memory _state, uint32 _insn, uint32 _opcode) internal returns (bytes32) { + unchecked { + uint32 baseReg = (_insn >> 21) & 0x1F; + uint32 base = _state.registers[baseReg]; + uint32 rtReg = (_insn >> 16) & 0x1F; + uint32 offset = ins.signExtendImmediate(_insn); + + uint32 effAddr = (base + offset) & 0xFFFFFFFC; + uint256 memProofOffset = MIPSMemory.memoryProofOffset(STEP_PROOF_OFFSET, 1); + uint32 mem = MIPSMemory.readMem(_state.memRoot, effAddr, memProofOffset); + + uint32 retVal; + if (_opcode == ins.OP_LOAD_LINKED) { + retVal = mem; + } else if (_opcode == ins.OP_STORE_CONDITIONAL) { + uint32 val = _state.registers[rtReg]; + _state.memRoot = MIPSMemory.writeMem(effAddr, memProofOffset, val); + retVal = 1; // 1 for success + } else { + revert InvalidRMWInstruction(); + } + + st.CpuScalars memory cpu = getCpuScalars(_state); + ins.handleRd(cpu, _state.registers, rtReg, retVal, true); + setStateCpuScalars(_state, cpu); + + return outputState(); + } + } + function getCpuScalars(State memory _state) internal pure returns (st.CpuScalars memory) { return st.CpuScalars({ pc: _state.pc, nextPC: _state.nextPC, lo: _state.lo, hi: _state.hi }); } diff --git a/packages/contracts-bedrock/src/cannon/MIPS2.sol b/packages/contracts-bedrock/src/cannon/MIPS2.sol index 08c7856f7aec..b9da8fa8cc37 100644 --- a/packages/contracts-bedrock/src/cannon/MIPS2.sol +++ b/packages/contracts-bedrock/src/cannon/MIPS2.sol @@ -8,7 +8,9 @@ import { MIPSSyscalls as sys } from "src/cannon/libraries/MIPSSyscalls.sol"; import { MIPSState as st } from "src/cannon/libraries/MIPSState.sol"; import { MIPSInstructions as ins } from "src/cannon/libraries/MIPSInstructions.sol"; import { VMStatuses } from "src/dispute/lib/Types.sol"; -import { InvalidMemoryProof, InvalidSecondMemoryProof } from "src/cannon/libraries/CannonErrors.sol"; +import { + InvalidMemoryProof, InvalidRMWInstruction, InvalidSecondMemoryProof +} from "src/cannon/libraries/CannonErrors.sol"; /// @title MIPS2 /// @notice The MIPS2 contract emulates a single MIPS instruction. @@ -33,13 +35,16 @@ contract MIPS2 is ISemver { } /// @notice Stores the VM state. - /// Total state size: 32 + 32 + 4 + 4 + 1 + 1 + 8 + 8 + 4 + 1 + 32 + 32 + 4 = 163 bytes + /// Total state size: 32 + 32 + 4 + 4 + 1 + 4 + 4 + 1 + 1 + 8 + 8 + 4 + 1 + 32 + 32 + 4 = 172 bytes /// If nextPC != pc + 4, then the VM is executing a branch/jump delay slot. struct State { bytes32 memRoot; bytes32 preimageKey; uint32 preimageOffset; uint32 heap; + bool llReservationActive; + uint32 llAddress; + uint32 llOwnerThread; uint8 exitCode; bool exited; uint64 step; @@ -52,8 +57,8 @@ contract MIPS2 is ISemver { } /// @notice The semantic version of the MIPS2 contract. - /// @custom:semver 1.0.0-beta.8 - string public constant version = "1.0.0-beta.8"; + /// @custom:semver 1.0.0-beta.9 + string public constant version = "1.0.0-beta.9"; /// @notice The preimage oracle contract. IPreimageOracle internal immutable ORACLE; @@ -71,7 +76,7 @@ contract MIPS2 is ISemver { uint256 internal constant STATE_MEM_OFFSET = 0x80; // ThreadState memory offset allocated during step - uint256 internal constant TC_MEM_OFFSET = 0x220; + uint256 internal constant TC_MEM_OFFSET = 0x280; /// @param _oracle The address of the preimage oracle contract. constructor(IPreimageOracle _oracle) { @@ -108,8 +113,8 @@ contract MIPS2 is ISemver { // expected thread mem offset check revert(0, 0) } - if iszero(eq(mload(0x40), shl(5, 60))) { - // 4 + 13 state slots + 43 thread slots = 60 expected memory check + if iszero(eq(mload(0x40), shl(5, 63))) { + // 4 + 16 state slots + 43 thread slots = 63 expected memory check revert(0, 0) } if iszero(eq(_stateData.offset, 132)) { @@ -136,6 +141,9 @@ contract MIPS2 is ISemver { c, m := putField(c, m, 32) // preimageKey c, m := putField(c, m, 4) // preimageOffset c, m := putField(c, m, 4) // heap + c, m := putField(c, m, 1) // llReservationActive + c, m := putField(c, m, 4) // llAddress + c, m := putField(c, m, 4) // llOwnerThread c, m := putField(c, m, 1) // exitCode c, m := putField(c, m, 1) // exited exited := mload(sub(m, 32)) @@ -228,19 +236,95 @@ contract MIPS2 is ISemver { return handleSyscall(_localContext); } + // Handle RMW (read-modify-write) ops + if (opcode == ins.OP_LOAD_LINKED || opcode == ins.OP_STORE_CONDITIONAL) { + return handleRMWOps(state, thread, insn, opcode); + } + // Exec the rest of the step logic st.CpuScalars memory cpu = getCpuScalars(thread); - (state.memRoot) = ins.execMipsCoreStepLogic({ - _cpu: cpu, - _registers: thread.registers, - _memRoot: state.memRoot, - _memProofOffset: MIPSMemory.memoryProofOffset(MEM_PROOF_OFFSET, 1), - _insn: insn, - _opcode: opcode, - _fun: fun + ins.CoreStepLogicParams memory coreStepArgs = ins.CoreStepLogicParams({ + cpu: cpu, + registers: thread.registers, + memRoot: state.memRoot, + memProofOffset: MIPSMemory.memoryProofOffset(MEM_PROOF_OFFSET, 1), + insn: insn, + opcode: opcode, + fun: fun }); + bool memUpdated; + uint32 memAddr; + (state.memRoot, memUpdated, memAddr) = ins.execMipsCoreStepLogic(coreStepArgs); setStateCpuScalars(thread, cpu); updateCurrentThreadRoot(); + if (memUpdated) { + handleMemoryUpdate(state, memAddr); + } + + return outputState(); + } + } + + function handleMemoryUpdate(State memory _state, uint32 _memAddr) internal pure { + if (_memAddr == _state.llAddress) { + // Reserved address was modified, clear the reservation + clearLLMemoryReservation(_state); + } + } + + function clearLLMemoryReservation(State memory _state) internal pure { + _state.llReservationActive = false; + _state.llAddress = 0; + _state.llOwnerThread = 0; + } + + function handleRMWOps( + State memory _state, + ThreadState memory _thread, + uint32 _insn, + uint32 _opcode + ) + internal + returns (bytes32) + { + unchecked { + uint32 baseReg = (_insn >> 21) & 0x1F; + uint32 base = _thread.registers[baseReg]; + uint32 rtReg = (_insn >> 16) & 0x1F; + uint32 offset = ins.signExtendImmediate(_insn); + + uint32 effAddr = (base + offset) & 0xFFFFFFFC; + uint256 memProofOffset = MIPSMemory.memoryProofOffset(MEM_PROOF_OFFSET, 1); + uint32 mem = MIPSMemory.readMem(_state.memRoot, effAddr, memProofOffset); + + uint32 retVal = 0; + uint32 threadId = _thread.threadID; + if (_opcode == ins.OP_LOAD_LINKED) { + retVal = mem; + _state.llReservationActive = true; + _state.llAddress = effAddr; + _state.llOwnerThread = threadId; + } else if (_opcode == ins.OP_STORE_CONDITIONAL) { + // Check if our memory reservation is still intact + if (_state.llReservationActive && _state.llOwnerThread == threadId && _state.llAddress == effAddr) { + // Complete atomic update: set memory and return 1 for success + clearLLMemoryReservation(_state); + uint32 val = _thread.registers[rtReg]; + _state.memRoot = MIPSMemory.writeMem(effAddr, memProofOffset, val); + retVal = 1; + } else { + // Atomic update failed, return 0 for failure + retVal = 0; + } + } else { + revert InvalidRMWInstruction(); + } + + st.CpuScalars memory cpu = getCpuScalars(_thread); + ins.handleRd(cpu, _thread.registers, rtReg, retVal, true); + setStateCpuScalars(_thread, cpu); + updateCurrentThreadRoot(); + return outputState(); } } @@ -319,7 +403,8 @@ contract MIPS2 is ISemver { proofOffset: MIPSMemory.memoryProofOffset(MEM_PROOF_OFFSET, 1), memRoot: state.memRoot }); - (v0, v1, state.preimageOffset, state.memRoot) = sys.handleSysRead(args); + // Encapsulate execution to avoid stack-too-deep error + (v0, v1) = execSysRead(state, args); } else if (syscall_no == sys.SYS_WRITE) { (v0, v1, state.preimageKey, state.preimageOffset) = sys.handleSysWrite({ _a0: a0, @@ -412,6 +497,7 @@ contract MIPS2 is ISemver { // Recompute the new root after updating effAddr state.memRoot = MIPSMemory.writeMem(effAddr, MIPSMemory.memoryProofOffset(MEM_PROOF_OFFSET, 1), secs); + handleMemoryUpdate(state, effAddr); // Verify the second memory proof against the newly computed root if ( !MIPSMemory.isValidProof( @@ -422,6 +508,7 @@ contract MIPS2 is ISemver { } state.memRoot = MIPSMemory.writeMem(effAddr + 4, MIPSMemory.memoryProofOffset(MEM_PROOF_OFFSET, 2), nsecs); + handleMemoryUpdate(state, effAddr + 4); } else { v0 = sys.SYS_ERROR_SIGNAL; v1 = sys.EINVAL; @@ -502,6 +589,22 @@ contract MIPS2 is ISemver { } } + function execSysRead( + State memory _state, + sys.SysReadParams memory _args + ) + internal + view + returns (uint32 v0, uint32 v1) + { + bool memUpdated; + uint32 memAddr; + (v0, v1, _state.preimageOffset, _state.memRoot, memUpdated, memAddr) = sys.handleSysRead(_args); + if (memUpdated) { + handleMemoryUpdate(_state, memAddr); + } + } + /// @notice Computes the hash of the MIPS state. /// @return out_ The hashed MIPS state. function outputState() internal returns (bytes32 out_) { @@ -526,6 +629,9 @@ contract MIPS2 is ISemver { from, to := copyMem(from, to, 32) // preimageKey from, to := copyMem(from, to, 4) // preimageOffset from, to := copyMem(from, to, 4) // heap + from, to := copyMem(from, to, 1) // llReservationActive + from, to := copyMem(from, to, 4) // llAddress + from, to := copyMem(from, to, 4) // llOwnerThread let exitCode := mload(from) from, to := copyMem(from, to, 1) // exitCode exited := mload(from) diff --git a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS.sol b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS.sol index d96432c68096..8e42ccf6dfa0 100644 --- a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS.sol +++ b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS.sol @@ -8,6 +8,7 @@ import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol"; /// @notice Interface for the MIPS contract. interface IMIPS is ISemver { error InvalidMemoryProof(); + error InvalidRMWInstruction(); function oracle() external view returns (IPreimageOracle oracle_); function step(bytes memory _stateData, bytes memory _proof, bytes32 _localContext) external returns (bytes32); diff --git a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol index e60b1d876b60..39653f031e3f 100644 --- a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol +++ b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol @@ -10,6 +10,7 @@ interface IMIPS2 is ISemver { error InvalidExitedValue(); error InvalidMemoryProof(); error InvalidSecondMemoryProof(); + error InvalidRMWInstruction(); function oracle() external view returns (IPreimageOracle oracle_); function step(bytes memory _stateData, bytes memory _proof, bytes32 _localContext) external returns (bytes32); diff --git a/packages/contracts-bedrock/src/cannon/libraries/CannonErrors.sol b/packages/contracts-bedrock/src/cannon/libraries/CannonErrors.sol index d8ecdfe2af9a..3649852cec6f 100644 --- a/packages/contracts-bedrock/src/cannon/libraries/CannonErrors.sol +++ b/packages/contracts-bedrock/src/cannon/libraries/CannonErrors.sol @@ -60,3 +60,6 @@ error InvalidMemoryProof(); /// @notice Thrown when the second memory location is invalid error InvalidSecondMemoryProof(); + +/// @notice Thrown when an RMW instruction is expected, but a different instruction is provided. +error InvalidRMWInstruction(); diff --git a/packages/contracts-bedrock/src/cannon/libraries/MIPSInstructions.sol b/packages/contracts-bedrock/src/cannon/libraries/MIPSInstructions.sol index 0652bea0d0e1..a2402531c82d 100644 --- a/packages/contracts-bedrock/src/cannon/libraries/MIPSInstructions.sol +++ b/packages/contracts-bedrock/src/cannon/libraries/MIPSInstructions.sol @@ -5,6 +5,26 @@ import { MIPSMemory } from "src/cannon/libraries/MIPSMemory.sol"; import { MIPSState as st } from "src/cannon/libraries/MIPSState.sol"; library MIPSInstructions { + uint32 internal constant OP_LOAD_LINKED = 0x30; + uint32 internal constant OP_STORE_CONDITIONAL = 0x38; + + struct CoreStepLogicParams { + /// @param opcode The opcode value parsed from insn_. + st.CpuScalars cpu; + /// @param registers The CPU registers. + uint32[32] registers; + /// @param memRoot The current merkle root of the memory. + bytes32 memRoot; + /// @param memProofOffset The offset in calldata specify where the memory merkle proof is located. + uint256 memProofOffset; + /// @param insn The current 32-bit instruction at the pc. + uint32 insn; + /// @param cpu The CPU scalar fields. + uint32 opcode; + /// @param fun The function value parsed from insn_. + uint32 fun; + } + /// @param _pc The program counter. /// @param _memRoot The current memory root. /// @param _insnProofOffset The calldata offset of the memory proof for the current instruction. @@ -30,91 +50,80 @@ library MIPSInstructions { } /// @notice Execute core MIPS step logic. - /// @notice _cpu The CPU scalar fields. - /// @notice _registers The CPU registers. - /// @notice _memRoot The current merkle root of the memory. - /// @notice _memProofOffset The offset in calldata specify where the memory merkle proof is located. - /// @param _insn The current 32-bit instruction at the pc. - /// @param _opcode The opcode value parsed from insn_. - /// @param _fun The function value parsed from insn_. /// @return newMemRoot_ The updated merkle root of memory after any modifications, may be unchanged. - function execMipsCoreStepLogic( - st.CpuScalars memory _cpu, - uint32[32] memory _registers, - bytes32 _memRoot, - uint256 _memProofOffset, - uint32 _insn, - uint32 _opcode, - uint32 _fun - ) + /// @return memUpdated_ True if memory was modified. + /// @return memAddr_ Holds the memory address that was updated if memUpdated_ is true. + function execMipsCoreStepLogic(CoreStepLogicParams memory _args) internal pure - returns (bytes32 newMemRoot_) + returns (bytes32 newMemRoot_, bool memUpdated_, uint32 memAddr_) { unchecked { - newMemRoot_ = _memRoot; + newMemRoot_ = _args.memRoot; + memUpdated_ = false; + memAddr_ = 0; // j-type j/jal - if (_opcode == 2 || _opcode == 3) { + if (_args.opcode == 2 || _args.opcode == 3) { // Take top 4 bits of the next PC (its 256 MB region), and concatenate with the 26-bit offset - uint32 target = (_cpu.nextPC & 0xF0000000) | (_insn & 0x03FFFFFF) << 2; - handleJump(_cpu, _registers, _opcode == 2 ? 0 : 31, target); - return newMemRoot_; + uint32 target = (_args.cpu.nextPC & 0xF0000000) | (_args.insn & 0x03FFFFFF) << 2; + handleJump(_args.cpu, _args.registers, _args.opcode == 2 ? 0 : 31, target); + return (newMemRoot_, memUpdated_, memAddr_); } // register fetch uint32 rs = 0; // source register 1 value uint32 rt = 0; // source register 2 / temp value - uint32 rtReg = (_insn >> 16) & 0x1F; + uint32 rtReg = (_args.insn >> 16) & 0x1F; // R-type or I-type (stores rt) - rs = _registers[(_insn >> 21) & 0x1F]; + rs = _args.registers[(_args.insn >> 21) & 0x1F]; uint32 rdReg = rtReg; - if (_opcode == 0 || _opcode == 0x1c) { + if (_args.opcode == 0 || _args.opcode == 0x1c) { // R-type (stores rd) - rt = _registers[rtReg]; - rdReg = (_insn >> 11) & 0x1F; - } else if (_opcode < 0x20) { + rt = _args.registers[rtReg]; + rdReg = (_args.insn >> 11) & 0x1F; + } else if (_args.opcode < 0x20) { // rt is SignExtImm // don't sign extend for andi, ori, xori - if (_opcode == 0xC || _opcode == 0xD || _opcode == 0xe) { + if (_args.opcode == 0xC || _args.opcode == 0xD || _args.opcode == 0xe) { // ZeroExtImm - rt = _insn & 0xFFFF; + rt = _args.insn & 0xFFFF; } else { // SignExtImm - rt = signExtend(_insn & 0xFFFF, 16); + rt = signExtend(_args.insn & 0xFFFF, 16); } - } else if (_opcode >= 0x28 || _opcode == 0x22 || _opcode == 0x26) { + } else if (_args.opcode >= 0x28 || _args.opcode == 0x22 || _args.opcode == 0x26) { // store rt value with store - rt = _registers[rtReg]; + rt = _args.registers[rtReg]; // store actual rt with lwl and lwr rdReg = rtReg; } - if ((_opcode >= 4 && _opcode < 8) || _opcode == 1) { + if ((_args.opcode >= 4 && _args.opcode < 8) || _args.opcode == 1) { handleBranch({ - _cpu: _cpu, - _registers: _registers, - _opcode: _opcode, - _insn: _insn, + _cpu: _args.cpu, + _registers: _args.registers, + _opcode: _args.opcode, + _insn: _args.insn, _rtReg: rtReg, _rs: rs }); - return newMemRoot_; + return (newMemRoot_, memUpdated_, memAddr_); } uint32 storeAddr = 0xFF_FF_FF_FF; // memory fetch (all I-type) // we do the load for stores also uint32 mem = 0; - if (_opcode >= 0x20) { + if (_args.opcode >= 0x20) { // M[R[rs]+SignExtImm] - rs += signExtend(_insn & 0xFFFF, 16); + rs += signExtend(_args.insn & 0xFFFF, 16); uint32 addr = rs & 0xFFFFFFFC; - mem = MIPSMemory.readMem(_memRoot, addr, _memProofOffset); - if (_opcode >= 0x28 && _opcode != 0x30) { + mem = MIPSMemory.readMem(_args.memRoot, addr, _args.memProofOffset); + if (_args.opcode >= 0x28) { // store storeAddr = addr; // store opcodes don't write back to a register @@ -124,49 +133,58 @@ library MIPSInstructions { // ALU // Note: swr outputs more than 4 bytes without the mask 0xffFFffFF - uint32 val = executeMipsInstruction(_insn, _opcode, _fun, rs, rt, mem) & 0xffFFffFF; + uint32 val = executeMipsInstruction(_args.insn, _args.opcode, _args.fun, rs, rt, mem) & 0xffFFffFF; - if (_opcode == 0 && _fun >= 8 && _fun < 0x1c) { - if (_fun == 8 || _fun == 9) { + if (_args.opcode == 0 && _args.fun >= 8 && _args.fun < 0x1c) { + if (_args.fun == 8 || _args.fun == 9) { // jr/jalr - handleJump(_cpu, _registers, _fun == 8 ? 0 : rdReg, rs); - return newMemRoot_; + handleJump(_args.cpu, _args.registers, _args.fun == 8 ? 0 : rdReg, rs); + return (newMemRoot_, memUpdated_, memAddr_); } - if (_fun == 0xa) { + if (_args.fun == 0xa) { // movz - handleRd(_cpu, _registers, rdReg, rs, rt == 0); - return newMemRoot_; + handleRd(_args.cpu, _args.registers, rdReg, rs, rt == 0); + return (newMemRoot_, memUpdated_, memAddr_); } - if (_fun == 0xb) { + if (_args.fun == 0xb) { // movn - handleRd(_cpu, _registers, rdReg, rs, rt != 0); - return newMemRoot_; + handleRd(_args.cpu, _args.registers, rdReg, rs, rt != 0); + return (newMemRoot_, memUpdated_, memAddr_); } // lo and hi registers // can write back - if (_fun >= 0x10 && _fun < 0x1c) { - handleHiLo({ _cpu: _cpu, _registers: _registers, _fun: _fun, _rs: rs, _rt: rt, _storeReg: rdReg }); - - return newMemRoot_; + if (_args.fun >= 0x10 && _args.fun < 0x1c) { + handleHiLo({ + _cpu: _args.cpu, + _registers: _args.registers, + _fun: _args.fun, + _rs: rs, + _rt: rt, + _storeReg: rdReg + }); + return (newMemRoot_, memUpdated_, memAddr_); } } - // stupid sc, write a 1 to rt - if (_opcode == 0x38 && rtReg != 0) { - _registers[rtReg] = 1; - } - // write memory if (storeAddr != 0xFF_FF_FF_FF) { - newMemRoot_ = MIPSMemory.writeMem(storeAddr, _memProofOffset, val); + newMemRoot_ = MIPSMemory.writeMem(storeAddr, _args.memProofOffset, val); + memUpdated_ = true; + memAddr_ = storeAddr; } // write back the value to destination register - handleRd(_cpu, _registers, rdReg, val, true); + handleRd(_args.cpu, _args.registers, rdReg, val, true); - return newMemRoot_; + return (newMemRoot_, memUpdated_, memAddr_); + } + } + + function signExtendImmediate(uint32 _insn) internal pure returns (uint32 offset_) { + unchecked { + return signExtend(_insn & 0xFFFF, 16); } } @@ -417,14 +435,6 @@ library MIPSInstructions { uint32 val = _rt << (24 - (_rs & 3) * 8); uint32 mask = uint32(0xFFFFFFFF) << (24 - (_rs & 3) * 8); return (_mem & ~mask) | val; - } - // ll - else if (_opcode == 0x30) { - return _mem; - } - // sc - else if (_opcode == 0x38) { - return _rt; } else { revert("invalid instruction"); } diff --git a/packages/contracts-bedrock/src/cannon/libraries/MIPSSyscalls.sol b/packages/contracts-bedrock/src/cannon/libraries/MIPSSyscalls.sol index cf2d34a56a66..a835b6feef58 100644 --- a/packages/contracts-bedrock/src/cannon/libraries/MIPSSyscalls.sol +++ b/packages/contracts-bedrock/src/cannon/libraries/MIPSSyscalls.sol @@ -202,13 +202,22 @@ library MIPSSyscalls { function handleSysRead(SysReadParams memory _args) internal view - returns (uint32 v0_, uint32 v1_, uint32 newPreimageOffset_, bytes32 newMemRoot_) + returns ( + uint32 v0_, + uint32 v1_, + uint32 newPreimageOffset_, + bytes32 newMemRoot_, + bool memUpdated_, + uint32 memAddr_ + ) { unchecked { v0_ = uint32(0); v1_ = uint32(0); newMemRoot_ = _args.memRoot; newPreimageOffset_ = _args.preimageOffset; + memUpdated_ = false; + memAddr_ = 0; // args: _a0 = fd, _a1 = addr, _a2 = count // returns: v0_ = read, v1_ = err code @@ -217,9 +226,10 @@ library MIPSSyscalls { } // pre-image oracle read else if (_args.a0 == FD_PREIMAGE_READ) { + uint32 effAddr = _args.a1 & 0xFFffFFfc; // verify proof is correct, and get the existing memory. // mask the addr to align it to 4 bytes - uint32 mem = MIPSMemory.readMem(_args.memRoot, _args.a1 & 0xFFffFFfc, _args.proofOffset); + uint32 mem = MIPSMemory.readMem(_args.memRoot, effAddr, _args.proofOffset); // If the preimage key is a local key, localize it in the context of the caller. if (uint8(_args.preimageKey[0]) == 1) { _args.preimageKey = PreimageKeyLib.localize(_args.preimageKey, _args.localContext); @@ -246,7 +256,9 @@ library MIPSSyscalls { } // Write memory back - newMemRoot_ = MIPSMemory.writeMem(_args.a1 & 0xFFffFFfc, _args.proofOffset, mem); + newMemRoot_ = MIPSMemory.writeMem(effAddr, _args.proofOffset, mem); + memUpdated_ = true; + memAddr_ = effAddr; newPreimageOffset_ += uint32(datLen); v0_ = uint32(datLen); } @@ -260,7 +272,7 @@ library MIPSSyscalls { v1_ = EBADF; } - return (v0_, v1_, newPreimageOffset_, newMemRoot_); + return (v0_, v1_, newPreimageOffset_, newMemRoot_, memUpdated_, memAddr_); } } diff --git a/packages/contracts-bedrock/test/cannon/MIPS2.t.sol b/packages/contracts-bedrock/test/cannon/MIPS2.t.sol index 84ae9fb6b4f1..969486265ff6 100644 --- a/packages/contracts-bedrock/test/cannon/MIPS2.t.sol +++ b/packages/contracts-bedrock/test/cannon/MIPS2.t.sol @@ -141,9 +141,9 @@ contract MIPS2_Test is CommonTest { /// https://github.com/ethereum-optimism/optimism/blob/1f64dd6db5561f3bb76ed1d1ffdaff0cde9b7c4b/cannon/mipsevm/evm_test.go#L80-L80 function test_mips2_step_debug_succeeds() external { bytes memory input = - hex"e14ced3200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a3df82bcbdf27955e04d467b84d94d0b4662c88a70264d7ea31325bc8d826681ef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000affffffff00cbf05eda4a03d05cc6a14cff1cf2f955bfb253097c296ea96032da307da4f353ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb500000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007c6000000000000ffffffff000000000000000000000000000000280000002c00000000000000000000000000000000000000010000000000000000000000000000000000000000fffffffd00000003000000000000000000000000000000000000000000000000bffffff00000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a7ef00d0ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5ae020008ae11000403e0000800000000000000000000000000000000000000003c10bfff3610fff0341100013c08ffff3508fffd34090003010950212d420001ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3021ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a193440eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f839867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756afcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8923490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99cc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8beccda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d22733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd95a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3774df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d4e545be579dc7118fc02cd7b19b704e4710a81bce0cb48bb7e289e403e7c969a00000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3021ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a193440eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f839867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756afcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8923490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99cc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8beccda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d22733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd95a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3774df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6a3e23902bafb21ac312e717f7942f8fd8ae795f67c918083442c2ab253cc66e0000000000000000000000000000000000000000000000000000"; + hex"e14ced3200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000acab5a39c6f974b22302e96dcdef1815483eaf580639bb1ee7ac98267afac2bf1ac041d3ff12045b73c86e4ff95ff662a5eee82abdf44a2d0b75fb180daf48a79e3143a81fa7c3d90b000000000000000000000078fc2ffac2fd940100000000000080c8ffffffff006504aeffb6e08baf3f85da5476a9160fa8f9f188a722fdd29268b0cbaf596736ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb500000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007c6000000000000ffffffff000000000000000000000000f1f85ff4f1f85ff8506d442dbb3938f83eb60825a7ecbff2000010185e1a31f600050f0000000064a7c3d90be5acea102ad7bda149e0bfd0e7111c77d98b335645e665389becadf140ef999cc64fbd7f04799e85c97dadc5cca510bd5b3d97166d1aec28829f3dd43d8cf1f9358e4103b16d09d466e2c7c048ea3ba1aef3141e700270581aa0b75b50e34fc926bb2d83ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb500000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3021ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a193440eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f839867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756afcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8923490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99cc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8beccda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d22733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd95a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3774df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618db8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; (bool success, bytes memory retVal) = address(mips).call(input); - bytes memory expectedRetVal = hex"03fc952a0bd8aabc407669b857af995eab91ce55c404d8b32eaf8b941a48188c"; + bytes memory expectedRetVal = hex"0335fe4205f8443eefa7ac4541197874224df35e8536158c2fc2d5c8c2d2adb4"; assertTrue(success); assertEq(retVal.length, 32, "Expect a bytes32 hash of the post-state to be returned"); @@ -177,6 +177,9 @@ contract MIPS2_Test is CommonTest { preimageKey: bytes32(0), preimageOffset: 0, heap: 0, + llReservationActive: false, + llAddress: 0, + llOwnerThread: 0, exitCode: 0, exited: false, step: 1, @@ -211,7 +214,7 @@ contract MIPS2_Test is CommonTest { assembly { // Manipulate state data // Push offset by an additional 32 bytes (0x20) to account for length prefix - mstore8(add(add(stateData, 0x20), 73), exited) + mstore8(add(add(stateData, 0x20), 82), exited) } // Call the step function and expect a revert. @@ -1992,36 +1995,50 @@ contract MIPS2_Test is CommonTest { } function test_ll_succeeds() public { - uint32 t1 = 0x100; - uint32 val = 0x12_23_45_67; - uint32 insn = encodeitype(0x30, 0x9, 0x8, 0x4); // ll $t0, 4($t1) + uint32 base = 0x100; + uint32 memVal = 0x12_23_45_67; + uint16 offset = 0x4; + uint32 effAddr = base + offset; + uint32 insn = encodeitype(0x30, 0x9, 0x8, offset); // ll baseReg, rtReg, offset + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = - constructMIPSState(0, insn, t1 + 4, val); - thread.registers[8] = 0; // t0 - thread.registers[9] = t1; + constructMIPSState(0, insn, effAddr, memVal); + thread.registers[8] = 0; // rtReg + thread.registers[9] = base; bytes memory threadWitness = abi.encodePacked(encodeThread(thread), EMPTY_THREAD_ROOT); updateThreadStacks(state, thread); - thread.registers[8] = val; // t0 - MIPS2.State memory expect = arithmeticPostState(state, thread, 8, /* t0 */ thread.registers[8]); + MIPS2.State memory expect = arithmeticPostState(state, thread, 8, memVal); + expect.llReservationActive = true; + expect.llAddress = effAddr; + expect.llOwnerThread = thread.threadID; bytes32 postState = mips.step(encodeState(state), bytes.concat(threadWitness, memProof), 0); assertEq(postState, outputState(expect), "unexpected post state"); } function test_sc_succeeds() public { - uint32 t1 = 0x100; - uint32 insn = encodeitype(0x38, 0x9, 0x8, 0x4); // sc $t0, 4($t1) + uint32 base = 0x100; + uint16 offset = 0x4; + uint32 effAddr = base + offset; + uint32 writeMemVal = 0xaa_bb_cc_dd; + uint32 insn = encodeitype(0x38, 0x9, 0x8, offset); // ll baseReg, rtReg, offset + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = - constructMIPSState(0, insn, t1 + 4, 0); - thread.registers[8] = 0xaa_bb_cc_dd; // t0 - thread.registers[9] = t1; + constructMIPSState(0, insn, effAddr, 0); + state.llReservationActive = true; + state.llAddress = effAddr; + state.llOwnerThread = thread.threadID; + thread.registers[8] = writeMemVal; + thread.registers[9] = base; bytes memory threadWitness = abi.encodePacked(encodeThread(thread), EMPTY_THREAD_ROOT); updateThreadStacks(state, thread); - thread.registers[8] = 0x1; // t0 - MIPS2.State memory expect = arithmeticPostState(state, thread, 8, /* t0 */ thread.registers[8]); - (expect.memRoot,) = ffi.getCannonMemoryProof(0, insn, t1 + 4, 0xaa_bb_cc_dd); + MIPS2.State memory expect = arithmeticPostState(state, thread, 8, 0x1); + (expect.memRoot,) = ffi.getCannonMemoryProof(0, insn, effAddr, writeMemVal); + expect.llReservationActive = false; + expect.llAddress = 0; + expect.llOwnerThread = 0; bytes32 postState = mips.step(encodeState(state), bytes.concat(threadWitness, memProof), 0); assertEq(postState, outputState(expect), "unexpected post state"); @@ -2528,23 +2545,33 @@ contract MIPS2_Test is CommonTest { } function encodeState(MIPS2.State memory _state) internal pure returns (bytes memory) { + // Split up encoding to get around stack-too-deep error + return abi.encodePacked(encodeStateA(_state), encodeStateB(_state)); + } + + function encodeStateA(MIPS2.State memory _state) internal pure returns (bytes memory) { return abi.encodePacked( _state.memRoot, _state.preimageKey, _state.preimageOffset, _state.heap, + _state.llReservationActive, + _state.llAddress, + _state.llOwnerThread, _state.exitCode, _state.exited, _state.step, _state.stepsSinceLastContextSwitch, _state.wakeup, _state.traverseRight, - _state.leftThreadStack, - _state.rightThreadStack, - _state.nextThreadID + _state.leftThreadStack ); } + function encodeStateB(MIPS2.State memory _state) internal pure returns (bytes memory) { + return abi.encodePacked(_state.rightThreadStack, _state.nextThreadID); + } + function copyState(MIPS2.State memory _state) internal pure returns (MIPS2.State memory out_) { bytes memory data = abi.encode(_state); return abi.decode(data, (MIPS2.State)); From db10999f064f1bd56a16c68e6e8b11ea8212712a Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Mon, 16 Sep 2024 12:58:11 -0600 Subject: [PATCH 148/264] Add integration test for apply (#11910) * Add integration test for apply Adds an integration test for OP Deployer's `apply` method. This test uses Kurtosis to spin up an in-memory L1, deploy the contracts using OP Deployer, then asserts that there is code at all reported addresses. * Review updates --- .circleci/config.yml | 117 +++++++++------- go.mod | 24 +++- go.sum | 53 +++++++- op-chain-ops/deployer/apply.go | 27 +++- op-chain-ops/deployer/broadcaster/keyed.go | 18 ++- .../deployer/integration_test/apply_test.go | 127 ++++++++++++++++++ op-chain-ops/deployer/pipeline/env.go | 1 - op-service/testutils/kurtosisutil/kurtosis.go | 12 ++ op-service/testutils/kurtosisutil/runner.go | 64 +++++++++ 9 files changed, 374 insertions(+), 69 deletions(-) create mode 100644 op-chain-ops/deployer/integration_test/apply_test.go create mode 100644 op-service/testutils/kurtosisutil/kurtosis.go create mode 100644 op-service/testutils/kurtosisutil/runner.go diff --git a/.circleci/config.yml b/.circleci/config.yml index d96b1051514a..4c5e401ada57 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -849,6 +849,64 @@ jobs: paths: - "/root/.cache/golangci-lint" + go-test-kurtosis: + parameters: + module: + description: Go Module Name + type: string + uses_artifacts: + description: Uses contract artifacts + type: boolean + default: false + test_directory: + description: Test directory + type: string + default: "./..." + machine: + image: <> # only used to enable codecov. + resource_class: xlarge + steps: + - run: + name: Install components + command: | + go version + go install gotest.tools/gotestsum@v1.11.0 + - run: + name: Install Kurtosis + command: | + echo "deb [trusted=yes] https://apt.fury.io/kurtosis-tech/ /" | sudo tee /etc/apt/sources.list.d/kurtosis.list + sudo apt update + sudo apt install kurtosis-cli + kurtosis engine start + - checkout + - when: + condition: <> + steps: + - attach_workspace: { at: "." } + - run: + name: prep results dir + command: | + # Make sure the workspace is properly owned + sudo chown -R $USER:$USER . + mkdir -p /tmp/test-results + mkdir -p /tmp/testlogs + - run: + name: run tests + command: | + ENABLE_KURTOSIS=true gotestsum \ + --format=testname \ + --junitfile=/tmp/test-results/<>.xml \ + --jsonfile=/tmp/testlogs/log.json \ + -- -parallel=8 \ + -coverpkg=github.com/ethereum-optimism/optimism/... \ + -coverprofile=coverage.out <> + working_directory: <> + - store_test_results: + path: /tmp/test-results + - store_artifacts: + path: /tmp/testlogs + when: always + go-test: parameters: module: @@ -881,10 +939,6 @@ jobs: key: golang-build-cache-test-<>-{{ checksum "go.sum" }} paths: - "/root/.cache/go-build" - # TODO(CLI-148): Fix codecov - #- run: - #name: upload coverage - #command: codecov --verbose --clean --flags bedrock-go-tests - store_test_results: path: /tmp/test-results - store_artifacts: @@ -1011,53 +1065,6 @@ jobs: - notify-failures-on-develop: mentions: "<>" - go-lint-test-build: - parameters: - binary_name: - description: Binary name to build - type: string - working_directory: - description: Working directory - type: string - build: - description: Whether or not to build the binary - type: boolean - default: true - dependencies: - description: Regex matching dependent packages - type: string - default: this-package-does-not-exist - docker: - - image: <> - resource_class: medium - steps: - - checkout - - check-changed: - patterns: <>,<> - - run: - name: Lint - command: make lint - working_directory: <> - - run: - name: Test - command: | - mkdir -p /test-results - gotestsum --format=testname --junitfile /test-results/tests.xml --jsonfile /test-results/log.json -- -parallel=2 - working_directory: <> - - store_test_results: - path: /test-results - - store_artifacts: - path: /testlogs - when: always - - when: - condition: - equal: [ true, <> ] - steps: - - run: - name: Build - command: make <> - working_directory: <> - cannon-prestate: docker: - image: <> @@ -1664,7 +1671,12 @@ workflows: - go-test: name: op-chain-ops-tests module: op-chain-ops - requires: ["go-mod-download"] + - go-test-kurtosis: + name: op-chain-ops-integration + module: op-chain-ops + test_directory: ./deployer/integration_test + uses_artifacts: true + requires: ["contracts-bedrock-build"] - go-test: name: op-node-tests module: op-node @@ -1740,6 +1752,7 @@ workflows: - go-mod-download - op-batcher-tests - op-chain-ops-tests + - op-chain-ops-integration - op-node-tests - op-proposer-tests - op-challenger-tests diff --git a/go.mod b/go.mod index e1b4e14530a1..08dd890d7025 100644 --- a/go.mod +++ b/go.mod @@ -26,6 +26,7 @@ require ( github.com/ipfs/go-datastore v0.6.0 github.com/ipfs/go-ds-leveldb v0.5.0 github.com/klauspost/compress v1.17.9 + github.com/kurtosis-tech/kurtosis/api/golang v1.2.0 github.com/libp2p/go-libp2p v0.36.2 github.com/libp2p/go-libp2p-mplex v0.9.0 github.com/libp2p/go-libp2p-pubsub v0.12.0 @@ -53,8 +54,10 @@ require ( require ( github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e // indirect + github.com/Masterminds/semver/v3 v3.1.1 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/VictoriaMetrics/fastcache v1.12.2 // indirect + github.com/adrg/xdg v0.4.0 // indirect github.com/allegro/bigcache v1.2.1 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/benbjohnson/clock v1.3.5 // indirect @@ -85,6 +88,7 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0 // indirect github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 // indirect + github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/elastic/gosigar v0.14.3 // indirect github.com/ethereum/c-kzg-4844 v1.0.0 // indirect @@ -96,15 +100,18 @@ require ( github.com/francoispqt/gojay v1.2.13 // indirect github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect + github.com/ghodss/yaml v1.0.0 // indirect github.com/go-ini/ini v1.67.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect + github.com/go-yaml/yaml v2.1.0+incompatible // indirect github.com/goccy/go-json v0.10.3 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect github.com/google/uuid v1.6.0 // indirect @@ -136,6 +143,11 @@ require ( github.com/koron/go-ssdp v0.0.4 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect + github.com/kurtosis-tech/kurtosis-portal/api/golang v0.0.0-20230818182330-1a86869414d2 // indirect + github.com/kurtosis-tech/kurtosis/contexts-config-store v0.0.0-20230818184218-f4e3e773463b // indirect + github.com/kurtosis-tech/kurtosis/grpc-file-transfer/golang v0.0.0-20230803130419-099ee7a4e3dc // indirect + github.com/kurtosis-tech/kurtosis/path-compression v0.0.0-20240307154559-64d2929cd265 // indirect + github.com/kurtosis-tech/stacktrace v0.0.0-20211028211901-1c67a77b5409 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect @@ -148,6 +160,7 @@ require ( github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/mholt/archiver v3.1.1+incompatible // indirect github.com/miekg/dns v1.1.62 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect @@ -166,11 +179,13 @@ require ( github.com/multiformats/go-varint v0.0.7 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/naoina/go-stringutil v0.1.0 // indirect + github.com/nwaples/rardecode v1.1.3 // indirect github.com/onsi/ginkgo/v2 v2.20.0 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 // indirect + github.com/pierrec/lz4 v2.6.1+incompatible // indirect github.com/pion/datachannel v1.5.8 // indirect github.com/pion/dtls/v2 v2.2.12 // indirect github.com/pion/ice/v2 v2.3.34 // indirect @@ -199,11 +214,12 @@ require ( github.com/quic-go/webtransport-go v0.8.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rivo/uniseg v0.4.4 // indirect - github.com/rogpeppe/go-internal v1.10.0 // indirect + github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/rs/cors v1.11.0 // indirect github.com/rs/xid v1.6.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect + github.com/sirupsen/logrus v1.9.3 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/status-im/keycard-go v0.2.0 // indirect github.com/stretchr/objx v0.5.2 // indirect @@ -212,7 +228,9 @@ require ( github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect + github.com/ulikunitz/xz v0.5.11 // indirect github.com/wlynxg/anet v0.0.4 // indirect + github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.etcd.io/bbolt v1.3.5 // indirect @@ -227,6 +245,10 @@ require ( golang.org/x/sys v0.25.0 // indirect golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.24.0 // indirect + google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect + google.golang.org/grpc v1.57.1 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 22368b8d57d1..cdfe4f7b43f0 100644 --- a/go.sum +++ b/go.sum @@ -16,11 +16,15 @@ github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3 github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e h1:ZIWapoIRN1VqT8GR8jAwb1Ie9GyehWjVcGh32Y2MznE= github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= +github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= +github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -168,6 +172,9 @@ github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 h1:qwcF+vdFrvPSEUDSX5R github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= +github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY= +github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s= +github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= @@ -196,6 +203,8 @@ github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg= github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= @@ -207,6 +216,7 @@ github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= @@ -232,6 +242,8 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o= +github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -400,8 +412,10 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= @@ -420,6 +434,18 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kurtosis-tech/kurtosis-portal/api/golang v0.0.0-20230818182330-1a86869414d2 h1:izciXrFyFR+ihJ7nLTOkoIX5GzBPIp8gVKlw94gIc98= +github.com/kurtosis-tech/kurtosis-portal/api/golang v0.0.0-20230818182330-1a86869414d2/go.mod h1:bWSMQK3WHVTGHX9CjxPAb/LtzcmfOxID2wdzakSWQxo= +github.com/kurtosis-tech/kurtosis/api/golang v1.2.0 h1:NaNkkAvLiAVgRVTM9yeLCg4FIoIe/BVJKfU93KIFqdc= +github.com/kurtosis-tech/kurtosis/api/golang v1.2.0/go.mod h1:9T22P7Vv3j5g6sbm78DxHQ4s9C4Cj3s9JjFQ7DFyYpM= +github.com/kurtosis-tech/kurtosis/contexts-config-store v0.0.0-20230818184218-f4e3e773463b h1:hMoIM99QKcYQqsnK4AF7Lovi9ZD9ac6lZLZ5D/jx2x8= +github.com/kurtosis-tech/kurtosis/contexts-config-store v0.0.0-20230818184218-f4e3e773463b/go.mod h1:4pFdrRwDz5R+Fov2ZuTaPhAVgjA2jhGh1Izf832sX7A= +github.com/kurtosis-tech/kurtosis/grpc-file-transfer/golang v0.0.0-20230803130419-099ee7a4e3dc h1:7IlEpSehmWcNXOFpNP24Cu5HQI3af7GCBQw//m+LnvQ= +github.com/kurtosis-tech/kurtosis/grpc-file-transfer/golang v0.0.0-20230803130419-099ee7a4e3dc/go.mod h1:TOWMQgvAJH/NiWWERGXg/plT9lS7aFcXFxCa0M5sfHo= +github.com/kurtosis-tech/kurtosis/path-compression v0.0.0-20240307154559-64d2929cd265 h1:uSDftcGStwuAjHv8fV2TleNCKSWPvUKe7EaplFG3yBI= +github.com/kurtosis-tech/kurtosis/path-compression v0.0.0-20240307154559-64d2929cd265/go.mod h1:aDMrPeS7Gii8W6SDKSKyrBNgEQAUYidriyeKGf+Ml3I= +github.com/kurtosis-tech/stacktrace v0.0.0-20211028211901-1c67a77b5409 h1:YQTATifMUwZEtZYb0LVA7DK2pj8s71iY8rzweuUQ5+g= +github.com/kurtosis-tech/stacktrace v0.0.0-20211028211901-1c67a77b5409/go.mod h1:y5weVs5d9wXXHcDA1awRxkIhhHC1xxYJN8a7aXnE6S8= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= @@ -478,6 +504,8 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mholt/archiver v3.1.1+incompatible h1:1dCVxuqs0dJseYEhi5pl7MYPH9zDa1wBi7mF09cbNkU= +github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= @@ -544,6 +572,8 @@ github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 h1:shk/vn9oCoOTmwcou github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/nwaples/rardecode v1.1.3 h1:cWCaZwfM5H7nAD6PyEdcVnczzV8i/JtotnyW/dD9lEc= +github.com/nwaples/rardecode v1.1.3/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= @@ -581,6 +611,8 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2D github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= +github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= +github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pion/datachannel v1.5.8 h1:ph1P1NsGkazkjrvyMfhRBUAWMxugJjq2HfQifaOoSNo= @@ -686,8 +718,8 @@ github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po= github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= @@ -725,6 +757,8 @@ github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5k github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -764,6 +798,9 @@ github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9f github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= +github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8= github.com/urfave/cli/v2 v2.27.4/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ= @@ -775,6 +812,8 @@ github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMI github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/wlynxg/anet v0.0.4 h1:0de1OFQxnNqAu+x2FAKKCVIrnfGKQbs7FQz++tB0+Uw= github.com/wlynxg/anet v0.0.4/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -937,11 +976,13 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1023,10 +1064,18 @@ google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoA google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e h1:xIXmWJ303kJCuogpj0bHq+dcjcZHU+XFyc1I0Yl9cRg= +google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:0ggbjUrZYpy1q+ANUS30SEoGZ53cdfwtbuG7Ptgy108= +google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 h1:FmF5cCW94Ij59cfpoLiwTgodWmm60eEV0CjlsVg2fuw= +google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 h1:eSaPbMR4T7WfH9FvABk36NBMacoTUKdWCvV0dx+KfOg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5/go.mod h1:zBEcrKX2ZOcEkHWxBPAIvYUWOKKMIhYcmNiUIu2ji3I= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg= +google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/op-chain-ops/deployer/apply.go b/op-chain-ops/deployer/apply.go index a58a0654c3be..d39628cc6363 100644 --- a/op-chain-ops/deployer/apply.go +++ b/op-chain-ops/deployer/apply.go @@ -6,6 +6,8 @@ import ( "fmt" "strings" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/pipeline" opcrypto "github.com/ethereum-optimism/optimism/op-service/crypto" "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" @@ -92,7 +94,6 @@ func Apply(ctx context.Context, cfg ApplyConfig) error { env := &pipeline.Env{ Workdir: cfg.Workdir, - L1RPCUrl: cfg.L1RPCUrl, L1Client: l1Client, Logger: cfg.Logger, Signer: signer, @@ -113,6 +114,24 @@ func Apply(ctx context.Context, cfg ApplyConfig) error { return err } + if err := ApplyPipeline(ctx, env, intent, st); err != nil { + return err + } + + st.AppliedIntent = intent + if err := env.WriteState(st); err != nil { + return err + } + + return nil +} + +func ApplyPipeline( + ctx context.Context, + env *pipeline.Env, + intent *state.Intent, + st *state.State, +) error { pline := []struct { name string stage pipeline.Stage @@ -125,11 +144,5 @@ func Apply(ctx context.Context, cfg ApplyConfig) error { return fmt.Errorf("error in pipeline stage: %w", err) } } - - st.AppliedIntent = intent - if err := env.WriteState(st); err != nil { - return err - } - return nil } diff --git a/op-chain-ops/deployer/broadcaster/keyed.go b/op-chain-ops/deployer/broadcaster/keyed.go index 3df4cd9ed1eb..8c34cb1ab531 100644 --- a/op-chain-ops/deployer/broadcaster/keyed.go +++ b/op-chain-ops/deployer/broadcaster/keyed.go @@ -30,11 +30,12 @@ type KeyedBroadcaster struct { } type KeyedBroadcasterOpts struct { - Logger log.Logger - ChainID *big.Int - Client *ethclient.Client - Signer opcrypto.SignerFn - From common.Address + Logger log.Logger + ChainID *big.Int + Client *ethclient.Client + Signer opcrypto.SignerFn + From common.Address + TXManagerLogger log.Logger } func NewKeyedBroadcaster(cfg KeyedBroadcasterOpts) (*KeyedBroadcaster, error) { @@ -66,9 +67,14 @@ func NewKeyedBroadcaster(cfg KeyedBroadcasterOpts) (*KeyedBroadcaster, error) { mgrCfg.MinTipCap.Store(minTipCap) mgrCfg.MinTipCap.Store(minBaseFee) + txmLogger := log.NewLogger(log.DiscardHandler()) + if cfg.TXManagerLogger != nil { + txmLogger = cfg.TXManagerLogger + } + mgr, err := txmgr.NewSimpleTxManagerFromConfig( "transactor", - log.NewLogger(log.DiscardHandler()), + txmLogger, &metrics.NoopTxMetrics{}, mgrCfg, ) diff --git a/op-chain-ops/deployer/integration_test/apply_test.go b/op-chain-ops/deployer/integration_test/apply_test.go new file mode 100644 index 000000000000..6a592998b3e3 --- /dev/null +++ b/op-chain-ops/deployer/integration_test/apply_test.go @@ -0,0 +1,127 @@ +package integration_test + +import ( + "context" + "fmt" + "log/slog" + "math/big" + "net/url" + "path" + "runtime" + "testing" + + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer" + + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/pipeline" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" + "github.com/ethereum-optimism/optimism/op-chain-ops/devkeys" + opcrypto "github.com/ethereum-optimism/optimism/op-service/crypto" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/testutils/kurtosisutil" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/stretchr/testify/require" +) + +const TestParams = ` +participants: + - el_type: geth + cl_type: lighthouse +network_params: + prefunded_accounts: '{ "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266": { "balance": "1000000ETH" } }' + network_id: "77799777" + seconds_per_slot: 3 +` + +type deployerKey struct{} + +func (d *deployerKey) HDPath() string { + return "m/44'/60'/0'/0/0" +} + +func (d *deployerKey) String() string { + return "deployer-key" +} + +func TestEndToEndApply(t *testing.T) { + kurtosisutil.Test(t) + + lgr := testlog.Logger(t, slog.LevelInfo) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + _, testFilename, _, ok := runtime.Caller(0) + require.Truef(t, ok, "failed to get test filename") + monorepoDir := path.Join(path.Dir(testFilename), "..", "..", "..") + artifactsDir := path.Join(monorepoDir, "packages", "contracts-bedrock", "forge-artifacts") + + enclaveCtx := kurtosisutil.StartEnclave(t, ctx, lgr, "github.com/ethpandaops/ethereum-package", TestParams) + + service, err := enclaveCtx.GetServiceContext("el-1-geth-lighthouse") + require.NoError(t, err) + + ip := service.GetMaybePublicIPAddress() + ports := service.GetPublicPorts() + rpcURL := fmt.Sprintf("http://%s:%d", ip, ports["rpc"].GetNumber()) + l1Client, err := ethclient.Dial(rpcURL) + require.NoError(t, err) + + artifactsURL, err := url.Parse(fmt.Sprintf("file://%s", artifactsDir)) + require.NoError(t, err) + + depKey := new(deployerKey) + l1ChainID := big.NewInt(77799777) + dk, err := devkeys.NewMnemonicDevKeys(devkeys.TestMnemonic) + require.NoError(t, err) + pk, err := dk.Secret(depKey) + require.NoError(t, err) + signer := opcrypto.SignerFnFromBind(opcrypto.PrivateKeySignerFn(pk, l1ChainID)) + + addrFor := func(key devkeys.Key) common.Address { + addr, err := dk.Address(key) + require.NoError(t, err) + return addr + } + env := &pipeline.Env{ + Workdir: t.TempDir(), + L1Client: l1Client, + Signer: signer, + Deployer: addrFor(depKey), + Logger: lgr, + } + intent := &state.Intent{ + L1ChainID: l1ChainID.Uint64(), + SuperchainRoles: state.SuperchainRoles{ + ProxyAdminOwner: addrFor(devkeys.L1ProxyAdminOwnerRole.Key(l1ChainID)), + ProtocolVersionsOwner: addrFor(devkeys.SuperchainDeployerKey.Key(l1ChainID)), + Guardian: addrFor(devkeys.SuperchainConfigGuardianKey.Key(l1ChainID)), + }, + UseFaultProofs: true, + FundDevAccounts: true, + ContractArtifactsURL: (*state.ArtifactsURL)(artifactsURL), + } + st := &state.State{ + Version: 1, + } + + require.NoError(t, deployer.ApplyPipeline( + ctx, + env, + intent, + st, + )) + + addrs := []common.Address{ + st.SuperchainDeployment.ProxyAdminAddress, + st.SuperchainDeployment.SuperchainConfigProxyAddress, + st.SuperchainDeployment.SuperchainConfigImplAddress, + st.SuperchainDeployment.ProtocolVersionsProxyAddress, + st.SuperchainDeployment.ProtocolVersionsImplAddress, + } + for _, addr := range addrs { + code, err := l1Client.CodeAt(ctx, addr, nil) + require.NoError(t, err) + require.NotEmpty(t, code) + } +} diff --git a/op-chain-ops/deployer/pipeline/env.go b/op-chain-ops/deployer/pipeline/env.go index d77beacac596..9ee28e3843f6 100644 --- a/op-chain-ops/deployer/pipeline/env.go +++ b/op-chain-ops/deployer/pipeline/env.go @@ -16,7 +16,6 @@ import ( type Env struct { Workdir string L1Client *ethclient.Client - L1RPCUrl string Signer opcrypto.SignerFn Deployer common.Address Logger log.Logger diff --git a/op-service/testutils/kurtosisutil/kurtosis.go b/op-service/testutils/kurtosisutil/kurtosis.go new file mode 100644 index 000000000000..8be6c9b3f2c7 --- /dev/null +++ b/op-service/testutils/kurtosisutil/kurtosis.go @@ -0,0 +1,12 @@ +package kurtosisutil + +import ( + "os" + "testing" +) + +func Test(t *testing.T) { + if os.Getenv("ENABLE_KURTOSIS") == "" { + t.Skip("skipping Kurtosis test") + } +} diff --git a/op-service/testutils/kurtosisutil/runner.go b/op-service/testutils/kurtosisutil/runner.go new file mode 100644 index 000000000000..6440cedef681 --- /dev/null +++ b/op-service/testutils/kurtosisutil/runner.go @@ -0,0 +1,64 @@ +package kurtosisutil + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/ethereum/go-ethereum/log" + "github.com/kurtosis-tech/kurtosis/api/golang/core/lib/enclaves" + "github.com/kurtosis-tech/kurtosis/api/golang/core/lib/starlark_run_config" + "github.com/kurtosis-tech/kurtosis/api/golang/engine/lib/kurtosis_context" + "github.com/stretchr/testify/require" +) + +func StartEnclave(t *testing.T, ctx context.Context, lgr log.Logger, pkg string, params string) *enclaves.EnclaveContext { + kurtosisCtx, err := kurtosis_context.NewKurtosisContextFromLocalEngine() + require.NoError(t, err) + + enclaveID := fmt.Sprintf("kurtosis-%s", t.Name()) + enclaveCtx, err := kurtosisCtx.CreateEnclave(ctx, enclaveID) + require.NoError(t, err) + + t.Cleanup(func() { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + err = kurtosisCtx.DestroyEnclave(ctx, enclaveID) + if err != nil { + lgr.Error("Error destroying enclave", "err", err) + } + }) + + stream, _, err := enclaveCtx.RunStarlarkRemotePackage( + ctx, + pkg, + &starlark_run_config.StarlarkRunConfig{ + SerializedParams: params, + }, + ) + require.NoError(t, err) + + logKurtosisOutput := func(msg string) { + lgr.Info(fmt.Sprintf("[KURTOSIS] %s", msg)) + } + + for responseLine := range stream { + if responseLine.GetProgressInfo() != nil { + stepInfo := responseLine.GetProgressInfo().CurrentStepInfo + logKurtosisOutput(stepInfo[len(stepInfo)-1]) + } else if responseLine.GetInstruction() != nil { + logKurtosisOutput(responseLine.GetInstruction().Description) + } else if responseLine.GetError() != nil { + if responseLine.GetError().GetInterpretationError() != nil { + t.Fatalf("interpretation error: %s", responseLine.GetError().GetInterpretationError().String()) + } else if responseLine.GetError().GetValidationError() != nil { + t.Fatalf("validation error: %s", responseLine.GetError().GetValidationError().String()) + } else if responseLine.GetError().GetExecutionError() != nil { + t.Fatalf("execution error: %s", responseLine.GetError().GetExecutionError().String()) + } + } + } + + return enclaveCtx +} From 7efa4e7cf5b5537048d0415d4540073a387df80e Mon Sep 17 00:00:00 2001 From: Inphi Date: Mon, 16 Sep 2024 16:09:28 -0400 Subject: [PATCH 149/264] circleci: Enable mt-cannon in develop-fault-proofs (#11928) --- .circleci/config.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4c5e401ada57..6a1448147ba7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -888,7 +888,7 @@ jobs: command: | # Make sure the workspace is properly owned sudo chown -R $USER:$USER . - mkdir -p /tmp/test-results + mkdir -p /tmp/test-results mkdir -p /tmp/testlogs - run: name: run tests @@ -2123,9 +2123,7 @@ workflows: name: op-e2e-cannon-tests<< matrix.variant >> matrix: parameters: - variant: [""] - # TODO(#11893): add mt-cannon to matrix once it's stable - #variant: ["", "-mt-cannon"] + variant: ["", "-mt-cannon"] module: op-e2e target: test-cannon parallelism: 4 From 9968aa3ba2e3995f5a1f4dc562352383db793627 Mon Sep 17 00:00:00 2001 From: AgusDuha <81362284+agusduha@users.noreply.github.com> Date: Mon, 16 Sep 2024 17:43:47 -0300 Subject: [PATCH 150/264] feat: add SuperchainERC20 baseline (#11675) * feat: add superchain erc20 baseline (#37) * feat: add superchain erc20 baseline * feat: make superchain ERC20 simpler * fix: small version fix and tests * test: fix test name * test: remove unused import * feat: making baseline abstract * fix: interfaces to comply with the new interface checker * fix: import paths and empty line * fix: lint line --------- Co-authored-by: 0xng Co-authored-by: 0xng <87835144+0xng@users.noreply.github.com> --- packages/contracts-bedrock/semver-lock.json | 4 +- .../src/L2/OptimismSuperchainERC20.sol | 72 ++---- .../src/L2/SuperchainERC20.sol | 49 ++++ .../interfaces/IOptimismSuperchainERC20.sol | 10 +- .../src/L2/interfaces/ISuperchainERC20.sol | 21 +- .../dependency/interfaces/IERC20Solady.sol | 95 ++++++++ .../test/L2/OptimismSuperchainERC20.t.sol | 54 ++--- .../test/L2/SuperchainERC20.t.sol | 223 ++++++++++++++++++ 8 files changed, 424 insertions(+), 104 deletions(-) create mode 100644 packages/contracts-bedrock/src/L2/SuperchainERC20.sol create mode 100644 packages/contracts-bedrock/src/dependency/interfaces/IERC20Solady.sol create mode 100644 packages/contracts-bedrock/test/L2/SuperchainERC20.t.sol diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index fc7c5aa8be86..9846577f0503 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -116,8 +116,8 @@ "sourceCodeHash": "0x4b806cc85cead74c8df34ab08f4b6c6a95a1a387a335ec8a7cb2de4ea4e1cf41" }, "src/L2/OptimismSuperchainERC20.sol": { - "initCodeHash": "0xdd16dbc0ccbbac53ec2d4273f06334960a907a9f20b7c40300833227ee31d0de", - "sourceCodeHash": "0x910d43a17800df64dbc104f69ef1f900ca761cec4949c01d1c1126fde5268349" + "initCodeHash": "0x4fd71b5352b78d51d39625b6defa77a75be53067b32f3cba86bd17a46917adf9", + "sourceCodeHash": "0xad3934ea533544b3c130c80be26201354af85f9166cb2ce54d96e5e383ebb5c1" }, "src/L2/OptimismSuperchainERC20Beacon.sol": { "initCodeHash": "0x99ce8095b23c124850d866cbc144fee6cee05dbc6bb5d83acadfe00b90cf42c7", diff --git a/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol b/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol index 731657e900fc..81cef632bfbe 100644 --- a/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol +++ b/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol @@ -2,27 +2,17 @@ pragma solidity 0.8.25; import { IOptimismSuperchainERC20Extension } from "src/L2/interfaces/IOptimismSuperchainERC20.sol"; -import { ERC20 } from "@solady/tokens/ERC20.sol"; import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; +import { ERC20 } from "@solady/tokens/ERC20.sol"; +import { SuperchainERC20 } from "src/L2/SuperchainERC20.sol"; import { Initializable } from "@openzeppelin/contracts-v5/proxy/utils/Initializable.sol"; import { ERC165 } from "@openzeppelin/contracts-v5/utils/introspection/ERC165.sol"; -/// @notice Thrown when attempting to relay a message and the function caller (msg.sender) is not -/// L2ToL2CrossDomainMessenger. -error CallerNotL2ToL2CrossDomainMessenger(); - -/// @notice Thrown when attempting to relay a message and the cross domain message sender is not this -/// OptimismSuperchainERC20. -error InvalidCrossDomainSender(); - /// @notice Thrown when attempting to mint or burn tokens and the function caller is not the StandardBridge. error OnlyBridge(); -/// @notice Thrown when attempting to mint or burn tokens and the account is the zero address. -error ZeroAddress(); - /// @custom:proxied true /// @title OptimismSuperchainERC20 /// @notice OptimismSuperchainERC20 is a standard extension of the base ERC20 token contract that unifies ERC20 token @@ -31,10 +21,13 @@ error ZeroAddress(); /// token, turning it fungible and interoperable across the superchain. Likewise, it also enables the inverse /// conversion path. /// Moreover, it builds on top of the L2ToL2CrossDomainMessenger for both replay protection and domain binding. -contract OptimismSuperchainERC20 is IOptimismSuperchainERC20Extension, ERC20, ISemver, Initializable, ERC165 { - /// @notice Address of the L2ToL2CrossDomainMessenger Predeploy. - address internal constant MESSENGER = Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER; - +contract OptimismSuperchainERC20 is + IOptimismSuperchainERC20Extension, + SuperchainERC20, + ISemver, + Initializable, + ERC165 +{ /// @notice Address of the StandardBridge Predeploy. address internal constant BRIDGE = Predeploys.L2_STANDARD_BRIDGE; @@ -57,7 +50,7 @@ contract OptimismSuperchainERC20 is IOptimismSuperchainERC20Extension, ERC20, IS } /// @notice Returns the storage for the OptimismSuperchainERC20Metadata. - function _getMetadataStorage() private pure returns (OptimismSuperchainERC20Metadata storage _storage) { + function _getStorage() private pure returns (OptimismSuperchainERC20Metadata storage _storage) { assembly { _storage.slot := OPTIMISM_SUPERCHAIN_ERC20_METADATA_SLOT } @@ -92,7 +85,7 @@ contract OptimismSuperchainERC20 is IOptimismSuperchainERC20Extension, ERC20, IS external initializer { - OptimismSuperchainERC20Metadata storage _storage = _getMetadataStorage(); + OptimismSuperchainERC20Metadata storage _storage = _getStorage(); _storage.remoteToken = _remoteToken; _storage.name = _name; _storage.symbol = _symbol; @@ -121,54 +114,19 @@ contract OptimismSuperchainERC20 is IOptimismSuperchainERC20Extension, ERC20, IS emit Burn(_from, _amount); } - /// @notice Sends tokens to some target address on another chain. - /// @param _to Address to send tokens to. - /// @param _amount Amount of tokens to send. - /// @param _chainId Chain ID of the destination chain. - function sendERC20(address _to, uint256 _amount, uint256 _chainId) external { - if (_to == address(0)) revert ZeroAddress(); - - _burn(msg.sender, _amount); - - bytes memory _message = abi.encodeCall(this.relayERC20, (msg.sender, _to, _amount)); - IL2ToL2CrossDomainMessenger(MESSENGER).sendMessage(_chainId, address(this), _message); - - emit SendERC20(msg.sender, _to, _amount, _chainId); - } - - /// @notice Relays tokens received from another chain. - /// @param _from Address of the msg.sender of sendERC20 on the source chain. - /// @param _to Address to relay tokens to. - /// @param _amount Amount of tokens to relay. - function relayERC20(address _from, address _to, uint256 _amount) external { - if (_to == address(0)) revert ZeroAddress(); - - if (msg.sender != MESSENGER) revert CallerNotL2ToL2CrossDomainMessenger(); - - if (IL2ToL2CrossDomainMessenger(MESSENGER).crossDomainMessageSender() != address(this)) { - revert InvalidCrossDomainSender(); - } - - uint256 source = IL2ToL2CrossDomainMessenger(MESSENGER).crossDomainMessageSource(); - - _mint(_to, _amount); - - emit RelayERC20(_from, _to, _amount, source); - } - /// @notice Returns the address of the corresponding version of this token on the remote chain. function remoteToken() public view override returns (address) { - return _getMetadataStorage().remoteToken; + return _getStorage().remoteToken; } /// @notice Returns the name of the token. function name() public view virtual override returns (string memory) { - return _getMetadataStorage().name; + return _getStorage().name; } /// @notice Returns the symbol of the token. function symbol() public view virtual override returns (string memory) { - return _getMetadataStorage().symbol; + return _getStorage().symbol; } /// @notice Returns the number of decimals used to get its user representation. @@ -178,7 +136,7 @@ contract OptimismSuperchainERC20 is IOptimismSuperchainERC20Extension, ERC20, IS /// no way affects any of the arithmetic of the contract, including /// {IERC20-balanceOf} and {IERC20-transfer}. function decimals() public view override returns (uint8) { - return _getMetadataStorage().decimals; + return _getStorage().decimals; } /// @notice ERC165 interface check function. diff --git a/packages/contracts-bedrock/src/L2/SuperchainERC20.sol b/packages/contracts-bedrock/src/L2/SuperchainERC20.sol new file mode 100644 index 000000000000..e20b375ff891 --- /dev/null +++ b/packages/contracts-bedrock/src/L2/SuperchainERC20.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +import { ISuperchainERC20Extensions, ISuperchainERC20Errors } from "src/L2/interfaces/ISuperchainERC20.sol"; +import { ERC20 } from "@solady/tokens/ERC20.sol"; +import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; + +/// @title SuperchainERC20 +/// @notice SuperchainERC20 is a standard extension of the base ERC20 token contract that unifies ERC20 token +/// bridging to make it fungible across the Superchain. It builds on top of the L2ToL2CrossDomainMessenger for +/// both replay protection and domain binding. +abstract contract SuperchainERC20 is ISuperchainERC20Extensions, ISuperchainERC20Errors, ERC20 { + /// @notice Address of the L2ToL2CrossDomainMessenger Predeploy. + address internal constant MESSENGER = Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER; + + /// @notice Sends tokens to some target address on another chain. + /// @param _to Address to send tokens to. + /// @param _amount Amount of tokens to send. + /// @param _chainId Chain ID of the destination chain. + function sendERC20(address _to, uint256 _amount, uint256 _chainId) external virtual { + if (_to == address(0)) revert ZeroAddress(); + + _burn(msg.sender, _amount); + + bytes memory _message = abi.encodeCall(this.relayERC20, (msg.sender, _to, _amount)); + IL2ToL2CrossDomainMessenger(MESSENGER).sendMessage(_chainId, address(this), _message); + + emit SendERC20(msg.sender, _to, _amount, _chainId); + } + + /// @notice Relays tokens received from another chain. + /// @param _from Address of the msg.sender of sendERC20 on the source chain. + /// @param _to Address to relay tokens to. + /// @param _amount Amount of tokens to relay. + function relayERC20(address _from, address _to, uint256 _amount) external virtual { + if (msg.sender != MESSENGER) revert CallerNotL2ToL2CrossDomainMessenger(); + + if (IL2ToL2CrossDomainMessenger(MESSENGER).crossDomainMessageSender() != address(this)) { + revert InvalidCrossDomainSender(); + } + + uint256 source = IL2ToL2CrossDomainMessenger(MESSENGER).crossDomainMessageSource(); + + _mint(_to, _amount); + + emit RelayERC20(_from, _to, _amount, source); + } +} diff --git a/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20.sol b/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20.sol index 9b9594e75d78..91a51e0fb543 100644 --- a/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20.sol +++ b/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { ISuperchainERC20Extensions } from "./ISuperchainERC20.sol"; +import { IERC20Solady } from "src/dependency/interfaces/IERC20Solady.sol"; +import { ISuperchainERC20Extensions, ISuperchainERC20Errors } from "./ISuperchainERC20.sol"; /// @title IOptimismSuperchainERC20Extension /// @notice This interface is available on the OptimismSuperchainERC20 contract. /// We declare it as a separate interface so that it can be used in /// custom implementations of SuperchainERC20. -interface IOptimismSuperchainERC20Extension is ISuperchainERC20Extensions { +interface IOptimismSuperchainERC20Extension is ISuperchainERC20Extensions, ISuperchainERC20Errors { /// @notice Emitted whenever tokens are minted for an account. /// @param account Address of the account tokens are being minted for. /// @param amount Amount of tokens minted. @@ -34,5 +34,5 @@ interface IOptimismSuperchainERC20Extension is ISuperchainERC20Extensions { } /// @title IOptimismSuperchainERC20 -/// @notice Combines the ERC20 interface with the OptimismSuperchainERC20Extension interface. -interface IOptimismSuperchainERC20 is IERC20, IOptimismSuperchainERC20Extension { } +/// @notice Combines Solady's ERC20 interface with the OptimismSuperchainERC20Extension interface. +interface IOptimismSuperchainERC20 is IERC20Solady, IOptimismSuperchainERC20Extension { } diff --git a/packages/contracts-bedrock/src/L2/interfaces/ISuperchainERC20.sol b/packages/contracts-bedrock/src/L2/interfaces/ISuperchainERC20.sol index 76488cdf32ea..78f7ae7fc1d7 100644 --- a/packages/contracts-bedrock/src/L2/interfaces/ISuperchainERC20.sol +++ b/packages/contracts-bedrock/src/L2/interfaces/ISuperchainERC20.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { IERC20Solady } from "src/dependency/interfaces/IERC20Solady.sol"; /// @title ISuperchainERC20Extensions /// @notice Interface for the extensions to the ERC20 standard that are used by SuperchainERC20. @@ -35,6 +35,21 @@ interface ISuperchainERC20Extensions { function relayERC20(address _from, address _to, uint256 _amount) external; } +/// @title ISuperchainERC20Errors +/// @notice Interface containing the errors added in the SuperchainERC20 implementation. +interface ISuperchainERC20Errors { + /// @notice Thrown when attempting to relay a message and the function caller (msg.sender) is not + /// L2ToL2CrossDomainMessenger. + error CallerNotL2ToL2CrossDomainMessenger(); + + /// @notice Thrown when attempting to relay a message and the cross domain message sender is not this + /// SuperchainERC20. + error InvalidCrossDomainSender(); + + /// @notice Thrown when attempting to perform an operation and the account is the zero address. + error ZeroAddress(); +} + /// @title ISuperchainERC20 -/// @notice Combines the ERC20 interface with the SuperchainERC20Extensions interface. -interface ISuperchainERC20 is IERC20, ISuperchainERC20Extensions { } +/// @notice Combines Solady's ERC20 interface with the SuperchainERC20Extensions interface. +interface ISuperchainERC20 is IERC20Solady, ISuperchainERC20Extensions, ISuperchainERC20Errors { } diff --git a/packages/contracts-bedrock/src/dependency/interfaces/IERC20Solady.sol b/packages/contracts-bedrock/src/dependency/interfaces/IERC20Solady.sol new file mode 100644 index 000000000000..1e696ad23ac3 --- /dev/null +++ b/packages/contracts-bedrock/src/dependency/interfaces/IERC20Solady.sol @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IERC20Solady { + /// @dev The total supply has overflowed. + error TotalSupplyOverflow(); + + /// @dev The allowance has overflowed. + error AllowanceOverflow(); + + /// @dev The allowance has underflowed. + error AllowanceUnderflow(); + + /// @dev Insufficient balance. + error InsufficientBalance(); + + /// @dev Insufficient allowance. + error InsufficientAllowance(); + + /// @dev The permit is invalid. + error InvalidPermit(); + + /// @dev The permit has expired. + error PermitExpired(); + + /// @dev Emitted when `amount` tokens is transferred from `from` to `to`. + event Transfer(address indexed from, address indexed to, uint256 amount); + + /// @dev Emitted when `amount` tokens is approved by `owner` to be used by `spender`. + event Approval(address indexed owner, address indexed spender, uint256 amount); + + /// @dev Returns the name of the token. + function name() external view returns (string memory); + + /// @dev Returns the symbol of the token. + function symbol() external view returns (string memory); + + /// @dev Returns the decimals places of the token. + function decimals() external view returns (uint8); + + /// @dev Returns the amount of tokens in existence. + function totalSupply() external view returns (uint256 result); + + /// @dev Returns the amount of tokens owned by `owner` + function balanceOf(address owner) external view returns (uint256 result); + + /// @dev Returns the amount of tokens that `spender` can spend on behalf of `owner`. + function allowance(address owner, address spender) external view returns (uint256 result); + + /// @dev Sets `amount` as the allowance of `spender` over the caller's tokens. + /// + /// Emits a {Approval} event. + function approve(address spender, uint256 amount) external returns (bool); + + /// @dev Transfer `amount` tokens from the caller to `to`. + /// + /// Requirements: + /// - `from` must at least have `amount`. + /// + /// Emits a {Transfer} event. + function transfer(address to, uint256 amount) external returns (bool); + + /// @dev Transfers `amount` tokens from `from` to `to`. + /// + /// Note: Does not update the allowance if it is the maximum uint256 value. + /// + /// Requirements: + /// - `from` must at least have `amount`. + /// - The caller must have at least `amount` of allowance to transfer the tokens of `from`. + /// + /// Emits a {Transfer} event. + function transferFrom(address from, address to, uint256 amount) external returns (bool); + + /// @dev Returns the current nonce for `owner`. + /// This value is used to compute the signature for EIP-2612 permit. + function nonces(address owner) external view returns (uint256 result); + + /// @dev Sets `value` as the allowance of `spender` over the tokens of `owner`, + /// authorized by a signed approval by `owner`. + /// + /// Emits a {Approval} event. + function permit( + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) + external; + + /// @dev Returns the EIP-712 domain separator for the EIP-2612 permit. + function DOMAIN_SEPARATOR() external view returns (bytes32 result); +} diff --git a/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20.t.sol b/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20.t.sol index 0fc7d88d0b7c..b8de1468421b 100644 --- a/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20.t.sol +++ b/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20.t.sol @@ -17,14 +17,11 @@ import { BeaconProxy } from "@openzeppelin/contracts-v5/proxy/beacon/BeaconProxy // Target contract import { - OptimismSuperchainERC20, - IOptimismSuperchainERC20Extension, - CallerNotL2ToL2CrossDomainMessenger, - InvalidCrossDomainSender, - OnlyBridge, - ZeroAddress + OptimismSuperchainERC20, IOptimismSuperchainERC20Extension, OnlyBridge } from "src/L2/OptimismSuperchainERC20.sol"; -import { ISuperchainERC20Extensions } from "src/L2/interfaces/ISuperchainERC20.sol"; + +// SuperchainERC20 Interfaces +import { ISuperchainERC20Extensions, ISuperchainERC20Errors } from "src/L2/interfaces/ISuperchainERC20.sol"; /// @title OptimismSuperchainERC20Test /// @notice Contract for testing the OptimismSuperchainERC20 contract. @@ -135,7 +132,7 @@ contract OptimismSuperchainERC20Test is Test { /// @notice Tests the `mint` function reverts when the amount is zero. function testFuzz_mint_zeroAddressTo_reverts(uint256 _amount) public { // Expect the revert with `ZeroAddress` selector - vm.expectRevert(ZeroAddress.selector); + vm.expectRevert(ISuperchainERC20Errors.ZeroAddress.selector); // Call the `mint` function with the zero address vm.prank(BRIDGE); @@ -152,11 +149,11 @@ contract OptimismSuperchainERC20Test is Test { uint256 _toBalanceBefore = superchainERC20.balanceOf(_to); // Look for the emit of the `Transfer` event - vm.expectEmit(true, true, true, true, address(superchainERC20)); + vm.expectEmit(address(superchainERC20)); emit IERC20.Transfer(ZERO_ADDRESS, _to, _amount); // Look for the emit of the `Mint` event - vm.expectEmit(true, true, true, true, address(superchainERC20)); + vm.expectEmit(address(superchainERC20)); emit IOptimismSuperchainERC20Extension.Mint(_to, _amount); // Call the `mint` function with the bridge caller @@ -184,7 +181,7 @@ contract OptimismSuperchainERC20Test is Test { /// @notice Tests the `burn` function reverts when the amount is zero. function testFuzz_burn_zeroAddressFrom_reverts(uint256 _amount) public { // Expect the revert with `ZeroAddress` selector - vm.expectRevert(ZeroAddress.selector); + vm.expectRevert(ISuperchainERC20Errors.ZeroAddress.selector); // Call the `burn` function with the zero address vm.prank(BRIDGE); @@ -205,11 +202,11 @@ contract OptimismSuperchainERC20Test is Test { uint256 _fromBalanceBefore = superchainERC20.balanceOf(_from); // Look for the emit of the `Transfer` event - vm.expectEmit(true, true, true, true, address(superchainERC20)); + vm.expectEmit(address(superchainERC20)); emit IERC20.Transfer(_from, ZERO_ADDRESS, _amount); // Look for the emit of the `Burn` event - vm.expectEmit(true, true, true, true, address(superchainERC20)); + vm.expectEmit(address(superchainERC20)); emit IOptimismSuperchainERC20Extension.Burn(_from, _amount); // Call the `burn` function with the bridge caller @@ -224,7 +221,7 @@ contract OptimismSuperchainERC20Test is Test { /// @notice Tests the `sendERC20` function reverts when the `_to` address is the zero address. function testFuzz_sendERC20_zeroAddressTo_reverts(uint256 _amount, uint256 _chainId) public { // Expect the revert with `ZeroAddress` selector - vm.expectRevert(ZeroAddress.selector); + vm.expectRevert(ISuperchainERC20Errors.ZeroAddress.selector); // Call the `sendERC20` function with the zero address vm.prank(BRIDGE); @@ -247,11 +244,11 @@ contract OptimismSuperchainERC20Test is Test { uint256 _senderBalanceBefore = superchainERC20.balanceOf(_sender); // Look for the emit of the `Transfer` event - vm.expectEmit(true, true, true, true, address(superchainERC20)); + vm.expectEmit(address(superchainERC20)); emit IERC20.Transfer(_sender, ZERO_ADDRESS, _amount); // Look for the emit of the `SendERC20` event - vm.expectEmit(true, true, true, true, address(superchainERC20)); + vm.expectEmit(address(superchainERC20)); emit ISuperchainERC20Extensions.SendERC20(_sender, _to, _amount, _chainId); // Mock the call over the `sendMessage` function and expect it to be called properly @@ -280,7 +277,7 @@ contract OptimismSuperchainERC20Test is Test { vm.assume(_to != ZERO_ADDRESS); // Expect the revert with `CallerNotL2ToL2CrossDomainMessenger` selector - vm.expectRevert(CallerNotL2ToL2CrossDomainMessenger.selector); + vm.expectRevert(ISuperchainERC20Errors.CallerNotL2ToL2CrossDomainMessenger.selector); // Call the `relayERC20` function with the non-messenger caller vm.prank(_caller); @@ -307,30 +304,13 @@ contract OptimismSuperchainERC20Test is Test { ); // Expect the revert with `InvalidCrossDomainSender` selector - vm.expectRevert(InvalidCrossDomainSender.selector); + vm.expectRevert(ISuperchainERC20Errors.InvalidCrossDomainSender.selector); // Call the `relayERC20` function with the sender caller vm.prank(MESSENGER); superchainERC20.relayERC20(_crossDomainMessageSender, _to, _amount); } - /// @notice Tests the `relayERC20` function reverts when the `_to` address is the zero address. - function testFuzz_relayERC20_zeroAddressTo_reverts(uint256 _amount) public { - // Expect the revert with `ZeroAddress` selector - vm.expectRevert(ZeroAddress.selector); - - // Mock the call over the `crossDomainMessageSender` function setting the same address as value - vm.mockCall( - MESSENGER, - abi.encodeWithSelector(IL2ToL2CrossDomainMessenger.crossDomainMessageSender.selector), - abi.encode(address(superchainERC20)) - ); - - // Call the `relayERC20` function with the zero address - vm.prank(MESSENGER); - superchainERC20.relayERC20({ _from: ZERO_ADDRESS, _to: ZERO_ADDRESS, _amount: _amount }); - } - /// @notice Tests the `relayERC20` mints the proper amount and emits the `RelayERC20` event. function testFuzz_relayERC20_succeeds(address _from, address _to, uint256 _amount, uint256 _source) public { vm.assume(_from != ZERO_ADDRESS); @@ -355,11 +335,11 @@ contract OptimismSuperchainERC20Test is Test { uint256 _toBalanceBefore = superchainERC20.balanceOf(_to); // Look for the emit of the `Transfer` event - vm.expectEmit(true, true, true, true, address(superchainERC20)); + vm.expectEmit(address(superchainERC20)); emit IERC20.Transfer(ZERO_ADDRESS, _to, _amount); // Look for the emit of the `RelayERC20` event - vm.expectEmit(true, true, true, true, address(superchainERC20)); + vm.expectEmit(address(superchainERC20)); emit ISuperchainERC20Extensions.RelayERC20(_from, _to, _amount, _source); // Call the `relayERC20` function with the messenger caller diff --git a/packages/contracts-bedrock/test/L2/SuperchainERC20.t.sol b/packages/contracts-bedrock/test/L2/SuperchainERC20.t.sol new file mode 100644 index 000000000000..66b20c1b911a --- /dev/null +++ b/packages/contracts-bedrock/test/L2/SuperchainERC20.t.sol @@ -0,0 +1,223 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +// Testing utilities +import { Test } from "forge-std/Test.sol"; + +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { IERC20 } from "@openzeppelin/contracts-v5/token/ERC20/IERC20.sol"; +import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; + +// Target contract +import { SuperchainERC20 } from "src/L2/SuperchainERC20.sol"; +import { ISuperchainERC20Extensions, ISuperchainERC20Errors } from "src/L2/interfaces/ISuperchainERC20.sol"; + +/// @notice Mock contract for the SuperchainERC20 contract so tests can mint tokens. +contract SuperchainERC20Mock is SuperchainERC20 { + string private _name; + string private _symbol; + uint8 private _decimals; + + constructor(string memory __name, string memory __symbol, uint8 __decimals) { + _name = __name; + _symbol = __symbol; + _decimals = __decimals; + } + + function mint(address _account, uint256 _amount) public { + _mint(_account, _amount); + } + + function name() public view virtual override returns (string memory) { + return _name; + } + + function symbol() public view virtual override returns (string memory) { + return _symbol; + } + + function decimals() public view virtual override returns (uint8) { + return _decimals; + } +} +/// @title SuperchainERC20Test +/// @notice Contract for testing the SuperchainERC20 contract. + +contract SuperchainERC20Test is Test { + address internal constant ZERO_ADDRESS = address(0); + string internal constant NAME = "SuperchainERC20"; + string internal constant SYMBOL = "SCE"; + uint8 internal constant DECIMALS = 18; + address internal constant MESSENGER = Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER; + + SuperchainERC20 public superchainERC20Impl; + SuperchainERC20Mock public superchainERC20; + + /// @notice Sets up the test suite. + function setUp() public { + superchainERC20 = new SuperchainERC20Mock(NAME, SYMBOL, DECIMALS); + } + + /// @notice Helper function to setup a mock and expect a call to it. + function _mockAndExpect(address _receiver, bytes memory _calldata, bytes memory _returned) internal { + vm.mockCall(_receiver, _calldata, _returned); + vm.expectCall(_receiver, _calldata); + } + + /// @notice Test that the contract's `constructor` sets the correct values. + function test_constructor_succeeds() public view { + assertEq(superchainERC20.name(), NAME); + assertEq(superchainERC20.symbol(), SYMBOL); + assertEq(superchainERC20.decimals(), DECIMALS); + } + + /// @notice Tests the `sendERC20` function reverts when the `_to` address is the zero address. + function testFuzz_sendERC20_zeroAddressTo_reverts(uint256 _amount, uint256 _chainId) public { + // Expect the revert with `ZeroAddress` selector + vm.expectRevert(ISuperchainERC20Errors.ZeroAddress.selector); + + // Call the `sendERC20` function with the zero address + superchainERC20.sendERC20({ _to: ZERO_ADDRESS, _amount: _amount, _chainId: _chainId }); + } + + /// @notice Tests the `sendERC20` function burns the sender tokens, sends the message, and emits the `SendERC20` + /// event. + function testFuzz_sendERC20_succeeds(address _sender, address _to, uint256 _amount, uint256 _chainId) external { + // Ensure `_sender` is not the zero address + vm.assume(_sender != ZERO_ADDRESS); + vm.assume(_to != ZERO_ADDRESS); + + // Mint some tokens to the sender so then they can be sent + superchainERC20.mint(_sender, _amount); + + // Get the total supply and balance of `_sender` before the send to compare later on the assertions + uint256 _totalSupplyBefore = superchainERC20.totalSupply(); + uint256 _senderBalanceBefore = superchainERC20.balanceOf(_sender); + + // Look for the emit of the `Transfer` event + vm.expectEmit(address(superchainERC20)); + emit IERC20.Transfer(_sender, ZERO_ADDRESS, _amount); + + // Look for the emit of the `SendERC20` event + vm.expectEmit(address(superchainERC20)); + emit ISuperchainERC20Extensions.SendERC20(_sender, _to, _amount, _chainId); + + // Mock the call over the `sendMessage` function and expect it to be called properly + bytes memory _message = abi.encodeCall(superchainERC20.relayERC20, (_sender, _to, _amount)); + _mockAndExpect( + MESSENGER, + abi.encodeWithSelector( + IL2ToL2CrossDomainMessenger.sendMessage.selector, _chainId, address(superchainERC20), _message + ), + abi.encode("") + ); + + // Call the `sendERC20` function + vm.prank(_sender); + superchainERC20.sendERC20(_to, _amount, _chainId); + + // Check the total supply and balance of `_sender` after the send were updated correctly + assertEq(superchainERC20.totalSupply(), _totalSupplyBefore - _amount); + assertEq(superchainERC20.balanceOf(_sender), _senderBalanceBefore - _amount); + } + + /// @notice Tests the `relayERC20` function reverts when the caller is not the L2ToL2CrossDomainMessenger. + function testFuzz_relayERC20_notMessenger_reverts(address _caller, address _to, uint256 _amount) public { + // Ensure the caller is not the messenger + vm.assume(_caller != MESSENGER); + vm.assume(_to != ZERO_ADDRESS); + + // Expect the revert with `CallerNotL2ToL2CrossDomainMessenger` selector + vm.expectRevert(ISuperchainERC20Errors.CallerNotL2ToL2CrossDomainMessenger.selector); + + // Call the `relayERC20` function with the non-messenger caller + vm.prank(_caller); + superchainERC20.relayERC20(_caller, _to, _amount); + } + + /// @notice Tests the `relayERC20` function reverts when the `crossDomainMessageSender` that sent the message is not + /// the same SuperchainERC20 address. + function testFuzz_relayERC20_notCrossDomainSender_reverts( + address _crossDomainMessageSender, + address _to, + uint256 _amount + ) + public + { + vm.assume(_to != ZERO_ADDRESS); + vm.assume(_crossDomainMessageSender != address(superchainERC20)); + + // Mock the call over the `crossDomainMessageSender` function setting a wrong sender + vm.mockCall( + MESSENGER, + abi.encodeWithSelector(IL2ToL2CrossDomainMessenger.crossDomainMessageSender.selector), + abi.encode(_crossDomainMessageSender) + ); + + // Expect the revert with `InvalidCrossDomainSender` selector + vm.expectRevert(ISuperchainERC20Errors.InvalidCrossDomainSender.selector); + + // Call the `relayERC20` function with the sender caller + vm.prank(MESSENGER); + superchainERC20.relayERC20(_crossDomainMessageSender, _to, _amount); + } + + /// @notice Tests the `relayERC20` mints the proper amount and emits the `RelayERC20` event. + function testFuzz_relayERC20_succeeds(address _from, address _to, uint256 _amount, uint256 _source) public { + vm.assume(_from != ZERO_ADDRESS); + vm.assume(_to != ZERO_ADDRESS); + + // Mock the call over the `crossDomainMessageSender` function setting the same address as value + _mockAndExpect( + MESSENGER, + abi.encodeWithSelector(IL2ToL2CrossDomainMessenger.crossDomainMessageSender.selector), + abi.encode(address(superchainERC20)) + ); + + // Mock the call over the `crossDomainMessageSource` function setting the source chain ID as value + _mockAndExpect( + MESSENGER, + abi.encodeWithSelector(IL2ToL2CrossDomainMessenger.crossDomainMessageSource.selector), + abi.encode(_source) + ); + + // Get the total supply and balance of `_to` before the relay to compare later on the assertions + uint256 _totalSupplyBefore = superchainERC20.totalSupply(); + uint256 _toBalanceBefore = superchainERC20.balanceOf(_to); + + // Look for the emit of the `Transfer` event + vm.expectEmit(address(superchainERC20)); + emit IERC20.Transfer(ZERO_ADDRESS, _to, _amount); + + // Look for the emit of the `RelayERC20` event + vm.expectEmit(address(superchainERC20)); + emit ISuperchainERC20Extensions.RelayERC20(_from, _to, _amount, _source); + + // Call the `relayERC20` function with the messenger caller + vm.prank(MESSENGER); + superchainERC20.relayERC20(_from, _to, _amount); + + // Check the total supply and balance of `_to` after the relay were updated correctly + assertEq(superchainERC20.totalSupply(), _totalSupplyBefore + _amount); + assertEq(superchainERC20.balanceOf(_to), _toBalanceBefore + _amount); + } + + /// @notice Tests the `name` function always returns the correct value. + function testFuzz_name_succeeds(string memory _name) public { + SuperchainERC20 _newSuperchainERC20 = new SuperchainERC20Mock(_name, SYMBOL, DECIMALS); + assertEq(_newSuperchainERC20.name(), _name); + } + + /// @notice Tests the `symbol` function always returns the correct value. + function testFuzz_symbol_succeeds(string memory _symbol) public { + SuperchainERC20 _newSuperchainERC20 = new SuperchainERC20Mock(NAME, _symbol, DECIMALS); + assertEq(_newSuperchainERC20.symbol(), _symbol); + } + + /// @notice Tests the `decimals` function always returns the correct value. + function testFuzz_decimals_succeeds(uint8 _decimals) public { + SuperchainERC20 _newSuperchainERC20 = new SuperchainERC20Mock(NAME, SYMBOL, _decimals); + assertEq(_newSuperchainERC20.decimals(), _decimals); + } +} From 7d92c98c75a2c81a183fd9c2445756f4e7e82ee5 Mon Sep 17 00:00:00 2001 From: tre Date: Mon, 16 Sep 2024 13:45:39 -0700 Subject: [PATCH 151/264] feat(op-service): add SuperchainWETH and ETHLiquidity to predeploys/addresses.go (#11927) --- op-service/predeploys/addresses.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/op-service/predeploys/addresses.go b/op-service/predeploys/addresses.go index a03fcf29188a..0b69df3bb834 100644 --- a/op-service/predeploys/addresses.go +++ b/op-service/predeploys/addresses.go @@ -27,6 +27,8 @@ const ( EAS = "0x4200000000000000000000000000000000000021" CrossL2Inbox = "0x4200000000000000000000000000000000000022" L2toL2CrossDomainMessenger = "0x4200000000000000000000000000000000000023" + SuperchainWETH = "0x4200000000000000000000000000000000000024" + ETHLiquidity = "0x4200000000000000000000000000000000000025" Create2Deployer = "0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2" MultiCall3 = "0xcA11bde05977b3631167028862bE2a173976CA11" Safe_v130 = "0x69f4D1788e39c87893C980c06EdF4b7f686e2938" @@ -64,6 +66,8 @@ var ( EASAddr = common.HexToAddress(EAS) CrossL2InboxAddr = common.HexToAddress(CrossL2Inbox) L2toL2CrossDomainMessengerAddr = common.HexToAddress(L2toL2CrossDomainMessenger) + SuperchainWETHAddr = common.HexToAddress(SuperchainWETH) + ETHLiquidityAddr = common.HexToAddress(ETHLiquidity) Create2DeployerAddr = common.HexToAddress(Create2Deployer) MultiCall3Addr = common.HexToAddress(MultiCall3) Safe_v130Addr = common.HexToAddress(Safe_v130) @@ -95,6 +99,8 @@ func init() { Predeploys["L1Block"] = &Predeploy{Address: L1BlockAddr} Predeploys["CrossL2Inbox"] = &Predeploy{Address: CrossL2InboxAddr} Predeploys["L2toL2CrossDomainMessenger"] = &Predeploy{Address: L2toL2CrossDomainMessengerAddr} + Predeploys["SuperchainWETH"] = &Predeploy{Address: SuperchainWETHAddr} + Predeploys["ETHLiquidity"] = &Predeploy{Address: ETHLiquidityAddr} Predeploys["GovernanceToken"] = &Predeploy{ Address: GovernanceTokenAddr, ProxyDisabled: true, From 717330e9803f4344606e8e71fe1dbaa382def5fc Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Mon, 16 Sep 2024 14:54:49 -0600 Subject: [PATCH 152/264] Port deployers, add end-to-end contract deployments (#11922) This PR ports over the deployers in `interopgen` into `op-deployer`, and updates `op-deployer` to support end-to end contract deployments for both the Superchain and individual OP Chains. This PR includes a couple of bugfixes for things I discovered along the way: 1. The script host is updated to bump the nonce of the address calling the CREATE2 deployer when broadcasting. This fixes a chain/simulation mismatch that blocked contracts from being deployed. 2. The DeployImplementations contract used a fixed CREATE2 salt, which caused problems on repeated deployments. I updated the contract to pull the nonce from the environment as we do elsewhere. Builds on https://github.com/ethereum-optimism/optimism/pull/11910. --- op-chain-ops/deployer/apply.go | 21 +++- op-chain-ops/deployer/broadcaster/discard.go | 20 ++++ op-chain-ops/deployer/broadcaster/keyed.go | 56 ++++++--- .../deployer/integration_test/apply_test.go | 91 +++++++++++++-- .../opsm}/implementations.go | 38 +++--- .../deployers => deployer/opsm}/opchain.go | 27 ++--- op-chain-ops/deployer/opsm/superchain.go | 57 ++------- op-chain-ops/deployer/pipeline/host.go | 70 +++++++++++ .../deployer/pipeline/implementations.go | 101 ++++++++++++++++ op-chain-ops/deployer/pipeline/init.go | 10 ++ op-chain-ops/deployer/pipeline/opchain.go | 110 ++++++++++++++++++ op-chain-ops/deployer/pipeline/superchain.go | 59 +++++----- op-chain-ops/deployer/state/intent.go | 33 +++--- op-chain-ops/deployer/state/state.go | 58 ++++++++- op-chain-ops/interopgen/deploy.go | 12 +- .../interopgen/deployers/superchain.go | 70 ----------- op-chain-ops/script/script.go | 18 ++- op-chain-ops/script/script_test.go | 6 +- .../scripts/DeployImplementations.s.sol | 3 +- 19 files changed, 624 insertions(+), 236 deletions(-) create mode 100644 op-chain-ops/deployer/broadcaster/discard.go rename op-chain-ops/{interopgen/deployers => deployer/opsm}/implementations.go (67%) rename op-chain-ops/{interopgen/deployers => deployer/opsm}/opchain.go (76%) create mode 100644 op-chain-ops/deployer/pipeline/host.go create mode 100644 op-chain-ops/deployer/pipeline/implementations.go create mode 100644 op-chain-ops/deployer/pipeline/opchain.go delete mode 100644 op-chain-ops/interopgen/deployers/superchain.go diff --git a/op-chain-ops/deployer/apply.go b/op-chain-ops/deployer/apply.go index d39628cc6363..e604eb8a9ffe 100644 --- a/op-chain-ops/deployer/apply.go +++ b/op-chain-ops/deployer/apply.go @@ -126,19 +126,32 @@ func Apply(ctx context.Context, cfg ApplyConfig) error { return nil } +type pipelineStage struct { + name string + stage pipeline.Stage +} + func ApplyPipeline( ctx context.Context, env *pipeline.Env, intent *state.Intent, st *state.State, ) error { - pline := []struct { - name string - stage pipeline.Stage - }{ + pline := []pipelineStage{ {"init", pipeline.Init}, {"deploy-superchain", pipeline.DeploySuperchain}, + {"deploy-implementations", pipeline.DeployImplementations}, + } + + for _, chain := range intent.Chains { + pline = append(pline, pipelineStage{ + fmt.Sprintf("deploy-opchain-%s", chain.ID.Hex()), + func(ctx context.Context, env *pipeline.Env, intent *state.Intent, st *state.State) error { + return pipeline.DeployOPChain(ctx, env, intent, st, chain.ID) + }, + }) } + for _, stage := range pline { if err := stage.stage(ctx, env, intent, st); err != nil { return fmt.Errorf("error in pipeline stage: %w", err) diff --git a/op-chain-ops/deployer/broadcaster/discard.go b/op-chain-ops/deployer/broadcaster/discard.go new file mode 100644 index 000000000000..42f5b1b0a964 --- /dev/null +++ b/op-chain-ops/deployer/broadcaster/discard.go @@ -0,0 +1,20 @@ +package broadcaster + +import ( + "context" + + "github.com/ethereum-optimism/optimism/op-chain-ops/script" +) + +type discardBroadcaster struct { +} + +func DiscardBroadcaster() Broadcaster { + return &discardBroadcaster{} +} + +func (d *discardBroadcaster) Broadcast(ctx context.Context) ([]BroadcastResult, error) { + return nil, nil +} + +func (d *discardBroadcaster) Hook(bcast script.Broadcast) {} diff --git a/op-chain-ops/deployer/broadcaster/keyed.go b/op-chain-ops/deployer/broadcaster/keyed.go index 8c34cb1ab531..2784c4d455be 100644 --- a/op-chain-ops/deployer/broadcaster/keyed.go +++ b/op-chain-ops/deployer/broadcaster/keyed.go @@ -20,13 +20,14 @@ import ( ) const ( - GasPadFactor = 1.5 + GasPadFactor = 2.0 ) type KeyedBroadcaster struct { lgr log.Logger mgr txmgr.TxManager bcasts []script.Broadcast + client *ethclient.Client } type KeyedBroadcasterOpts struct { @@ -84,8 +85,9 @@ func NewKeyedBroadcaster(cfg KeyedBroadcasterOpts) (*KeyedBroadcaster, error) { } return &KeyedBroadcaster{ - lgr: cfg.Logger, - mgr: mgr, + lgr: cfg.Logger, + mgr: mgr, + client: cfg.Client, }, nil } @@ -98,8 +100,13 @@ func (t *KeyedBroadcaster) Broadcast(ctx context.Context) ([]BroadcastResult, er futures := make([]<-chan txmgr.SendResponse, len(t.bcasts)) ids := make([]common.Hash, len(t.bcasts)) + latestBlock, err := t.client.BlockByNumber(ctx, nil) + if err != nil { + return nil, fmt.Errorf("failed to get latest block: %w", err) + } + for i, bcast := range t.bcasts { - futures[i], ids[i] = t.broadcast(ctx, bcast) + futures[i], ids[i] = t.broadcast(ctx, bcast, latestBlock.GasLimit()) t.lgr.Info( "transaction broadcasted", "id", ids[i], @@ -107,7 +114,7 @@ func (t *KeyedBroadcaster) Broadcast(ctx context.Context) ([]BroadcastResult, er ) } - var err *multierror.Error + var txErr *multierror.Error var completed int for i, fut := range futures { bcastRes := <-fut @@ -122,7 +129,7 @@ func (t *KeyedBroadcaster) Broadcast(ctx context.Context) ([]BroadcastResult, er if bcastRes.Receipt.Status == 0 { failErr := fmt.Errorf("transaction failed: %s", outRes.Receipt.TxHash.String()) - err = multierror.Append(err, failErr) + txErr = multierror.Append(txErr, failErr) outRes.Err = failErr t.lgr.Error( "transaction failed on chain", @@ -144,7 +151,7 @@ func (t *KeyedBroadcaster) Broadcast(ctx context.Context) ([]BroadcastResult, er ) } } else { - err = multierror.Append(err, bcastRes.Err) + txErr = multierror.Append(txErr, bcastRes.Err) outRes.Err = bcastRes.Err t.lgr.Error( "transaction failed", @@ -157,12 +164,13 @@ func (t *KeyedBroadcaster) Broadcast(ctx context.Context) ([]BroadcastResult, er results = append(results, outRes) } - return results, err.ErrorOrNil() + return results, txErr.ErrorOrNil() } -func (t *KeyedBroadcaster) broadcast(ctx context.Context, bcast script.Broadcast) (<-chan txmgr.SendResponse, common.Hash) { - id := bcast.ID() +func (t *KeyedBroadcaster) broadcast(ctx context.Context, bcast script.Broadcast, blockGasLimit uint64) (<-chan txmgr.SendResponse, common.Hash) { + ch := make(chan txmgr.SendResponse, 1) + id := bcast.ID() value := ((*uint256.Int)(bcast.Value)).ToBig() var candidate txmgr.TxCandidate switch bcast.Type { @@ -172,27 +180,45 @@ func (t *KeyedBroadcaster) broadcast(ctx context.Context, bcast script.Broadcast TxData: bcast.Input, To: to, Value: value, - GasLimit: padGasLimit(bcast.Input, bcast.GasUsed, false), + GasLimit: padGasLimit(bcast.Input, bcast.GasUsed, false, blockGasLimit), } case script.BroadcastCreate: candidate = txmgr.TxCandidate{ TxData: bcast.Input, To: nil, - GasLimit: padGasLimit(bcast.Input, bcast.GasUsed, true), + GasLimit: padGasLimit(bcast.Input, bcast.GasUsed, true, blockGasLimit), + } + case script.BroadcastCreate2: + txData := make([]byte, len(bcast.Salt)+len(bcast.Input)) + copy(txData, bcast.Salt[:]) + copy(txData[len(bcast.Salt):], bcast.Input) + + candidate = txmgr.TxCandidate{ + TxData: txData, + To: &script.DeterministicDeployerAddress, + Value: value, + GasLimit: padGasLimit(bcast.Input, bcast.GasUsed, true, blockGasLimit), } } - ch := make(chan txmgr.SendResponse, 1) t.mgr.SendAsync(ctx, candidate, ch) return ch, id } -func padGasLimit(data []byte, gasUsed uint64, creation bool) uint64 { +// padGasLimit calculates the gas limit for a transaction based on the intrinsic gas and the gas used by +// the underlying call. Values are multiplied by a pad factor to account for any discrepancies. The output +// is clamped to the block gas limit since Geth will reject transactions that exceed it before letting them +// into the mempool. +func padGasLimit(data []byte, gasUsed uint64, creation bool, blockGasLimit uint64) uint64 { intrinsicGas, err := core.IntrinsicGas(data, nil, creation, true, true, false) // This method never errors - we should look into it if it does. if err != nil { panic(err) } - return uint64(float64(intrinsicGas+gasUsed) * GasPadFactor) + limit := uint64(float64(intrinsicGas+gasUsed) * GasPadFactor) + if limit > blockGasLimit { + return blockGasLimit + } + return limit } diff --git a/op-chain-ops/deployer/integration_test/apply_test.go b/op-chain-ops/deployer/integration_test/apply_test.go index 6a592998b3e3..ca03b4998004 100644 --- a/op-chain-ops/deployer/integration_test/apply_test.go +++ b/op-chain-ops/deployer/integration_test/apply_test.go @@ -11,6 +11,7 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer" + "github.com/holiman/uint256" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/pipeline" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" @@ -29,6 +30,15 @@ participants: cl_type: lighthouse network_params: prefunded_accounts: '{ "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266": { "balance": "1000000ETH" } }' + additional_preloaded_contracts: '{ + "0x4e59b44847b379578588920cA78FbF26c0B4956C": { + balance: "0ETH", + code: "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3", + storage: {}, + nonce: 0, + secretKey: "0x" + } + }' network_id: "77799777" seconds_per_slot: 3 ` @@ -78,6 +88,8 @@ func TestEndToEndApply(t *testing.T) { require.NoError(t, err) signer := opcrypto.SignerFnFromBind(opcrypto.PrivateKeySignerFn(pk, l1ChainID)) + id := uint256.NewInt(1) + addrFor := func(key devkeys.Key) common.Address { addr, err := dk.Address(key) require.NoError(t, err) @@ -100,6 +112,20 @@ func TestEndToEndApply(t *testing.T) { UseFaultProofs: true, FundDevAccounts: true, ContractArtifactsURL: (*state.ArtifactsURL)(artifactsURL), + Chains: []state.ChainIntent{ + { + ID: id.Bytes32(), + Roles: state.ChainRoles{ + ProxyAdminOwner: addrFor(devkeys.L2ProxyAdminOwnerRole.Key(l1ChainID)), + SystemConfigOwner: addrFor(devkeys.SystemConfigOwner.Key(l1ChainID)), + GovernanceTokenOwner: addrFor(devkeys.L2ProxyAdminOwnerRole.Key(l1ChainID)), + UnsafeBlockSigner: addrFor(devkeys.SequencerP2PRole.Key(l1ChainID)), + Batcher: addrFor(devkeys.BatcherRole.Key(l1ChainID)), + Proposer: addrFor(devkeys.ProposerRole.Key(l1ChainID)), + Challenger: addrFor(devkeys.ChallengerRole.Key(l1ChainID)), + }, + }, + }, } st := &state.State{ Version: 1, @@ -112,16 +138,63 @@ func TestEndToEndApply(t *testing.T) { st, )) - addrs := []common.Address{ - st.SuperchainDeployment.ProxyAdminAddress, - st.SuperchainDeployment.SuperchainConfigProxyAddress, - st.SuperchainDeployment.SuperchainConfigImplAddress, - st.SuperchainDeployment.ProtocolVersionsProxyAddress, - st.SuperchainDeployment.ProtocolVersionsImplAddress, + addrs := []struct { + name string + addr common.Address + }{ + {"SuperchainProxyAdmin", st.SuperchainDeployment.ProxyAdminAddress}, + {"SuperchainConfigProxy", st.SuperchainDeployment.SuperchainConfigProxyAddress}, + {"SuperchainConfigImpl", st.SuperchainDeployment.SuperchainConfigImplAddress}, + {"ProtocolVersionsProxy", st.SuperchainDeployment.ProtocolVersionsProxyAddress}, + {"ProtocolVersionsImpl", st.SuperchainDeployment.ProtocolVersionsImplAddress}, + {"Opsm", st.ImplementationsDeployment.OpsmAddress}, + {"DelayedWETHImpl", st.ImplementationsDeployment.DelayedWETHImplAddress}, + {"OptimismPortalImpl", st.ImplementationsDeployment.OptimismPortalImplAddress}, + {"PreimageOracleSingleton", st.ImplementationsDeployment.PreimageOracleSingletonAddress}, + {"MipsSingleton", st.ImplementationsDeployment.MipsSingletonAddress}, + {"SystemConfigImpl", st.ImplementationsDeployment.SystemConfigImplAddress}, + {"L1CrossDomainMessengerImpl", st.ImplementationsDeployment.L1CrossDomainMessengerImplAddress}, + {"L1ERC721BridgeImpl", st.ImplementationsDeployment.L1ERC721BridgeImplAddress}, + {"L1StandardBridgeImpl", st.ImplementationsDeployment.L1StandardBridgeImplAddress}, + {"OptimismMintableERC20FactoryImpl", st.ImplementationsDeployment.OptimismMintableERC20FactoryImplAddress}, + {"DisputeGameFactoryImpl", st.ImplementationsDeployment.DisputeGameFactoryImplAddress}, } for _, addr := range addrs { - code, err := l1Client.CodeAt(ctx, addr, nil) - require.NoError(t, err) - require.NotEmpty(t, code) + t.Run(addr.name, func(t *testing.T) { + code, err := l1Client.CodeAt(ctx, addr.addr, nil) + require.NoError(t, err) + require.NotEmpty(t, code, "contracts %s at %s has no code", addr.name, addr.addr) + }) + } + + for _, chainState := range st.Chains { + chainAddrs := []struct { + name string + addr common.Address + }{ + {"ProxyAdminAddress", chainState.ProxyAdminAddress}, + {"AddressManagerAddress", chainState.AddressManagerAddress}, + {"L1ERC721BridgeProxyAddress", chainState.L1ERC721BridgeProxyAddress}, + {"SystemConfigProxyAddress", chainState.SystemConfigProxyAddress}, + {"OptimismMintableERC20FactoryProxyAddress", chainState.OptimismMintableERC20FactoryProxyAddress}, + {"L1StandardBridgeProxyAddress", chainState.L1StandardBridgeProxyAddress}, + {"L1CrossDomainMessengerProxyAddress", chainState.L1CrossDomainMessengerProxyAddress}, + {"OptimismPortalProxyAddress", chainState.OptimismPortalProxyAddress}, + {"DisputeGameFactoryProxyAddress", chainState.DisputeGameFactoryProxyAddress}, + {"DisputeGameFactoryImplAddress", chainState.DisputeGameFactoryImplAddress}, + {"AnchorStateRegistryProxyAddress", chainState.AnchorStateRegistryProxyAddress}, + {"AnchorStateRegistryImplAddress", chainState.AnchorStateRegistryImplAddress}, + {"FaultDisputeGameAddress", chainState.FaultDisputeGameAddress}, + {"PermissionedDisputeGameAddress", chainState.PermissionedDisputeGameAddress}, + {"DelayedWETHPermissionedGameProxyAddress", chainState.DelayedWETHPermissionedGameProxyAddress}, + {"DelayedWETHPermissionlessGameProxyAddress", chainState.DelayedWETHPermissionlessGameProxyAddress}, + } + for _, addr := range chainAddrs { + t.Run(fmt.Sprintf("chain %s - %s", chainState.ID, addr.name), func(t *testing.T) { + code, err := l1Client.CodeAt(ctx, addr.addr, nil) + require.NoError(t, err) + require.NotEmpty(t, code, "contracts %s at %s for chain %s has no code", addr.name, addr.addr, chainState.ID) + }) + } } } diff --git a/op-chain-ops/interopgen/deployers/implementations.go b/op-chain-ops/deployer/opsm/implementations.go similarity index 67% rename from op-chain-ops/interopgen/deployers/implementations.go rename to op-chain-ops/deployer/opsm/implementations.go index 29a1fb6dee99..d5b576fb9cb6 100644 --- a/op-chain-ops/interopgen/deployers/implementations.go +++ b/op-chain-ops/deployer/opsm/implementations.go @@ -1,4 +1,4 @@ -package deployers +package opsm import ( "fmt" @@ -19,8 +19,9 @@ type DeployImplementationsInput struct { Release string SuperchainConfigProxy common.Address ProtocolVersionsProxy common.Address - SuperchainProxyAdmin common.Address UseInterop bool // if true, deploy Interop implementations + + SuperchainProxyAdmin common.Address } func (input *DeployImplementationsInput) InputSet() bool { @@ -49,21 +50,24 @@ type DeployImplementationsScript struct { Run func(input, output common.Address) error } -func DeployImplementations(l1Host *script.Host, input *DeployImplementationsInput) (*DeployImplementationsOutput, error) { - output := &DeployImplementationsOutput{} - inputAddr := l1Host.NewScriptAddress() - outputAddr := l1Host.NewScriptAddress() +func DeployImplementations( + host *script.Host, + input DeployImplementationsInput, +) (DeployImplementationsOutput, error) { + var output DeployImplementationsOutput + inputAddr := host.NewScriptAddress() + outputAddr := host.NewScriptAddress() - cleanupInput, err := script.WithPrecompileAtAddress[*DeployImplementationsInput](l1Host, inputAddr, input) + cleanupInput, err := script.WithPrecompileAtAddress[*DeployImplementationsInput](host, inputAddr, &input) if err != nil { - return nil, fmt.Errorf("failed to insert DeployImplementationsInput precompile: %w", err) + return output, fmt.Errorf("failed to insert DeployImplementationsInput precompile: %w", err) } defer cleanupInput() - cleanupOutput, err := script.WithPrecompileAtAddress[*DeployImplementationsOutput](l1Host, outputAddr, output, + cleanupOutput, err := script.WithPrecompileAtAddress[*DeployImplementationsOutput](host, outputAddr, &output, script.WithFieldSetter[*DeployImplementationsOutput]) if err != nil { - return nil, fmt.Errorf("failed to insert DeployImplementationsOutput precompile: %w", err) + return output, fmt.Errorf("failed to insert DeployImplementationsOutput precompile: %w", err) } defer cleanupOutput() @@ -71,9 +75,9 @@ func DeployImplementations(l1Host *script.Host, input *DeployImplementationsInpu if input.UseInterop { implContract = "DeployImplementationsInterop" } - deployScript, cleanupDeploy, err := script.WithScript[DeployImplementationsScript](l1Host, "DeployImplementations.s.sol", implContract) + deployScript, cleanupDeploy, err := script.WithScript[DeployImplementationsScript](host, "DeployImplementations.s.sol", implContract) if err != nil { - return nil, fmt.Errorf("failed to load %s script: %w", implContract, err) + return output, fmt.Errorf("failed to load %s script: %w", implContract, err) } defer cleanupDeploy() @@ -81,8 +85,8 @@ func DeployImplementations(l1Host *script.Host, input *DeployImplementationsInpu if input.UseInterop { opsmContract = "OPStackManagerInterop" } - if err := l1Host.RememberOnLabel("OPStackManager", opsmContract+".sol", opsmContract); err != nil { - return nil, fmt.Errorf("failed to link OPStackManager label: %w", err) + if err := host.RememberOnLabel("OPStackManager", opsmContract+".sol", opsmContract); err != nil { + return output, fmt.Errorf("failed to link OPStackManager label: %w", err) } // So we can see in detail where the SystemConfig interop initializer fails @@ -90,12 +94,12 @@ func DeployImplementations(l1Host *script.Host, input *DeployImplementationsInpu if input.UseInterop { sysConfig = "SystemConfigInterop" } - if err := l1Host.RememberOnLabel("SystemConfigImpl", sysConfig+".sol", sysConfig); err != nil { - return nil, fmt.Errorf("failed to link SystemConfig label: %w", err) + if err := host.RememberOnLabel("SystemConfigImpl", sysConfig+".sol", sysConfig); err != nil { + return output, fmt.Errorf("failed to link SystemConfig label: %w", err) } if err := deployScript.Run(inputAddr, outputAddr); err != nil { - return nil, fmt.Errorf("failed to run %s script: %w", implContract, err) + return output, fmt.Errorf("failed to run %s script: %w", implContract, err) } return output, nil diff --git a/op-chain-ops/interopgen/deployers/opchain.go b/op-chain-ops/deployer/opsm/opchain.go similarity index 76% rename from op-chain-ops/interopgen/deployers/opchain.go rename to op-chain-ops/deployer/opsm/opchain.go index 184ccc946bf0..6bab3fdbfe75 100644 --- a/op-chain-ops/interopgen/deployers/opchain.go +++ b/op-chain-ops/deployer/opsm/opchain.go @@ -1,4 +1,4 @@ -package deployers +package opsm import ( "fmt" @@ -35,6 +35,7 @@ type DeployOPChainOutput struct { OptimismMintableERC20FactoryProxy common.Address L1StandardBridgeProxy common.Address L1CrossDomainMessengerProxy common.Address + // Fault proof contracts below. OptimismPortalProxy common.Address DisputeGameFactoryProxy common.Address @@ -55,33 +56,33 @@ type DeployOPChainScript struct { Run func(input, output common.Address) error } -func DeployOPChain(l1Host *script.Host, input *DeployOPChainInput) (*DeployOPChainOutput, error) { - output := &DeployOPChainOutput{} - inputAddr := l1Host.NewScriptAddress() - outputAddr := l1Host.NewScriptAddress() +func DeployOPChain(host *script.Host, input DeployOPChainInput) (DeployOPChainOutput, error) { + var dco DeployOPChainOutput + inputAddr := host.NewScriptAddress() + outputAddr := host.NewScriptAddress() - cleanupInput, err := script.WithPrecompileAtAddress[*DeployOPChainInput](l1Host, inputAddr, input) + cleanupInput, err := script.WithPrecompileAtAddress[*DeployOPChainInput](host, inputAddr, &input) if err != nil { - return nil, fmt.Errorf("failed to insert DeployOPChainInput precompile: %w", err) + return dco, fmt.Errorf("failed to insert DeployOPChainInput precompile: %w", err) } defer cleanupInput() - cleanupOutput, err := script.WithPrecompileAtAddress[*DeployOPChainOutput](l1Host, outputAddr, output, + cleanupOutput, err := script.WithPrecompileAtAddress[*DeployOPChainOutput](host, outputAddr, &dco, script.WithFieldSetter[*DeployOPChainOutput]) if err != nil { - return nil, fmt.Errorf("failed to insert DeployOPChainOutput precompile: %w", err) + return dco, fmt.Errorf("failed to insert DeployOPChainOutput precompile: %w", err) } defer cleanupOutput() - deployScript, cleanupDeploy, err := script.WithScript[DeployOPChainScript](l1Host, "DeployOPChain.s.sol", "DeployOPChain") + deployScript, cleanupDeploy, err := script.WithScript[DeployOPChainScript](host, "DeployOPChain.s.sol", "DeployOPChain") if err != nil { - return nil, fmt.Errorf("failed to load DeployOPChain script: %w", err) + return dco, fmt.Errorf("failed to load DeployOPChain script: %w", err) } defer cleanupDeploy() if err := deployScript.Run(inputAddr, outputAddr); err != nil { - return nil, fmt.Errorf("failed to run DeployOPChain script: %w", err) + return dco, fmt.Errorf("failed to run DeployOPChain script: %w", err) } - return output, nil + return dco, nil } diff --git a/op-chain-ops/deployer/opsm/superchain.go b/op-chain-ops/deployer/opsm/superchain.go index 99adb77817e1..0505d34760a9 100644 --- a/op-chain-ops/deployer/opsm/superchain.go +++ b/op-chain-ops/deployer/opsm/superchain.go @@ -1,11 +1,9 @@ package opsm import ( - "context" "fmt" "math/big" - "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/broadcaster" "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" "github.com/ethereum-optimism/optimism/op-chain-ops/script" opcrypto "github.com/ethereum-optimism/optimism/op-service/crypto" @@ -29,11 +27,11 @@ func (dsi *DeploySuperchainInput) InputSet() bool { } type DeploySuperchainOutput struct { - SuperchainProxyAdmin common.Address `toml:"superchainProxyAdmin"` - SuperchainConfigImpl common.Address `toml:"superchainConfigImpl"` - SuperchainConfigProxy common.Address `toml:"superchainConfigProxy"` - ProtocolVersionsImpl common.Address `toml:"protocolVersionsImpl"` - ProtocolVersionsProxy common.Address `toml:"protocolVersionsProxy"` + SuperchainProxyAdmin common.Address + SuperchainConfigImpl common.Address + SuperchainConfigProxy common.Address + ProtocolVersionsImpl common.Address + ProtocolVersionsProxy common.Address } func (output *DeploySuperchainOutput) CheckOutput() error { @@ -54,46 +52,13 @@ type DeploySuperchainOpts struct { Logger log.Logger } -func DeploySuperchainForge(ctx context.Context, opts DeploySuperchainOpts) (DeploySuperchainOutput, error) { +func DeploySuperchain(h *script.Host, input DeploySuperchainInput) (DeploySuperchainOutput, error) { var dso DeploySuperchainOutput - bcaster, err := broadcaster.NewKeyedBroadcaster(broadcaster.KeyedBroadcasterOpts{ - Logger: opts.Logger, - ChainID: opts.ChainID, - Client: opts.Client, - Signer: opts.Signer, - From: opts.Deployer, - }) - if err != nil { - return dso, fmt.Errorf("failed to create broadcaster: %w", err) - } - - scriptCtx := script.DefaultContext - scriptCtx.Sender = opts.Deployer - scriptCtx.Origin = opts.Deployer - artifacts := &foundry.ArtifactsFS{FS: opts.ArtifactsFS} - h := script.NewHost( - opts.Logger, - artifacts, - nil, - scriptCtx, - script.WithBroadcastHook(bcaster.Hook), - script.WithIsolatedBroadcasts(), - ) - - if err := h.EnableCheats(); err != nil { - return dso, fmt.Errorf("failed to enable cheats: %w", err) - } - - nonce, err := opts.Client.NonceAt(ctx, opts.Deployer, nil) - if err != nil { - return dso, fmt.Errorf("failed to get deployer nonce: %w", err) - } - inputAddr := h.NewScriptAddress() outputAddr := h.NewScriptAddress() - cleanupInput, err := script.WithPrecompileAtAddress[*DeploySuperchainInput](h, inputAddr, &opts.Input) + cleanupInput, err := script.WithPrecompileAtAddress[*DeploySuperchainInput](h, inputAddr, &input) if err != nil { return dso, fmt.Errorf("failed to insert DeploySuperchainInput precompile: %w", err) } @@ -116,17 +81,9 @@ func DeploySuperchainForge(ctx context.Context, opts DeploySuperchainOpts) (Depl } defer cleanupDeploy() - h.SetNonce(opts.Deployer, nonce) - - opts.Logger.Info("deployer nonce", "nonce", nonce) - if err := deployScript.Run(inputAddr, outputAddr); err != nil { return dso, fmt.Errorf("failed to run DeploySuperchain script: %w", err) } - if _, err := bcaster.Broadcast(ctx); err != nil { - return dso, fmt.Errorf("failed to broadcast transactions: %w", err) - } - return dso, nil } diff --git a/op-chain-ops/deployer/pipeline/host.go b/op-chain-ops/deployer/pipeline/host.go new file mode 100644 index 000000000000..f62a2ee8bfae --- /dev/null +++ b/op-chain-ops/deployer/pipeline/host.go @@ -0,0 +1,70 @@ +package pipeline + +import ( + "context" + "fmt" + "math/big" + + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/broadcaster" + "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" + "github.com/ethereum-optimism/optimism/op-chain-ops/script" + opcrypto "github.com/ethereum-optimism/optimism/op-service/crypto" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" +) + +type CallScriptBroadcastOpts struct { + L1ChainID *big.Int + Logger log.Logger + ArtifactsFS foundry.StatDirFs + Deployer common.Address + Signer opcrypto.SignerFn + Client *ethclient.Client + Handler func(host *script.Host) error +} + +func CallScriptBroadcast( + ctx context.Context, + opts CallScriptBroadcastOpts, +) error { + bcaster, err := broadcaster.NewKeyedBroadcaster(broadcaster.KeyedBroadcasterOpts{ + Logger: opts.Logger, + ChainID: opts.L1ChainID, + Client: opts.Client, + Signer: opts.Signer, + From: opts.Deployer, + }) + if err != nil { + return fmt.Errorf("failed to create broadcaster: %w", err) + } + + scriptCtx := script.DefaultContext + scriptCtx.Sender = opts.Deployer + scriptCtx.Origin = opts.Deployer + artifacts := &foundry.ArtifactsFS{FS: opts.ArtifactsFS} + h := script.NewHost( + opts.Logger, + artifacts, + nil, + scriptCtx, + script.WithBroadcastHook(bcaster.Hook), + script.WithIsolatedBroadcasts(), + script.WithCreate2Deployer(), + ) + + if err := h.EnableCheats(); err != nil { + return fmt.Errorf("failed to enable cheats: %w", err) + } + + err = opts.Handler(h) + if err != nil { + return fmt.Errorf("failed to run handler: %w", err) + } + + if _, err := bcaster.Broadcast(ctx); err != nil { + return fmt.Errorf("failed to broadcast: %w", err) + } + + return nil +} diff --git a/op-chain-ops/deployer/pipeline/implementations.go b/op-chain-ops/deployer/pipeline/implementations.go new file mode 100644 index 000000000000..e315dc6fbf1d --- /dev/null +++ b/op-chain-ops/deployer/pipeline/implementations.go @@ -0,0 +1,101 @@ +package pipeline + +import ( + "context" + "fmt" + "math/big" + "os" + + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opsm" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" + "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" + "github.com/ethereum-optimism/optimism/op-chain-ops/script" +) + +func DeployImplementations(ctx context.Context, env *Env, intent *state.Intent, st *state.State) error { + lgr := env.Logger.New("stage", "deploy-implementations") + + if !shouldDeployImplementations(intent, st) { + lgr.Info("implementations deployment not needed") + return nil + } + + lgr.Info("deploying implementations") + + var artifactsFS foundry.StatDirFs + var err error + if intent.ContractArtifactsURL.Scheme == "file" { + fs := os.DirFS(intent.ContractArtifactsURL.Path) + artifactsFS = fs.(foundry.StatDirFs) + } else { + return fmt.Errorf("only file:// artifacts URLs are supported") + } + + var dump *foundry.ForgeAllocs + var dio opsm.DeployImplementationsOutput + err = CallScriptBroadcast( + ctx, + CallScriptBroadcastOpts{ + L1ChainID: big.NewInt(int64(intent.L1ChainID)), + Logger: lgr, + ArtifactsFS: artifactsFS, + Deployer: env.Deployer, + Signer: env.Signer, + Client: env.L1Client, + Handler: func(host *script.Host) error { + host.SetEnvVar("IMPL_SALT", st.Create2Salt.Hex()[2:]) + host.ImportState(st.SuperchainDeployment.StateDump) + dio, err = opsm.DeployImplementations( + host, + opsm.DeployImplementationsInput{ + WithdrawalDelaySeconds: big.NewInt(604800), + MinProposalSizeBytes: big.NewInt(126000), + ChallengePeriodSeconds: big.NewInt(86400), + ProofMaturityDelaySeconds: big.NewInt(604800), + DisputeGameFinalityDelaySeconds: big.NewInt(302400), + Release: "op-contracts/v1.6.0", + SuperchainConfigProxy: st.SuperchainDeployment.SuperchainConfigProxyAddress, + ProtocolVersionsProxy: st.SuperchainDeployment.ProtocolVersionsProxyAddress, + SuperchainProxyAdmin: st.SuperchainDeployment.ProxyAdminAddress, + UseInterop: false, + }, + ) + if err != nil { + return fmt.Errorf("error deploying implementations: %w", err) + } + dump, err = host.StateDump() + if err != nil { + return fmt.Errorf("error dumping state: %w", err) + } + return nil + }, + }, + ) + if err != nil { + return fmt.Errorf("error deploying implementations: %w", err) + } + + st.ImplementationsDeployment = &state.ImplementationsDeployment{ + OpsmAddress: dio.Opsm, + DelayedWETHImplAddress: dio.DelayedWETHImpl, + OptimismPortalImplAddress: dio.OptimismPortalImpl, + PreimageOracleSingletonAddress: dio.PreimageOracleSingleton, + MipsSingletonAddress: dio.MipsSingleton, + SystemConfigImplAddress: dio.SystemConfigImpl, + L1CrossDomainMessengerImplAddress: dio.L1CrossDomainMessengerImpl, + L1ERC721BridgeImplAddress: dio.L1ERC721BridgeImpl, + L1StandardBridgeImplAddress: dio.L1StandardBridgeImpl, + OptimismMintableERC20FactoryImplAddress: dio.OptimismMintableERC20FactoryImpl, + DisputeGameFactoryImplAddress: dio.DisputeGameFactoryImpl, + StateDump: dump, + } + if err := env.WriteState(st); err != nil { + return err + } + + return nil +} + +func shouldDeployImplementations(intent *state.Intent, st *state.State) bool { + return st.ImplementationsDeployment == nil +} diff --git a/op-chain-ops/deployer/pipeline/init.go b/op-chain-ops/deployer/pipeline/init.go index 9f4227f856b0..55cbe9793d6a 100644 --- a/op-chain-ops/deployer/pipeline/init.go +++ b/op-chain-ops/deployer/pipeline/init.go @@ -2,8 +2,11 @@ package pipeline import ( "context" + "crypto/rand" "fmt" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" ) @@ -20,6 +23,13 @@ func Init(ctx context.Context, env *Env, intent *state.Intent, st *state.State) return fmt.Errorf("unsupported state version: %d", st.Version) } + if st.Create2Salt == (common.Hash{}) { + _, err := rand.Read(st.Create2Salt[:]) + if err != nil { + return fmt.Errorf("failed to generate CREATE2 salt: %w", err) + } + } + // If the state has never been applied, we don't need to perform // any additional checks. if st.AppliedIntent == nil { diff --git a/op-chain-ops/deployer/pipeline/opchain.go b/op-chain-ops/deployer/pipeline/opchain.go new file mode 100644 index 000000000000..6a27ded2d520 --- /dev/null +++ b/op-chain-ops/deployer/pipeline/opchain.go @@ -0,0 +1,110 @@ +package pipeline + +import ( + "context" + "fmt" + "math/big" + "os" + + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opsm" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" + "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" + "github.com/ethereum-optimism/optimism/op-chain-ops/script" + "github.com/ethereum/go-ethereum/common" +) + +func DeployOPChain(ctx context.Context, env *Env, intent *state.Intent, st *state.State, chainID common.Hash) error { + lgr := env.Logger.New("stage", "deploy-opchain") + + if !shouldDeployOPChain(intent, st, chainID) { + lgr.Info("opchain deployment not needed") + return nil + } + + lgr.Info("deploying OP chain", "id", chainID.Hex()) + + var artifactsFS foundry.StatDirFs + var err error + if intent.ContractArtifactsURL.Scheme == "file" { + fs := os.DirFS(intent.ContractArtifactsURL.Path) + artifactsFS = fs.(foundry.StatDirFs) + } else { + return fmt.Errorf("only file:// artifacts URLs are supported") + } + + thisIntent, err := intent.Chain(chainID) + if err != nil { + return fmt.Errorf("failed to get chain intent: %w", err) + } + + var dco opsm.DeployOPChainOutput + err = CallScriptBroadcast( + ctx, + CallScriptBroadcastOpts{ + L1ChainID: big.NewInt(int64(intent.L1ChainID)), + Logger: lgr, + ArtifactsFS: artifactsFS, + Deployer: env.Deployer, + Signer: env.Signer, + Client: env.L1Client, + Handler: func(host *script.Host) error { + host.ImportState(st.ImplementationsDeployment.StateDump) + dco, err = opsm.DeployOPChain( + host, + opsm.DeployOPChainInput{ + OpChainProxyAdminOwner: thisIntent.Roles.ProxyAdminOwner, + SystemConfigOwner: thisIntent.Roles.SystemConfigOwner, + Batcher: thisIntent.Roles.Batcher, + UnsafeBlockSigner: thisIntent.Roles.UnsafeBlockSigner, + Proposer: thisIntent.Roles.Proposer, + Challenger: thisIntent.Roles.Challenger, + BasefeeScalar: 1368, + BlobBaseFeeScalar: 801949, + L2ChainId: chainID.Big(), + Opsm: st.ImplementationsDeployment.OpsmAddress, + }, + ) + return err + }, + }, + ) + if err != nil { + return fmt.Errorf("error deploying OP chain: %w", err) + } + + st.Chains = append(st.Chains, state.ChainState{ + ID: chainID, + + ProxyAdminAddress: dco.OpChainProxyAdmin, + AddressManagerAddress: dco.AddressManager, + L1ERC721BridgeProxyAddress: dco.L1ERC721BridgeProxy, + SystemConfigProxyAddress: dco.SystemConfigProxy, + OptimismMintableERC20FactoryProxyAddress: dco.OptimismMintableERC20FactoryProxy, + L1StandardBridgeProxyAddress: dco.L1StandardBridgeProxy, + L1CrossDomainMessengerProxyAddress: dco.L1CrossDomainMessengerProxy, + OptimismPortalProxyAddress: dco.OptimismPortalProxy, + DisputeGameFactoryProxyAddress: dco.DisputeGameFactoryProxy, + DisputeGameFactoryImplAddress: dco.DisputeGameFactoryImpl, + AnchorStateRegistryProxyAddress: dco.AnchorStateRegistryProxy, + AnchorStateRegistryImplAddress: dco.AnchorStateRegistryImpl, + FaultDisputeGameAddress: dco.FaultDisputeGame, + PermissionedDisputeGameAddress: dco.PermissionedDisputeGame, + DelayedWETHPermissionedGameProxyAddress: dco.DelayedWETHPermissionedGameProxy, + DelayedWETHPermissionlessGameProxyAddress: dco.DelayedWETHPermissionlessGameProxy, + }) + if err := env.WriteState(st); err != nil { + return err + } + + return nil +} + +func shouldDeployOPChain(intent *state.Intent, st *state.State, chainID common.Hash) bool { + for _, chain := range st.Chains { + if chain.ID == chainID { + return false + } + } + + return true +} diff --git a/op-chain-ops/deployer/pipeline/superchain.go b/op-chain-ops/deployer/pipeline/superchain.go index 5b44b2ee01c3..3a91c867ff3a 100644 --- a/op-chain-ops/deployer/pipeline/superchain.go +++ b/op-chain-ops/deployer/pipeline/superchain.go @@ -6,14 +6,14 @@ import ( "math/big" "os" + "github.com/ethereum-optimism/optimism/op-chain-ops/script" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opsm" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" "github.com/ethereum-optimism/optimism/op-node/rollup" ) -const DefaultContractsBedrockRepo = "us-docker.pkg.dev/oplabs-tools-artifacts/images/contracts-bedrock" - func DeploySuperchain(ctx context.Context, env *Env, intent *state.Intent, st *state.State) error { lgr := env.Logger.New("stage", "deploy-superchain") @@ -33,23 +33,38 @@ func DeploySuperchain(ctx context.Context, env *Env, intent *state.Intent, st *s return fmt.Errorf("only file:// artifacts URLs are supported") } - dso, err := opsm.DeploySuperchainForge( + var dump *foundry.ForgeAllocs + var dso opsm.DeploySuperchainOutput + err = CallScriptBroadcast( ctx, - opsm.DeploySuperchainOpts{ - Input: opsm.DeploySuperchainInput{ - ProxyAdminOwner: intent.SuperchainRoles.ProxyAdminOwner, - ProtocolVersionsOwner: intent.SuperchainRoles.ProtocolVersionsOwner, - Guardian: intent.SuperchainRoles.Guardian, - Paused: false, - RequiredProtocolVersion: rollup.OPStackSupport, - RecommendedProtocolVersion: rollup.OPStackSupport, - }, + CallScriptBroadcastOpts{ + L1ChainID: big.NewInt(int64(intent.L1ChainID)), + Logger: lgr, ArtifactsFS: artifactsFS, - ChainID: big.NewInt(int64(intent.L1ChainID)), - Client: env.L1Client, - Signer: env.Signer, Deployer: env.Deployer, - Logger: lgr, + Signer: env.Signer, + Client: env.L1Client, + Handler: func(host *script.Host) error { + dso, err = opsm.DeploySuperchain( + host, + opsm.DeploySuperchainInput{ + ProxyAdminOwner: intent.SuperchainRoles.ProxyAdminOwner, + ProtocolVersionsOwner: intent.SuperchainRoles.ProtocolVersionsOwner, + Guardian: intent.SuperchainRoles.Guardian, + Paused: false, + RequiredProtocolVersion: rollup.OPStackSupport, + RecommendedProtocolVersion: rollup.OPStackSupport, + }, + ) + if err != nil { + return fmt.Errorf("failed to deploy superchain: %w", err) + } + dump, err = host.StateDump() + if err != nil { + return fmt.Errorf("error dumping state: %w", err) + } + return nil + }, }, ) if err != nil { @@ -62,8 +77,8 @@ func DeploySuperchain(ctx context.Context, env *Env, intent *state.Intent, st *s SuperchainConfigImplAddress: dso.SuperchainConfigImpl, ProtocolVersionsProxyAddress: dso.ProtocolVersionsProxy, ProtocolVersionsImplAddress: dso.ProtocolVersionsImpl, + StateDump: dump, } - if err := env.WriteState(st); err != nil { return err } @@ -72,13 +87,5 @@ func DeploySuperchain(ctx context.Context, env *Env, intent *state.Intent, st *s } func shouldDeploySuperchain(intent *state.Intent, st *state.State) bool { - if st.AppliedIntent == nil { - return true - } - - if st.SuperchainDeployment == nil { - return true - } - - return false + return st.SuperchainDeployment == nil } diff --git a/op-chain-ops/deployer/state/intent.go b/op-chain-ops/deployer/state/intent.go index 5184a3bb28ef..3c41169e1d45 100644 --- a/op-chain-ops/deployer/state/intent.go +++ b/op-chain-ops/deployer/state/intent.go @@ -24,7 +24,7 @@ type Intent struct { ContractArtifactsURL *ArtifactsURL `json:"contractArtifactsURL" toml:"contractArtifactsURL"` - Chains []Chain `json:"chains" toml:"chains"` + Chains []ChainIntent `json:"chains" toml:"chains"` } func (c Intent) L1ChainIDBig() *big.Int { @@ -62,14 +62,14 @@ func (c Intent) Check() error { return nil } -func (c Intent) Chain(id uint64) (Chain, error) { +func (c Intent) Chain(id common.Hash) (ChainIntent, error) { for i := range c.Chains { if c.Chains[i].ID == id { return c.Chains[i], nil } } - return Chain{}, fmt.Errorf("chain %d not found", id) + return ChainIntent{}, fmt.Errorf("chain %d not found", id) } func (c Intent) WriteToFile(path string) error { @@ -84,32 +84,33 @@ type SuperchainRoles struct { Guardian common.Address `json:"guardian" toml:"guardian"` } -type Chain struct { - ID uint64 `json:"id"` +type ChainIntent struct { + ID common.Hash `json:"id" toml:"id"` - Roles ChainRoles `json:"roles"` + Roles ChainRoles `json:"roles" toml:"roles"` - Overrides map[string]any `json:"overrides"` + Overrides map[string]any `json:"overrides" toml:"overrides"` } type ChainRoles struct { - ProxyAdminOwner common.Address `json:"proxyAdminOwner"` + ProxyAdminOwner common.Address `json:"proxyAdminOwner" toml:"proxyAdminOwner"` - SystemConfigOwner common.Address `json:"systemConfigOwner"` + SystemConfigOwner common.Address `json:"systemConfigOwner" toml:"systemConfigOwner"` - GovernanceTokenOwner common.Address `json:"governanceTokenOwner"` + GovernanceTokenOwner common.Address `json:"governanceTokenOwner" toml:"governanceTokenOwner"` - UnsafeBlockSigner common.Address `json:"unsafeBlockSigner"` + UnsafeBlockSigner common.Address `json:"unsafeBlockSigner" toml:"unsafeBlockSigner"` - Batcher common.Address `json:"batcher"` + Batcher common.Address `json:"batcher" toml:"batcher"` - Proposer common.Address `json:"proposer"` + Proposer common.Address `json:"proposer" toml:"proposer"` - Challenger common.Address `json:"challenger"` + Challenger common.Address `json:"challenger" toml:"challenger"` } -func (c *Chain) Check() error { - if c.ID == 0 { +func (c *ChainIntent) Check() error { + var emptyHash common.Hash + if c.ID == emptyHash { return fmt.Errorf("id must be set") } diff --git a/op-chain-ops/deployer/state/state.go b/op-chain-ops/deployer/state/state.go index 19addf79938d..315f25b64b76 100644 --- a/op-chain-ops/deployer/state/state.go +++ b/op-chain-ops/deployer/state/state.go @@ -1,6 +1,7 @@ package state import ( + "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/ethereum-optimism/optimism/op-service/jsonutil" "github.com/ethereum/go-ethereum/common" @@ -12,6 +13,9 @@ type State struct { // Version versions the state so we can update it later. Version int `json:"version"` + // Create2Salt is the salt used for CREATE2 deployments. + Create2Salt common.Hash `json:"create2Salt"` + // AppliedIntent contains the chain intent that was last // successfully applied. It is diffed against new intent // in order to determine what deployment steps to take. @@ -22,6 +26,13 @@ type State struct { // deployment. It only contains the proxies because the implementations // can be looked up on chain. SuperchainDeployment *SuperchainDeployment `json:"superchainDeployment"` + + // ImplementationsDeployment contains the addresses of the common implementation + // contracts required for the Superchain to function. + ImplementationsDeployment *ImplementationsDeployment `json:"implementationsDeployment"` + + // Chains contains data about L2 chain deployments. + Chains []ChainState `json:"opChainDeployments"` } func (s State) WriteToFile(path string) error { @@ -29,9 +40,46 @@ func (s State) WriteToFile(path string) error { } type SuperchainDeployment struct { - ProxyAdminAddress common.Address `json:"proxyAdminAddress"` - SuperchainConfigProxyAddress common.Address `json:"superchainConfigProxyAddress"` - SuperchainConfigImplAddress common.Address `json:"superchainConfigImplAddress"` - ProtocolVersionsProxyAddress common.Address `json:"protocolVersionsProxyAddress"` - ProtocolVersionsImplAddress common.Address `json:"protocolVersionsImplAddress"` + ProxyAdminAddress common.Address `json:"proxyAdminAddress"` + SuperchainConfigProxyAddress common.Address `json:"superchainConfigProxyAddress"` + SuperchainConfigImplAddress common.Address `json:"superchainConfigImplAddress"` + ProtocolVersionsProxyAddress common.Address `json:"protocolVersionsProxyAddress"` + ProtocolVersionsImplAddress common.Address `json:"protocolVersionsImplAddress"` + StateDump *foundry.ForgeAllocs `json:"stateDump"` +} + +type ImplementationsDeployment struct { + OpsmAddress common.Address `json:"opsmAddress"` + DelayedWETHImplAddress common.Address `json:"delayedWETHImplAddress"` + OptimismPortalImplAddress common.Address `json:"optimismPortalImplAddress"` + PreimageOracleSingletonAddress common.Address `json:"preimageOracleSingletonAddress"` + MipsSingletonAddress common.Address `json:"mipsSingletonAddress"` + SystemConfigImplAddress common.Address `json:"systemConfigImplAddress"` + L1CrossDomainMessengerImplAddress common.Address `json:"l1CrossDomainMessengerImplAddress"` + L1ERC721BridgeImplAddress common.Address `json:"l1ERC721BridgeImplAddress"` + L1StandardBridgeImplAddress common.Address `json:"l1StandardBridgeImplAddress"` + OptimismMintableERC20FactoryImplAddress common.Address `json:"optimismMintableERC20FactoryImplAddress"` + DisputeGameFactoryImplAddress common.Address `json:"disputeGameFactoryImplAddress"` + StateDump *foundry.ForgeAllocs `json:"stateDump"` +} + +type ChainState struct { + ID common.Hash `json:"id"` + + ProxyAdminAddress common.Address `json:"proxyAdminAddress"` + AddressManagerAddress common.Address `json:"addressManagerAddress"` + L1ERC721BridgeProxyAddress common.Address `json:"l1ERC721BridgeProxyAddress"` + SystemConfigProxyAddress common.Address `json:"systemConfigProxyAddress"` + OptimismMintableERC20FactoryProxyAddress common.Address `json:"optimismMintableERC20FactoryProxyAddress"` + L1StandardBridgeProxyAddress common.Address `json:"l1StandardBridgeProxyAddress"` + L1CrossDomainMessengerProxyAddress common.Address `json:"l1CrossDomainMessengerProxyAddress"` + OptimismPortalProxyAddress common.Address `json:"optimismPortalProxyAddress"` + DisputeGameFactoryProxyAddress common.Address `json:"disputeGameFactoryProxyAddress"` + DisputeGameFactoryImplAddress common.Address `json:"disputeGameFactoryImplAddress"` + AnchorStateRegistryProxyAddress common.Address `json:"anchorStateRegistryProxyAddress"` + AnchorStateRegistryImplAddress common.Address `json:"anchorStateRegistryImplAddress"` + FaultDisputeGameAddress common.Address `json:"faultDisputeGameAddress"` + PermissionedDisputeGameAddress common.Address `json:"permissionedDisputeGameAddress"` + DelayedWETHPermissionedGameProxyAddress common.Address `json:"delayedWETHPermissionedGameProxyAddress"` + DelayedWETHPermissionlessGameProxyAddress common.Address `json:"delayedWETHPermissionlessGameProxyAddress"` } diff --git a/op-chain-ops/interopgen/deploy.go b/op-chain-ops/interopgen/deploy.go index 89982a876337..65cb474d9f2b 100644 --- a/op-chain-ops/interopgen/deploy.go +++ b/op-chain-ops/interopgen/deploy.go @@ -5,6 +5,8 @@ import ( "fmt" "math/big" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opsm" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" @@ -147,7 +149,7 @@ func prepareInitialL1(l1Host *script.Host, cfg *L1Config) (*L1Deployment, error) func deploySuperchainToL1(l1Host *script.Host, superCfg *SuperchainConfig) (*SuperchainDeployment, error) { l1Host.SetTxOrigin(superCfg.Deployer) - superDeployment, err := deployers.DeploySuperchain(l1Host, &deployers.DeploySuperchainInput{ + superDeployment, err := opsm.DeploySuperchain(l1Host, opsm.DeploySuperchainInput{ ProxyAdminOwner: superCfg.ProxyAdminOwner, ProtocolVersionsOwner: superCfg.ProtocolVersionsOwner, Guardian: superCfg.SuperchainConfigGuardian, @@ -159,7 +161,7 @@ func deploySuperchainToL1(l1Host *script.Host, superCfg *SuperchainConfig) (*Sup return nil, fmt.Errorf("failed to deploy Superchain contracts: %w", err) } - implementationsDeployment, err := deployers.DeployImplementations(l1Host, &deployers.DeployImplementationsInput{ + implementationsDeployment, err := opsm.DeployImplementations(l1Host, opsm.DeployImplementationsInput{ WithdrawalDelaySeconds: superCfg.Implementations.FaultProof.WithdrawalDelaySeconds, MinProposalSizeBytes: superCfg.Implementations.FaultProof.MinProposalSizeBytes, ChallengePeriodSeconds: superCfg.Implementations.FaultProof.ChallengePeriodSeconds, @@ -178,7 +180,7 @@ func deploySuperchainToL1(l1Host *script.Host, superCfg *SuperchainConfig) (*Sup // Collect deployment addresses // This could all be automatic once we have better output-contract typing/scripting return &SuperchainDeployment{ - Implementations: Implementations(*implementationsDeployment), + Implementations: Implementations(implementationsDeployment), ProxyAdmin: superDeployment.SuperchainProxyAdmin, ProtocolVersions: superDeployment.ProtocolVersionsImpl, ProtocolVersionsProxy: superDeployment.ProtocolVersionsProxy, @@ -194,7 +196,7 @@ func deployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme l1Host.SetTxOrigin(cfg.Deployer) - output, err := deployers.DeployOPChain(l1Host, &deployers.DeployOPChainInput{ + output, err := opsm.DeployOPChain(l1Host, opsm.DeployOPChainInput{ OpChainProxyAdminOwner: cfg.ProxyAdminOwner, SystemConfigOwner: cfg.SystemConfigOwner, Batcher: cfg.BatchSenderAddress, @@ -212,7 +214,7 @@ func deployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme // Collect deployment addresses return &L2Deployment{ - L2OpchainDeployment: L2OpchainDeployment(*output), + L2OpchainDeployment: L2OpchainDeployment(output), }, nil } diff --git a/op-chain-ops/interopgen/deployers/superchain.go b/op-chain-ops/interopgen/deployers/superchain.go deleted file mode 100644 index 60e9805d6711..000000000000 --- a/op-chain-ops/interopgen/deployers/superchain.go +++ /dev/null @@ -1,70 +0,0 @@ -package deployers - -import ( - "fmt" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/params" - - "github.com/ethereum-optimism/optimism/op-chain-ops/script" -) - -type DeploySuperchainInput struct { - ProxyAdminOwner common.Address // TODO(#11783): also used as interop-dependency-set owner - ProtocolVersionsOwner common.Address - Guardian common.Address - Paused bool - RequiredProtocolVersion params.ProtocolVersion - RecommendedProtocolVersion params.ProtocolVersion -} - -func (input *DeploySuperchainInput) InputSet() bool { - return true -} - -type DeploySuperchainOutput struct { - SuperchainProxyAdmin common.Address - SuperchainConfigImpl common.Address - SuperchainConfigProxy common.Address - ProtocolVersionsImpl common.Address - ProtocolVersionsProxy common.Address -} - -func (output *DeploySuperchainOutput) CheckOutput() error { - return nil -} - -type DeploySuperchainScript struct { - Run func(input, output common.Address) error -} - -func DeploySuperchain(l1Host *script.Host, input *DeploySuperchainInput) (*DeploySuperchainOutput, error) { - output := &DeploySuperchainOutput{} - inputAddr := l1Host.NewScriptAddress() - outputAddr := l1Host.NewScriptAddress() - - cleanupInput, err := script.WithPrecompileAtAddress[*DeploySuperchainInput](l1Host, inputAddr, input) - if err != nil { - return nil, fmt.Errorf("failed to insert DeploySuperchainInput precompile: %w", err) - } - defer cleanupInput() - - cleanupOutput, err := script.WithPrecompileAtAddress[*DeploySuperchainOutput](l1Host, outputAddr, output, - script.WithFieldSetter[*DeploySuperchainOutput]) - if err != nil { - return nil, fmt.Errorf("failed to insert DeploySuperchainOutput precompile: %w", err) - } - defer cleanupOutput() - - deployScript, cleanupDeploy, err := script.WithScript[DeploySuperchainScript](l1Host, "DeploySuperchain.s.sol", "DeploySuperchain") - if err != nil { - return nil, fmt.Errorf("failed to load DeploySuperchain script: %w", err) - } - defer cleanupDeploy() - - if err := deployScript.Run(inputAddr, outputAddr); err != nil { - return nil, fmt.Errorf("failed to run DeploySuperchain script: %w", err) - } - - return output, nil -} diff --git a/op-chain-ops/script/script.go b/op-chain-ops/script/script.go index 5bbc0942a52b..d156adb67187 100644 --- a/op-chain-ops/script/script.go +++ b/op-chain-ops/script/script.go @@ -386,6 +386,20 @@ func (h *Host) GetNonce(addr common.Address) uint64 { return h.state.GetNonce(addr) } +// ImportState imports a set of foundry.ForgeAllocs into the +// host's state database. It does not erase existing state +// when importing. +func (h *Host) ImportState(allocs *foundry.ForgeAllocs) { + for addr, alloc := range allocs.Accounts { + h.state.SetBalance(addr, uint256.MustFromBig(alloc.Balance), tracing.BalanceChangeUnspecified) + h.state.SetNonce(addr, alloc.Nonce) + h.state.SetCode(addr, alloc.Code) + for key, value := range alloc.Storage { + h.state.SetState(addr, key, value) + } + } +} + // getPrecompile overrides any accounts during runtime, to insert special precompiles, if activated. func (h *Host) getPrecompile(rules params.Rules, original vm.PrecompiledContract, addr common.Address) vm.PrecompiledContract { if p, ok := h.precompiles[addr]; ok { @@ -436,8 +450,8 @@ func (h *Host) onEnter(depth int, typ byte, from common.Address, to common.Addre return } - // Bump nonce value, such that a broadcast Call appears like a tx - if parentCallFrame.LastOp == vm.CALL { + // Bump nonce value, such that a broadcast Call or CREATE2 appears like a tx + if parentCallFrame.LastOp == vm.CALL || parentCallFrame.LastOp == vm.CREATE2 { sender := parentCallFrame.Ctx.Address() if parentCallFrame.Prank.Sender != nil { sender = *parentCallFrame.Prank.Sender diff --git a/op-chain-ops/script/script_test.go b/op-chain-ops/script/script_test.go index 53415d1f0583..9d029c801060 100644 --- a/op-chain-ops/script/script_test.go +++ b/op-chain-ops/script/script_test.go @@ -164,7 +164,7 @@ func TestScriptBroadcast(t *testing.T) { require.EqualValues(t, 0, h.GetNonce(senderAddr)) require.EqualValues(t, 3, h.GetNonce(scriptAddr)) require.EqualValues(t, 2, h.GetNonce(coffeeAddr)) - // This is zero because the deterministic deployer is the - // address that actually deploys the contract using CREATE2. - require.EqualValues(t, 0, h.GetNonce(cafeAddr)) + // This is one because we still need to bump the nonce of the + // address that will perform the send to the Create2Deployer. + require.EqualValues(t, 1, h.GetNonce(cafeAddr)) } diff --git a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol index f68db7511f5a..5cb6fe9d0c6d 100644 --- a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol +++ b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol @@ -33,6 +33,7 @@ import { OptimismPortalInterop } from "src/L1/OptimismPortalInterop.sol"; import { SystemConfigInterop } from "src/L1/SystemConfigInterop.sol"; import { Blueprint } from "src/libraries/Blueprint.sol"; +import { Config } from "scripts/libraries/Config.sol"; import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; import { Solarray } from "scripts/libraries/Solarray.sol"; @@ -338,7 +339,7 @@ contract DeployImplementations is Script { // First we deploy the blueprints for the singletons deployed by OPSM. // forgefmt: disable-start - bytes32 salt = bytes32(0); + bytes32 salt = keccak256(bytes(Config.implSalt())); OPStackManager.Blueprints memory blueprints; vm.startBroadcast(msg.sender); From 95765dfc72c1e6b6c635b6e65d1825cdb213a0a1 Mon Sep 17 00:00:00 2001 From: mbaxter Date: Mon, 16 Sep 2024 17:38:25 -0400 Subject: [PATCH 153/264] cannon: Handle unaligned futex addresses (#11929) * cannon: Update tests for futex unaligned memory behavior * cannon: Align futex-related addresses when they are set * cannon: Run lint and semver tasks * cannon: Add wakeup traversal tests with unaligend addresses * cannon: Don't panic if ThreadState.FutexAddr is unaligned * cannon: Run semver lock task * cannon: Cleanup stray whitespace --- cannon/mipsevm/multithreaded/mips.go | 14 +-- .../mipsevm/tests/evm_multithreaded_test.go | 96 ++++++++++++------- packages/contracts-bedrock/semver-lock.json | 4 +- .../contracts-bedrock/src/cannon/MIPS2.sol | 16 ++-- 4 files changed, 79 insertions(+), 51 deletions(-) diff --git a/cannon/mipsevm/multithreaded/mips.go b/cannon/mipsevm/multithreaded/mips.go index 89ecadd01366..daa36d05c0ff 100644 --- a/cannon/mipsevm/multithreaded/mips.go +++ b/cannon/mipsevm/multithreaded/mips.go @@ -105,15 +105,16 @@ func (m *InstrumentedState) handleSyscall() error { return nil case exec.SysFutex: // args: a0 = addr, a1 = op, a2 = val, a3 = timeout + effAddr := a0 & 0xFFffFFfc switch a1 { case exec.FutexWaitPrivate: - m.memoryTracker.TrackMemAccess(a0) - mem := m.state.Memory.GetMemory(a0) + m.memoryTracker.TrackMemAccess(effAddr) + mem := m.state.Memory.GetMemory(effAddr) if mem != a2 { v0 = exec.SysErrorSignal v1 = exec.MipsEAGAIN } else { - thread.FutexAddr = a0 + thread.FutexAddr = effAddr thread.FutexVal = a2 if a3 == 0 { thread.FutexTimeoutStep = exec.FutexNoTimeout @@ -126,7 +127,7 @@ func (m *InstrumentedState) handleSyscall() error { case exec.FutexWakePrivate: // Trigger thread traversal starting from the left stack until we find one waiting on the wakeup // address - m.state.Wakeup = a0 + m.state.Wakeup = effAddr // Don't indicate to the program that we've woken up a waiting thread, as there are no guarantees. // The woken up thread should indicate this in userspace. v0 = 0 @@ -255,8 +256,9 @@ func (m *InstrumentedState) mipsStep() error { m.onWaitComplete(thread, true) return nil } else { - m.memoryTracker.TrackMemAccess(thread.FutexAddr) - mem := m.state.Memory.GetMemory(thread.FutexAddr) + effAddr := thread.FutexAddr & 0xFFffFFfc + m.memoryTracker.TrackMemAccess(effAddr) + mem := m.state.Memory.GetMemory(effAddr) if thread.FutexVal == mem { // still got expected value, continue sleeping, try next thread. m.preemptThread(thread) diff --git a/cannon/mipsevm/tests/evm_multithreaded_test.go b/cannon/mipsevm/tests/evm_multithreaded_test.go index f7ead804c707..a26ebe96eb37 100644 --- a/cannon/mipsevm/tests/evm_multithreaded_test.go +++ b/cannon/mipsevm/tests/evm_multithreaded_test.go @@ -654,17 +654,22 @@ func TestEVM_SysFutex_WaitPrivate(t *testing.T) { var tracer *tracing.Hooks cases := []struct { name string - address uint32 + addressParam uint32 + effAddr uint32 targetValue uint32 actualValue uint32 timeout uint32 shouldFail bool shouldSetTimeout bool }{ - {name: "successful wait, no timeout", address: 0x1234, targetValue: 0x01, actualValue: 0x01}, - {name: "memory mismatch, no timeout", address: 0x1200, targetValue: 0x01, actualValue: 0x02, shouldFail: true}, - {name: "successful wait w timeout", address: 0x1234, targetValue: 0x01, actualValue: 0x01, timeout: 1000000, shouldSetTimeout: true}, - {name: "memory mismatch w timeout", address: 0x1200, targetValue: 0x01, actualValue: 0x02, timeout: 2000000, shouldFail: true}, + {name: "successful wait, no timeout", addressParam: 0x1234, effAddr: 0x1234, targetValue: 0x01, actualValue: 0x01}, + {name: "successful wait, no timeout, unaligned addr", addressParam: 0x1235, effAddr: 0x1234, targetValue: 0x01, actualValue: 0x01}, + {name: "memory mismatch, no timeout", addressParam: 0x1200, effAddr: 0x1200, targetValue: 0x01, actualValue: 0x02, shouldFail: true}, + {name: "memory mismatch, no timeout, unaligned", addressParam: 0x1203, effAddr: 0x1200, targetValue: 0x01, actualValue: 0x02, shouldFail: true}, + {name: "successful wait w timeout", addressParam: 0x1234, effAddr: 0x1234, targetValue: 0x01, actualValue: 0x01, timeout: 1000000, shouldSetTimeout: true}, + {name: "successful wait w timeout, unaligned", addressParam: 0x1232, effAddr: 0x1230, targetValue: 0x01, actualValue: 0x01, timeout: 1000000, shouldSetTimeout: true}, + {name: "memory mismatch w timeout", addressParam: 0x1200, effAddr: 0x1200, targetValue: 0x01, actualValue: 0x02, timeout: 2000000, shouldFail: true}, + {name: "memory mismatch w timeout, unaligned", addressParam: 0x120F, effAddr: 0x120C, targetValue: 0x01, actualValue: 0x02, timeout: 2000000, shouldFail: true}, } for i, c := range cases { @@ -673,9 +678,9 @@ func TestEVM_SysFutex_WaitPrivate(t *testing.T) { step := state.GetStep() state.Memory.SetMemory(state.GetPC(), syscallInsn) - state.Memory.SetMemory(c.address, c.actualValue) + state.Memory.SetMemory(c.effAddr, c.actualValue) state.GetRegistersRef()[2] = exec.SysFutex // Set syscall number - state.GetRegistersRef()[4] = c.address + state.GetRegistersRef()[4] = c.addressParam state.GetRegistersRef()[5] = exec.FutexWaitPrivate state.GetRegistersRef()[6] = c.targetValue state.GetRegistersRef()[7] = c.timeout @@ -691,7 +696,7 @@ func TestEVM_SysFutex_WaitPrivate(t *testing.T) { expected.ActiveThread().Registers[7] = exec.MipsEAGAIN } else { // PC and return registers should not update on success, updates happen when wait completes - expected.ActiveThread().FutexAddr = c.address + expected.ActiveThread().FutexAddr = c.effAddr expected.ActiveThread().FutexVal = c.targetValue expected.ActiveThread().FutexTimeoutStep = exec.FutexNoTimeout if c.shouldSetTimeout { @@ -716,18 +721,25 @@ func TestEVM_SysFutex_WakePrivate(t *testing.T) { var tracer *tracing.Hooks cases := []struct { name string - address uint32 + addressParam uint32 + effAddr uint32 activeThreadCount int inactiveThreadCount int traverseRight bool expectTraverseRight bool }{ - {name: "Traverse right", address: 0x6789, activeThreadCount: 2, inactiveThreadCount: 1, traverseRight: true}, - {name: "Traverse right, no left threads", address: 0x6789, activeThreadCount: 2, inactiveThreadCount: 0, traverseRight: true}, - {name: "Traverse right, single thread", address: 0x6789, activeThreadCount: 1, inactiveThreadCount: 0, traverseRight: true}, - {name: "Traverse left", address: 0x6789, activeThreadCount: 2, inactiveThreadCount: 1, traverseRight: false}, - {name: "Traverse left, switch directions", address: 0x6789, activeThreadCount: 1, inactiveThreadCount: 1, traverseRight: false, expectTraverseRight: true}, - {name: "Traverse left, single thread", address: 0x6789, activeThreadCount: 1, inactiveThreadCount: 0, traverseRight: false, expectTraverseRight: true}, + {name: "Traverse right", addressParam: 0x6700, effAddr: 0x6700, activeThreadCount: 2, inactiveThreadCount: 1, traverseRight: true}, + {name: "Traverse right, unaligned addr", addressParam: 0x6789, effAddr: 0x6788, activeThreadCount: 2, inactiveThreadCount: 1, traverseRight: true}, + {name: "Traverse right, no left threads", addressParam: 0x6784, effAddr: 0x6784, activeThreadCount: 2, inactiveThreadCount: 0, traverseRight: true}, + {name: "Traverse right, no left threads, unaligned addr", addressParam: 0x678E, effAddr: 0x678C, activeThreadCount: 2, inactiveThreadCount: 0, traverseRight: true}, + {name: "Traverse right, single thread", addressParam: 0x6788, effAddr: 0x6788, activeThreadCount: 1, inactiveThreadCount: 0, traverseRight: true}, + {name: "Traverse right, single thread, unaligned", addressParam: 0x6789, effAddr: 0x6788, activeThreadCount: 1, inactiveThreadCount: 0, traverseRight: true}, + {name: "Traverse left", addressParam: 0x6788, effAddr: 0x6788, activeThreadCount: 2, inactiveThreadCount: 1, traverseRight: false}, + {name: "Traverse left, unaliagned", addressParam: 0x6789, effAddr: 0x6788, activeThreadCount: 2, inactiveThreadCount: 1, traverseRight: false}, + {name: "Traverse left, switch directions", addressParam: 0x6788, effAddr: 0x6788, activeThreadCount: 1, inactiveThreadCount: 1, traverseRight: false, expectTraverseRight: true}, + {name: "Traverse left, switch directions, unaligned", addressParam: 0x6789, effAddr: 0x6788, activeThreadCount: 1, inactiveThreadCount: 1, traverseRight: false, expectTraverseRight: true}, + {name: "Traverse left, single thread", addressParam: 0x6788, effAddr: 0x6788, activeThreadCount: 1, inactiveThreadCount: 0, traverseRight: false, expectTraverseRight: true}, + {name: "Traverse left, single thread, unaligned", addressParam: 0x6789, effAddr: 0x6788, activeThreadCount: 1, inactiveThreadCount: 0, traverseRight: false, expectTraverseRight: true}, } for i, c := range cases { @@ -738,7 +750,7 @@ func TestEVM_SysFutex_WakePrivate(t *testing.T) { state.Memory.SetMemory(state.GetPC(), syscallInsn) state.GetRegistersRef()[2] = exec.SysFutex // Set syscall number - state.GetRegistersRef()[4] = c.address + state.GetRegistersRef()[4] = c.addressParam state.GetRegistersRef()[5] = exec.FutexWakePrivate // Set up post-state expectations @@ -746,7 +758,7 @@ func TestEVM_SysFutex_WakePrivate(t *testing.T) { expected.ExpectStep() expected.ActiveThread().Registers[2] = 0 expected.ActiveThread().Registers[7] = 0 - expected.Wakeup = c.address + expected.Wakeup = c.effAddr expected.ExpectPreemption(state) expected.TraverseRight = c.expectTraverseRight if c.traverseRight != c.expectTraverseRight { @@ -1192,13 +1204,17 @@ func TestEVM_NormalTraversalStep_HandleWaitingThread(t *testing.T) { {name: "Preempt, no timeout #1", step: 100, activeStackSize: 1, otherStackSize: 0, futexAddr: 0x100, targetValue: 0x01, actualValue: 0x01, timeoutStep: exec.FutexNoTimeout}, {name: "Preempt, no timeout #2", step: 100, activeStackSize: 1, otherStackSize: 1, futexAddr: 0x100, targetValue: 0x01, actualValue: 0x01, timeoutStep: exec.FutexNoTimeout}, {name: "Preempt, no timeout #3", step: 100, activeStackSize: 2, otherStackSize: 1, futexAddr: 0x100, targetValue: 0x01, actualValue: 0x01, timeoutStep: exec.FutexNoTimeout}, + {name: "Preempt, no timeout, unaligned", step: 100, activeStackSize: 2, otherStackSize: 1, futexAddr: 0x101, targetValue: 0x01, actualValue: 0x01, timeoutStep: exec.FutexNoTimeout}, {name: "Preempt, with timeout #1", step: 100, activeStackSize: 2, otherStackSize: 1, futexAddr: 0x100, targetValue: 0x01, actualValue: 0x01, timeoutStep: 101}, {name: "Preempt, with timeout #2", step: 100, activeStackSize: 1, otherStackSize: 1, futexAddr: 0x100, targetValue: 0x01, actualValue: 0x01, timeoutStep: 150}, + {name: "Preempt, with timeout, unaligned", step: 100, activeStackSize: 1, otherStackSize: 1, futexAddr: 0x101, targetValue: 0x01, actualValue: 0x01, timeoutStep: 150}, {name: "Wakeup, no timeout #1", step: 100, activeStackSize: 1, otherStackSize: 0, futexAddr: 0x100, targetValue: 0x01, actualValue: 0x02, timeoutStep: exec.FutexNoTimeout, shouldWakeup: true}, {name: "Wakeup, no timeout #2", step: 100, activeStackSize: 2, otherStackSize: 1, futexAddr: 0x100, targetValue: 0x01, actualValue: 0x02, timeoutStep: exec.FutexNoTimeout, shouldWakeup: true}, + {name: "Wakeup, no timeout, unaligned", step: 100, activeStackSize: 2, otherStackSize: 1, futexAddr: 0x102, targetValue: 0x01, actualValue: 0x02, timeoutStep: exec.FutexNoTimeout, shouldWakeup: true}, {name: "Wakeup with timeout #1", step: 100, activeStackSize: 2, otherStackSize: 1, futexAddr: 0x100, targetValue: 0x01, actualValue: 0x02, timeoutStep: 100, shouldWakeup: true, shouldTimeout: true}, {name: "Wakeup with timeout #2", step: 100, activeStackSize: 2, otherStackSize: 1, futexAddr: 0x100, targetValue: 0x02, actualValue: 0x02, timeoutStep: 100, shouldWakeup: true, shouldTimeout: true}, {name: "Wakeup with timeout #3", step: 100, activeStackSize: 2, otherStackSize: 1, futexAddr: 0x100, targetValue: 0x02, actualValue: 0x02, timeoutStep: 50, shouldWakeup: true, shouldTimeout: true}, + {name: "Wakeup with timeout, unaligned", step: 100, activeStackSize: 2, otherStackSize: 1, futexAddr: 0x103, targetValue: 0x02, actualValue: 0x02, timeoutStep: 50, shouldWakeup: true, shouldTimeout: true}, } for _, c := range cases { @@ -1209,7 +1225,7 @@ func TestEVM_NormalTraversalStep_HandleWaitingThread(t *testing.T) { if !c.shouldWakeup && c.shouldTimeout { require.Fail(t, "Invalid test case - cannot expect a timeout with no wakeup") } - + effAddr := c.futexAddr & 0xFF_FF_FF_Fc goVm, state, contracts := setup(t, i, nil) mttestutil.SetupThreads(int64(i*101), state, traverseRight, c.activeStackSize, c.otherStackSize) state.Step = c.step @@ -1218,7 +1234,7 @@ func TestEVM_NormalTraversalStep_HandleWaitingThread(t *testing.T) { activeThread.FutexAddr = c.futexAddr activeThread.FutexVal = c.targetValue activeThread.FutexTimeoutStep = c.timeoutStep - state.GetMemory().SetMemory(c.futexAddr, c.actualValue) + state.GetMemory().SetMemory(effAddr, c.actualValue) // Set up post-state expectations expected := mttestutil.NewExpectedMTState(state) @@ -1312,11 +1328,12 @@ func TestEVM_NormalTraversal_Full(t *testing.T) { } func TestEVM_WakeupTraversalStep(t *testing.T) { - wakeupAddr := uint32(0x1234) + addr := uint32(0x1234) wakeupVal := uint32(0x999) var tracer *tracing.Hooks cases := []struct { name string + wakeupAddr uint32 futexAddr uint32 targetVal uint32 traverseRight bool @@ -1325,19 +1342,28 @@ func TestEVM_WakeupTraversalStep(t *testing.T) { shouldClearWakeup bool shouldPreempt bool }{ - {name: "Matching addr, not wakeable, first thread", futexAddr: wakeupAddr, targetVal: wakeupVal, traverseRight: false, activeStackSize: 3, otherStackSize: 0, shouldClearWakeup: true}, - {name: "Matching addr, wakeable, first thread", futexAddr: wakeupAddr, targetVal: wakeupVal + 1, traverseRight: false, activeStackSize: 3, otherStackSize: 0, shouldClearWakeup: true}, - {name: "Matching addr, not wakeable, last thread", futexAddr: wakeupAddr, targetVal: wakeupVal, traverseRight: true, activeStackSize: 1, otherStackSize: 2, shouldClearWakeup: true}, - {name: "Matching addr, wakeable, last thread", futexAddr: wakeupAddr, targetVal: wakeupVal + 1, traverseRight: true, activeStackSize: 1, otherStackSize: 2, shouldClearWakeup: true}, - {name: "Matching addr, not wakeable, intermediate thread", futexAddr: wakeupAddr, targetVal: wakeupVal, traverseRight: false, activeStackSize: 2, otherStackSize: 2, shouldClearWakeup: true}, - {name: "Matching addr, wakeable, intermediate thread", futexAddr: wakeupAddr, targetVal: wakeupVal + 1, traverseRight: true, activeStackSize: 2, otherStackSize: 2, shouldClearWakeup: true}, - {name: "Mismatched addr, last thread", futexAddr: wakeupAddr + 4, traverseRight: true, activeStackSize: 1, otherStackSize: 2, shouldPreempt: true, shouldClearWakeup: true}, - {name: "Mismatched addr", futexAddr: wakeupAddr + 4, traverseRight: true, activeStackSize: 2, otherStackSize: 2, shouldPreempt: true}, - {name: "Mismatched addr", futexAddr: wakeupAddr + 4, traverseRight: false, activeStackSize: 2, otherStackSize: 0, shouldPreempt: true}, - {name: "Mismatched addr", futexAddr: wakeupAddr + 4, traverseRight: false, activeStackSize: 1, otherStackSize: 0, shouldPreempt: true}, - {name: "Non-waiting thread", futexAddr: exec.FutexEmptyAddr, traverseRight: false, activeStackSize: 1, otherStackSize: 0, shouldPreempt: true}, - {name: "Non-waiting thread", futexAddr: exec.FutexEmptyAddr, traverseRight: true, activeStackSize: 2, otherStackSize: 1, shouldPreempt: true}, - {name: "Non-waiting thread, last thread", futexAddr: exec.FutexEmptyAddr, traverseRight: true, activeStackSize: 1, otherStackSize: 1, shouldPreempt: true, shouldClearWakeup: true}, + {name: "Matching addr, not wakeable, first thread", wakeupAddr: addr, futexAddr: addr, targetVal: wakeupVal, traverseRight: false, activeStackSize: 3, otherStackSize: 0, shouldClearWakeup: true}, + {name: "Matching addr, wakeable, first thread", wakeupAddr: addr, futexAddr: addr, targetVal: wakeupVal + 1, traverseRight: false, activeStackSize: 3, otherStackSize: 0, shouldClearWakeup: true}, + {name: "Matching addr, not wakeable, last thread", wakeupAddr: addr, futexAddr: addr, targetVal: wakeupVal, traverseRight: true, activeStackSize: 1, otherStackSize: 2, shouldClearWakeup: true}, + {name: "Matching addr, wakeable, last thread", wakeupAddr: addr, futexAddr: addr, targetVal: wakeupVal + 1, traverseRight: true, activeStackSize: 1, otherStackSize: 2, shouldClearWakeup: true}, + {name: "Matching addr, not wakeable, intermediate thread", wakeupAddr: addr, futexAddr: addr, targetVal: wakeupVal, traverseRight: false, activeStackSize: 2, otherStackSize: 2, shouldClearWakeup: true}, + {name: "Matching addr, wakeable, intermediate thread", wakeupAddr: addr, futexAddr: addr, targetVal: wakeupVal + 1, traverseRight: true, activeStackSize: 2, otherStackSize: 2, shouldClearWakeup: true}, + {name: "Mismatched addr, last thread", wakeupAddr: addr, futexAddr: addr + 4, traverseRight: true, activeStackSize: 1, otherStackSize: 2, shouldPreempt: true, shouldClearWakeup: true}, + {name: "Mismatched addr", wakeupAddr: addr, futexAddr: addr + 4, traverseRight: true, activeStackSize: 2, otherStackSize: 2, shouldPreempt: true}, + {name: "Mismatched addr", wakeupAddr: addr, futexAddr: addr + 4, traverseRight: false, activeStackSize: 2, otherStackSize: 0, shouldPreempt: true}, + {name: "Mismatched addr", wakeupAddr: addr, futexAddr: addr + 4, traverseRight: false, activeStackSize: 1, otherStackSize: 0, shouldPreempt: true}, + {name: "Non-waiting thread", wakeupAddr: addr, futexAddr: exec.FutexEmptyAddr, traverseRight: false, activeStackSize: 1, otherStackSize: 0, shouldPreempt: true}, + {name: "Non-waiting thread", wakeupAddr: addr, futexAddr: exec.FutexEmptyAddr, traverseRight: true, activeStackSize: 2, otherStackSize: 1, shouldPreempt: true}, + {name: "Non-waiting thread, last thread", wakeupAddr: addr, futexAddr: exec.FutexEmptyAddr, traverseRight: true, activeStackSize: 1, otherStackSize: 1, shouldPreempt: true, shouldClearWakeup: true}, + // Check behavior of unaligned addresses - should be the same as aligned addresses (no memory access) + {name: "Matching addr, unaligned", wakeupAddr: addr + 1, futexAddr: addr + 1, targetVal: wakeupVal, traverseRight: false, activeStackSize: 3, otherStackSize: 0, shouldClearWakeup: true}, + {name: "Mismatched addr, last thread, wakeup unaligned", wakeupAddr: addr + 1, futexAddr: addr + 4, traverseRight: true, activeStackSize: 1, otherStackSize: 2, shouldPreempt: true, shouldClearWakeup: true}, + {name: "Mismatched addr, last thread, futex unaligned", wakeupAddr: addr, futexAddr: addr + 5, traverseRight: true, activeStackSize: 1, otherStackSize: 2, shouldPreempt: true, shouldClearWakeup: true}, + {name: "Mismatched addr, last thread, wake & futex unaligned", wakeupAddr: addr + 1, futexAddr: addr + 5, traverseRight: true, activeStackSize: 1, otherStackSize: 2, shouldPreempt: true, shouldClearWakeup: true}, + {name: "Mismatched addr, wakeup unaligned", wakeupAddr: addr + 3, futexAddr: addr + 4, traverseRight: true, activeStackSize: 2, otherStackSize: 2, shouldPreempt: true}, + {name: "Mismatched addr, futex unaligned", wakeupAddr: addr, futexAddr: addr + 6, traverseRight: true, activeStackSize: 2, otherStackSize: 2, shouldPreempt: true}, + {name: "Mismatched addr, wakeup & futex unaligned", wakeupAddr: addr + 2, futexAddr: addr + 6, traverseRight: true, activeStackSize: 2, otherStackSize: 2, shouldPreempt: true}, + {name: "Non-waiting thread, last thread, unaligned wakeup", wakeupAddr: addr + 3, futexAddr: exec.FutexEmptyAddr, traverseRight: true, activeStackSize: 1, otherStackSize: 1, shouldPreempt: true, shouldClearWakeup: true}, } for i, c := range cases { @@ -1346,8 +1372,8 @@ func TestEVM_WakeupTraversalStep(t *testing.T) { mttestutil.SetupThreads(int64(i*101), state, c.traverseRight, c.activeStackSize, c.otherStackSize) step := state.Step - state.Wakeup = wakeupAddr - state.GetMemory().SetMemory(wakeupAddr, wakeupVal) + state.Wakeup = c.wakeupAddr + state.GetMemory().SetMemory(c.wakeupAddr&0xFF_FF_FF_FC, wakeupVal) activeThread := state.GetCurrentThread() activeThread.FutexAddr = c.futexAddr activeThread.FutexVal = c.targetVal diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 9846577f0503..d023f61bc244 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -144,8 +144,8 @@ "sourceCodeHash": "0xba4674e1846afbbc708877332a38dfabd4b8d1e48ce07d8ebf0a45c9f27f16b0" }, "src/cannon/MIPS2.sol": { - "initCodeHash": "0xdaed5d70cc84a53f224c28f24f8eef26d5d53dfba9fdc4f1b28c3b231b974e53", - "sourceCodeHash": "0x4026eb7ae7b303ec4c3c2880e14e260dbcfc0b4290459bcd22994cfed8655f80" + "initCodeHash": "0xd9da47f735b7a655a25ae0e867b467620a2cb537eb65d184a361f5ea4174d384", + "sourceCodeHash": "0x3a6d83a7d46eb267f6778f8ae116383fe3c14ad553d90b6c761fafeef22ae29c" }, "src/cannon/PreimageOracle.sol": { "initCodeHash": "0x801e52f9c8439fcf7089575fa93272dfb874641dbfc7d82f36d979c987271c0b", diff --git a/packages/contracts-bedrock/src/cannon/MIPS2.sol b/packages/contracts-bedrock/src/cannon/MIPS2.sol index b9da8fa8cc37..45811d9b46c8 100644 --- a/packages/contracts-bedrock/src/cannon/MIPS2.sol +++ b/packages/contracts-bedrock/src/cannon/MIPS2.sol @@ -57,8 +57,8 @@ contract MIPS2 is ISemver { } /// @notice The semantic version of the MIPS2 contract. - /// @custom:semver 1.0.0-beta.9 - string public constant version = "1.0.0-beta.9"; + /// @custom:semver 1.0.0-beta.10 + string public constant version = "1.0.0-beta.10"; /// @notice The preimage oracle contract. IPreimageOracle internal immutable ORACLE; @@ -175,7 +175,7 @@ contract MIPS2 is ISemver { // Don't allow regular execution until we resolved if we have woken up any thread. if (state.wakeup != sys.FUTEX_EMPTY_ADDR) { if (state.wakeup == thread.futexAddr) { - // completed wake traverssal + // completed wake traversal // resume execution on woken up thread state.wakeup = sys.FUTEX_EMPTY_ADDR; return outputState(); @@ -431,15 +431,15 @@ contract MIPS2 is ISemver { return outputState(); } else if (syscall_no == sys.SYS_FUTEX) { // args: a0 = addr, a1 = op, a2 = val, a3 = timeout + uint32 effAddr = a0 & 0xFFffFFfc; if (a1 == sys.FUTEX_WAIT_PRIVATE) { - uint32 mem = MIPSMemory.readMem( - state.memRoot, a0 & 0xFFffFFfc, MIPSMemory.memoryProofOffset(MEM_PROOF_OFFSET, 1) - ); + uint32 mem = + MIPSMemory.readMem(state.memRoot, effAddr, MIPSMemory.memoryProofOffset(MEM_PROOF_OFFSET, 1)); if (mem != a2) { v0 = sys.SYS_ERROR_SIGNAL; v1 = sys.EAGAIN; } else { - thread.futexAddr = a0; + thread.futexAddr = effAddr; thread.futexVal = a2; thread.futexTimeoutStep = a3 == 0 ? sys.FUTEX_NO_TIMEOUT : state.step + sys.FUTEX_TIMEOUT_STEPS; // Leave cpu scalars as-is. This instruction will be completed by `onWaitComplete` @@ -449,7 +449,7 @@ contract MIPS2 is ISemver { } else if (a1 == sys.FUTEX_WAKE_PRIVATE) { // Trigger thread traversal starting from the left stack until we find one waiting on the wakeup // address - state.wakeup = a0; + state.wakeup = effAddr; // Don't indicate to the program that we've woken up a waiting thread, as there are no guarantees. // The woken up thread should indicate this in userspace. v0 = 0; From d4467a1f5065e6bfe8e10707bea598e817a0f046 Mon Sep 17 00:00:00 2001 From: Axel Kingsley Date: Mon, 16 Sep 2024 17:38:15 -0500 Subject: [PATCH 154/264] Add Logging ; Fix Broken Maintenance Context (#11931) * Add Logging ; Fix Broken Maintenance Context * Remove unneeded timing ; use Testlogger --- op-e2e/interop/interop_test.go | 3 ++ op-e2e/interop/supersystem.go | 7 ++-- op-service/sources/supervisor_client.go | 28 +++++++++++++++ op-supervisor/supervisor/backend/backend.go | 9 +++-- op-supervisor/supervisor/backend/db/db.go | 13 +++++-- .../supervisor/backend/db/db_test.go | 36 ++++++++++++------- .../backend/db/safety_checkers_test.go | 6 ++-- 7 files changed, 79 insertions(+), 23 deletions(-) diff --git a/op-e2e/interop/interop_test.go b/op-e2e/interop/interop_test.go index 04f0081e5f3f..f88ae7b3348e 100644 --- a/op-e2e/interop/interop_test.go +++ b/op-e2e/interop/interop_test.go @@ -53,6 +53,9 @@ func TestInteropTrivial(t *testing.T) { expectedBalance, _ := big.NewInt(0).SetString("10000000000000000000000000", 10) require.Equal(t, expectedBalance, bobBalance) + // sleep for a bit to allow the chain to start + time.Sleep(30 * time.Second) + // send a tx from Alice to Bob s2.SendL2Tx( chainA, diff --git a/op-e2e/interop/supersystem.go b/op-e2e/interop/supersystem.go index c33ac9affc82..24a1265e5e16 100644 --- a/op-e2e/interop/supersystem.go +++ b/op-e2e/interop/supersystem.go @@ -413,7 +413,7 @@ func (s *interopE2ESystem) prepareSupervisor() *supervisor.SupervisorService { ListenEnabled: false, }, LogConfig: oplog.CLIConfig{ - Level: log.LevelTrace, + Level: log.LevelDebug, Format: oplog.FormatText, }, RPC: oprpc.CLIConfig{ @@ -469,9 +469,10 @@ func (s *interopE2ESystem) prepare(t *testing.T, w worldResourcePaths) { s.l2s = s.prepareL2s() // add the L2 RPCs to the supervisor now that the L2s are created + ctx := context.Background() for _, l2 := range s.l2s { - err := s.SupervisorClient().AddL2RPC(context.Background(), l2.l2Geth.UserRPC().RPC()) - require.NoError(s.t, err, "failed to add L2 RPC to supervisor") + err := s.SupervisorClient().AddL2RPC(ctx, l2.l2Geth.UserRPC().RPC()) + require.NoError(s.t, err, "failed to add L2 RPC to supervisor", "error", err) } } diff --git a/op-service/sources/supervisor_client.go b/op-service/sources/supervisor_client.go index 0b0b7a99b2f0..db40e55ef472 100644 --- a/op-service/sources/supervisor_client.go +++ b/op-service/sources/supervisor_client.go @@ -21,6 +21,34 @@ func NewSupervisorClient(client client.RPC) *SupervisorClient { } } +func (cl *SupervisorClient) Stop( + ctx context.Context, +) error { + var result error + err := cl.client.CallContext( + ctx, + &result, + "admin_stop") + if err != nil { + return fmt.Errorf("failed to stop Supervisor: %w", err) + } + return result +} + +func (cl *SupervisorClient) Start( + ctx context.Context, +) error { + var result error + err := cl.client.CallContext( + ctx, + &result, + "admin_start") + if err != nil { + return fmt.Errorf("failed to start Supervisor: %w", err) + } + return result +} + func (cl *SupervisorClient) AddL2RPC( ctx context.Context, rpc string, diff --git a/op-supervisor/supervisor/backend/backend.go b/op-supervisor/supervisor/backend/backend.go index 7b4db31db205..7cf0d960a958 100644 --- a/op-supervisor/supervisor/backend/backend.go +++ b/op-supervisor/supervisor/backend/backend.go @@ -53,7 +53,7 @@ func NewSupervisorBackend(ctx context.Context, logger log.Logger, m Metrics, cfg } // create the chains db - db := db.NewChainsDB(map[types.ChainID]db.LogStorage{}, headTracker) + db := db.NewChainsDB(map[types.ChainID]db.LogStorage{}, headTracker, logger) // create an empty map of chain monitors chainMonitors := make(map[types.ChainID]*source.ChainMonitor, len(cfg.L2RPCs)) @@ -85,6 +85,7 @@ func (su *SupervisorBackend) addFromRPC(ctx context.Context, logger log.Logger, if err != nil { return err } + su.logger.Info("adding from rpc connection", "rpc", rpc, "chainID", chainID) // create metrics and a logdb for the chain cm := newChainMetrics(chainID, su.m) path, err := prepLogDBPath(chainID, su.dataDir) @@ -135,15 +136,17 @@ func (su *SupervisorBackend) Start(ctx context.Context) error { } } // start db maintenance loop - maintinenceCtx, cancel := context.WithCancel(ctx) + maintinenceCtx, cancel := context.WithCancel(context.Background()) su.db.StartCrossHeadMaintenance(maintinenceCtx) su.maintenanceCancel = cancel return nil } +var errAlreadyStopped = errors.New("already stopped") + func (su *SupervisorBackend) Stop(ctx context.Context) error { if !su.started.CompareAndSwap(true, false) { - return errors.New("already stopped") + return errAlreadyStopped } // signal the maintenance loop to stop su.maintenanceCancel() diff --git a/op-supervisor/supervisor/backend/db/db.go b/op-supervisor/supervisor/backend/db/db.go index 27ece73cc77b..7a14870297ab 100644 --- a/op-supervisor/supervisor/backend/db/db.go +++ b/op-supervisor/supervisor/backend/db/db.go @@ -43,12 +43,14 @@ type ChainsDB struct { logDBs map[types.ChainID]LogStorage heads HeadsStorage maintenanceReady chan struct{} + logger log.Logger } -func NewChainsDB(logDBs map[types.ChainID]LogStorage, heads HeadsStorage) *ChainsDB { +func NewChainsDB(logDBs map[types.ChainID]LogStorage, heads HeadsStorage, l log.Logger) *ChainsDB { return &ChainsDB{ logDBs: logDBs, heads: heads, + logger: l, } } @@ -76,17 +78,21 @@ func (db *ChainsDB) Resume() error { // for now it does not prevent multiple instances of this process from running func (db *ChainsDB) StartCrossHeadMaintenance(ctx context.Context) { go func() { + db.logger.Info("cross-head maintenance loop started") // run the maintenance loop every 10 seconds for now - ticker := time.NewTicker(time.Second * 10) + ticker := time.NewTicker(time.Second * 1) for { select { case <-ctx.Done(): + db.logger.Warn("context cancelled, stopping maintenance loop") return case <-ticker.C: + db.logger.Debug("regular maintenance requested") db.RequestMaintenance() case <-db.maintenanceReady: + db.logger.Debug("running maintenance") if err := db.updateAllHeads(); err != nil { - log.Error("failed to update cross-heads", "err", err) + db.logger.Error("failed to update cross-heads", "err", err) } } } @@ -184,6 +190,7 @@ func (db *ChainsDB) UpdateCrossHeadsForChain(chainID types.ChainID, checker Safe // this allows for the maintenance loop to handle cascading updates // instead of waiting for the next scheduled update if updated { + db.logger.Debug("heads were updated, requesting maintenance") db.RequestMaintenance() } return nil diff --git a/op-supervisor/supervisor/backend/db/db_test.go b/op-supervisor/supervisor/backend/db/db_test.go index 4f74fe473d72..71a4c50cf239 100644 --- a/op-supervisor/supervisor/backend/db/db_test.go +++ b/op-supervisor/supervisor/backend/db/db_test.go @@ -6,17 +6,19 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs" backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" + "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/require" ) func TestChainsDB_AddLog(t *testing.T) { t.Run("UnknownChain", func(t *testing.T) { - db := NewChainsDB(nil, &stubHeadStorage{}) + db := NewChainsDB(nil, &stubHeadStorage{}, testlog.Logger(t, log.LevelDebug)) err := db.AddLog(types.ChainIDFromUInt64(2), backendTypes.TruncatedHash{}, eth.BlockID{}, 1234, 33, nil) require.ErrorIs(t, err, ErrUnknownChain) }) @@ -26,7 +28,8 @@ func TestChainsDB_AddLog(t *testing.T) { logDB := &stubLogDB{} db := NewChainsDB(map[types.ChainID]LogStorage{ chainID: logDB, - }, &stubHeadStorage{}) + }, &stubHeadStorage{}, + testlog.Logger(t, log.LevelDebug)) err := db.AddLog(chainID, backendTypes.TruncatedHash{}, eth.BlockID{}, 1234, 33, nil) require.NoError(t, err, err) require.Equal(t, 1, logDB.addLogCalls) @@ -35,7 +38,7 @@ func TestChainsDB_AddLog(t *testing.T) { func TestChainsDB_Rewind(t *testing.T) { t.Run("UnknownChain", func(t *testing.T) { - db := NewChainsDB(nil, &stubHeadStorage{}) + db := NewChainsDB(nil, &stubHeadStorage{}, testlog.Logger(t, log.LevelDebug)) err := db.Rewind(types.ChainIDFromUInt64(2), 42) require.ErrorIs(t, err, ErrUnknownChain) }) @@ -45,7 +48,8 @@ func TestChainsDB_Rewind(t *testing.T) { logDB := &stubLogDB{} db := NewChainsDB(map[types.ChainID]LogStorage{ chainID: logDB, - }, &stubHeadStorage{}) + }, &stubHeadStorage{}, + testlog.Logger(t, log.LevelDebug)) err := db.Rewind(chainID, 23) require.NoError(t, err, err) require.EqualValues(t, 23, logDB.headBlockNum) @@ -69,7 +73,8 @@ func TestChainsDB_LastLogInBlock(t *testing.T) { db := NewChainsDB( map[types.ChainID]LogStorage{ chainID: logDB}, - &stubHeadStorage{h}) + &stubHeadStorage{h}, + testlog.Logger(t, log.LevelDebug)) // LastLogInBlock is expected to: // 1. get a block iterator for block 10 (stubbed) @@ -98,7 +103,8 @@ func TestChainsDB_LastLogInBlockEOF(t *testing.T) { db := NewChainsDB( map[types.ChainID]LogStorage{ chainID: logDB}, - &stubHeadStorage{h}) + &stubHeadStorage{h}, + testlog.Logger(t, log.LevelDebug)) // LastLogInBlock is expected to: // 1. get a block iterator for block 10 (stubbed) @@ -127,7 +133,8 @@ func TestChainsDB_LastLogInBlockNotFound(t *testing.T) { db := NewChainsDB( map[types.ChainID]LogStorage{ chainID: logDB}, - &stubHeadStorage{h}) + &stubHeadStorage{h}, + testlog.Logger(t, log.LevelDebug)) // LastLogInBlock is expected to: // 1. get a block iterator for block 10 (stubbed) @@ -154,7 +161,8 @@ func TestChainsDB_LastLogInBlockError(t *testing.T) { db := NewChainsDB( map[types.ChainID]LogStorage{ chainID: logDB}, - &stubHeadStorage{h}) + &stubHeadStorage{h}, + testlog.Logger(t, log.LevelDebug)) // LastLogInBlock is expected to: // 1. get a block iterator for block 10 (stubbed) @@ -174,7 +182,8 @@ func TestChainsDB_UpdateCrossHeads(t *testing.T) { db := NewChainsDB( map[types.ChainID]LogStorage{ chainID: logDB}, - &stubHeadStorage{h}) + &stubHeadStorage{h}, + testlog.Logger(t, log.LevelDebug)) // Update cross-heads is expected to: // 1. get a last checkpoint iterator from the logDB (stubbed to be at 15) @@ -198,7 +207,8 @@ func TestChainsDB_UpdateCrossHeadsBeyondLocal(t *testing.T) { db := NewChainsDB( map[types.ChainID]LogStorage{ chainID: logDB}, - &stubHeadStorage{h}) + &stubHeadStorage{h}, + testlog.Logger(t, log.LevelDebug)) // Update cross-heads is expected to: // 1. get a last checkpoint iterator from the logDB (stubbed to be at 15) @@ -224,7 +234,8 @@ func TestChainsDB_UpdateCrossHeadsEOF(t *testing.T) { db := NewChainsDB( map[types.ChainID]LogStorage{ chainID: logDB}, - &stubHeadStorage{h}) + &stubHeadStorage{h}, + testlog.Logger(t, log.LevelDebug)) // Update cross-heads is expected to: // 1. get a last checkpoint iterator from the logDB (stubbed to be at 15) @@ -250,7 +261,8 @@ func TestChainsDB_UpdateCrossHeadsError(t *testing.T) { db := NewChainsDB( map[types.ChainID]LogStorage{ chainID: logDB}, - &stubHeadStorage{h}) + &stubHeadStorage{h}, + testlog.Logger(t, log.LevelDebug)) // Update cross-heads is expected to: // 1. get a last checkpoint iterator from the logDB (stubbed to be at 10) diff --git a/op-supervisor/supervisor/backend/db/safety_checkers_test.go b/op-supervisor/supervisor/backend/db/safety_checkers_test.go index d2303d7ec3e5..0e815bdaccb5 100644 --- a/op-supervisor/supervisor/backend/db/safety_checkers_test.go +++ b/op-supervisor/supervisor/backend/db/safety_checkers_test.go @@ -4,10 +4,12 @@ import ( "fmt" "testing" + "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads" backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" + "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/require" ) @@ -25,7 +27,7 @@ func TestHeadsForChain(t *testing.T) { CrossFinalized: entrydb.EntryIdx(6), } h.Put(types.ChainIDFromUInt64(1), chainHeads) - chainsDB := NewChainsDB(nil, &stubHeadStorage{h}) + chainsDB := NewChainsDB(nil, &stubHeadStorage{h}, testlog.Logger(t, log.LevelDebug)) tcases := []struct { name string chainID types.ChainID @@ -92,7 +94,7 @@ func TestCheck(t *testing.T) { types.ChainIDFromUInt64(1): logDB, } - chainsDB := NewChainsDB(logsStore, &stubHeadStorage{h}) + chainsDB := NewChainsDB(logsStore, &stubHeadStorage{h}, testlog.Logger(t, log.LevelDebug)) tcases := []struct { name string From 8dd6fb36aad7a1cd5c9e7e877b340b2e0c5cc14c Mon Sep 17 00:00:00 2001 From: clabby Date: Mon, 16 Sep 2024 18:39:57 -0400 Subject: [PATCH 155/264] feat(op-e2e): Expose `L1Replica` + `L2Engine` + `BlobsStore` endpoints (#11926) * feat(op-e2e): Expose `L1Replica` + `L2Engine` + `BlobsStore` endpoints * mutex * deterministic blob indexing * proto review * lint --- op-e2e/actions/l1_miner.go | 3 +- op-e2e/actions/l1_replica.go | 4 ++ op-e2e/actions/l2_engine.go | 4 ++ op-e2e/e2eutils/blobs.go | 53 ++++++++++++++++----- op-e2e/e2eutils/fakebeacon/blobs.go | 73 +++++++++++++++++------------ op-e2e/l1_beacon_client_test.go | 7 ++- op-e2e/setup.go | 2 +- 7 files changed, 102 insertions(+), 44 deletions(-) diff --git a/op-e2e/actions/l1_miner.go b/op-e2e/actions/l1_miner.go index e29d09ceb796..c35e38ae63c5 100644 --- a/op-e2e/actions/l1_miner.go +++ b/op-e2e/actions/l1_miner.go @@ -240,7 +240,8 @@ func (s *L1Miner) ActL1EndBlock(t Testing) { for _, sidecar := range s.l1BuildingBlobSidecars { for i, h := range sidecar.BlobHashes() { blob := (*eth.Blob)(&sidecar.Blobs[i]) - s.blobStore.StoreBlob(block.Time(), h, blob) + indexedHash := eth.IndexedBlobHash{Index: uint64(i), Hash: h} + s.blobStore.StoreBlob(block.Time(), indexedHash, blob) } } _, err = s.l1Chain.InsertChain(types.Blocks{block}) diff --git a/op-e2e/actions/l1_replica.go b/op-e2e/actions/l1_replica.go index 83120203ee7b..3f6a27ed541f 100644 --- a/op-e2e/actions/l1_replica.go +++ b/op-e2e/actions/l1_replica.go @@ -168,6 +168,10 @@ func (s *L1Replica) MockL1RPCErrors(fn func() error) { } } +func (s *L1Replica) HTTPEndpoint() string { + return s.node.HTTPEndpoint() +} + func (s *L1Replica) EthClient() *ethclient.Client { cl := s.node.Attach() return ethclient.NewClient(cl) diff --git a/op-e2e/actions/l2_engine.go b/op-e2e/actions/l2_engine.go index 828ede53cade..80d705d854e5 100644 --- a/op-e2e/actions/l2_engine.go +++ b/op-e2e/actions/l2_engine.go @@ -153,6 +153,10 @@ func (s *L2Engine) PeerCount() int { return s.node.Server().PeerCount() } +func (s *L2Engine) HTTPEndpoint() string { + return s.node.HTTPEndpoint() +} + func (s *L2Engine) EthClient() *ethclient.Client { cl := s.node.Attach() return ethclient.NewClient(cl) diff --git a/op-e2e/e2eutils/blobs.go b/op-e2e/e2eutils/blobs.go index ae9ccd562c02..791130470eda 100644 --- a/op-e2e/e2eutils/blobs.go +++ b/op-e2e/e2eutils/blobs.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" @@ -15,20 +14,20 @@ import ( // BlobsStore is a simple in-memory store of blobs, for testing purposes type BlobsStore struct { // block timestamp -> blob versioned hash -> blob - blobs map[uint64]map[common.Hash]*eth.Blob + blobs map[uint64]map[eth.IndexedBlobHash]*eth.Blob } func NewBlobStore() *BlobsStore { - return &BlobsStore{blobs: make(map[uint64]map[common.Hash]*eth.Blob)} + return &BlobsStore{blobs: make(map[uint64]map[eth.IndexedBlobHash]*eth.Blob)} } -func (store *BlobsStore) StoreBlob(blockTime uint64, versionedHash common.Hash, blob *eth.Blob) { +func (store *BlobsStore) StoreBlob(blockTime uint64, indexedHash eth.IndexedBlobHash, blob *eth.Blob) { m, ok := store.blobs[blockTime] if !ok { - m = make(map[common.Hash]*eth.Blob) + m = make(map[eth.IndexedBlobHash]*eth.Blob) store.blobs[blockTime] = m } - m[versionedHash] = blob + m[indexedHash] = blob } func (store *BlobsStore) GetBlobs(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.Blob, error) { @@ -38,7 +37,7 @@ func (store *BlobsStore) GetBlobs(ctx context.Context, ref eth.L1BlockRef, hashe return nil, fmt.Errorf("no blobs known with given time: %w", ethereum.NotFound) } for _, h := range hashes { - b, ok := m[h.Hash] + b, ok := m[h] if !ok { return nil, fmt.Errorf("blob %d %s is not in store: %w", h.Index, h.Hash, ethereum.NotFound) } @@ -54,7 +53,7 @@ func (store *BlobsStore) GetBlobSidecars(ctx context.Context, ref eth.L1BlockRef return nil, fmt.Errorf("no blobs known with given time: %w", ethereum.NotFound) } for _, h := range hashes { - b, ok := m[h.Hash] + b, ok := m[h] if !ok { return nil, fmt.Errorf("blob %d %s is not in store: %w", h.Index, h.Hash, ethereum.NotFound) } @@ -66,15 +65,47 @@ func (store *BlobsStore) GetBlobSidecars(ctx context.Context, ref eth.L1BlockRef if err != nil { return nil, fmt.Errorf("failed to convert blob to commitment: %w", err) } + proof, err := kzg4844.ComputeBlobProof(b.KZGBlob(), commitment) + if err != nil { + return nil, fmt.Errorf("failed to compute blob proof: %w", err) + } out = append(out, ð.BlobSidecar{ Index: eth.Uint64String(h.Index), Blob: *b, KZGCommitment: eth.Bytes48(commitment), + KZGProof: eth.Bytes48(proof), }) } return out, nil } -var ( - _ derive.L1BlobsFetcher = (*BlobsStore)(nil) -) +func (store *BlobsStore) GetAllSidecars(ctx context.Context, l1Timestamp uint64) ([]*eth.BlobSidecar, error) { + m, ok := store.blobs[l1Timestamp] + if !ok { + return nil, fmt.Errorf("no blobs known with given time: %w", ethereum.NotFound) + } + out := make([]*eth.BlobSidecar, len(m)) + for h, b := range m { + if b == nil { + return nil, fmt.Errorf("blob %d %s is nil, cannot copy: %w", h.Index, h.Hash, ethereum.NotFound) + } + + commitment, err := kzg4844.BlobToCommitment(b.KZGBlob()) + if err != nil { + return nil, fmt.Errorf("failed to convert blob to commitment: %w", err) + } + proof, err := kzg4844.ComputeBlobProof(b.KZGBlob(), commitment) + if err != nil { + return nil, fmt.Errorf("failed to compute blob proof: %w", err) + } + out[h.Index] = ð.BlobSidecar{ + Index: eth.Uint64String(h.Index), + Blob: *b, + KZGCommitment: eth.Bytes48(commitment), + KZGProof: eth.Bytes48(proof), + } + } + return out, nil +} + +var _ derive.L1BlobsFetcher = (*BlobsStore)(nil) diff --git a/op-e2e/e2eutils/fakebeacon/blobs.go b/op-e2e/e2eutils/fakebeacon/blobs.go index 6be65bbb3521..a96042bc7add 100644 --- a/op-e2e/e2eutils/fakebeacon/blobs.go +++ b/op-e2e/e2eutils/fakebeacon/blobs.go @@ -1,23 +1,24 @@ package fakebeacon import ( + "context" "encoding/binary" "encoding/json" "errors" "fmt" - "io/fs" "net" "net/http" - "os" - "path/filepath" "strconv" "strings" "sync" "time" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/beacon/engine" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/log" ) @@ -27,8 +28,8 @@ import ( type FakeBeacon struct { log log.Logger - // directory to store blob contents in after the blobs are persisted in a block - blobsDir string + // in-memory blob store + blobStore *e2eutils.BlobsStore blobsLock sync.Mutex beaconSrv *http.Server @@ -38,10 +39,10 @@ type FakeBeacon struct { blockTime uint64 } -func NewBeacon(log log.Logger, blobsDir string, genesisTime uint64, blockTime uint64) *FakeBeacon { +func NewBeacon(log log.Logger, blobStore *e2eutils.BlobsStore, genesisTime uint64, blockTime uint64) *FakeBeacon { return &FakeBeacon{ log: log, - blobsDir: blobsDir, + blobStore: blobStore, genesisTime: genesisTime, blockTime: blockTime, } @@ -158,20 +159,23 @@ func (f *FakeBeacon) Start(addr string) error { } func (f *FakeBeacon) StoreBlobsBundle(slot uint64, bundle *engine.BlobsBundleV1) error { - data, err := json.Marshal(bundle) - if err != nil { - return fmt.Errorf("failed to encode blobs bundle of slot %d: %w", slot, err) - } - f.blobsLock.Lock() defer f.blobsLock.Unlock() - bundlePath := fmt.Sprintf("blobs_bundle_%d.json", slot) - if err := os.MkdirAll(f.blobsDir, 0755); err != nil { - return fmt.Errorf("failed to create dir for blob storage: %w", err) - } - err = os.WriteFile(filepath.Join(f.blobsDir, bundlePath), data, 0755) - if err != nil { - return fmt.Errorf("failed to write blobs bundle of slot %d: %w", slot, err) + + // Solve for the slot timestamp. + // slot = (timestamp - genesis) / slot_time + // timestamp = slot * slot_time + genesis + slotTimestamp := slot*f.blockTime + f.genesisTime + + for i, b := range bundle.Blobs { + f.blobStore.StoreBlob( + slotTimestamp, + eth.IndexedBlobHash{ + Index: uint64(i), + Hash: eth.KZGToVersionedHash(kzg4844.Commitment(bundle.Commitments[i])), + }, + (*eth.Blob)(b[:]), + ) } return nil } @@ -179,19 +183,30 @@ func (f *FakeBeacon) StoreBlobsBundle(slot uint64, bundle *engine.BlobsBundleV1) func (f *FakeBeacon) LoadBlobsBundle(slot uint64) (*engine.BlobsBundleV1, error) { f.blobsLock.Lock() defer f.blobsLock.Unlock() - bundlePath := fmt.Sprintf("blobs_bundle_%d.json", slot) - data, err := os.ReadFile(filepath.Join(f.blobsDir, bundlePath)) + + // Solve for the slot timestamp. + // slot = (timestamp - genesis) / slot_time + // timestamp = slot * slot_time + genesis + slotTimestamp := slot*f.blockTime + f.genesisTime + + // Load blobs from the store + blobs, err := f.blobStore.GetAllSidecars(context.Background(), slotTimestamp) if err != nil { - if errors.Is(err, fs.ErrNotExist) { - return nil, fmt.Errorf("no blobs bundle found for slot %d (%q): %w", slot, bundlePath, ethereum.NotFound) - } else { - return nil, fmt.Errorf("failed to read blobs bundle of slot %d (%q): %w", slot, bundlePath, err) - } + return nil, fmt.Errorf("failed to load blobs from store: %w", err) } - var out engine.BlobsBundleV1 - if err := json.Unmarshal(data, &out); err != nil { - return nil, fmt.Errorf("failed to decode blobs bundle of slot %d (%q): %w", slot, bundlePath, err) + + // Convert blobs to the bundle + out := engine.BlobsBundleV1{ + Commitments: make([]hexutil.Bytes, len(blobs)), + Proofs: make([]hexutil.Bytes, len(blobs)), + Blobs: make([]hexutil.Bytes, len(blobs)), + } + for _, b := range blobs { + out.Commitments[b.Index] = hexutil.Bytes(b.KZGCommitment[:]) + out.Proofs[b.Index] = hexutil.Bytes(b.KZGProof[:]) + out.Blobs[b.Index] = hexutil.Bytes(b.Blob[:]) } + return &out, nil } diff --git a/op-e2e/l1_beacon_client_test.go b/op-e2e/l1_beacon_client_test.go index 93094d4884e7..6d4ffd6207fa 100644 --- a/op-e2e/l1_beacon_client_test.go +++ b/op-e2e/l1_beacon_client_test.go @@ -4,6 +4,7 @@ import ( "context" "testing" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/fakebeacon" "github.com/ethereum-optimism/optimism/op-service/client" "github.com/ethereum-optimism/optimism/op-service/eth" @@ -19,7 +20,8 @@ func TestGetVersion(t *testing.T) { l := testlog.Logger(t, log.LevelInfo) - beaconApi := fakebeacon.NewBeacon(l, t.TempDir(), uint64(0), uint64(0)) + blobStore := e2eutils.NewBlobStore() + beaconApi := fakebeacon.NewBeacon(l, blobStore, uint64(0), uint64(0)) t.Cleanup(func() { _ = beaconApi.Close() }) @@ -38,7 +40,8 @@ func Test404NotFound(t *testing.T) { l := testlog.Logger(t, log.LevelInfo) - beaconApi := fakebeacon.NewBeacon(l, t.TempDir(), uint64(0), uint64(12)) + blobStore := e2eutils.NewBlobStore() + beaconApi := fakebeacon.NewBeacon(l, blobStore, uint64(0), uint64(12)) t.Cleanup(func() { _ = beaconApi.Close() }) diff --git a/op-e2e/setup.go b/op-e2e/setup.go index df7051c50626..e53867fefb06 100644 --- a/op-e2e/setup.go +++ b/op-e2e/setup.go @@ -588,7 +588,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste // Create a fake Beacon node to hold on to blobs created by the L1 miner, and to serve them to L2 bcn := fakebeacon.NewBeacon(testlog.Logger(t, log.LevelInfo).New("role", "l1_cl"), - path.Join(cfg.BlobsPath, "l1_cl"), l1Genesis.Timestamp, cfg.DeployConfig.L1BlockTime) + e2eutils.NewBlobStore(), l1Genesis.Timestamp, cfg.DeployConfig.L1BlockTime) t.Cleanup(func() { _ = bcn.Close() }) From 21375b4ad27aa5484fe02b9b1797d662d11e002a Mon Sep 17 00:00:00 2001 From: protolambda Date: Mon, 16 Sep 2024 17:08:38 -0600 Subject: [PATCH 156/264] op-node: handle crit error events, lift event-system out of driver (#11932) --- op-node/node/node.go | 42 +++++++++++++++++++++++---- op-node/rollup/driver/driver.go | 22 ++++++--------- op-node/rollup/driver/state.go | 24 ---------------- op-node/rollup/event.go | 11 ++------ op-node/rollup/event/events.go | 10 +++++++ op-node/rollup/event/system.go | 19 ++++++++++++- op-node/rollup/event/system_test.go | 44 +++++++++++++++++++++++++++++ 7 files changed, 119 insertions(+), 53 deletions(-) diff --git a/op-node/node/node.go b/op-node/node/node.go index 13142bdf3343..d0853a63a79a 100644 --- a/op-node/node/node.go +++ b/op-node/node/node.go @@ -8,13 +8,11 @@ import ( "sync/atomic" "time" - "github.com/ethereum-optimism/optimism/op-node/rollup/sequencing" - "github.com/hashicorp/go-multierror" "github.com/libp2p/go-libp2p/core/peer" "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/event" + gethevent "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" altda "github.com/ethereum-optimism/optimism/op-alt-da" @@ -24,6 +22,8 @@ import ( "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/conductor" "github.com/ethereum-optimism/optimism/op-node/rollup/driver" + "github.com/ethereum-optimism/optimism/op-node/rollup/event" + "github.com/ethereum-optimism/optimism/op-node/rollup/sequencing" "github.com/ethereum-optimism/optimism/op-node/rollup/sync" "github.com/ethereum-optimism/optimism/op-service/client" "github.com/ethereum-optimism/optimism/op-service/eth" @@ -52,6 +52,9 @@ type OpNode struct { l1SafeSub ethereum.Subscription // Subscription to get L1 safe blocks, a.k.a. justified data (polling) l1FinalizedSub ethereum.Subscription // Subscription to get L1 safe blocks, a.k.a. justified data (polling) + eventSys event.System + eventDrain event.Drainer + l1Source *sources.L1Client // L1 Client to fetch data from l2Driver *driver.Driver // L2 Engine to Sync l2Source *sources.EngineClient // L2 Execution Engine RPC bindings @@ -126,6 +129,7 @@ func (n *OpNode) init(ctx context.Context, cfg *Config) error { if err := n.initTracer(ctx, cfg); err != nil { return fmt.Errorf("failed to init the trace: %w", err) } + n.initEventSystem() if err := n.initL1(ctx, cfg); err != nil { return fmt.Errorf("failed to init L1: %w", err) } @@ -159,6 +163,16 @@ func (n *OpNode) init(ctx context.Context, cfg *Config) error { return nil } +func (n *OpNode) initEventSystem() { + // This executor will be configurable in the future, for parallel event processing + executor := event.NewGlobalSynchronous(n.resourcesCtx) + sys := event.NewSystem(n.log, executor) + sys.AddTracer(event.NewMetricsTracer(n.metrics)) + sys.Register("node", event.DeriverFunc(n.onEvent), event.DefaultRegisterOpts()) + n.eventSys = sys + n.eventDrain = executor +} + func (n *OpNode) initTracer(ctx context.Context, cfg *Config) error { if cfg.Tracer != nil { n.tracer = cfg.Tracer @@ -185,7 +199,7 @@ func (n *OpNode) initL1(ctx context.Context, cfg *Config) error { } // Keep subscribed to the L1 heads, which keeps the L1 maintainer pointing to the best headers to sync - n.l1HeadsSub = event.ResubscribeErr(time.Second*10, func(ctx context.Context, err error) (event.Subscription, error) { + n.l1HeadsSub = gethevent.ResubscribeErr(time.Second*10, func(ctx context.Context, err error) (gethevent.Subscription, error) { if err != nil { n.log.Warn("resubscribing after failed L1 subscription", "err", err) } @@ -410,7 +424,7 @@ func (n *OpNode) initL2(ctx context.Context, cfg *Config) error { } else { n.safeDB = safedb.Disabled } - n.l2Driver = driver.NewDriver(&cfg.Driver, &cfg.Rollup, n.l2Source, n.l1Source, + n.l2Driver = driver.NewDriver(n.eventSys, n.eventDrain, &cfg.Driver, &cfg.Rollup, n.l2Source, n.l1Source, n.supervisor, n.beacon, n, n, n.log, n.metrics, cfg.ConfigPersistence, n.safeDB, &cfg.Sync, sequencerConductor, altDA) return nil } @@ -509,6 +523,20 @@ func (n *OpNode) Start(ctx context.Context) error { return nil } +// onEvent handles broadcast events. +// The OpNode itself is a deriver to catch system-critical events. +// Other event-handling should be encapsulated into standalone derivers. +func (n *OpNode) onEvent(ev event.Event) bool { + switch x := ev.(type) { + case rollup.CriticalErrorEvent: + n.log.Error("Critical error", "err", x.Err) + n.cancel(fmt.Errorf("critical error: %w", x.Err)) + return true + default: + return false + } +} + func (n *OpNode) OnNewL1Head(ctx context.Context, sig eth.L1BlockRef) { n.tracer.OnNewL1Head(ctx, sig) @@ -679,6 +707,10 @@ func (n *OpNode) Stop(ctx context.Context) error { } } + if n.eventSys != nil { + n.eventSys.Stop() + } + if n.safeDB != nil { if err := n.safeDB.Close(); err != nil { result = multierror.Append(result, fmt.Errorf("failed to close safe head db: %w", err)) diff --git a/op-node/rollup/driver/driver.go b/op-node/rollup/driver/driver.go index 8c4c975c87cf..81607e612d5a 100644 --- a/op-node/rollup/driver/driver.go +++ b/op-node/rollup/driver/driver.go @@ -150,8 +150,14 @@ type SequencerStateListener interface { SequencerStopped() error } +type Drain interface { + Drain() error +} + // NewDriver composes an events handler that tracks L1 state, triggers L2 Derivation, and optionally sequences new L2 blocks. func NewDriver( + sys event.Registry, + drain Drain, driverCfg *Config, cfg *rollup.Config, l2 L2Chain, @@ -170,17 +176,6 @@ func NewDriver( ) *Driver { driverCtx, driverCancel := context.WithCancel(context.Background()) - var executor event.Executor - var drain func() error - // This instantiation will be one of more options: soon there will be a parallel events executor - { - s := event.NewGlobalSynchronous(driverCtx) - executor = s - drain = s.Drain - } - sys := event.NewSystem(log, executor) - sys.AddTracer(event.NewMetricsTracer(metrics)) - opts := event.DefaultRegisterOpts() // If interop is scheduled we start the driver. @@ -236,7 +231,7 @@ func NewDriver( L2: l2, Log: log, Ctx: driverCtx, - Drain: drain, + Drain: drain.Drain, } sys.Register("sync", syncDeriver, opts) @@ -260,12 +255,11 @@ func NewDriver( driverEmitter := sys.Register("driver", nil, opts) driver := &Driver{ - eventSys: sys, statusTracker: statusTracker, SyncDeriver: syncDeriver, sched: schedDeriv, emitter: driverEmitter, - drain: drain, + drain: drain.Drain, stateReq: make(chan chan struct{}), forceReset: make(chan chan struct{}, 10), driverConfig: driverCfg, diff --git a/op-node/rollup/driver/state.go b/op-node/rollup/driver/state.go index 73374dbf8055..2840cedcf423 100644 --- a/op-node/rollup/driver/state.go +++ b/op-node/rollup/driver/state.go @@ -26,8 +26,6 @@ import ( type SyncStatus = eth.SyncStatus type Driver struct { - eventSys event.System - statusTracker SyncStatusTracker *SyncDeriver @@ -100,7 +98,6 @@ func (s *Driver) Start() error { func (s *Driver) Close() error { s.driverCancel() s.wg.Wait() - s.eventSys.Stop() s.sequencer.Close() return nil } @@ -282,27 +279,6 @@ func (s *Driver) eventLoop() { } } -// OnEvent handles broadcasted events. -// The Driver itself is a deriver to catch system-critical events. -// Other event-handling should be encapsulated into standalone derivers. -func (s *Driver) OnEvent(ev event.Event) bool { - switch x := ev.(type) { - case rollup.CriticalErrorEvent: - s.Log.Error("Derivation process critical error", "err", x.Err) - // we need to unblock event-processing to be able to close - go func() { - logger := s.Log - err := s.Close() - if err != nil { - logger.Error("Failed to shutdown driver on critical error", "err", err) - } - }() - return true - default: - return false - } -} - type SyncDeriver struct { // The derivation pipeline is reset whenever we reorg. // The derivation pipeline determines the new l2Safe. diff --git a/op-node/rollup/event.go b/op-node/rollup/event.go index bcab847451d8..3d12c34a9f6b 100644 --- a/op-node/rollup/event.go +++ b/op-node/rollup/event.go @@ -37,12 +37,5 @@ func (ev ResetEvent) String() string { return "reset-event" } -type CriticalErrorEvent struct { - Err error -} - -var _ event.Event = CriticalErrorEvent{} - -func (ev CriticalErrorEvent) String() string { - return "critical-error" -} +// CriticalErrorEvent is an alias for event.CriticalErrorEvent +type CriticalErrorEvent = event.CriticalErrorEvent diff --git a/op-node/rollup/event/events.go b/op-node/rollup/event/events.go index ac550e203e55..6fed3859a64e 100644 --- a/op-node/rollup/event/events.go +++ b/op-node/rollup/event/events.go @@ -75,3 +75,13 @@ func (fn DeriverFunc) OnEvent(ev Event) bool { type NoopEmitter struct{} func (e NoopEmitter) Emit(ev Event) {} + +type CriticalErrorEvent struct { + Err error +} + +var _ Event = CriticalErrorEvent{} + +func (ev CriticalErrorEvent) String() string { + return "critical-error" +} diff --git a/op-node/rollup/event/system.go b/op-node/rollup/event/system.go index 3b59b89651b3..566f28fdbe40 100644 --- a/op-node/rollup/event/system.go +++ b/op-node/rollup/event/system.go @@ -11,7 +11,7 @@ import ( "github.com/ethereum/go-ethereum/log" ) -type System interface { +type Registry interface { // Register registers a named event-emitter, optionally processing events itself: // deriver may be nil, not all registrants have to process events. // A non-nil deriver may implement AttachEmitter to automatically attach the Emitter to it, @@ -20,6 +20,10 @@ type System interface { // Unregister removes a named emitter, // also removing it from the set of events-receiving derivers (if registered with non-nil deriver). Unregister(name string) (old Emitter) +} + +type System interface { + Registry // AddTracer registers a tracer to capture all event deriver/emitter work. It runs until RemoveTracer is called. // Duplicate tracers are allowed. AddTracer(t Tracer) @@ -73,6 +77,10 @@ func (r *systemActor) RunEvent(ev AnnotatedEvent) { if r.ctx.Err() != nil { return } + if r.sys.abort.Load() && !Is[CriticalErrorEvent](ev.Event) { + // if aborting, and not the CriticalErrorEvent itself, then do not process the event + return + } prev := r.currentEvent start := time.Now() @@ -99,6 +107,9 @@ type Sys struct { tracers []Tracer tracersLock sync.RWMutex + + // if true, no events may be processed, except CriticalError itself + abort atomic.Bool } func NewSystem(log log.Logger, ex Executor) *Sys { @@ -240,6 +251,12 @@ func (s *Sys) emit(name string, derivContext uint64, ev Event) { emitContext := s.emitContext.Add(1) annotated := AnnotatedEvent{Event: ev, EmitContext: emitContext} + // As soon as anything emits a critical event, + // make the system aware, before the executor event schedules it for processing. + if Is[CriticalErrorEvent](ev) { + s.abort.Store(true) + } + emitTime := time.Now() s.recordEmit(name, annotated, derivContext, emitTime) diff --git a/op-node/rollup/event/system_test.go b/op-node/rollup/event/system_test.go index 9feef9628531..749eb681a75c 100644 --- a/op-node/rollup/event/system_test.go +++ b/op-node/rollup/event/system_test.go @@ -2,6 +2,7 @@ package event import ( "context" + "errors" "testing" "github.com/stretchr/testify/require" @@ -104,3 +105,46 @@ func TestSystemBroadcast(t *testing.T) { require.Equal(t, 3, fooCount) require.Equal(t, 3, barCount) } + +func TestCriticalError(t *testing.T) { + logger := testlog.Logger(t, log.LevelError) + count := 0 + seenCrit := 0 + deriverFn := DeriverFunc(func(ev Event) bool { + switch ev.(type) { + case CriticalErrorEvent: + seenCrit += 1 + default: + count += 1 + } + return true + }) + exec := NewGlobalSynchronous(context.Background()) + sys := NewSystem(logger, exec) + emitterA := sys.Register("a", deriverFn, DefaultRegisterOpts()) + emitterB := sys.Register("b", deriverFn, DefaultRegisterOpts()) + + require.NoError(t, exec.Drain(), "can drain, even if empty") + emitterA.Emit(TestEvent{}) + require.Equal(t, 0, count, "no processing yet, queued event") + require.NoError(t, exec.Drain()) + require.Equal(t, 2, count, "both A and B processed the event") + + emitterA.Emit(TestEvent{}) + emitterB.Emit(TestEvent{}) + testErr := errors.New("test crit error") + emitterB.Emit(CriticalErrorEvent{Err: testErr}) + require.Equal(t, 2, count, "no processing yet, queued events") + require.Equal(t, 0, seenCrit, "critical error events are still scheduled like normal") + require.True(t, sys.abort.Load(), "we are aware of the crit") + require.NoError(t, exec.Drain()) + require.Equal(t, 2, count, "still no processing, since we hit a crit error, the events are ignored") + require.Equal(t, 2, seenCrit, "but everyone has seen the crit now") + + // We are able to stop the processing now + sys.Stop() + + emitterA.Emit(TestEvent{}) + require.NoError(t, exec.Drain(), "system is closed, no further event processing") + require.Equal(t, 2, count) +} From 66bfe67860edcca9378f3c2dfb1a489b2c4f7a9f Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Tue, 17 Sep 2024 09:51:32 +1000 Subject: [PATCH 157/264] op-e2e: Fix compile error (#11933) * op-e2e: Fix compile error * ci: Make go-lint a dependency of bedrock-go-tests to prevent merging if it fails. --- .circleci/config.yml | 1 + op-e2e/interop/supersystem.go | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6a1448147ba7..4a4973a8d294 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1745,6 +1745,7 @@ workflows: - bedrock-go-tests: requires: - go-mod-download + - go-lint - cannon-build-test-vectors - cannon-go-lint-and-test - check-generated-mocks-op-node diff --git a/op-e2e/interop/supersystem.go b/op-e2e/interop/supersystem.go index 24a1265e5e16..24ec4aa1046a 100644 --- a/op-e2e/interop/supersystem.go +++ b/op-e2e/interop/supersystem.go @@ -10,6 +10,7 @@ import ( "testing" "time" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/stretchr/testify/require" "github.com/ethereum/go-ethereum/common" @@ -163,7 +164,7 @@ func (s *interopE2ESystem) prepareL1() (*fakebeacon.FakeBeacon, *geth.GethInstan blockTimeL1 := uint64(6) blobPath := s.t.TempDir() bcn := fakebeacon.NewBeacon(s.logger.New("role", "l1_cl"), - filepath.Join(blobPath, "l1_cl"), genesisTimestampL1, blockTimeL1) + e2eutils.NewBlobStore(), genesisTimestampL1, blockTimeL1) s.t.Cleanup(func() { _ = bcn.Close() }) From 994f63476e8d3b5790c79fa2e88c55261d6932a9 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Tue, 17 Sep 2024 10:18:36 +1000 Subject: [PATCH 158/264] op-e2e: Separate actions tests into different packages (#11921) * op-e2e: Move most action tests into a package based on what they test * op-e2e: Move batch_queue_test.go to derivation package * op-e2e: Move eip4844_test.go to batcher package * op-e2e: Move actions helper code to helpers package * update makefile * op-e2e: Fix typo --------- Co-authored-by: clabby --- op-e2e/Makefile | 2 +- op-e2e/actions/{ => altda}/altda_test.go | 82 +++---- op-e2e/actions/{ => batcher}/eip4844_test.go | 27 +-- .../actions/{ => batcher}/l2_batcher_test.go | 137 +++++------- .../{ => derivation}/batch_queue_test.go | 49 +++-- .../{ => derivation}/blocktime_test.go | 34 +-- .../{ => derivation}/l2_verifier_test.go | 44 +--- op-e2e/actions/{ => derivation}/reorg_test.go | 114 ++++------ .../{ => derivation}/system_config_test.go | 66 +++--- op-e2e/actions/{ => helpers}/action.go | 2 +- .../{ => helpers}/garbage_channel_out.go | 2 +- op-e2e/actions/{ => helpers}/l1_miner.go | 30 +-- op-e2e/actions/{ => helpers}/l1_miner_test.go | 2 +- op-e2e/actions/{ => helpers}/l1_replica.go | 6 +- .../actions/{ => helpers}/l1_replica_test.go | 2 +- op-e2e/actions/{ => helpers}/l2_batcher.go | 66 +++--- op-e2e/actions/{ => helpers}/l2_engine.go | 30 +-- .../actions/{ => helpers}/l2_engine_test.go | 2 +- op-e2e/actions/{ => helpers}/l2_proposer.go | 2 +- op-e2e/actions/{ => helpers}/l2_sequencer.go | 16 +- op-e2e/actions/{ => helpers}/l2_verifier.go | 22 +- op-e2e/actions/helpers/setups.go | 75 +++++++ op-e2e/actions/{ => helpers}/tx_helper.go | 2 +- op-e2e/actions/{ => helpers}/user.go | 2 +- op-e2e/actions/{ => helpers}/user_test.go | 8 +- op-e2e/actions/{ => helpers}/utils.go | 2 +- op-e2e/actions/{ => interop}/interop_test.go | 19 +- op-e2e/actions/proofs/channel_timeout_test.go | 4 +- op-e2e/actions/proofs/garbage_channel_test.go | 18 +- op-e2e/actions/proofs/helpers/env.go | 56 ++--- op-e2e/actions/proofs/helpers/fixture.go | 4 +- .../proofs/sequence_window_expiry_test.go | 4 +- op-e2e/actions/proofs/simple_program_test.go | 4 +- .../{ => proposer}/l2_proposer_test.go | 22 +- op-e2e/actions/safedb/helpers/setups.go | 38 ++++ op-e2e/actions/{ => safedb}/safedb_test.go | 51 +---- .../{ => sequencer}/l2_sequencer_test.go | 44 ++-- op-e2e/actions/{ => sync}/sync_test.go | 204 +++++++++--------- .../{ => upgrades}/dencun_fork_test.go | 89 ++++---- .../{ => upgrades}/ecotone_fork_test.go | 25 +-- .../actions/{ => upgrades}/fjord_fork_test.go | 11 +- op-e2e/actions/upgrades/helpers/config.go | 27 +++ .../actions/{ => upgrades}/span_batch_test.go | 122 +++++------ 43 files changed, 808 insertions(+), 760 deletions(-) rename op-e2e/actions/{ => altda}/altda_test.go (87%) rename op-e2e/actions/{ => batcher}/eip4844_test.go (85%) rename op-e2e/actions/{ => batcher}/l2_batcher_test.go (80%) rename op-e2e/actions/{ => derivation}/batch_queue_test.go (62%) rename op-e2e/actions/{ => derivation}/blocktime_test.go (89%) rename op-e2e/actions/{ => derivation}/l2_verifier_test.go (55%) rename op-e2e/actions/{ => derivation}/reorg_test.go (89%) rename op-e2e/actions/{ => derivation}/system_config_test.go (87%) rename op-e2e/actions/{ => helpers}/action.go (99%) rename op-e2e/actions/{ => helpers}/garbage_channel_out.go (99%) rename op-e2e/actions/{ => helpers}/l1_miner.go (92%) rename op-e2e/actions/{ => helpers}/l1_miner_test.go (99%) rename op-e2e/actions/{ => helpers}/l1_replica.go (99%) rename op-e2e/actions/{ => helpers}/l1_replica_test.go (99%) rename op-e2e/actions/{ => helpers}/l2_batcher.go (91%) rename op-e2e/actions/{ => helpers}/l2_engine.go (91%) rename op-e2e/actions/{ => helpers}/l2_engine_test.go (99%) rename op-e2e/actions/{ => helpers}/l2_proposer.go (99%) rename op-e2e/actions/{ => helpers}/l2_sequencer.go (95%) rename op-e2e/actions/{ => helpers}/l2_verifier.go (97%) create mode 100644 op-e2e/actions/helpers/setups.go rename op-e2e/actions/{ => helpers}/tx_helper.go (99%) rename op-e2e/actions/{ => helpers}/user.go (99%) rename op-e2e/actions/{ => helpers}/user_test.go (98%) rename op-e2e/actions/{ => helpers}/utils.go (99%) rename op-e2e/actions/{ => interop}/interop_test.go (89%) rename op-e2e/actions/{ => proposer}/l2_proposer_test.go (88%) create mode 100644 op-e2e/actions/safedb/helpers/setups.go rename op-e2e/actions/{ => safedb}/safedb_test.go (68%) rename op-e2e/actions/{ => sequencer}/l2_sequencer_test.go (79%) rename op-e2e/actions/{ => sync}/sync_test.go (82%) rename op-e2e/actions/{ => upgrades}/dencun_fork_test.go (71%) rename op-e2e/actions/{ => upgrades}/ecotone_fork_test.go (93%) rename op-e2e/actions/{ => upgrades}/fjord_fork_test.go (94%) create mode 100644 op-e2e/actions/upgrades/helpers/config.go rename op-e2e/actions/{ => upgrades}/span_batch_test.go (82%) diff --git a/op-e2e/Makefile b/op-e2e/Makefile index 6bf5d616640b..e33f83e9b6c1 100644 --- a/op-e2e/Makefile +++ b/op-e2e/Makefile @@ -21,7 +21,7 @@ test-ws: pre-test .PHONY: test-ws test-actions: pre-test - $(go_test) $(go_test_flags) ./actions + $(go_test) $(go_test_flags) ./actions/... .PHONY: test-actions test-http: pre-test diff --git a/op-e2e/actions/altda_test.go b/op-e2e/actions/altda/altda_test.go similarity index 87% rename from op-e2e/actions/altda_test.go rename to op-e2e/actions/altda/altda_test.go index ed6068c141ae..ac122d9d999a 100644 --- a/op-e2e/actions/altda_test.go +++ b/op-e2e/actions/altda/altda_test.go @@ -1,10 +1,11 @@ -package actions +package altda import ( "math/big" "math/rand" "testing" + "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/stretchr/testify/require" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -32,21 +33,21 @@ type L2AltDA struct { daMgr *altda.DA altDACfg altda.Config contract *bindings.DataAvailabilityChallenge - batcher *L2Batcher - sequencer *L2Sequencer - engine *L2Engine + batcher *helpers.L2Batcher + sequencer *helpers.L2Sequencer + engine *helpers.L2Engine engCl *sources.EngineClient sd *e2eutils.SetupData dp *e2eutils.DeployParams - miner *L1Miner - alice *CrossLayerUser + miner *helpers.L1Miner + alice *helpers.CrossLayerUser lastComm []byte lastCommBn uint64 } type AltDAParam func(p *e2eutils.TestParams) -func NewL2AltDA(t Testing, params ...AltDAParam) *L2AltDA { +func NewL2AltDA(t helpers.Testing, params ...AltDAParam) *L2AltDA { p := &e2eutils.TestParams{ MaxSequencerDrift: 40, SequencerWindowSize: 12, @@ -60,15 +61,15 @@ func NewL2AltDA(t Testing, params ...AltDAParam) *L2AltDA { log := testlog.Logger(t, log.LvlDebug) dp := e2eutils.MakeDeployParams(t, p) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc) require.True(t, sd.RollupCfg.AltDAEnabled()) - miner := NewL1Miner(t, log, sd.L1Cfg) + miner := helpers.NewL1Miner(t, log, sd.L1Cfg) l1Client := miner.EthClient() jwtPath := e2eutils.WriteDefaultJWT(t) - engine := NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath) + engine := helpers.NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath) engCl := engine.EngineClient(t, sd.RollupCfg) storage := &altda.DAErrFaker{Client: altda.NewMockDAClient(log)} @@ -81,21 +82,21 @@ func NewL2AltDA(t Testing, params ...AltDAParam) *L2AltDA { daMgr := altda.NewAltDAWithStorage(log, altDACfg, storage, &altda.NoopMetrics{}) - sequencer := NewL2Sequencer(t, log, l1F, miner.BlobStore(), daMgr, engCl, sd.RollupCfg, 0, nil) + sequencer := helpers.NewL2Sequencer(t, log, l1F, miner.BlobStore(), daMgr, engCl, sd.RollupCfg, 0, nil) miner.ActL1SetFeeRecipient(common.Address{'A'}) sequencer.ActL2PipelineFull(t) - batcher := NewL2Batcher(log, sd.RollupCfg, AltDABatcherCfg(dp, storage), sequencer.RollupClient(), l1Client, engine.EthClient(), engCl) + batcher := helpers.NewL2Batcher(log, sd.RollupCfg, helpers.AltDABatcherCfg(dp, storage), sequencer.RollupClient(), l1Client, engine.EthClient(), engCl) addresses := e2eutils.CollectAddresses(sd, dp) cl := engine.EthClient() - l2UserEnv := &BasicUserEnv[*L2Bindings]{ + l2UserEnv := &helpers.BasicUserEnv[*helpers.L2Bindings]{ EthCl: cl, Signer: types.LatestSigner(sd.L2Cfg.Config), AddressCorpora: addresses, - Bindings: NewL2Bindings(t, cl, engine.GethClient()), + Bindings: helpers.NewL2Bindings(t, cl, engine.GethClient()), } - alice := NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b))) + alice := helpers.NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b))) alice.L2.SetUserEnv(l2UserEnv) contract, err := bindings.NewDataAvailabilityChallenge(sd.RollupCfg.AltDAConfig.DAChallengeAddress, l1Client) @@ -130,21 +131,21 @@ func (a *L2AltDA) StorageClient() *altda.DAErrFaker { return a.storage } -func (a *L2AltDA) NewVerifier(t Testing) *L2Verifier { +func (a *L2AltDA) NewVerifier(t helpers.Testing) *helpers.L2Verifier { jwtPath := e2eutils.WriteDefaultJWT(t) - engine := NewL2Engine(t, a.log, a.sd.L2Cfg, a.sd.RollupCfg.Genesis.L1, jwtPath) + engine := helpers.NewL2Engine(t, a.log, a.sd.L2Cfg, a.sd.RollupCfg.Genesis.L1, jwtPath) engCl := engine.EngineClient(t, a.sd.RollupCfg) l1F, err := sources.NewL1Client(a.miner.RPCClient(), a.log, nil, sources.L1ClientDefaultConfig(a.sd.RollupCfg, false, sources.RPCKindBasic)) require.NoError(t, err) daMgr := altda.NewAltDAWithStorage(a.log, a.altDACfg, a.storage, &altda.NoopMetrics{}) - verifier := NewL2Verifier(t, a.log, l1F, a.miner.BlobStore(), daMgr, engCl, a.sd.RollupCfg, &sync.Config{}, safedb.Disabled, nil) + verifier := helpers.NewL2Verifier(t, a.log, l1F, a.miner.BlobStore(), daMgr, engCl, a.sd.RollupCfg, &sync.Config{}, safedb.Disabled, nil) return verifier } -func (a *L2AltDA) ActSequencerIncludeTx(t Testing) { +func (a *L2AltDA) ActSequencerIncludeTx(t helpers.Testing) { a.alice.L2.ActResetTxOpts(t) a.alice.L2.ActSetTxToAddr(&a.dp.Addresses.Bob)(t) a.alice.L2.ActMakeTx(t) @@ -156,7 +157,7 @@ func (a *L2AltDA) ActSequencerIncludeTx(t Testing) { a.sequencer.ActL2EndBlock(t) } -func (a *L2AltDA) ActNewL2Tx(t Testing) { +func (a *L2AltDA) ActNewL2Tx(t helpers.Testing) { a.ActSequencerIncludeTx(t) a.batcher.ActL2BatchBuffer(t) @@ -170,20 +171,20 @@ func (a *L2AltDA) ActNewL2Tx(t Testing) { a.miner.ActL1IncludeTx(a.dp.Addresses.Batcher)(t) a.miner.ActL1EndBlock(t) - a.lastCommBn = a.miner.l1Chain.CurrentBlock().Number.Uint64() + a.lastCommBn = a.miner.L1Chain().CurrentBlock().Number.Uint64() } -func (a *L2AltDA) ActDeleteLastInput(t Testing) { +func (a *L2AltDA) ActDeleteLastInput(t helpers.Testing) { require.NoError(t, a.storage.Client.DeleteData(a.lastComm)) } -func (a *L2AltDA) ActChallengeLastInput(t Testing) { +func (a *L2AltDA) ActChallengeLastInput(t helpers.Testing) { a.ActChallengeInput(t, a.lastComm, a.lastCommBn) a.log.Info("challenged last input", "block", a.lastCommBn) } -func (a *L2AltDA) ActChallengeInput(t Testing, comm []byte, bn uint64) { +func (a *L2AltDA) ActChallengeInput(t helpers.Testing, comm []byte, bn uint64) { bondValue, err := a.contract.BondSize(&bind.CallOpts{}) require.NoError(t, err) @@ -209,15 +210,15 @@ func (a *L2AltDA) ActChallengeInput(t Testing, comm []byte, bn uint64) { a.miner.ActL1EndBlock(t) } -func (a *L2AltDA) ActExpireLastInput(t Testing) { +func (a *L2AltDA) ActExpireLastInput(t helpers.Testing) { reorgWindow := a.altDACfg.ResolveWindow + a.altDACfg.ChallengeWindow - for a.miner.l1Chain.CurrentBlock().Number.Uint64() <= a.lastCommBn+reorgWindow { + for a.miner.L1Chain().CurrentBlock().Number.Uint64() <= a.lastCommBn+reorgWindow { a.miner.ActL1StartBlock(12)(t) a.miner.ActL1EndBlock(t) } } -func (a *L2AltDA) ActResolveInput(t Testing, comm []byte, input []byte, bn uint64) { +func (a *L2AltDA) ActResolveInput(t helpers.Testing, comm []byte, input []byte, bn uint64) { txOpts, err := bind.NewKeyedTransactorWithChainID(a.dp.Secrets.Alice, a.sd.L1Cfg.Config.ChainID) require.NoError(t, err) @@ -229,7 +230,7 @@ func (a *L2AltDA) ActResolveInput(t Testing, comm []byte, input []byte, bn uint6 a.miner.ActL1EndBlock(t) } -func (a *L2AltDA) ActResolveLastChallenge(t Testing) { +func (a *L2AltDA) ActResolveLastChallenge(t helpers.Testing) { // remove derivation byte prefix input, err := a.storage.GetInput(t.Ctx(), altda.Keccak256Commitment(a.lastComm[1:])) require.NoError(t, err) @@ -237,23 +238,22 @@ func (a *L2AltDA) ActResolveLastChallenge(t Testing) { a.ActResolveInput(t, a.lastComm, input, a.lastCommBn) } -func (a *L2AltDA) ActL1Blocks(t Testing, n uint64) { +func (a *L2AltDA) ActL1Blocks(t helpers.Testing, n uint64) { for i := uint64(0); i < n; i++ { a.miner.ActL1StartBlock(12)(t) a.miner.ActL1EndBlock(t) } } -func (a *L2AltDA) GetLastTxBlock(t Testing) *types.Block { - rcpt, err := a.engine.EthClient().TransactionReceipt(t.Ctx(), a.alice.L2.lastTxHash) - require.NoError(t, err) +func (a *L2AltDA) GetLastTxBlock(t helpers.Testing) *types.Block { + rcpt := a.alice.L2.LastTxReceipt(t) blk, err := a.engine.EthClient().BlockByHash(t.Ctx(), rcpt.BlockHash) require.NoError(t, err) return blk } -func (a *L2AltDA) ActL1Finalized(t Testing) { - latest := a.miner.l1Chain.CurrentBlock().Number.Uint64() +func (a *L2AltDA) ActL1Finalized(t helpers.Testing) { + latest := a.miner.L1Chain().CurrentBlock().Number.Uint64() a.miner.ActL1Safe(t, latest) a.miner.ActL1Finalize(t, latest) a.sequencer.ActL1FinalizedSignal(t) @@ -265,7 +265,7 @@ func TestAltDA_ChallengeExpired(gt *testing.T) { gt.Skip("AltDA is not enabled") } - t := NewDefaultTesting(gt) + t := helpers.NewDefaultTesting(gt) harness := NewL2AltDA(t) // generate enough initial l1 blocks to have a finalized head. @@ -325,7 +325,7 @@ func TestAltDA_ChallengeResolved(gt *testing.T) { gt.Skip("AltDA is not enabled") } - t := NewDefaultTesting(gt) + t := helpers.NewDefaultTesting(gt) harness := NewL2AltDA(t) // include a new l2 transaction, submitting an input commitment to the l1. @@ -373,7 +373,7 @@ func TestAltDA_StorageError(gt *testing.T) { gt.Skip("AltDA is not enabled") } - t := NewDefaultTesting(gt) + t := helpers.NewDefaultTesting(gt) harness := NewL2AltDA(t) // include a new l2 transaction, submitting an input commitment to the l1. @@ -402,7 +402,7 @@ func TestAltDA_ChallengeReorg(gt *testing.T) { gt.Skip("AltDA is not enabled") } - t := NewDefaultTesting(gt) + t := helpers.NewDefaultTesting(gt) harness := NewL2AltDA(t) // New L2 tx added to a batch and committed to L1 @@ -450,7 +450,7 @@ func TestAltDA_SequencerStalledMultiChallenges(gt *testing.T) { gt.Skip("AltDA is not enabled") } - t := NewDefaultTesting(gt) + t := helpers.NewDefaultTesting(gt) a := NewL2AltDA(t) // create a new tx on l2 and commit it to l1 @@ -509,7 +509,7 @@ func TestAltDA_SequencerStalledMultiChallenges(gt *testing.T) { comm2 := a.lastComm _, err = a.storage.GetInput(t.Ctx(), altda.Keccak256Commitment(comm2[1:])) require.NoError(t, err) - a.lastCommBn = a.miner.l1Chain.CurrentBlock().Number.Uint64() + a.lastCommBn = a.miner.L1Chain().CurrentBlock().Number.Uint64() // ensure the second commitment is distinct from the first require.NotEqual(t, comm1, comm2) @@ -545,7 +545,7 @@ func TestAltDA_Finalization(gt *testing.T) { if !e2eutils.UseAltDA() { gt.Skip("AltDA is not enabled") } - t := NewDefaultTesting(gt) + t := helpers.NewDefaultTesting(gt) a := NewL2AltDA(t) // build L1 block #1 diff --git a/op-e2e/actions/eip4844_test.go b/op-e2e/actions/batcher/eip4844_test.go similarity index 85% rename from op-e2e/actions/eip4844_test.go rename to op-e2e/actions/batcher/eip4844_test.go index 8b287250bb0e..6d77a3961788 100644 --- a/op-e2e/actions/eip4844_test.go +++ b/op-e2e/actions/batcher/eip4844_test.go @@ -1,8 +1,9 @@ -package actions +package batcher import ( "testing" + "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/stretchr/testify/require" "github.com/ethereum/go-ethereum/common" @@ -16,26 +17,26 @@ import ( "github.com/ethereum-optimism/optimism/op-service/testlog" ) -func setupEIP4844Test(t Testing, log log.Logger) (*e2eutils.SetupData, *e2eutils.DeployParams, *L1Miner, *L2Sequencer, *L2Engine, *L2Verifier, *L2Engine) { - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) +func setupEIP4844Test(t helpers.Testing, log log.Logger) (*e2eutils.SetupData, *e2eutils.DeployParams, *helpers.L1Miner, *helpers.L2Sequencer, *helpers.L2Engine, *helpers.L2Verifier, *helpers.L2Engine) { + dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams) genesisActivation := hexutil.Uint64(0) dp.DeployConfig.L1CancunTimeOffset = &genesisActivation dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisActivation dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisActivation dp.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisActivation - sd := e2eutils.Setup(t, dp, DefaultAlloc) - miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) + sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc) + miner, seqEngine, sequencer := helpers.SetupSequencerTest(t, sd, log) miner.ActL1SetFeeRecipient(common.Address{'A'}) sequencer.ActL2PipelineFull(t) - verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + verifEngine, verifier := helpers.SetupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) return sd, dp, miner, sequencer, seqEngine, verifier, verifEngine } -func setupBatcher(t Testing, log log.Logger, sd *e2eutils.SetupData, dp *e2eutils.DeployParams, miner *L1Miner, - sequencer *L2Sequencer, engine *L2Engine, daType batcherFlags.DataAvailabilityType, -) *L2Batcher { - return NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ +func setupBatcher(t helpers.Testing, log log.Logger, sd *e2eutils.SetupData, dp *e2eutils.DeployParams, miner *helpers.L1Miner, + sequencer *helpers.L2Sequencer, engine *helpers.L2Engine, daType batcherFlags.DataAvailabilityType, +) *helpers.L2Batcher { + return helpers.NewL2Batcher(log, sd.RollupCfg, &helpers.BatcherCfg{ MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Batcher, @@ -44,7 +45,7 @@ func setupBatcher(t Testing, log log.Logger, sd *e2eutils.SetupData, dp *e2eutil } func TestEIP4844DataAvailability(gt *testing.T) { - t := NewDefaultTesting(gt) + t := helpers.NewDefaultTesting(gt) log := testlog.Logger(t, log.LevelDebug) sd, dp, miner, sequencer, seqEngine, verifier, _ := setupEIP4844Test(t, log) @@ -82,7 +83,7 @@ func TestEIP4844DataAvailability(gt *testing.T) { } func TestEIP4844MultiBlobs(gt *testing.T) { - t := NewDefaultTesting(gt) + t := helpers.NewDefaultTesting(gt) log := testlog.Logger(t, log.LevelDebug) sd, dp, miner, sequencer, seqEngine, verifier, _ := setupEIP4844Test(t, log) @@ -121,7 +122,7 @@ func TestEIP4844MultiBlobs(gt *testing.T) { } func TestEIP4844DataAvailabilitySwitch(gt *testing.T) { - t := NewDefaultTesting(gt) + t := helpers.NewDefaultTesting(gt) log := testlog.Logger(t, log.LevelDebug) sd, dp, miner, sequencer, seqEngine, verifier, _ := setupEIP4844Test(t, log) diff --git a/op-e2e/actions/l2_batcher_test.go b/op-e2e/actions/batcher/l2_batcher_test.go similarity index 80% rename from op-e2e/actions/l2_batcher_test.go rename to op-e2e/actions/batcher/l2_batcher_test.go index 0b9140020b0b..e0605f3fb121 100644 --- a/op-e2e/actions/l2_batcher_test.go +++ b/op-e2e/actions/batcher/l2_batcher_test.go @@ -1,4 +1,4 @@ -package actions +package batcher import ( "errors" @@ -6,6 +6,8 @@ import ( "math/rand" "testing" + actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" + upgradesHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/upgrades/helpers" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" @@ -50,29 +52,8 @@ func TestL2BatcherBatchType(t *testing.T) { } } -// applyDeltaTimeOffset adjusts fork configuration to not conflict with the delta overrides -func applyDeltaTimeOffset(dp *e2eutils.DeployParams, deltaTimeOffset *hexutil.Uint64) { - dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset - // configure Ecotone to not be before Delta accidentally - if dp.DeployConfig.L2GenesisEcotoneTimeOffset != nil { - if deltaTimeOffset == nil { - dp.DeployConfig.L2GenesisEcotoneTimeOffset = nil - } else if *dp.DeployConfig.L2GenesisEcotoneTimeOffset < *deltaTimeOffset { - dp.DeployConfig.L2GenesisEcotoneTimeOffset = deltaTimeOffset - } - } - // configure Fjord to not be before Delta accidentally - if dp.DeployConfig.L2GenesisFjordTimeOffset != nil { - if deltaTimeOffset == nil { - dp.DeployConfig.L2GenesisFjordTimeOffset = nil - } else if *dp.DeployConfig.L2GenesisFjordTimeOffset < *deltaTimeOffset { - dp.DeployConfig.L2GenesisFjordTimeOffset = deltaTimeOffset - } - } -} - func NormalBatcher(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { - t := NewDefaultTesting(gt) + t := actionsHelpers.NewDefaultTesting(gt) p := &e2eutils.TestParams{ MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) SequencerWindowSize: 24, @@ -80,14 +61,14 @@ func NormalBatcher(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { L1BlockTime: 12, } dp := e2eutils.MakeDeployParams(t, p) - applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) - miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) - verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + miner, seqEngine, sequencer := actionsHelpers.SetupSequencerTest(t, sd, log) + verifEngine, verifier := actionsHelpers.SetupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) rollupSeqCl := sequencer.RollupClient() - batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + batcher := actionsHelpers.NewL2Batcher(log, sd.RollupCfg, actionsHelpers.DefaultBatcherCfg(dp), rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) // Alice makes a L2 tx @@ -99,7 +80,7 @@ func NormalBatcher(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { ChainID: sd.L2Cfg.Config.ChainID, Nonce: n, GasTipCap: big.NewInt(2 * params.GWei), - GasFeeCap: new(big.Int).Add(miner.l1Chain.CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), + GasFeeCap: new(big.Int).Add(miner.L1Chain().CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), Gas: params.TxGas, To: &dp.Addresses.Bob, Value: e2eutils.Ether(2), @@ -123,8 +104,8 @@ func NormalBatcher(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { miner.ActL1StartBlock(12)(t) miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) miner.ActL1EndBlock(t) - bl := miner.l1Chain.CurrentBlock() - log.Info("bl", "txs", len(miner.l1Chain.GetBlockByHash(bl.Hash()).Transactions())) + bl := miner.L1Chain().CurrentBlock() + log.Info("bl", "txs", len(miner.L1Chain().GetBlockByHash(bl.Hash()).Transactions())) // Now make enough L1 blocks that the verifier will have to derive a L2 block // It will also eagerly derive the block from the batcher @@ -147,12 +128,12 @@ func NormalBatcher(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { } func L2Finalization(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) - applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) + upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) - miner, engine, sequencer := setupSequencerTest(t, sd, log) + miner, engine, sequencer := actionsHelpers.SetupSequencerTest(t, sd, log) sequencer.ActL2PipelineFull(t) @@ -184,7 +165,7 @@ func L2Finalization(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { require.Equal(t, uint64(1), sequencer.SyncStatus().FinalizedL1.Number) require.Equal(t, uint64(0), sequencer.SyncStatus().FinalizedL2.Number, "L2 block has to be included on L1 before it can be finalized") - batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + batcher := actionsHelpers.NewL2Batcher(log, sd.RollupCfg, actionsHelpers.DefaultBatcherCfg(dp), sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engine.EngineClient(t, sd.RollupCfg)) heightToSubmit := sequencer.SyncStatus().UnsafeL2.Number @@ -244,12 +225,12 @@ func L2Finalization(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // L2FinalizationWithSparseL1 tests that safe L2 blocks can be finalized even if we do not regularly get a L1 finalization signal func L2FinalizationWithSparseL1(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) - applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) + upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) - miner, engine, sequencer := setupSequencerTest(t, sd, log) + miner, engine, sequencer := actionsHelpers.SetupSequencerTest(t, sd, log) sequencer.ActL2PipelineFull(t) @@ -260,7 +241,7 @@ func L2FinalizationWithSparseL1(gt *testing.T, deltaTimeOffset *hexutil.Uint64) startStatus := sequencer.SyncStatus() require.Less(t, startStatus.SafeL2.Number, startStatus.UnsafeL2.Number, "sequencer has unsafe L2 block") - batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + batcher := actionsHelpers.NewL2Batcher(log, sd.RollupCfg, actionsHelpers.DefaultBatcherCfg(dp), sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engine.EngineClient(t, sd.RollupCfg)) batcher.ActSubmitAll(t) @@ -300,29 +281,29 @@ func L2FinalizationWithSparseL1(gt *testing.T, deltaTimeOffset *hexutil.Uint64) // valid batches being submitted to the batch inbox. These batches should always be rejected // and the safe L2 head should remain unaltered. func GarbageBatch(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { - t := NewDefaultTesting(gt) - p := DefaultRollupTestParams + t := actionsHelpers.NewDefaultTesting(gt) + p := actionsHelpers.DefaultRollupTestParams dp := e2eutils.MakeDeployParams(t, p) - applyDeltaTimeOffset(dp, deltaTimeOffset) - for _, garbageKind := range GarbageKinds { - sd := e2eutils.Setup(t, dp, DefaultAlloc) + upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset) + for _, garbageKind := range actionsHelpers.GarbageKinds { + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelError) - miner, engine, sequencer := setupSequencerTest(t, sd, log) + miner, engine, sequencer := actionsHelpers.SetupSequencerTest(t, sd, log) - _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + _, verifier := actionsHelpers.SetupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) - batcherCfg := DefaultBatcherCfg(dp) + batcherCfg := actionsHelpers.DefaultBatcherCfg(dp) - if garbageKind == MALFORM_RLP || garbageKind == INVALID_COMPRESSION { + if garbageKind == actionsHelpers.MALFORM_RLP || garbageKind == actionsHelpers.INVALID_COMPRESSION { // If the garbage kind is `INVALID_COMPRESSION` or `MALFORM_RLP`, use the `actions` packages // modified `ChannelOut`. - batcherCfg.GarbageCfg = &GarbageChannelCfg{ - UseInvalidCompression: garbageKind == INVALID_COMPRESSION, - MalformRLP: garbageKind == MALFORM_RLP, + batcherCfg.GarbageCfg = &actionsHelpers.GarbageChannelCfg{ + UseInvalidCompression: garbageKind == actionsHelpers.INVALID_COMPRESSION, + MalformRLP: garbageKind == actionsHelpers.MALFORM_RLP, } } - batcher := NewL2Batcher(log, sd.RollupCfg, batcherCfg, sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engine.EngineClient(t, sd.RollupCfg)) + batcher := actionsHelpers.NewL2Batcher(log, sd.RollupCfg, batcherCfg, sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engine.EngineClient(t, sd.RollupCfg)) sequencer.ActL2PipelineFull(t) verifier.ActL2PipelineFull(t) @@ -376,7 +357,7 @@ func GarbageBatch(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { } func ExtendedTimeWithoutL1Batches(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { - t := NewDefaultTesting(gt) + t := actionsHelpers.NewDefaultTesting(gt) p := &e2eutils.TestParams{ MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) SequencerWindowSize: 24, @@ -384,14 +365,14 @@ func ExtendedTimeWithoutL1Batches(gt *testing.T, deltaTimeOffset *hexutil.Uint64 L1BlockTime: 12, } dp := e2eutils.MakeDeployParams(t, p) - applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelError) - miner, engine, sequencer := setupSequencerTest(t, sd, log) + miner, engine, sequencer := actionsHelpers.SetupSequencerTest(t, sd, log) - _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + _, verifier := actionsHelpers.SetupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) - batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + batcher := actionsHelpers.NewL2Batcher(log, sd.RollupCfg, actionsHelpers.DefaultBatcherCfg(dp), sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engine.EngineClient(t, sd.RollupCfg)) sequencer.ActL2PipelineFull(t) @@ -432,7 +413,7 @@ func ExtendedTimeWithoutL1Batches(gt *testing.T, deltaTimeOffset *hexutil.Uint64 // This does not test the batcher code, but is really focused at testing the batcher utils // and channel-decoding verifier code in the derive package. func BigL2Txs(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { - t := NewDefaultTesting(gt) + t := actionsHelpers.NewDefaultTesting(gt) p := &e2eutils.TestParams{ MaxSequencerDrift: 100, SequencerWindowSize: 1000, @@ -440,14 +421,14 @@ func BigL2Txs(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { L1BlockTime: 12, } dp := e2eutils.MakeDeployParams(t, p) - applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelInfo) - miner, engine, sequencer := setupSequencerTest(t, sd, log) + miner, engine, sequencer := actionsHelpers.SetupSequencerTest(t, sd, log) - _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + _, verifier := actionsHelpers.SetupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) - batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ + batcher := actionsHelpers.NewL2Batcher(log, sd.RollupCfg, &actionsHelpers.BatcherCfg{ MinL1TxSize: 0, MaxL1TxSize: 40_000, // try a small batch size, to force the data to be split between more frames BatcherKey: dp.Secrets.Batcher, @@ -478,7 +459,7 @@ func BigL2Txs(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { } sequencer.ActL1HeadSignal(t) sequencer.ActL2StartBlock(t) - baseFee := engine.l2Chain.CurrentBlock().BaseFee // this will go quite high, since so many consecutive blocks are filled at capacity. + baseFee := engine.L2Chain().CurrentBlock().BaseFee // this will go quite high, since so many consecutive blocks are filled at capacity. // fill the block with large L2 txs from alice for n := aliceNonce; ; n++ { require.NoError(t, err) @@ -488,7 +469,7 @@ func BigL2Txs(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { require.NoError(t, err) gas, err := core.IntrinsicGas(data, nil, false, true, true, false) require.NoError(t, err) - if gas > engine.engineApi.RemainingBlockGas() { + if gas > engine.EngineApi.RemainingBlockGas() { break } tx := types.MustSignNewTx(dp.Secrets.Alice, signer, &types.DynamicFeeTx{ @@ -505,12 +486,12 @@ func BigL2Txs(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { engine.ActL2IncludeTx(dp.Addresses.Alice)(t) } sequencer.ActL2EndBlock(t) - for batcher.l2BufferedBlock.Number < sequencer.SyncStatus().UnsafeL2.Number { + for batcher.L2BufferedBlock.Number < sequencer.SyncStatus().UnsafeL2.Number { // if we run out of space, close the channel and submit all the txs if err := batcher.Buffer(t); errors.Is(err, derive.ErrTooManyRLPBytes) || errors.Is(err, derive.ErrCompressorFull) { - log.Info("flushing filled channel to batch txs", "id", batcher.l2ChannelOut.ID()) + log.Info("flushing filled channel to batch txs", "id", batcher.L2ChannelOut.ID()) batcher.ActL2ChannelClose(t) - for batcher.l2ChannelOut != nil { + for batcher.L2ChannelOut != nil { batcher.ActL2BatchSubmit(t, batcherTxOpts) } } @@ -518,16 +499,16 @@ func BigL2Txs(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { } // if anything is left in the channel, submit it - if batcher.l2ChannelOut != nil { - log.Info("flushing trailing channel to batch txs", "id", batcher.l2ChannelOut.ID()) + if batcher.L2ChannelOut != nil { + log.Info("flushing trailing channel to batch txs", "id", batcher.L2ChannelOut.ID()) batcher.ActL2ChannelClose(t) - for batcher.l2ChannelOut != nil { + for batcher.L2ChannelOut != nil { batcher.ActL2BatchSubmit(t, batcherTxOpts) } } // build L1 blocks until we're out of txs - txs, _ := miner.eth.TxPool().ContentFrom(dp.Addresses.Batcher) + txs, _ := miner.Eth.TxPool().ContentFrom(dp.Addresses.Batcher) for { if len(txs) == 0 { break @@ -538,7 +519,7 @@ func BigL2Txs(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { break } tx := txs[0] - if miner.l1GasPool.Gas() < tx.Gas() { // fill the L1 block with batcher txs until we run out of gas + if miner.L1GasPool.Gas() < tx.Gas() { // fill the L1 block with batcher txs until we run out of gas break } log.Info("including batcher tx", "nonce", tx.Nonce()) diff --git a/op-e2e/actions/batch_queue_test.go b/op-e2e/actions/derivation/batch_queue_test.go similarity index 62% rename from op-e2e/actions/batch_queue_test.go rename to op-e2e/actions/derivation/batch_queue_test.go index e5132a85ac94..af5b7231b884 100644 --- a/op-e2e/actions/batch_queue_test.go +++ b/op-e2e/actions/derivation/batch_queue_test.go @@ -1,13 +1,16 @@ -package actions +package derivation import ( "testing" altda "github.com/ethereum-optimism/optimism/op-alt-da" batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" + "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" + upgradesHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/upgrades/helpers" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-node/node/safedb" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/ethereum-optimism/optimism/op-node/rollup/sync" "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum/go-ethereum/log" @@ -20,7 +23,7 @@ import ( // This is a regression test, previously the pipeline encountered got stuck in a reset loop with the error: // buffered L1 chain epoch %s in batch queue does not match safe head origin %s func TestDeriveChainFromNearL1Genesis(gt *testing.T) { - t := NewDefaultTesting(gt) + t := helpers.NewDefaultTesting(gt) p := &e2eutils.TestParams{ MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) SequencerWindowSize: 24, @@ -29,22 +32,22 @@ func TestDeriveChainFromNearL1Genesis(gt *testing.T) { } dp := e2eutils.MakeDeployParams(t, p) // do not activate Delta hardfork for verifier - applyDeltaTimeOffset(dp, nil) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + upgradesHelpers.ApplyDeltaTimeOffset(dp, nil) + sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc) logger := testlog.Logger(t, log.LevelInfo) - miner, seqEngine, sequencer := setupSequencerTest(t, sd, logger) + miner, seqEngine, sequencer := helpers.SetupSequencerTest(t, sd, logger) miner.ActEmptyBlock(t) - require.EqualValues(gt, 1, miner.l1Chain.CurrentBlock().Number.Uint64()) + require.EqualValues(gt, 1, miner.L1Chain().CurrentBlock().Number.Uint64()) - ref, err := derive.L2BlockToBlockRef(sequencer.rollupCfg, seqEngine.l2Chain.Genesis()) + ref, err := derive.L2BlockToBlockRef(sequencer.RollupCfg, seqEngine.L2Chain().Genesis()) require.NoError(gt, err) require.EqualValues(gt, 0, ref.L1Origin.Number) sequencer.ActL1HeadSignal(t) sequencer.ActBuildToL1Head(t) - l2BlockNum := seqEngine.l2Chain.CurrentBlock().Number.Uint64() - ref, err = derive.L2BlockToBlockRef(sequencer.rollupCfg, seqEngine.l2Chain.GetBlockByNumber(l2BlockNum)) + l2BlockNum := seqEngine.L2Chain().CurrentBlock().Number.Uint64() + ref, err = derive.L2BlockToBlockRef(sequencer.RollupCfg, seqEngine.L2Chain().GetBlockByNumber(l2BlockNum)) require.NoError(gt, err) require.EqualValues(gt, 1, ref.L1Origin.Number) @@ -52,7 +55,7 @@ func TestDeriveChainFromNearL1Genesis(gt *testing.T) { rollupSeqCl := sequencer.RollupClient() // Force batcher to submit SingularBatches to L1. - batcher := NewL2Batcher(logger, sd.RollupCfg, &BatcherCfg{ + batcher := helpers.NewL2Batcher(logger, sd.RollupCfg, &helpers.BatcherCfg{ MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Batcher, @@ -60,40 +63,40 @@ func TestDeriveChainFromNearL1Genesis(gt *testing.T) { }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) batcher.ActSubmitAll(t) - require.EqualValues(gt, l2BlockNum, batcher.l2BufferedBlock.Number) + require.EqualValues(gt, l2BlockNum, batcher.L2BufferedBlock.Number) // confirm batch on L1 miner.ActL1StartBlock(12)(t) miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) miner.ActL1EndBlock(t) - bl := miner.l1Chain.CurrentBlock() + bl := miner.L1Chain().CurrentBlock() logger.Info("Produced L1 block with batch", - "num", miner.l1Chain.CurrentBlock().Number.Uint64(), - "txs", len(miner.l1Chain.GetBlockByHash(bl.Hash()).Transactions())) + "num", miner.L1Chain().CurrentBlock().Number.Uint64(), + "txs", len(miner.L1Chain().GetBlockByHash(bl.Hash()).Transactions())) // Process batches so safe head updates sequencer.ActL1HeadSignal(t) sequencer.ActL2PipelineFull(t) - require.EqualValues(gt, l2BlockNum, seqEngine.l2Chain.CurrentSafeBlock().Number.Uint64()) + require.EqualValues(gt, l2BlockNum, seqEngine.L2Chain().CurrentSafeBlock().Number.Uint64()) // Finalize L1 and process so L2 finalized updates - miner.ActL1Safe(t, miner.l1Chain.CurrentBlock().Number.Uint64()) - miner.ActL1Finalize(t, miner.l1Chain.CurrentBlock().Number.Uint64()) + miner.ActL1Safe(t, miner.L1Chain().CurrentBlock().Number.Uint64()) + miner.ActL1Finalize(t, miner.L1Chain().CurrentBlock().Number.Uint64()) sequencer.ActL1SafeSignal(t) sequencer.ActL1FinalizedSignal(t) sequencer.ActL2PipelineFull(t) - require.EqualValues(gt, l2BlockNum, seqEngine.l2Chain.CurrentFinalBlock().Number.Uint64()) + require.EqualValues(gt, l2BlockNum, seqEngine.L2Chain().CurrentFinalBlock().Number.Uint64()) // Create a new verifier using the existing engine so it already has the safe and finalized heads set. // This is the same situation as if op-node restarted at this point. l2Cl, err := sources.NewEngineClient(seqEngine.RPCClient(), logger, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(gt, err) - verifier := NewL2Verifier(t, logger, sequencer.l1, miner.BlobStore(), altda.Disabled, - l2Cl, sequencer.rollupCfg, sequencer.syncCfg, safedb.Disabled, nil) + verifier := helpers.NewL2Verifier(t, logger, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), altda.Disabled, + l2Cl, sequencer.RollupCfg, &sync.Config{}, safedb.Disabled, nil) verifier.ActL2PipelineFull(t) // Should not get stuck in a reset loop forever - require.EqualValues(gt, l2BlockNum, seqEngine.l2Chain.CurrentSafeBlock().Number.Uint64()) - require.EqualValues(gt, l2BlockNum, seqEngine.l2Chain.CurrentFinalBlock().Number.Uint64()) - syncStatus := verifier.syncStatus.SyncStatus() + require.EqualValues(gt, l2BlockNum, seqEngine.L2Chain().CurrentSafeBlock().Number.Uint64()) + require.EqualValues(gt, l2BlockNum, seqEngine.L2Chain().CurrentFinalBlock().Number.Uint64()) + syncStatus := verifier.SyncStatus() require.EqualValues(gt, l2BlockNum, syncStatus.SafeL2.Number) require.EqualValues(gt, l2BlockNum, syncStatus.FinalizedL2.Number) } diff --git a/op-e2e/actions/blocktime_test.go b/op-e2e/actions/derivation/blocktime_test.go similarity index 89% rename from op-e2e/actions/blocktime_test.go rename to op-e2e/actions/derivation/blocktime_test.go index 20f644887697..ec192d08ad78 100644 --- a/op-e2e/actions/blocktime_test.go +++ b/op-e2e/actions/derivation/blocktime_test.go @@ -1,9 +1,11 @@ -package actions +package derivation import ( "math/big" "testing" + actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" + upgradesHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/upgrades/helpers" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum/go-ethereum/common/hexutil" @@ -44,16 +46,16 @@ func TestBlockTimeBatchType(t *testing.T) { // window. // This is a regression test against the bug fixed in PR #4566 func BatchInLastPossibleBlocks(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) - applyDeltaTimeOffset(dp, deltaTimeOffset) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) + upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset) dp.DeployConfig.SequencerWindowSize = 4 dp.DeployConfig.L2BlockTime = 2 - sd := e2eutils.Setup(t, dp, DefaultAlloc) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) - sd, _, miner, sequencer, sequencerEngine, _, _, batcher := setupReorgTestActors(t, dp, sd, log) + sd, _, miner, sequencer, sequencerEngine, _, _, batcher := actionsHelpers.SetupReorgTestActors(t, dp, sd, log) signer := types.LatestSigner(sd.L2Cfg.Config) cl := sequencerEngine.EthClient() @@ -63,7 +65,7 @@ func BatchInLastPossibleBlocks(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { ChainID: sd.L2Cfg.Config.ChainID, Nonce: aliceNonce, GasTipCap: big.NewInt(2 * params.GWei), - GasFeeCap: new(big.Int).Add(miner.l1Chain.CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), + GasFeeCap: new(big.Int).Add(miner.L1Chain().CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), Gas: params.TxGas, To: &dp.Addresses.Bob, Value: e2eutils.Ether(2), @@ -78,7 +80,7 @@ func BatchInLastPossibleBlocks(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { sequencer.ActL2EndBlock(t) } verifyChainStateOnSequencer := func(l1Number, unsafeHead, unsafeHeadOrigin, safeHead, safeHeadOrigin uint64) { - require.Equal(t, l1Number, miner.l1Chain.CurrentHeader().Number.Uint64()) + require.Equal(t, l1Number, miner.L1Chain().CurrentHeader().Number.Uint64()) require.Equal(t, unsafeHead, sequencer.L2Unsafe().Number) require.Equal(t, unsafeHeadOrigin, sequencer.L2Unsafe().L1Origin.Number) require.Equal(t, safeHead, sequencer.L2Safe().Number) @@ -155,8 +157,8 @@ func BatchInLastPossibleBlocks(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // At this point it can verify that the batches where properly generated. // Note: It batches submits when possible. func LargeL1Gaps(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) dp.DeployConfig.L1BlockTime = 4 dp.DeployConfig.L2BlockTime = 2 dp.DeployConfig.SequencerWindowSize = 4 @@ -165,11 +167,11 @@ func LargeL1Gaps(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { dp.DeployConfig.L2GenesisFjordTimeOffset = nil // TODO(client-pod#831): The Ecotone (and Fjord) activation blocks don't include user txs, // so disabling these forks for now. - applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) - sd, _, miner, sequencer, sequencerEngine, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + sd, _, miner, sequencer, sequencerEngine, verifier, _, batcher := actionsHelpers.SetupReorgTestActors(t, dp, sd, log) signer := types.LatestSigner(sd.L2Cfg.Config) cl := sequencerEngine.EthClient() @@ -180,7 +182,7 @@ func LargeL1Gaps(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { ChainID: sd.L2Cfg.Config.ChainID, Nonce: aliceNonce, GasTipCap: big.NewInt(2 * params.GWei), - GasFeeCap: new(big.Int).Add(miner.l1Chain.CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), + GasFeeCap: new(big.Int).Add(miner.L1Chain().CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), Gas: params.TxGas, To: &dp.Addresses.Bob, Value: e2eutils.Ether(2), @@ -196,7 +198,7 @@ func LargeL1Gaps(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { } verifyChainStateOnSequencer := func(l1Number, unsafeHead, unsafeHeadOrigin, safeHead, safeHeadOrigin uint64) { - require.Equal(t, l1Number, miner.l1Chain.CurrentHeader().Number.Uint64()) + require.Equal(t, l1Number, miner.L1Chain().CurrentHeader().Number.Uint64()) require.Equal(t, unsafeHead, sequencer.L2Unsafe().Number) require.Equal(t, unsafeHeadOrigin, sequencer.L2Unsafe().L1Origin.Number) require.Equal(t, safeHead, sequencer.L2Safe().Number) @@ -204,7 +206,7 @@ func LargeL1Gaps(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { } verifyChainStateOnVerifier := func(l1Number, unsafeHead, unsafeHeadOrigin, safeHead, safeHeadOrigin uint64) { - require.Equal(t, l1Number, miner.l1Chain.CurrentHeader().Number.Uint64()) + require.Equal(t, l1Number, miner.L1Chain().CurrentHeader().Number.Uint64()) require.Equal(t, unsafeHead, verifier.L2Unsafe().Number) require.Equal(t, unsafeHeadOrigin, verifier.L2Unsafe().L1Origin.Number) require.Equal(t, safeHead, verifier.L2Safe().Number) diff --git a/op-e2e/actions/l2_verifier_test.go b/op-e2e/actions/derivation/l2_verifier_test.go similarity index 55% rename from op-e2e/actions/l2_verifier_test.go rename to op-e2e/actions/derivation/l2_verifier_test.go index 75c1efbc176c..2f4fce628d53 100644 --- a/op-e2e/actions/l2_verifier_test.go +++ b/op-e2e/actions/derivation/l2_verifier_test.go @@ -1,41 +1,19 @@ -package actions +package derivation import ( "testing" + "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/require" - altda "github.com/ethereum-optimism/optimism/op-alt-da" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" - "github.com/ethereum-optimism/optimism/op-node/rollup/derive" - "github.com/ethereum-optimism/optimism/op-node/rollup/sync" "github.com/ethereum-optimism/optimism/op-service/testlog" ) -func setupVerifier(t Testing, sd *e2eutils.SetupData, log log.Logger, - l1F derive.L1Fetcher, blobSrc derive.L1BlobsFetcher, syncCfg *sync.Config, opts ...VerifierOpt) (*L2Engine, *L2Verifier) { - cfg := DefaultVerifierCfg() - for _, opt := range opts { - opt(cfg) - } - jwtPath := e2eutils.WriteDefaultJWT(t) - engine := NewL2Engine(t, log.New("role", "verifier-engine"), sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath, EngineWithP2P()) - engCl := engine.EngineClient(t, sd.RollupCfg) - verifier := NewL2Verifier(t, log.New("role", "verifier"), l1F, blobSrc, altda.Disabled, engCl, sd.RollupCfg, syncCfg, cfg.SafeHeadListener, cfg.InteropBackend) - return engine, verifier -} - -func setupVerifierOnlyTest(t Testing, sd *e2eutils.SetupData, log log.Logger) (*L1Miner, *L2Engine, *L2Verifier) { - miner := NewL1Miner(t, log, sd.L1Cfg) - l1Cl := miner.L1Client(t, sd.RollupCfg) - engine, verifier := setupVerifier(t, sd, log, l1Cl, miner.BlobStore(), &sync.Config{}) - return miner, engine, verifier -} - func TestL2Verifier_SequenceWindow(gt *testing.T) { - t := NewDefaultTesting(gt) + t := helpers.NewDefaultTesting(gt) p := &e2eutils.TestParams{ MaxSequencerDrift: 10, SequencerWindowSize: 24, @@ -43,26 +21,26 @@ func TestL2Verifier_SequenceWindow(gt *testing.T) { L1BlockTime: 15, } dp := e2eutils.MakeDeployParams(t, p) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) - miner, engine, verifier := setupVerifierOnlyTest(t, sd, log) + miner, engine, verifier := helpers.SetupVerifierOnlyTest(t, sd, log) miner.ActL1SetFeeRecipient(common.Address{'A'}) // Make two sequence windows worth of empty L1 blocks. After we pass the first sequence window, the L2 chain should get blocks - for miner.l1Chain.CurrentBlock().Number.Uint64() < sd.RollupCfg.SeqWindowSize*2 { + for miner.L1Chain().CurrentBlock().Number.Uint64() < sd.RollupCfg.SeqWindowSize*2 { miner.ActL1StartBlock(10)(t) miner.ActL1EndBlock(t) verifier.ActL2PipelineFull(t) - l1Head := miner.l1Chain.CurrentBlock().Number.Uint64() + l1Head := miner.L1Chain().CurrentBlock().Number.Uint64() expectedL1Origin := uint64(0) // as soon as we complete the sequence window, we force-adopt the L1 origin if l1Head >= sd.RollupCfg.SeqWindowSize { expectedL1Origin = l1Head - sd.RollupCfg.SeqWindowSize } require.Equal(t, expectedL1Origin, verifier.SyncStatus().SafeL2.L1Origin.Number, "L1 origin is forced in, given enough L1 blocks pass by") - require.LessOrEqual(t, miner.l1Chain.GetBlockByNumber(expectedL1Origin).Time(), engine.l2Chain.CurrentBlock().Time, "L2 time higher than L1 origin time") + require.LessOrEqual(t, miner.L1Chain().GetBlockByNumber(expectedL1Origin).Time(), engine.L2Chain().CurrentBlock().Time, "L2 time higher than L1 origin time") } tip2N := verifier.SyncStatus() @@ -77,13 +55,13 @@ func TestL2Verifier_SequenceWindow(gt *testing.T) { miner.ActL1SetFeeRecipient(common.Address{'B'}) miner.ActL1StartBlock(10)(t) miner.ActL1EndBlock(t) - reorgL1Block := miner.l1Chain.CurrentBlock() + reorgL1Block := miner.L1Chain().CurrentBlock() // Still no reorg, we need more L1 blocks first, before the reorged L1 block is forced in by sequence window verifier.ActL2PipelineFull(t) require.Equal(t, tip2N.SafeL2, verifier.SyncStatus().SafeL2) - for miner.l1Chain.CurrentBlock().Number.Uint64() < sd.RollupCfg.SeqWindowSize*2 { + for miner.L1Chain().CurrentBlock().Number.Uint64() < sd.RollupCfg.SeqWindowSize*2 { miner.ActL1StartBlock(10)(t) miner.ActL1EndBlock(t) } @@ -95,6 +73,6 @@ func TestL2Verifier_SequenceWindow(gt *testing.T) { // Now it will reorg verifier.ActL2PipelineFull(t) - got := miner.l1Chain.GetBlockByHash(miner.l1Chain.GetBlockByHash(verifier.SyncStatus().SafeL2.L1Origin.Hash).Hash()) + got := miner.L1Chain().GetBlockByHash(miner.L1Chain().GetBlockByHash(verifier.SyncStatus().SafeL2.L1Origin.Hash).Hash()) require.Equal(t, reorgL1Block.Hash(), got.Hash(), "must have reorged L2 chain to the new L1 chain") } diff --git a/op-e2e/actions/reorg_test.go b/op-e2e/actions/derivation/reorg_test.go similarity index 89% rename from op-e2e/actions/reorg_test.go rename to op-e2e/actions/derivation/reorg_test.go index 1ffd512d328f..6551b314c1ea 100644 --- a/op-e2e/actions/reorg_test.go +++ b/op-e2e/actions/derivation/reorg_test.go @@ -1,4 +1,4 @@ -package actions +package derivation import ( "math/big" @@ -6,6 +6,8 @@ import ( "path" "testing" + actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" + upgradesHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/upgrades/helpers" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" @@ -16,34 +18,12 @@ import ( altda "github.com/ethereum-optimism/optimism/op-alt-da" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" - "github.com/ethereum-optimism/optimism/op-node/rollup/sync" "github.com/ethereum-optimism/optimism/op-service/client" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-service/testlog" ) -func setupReorgTest(t Testing, config *e2eutils.TestParams, deltaTimeOffset *hexutil.Uint64) (*e2eutils.SetupData, *e2eutils.DeployParams, *L1Miner, *L2Sequencer, *L2Engine, *L2Verifier, *L2Engine, *L2Batcher) { - dp := e2eutils.MakeDeployParams(t, config) - applyDeltaTimeOffset(dp, deltaTimeOffset) - - sd := e2eutils.Setup(t, dp, DefaultAlloc) - log := testlog.Logger(t, log.LevelDebug) - - return setupReorgTestActors(t, dp, sd, log) -} - -func setupReorgTestActors(t Testing, dp *e2eutils.DeployParams, sd *e2eutils.SetupData, log log.Logger) (*e2eutils.SetupData, *e2eutils.DeployParams, *L1Miner, *L2Sequencer, *L2Engine, *L2Verifier, *L2Engine, *L2Batcher) { - miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) - miner.ActL1SetFeeRecipient(common.Address{'A'}) - sequencer.ActL2PipelineFull(t) - verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) - rollupSeqCl := sequencer.RollupClient() - batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), - rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) - return sd, dp, miner, sequencer, seqEngine, verifier, verifEngine, batcher -} - // TestReorgBatchType run each reorg-related test case in singular batch mode and span batch mode. func TestReorgBatchType(t *testing.T) { tests := []struct { @@ -74,8 +54,8 @@ func TestReorgBatchType(t *testing.T) { } func ReorgOrphanBlock(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { - t := NewDefaultTesting(gt) - sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, DefaultRollupTestParams, deltaTimeOffset) + t := actionsHelpers.NewDefaultTesting(gt) + sd, _, miner, sequencer, _, verifier, verifierEng, batcher := actionsHelpers.SetupReorgTest(t, actionsHelpers.DefaultRollupTestParams, deltaTimeOffset) verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg) sequencer.ActL2PipelineFull(t) @@ -94,7 +74,7 @@ func ReorgOrphanBlock(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // new L1 block with L2 batch miner.ActL1StartBlock(12)(t) miner.ActL1IncludeTx(sd.RollupCfg.Genesis.SystemConfig.BatcherAddr)(t) - batchTx := miner.l1Transactions[0] + batchTx := miner.L1Transactions[0] miner.ActL1EndBlock(t) // verifier picks up the L2 chain that was submitted @@ -123,7 +103,7 @@ func ReorgOrphanBlock(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { miner.ActL1SetFeeRecipient(common.Address{'C'}) // note: the geth tx pool reorgLoop is too slow (responds to chain head events, but async), // and there's no way to manually trigger runReorg, so we re-insert it ourselves. - require.NoError(t, miner.eth.TxPool().Add([]*types.Transaction{batchTx}, true, true)[0]) + require.NoError(t, miner.Eth.TxPool().Add([]*types.Transaction{batchTx}, true, true)[0]) // need to re-insert previously included tx into the block miner.ActL1IncludeTx(sd.RollupCfg.Genesis.SystemConfig.BatcherAddr)(t) miner.ActL1EndBlock(t) @@ -142,8 +122,8 @@ func ReorgOrphanBlock(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { } func ReorgFlipFlop(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { - t := NewDefaultTesting(gt) - sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, DefaultRollupTestParams, deltaTimeOffset) + t := actionsHelpers.NewDefaultTesting(gt) + sd, _, miner, sequencer, _, verifier, verifierEng, batcher := actionsHelpers.SetupReorgTest(t, actionsHelpers.DefaultRollupTestParams, deltaTimeOffset) minerCl := miner.L1Client(t, sd.RollupCfg) verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg) checkVerifEngine := func() { @@ -172,7 +152,7 @@ func ReorgFlipFlop(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { miner.ActL1SetFeeRecipient(common.Address{'A', 1}) miner.ActL1StartBlock(12)(t) miner.ActL1IncludeTx(sd.RollupCfg.Genesis.SystemConfig.BatcherAddr)(t) - batchTxA := miner.l1Transactions[0] + batchTxA := miner.L1Transactions[0] miner.ActL1EndBlock(t) // verifier picks up the L2 chain that was submitted @@ -195,7 +175,7 @@ func ReorgFlipFlop(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // re-include the batch tx that submitted L2 chain data that pointed to A0, in the new block B1 miner.ActL1SetFeeRecipient(common.Address{'B', 1}) miner.ActL1StartBlock(12)(t) - require.NoError(t, miner.eth.TxPool().Add([]*types.Transaction{batchTxA}, true, true)[0]) + require.NoError(t, miner.Eth.TxPool().Add([]*types.Transaction{batchTxA}, true, true)[0]) miner.ActL1IncludeTx(sd.RollupCfg.Genesis.SystemConfig.BatcherAddr)(t) miner.ActL1EndBlock(t) @@ -219,7 +199,7 @@ func ReorgFlipFlop(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // after delta hard fork require.Zero(t, verifier.L2Safe().Number, "safe head is at genesis block because span batch referenced reorged L1 chain is not accepted") require.Equal(t, verifier.L2Unsafe().ID(), sequencer.L2Unsafe().ParentID(), "head is at the highest unsafe block that references canonical L1 chain(genesis block)") - batcher.l2BufferedBlock = eth.L2BlockRef{} // must reset batcher to resubmit blocks included in the last batch + batcher.L2BufferedBlock = eth.L2BlockRef{} // must reset batcher to resubmit blocks included in the last batch } checkVerifEngine() @@ -260,7 +240,7 @@ func ReorgFlipFlop(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { miner.ActL1SetFeeRecipient(common.Address{'A', 2}) miner.ActL1StartBlock(12)(t) - require.NoError(t, miner.eth.TxPool().Add([]*types.Transaction{batchTxA}, true, true)[0]) // replay chain A batches, but now in A2 instead of A1 + require.NoError(t, miner.Eth.TxPool().Add([]*types.Transaction{batchTxA}, true, true)[0]) // replay chain A batches, but now in A2 instead of A1 miner.ActL1IncludeTx(sd.RollupCfg.Genesis.SystemConfig.BatcherAddr)(t) miner.ActL1EndBlock(t) @@ -356,10 +336,10 @@ func ReorgFlipFlop(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // - Unsafe head is 62 // - Safe head is 42 func DeepReorg(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { - t := NewDefaultTesting(gt) + t := actionsHelpers.NewDefaultTesting(gt) // Create actor and verification engine client - sd, dp, miner, sequencer, seqEngine, verifier, verifierEng, batcher := setupReorgTest(t, &e2eutils.TestParams{ + sd, dp, miner, sequencer, seqEngine, verifier, verifierEng, batcher := actionsHelpers.SetupReorgTest(t, &e2eutils.TestParams{ MaxSequencerDrift: 40, SequencerWindowSize: 20, ChannelTimeout: 120, @@ -377,13 +357,13 @@ func DeepReorg(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // Set up alice log := testlog.Logger(t, log.LevelDebug) addresses := e2eutils.CollectAddresses(sd, dp) - l2UserEnv := &BasicUserEnv[*L2Bindings]{ + l2UserEnv := &actionsHelpers.BasicUserEnv[*actionsHelpers.L2Bindings]{ EthCl: l2Client, Signer: types.LatestSigner(sd.L2Cfg.Config), AddressCorpora: addresses, - Bindings: NewL2Bindings(t, l2Client, seqEngine.GethClient()), + Bindings: actionsHelpers.NewL2Bindings(t, l2Client, seqEngine.GethClient()), } - alice := NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b))) + alice := actionsHelpers.NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b))) alice.L2.SetUserEnv(l2UserEnv) // Run one iteration of the L2 derivation pipeline @@ -593,29 +573,29 @@ type rpcWrapper struct { // RestartOpGeth tests that the sequencer can restart its execution engine without rollup-node restart, // including recovering the finalized/safe state of L2 chain without reorging. func RestartOpGeth(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { - t := NewDefaultTesting(gt) + t := actionsHelpers.NewDefaultTesting(gt) dbPath := path.Join(t.TempDir(), "testdb") dbOption := func(_ *ethconfig.Config, nodeCfg *node.Config) error { nodeCfg.DataDir = dbPath return nil } - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) - applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) + upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) jwtPath := e2eutils.WriteDefaultJWT(t) // L1 - miner := NewL1Miner(t, log, sd.L1Cfg) + miner := actionsHelpers.NewL1Miner(t, log, sd.L1Cfg) l1F, err := sources.NewL1Client(miner.RPCClient(), log, nil, sources.L1ClientDefaultConfig(sd.RollupCfg, false, sources.RPCKindStandard)) require.NoError(t, err) // Sequencer - seqEng := NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath, dbOption) + seqEng := actionsHelpers.NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath, dbOption) engRpc := &rpcWrapper{seqEng.RPCClient()} l2Cl, err := sources.NewEngineClient(engRpc, log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(t, err) - sequencer := NewL2Sequencer(t, log, l1F, miner.BlobStore(), altda.Disabled, l2Cl, sd.RollupCfg, 0, nil) + sequencer := actionsHelpers.NewL2Sequencer(t, log, l1F, miner.BlobStore(), altda.Disabled, l2Cl, sd.RollupCfg, 0, nil) - batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + batcher := actionsHelpers.NewL2Batcher(log, sd.RollupCfg, actionsHelpers.DefaultBatcherCfg(dp), sequencer.RollupClient(), miner.EthClient(), seqEng.EthClient(), seqEng.EngineClient(t, sd.RollupCfg)) // start @@ -664,7 +644,7 @@ func RestartOpGeth(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // close the sequencer engine require.NoError(t, seqEng.Close()) // and start a new one with same db path - seqEngNew := NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath, dbOption) + seqEngNew := actionsHelpers.NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath, dbOption) // swap in the new rpc. This is as close as we can get to reconnecting to a new in-memory rpc connection engRpc.RPC = seqEngNew.RPCClient() @@ -686,35 +666,35 @@ func RestartOpGeth(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // L2 block (compared to something already secured by the first sequencer): // the alt block is not synced by the verifier, in unsafe and safe sync modes. func ConflictingL2Blocks(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) - applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) + upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) - sd, _, miner, sequencer, seqEng, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + sd, _, miner, sequencer, seqEng, verifier, _, batcher := actionsHelpers.SetupReorgTestActors(t, dp, sd, log) // Extra setup: a full alternative sequencer, sequencer engine, and batcher jwtPath := e2eutils.WriteDefaultJWT(t) - altSeqEng := NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath) + altSeqEng := actionsHelpers.NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath) altSeqEngCl, err := sources.NewEngineClient(altSeqEng.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(t, err) l1F, err := sources.NewL1Client(miner.RPCClient(), log, nil, sources.L1ClientDefaultConfig(sd.RollupCfg, false, sources.RPCKindStandard)) require.NoError(t, err) - altSequencer := NewL2Sequencer(t, log, l1F, miner.BlobStore(), altda.Disabled, altSeqEngCl, sd.RollupCfg, 0, nil) - altBatcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + altSequencer := actionsHelpers.NewL2Sequencer(t, log, l1F, miner.BlobStore(), altda.Disabled, altSeqEngCl, sd.RollupCfg, 0, nil) + altBatcher := actionsHelpers.NewL2Batcher(log, sd.RollupCfg, actionsHelpers.DefaultBatcherCfg(dp), altSequencer.RollupClient(), miner.EthClient(), altSeqEng.EthClient(), altSeqEng.EngineClient(t, sd.RollupCfg)) // And set up user Alice, using the alternative sequencer endpoint l2Cl := altSeqEng.EthClient() addresses := e2eutils.CollectAddresses(sd, dp) - l2UserEnv := &BasicUserEnv[*L2Bindings]{ + l2UserEnv := &actionsHelpers.BasicUserEnv[*actionsHelpers.L2Bindings]{ EthCl: l2Cl, Signer: types.LatestSigner(sd.L2Cfg.Config), AddressCorpora: addresses, - Bindings: NewL2Bindings(t, l2Cl, altSeqEng.GethClient()), + Bindings: actionsHelpers.NewL2Bindings(t, l2Cl, altSeqEng.GethClient()), } - alice := NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(1234))) + alice := actionsHelpers.NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(1234))) alice.L2.SetUserEnv(l2UserEnv) sequencer.ActL2PipelineFull(t) @@ -756,7 +736,7 @@ func ConflictingL2Blocks(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { altSeqEng.ActL2IncludeTx(alice.Address())(t) altSequencer.ActL2EndBlock(t) - conflictBlock := seqEng.l2Chain.GetBlockByNumber(altSequencer.L2Unsafe().Number) + conflictBlock := seqEng.L2Chain().GetBlockByNumber(altSequencer.L2Unsafe().Number) require.NotEqual(t, conflictBlock.Hash(), altSequencer.L2Unsafe().Hash, "alt sequencer has built a conflicting block") // give the unsafe block to the verifier, and see if it reorgs because of any unsafe inputs @@ -776,7 +756,7 @@ func ConflictingL2Blocks(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { miner.ActL1StartBlock(12)(t) miner.ActL1IncludeTx(sd.RollupCfg.Genesis.SystemConfig.BatcherAddr)(t) miner.ActL1EndBlock(t) - l1Number := miner.l1Chain.CurrentHeader().Number.Uint64() + l1Number := miner.L1Chain().CurrentHeader().Number.Uint64() // show latest L1 block with new batch data to verifier, and make it sync. verifier.ActL1HeadSignal(t) @@ -793,24 +773,24 @@ func ConflictingL2Blocks(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { } func SyncAfterReorg(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { - t := NewDefaultTesting(gt) + t := actionsHelpers.NewDefaultTesting(gt) testingParams := e2eutils.TestParams{ MaxSequencerDrift: 60, SequencerWindowSize: 4, ChannelTimeout: 2, L1BlockTime: 12, } - sd, dp, miner, sequencer, seqEngine, verifier, _, batcher := setupReorgTest(t, &testingParams, deltaTimeOffset) + sd, dp, miner, sequencer, seqEngine, verifier, _, batcher := actionsHelpers.SetupReorgTest(t, &testingParams, deltaTimeOffset) l2Client := seqEngine.EthClient() log := testlog.Logger(t, log.LevelDebug) addresses := e2eutils.CollectAddresses(sd, dp) - l2UserEnv := &BasicUserEnv[*L2Bindings]{ + l2UserEnv := &actionsHelpers.BasicUserEnv[*actionsHelpers.L2Bindings]{ EthCl: l2Client, Signer: types.LatestSigner(sd.L2Cfg.Config), AddressCorpora: addresses, - Bindings: NewL2Bindings(t, l2Client, seqEngine.GethClient()), + Bindings: actionsHelpers.NewL2Bindings(t, l2Client, seqEngine.GethClient()), } - alice := NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b))) + alice := actionsHelpers.NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b))) alice.L2.SetUserEnv(l2UserEnv) sequencer.ActL2PipelineFull(t) @@ -820,11 +800,11 @@ func SyncAfterReorg(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { miner.ActL1SetFeeRecipient(common.Address{'A', 0}) miner.ActEmptyBlock(t) sequencer.ActL1HeadSignal(t) - for sequencer.engine.UnsafeL2Head().L1Origin.Number < sequencer.syncStatus.L1Head().Number { + for sequencer.L2Unsafe().L1Origin.Number < sequencer.SyncStatus().HeadL1.Number { // build L2 blocks until the L1 origin is the current L1 head(A0) sequencer.ActL2PipelineFull(t) sequencer.ActL2StartBlock(t) - if sequencer.engine.UnsafeL2Head().Number == 11 { + if sequencer.L2Unsafe().Number == 11 { // include a user tx at L2 block #12 to make a state transition alice.L2.ActResetTxOpts(t) alice.L2.ActSetTxToAddr(&dp.Addresses.Bob)(t) diff --git a/op-e2e/actions/system_config_test.go b/op-e2e/actions/derivation/system_config_test.go similarity index 87% rename from op-e2e/actions/system_config_test.go rename to op-e2e/actions/derivation/system_config_test.go index 406ca0a16983..bb62001de4a2 100644 --- a/op-e2e/actions/system_config_test.go +++ b/op-e2e/actions/derivation/system_config_test.go @@ -1,10 +1,12 @@ -package actions +package derivation import ( "math/big" "math/rand" "testing" + actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" + upgradesHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/upgrades/helpers" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -49,27 +51,27 @@ func TestSystemConfigBatchType(t *testing.T) { // BatcherKeyRotation tests that batcher A can operate, then be replaced with batcher B, then ignore old batcher A, // and that the change to batcher B is reverted properly upon reorg of L1. func BatcherKeyRotation(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { - t := NewDefaultTesting(gt) + t := actionsHelpers.NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) dp.DeployConfig.L2BlockTime = 2 - applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) - miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) + miner, seqEngine, sequencer := actionsHelpers.SetupSequencerTest(t, sd, log) miner.ActL1SetFeeRecipient(common.Address{'A'}) sequencer.ActL2PipelineFull(t) - _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + _, verifier := actionsHelpers.SetupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) rollupSeqCl := sequencer.RollupClient() // the default batcher - batcherA := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + batcherA := actionsHelpers.NewL2Batcher(log, sd.RollupCfg, actionsHelpers.DefaultBatcherCfg(dp), rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) // a batcher with a new key - altCfg := *DefaultBatcherCfg(dp) + altCfg := *actionsHelpers.DefaultBatcherCfg(dp) altCfg.BatcherKey = dp.Secrets.Bob - batcherB := NewL2Batcher(log, sd.RollupCfg, &altCfg, + batcherB := actionsHelpers.NewL2Batcher(log, sd.RollupCfg, &altCfg, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) sequencer.ActL2PipelineFull(t) @@ -114,7 +116,7 @@ func BatcherKeyRotation(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { receipt, err := miner.EthClient().TransactionReceipt(t.Ctx(), tx.Hash()) require.NoError(t, err) - cfgChangeL1BlockNum := miner.l1Chain.CurrentBlock().Number.Uint64() + cfgChangeL1BlockNum := miner.L1Chain().CurrentBlock().Number.Uint64() require.Equal(t, cfgChangeL1BlockNum, receipt.BlockNumber.Uint64()) // sequence L2 blocks, and submit with new batcher @@ -225,9 +227,9 @@ func BatcherKeyRotation(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // GPOParamsChange tests that the GPO params can be updated to adjust fees of L2 transactions, // and that the L1 data fees to the L2 transaction are applied correctly before, during and after the GPO update in L2. func GPOParamsChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) - applyDeltaTimeOffset(dp, deltaTimeOffset) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) + upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset) // activating Delta only, not Ecotone and further: // the GPO change assertions here all apply only for the Delta transition. @@ -236,14 +238,14 @@ func GPOParamsChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { dp.DeployConfig.L2GenesisFjordTimeOffset = nil dp.DeployConfig.L2GenesisGraniteTimeOffset = nil - sd := e2eutils.Setup(t, dp, DefaultAlloc) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) - miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) - batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + miner, seqEngine, sequencer := actionsHelpers.SetupSequencerTest(t, sd, log) + batcher := actionsHelpers.NewL2Batcher(log, sd.RollupCfg, actionsHelpers.DefaultBatcherCfg(dp), sequencer.RollupClient(), miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) - alice := NewBasicUser[any](log, dp.Secrets.Alice, rand.New(rand.NewSource(1234))) - alice.SetUserEnv(&BasicUserEnv[any]{ + alice := actionsHelpers.NewBasicUser[any](log, dp.Secrets.Alice, rand.New(rand.NewSource(1234))) + alice.SetUserEnv(&actionsHelpers.BasicUserEnv[any]{ EthCl: seqEngine.EthClient(), Signer: types.LatestSigner(sd.L2Cfg.Config), }) @@ -254,7 +256,7 @@ func GPOParamsChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { miner.ActEmptyBlock(t) sequencer.ActL1HeadSignal(t) sequencer.ActBuildToL1Head(t) - basefee := miner.l1Chain.CurrentBlock().BaseFee + basefee := miner.L1Chain().CurrentBlock().BaseFee // alice makes a L2 tx, sequencer includes it alice.ActResetTxOpts(t) @@ -299,7 +301,7 @@ func GPOParamsChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { miner.ActL1StartBlock(12)(t) miner.ActL1IncludeTx(dp.Addresses.SysCfgOwner)(t) miner.ActL1EndBlock(t) - basefeeGPOUpdate := miner.l1Chain.CurrentBlock().BaseFee + basefeeGPOUpdate := miner.L1Chain().CurrentBlock().BaseFee // build empty L2 chain, up to but excluding the L2 block with the L1 origin that processes the GPO change sequencer.ActL1HeadSignal(t) @@ -336,7 +338,7 @@ func GPOParamsChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // build more L2 blocks, with new L1 origin miner.ActEmptyBlock(t) - basefee = miner.l1Chain.CurrentBlock().BaseFee + basefee = miner.L1Chain().CurrentBlock().BaseFee sequencer.ActL1HeadSignal(t) sequencer.ActBuildToL1Head(t) // and Alice makes a tx again @@ -360,13 +362,13 @@ func GPOParamsChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // and that the L2 changes the gas limit instantly at the exact block that adopts the L1 origin with // the gas limit change event. And checks if a verifier node can reproduce the same gas limit change. func GasLimitChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) - applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) + upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) - miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) - batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + miner, seqEngine, sequencer := actionsHelpers.SetupSequencerTest(t, sd, log) + batcher := actionsHelpers.NewL2Batcher(log, sd.RollupCfg, actionsHelpers.DefaultBatcherCfg(dp), sequencer.RollupClient(), miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) sequencer.ActL2PipelineFull(t) @@ -374,7 +376,7 @@ func GasLimitChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { sequencer.ActL1HeadSignal(t) sequencer.ActBuildToL1Head(t) - oldGasLimit := seqEngine.l2Chain.CurrentBlock().GasLimit + oldGasLimit := seqEngine.L2Chain().CurrentBlock().GasLimit require.Equal(t, oldGasLimit, uint64(dp.DeployConfig.L2GenesisBlockGasLimit)) // change gas limit on L1 to triple what it was @@ -396,12 +398,12 @@ func GasLimitChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { sequencer.ActL1HeadSignal(t) sequencer.ActBuildToL1HeadExcl(t) - require.Equal(t, oldGasLimit, seqEngine.l2Chain.CurrentBlock().GasLimit) + require.Equal(t, oldGasLimit, seqEngine.L2Chain().CurrentBlock().GasLimit) require.Equal(t, uint64(1), sequencer.SyncStatus().UnsafeL2.L1Origin.Number) // now include the L1 block with the gaslimit change, and see if it changes as expected sequencer.ActBuildToL1Head(t) - require.Equal(t, oldGasLimit*3, seqEngine.l2Chain.CurrentBlock().GasLimit) + require.Equal(t, oldGasLimit*3, seqEngine.L2Chain().CurrentBlock().GasLimit) require.Equal(t, uint64(2), sequencer.SyncStatus().UnsafeL2.L1Origin.Number) // now submit all this to L1, and see if a verifier can sync and reproduce it @@ -410,7 +412,7 @@ func GasLimitChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) miner.ActL1EndBlock(t) - _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + _, verifier := actionsHelpers.SetupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) verifier.ActL2PipelineFull(t) require.Equal(t, sequencer.L2Unsafe(), verifier.L2Safe(), "verifier stays in sync, even with gaslimit changes") diff --git a/op-e2e/actions/action.go b/op-e2e/actions/helpers/action.go similarity index 99% rename from op-e2e/actions/action.go rename to op-e2e/actions/helpers/action.go index 551ab58d9632..3f8bba669242 100644 --- a/op-e2e/actions/action.go +++ b/op-e2e/actions/helpers/action.go @@ -1,4 +1,4 @@ -package actions +package helpers import ( "context" diff --git a/op-e2e/actions/garbage_channel_out.go b/op-e2e/actions/helpers/garbage_channel_out.go similarity index 99% rename from op-e2e/actions/garbage_channel_out.go rename to op-e2e/actions/helpers/garbage_channel_out.go index d5373755f8fe..6d813520a10a 100644 --- a/op-e2e/actions/garbage_channel_out.go +++ b/op-e2e/actions/helpers/garbage_channel_out.go @@ -1,4 +1,4 @@ -package actions +package helpers import ( "bytes" diff --git a/op-e2e/actions/l1_miner.go b/op-e2e/actions/helpers/l1_miner.go similarity index 92% rename from op-e2e/actions/l1_miner.go rename to op-e2e/actions/helpers/l1_miner.go index c35e38ae63c5..c310f234abc8 100644 --- a/op-e2e/actions/l1_miner.go +++ b/op-e2e/actions/helpers/l1_miner.go @@ -1,4 +1,4 @@ -package actions +package helpers import ( "math/big" @@ -33,9 +33,9 @@ type L1Miner struct { // L1 block building data l1BuildingHeader *types.Header // block header that we add txs to for block building l1BuildingState *state.StateDB // state used for block building - l1GasPool *core.GasPool // track gas used of ongoing building + L1GasPool *core.GasPool // track gas used of ongoing building pendingIndices map[common.Address]uint64 // per account, how many txs from the pool were already included in the block, since the pool is lagging behind block mining. - l1Transactions []*types.Transaction // collects txs that were successfully included into current block build + L1Transactions []*types.Transaction // collects txs that were successfully included into current block build l1Receipts []*types.Receipt // collect receipts of ongoing building l1Building bool l1TxFailed []*types.Transaction // log of failed transactions which could not be included @@ -120,11 +120,11 @@ func (s *L1Miner) ActL1StartBlock(timeDelta uint64) Action { s.l1BuildingHeader = header s.l1BuildingState = statedb s.l1Receipts = make([]*types.Receipt, 0) - s.l1Transactions = make([]*types.Transaction, 0) + s.L1Transactions = make([]*types.Transaction, 0) s.pendingIndices = make(map[common.Address]uint64) s.l1BuildingBlobSidecars = make([]*types.BlobTxSidecar, 0) - s.l1GasPool = new(core.GasPool).AddGas(header.GasLimit) + s.L1GasPool = new(core.GasPool).AddGas(header.GasLimit) } } @@ -138,7 +138,7 @@ func (s *L1Miner) ActL1IncludeTx(from common.Address) Action { getPendingIndex := func(from common.Address) uint64 { return s.pendingIndices[from] } - tx := firstValidTx(t, from, getPendingIndex, s.eth.TxPool().ContentFrom, s.EthClient().NonceAt) + tx := firstValidTx(t, from, getPendingIndex, s.Eth.TxPool().ContentFrom, s.EthClient().NonceAt) s.IncludeTx(t, tx) s.pendingIndices[from] = s.pendingIndices[from] + 1 // won't retry the tx } @@ -151,7 +151,7 @@ func (s *L1Miner) ActL1IncludeTxByHash(txHash common.Hash) Action { t.InvalidAction("no tx inclusion when not building l1 block") return } - tx := s.eth.TxPool().Get(txHash) + tx := s.Eth.TxPool().Get(txHash) require.NotNil(t, tx, "cannot find tx %s", txHash) s.IncludeTx(t, tx) from, err := s.l1Signer.Sender(tx) @@ -167,19 +167,19 @@ func (s *L1Miner) IncludeTx(t Testing, tx *types.Transaction) { if tx.Gas() > s.l1BuildingHeader.GasLimit { t.Fatalf("tx consumes %d gas, more than available in L1 block %d", tx.Gas(), s.l1BuildingHeader.GasLimit) } - if tx.Gas() > uint64(*s.l1GasPool) { - t.InvalidAction("action takes too much gas: %d, only have %d", tx.Gas(), uint64(*s.l1GasPool)) + if tx.Gas() > uint64(*s.L1GasPool) { + t.InvalidAction("action takes too much gas: %d, only have %d", tx.Gas(), uint64(*s.L1GasPool)) return } - s.l1BuildingState.SetTxContext(tx.Hash(), len(s.l1Transactions)) + s.l1BuildingState.SetTxContext(tx.Hash(), len(s.L1Transactions)) receipt, err := core.ApplyTransaction(s.l1Cfg.Config, s.l1Chain, &s.l1BuildingHeader.Coinbase, - s.l1GasPool, s.l1BuildingState, s.l1BuildingHeader, tx.WithoutBlobTxSidecar(), &s.l1BuildingHeader.GasUsed, *s.l1Chain.GetVMConfig()) + s.L1GasPool, s.l1BuildingState, s.l1BuildingHeader, tx.WithoutBlobTxSidecar(), &s.l1BuildingHeader.GasUsed, *s.l1Chain.GetVMConfig()) if err != nil { s.l1TxFailed = append(s.l1TxFailed, tx) - t.Fatalf("failed to apply transaction to L1 block (tx %d): %v", len(s.l1Transactions), err) + t.Fatalf("failed to apply transaction to L1 block (tx %d): %v", len(s.L1Transactions), err) } s.l1Receipts = append(s.l1Receipts, receipt) - s.l1Transactions = append(s.l1Transactions, tx.WithoutBlobTxSidecar()) + s.L1Transactions = append(s.L1Transactions, tx.WithoutBlobTxSidecar()) if tx.Type() == types.BlobTxType { require.True(t, s.l1Cfg.Config.IsCancun(s.l1BuildingHeader.Number, s.l1BuildingHeader.Time), "L1 must be cancun to process blob tx") sidecar := tx.BlobTxSidecar() @@ -205,7 +205,7 @@ func (s *L1Miner) ActL1EndBlock(t Testing) { } s.l1Building = false - s.l1BuildingHeader.GasUsed = s.l1BuildingHeader.GasLimit - uint64(*s.l1GasPool) + s.l1BuildingHeader.GasUsed = s.l1BuildingHeader.GasLimit - uint64(*s.L1GasPool) s.l1BuildingHeader.Root = s.l1BuildingState.IntermediateRoot(s.l1Cfg.Config.IsEIP158(s.l1BuildingHeader.Number)) var withdrawals []*types.Withdrawal @@ -213,7 +213,7 @@ func (s *L1Miner) ActL1EndBlock(t Testing) { withdrawals = make([]*types.Withdrawal, 0) } - block := types.NewBlock(s.l1BuildingHeader, &types.Body{Transactions: s.l1Transactions, Withdrawals: withdrawals}, s.l1Receipts, trie.NewStackTrie(nil)) + block := types.NewBlock(s.l1BuildingHeader, &types.Body{Transactions: s.L1Transactions, Withdrawals: withdrawals}, s.l1Receipts, trie.NewStackTrie(nil)) if s.l1Cfg.Config.IsCancun(s.l1BuildingHeader.Number, s.l1BuildingHeader.Time) { parent := s.l1Chain.GetHeaderByHash(s.l1BuildingHeader.ParentHash) var ( diff --git a/op-e2e/actions/l1_miner_test.go b/op-e2e/actions/helpers/l1_miner_test.go similarity index 99% rename from op-e2e/actions/l1_miner_test.go rename to op-e2e/actions/helpers/l1_miner_test.go index a56fc06c235b..b102dcaf84f0 100644 --- a/op-e2e/actions/l1_miner_test.go +++ b/op-e2e/actions/helpers/l1_miner_test.go @@ -1,4 +1,4 @@ -package actions +package helpers import ( "math/big" diff --git a/op-e2e/actions/l1_replica.go b/op-e2e/actions/helpers/l1_replica.go similarity index 99% rename from op-e2e/actions/l1_replica.go rename to op-e2e/actions/helpers/l1_replica.go index 3f6a27ed541f..7d5b50d39ccc 100644 --- a/op-e2e/actions/l1_replica.go +++ b/op-e2e/actions/helpers/l1_replica.go @@ -1,4 +1,4 @@ -package actions +package helpers import ( "errors" @@ -38,7 +38,7 @@ type L1Replica struct { log log.Logger node *node.Node - eth *eth.Ethereum + Eth *eth.Ethereum // L1 evm / chain l1Chain *core.BlockChain @@ -90,7 +90,7 @@ func NewL1Replica(t Testing, log log.Logger, genesis *core.Genesis) *L1Replica { return &L1Replica{ log: log, node: n, - eth: backend, + Eth: backend, l1Chain: backend.BlockChain(), l1Database: backend.ChainDb(), l1Cfg: genesis, diff --git a/op-e2e/actions/l1_replica_test.go b/op-e2e/actions/helpers/l1_replica_test.go similarity index 99% rename from op-e2e/actions/l1_replica_test.go rename to op-e2e/actions/helpers/l1_replica_test.go index 1d342a86e81f..5bfe2212f59e 100644 --- a/op-e2e/actions/l1_replica_test.go +++ b/op-e2e/actions/helpers/l1_replica_test.go @@ -1,4 +1,4 @@ -package actions +package helpers import ( "encoding/binary" diff --git a/op-e2e/actions/l2_batcher.go b/op-e2e/actions/helpers/l2_batcher.go similarity index 91% rename from op-e2e/actions/l2_batcher.go rename to op-e2e/actions/helpers/l2_batcher.go index 75d46f3418ca..d39c324ef9f0 100644 --- a/op-e2e/actions/l2_batcher.go +++ b/op-e2e/actions/helpers/l2_batcher.go @@ -1,4 +1,4 @@ -package actions +package helpers import ( "bytes" @@ -106,12 +106,12 @@ type L2Batcher struct { l1Signer types.Signer - l2ChannelOut ChannelOutIface + L2ChannelOut ChannelOutIface l2Submitting bool // when the channel out is being submitted, and not safe to write to without resetting - l2BufferedBlock eth.L2BlockRef + L2BufferedBlock eth.L2BlockRef l2SubmittedBlock eth.L2BlockRef l2BatcherCfg *BatcherCfg - batcherAddr common.Address + BatcherAddr common.Address LastSubmitted *types.Transaction } @@ -126,7 +126,7 @@ func NewL2Batcher(log log.Logger, rollupCfg *rollup.Config, batcherCfg *BatcherC engCl: engCl, l2BatcherCfg: batcherCfg, l1Signer: types.LatestSignerForChainID(rollupCfg.L1ChainID), - batcherAddr: crypto.PubkeyToAddress(batcherCfg.BatcherKey.PublicKey), + BatcherAddr: crypto.PubkeyToAddress(batcherCfg.BatcherKey.PublicKey), } } @@ -144,7 +144,7 @@ func (s *L2Batcher) ActL2BatchBuffer(t Testing) { func (s *L2Batcher) Buffer(t Testing) error { if s.l2Submitting { // break ongoing submitting work if necessary - s.l2ChannelOut = nil + s.L2ChannelOut = nil s.l2Submitting = false } syncStatus, err := s.syncStatusAPI.SyncStatus(t.Ctx()) @@ -153,38 +153,38 @@ func (s *L2Batcher) Buffer(t Testing) error { if s.l2SubmittedBlock == (eth.L2BlockRef{}) { s.log.Info("Starting batch-submitter work at safe-head", "safe", syncStatus.SafeL2) s.l2SubmittedBlock = syncStatus.SafeL2 - s.l2BufferedBlock = syncStatus.SafeL2 - s.l2ChannelOut = nil + s.L2BufferedBlock = syncStatus.SafeL2 + s.L2ChannelOut = nil } // If it's lagging behind, catch it up. if s.l2SubmittedBlock.Number < syncStatus.SafeL2.Number { s.log.Warn("last submitted block lagged behind L2 safe head: batch submission will continue from the safe head now", "last", s.l2SubmittedBlock, "safe", syncStatus.SafeL2) s.l2SubmittedBlock = syncStatus.SafeL2 - s.l2BufferedBlock = syncStatus.SafeL2 - s.l2ChannelOut = nil + s.L2BufferedBlock = syncStatus.SafeL2 + s.L2ChannelOut = nil } // Add the next unsafe block to the channel - if s.l2BufferedBlock.Number >= syncStatus.UnsafeL2.Number { - if s.l2BufferedBlock.Number > syncStatus.UnsafeL2.Number || s.l2BufferedBlock.Hash != syncStatus.UnsafeL2.Hash { + if s.L2BufferedBlock.Number >= syncStatus.UnsafeL2.Number { + if s.L2BufferedBlock.Number > syncStatus.UnsafeL2.Number || s.L2BufferedBlock.Hash != syncStatus.UnsafeL2.Hash { s.log.Error("detected a reorg in L2 chain vs previous buffered information, resetting to safe head now", "safe_head", syncStatus.SafeL2) s.l2SubmittedBlock = syncStatus.SafeL2 - s.l2BufferedBlock = syncStatus.SafeL2 - s.l2ChannelOut = nil + s.L2BufferedBlock = syncStatus.SafeL2 + s.L2ChannelOut = nil } else { s.log.Info("nothing left to submit") return nil } } - block, err := s.l2.BlockByNumber(t.Ctx(), big.NewInt(int64(s.l2BufferedBlock.Number+1))) + block, err := s.l2.BlockByNumber(t.Ctx(), big.NewInt(int64(s.L2BufferedBlock.Number+1))) require.NoError(t, err, "need l2 block %d from sync status", s.l2SubmittedBlock.Number+1) - if block.ParentHash() != s.l2BufferedBlock.Hash { + if block.ParentHash() != s.L2BufferedBlock.Hash { s.log.Error("detected a reorg in L2 chain vs previous submitted information, resetting to safe head now", "safe_head", syncStatus.SafeL2) s.l2SubmittedBlock = syncStatus.SafeL2 - s.l2BufferedBlock = syncStatus.SafeL2 - s.l2ChannelOut = nil + s.L2BufferedBlock = syncStatus.SafeL2 + s.L2ChannelOut = nil } // Create channel if we don't have one yet - if s.l2ChannelOut == nil { + if s.L2ChannelOut == nil { var ch ChannelOutIface if s.l2BatcherCfg.GarbageCfg != nil { ch, err = NewGarbageChannelOut(s.l2BatcherCfg.GarbageCfg) @@ -210,29 +210,29 @@ func (s *L2Batcher) Buffer(t Testing) error { } } require.NoError(t, err, "failed to create channel") - s.l2ChannelOut = ch + s.L2ChannelOut = ch } - if err := s.l2ChannelOut.AddBlock(s.rollupCfg, block); err != nil { + if err := s.L2ChannelOut.AddBlock(s.rollupCfg, block); err != nil { return err } ref, err := s.engCl.L2BlockRefByHash(t.Ctx(), block.Hash()) require.NoError(t, err, "failed to get L2BlockRef") - s.l2BufferedBlock = ref + s.L2BufferedBlock = ref return nil } func (s *L2Batcher) ActL2ChannelClose(t Testing) { // Don't run this action if there's no data to submit - if s.l2ChannelOut == nil { + if s.L2ChannelOut == nil { t.InvalidAction("need to buffer data first, cannot batch submit with empty buffer") return } - require.NoError(t, s.l2ChannelOut.Close(), "must close channel before submitting it") + require.NoError(t, s.L2ChannelOut.Close(), "must close channel before submitting it") } func (s *L2Batcher) ReadNextOutputFrame(t Testing) []byte { // Don't run this action if there's no data to submit - if s.l2ChannelOut == nil { + if s.L2ChannelOut == nil { t.InvalidAction("need to buffer data first, cannot batch submit with empty buffer") return nil } @@ -240,8 +240,8 @@ func (s *L2Batcher) ReadNextOutputFrame(t Testing) []byte { data := new(bytes.Buffer) data.WriteByte(derive.DerivationVersion0) // subtract one, to account for the version byte - if _, err := s.l2ChannelOut.OutputFrame(data, s.l2BatcherCfg.MaxL1TxSize-1); err == io.EOF { - s.l2ChannelOut = nil + if _, err := s.L2ChannelOut.OutputFrame(data, s.l2BatcherCfg.MaxL1TxSize-1); err == io.EOF { + s.L2ChannelOut = nil s.l2Submitting = false } else if err != nil { s.l2Submitting = false @@ -263,7 +263,7 @@ func (s *L2Batcher) ActL2BatchSubmitRaw(t Testing, payload []byte, txOpts ...fun payload = comm.TxData() } - nonce, err := s.l1.PendingNonceAt(t.Ctx(), s.batcherAddr) + nonce, err := s.l1.PendingNonceAt(t.Ctx(), s.BatcherAddr) require.NoError(t, err, "need batcher nonce") gasTipCap := big.NewInt(2 * params.GWei) @@ -334,7 +334,7 @@ func (s *L2Batcher) ActL2BatchSubmitMultiBlob(t Testing, numBlobs int) { } // Don't run this action if there's no data to submit - if s.l2ChannelOut == nil { + if s.L2ChannelOut == nil { t.InvalidAction("need to buffer data first, cannot batch submit with empty buffer") return } @@ -351,12 +351,12 @@ func (s *L2Batcher) ActL2BatchSubmitMultiBlob(t Testing, numBlobs int) { // subtract one, to account for the version byte l = s.l2BatcherCfg.MaxL1TxSize - 1 } - if _, err := s.l2ChannelOut.OutputFrame(data, l); err == io.EOF { + if _, err := s.L2ChannelOut.OutputFrame(data, l); err == io.EOF { s.l2Submitting = false if i < numBlobs-1 { t.Fatalf("failed to fill up %d blobs, only filled %d", numBlobs, i+1) } - s.l2ChannelOut = nil + s.L2ChannelOut = nil } else if err != nil { s.l2Submitting = false t.Fatalf("failed to output channel data to frame: %v", err) @@ -366,7 +366,7 @@ func (s *L2Batcher) ActL2BatchSubmitMultiBlob(t Testing, numBlobs int) { require.NoError(t, blobs[i].FromData(data.Bytes()), "must turn data into blob") } - nonce, err := s.l1.PendingNonceAt(t.Ctx(), s.batcherAddr) + nonce, err := s.l1.PendingNonceAt(t.Ctx(), s.BatcherAddr) require.NoError(t, err, "need batcher nonce") gasTipCap := big.NewInt(2 * params.GWei) @@ -453,7 +453,7 @@ func (s *L2Batcher) ActL2BatchSubmitGarbageRaw(t Testing, outputFrame []byte, ki func (s *L2Batcher) ActBufferAll(t Testing) { stat, err := s.syncStatusAPI.SyncStatus(t.Ctx()) require.NoError(t, err) - for s.l2BufferedBlock.Number < stat.UnsafeL2.Number { + for s.L2BufferedBlock.Number < stat.UnsafeL2.Number { s.ActL2BatchBuffer(t) } } diff --git a/op-e2e/actions/l2_engine.go b/op-e2e/actions/helpers/l2_engine.go similarity index 91% rename from op-e2e/actions/l2_engine.go rename to op-e2e/actions/helpers/l2_engine.go index 80d705d854e5..4bd8fe118d61 100644 --- a/op-e2e/actions/l2_engine.go +++ b/op-e2e/actions/helpers/l2_engine.go @@ -1,4 +1,4 @@ -package actions +package helpers import ( "errors" @@ -35,7 +35,7 @@ type L2Engine struct { log log.Logger node *node.Node - eth *geth.Ethereum + Eth *geth.Ethereum rollupGenesis *rollup.Genesis @@ -43,9 +43,9 @@ type L2Engine struct { l2Chain *core.BlockChain l2Signer types.Signer - engineApi *engineapi.L2EngineAPI + EngineApi *engineapi.L2EngineAPI - failL2RPC func(call []rpc.BatchElem) error // mock error + FailL2RPC func(call []rpc.BatchElem) error // mock error } type EngineOption func(ethCfg *ethconfig.Config, nodeCfg *node.Config) error @@ -58,7 +58,7 @@ func NewL2Engine(t Testing, log log.Logger, genesis *core.Genesis, rollupGenesis eng := &L2Engine{ log: log, node: n, - eth: ethBackend, + Eth: ethBackend, rollupGenesis: &rollup.Genesis{ L1: rollupGenesisL1, L2: eth.BlockID{Hash: genesisBlock.Hash(), Number: genesisBlock.NumberU64()}, @@ -66,14 +66,14 @@ func NewL2Engine(t Testing, log log.Logger, genesis *core.Genesis, rollupGenesis }, l2Chain: chain, l2Signer: types.LatestSigner(genesis.Config), - engineApi: engineApi, + EngineApi: engineApi, } // register the custom engine API, so we can serve engine requests while having more control // over sequencing of individual txs. n.RegisterAPIs([]rpc.API{ { Namespace: "engine", - Service: eng.engineApi, + Service: eng.EngineApi, Authenticated: true, }, }) @@ -172,10 +172,10 @@ func (e *L2Engine) RPCClient() client.RPC { return testutils.RPCErrFaker{ RPC: client.NewBaseRPCClient(cl), ErrFn: func(call []rpc.BatchElem) error { - if e.failL2RPC == nil { + if e.FailL2RPC == nil { return nil } - return e.failL2RPC(call) + return e.FailL2RPC(call) }, } } @@ -188,12 +188,12 @@ func (e *L2Engine) EngineClient(t Testing, cfg *rollup.Config) *sources.EngineCl // ActL2RPCFail makes the next L2 RPC request fail with given error func (e *L2Engine) ActL2RPCFail(t Testing, err error) { - if e.failL2RPC != nil { // already set to fail? + if e.FailL2RPC != nil { // already set to fail? t.InvalidAction("already set a mock L2 rpc error") return } - e.failL2RPC = func(call []rpc.BatchElem) error { - e.failL2RPC = nil + e.FailL2RPC = func(call []rpc.BatchElem) error { + e.FailL2RPC = nil return err } } @@ -201,13 +201,13 @@ func (e *L2Engine) ActL2RPCFail(t Testing, err error) { // ActL2IncludeTx includes the next transaction from the given address in the block that is being built func (e *L2Engine) ActL2IncludeTx(from common.Address) Action { return func(t Testing) { - if e.engineApi.ForcedEmpty() { + if e.EngineApi.ForcedEmpty() { e.log.Info("Skipping including a transaction because e.L2ForceEmpty is true") return } - tx := firstValidTx(t, from, e.engineApi.PendingIndices, e.eth.TxPool().ContentFrom, e.EthClient().NonceAt) - err := e.engineApi.IncludeTx(tx, from) + tx := firstValidTx(t, from, e.EngineApi.PendingIndices, e.Eth.TxPool().ContentFrom, e.EthClient().NonceAt) + err := e.EngineApi.IncludeTx(tx, from) if errors.Is(err, engineapi.ErrNotBuildingBlock) { t.InvalidAction(err.Error()) } else if errors.Is(err, engineapi.ErrUsesTooMuchGas) { diff --git a/op-e2e/actions/l2_engine_test.go b/op-e2e/actions/helpers/l2_engine_test.go similarity index 99% rename from op-e2e/actions/l2_engine_test.go rename to op-e2e/actions/helpers/l2_engine_test.go index 2ea335ec855e..d74595d31621 100644 --- a/op-e2e/actions/l2_engine_test.go +++ b/op-e2e/actions/helpers/l2_engine_test.go @@ -1,4 +1,4 @@ -package actions +package helpers import ( "encoding/binary" diff --git a/op-e2e/actions/l2_proposer.go b/op-e2e/actions/helpers/l2_proposer.go similarity index 99% rename from op-e2e/actions/l2_proposer.go rename to op-e2e/actions/helpers/l2_proposer.go index 6f7edd0e5057..e97a66a1f5bc 100644 --- a/op-e2e/actions/l2_proposer.go +++ b/op-e2e/actions/helpers/l2_proposer.go @@ -1,4 +1,4 @@ -package actions +package helpers import ( "context" diff --git a/op-e2e/actions/l2_sequencer.go b/op-e2e/actions/helpers/l2_sequencer.go similarity index 95% rename from op-e2e/actions/l2_sequencer.go rename to op-e2e/actions/helpers/l2_sequencer.go index a4626749b18a..98becdcc87a4 100644 --- a/op-e2e/actions/l2_sequencer.go +++ b/op-e2e/actions/helpers/l2_sequencer.go @@ -1,4 +1,4 @@ -package actions +package helpers import ( "context" @@ -89,7 +89,7 @@ func NewL2Sequencer(t Testing, log log.Logger, l1 derive.L1Fetcher, blobSrc deri // ActL2StartBlock starts building of a new L2 block on top of the head func (s *L2Sequencer) ActL2StartBlock(t Testing) { - if !s.l2PipelineIdle { + if !s.L2PipelineIdle { t.InvalidAction("cannot start L2 build when derivation is not idle") return } @@ -191,22 +191,22 @@ func (s *L2Sequencer) ActBuildL2ToTime(t Testing, target uint64) { } func (s *L2Sequencer) ActBuildL2ToEcotone(t Testing) { - require.NotNil(t, s.rollupCfg.EcotoneTime, "cannot activate Ecotone when it is not scheduled") - for s.L2Unsafe().Time < *s.rollupCfg.EcotoneTime { + require.NotNil(t, s.RollupCfg.EcotoneTime, "cannot activate Ecotone when it is not scheduled") + for s.L2Unsafe().Time < *s.RollupCfg.EcotoneTime { s.ActL2StartBlock(t) s.ActL2EndBlock(t) } } func (s *L2Sequencer) ActBuildL2ToFjord(t Testing) { - require.NotNil(t, s.rollupCfg.FjordTime, "cannot activate FjordTime when it is not scheduled") - for s.L2Unsafe().Time < *s.rollupCfg.FjordTime { + require.NotNil(t, s.RollupCfg.FjordTime, "cannot activate FjordTime when it is not scheduled") + for s.L2Unsafe().Time < *s.RollupCfg.FjordTime { s.ActL2StartBlock(t) s.ActL2EndBlock(t) } } func (s *L2Sequencer) ActBuildL2ToGranite(t Testing) { - require.NotNil(t, s.rollupCfg.GraniteTime, "cannot activate GraniteTime when it is not scheduled") - for s.L2Unsafe().Time < *s.rollupCfg.GraniteTime { + require.NotNil(t, s.RollupCfg.GraniteTime, "cannot activate GraniteTime when it is not scheduled") + for s.L2Unsafe().Time < *s.RollupCfg.GraniteTime { s.ActL2StartBlock(t) s.ActL2EndBlock(t) } diff --git a/op-e2e/actions/l2_verifier.go b/op-e2e/actions/helpers/l2_verifier.go similarity index 97% rename from op-e2e/actions/l2_verifier.go rename to op-e2e/actions/helpers/l2_verifier.go index 03de1a674f1c..4d201a88fb0c 100644 --- a/op-e2e/actions/l2_verifier.go +++ b/op-e2e/actions/helpers/l2_verifier.go @@ -1,4 +1,4 @@ -package actions +package helpers import ( "context" @@ -40,7 +40,7 @@ type L2Verifier struct { log log.Logger - eng L2API + Eng L2API syncStatus driver.SyncStatusTracker @@ -57,10 +57,10 @@ type L2Verifier struct { l1 derive.L1Fetcher - l2PipelineIdle bool + L2PipelineIdle bool l2Building bool - rollupCfg *rollup.Config + RollupCfg *rollup.Config rpc *rpc.Server @@ -160,7 +160,7 @@ func NewL2Verifier(t Testing, log log.Logger, l1 derive.L1Fetcher, rollupNode := &L2Verifier{ eventSys: sys, log: log, - eng: eng, + Eng: eng, engine: ec, derivation: pipeline, safeHeadListener: safeHeadListener, @@ -168,9 +168,9 @@ func NewL2Verifier(t Testing, log log.Logger, l1 derive.L1Fetcher, drainer: executor, l1: l1, syncStatus: syncStatusTracker, - l2PipelineIdle: true, + L2PipelineIdle: true, l2Building: false, - rollupCfg: cfg, + RollupCfg: cfg, rpc: rpc.NewServer(), synchronousEvents: testActionEmitter, } @@ -205,7 +205,7 @@ type l2VerifierBackend struct { } func (s *l2VerifierBackend) BlockRefWithStatus(ctx context.Context, num uint64) (eth.L2BlockRef, *eth.SyncStatus, error) { - ref, err := s.verifier.eng.L2BlockRefByNumber(ctx, num) + ref, err := s.verifier.Eng.L2BlockRefByNumber(ctx, num) return ref, s.verifier.SyncStatus(), err } @@ -345,9 +345,9 @@ func (s *L2Verifier) OnEvent(ev event.Event) bool { case rollup.CriticalErrorEvent: panic(fmt.Errorf("derivation failed critically: %w", x.Err)) case derive.DeriverIdleEvent: - s.l2PipelineIdle = true + s.L2PipelineIdle = true case derive.PipelineStepEvent: - s.l2PipelineIdle = false + s.L2PipelineIdle = false case driver.StepReqEvent: s.synchronousEvents.Emit(driver.StepEvent{}) default: @@ -396,7 +396,7 @@ func (s *L2Verifier) ActL2UnsafeGossipReceive(payload *eth.ExecutionPayloadEnvel // ActL2InsertUnsafePayload creates an action that can insert an unsafe execution payload func (s *L2Verifier) ActL2InsertUnsafePayload(payload *eth.ExecutionPayloadEnvelope) Action { return func(t Testing) { - ref, err := derive.PayloadToBlockRef(s.rollupCfg, payload.ExecutionPayload) + ref, err := derive.PayloadToBlockRef(s.RollupCfg, payload.ExecutionPayload) require.NoError(t, err) err = s.engine.InsertUnsafePayload(t.Ctx(), payload, ref) require.NoError(t, err) diff --git a/op-e2e/actions/helpers/setups.go b/op-e2e/actions/helpers/setups.go new file mode 100644 index 000000000000..26e19eae82a0 --- /dev/null +++ b/op-e2e/actions/helpers/setups.go @@ -0,0 +1,75 @@ +package helpers + +import ( + altda "github.com/ethereum-optimism/optimism/op-alt-da" + "github.com/ethereum-optimism/optimism/op-e2e/actions/upgrades/helpers" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/ethereum-optimism/optimism/op-node/rollup/sync" + "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +func SetupSequencerTest(t Testing, sd *e2eutils.SetupData, log log.Logger, opts ...SequencerOpt) (*L1Miner, *L2Engine, *L2Sequencer) { + jwtPath := e2eutils.WriteDefaultJWT(t) + cfg := DefaultSequencerConfig() + for _, opt := range opts { + opt(cfg) + } + + miner := NewL1Miner(t, log.New("role", "l1-miner"), sd.L1Cfg) + + l1F, err := sources.NewL1Client(miner.RPCClient(), log, nil, sources.L1ClientDefaultConfig(sd.RollupCfg, false, sources.RPCKindStandard)) + require.NoError(t, err) + engine := NewL2Engine(t, log.New("role", "sequencer-engine"), sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath, EngineWithP2P()) + l2Cl, err := sources.NewEngineClient(engine.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) + require.NoError(t, err) + + sequencer := NewL2Sequencer(t, log.New("role", "sequencer"), l1F, miner.BlobStore(), altda.Disabled, l2Cl, sd.RollupCfg, 0, cfg.InteropBackend) + return miner, engine, sequencer +} + +func SetupVerifier(t Testing, sd *e2eutils.SetupData, log log.Logger, + l1F derive.L1Fetcher, blobSrc derive.L1BlobsFetcher, syncCfg *sync.Config, opts ...VerifierOpt) (*L2Engine, *L2Verifier) { + cfg := DefaultVerifierCfg() + for _, opt := range opts { + opt(cfg) + } + jwtPath := e2eutils.WriteDefaultJWT(t) + engine := NewL2Engine(t, log.New("role", "verifier-engine"), sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath, EngineWithP2P()) + engCl := engine.EngineClient(t, sd.RollupCfg) + verifier := NewL2Verifier(t, log.New("role", "verifier"), l1F, blobSrc, altda.Disabled, engCl, sd.RollupCfg, syncCfg, cfg.SafeHeadListener, cfg.InteropBackend) + return engine, verifier +} + +func SetupVerifierOnlyTest(t Testing, sd *e2eutils.SetupData, log log.Logger) (*L1Miner, *L2Engine, *L2Verifier) { + miner := NewL1Miner(t, log, sd.L1Cfg) + l1Cl := miner.L1Client(t, sd.RollupCfg) + engine, verifier := SetupVerifier(t, sd, log, l1Cl, miner.BlobStore(), &sync.Config{}) + return miner, engine, verifier +} + +func SetupReorgTest(t Testing, config *e2eutils.TestParams, deltaTimeOffset *hexutil.Uint64) (*e2eutils.SetupData, *e2eutils.DeployParams, *L1Miner, *L2Sequencer, *L2Engine, *L2Verifier, *L2Engine, *L2Batcher) { + dp := e2eutils.MakeDeployParams(t, config) + helpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset) + + sd := e2eutils.Setup(t, dp, DefaultAlloc) + log := testlog.Logger(t, log.LevelDebug) + + return SetupReorgTestActors(t, dp, sd, log) +} + +func SetupReorgTestActors(t Testing, dp *e2eutils.DeployParams, sd *e2eutils.SetupData, log log.Logger) (*e2eutils.SetupData, *e2eutils.DeployParams, *L1Miner, *L2Sequencer, *L2Engine, *L2Verifier, *L2Engine, *L2Batcher) { + miner, seqEngine, sequencer := SetupSequencerTest(t, sd, log) + miner.ActL1SetFeeRecipient(common.Address{'A'}) + sequencer.ActL2PipelineFull(t) + verifEngine, verifier := SetupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + rollupSeqCl := sequencer.RollupClient() + batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) + return sd, dp, miner, sequencer, seqEngine, verifier, verifEngine, batcher +} diff --git a/op-e2e/actions/tx_helper.go b/op-e2e/actions/helpers/tx_helper.go similarity index 99% rename from op-e2e/actions/tx_helper.go rename to op-e2e/actions/helpers/tx_helper.go index e63c1a224822..8174563102c8 100644 --- a/op-e2e/actions/tx_helper.go +++ b/op-e2e/actions/helpers/tx_helper.go @@ -1,4 +1,4 @@ -package actions +package helpers import ( "context" diff --git a/op-e2e/actions/user.go b/op-e2e/actions/helpers/user.go similarity index 99% rename from op-e2e/actions/user.go rename to op-e2e/actions/helpers/user.go index dabc9c1d8980..401237c0fad3 100644 --- a/op-e2e/actions/user.go +++ b/op-e2e/actions/helpers/user.go @@ -1,4 +1,4 @@ -package actions +package helpers import ( "context" diff --git a/op-e2e/actions/user_test.go b/op-e2e/actions/helpers/user_test.go similarity index 98% rename from op-e2e/actions/user_test.go rename to op-e2e/actions/helpers/user_test.go index 8bb1b042c9a3..8ee60aa680e3 100644 --- a/op-e2e/actions/user_test.go +++ b/op-e2e/actions/helpers/user_test.go @@ -1,4 +1,4 @@ -package actions +package helpers import ( "fmt" @@ -131,7 +131,7 @@ func runCrossLayerUserTest(gt *testing.T, test hardforkScheduledTest) { require.Equal(t, dp.Secrets.Addresses().Batcher, dp.DeployConfig.BatchSenderAddress) require.Equal(t, dp.Secrets.Addresses().Proposer, dp.DeployConfig.L2OutputOracleProposer) - miner, seqEngine, seq := setupSequencerTest(t, sd, log) + miner, seqEngine, seq := SetupSequencerTest(t, sd, log) batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), seq.RollupClient(), miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) @@ -199,7 +199,7 @@ func runCrossLayerUserTest(gt *testing.T, test hardforkScheduledTest) { require.NoError(t, err) require.True(t, infoTx.IsDepositTx()) // Should only be a system tx if regolith is not enabled - require.Equal(t, !seq.rollupCfg.IsRegolith(seq.L2Unsafe().Time), infoTx.IsSystemTx()) + require.Equal(t, !seq.RollupCfg.IsRegolith(seq.L2Unsafe().Time), infoTx.IsSystemTx()) // regular L2 tx, in new L2 block alice.L2.ActResetTxOpts(t) @@ -320,5 +320,5 @@ func runCrossLayerUserTest(gt *testing.T, test hardforkScheduledTest) { require.NoError(t, err) require.True(t, infoTx.IsDepositTx()) // Should only be a system tx if regolith is not enabled - require.Equal(t, !seq.rollupCfg.IsRegolith(seq.L2Unsafe().Time), infoTx.IsSystemTx()) + require.Equal(t, !seq.RollupCfg.IsRegolith(seq.L2Unsafe().Time), infoTx.IsSystemTx()) } diff --git a/op-e2e/actions/utils.go b/op-e2e/actions/helpers/utils.go similarity index 99% rename from op-e2e/actions/utils.go rename to op-e2e/actions/helpers/utils.go index aa03db3e29b5..f4f1b812cbaa 100644 --- a/op-e2e/actions/utils.go +++ b/op-e2e/actions/helpers/utils.go @@ -1,4 +1,4 @@ -package actions +package helpers import ( "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" diff --git a/op-e2e/actions/interop_test.go b/op-e2e/actions/interop/interop_test.go similarity index 89% rename from op-e2e/actions/interop_test.go rename to op-e2e/actions/interop/interop_test.go index 614ab05f65a7..4015ffa29ce9 100644 --- a/op-e2e/actions/interop_test.go +++ b/op-e2e/actions/interop/interop_test.go @@ -1,8 +1,9 @@ -package actions +package interop import ( "testing" + "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/stretchr/testify/require" "github.com/ethereum/go-ethereum/log" @@ -18,24 +19,24 @@ import ( var _ interop.InteropBackend = (*testutils.MockInteropBackend)(nil) func TestInteropVerifier(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + t := helpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams) + sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc) // Temporary work-around: interop needs to be active, for cross-safety to not be instant. // The state genesis in this test is pre-interop however. sd.RollupCfg.InteropTime = new(uint64) logger := testlog.Logger(t, log.LevelDebug) seqMockBackend := &testutils.MockInteropBackend{} - l1Miner, seqEng, seq := setupSequencerTest(t, sd, logger, - WithVerifierOpts(WithInteropBackend(seqMockBackend))) + l1Miner, seqEng, seq := helpers.SetupSequencerTest(t, sd, logger, + helpers.WithVerifierOpts(helpers.WithInteropBackend(seqMockBackend))) - batcher := NewL2Batcher(logger, sd.RollupCfg, DefaultBatcherCfg(dp), + batcher := helpers.NewL2Batcher(logger, sd.RollupCfg, helpers.DefaultBatcherCfg(dp), seq.RollupClient(), l1Miner.EthClient(), seqEng.EthClient(), seqEng.EngineClient(t, sd.RollupCfg)) verMockBackend := &testutils.MockInteropBackend{} - _, ver := setupVerifier(t, sd, logger, + _, ver := helpers.SetupVerifier(t, sd, logger, l1Miner.L1Client(t, sd.RollupCfg), l1Miner.BlobStore(), &sync.Config{}, - WithInteropBackend(verMockBackend)) + helpers.WithInteropBackend(verMockBackend)) seq.ActL2PipelineFull(t) ver.ActL2PipelineFull(t) diff --git a/op-e2e/actions/proofs/channel_timeout_test.go b/op-e2e/actions/proofs/channel_timeout_test.go index 9bee473f188b..f4ab00a86538 100644 --- a/op-e2e/actions/proofs/channel_timeout_test.go +++ b/op-e2e/actions/proofs/channel_timeout_test.go @@ -3,7 +3,7 @@ package proofs import ( "testing" - "github.com/ethereum-optimism/optimism/op-e2e/actions" + actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/ethereum-optimism/optimism/op-e2e/actions/proofs/helpers" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-program/client/claim" @@ -21,7 +21,7 @@ import ( // 5. Instruct the sequencer to derive the L2 chain. // 6. Run the FPP on the safe head. func runChannelTimeoutTest(gt *testing.T, testCfg *helpers.TestCfg[any]) { - t := actions.NewDefaultTesting(gt) + t := actionsHelpers.NewDefaultTesting(gt) tp := helpers.NewTestParams(func(tp *e2eutils.TestParams) { // Set the channel timeout to 10 blocks, 12x lower than the sequencing window. tp.ChannelTimeout = 10 diff --git a/op-e2e/actions/proofs/garbage_channel_test.go b/op-e2e/actions/proofs/garbage_channel_test.go index 06c888582a05..f112a1a71bda 100644 --- a/op-e2e/actions/proofs/garbage_channel_test.go +++ b/op-e2e/actions/proofs/garbage_channel_test.go @@ -4,7 +4,7 @@ import ( "fmt" "testing" - "github.com/ethereum-optimism/optimism/op-e2e/actions" + actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/ethereum-optimism/optimism/op-e2e/actions/proofs/helpers" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-program/client/claim" @@ -15,19 +15,19 @@ import ( // garbageKinds is a list of garbage kinds to test. We don't use `INVALID_COMPRESSION` and `MALFORM_RLP` because // they submit malformed frames always, and this test models a valid channel with a single invalid frame in the // middle. -var garbageKinds = []actions.GarbageKind{ - actions.STRIP_VERSION, - actions.RANDOM, - actions.TRUNCATE_END, - actions.DIRTY_APPEND, +var garbageKinds = []actionsHelpers.GarbageKind{ + actionsHelpers.STRIP_VERSION, + actionsHelpers.RANDOM, + actionsHelpers.TRUNCATE_END, + actionsHelpers.DIRTY_APPEND, } // Run a test that submits garbage channel data in the middle of a channel. // // channel format ([]Frame): // [f[0 - correct] f_x[1 - bad frame] f[1 - correct]] -func runGarbageChannelTest(gt *testing.T, testCfg *helpers.TestCfg[actions.GarbageKind]) { - t := actions.NewDefaultTesting(gt) +func runGarbageChannelTest(gt *testing.T, testCfg *helpers.TestCfg[actionsHelpers.GarbageKind]) { + t := actionsHelpers.NewDefaultTesting(gt) tp := helpers.NewTestParams(func(tp *e2eutils.TestParams) { // Set the channel timeout to 10 blocks, 12x lower than the sequencing window. tp.ChannelTimeout = 10 @@ -100,7 +100,7 @@ func runGarbageChannelTest(gt *testing.T, testCfg *helpers.TestCfg[actions.Garba } func Test_ProgramAction_GarbageChannel(gt *testing.T) { - matrix := helpers.NewMatrix[actions.GarbageKind]() + matrix := helpers.NewMatrix[actionsHelpers.GarbageKind]() defer matrix.Run(gt) for _, garbageKind := range garbageKinds { diff --git a/op-e2e/actions/proofs/helpers/env.go b/op-e2e/actions/proofs/helpers/env.go index 50fecbb94fb2..1ec23eb472f6 100644 --- a/op-e2e/actions/proofs/helpers/env.go +++ b/op-e2e/actions/proofs/helpers/env.go @@ -6,7 +6,7 @@ import ( altda "github.com/ethereum-optimism/optimism/op-alt-da" batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" - "github.com/ethereum-optimism/optimism/op-e2e/actions" + "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-program/host" "github.com/ethereum-optimism/optimism/op-program/host/config" @@ -25,17 +25,17 @@ import ( // L2FaultProofEnv is a test harness for a fault provable L2 chain. type L2FaultProofEnv struct { log log.Logger - Batcher *actions.L2Batcher - Sequencer *actions.L2Sequencer - Engine *actions.L2Engine + Batcher *helpers.L2Batcher + Sequencer *helpers.L2Sequencer + Engine *helpers.L2Engine engCl *sources.EngineClient sd *e2eutils.SetupData dp *e2eutils.DeployParams - Miner *actions.L1Miner - Alice *actions.CrossLayerUser + Miner *helpers.L1Miner + Alice *helpers.CrossLayerUser } -func NewL2FaultProofEnv[c any](t actions.Testing, testCfg *TestCfg[c], tp *e2eutils.TestParams, batcherCfg *actions.BatcherCfg) *L2FaultProofEnv { +func NewL2FaultProofEnv[c any](t helpers.Testing, testCfg *TestCfg[c], tp *e2eutils.TestParams, batcherCfg *helpers.BatcherCfg) *L2FaultProofEnv { log := testlog.Logger(t, log.LvlDebug) dp := NewDeployParams(t, func(dp *e2eutils.DeployParams) { genesisBlock := hexutil.Uint64(0) @@ -59,44 +59,44 @@ func NewL2FaultProofEnv[c any](t actions.Testing, testCfg *TestCfg[c], tp *e2eut dp.DeployConfig.L2GenesisGraniteTimeOffset = &genesisBlock } }) - sd := e2eutils.Setup(t, dp, actions.DefaultAlloc) + sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc) jwtPath := e2eutils.WriteDefaultJWT(t) - cfg := &actions.SequencerCfg{VerifierCfg: *actions.DefaultVerifierCfg()} + cfg := &helpers.SequencerCfg{VerifierCfg: *helpers.DefaultVerifierCfg()} - miner := actions.NewL1Miner(t, log.New("role", "l1-miner"), sd.L1Cfg) + miner := helpers.NewL1Miner(t, log.New("role", "l1-miner"), sd.L1Cfg) l1Cl, err := sources.NewL1Client(miner.RPCClient(), log, nil, sources.L1ClientDefaultConfig(sd.RollupCfg, false, sources.RPCKindStandard)) require.NoError(t, err) - engine := actions.NewL2Engine(t, log.New("role", "sequencer-engine"), sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath, actions.EngineWithP2P()) + engine := helpers.NewL2Engine(t, log.New("role", "sequencer-engine"), sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath, helpers.EngineWithP2P()) l2EngineCl, err := sources.NewEngineClient(engine.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(t, err) - sequencer := actions.NewL2Sequencer(t, log.New("role", "sequencer"), l1Cl, miner.BlobStore(), altda.Disabled, l2EngineCl, sd.RollupCfg, 0, cfg.InteropBackend) + sequencer := helpers.NewL2Sequencer(t, log.New("role", "sequencer"), l1Cl, miner.BlobStore(), altda.Disabled, l2EngineCl, sd.RollupCfg, 0, cfg.InteropBackend) miner.ActL1SetFeeRecipient(common.Address{0xCA, 0xFE, 0xBA, 0xBE}) sequencer.ActL2PipelineFull(t) engCl := engine.EngineClient(t, sd.RollupCfg) // Set the batcher key to the secret key of the batcher batcherCfg.BatcherKey = dp.Secrets.Batcher - batcher := actions.NewL2Batcher(log, sd.RollupCfg, batcherCfg, sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engCl) + batcher := helpers.NewL2Batcher(log, sd.RollupCfg, batcherCfg, sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engCl) addresses := e2eutils.CollectAddresses(sd, dp) l1EthCl := miner.EthClient() l2EthCl := engine.EthClient() - l1UserEnv := &actions.BasicUserEnv[*actions.L1Bindings]{ + l1UserEnv := &helpers.BasicUserEnv[*helpers.L1Bindings]{ EthCl: l1EthCl, Signer: types.LatestSigner(sd.L1Cfg.Config), AddressCorpora: addresses, - Bindings: actions.NewL1Bindings(t, l1EthCl), + Bindings: helpers.NewL1Bindings(t, l1EthCl), } - l2UserEnv := &actions.BasicUserEnv[*actions.L2Bindings]{ + l2UserEnv := &helpers.BasicUserEnv[*helpers.L2Bindings]{ EthCl: l2EthCl, Signer: types.LatestSigner(sd.L2Cfg.Config), AddressCorpora: addresses, - Bindings: actions.NewL2Bindings(t, l2EthCl, engine.GethClient()), + Bindings: helpers.NewL2Bindings(t, l2EthCl, engine.GethClient()), } - alice := actions.NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b))) + alice := helpers.NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b))) alice.L1.SetUserEnv(l1UserEnv) alice.L2.SetUserEnv(l2UserEnv) @@ -115,16 +115,16 @@ func NewL2FaultProofEnv[c any](t actions.Testing, testCfg *TestCfg[c], tp *e2eut type FixtureInputParam func(f *FixtureInputs) -type CheckResult func(actions.Testing, error) +type CheckResult func(helpers.Testing, error) func ExpectNoError() CheckResult { - return func(t actions.Testing, err error) { + return func(t helpers.Testing, err error) { require.NoError(t, err, "fault proof program should have succeeded") } } func ExpectError(expectedErr error) CheckResult { - return func(t actions.Testing, err error) { + return func(t helpers.Testing, err error) { require.ErrorIs(t, err, expectedErr, "fault proof program should have failed with expected error") } } @@ -135,7 +135,7 @@ func WithL2Claim(claim common.Hash) FixtureInputParam { } } -func (env *L2FaultProofEnv) RunFaultProofProgram(t actions.Testing, l2ClaimBlockNum uint64, checkResult CheckResult, fixtureInputParams ...FixtureInputParam) { +func (env *L2FaultProofEnv) RunFaultProofProgram(t helpers.Testing, l2ClaimBlockNum uint64, checkResult CheckResult, fixtureInputParams ...FixtureInputParam) { // Fetch the pre and post output roots for the fault proof. preRoot, err := env.Sequencer.RollupClient().OutputAtBlock(t.Ctx(), l2ClaimBlockNum-1) require.NoError(t, err) @@ -182,7 +182,7 @@ func (env *L2FaultProofEnv) RunFaultProofProgram(t actions.Testing, l2ClaimBlock type TestParam func(p *e2eutils.TestParams) func NewTestParams(params ...TestParam) *e2eutils.TestParams { - dfault := actions.DefaultRollupTestParams + dfault := helpers.DefaultRollupTestParams for _, apply := range params { apply(dfault) } @@ -191,7 +191,7 @@ func NewTestParams(params ...TestParam) *e2eutils.TestParams { type DeployParam func(p *e2eutils.DeployParams) -func NewDeployParams(t actions.Testing, params ...DeployParam) *e2eutils.DeployParams { +func NewDeployParams(t helpers.Testing, params ...DeployParam) *e2eutils.DeployParams { dfault := e2eutils.MakeDeployParams(t, NewTestParams()) for _, apply := range params { apply(dfault) @@ -199,10 +199,10 @@ func NewDeployParams(t actions.Testing, params ...DeployParam) *e2eutils.DeployP return dfault } -type BatcherCfgParam func(c *actions.BatcherCfg) +type BatcherCfgParam func(c *helpers.BatcherCfg) -func NewBatcherCfg(params ...BatcherCfgParam) *actions.BatcherCfg { - dfault := &actions.BatcherCfg{ +func NewBatcherCfg(params ...BatcherCfgParam) *helpers.BatcherCfg { + dfault := &helpers.BatcherCfg{ MinL1TxSize: 0, MaxL1TxSize: 128_000, DataAvailabilityType: batcherFlags.BlobsType, @@ -216,7 +216,7 @@ func NewBatcherCfg(params ...BatcherCfgParam) *actions.BatcherCfg { type OpProgramCfgParam func(p *config.Config) func NewOpProgramCfg( - t actions.Testing, + t helpers.Testing, env *L2FaultProofEnv, fi *FixtureInputs, params ...OpProgramCfgParam, diff --git a/op-e2e/actions/proofs/helpers/fixture.go b/op-e2e/actions/proofs/helpers/fixture.go index 22c5590b9955..26c97de0a0cf 100644 --- a/op-e2e/actions/proofs/helpers/fixture.go +++ b/op-e2e/actions/proofs/helpers/fixture.go @@ -10,7 +10,7 @@ import ( "regexp" "strings" - "github.com/ethereum-optimism/optimism/op-e2e/actions" + "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/ethereum-optimism/optimism/op-program/client/claim" "github.com/ethereum-optimism/optimism/op-program/host/config" "github.com/ethereum/go-ethereum/common" @@ -48,7 +48,7 @@ type FixtureInputs struct { // Dumps a `fp-tests` test fixture to disk if the `OP_E2E_DUMP_FIXTURES` environment variable is set. // // [fp-tests]: https://github.com/ethereum-optimism/fp-tests -func tryDumpTestFixture(t actions.Testing, result error, name string, env *L2FaultProofEnv, programCfg *config.Config) { +func tryDumpTestFixture(t helpers.Testing, result error, name string, env *L2FaultProofEnv, programCfg *config.Config) { if !dumpFixtures { return } diff --git a/op-e2e/actions/proofs/sequence_window_expiry_test.go b/op-e2e/actions/proofs/sequence_window_expiry_test.go index 68a949a10b3f..44f58895faac 100644 --- a/op-e2e/actions/proofs/sequence_window_expiry_test.go +++ b/op-e2e/actions/proofs/sequence_window_expiry_test.go @@ -3,7 +3,7 @@ package proofs import ( "testing" - "github.com/ethereum-optimism/optimism/op-e2e/actions" + actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/ethereum-optimism/optimism/op-e2e/actions/proofs/helpers" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" @@ -11,7 +11,7 @@ import ( // Run a test that proves a deposit-only block generated due to sequence window expiry. func runSequenceWindowExpireTest(gt *testing.T, testCfg *helpers.TestCfg[any]) { - t := actions.NewDefaultTesting(gt) + t := actionsHelpers.NewDefaultTesting(gt) tp := helpers.NewTestParams() env := helpers.NewL2FaultProofEnv(t, testCfg, tp, helpers.NewBatcherCfg()) diff --git a/op-e2e/actions/proofs/simple_program_test.go b/op-e2e/actions/proofs/simple_program_test.go index 2d7360bb94af..ab3218caf1e4 100644 --- a/op-e2e/actions/proofs/simple_program_test.go +++ b/op-e2e/actions/proofs/simple_program_test.go @@ -3,7 +3,7 @@ package proofs import ( "testing" - "github.com/ethereum-optimism/optimism/op-e2e/actions" + actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/ethereum-optimism/optimism/op-e2e/actions/proofs/helpers" "github.com/ethereum-optimism/optimism/op-program/client/claim" "github.com/ethereum/go-ethereum/common" @@ -11,7 +11,7 @@ import ( ) func runSimpleProgramTest(gt *testing.T, testCfg *helpers.TestCfg[any]) { - t := actions.NewDefaultTesting(gt) + t := actionsHelpers.NewDefaultTesting(gt) env := helpers.NewL2FaultProofEnv(t, testCfg, helpers.NewTestParams(), helpers.NewBatcherCfg()) // Build an empty block on L2 diff --git a/op-e2e/actions/l2_proposer_test.go b/op-e2e/actions/proposer/l2_proposer_test.go similarity index 88% rename from op-e2e/actions/l2_proposer_test.go rename to op-e2e/actions/proposer/l2_proposer_test.go index a8fe25816a0c..a75ece69b080 100644 --- a/op-e2e/actions/l2_proposer_test.go +++ b/op-e2e/actions/proposer/l2_proposer_test.go @@ -1,10 +1,12 @@ -package actions +package proposer import ( "math/big" "testing" "time" + actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" + upgradesHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/upgrades/helpers" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -44,24 +46,24 @@ func TestProposerBatchType(t *testing.T) { } func RunProposerTest(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) - applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) + upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) - miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) + miner, seqEngine, sequencer := actionsHelpers.SetupSequencerTest(t, sd, log) rollupSeqCl := sequencer.RollupClient() - batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + batcher := actionsHelpers.NewL2Batcher(log, sd.RollupCfg, actionsHelpers.DefaultBatcherCfg(dp), rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) - var proposer *L2Proposer + var proposer *actionsHelpers.L2Proposer if e2eutils.UseFaultProofs() { optimismPortal2Contract, err := bindingspreview.NewOptimismPortal2(sd.DeploymentsL1.OptimismPortalProxy, miner.EthClient()) require.NoError(t, err) respectedGameType, err := optimismPortal2Contract.RespectedGameType(&bind.CallOpts{}) require.NoError(t, err) - proposer = NewL2Proposer(t, log, &ProposerCfg{ + proposer = actionsHelpers.NewL2Proposer(t, log, &actionsHelpers.ProposerCfg{ DisputeGameFactoryAddr: &sd.DeploymentsL1.DisputeGameFactoryProxy, ProposalInterval: 6 * time.Second, ProposalRetryInterval: 3 * time.Second, @@ -70,7 +72,7 @@ func RunProposerTest(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { AllowNonFinalized: true, }, miner.EthClient(), rollupSeqCl) } else { - proposer = NewL2Proposer(t, log, &ProposerCfg{ + proposer = actionsHelpers.NewL2Proposer(t, log, &actionsHelpers.ProposerCfg{ OutputOracleAddr: &sd.DeploymentsL1.L2OutputOracleProxy, ProposerKey: dp.Secrets.Proposer, ProposalRetryInterval: 3 * time.Second, diff --git a/op-e2e/actions/safedb/helpers/setups.go b/op-e2e/actions/safedb/helpers/setups.go new file mode 100644 index 000000000000..fcc70f494a74 --- /dev/null +++ b/op-e2e/actions/safedb/helpers/setups.go @@ -0,0 +1,38 @@ +package helpers + +import ( + "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-node/node/safedb" + "github.com/ethereum-optimism/optimism/op-node/rollup/sync" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +func SetupSafeDBTest(t helpers.Testing, config *e2eutils.TestParams) (*e2eutils.SetupData, *helpers.L1Miner, *helpers.L2Sequencer, *helpers.L2Verifier, *helpers.L2Engine, *helpers.L2Batcher) { + dp := e2eutils.MakeDeployParams(t, config) + + sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc) + logger := testlog.Logger(t, log.LevelDebug) + + return SetupSafeDBTestActors(t, dp, sd, logger) +} + +func SetupSafeDBTestActors(t helpers.Testing, dp *e2eutils.DeployParams, sd *e2eutils.SetupData, log log.Logger) (*e2eutils.SetupData, *helpers.L1Miner, *helpers.L2Sequencer, *helpers.L2Verifier, *helpers.L2Engine, *helpers.L2Batcher) { + dir := t.TempDir() + db, err := safedb.NewSafeDB(log, dir) + require.NoError(t, err) + t.Cleanup(func() { + _ = db.Close() + }) + miner, seqEngine, sequencer := helpers.SetupSequencerTest(t, sd, log) + miner.ActL1SetFeeRecipient(common.Address{'A'}) + sequencer.ActL2PipelineFull(t) + verifEngine, verifier := helpers.SetupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}, helpers.WithSafeHeadListener(db)) + rollupSeqCl := sequencer.RollupClient() + batcher := helpers.NewL2Batcher(log, sd.RollupCfg, helpers.DefaultBatcherCfg(dp), + rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) + return sd, miner, sequencer, verifier, verifEngine, batcher +} diff --git a/op-e2e/actions/safedb_test.go b/op-e2e/actions/safedb/safedb_test.go similarity index 68% rename from op-e2e/actions/safedb_test.go rename to op-e2e/actions/safedb/safedb_test.go index d7baeeb3715c..369825e46263 100644 --- a/op-e2e/actions/safedb_test.go +++ b/op-e2e/actions/safedb/safedb_test.go @@ -1,23 +1,20 @@ -package actions +package safedb import ( "context" "testing" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" - "github.com/ethereum-optimism/optimism/op-node/node/safedb" - "github.com/ethereum-optimism/optimism/op-node/rollup/sync" + actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" + "github.com/ethereum-optimism/optimism/op-e2e/actions/safedb/helpers" "github.com/ethereum-optimism/optimism/op-service/eth" - "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/require" ) func TestRecordSafeHeadUpdates(gt *testing.T) { - t := NewDefaultTesting(gt) - sd, miner, sequencer, verifier, verifierEng, batcher := setupSafeDBTest(t, DefaultRollupTestParams) + t := actionsHelpers.NewDefaultTesting(gt) + sd, miner, sequencer, verifier, verifierEng, batcher := helpers.SetupSafeDBTest(t, actionsHelpers.DefaultRollupTestParams) verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg) sequencer.ActL2PipelineFull(t) @@ -36,7 +33,7 @@ func TestRecordSafeHeadUpdates(gt *testing.T) { // new L1 block with L2 batch miner.ActL1StartBlock(12)(t) miner.ActL1IncludeTx(sd.RollupCfg.Genesis.SystemConfig.BatcherAddr)(t) - batchTx := miner.l1Transactions[0] + batchTx := miner.L1Transactions[0] miner.ActL1EndBlock(t) // verifier picks up the L2 chain that was submitted @@ -46,7 +43,7 @@ func TestRecordSafeHeadUpdates(gt *testing.T) { require.NotEqual(t, sequencer.L2Safe(), sequencer.L2Unsafe(), "sequencer has not processed L1 yet") // Verify the safe head is recorded - l1Head := miner.l1Chain.CurrentBlock() + l1Head := miner.L1Chain().CurrentBlock() firstSafeHeadUpdateL1Block := l1Head.Number.Uint64() response, err := verifier.RollupClient().SafeHeadAtL1Block(context.Background(), firstSafeHeadUpdateL1Block) require.NoError(t, err) @@ -62,7 +59,7 @@ func TestRecordSafeHeadUpdates(gt *testing.T) { // Only genesis is safe at this point response, err = verifier.RollupClient().SafeHeadAtL1Block(context.Background(), firstSafeHeadUpdateL1Block-1) require.NoError(t, err) - require.Equal(t, eth.HeaderBlockID(miner.l1Chain.Genesis().Header()), response.L1Block) + require.Equal(t, eth.HeaderBlockID(miner.L1Chain().Genesis().Header()), response.L1Block) require.Equal(t, sd.RollupCfg.Genesis.L2, response.SafeHead) // orphan the L1 block that included the batch tx, and build a new different L1 block @@ -83,7 +80,7 @@ func TestRecordSafeHeadUpdates(gt *testing.T) { // The safe head has been reorged so the record should have been deleted, leaving us back with just genesis safe response, err = verifier.RollupClient().SafeHeadAtL1Block(context.Background(), firstSafeHeadUpdateL1Block) require.NoError(t, err) - require.Equal(t, eth.HeaderBlockID(miner.l1Chain.Genesis().Header()), response.L1Block) + require.Equal(t, eth.HeaderBlockID(miner.L1Chain().Genesis().Header()), response.L1Block) require.Equal(t, sd.RollupCfg.Genesis.L2, response.SafeHead) // Now replay the batch tx in a new L1 block @@ -91,7 +88,7 @@ func TestRecordSafeHeadUpdates(gt *testing.T) { miner.ActL1SetFeeRecipient(common.Address{'C'}) // note: the geth tx pool reorgLoop is too slow (responds to chain head events, but async), // and there's no way to manually trigger runReorg, so we re-insert it ourselves. - require.NoError(t, miner.eth.TxPool().Add([]*types.Transaction{batchTx}, true, true)[0]) + require.NoError(t, miner.Eth.TxPool().Add([]*types.Transaction{batchTx}, true, true)[0]) // need to re-insert previously included tx into the block miner.ActL1IncludeTx(sd.RollupCfg.Genesis.SystemConfig.BatcherAddr)(t) miner.ActL1EndBlock(t) @@ -105,36 +102,10 @@ func TestRecordSafeHeadUpdates(gt *testing.T) { require.Equal(t, verifier.L2Safe(), ref, "verifier engine matches rollup client") // Verify the safe head is recorded again - l1Head = miner.l1Chain.CurrentBlock() + l1Head = miner.L1Chain().CurrentBlock() firstSafeHeadUpdateL1Block = l1Head.Number.Uint64() response, err = verifier.RollupClient().SafeHeadAtL1Block(context.Background(), firstSafeHeadUpdateL1Block) require.NoError(t, err) require.Equal(t, eth.HeaderBlockID(l1Head), response.L1Block) require.Equal(t, verifier.L2Unsafe().ID(), response.SafeHead) } - -func setupSafeDBTest(t Testing, config *e2eutils.TestParams) (*e2eutils.SetupData, *L1Miner, *L2Sequencer, *L2Verifier, *L2Engine, *L2Batcher) { - dp := e2eutils.MakeDeployParams(t, config) - - sd := e2eutils.Setup(t, dp, DefaultAlloc) - logger := testlog.Logger(t, log.LevelDebug) - - return setupSafeDBTestActors(t, dp, sd, logger) -} - -func setupSafeDBTestActors(t Testing, dp *e2eutils.DeployParams, sd *e2eutils.SetupData, log log.Logger) (*e2eutils.SetupData, *L1Miner, *L2Sequencer, *L2Verifier, *L2Engine, *L2Batcher) { - dir := t.TempDir() - db, err := safedb.NewSafeDB(log, dir) - require.NoError(t, err) - t.Cleanup(func() { - _ = db.Close() - }) - miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) - miner.ActL1SetFeeRecipient(common.Address{'A'}) - sequencer.ActL2PipelineFull(t) - verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}, WithSafeHeadListener(db)) - rollupSeqCl := sequencer.RollupClient() - batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), - rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) - return sd, miner, sequencer, verifier, verifEngine, batcher -} diff --git a/op-e2e/actions/l2_sequencer_test.go b/op-e2e/actions/sequencer/l2_sequencer_test.go similarity index 79% rename from op-e2e/actions/l2_sequencer_test.go rename to op-e2e/actions/sequencer/l2_sequencer_test.go index 8872da6481d1..5192c25d7afd 100644 --- a/op-e2e/actions/l2_sequencer_test.go +++ b/op-e2e/actions/sequencer/l2_sequencer_test.go @@ -1,9 +1,10 @@ -package actions +package sequencer import ( "math/big" "testing" + "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" @@ -11,33 +12,12 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/require" - altda "github.com/ethereum-optimism/optimism/op-alt-da" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" - "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-service/testlog" ) -func setupSequencerTest(t Testing, sd *e2eutils.SetupData, log log.Logger, opts ...SequencerOpt) (*L1Miner, *L2Engine, *L2Sequencer) { - jwtPath := e2eutils.WriteDefaultJWT(t) - cfg := DefaultSequencerConfig() - for _, opt := range opts { - opt(cfg) - } - - miner := NewL1Miner(t, log.New("role", "l1-miner"), sd.L1Cfg) - - l1F, err := sources.NewL1Client(miner.RPCClient(), log, nil, sources.L1ClientDefaultConfig(sd.RollupCfg, false, sources.RPCKindStandard)) - require.NoError(t, err) - engine := NewL2Engine(t, log.New("role", "sequencer-engine"), sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath, EngineWithP2P()) - l2Cl, err := sources.NewEngineClient(engine.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) - require.NoError(t, err) - - sequencer := NewL2Sequencer(t, log.New("role", "sequencer"), l1F, miner.BlobStore(), altda.Disabled, l2Cl, sd.RollupCfg, 0, cfg.InteropBackend) - return miner, engine, sequencer -} - func TestL2Sequencer_SequencerDrift(gt *testing.T) { - t := NewDefaultTesting(gt) + t := helpers.NewDefaultTesting(gt) p := &e2eutils.TestParams{ MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) SequencerWindowSize: 24, @@ -45,9 +25,9 @@ func TestL2Sequencer_SequencerDrift(gt *testing.T) { L1BlockTime: 12, } dp := e2eutils.MakeDeployParams(t, p) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) - miner, engine, sequencer := setupSequencerTest(t, sd, log) + miner, engine, sequencer := helpers.SetupSequencerTest(t, sd, log) miner.ActL1SetFeeRecipient(common.Address{'A'}) sequencer.ActL2PipelineFull(t) @@ -61,7 +41,7 @@ func TestL2Sequencer_SequencerDrift(gt *testing.T) { ChainID: sd.L2Cfg.Config.ChainID, Nonce: n, GasTipCap: big.NewInt(2 * params.GWei), - GasFeeCap: new(big.Int).Add(miner.l1Chain.CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), + GasFeeCap: new(big.Int).Add(miner.L1Chain().CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), Gas: params.TxGas, To: &dp.Addresses.Bob, Value: e2eutils.Ether(2), @@ -79,7 +59,7 @@ func TestL2Sequencer_SequencerDrift(gt *testing.T) { miner.ActL1StartBlock(12)(t) miner.ActL1EndBlock(t) sequencer.ActL1HeadSignal(t) - origin := miner.l1Chain.CurrentBlock() + origin := miner.L1Chain().CurrentBlock() // L2 makes blocks to catch up for sequencer.SyncStatus().UnsafeL2.Time+sd.RollupCfg.BlockTime < origin.Time { @@ -104,18 +84,18 @@ func TestL2Sequencer_SequencerDrift(gt *testing.T) { // We passed the sequencer drift: we can still keep the old origin, but can't include any txs sequencer.ActL2KeepL1Origin(t) sequencer.ActL2StartBlock(t) - require.True(t, engine.engineApi.ForcedEmpty(), "engine should not be allowed to include anything after sequencer drift is surpassed") + require.True(t, engine.EngineApi.ForcedEmpty(), "engine should not be allowed to include anything after sequencer drift is surpassed") } // TestL2Sequencer_SequencerOnlyReorg regression-tests a Goerli halt where the sequencer // would build an unsafe L2 block with a L1 origin that then gets reorged out, // while the verifier-codepath only ever sees the valid post-reorg L1 chain. func TestL2Sequencer_SequencerOnlyReorg(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + t := helpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams) + sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) - miner, _, sequencer := setupSequencerTest(t, sd, log) + miner, _, sequencer := helpers.SetupSequencerTest(t, sd, log) // Sequencer at first only recognizes the genesis as safe. // The rest of the L1 chain will be incorporated as L1 origins into unsafe L2 blocks. diff --git a/op-e2e/actions/sync_test.go b/op-e2e/actions/sync/sync_test.go similarity index 82% rename from op-e2e/actions/sync_test.go rename to op-e2e/actions/sync/sync_test.go index d2b34b1f06fa..cd6bf4b29b9d 100644 --- a/op-e2e/actions/sync_test.go +++ b/op-e2e/actions/sync/sync_test.go @@ -1,4 +1,4 @@ -package actions +package sync import ( "errors" @@ -8,6 +8,8 @@ import ( "testing" "time" + actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" + upgradesHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/upgrades/helpers" "github.com/stretchr/testify/require" "github.com/ethereum/go-ethereum" @@ -32,7 +34,7 @@ import ( "github.com/ethereum-optimism/optimism/op-service/testutils" ) -func newSpanChannelOut(t StatefulTesting, e e2eutils.SetupData) derive.ChannelOut { +func newSpanChannelOut(t actionsHelpers.StatefulTesting, e e2eutils.SetupData) derive.ChannelOut { channelOut, err := derive.NewSpanChannelOut(e.RollupCfg.Genesis.L2Time, e.RollupCfg.L2ChainID, 128_000, derive.Zlib, rollup.NewChainSpec(e.RollupCfg)) require.NoError(t, err) return channelOut @@ -64,12 +66,12 @@ func TestSyncBatchType(t *testing.T) { } func DerivationWithFlakyL1RPC(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) - applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) + upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelError) // mute all the temporary derivation errors that we forcefully create - _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + _, _, miner, sequencer, _, verifier, _, batcher := actionsHelpers.SetupReorgTestActors(t, dp, sd, log) rng := rand.New(rand.NewSource(1234)) sequencer.ActL2PipelineFull(t) @@ -83,7 +85,7 @@ func DerivationWithFlakyL1RPC(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { sequencer.ActBuildToL1Head(t) batcher.ActSubmitAll(t) miner.ActL1StartBlock(12)(t) - miner.ActL1IncludeTx(batcher.batcherAddr)(t) + miner.ActL1IncludeTx(batcher.BatcherAddr)(t) miner.ActL1EndBlock(t) } // Make verifier aware of head @@ -104,12 +106,12 @@ func DerivationWithFlakyL1RPC(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { } func FinalizeWhileSyncing(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) - applyDeltaTimeOffset(dp, deltaTimeOffset) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) + upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelError) // mute all the temporary derivation errors that we forcefully create - _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + _, _, miner, sequencer, _, verifier, _, batcher := actionsHelpers.SetupReorgTestActors(t, dp, sd, log) sequencer.ActL2PipelineFull(t) verifier.ActL2PipelineFull(t) @@ -126,10 +128,10 @@ func FinalizeWhileSyncing(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { sequencer.ActBuildToL1Head(t) batcher.ActSubmitAll(t) miner.ActL1StartBlock(12)(t) - miner.ActL1IncludeTx(batcher.batcherAddr)(t) + miner.ActL1IncludeTx(batcher.BatcherAddr)(t) miner.ActL1EndBlock(t) } - l1Head := miner.l1Chain.CurrentHeader() + l1Head := miner.L1Chain().CurrentHeader() // finalize all of L1 miner.ActL1Safe(t, l1Head.Number.Uint64()) miner.ActL1Finalize(t, l1Head.Number.Uint64()) @@ -150,12 +152,12 @@ func FinalizeWhileSyncing(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { // TestUnsafeSync tests that a verifier properly imports unsafe blocks via gossip. func TestUnsafeSync(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelInfo) - sd, _, _, sequencer, seqEng, verifier, _, _ := setupReorgTestActors(t, dp, sd, log) + sd, _, _, sequencer, seqEng, verifier, _, _ := actionsHelpers.SetupReorgTestActors(t, dp, sd, log) seqEngCl, err := sources.NewEngineClient(seqEng.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(t, err) @@ -178,15 +180,15 @@ func TestUnsafeSync(gt *testing.T) { } func TestBackupUnsafe(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) minTs := hexutil.Uint64(0) // Activate Delta hardfork - applyDeltaTimeOffset(dp, &minTs) + upgradesHelpers.ApplyDeltaTimeOffset(dp, &minTs) dp.DeployConfig.L2BlockTime = 2 - sd := e2eutils.Setup(t, dp, DefaultAlloc) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LvlInfo) - _, dp, miner, sequencer, seqEng, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + _, dp, miner, sequencer, seqEng, verifier, _, batcher := actionsHelpers.SetupReorgTestActors(t, dp, sd, log) l2Cl := seqEng.EthClient() seqEngCl, err := sources.NewEngineClient(seqEng.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(t, err) @@ -238,7 +240,7 @@ func TestBackupUnsafe(gt *testing.T) { ChainID: sd.L2Cfg.Config.ChainID, Nonce: n, GasTipCap: big.NewInt(2 * params.GWei), - GasFeeCap: new(big.Int).Add(miner.l1Chain.CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), + GasFeeCap: new(big.Int).Add(miner.L1Chain().CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), Gas: params.TxGas, To: &dp.Addresses.Bob, Value: e2eutils.Ether(2), @@ -256,7 +258,7 @@ func TestBackupUnsafe(gt *testing.T) { } // Submit span batch(A1, B2, invalid B3, B4, B5) - batcher.l2ChannelOut = channelOut + batcher.L2ChannelOut = channelOut batcher.ActL2ChannelClose(t) batcher.ActL2BatchSubmit(t) @@ -339,15 +341,15 @@ func TestBackupUnsafe(gt *testing.T) { } func TestBackupUnsafeReorgForkChoiceInputError(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) minTs := hexutil.Uint64(0) // Activate Delta hardfork - applyDeltaTimeOffset(dp, &minTs) + upgradesHelpers.ApplyDeltaTimeOffset(dp, &minTs) dp.DeployConfig.L2BlockTime = 2 - sd := e2eutils.Setup(t, dp, DefaultAlloc) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LvlInfo) - _, dp, miner, sequencer, seqEng, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + _, dp, miner, sequencer, seqEng, verifier, _, batcher := actionsHelpers.SetupReorgTestActors(t, dp, sd, log) l2Cl := seqEng.EthClient() seqEngCl, err := sources.NewEngineClient(seqEng.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(t, err) @@ -399,7 +401,7 @@ func TestBackupUnsafeReorgForkChoiceInputError(gt *testing.T) { ChainID: sd.L2Cfg.Config.ChainID, Nonce: n, GasTipCap: big.NewInt(2 * params.GWei), - GasFeeCap: new(big.Int).Add(miner.l1Chain.CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), + GasFeeCap: new(big.Int).Add(miner.L1Chain().CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), Gas: params.TxGas, To: &dp.Addresses.Bob, Value: e2eutils.Ether(2), @@ -417,7 +419,7 @@ func TestBackupUnsafeReorgForkChoiceInputError(gt *testing.T) { } // Submit span batch(A1, B2, invalid B3, B4, B5) - batcher.l2ChannelOut = channelOut + batcher.L2ChannelOut = channelOut batcher.ActL2ChannelClose(t) batcher.ActL2BatchSubmit(t) @@ -472,15 +474,15 @@ func TestBackupUnsafeReorgForkChoiceInputError(gt *testing.T) { } func TestBackupUnsafeReorgForkChoiceNotInputError(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) minTs := hexutil.Uint64(0) // Activate Delta hardfork - applyDeltaTimeOffset(dp, &minTs) + upgradesHelpers.ApplyDeltaTimeOffset(dp, &minTs) dp.DeployConfig.L2BlockTime = 2 - sd := e2eutils.Setup(t, dp, DefaultAlloc) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LvlInfo) - _, dp, miner, sequencer, seqEng, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + _, dp, miner, sequencer, seqEng, verifier, _, batcher := actionsHelpers.SetupReorgTestActors(t, dp, sd, log) l2Cl := seqEng.EthClient() seqEngCl, err := sources.NewEngineClient(seqEng.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(t, err) @@ -532,7 +534,7 @@ func TestBackupUnsafeReorgForkChoiceNotInputError(gt *testing.T) { ChainID: sd.L2Cfg.Config.ChainID, Nonce: n, GasTipCap: big.NewInt(2 * params.GWei), - GasFeeCap: new(big.Int).Add(miner.l1Chain.CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), + GasFeeCap: new(big.Int).Add(miner.L1Chain().CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), Gas: params.TxGas, To: &dp.Addresses.Bob, Value: e2eutils.Ether(2), @@ -550,7 +552,7 @@ func TestBackupUnsafeReorgForkChoiceNotInputError(gt *testing.T) { } // Submit span batch(A1, B2, invalid B3, B4, B5) - batcher.l2ChannelOut = channelOut + batcher.L2ChannelOut = channelOut batcher.ActL2ChannelClose(t) batcher.ActL2BatchSubmit(t) @@ -587,7 +589,7 @@ func TestBackupUnsafeReorgForkChoiceNotInputError(gt *testing.T) { serverErrCnt := 2 // mock forkChoiceUpdate failure while restoring previous unsafe chain using backupUnsafe. - seqEng.failL2RPC = func(call []rpc.BatchElem) error { + seqEng.FailL2RPC = func(call []rpc.BatchElem) error { for _, e := range call { // There may be other calls, like payload-processing-cancellation // based on previous invalid block, and processing of block attributes. @@ -625,7 +627,7 @@ func TestBackupUnsafeReorgForkChoiceNotInputError(gt *testing.T) { // builds l2 blocks within the specified range `from` - `to` // and performs an EL sync between the sequencer and the verifier, // then checks the validity of the payloads within a specified block range. -func PerformELSyncAndCheckPayloads(t Testing, miner *L1Miner, seqEng *L2Engine, sequencer *L2Sequencer, verEng *L2Engine, verifier *L2Verifier, seqEngCl *sources.EngineClient, from, to uint64) { +func PerformELSyncAndCheckPayloads(t actionsHelpers.Testing, miner *actionsHelpers.L1Miner, seqEng *actionsHelpers.L2Engine, sequencer *actionsHelpers.L2Sequencer, verEng *actionsHelpers.L2Engine, verifier *actionsHelpers.L2Verifier, seqEngCl *sources.EngineClient, from, to uint64) { miner.ActEmptyBlock(t) sequencer.ActL2PipelineFull(t) @@ -658,7 +660,7 @@ func PerformELSyncAndCheckPayloads(t Testing, miner *L1Miner, seqEng *L2Engine, // Verify this by checking that the verifier has the correct value for block 1 require.Eventually(t, func() bool { - block, err := verifier.eng.L2BlockRefByNumber(t.Ctx(), from) + block, err := verifier.Eng.L2BlockRefByNumber(t.Ctx(), from) if err != nil { return false } @@ -670,14 +672,14 @@ func PerformELSyncAndCheckPayloads(t Testing, miner *L1Miner, seqEng *L2Engine, } // verifies that a specific block number on the L2 engine has the expected label. -func VerifyBlock(t Testing, engine L2API, number uint64, label eth.BlockLabel) { +func VerifyBlock(t actionsHelpers.Testing, engine actionsHelpers.L2API, number uint64, label eth.BlockLabel) { id, err := engine.L2BlockRefByLabel(t.Ctx(), label) require.NoError(t, err) require.Equal(t, number, id.Number) } // submits batch at a specified block number -func BatchSubmitBlock(t Testing, miner *L1Miner, sequencer *L2Sequencer, verifier *L2Verifier, batcher *L2Batcher, dp *e2eutils.DeployParams, number uint64) { +func BatchSubmitBlock(t actionsHelpers.Testing, miner *actionsHelpers.L1Miner, sequencer *actionsHelpers.L2Sequencer, verifier *actionsHelpers.L2Verifier, batcher *actionsHelpers.L2Batcher, dp *e2eutils.DeployParams, number uint64) { sequencer.ActL2StartBlock(t) sequencer.ActL2EndBlock(t) batcher.ActSubmitAll(t) @@ -691,14 +693,14 @@ func BatchSubmitBlock(t Testing, miner *L1Miner, sequencer *L2Sequencer, verifie // TestELSync tests that a verifier will have the EL import the full chain from the sequencer // when passed a single unsafe block. op-geth can either snap sync or full sync here. func TestELSync(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelInfo) - miner, seqEng, sequencer := setupSequencerTest(t, sd, log) + miner, seqEng, sequencer := actionsHelpers.SetupSequencerTest(t, sd, log) // Enable engine P2P sync - verEng, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{SyncMode: sync.ELSync}) + verEng, verifier := actionsHelpers.SetupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{SyncMode: sync.ELSync}) seqEngCl, err := sources.NewEngineClient(seqEng.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(t, err) @@ -706,11 +708,11 @@ func TestELSync(gt *testing.T) { PerformELSyncAndCheckPayloads(t, miner, seqEng, sequencer, verEng, verifier, seqEngCl, 0, 10) } -func PrepareELSyncedNode(t Testing, miner *L1Miner, sequencer *L2Sequencer, seqEng *L2Engine, verifier *L2Verifier, verEng *L2Engine, seqEngCl *sources.EngineClient, batcher *L2Batcher, dp *e2eutils.DeployParams) { +func PrepareELSyncedNode(t actionsHelpers.Testing, miner *actionsHelpers.L1Miner, sequencer *actionsHelpers.L2Sequencer, seqEng *actionsHelpers.L2Engine, verifier *actionsHelpers.L2Verifier, verEng *actionsHelpers.L2Engine, seqEngCl *sources.EngineClient, batcher *actionsHelpers.L2Batcher, dp *e2eutils.DeployParams) { PerformELSyncAndCheckPayloads(t, miner, seqEng, sequencer, verEng, verifier, seqEngCl, 0, 10) // Despite downloading the blocks, it has not finished finalizing - _, err := verifier.eng.L2BlockRefByLabel(t.Ctx(), "safe") + _, err := verifier.Eng.L2BlockRefByLabel(t.Ctx(), "safe") require.ErrorIs(t, err, ethereum.NotFound) // Insert a block on the verifier to end snap sync @@ -721,15 +723,15 @@ func PrepareELSyncedNode(t Testing, miner *L1Miner, sequencer *L2Sequencer, seqE verifier.ActL2InsertUnsafePayload(seqHead)(t) // Check that safe + finalized are there - VerifyBlock(t, verifier.eng, 11, eth.Safe) - VerifyBlock(t, verifier.eng, 11, eth.Finalized) + VerifyBlock(t, verifier.Eng, 11, eth.Safe) + VerifyBlock(t, verifier.Eng, 11, eth.Finalized) // Batch submit everything BatchSubmitBlock(t, miner, sequencer, verifier, batcher, dp, 12) // Verify that the batch submitted blocks are there now - VerifyBlock(t, sequencer.eng, 12, eth.Safe) - VerifyBlock(t, verifier.eng, 12, eth.Safe) + VerifyBlock(t, sequencer.Eng, 12, eth.Safe) + VerifyBlock(t, verifier.Eng, 12, eth.Safe) } // TestELSyncTransitionstoCL tests that a verifier which starts with EL sync can switch back to a proper CL sync. @@ -744,17 +746,17 @@ func PrepareELSyncedNode(t Testing, miner *L1Miner, sequencer *L2Sequencer, seqE // Prior to this PR, the test would fail at this point. // 8. Create 1 more block & batch submit everything & assert that the verifier picked up those blocks func TestELSyncTransitionstoCL(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) logger := testlog.Logger(t, log.LevelInfo) captureLog, captureLogHandler := testlog.CaptureLogger(t, log.LevelInfo) - miner, seqEng, sequencer := setupSequencerTest(t, sd, logger) - batcher := NewL2Batcher(logger, sd.RollupCfg, DefaultBatcherCfg(dp), sequencer.RollupClient(), miner.EthClient(), seqEng.EthClient(), seqEng.EngineClient(t, sd.RollupCfg)) + miner, seqEng, sequencer := actionsHelpers.SetupSequencerTest(t, sd, logger) + batcher := actionsHelpers.NewL2Batcher(logger, sd.RollupCfg, actionsHelpers.DefaultBatcherCfg(dp), sequencer.RollupClient(), miner.EthClient(), seqEng.EthClient(), seqEng.EngineClient(t, sd.RollupCfg)) // Enable engine P2P sync - verEng, verifier := setupVerifier(t, sd, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{SyncMode: sync.ELSync}) + verEng, verifier := actionsHelpers.SetupVerifier(t, sd, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{SyncMode: sync.ELSync}) seqEngCl, err := sources.NewEngineClient(seqEng.RPCClient(), logger, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(t, err) @@ -790,28 +792,28 @@ func TestELSyncTransitionstoCL(gt *testing.T) { // This was failing prior to PR 9661 because op-node would attempt to immediately insert blocks into the EL inside the engine queue. op-geth // would not be able to fetch the second range of blocks & it would wipe out the unsafe payloads queue because op-node thought that it had a // higher unsafe block but op-geth did not. - VerifyBlock(t, verifier.eng, 22, eth.Unsafe) + VerifyBlock(t, verifier.Eng, 22, eth.Unsafe) // Create 1 more block & batch submit everything BatchSubmitBlock(t, miner, sequencer, verifier, batcher, dp, 12) // Verify that the batch submitted blocks are there now - VerifyBlock(t, sequencer.eng, 23, eth.Safe) - VerifyBlock(t, verifier.eng, 23, eth.Safe) + VerifyBlock(t, sequencer.Eng, 23, eth.Safe) + VerifyBlock(t, verifier.Eng, 23, eth.Safe) } func TestELSyncTransitionsToCLSyncAfterNodeRestart(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) logger := testlog.Logger(t, log.LevelInfo) captureLog, captureLogHandler := testlog.CaptureLogger(t, log.LevelInfo) - miner, seqEng, sequencer := setupSequencerTest(t, sd, logger) - batcher := NewL2Batcher(logger, sd.RollupCfg, DefaultBatcherCfg(dp), sequencer.RollupClient(), miner.EthClient(), seqEng.EthClient(), seqEng.EngineClient(t, sd.RollupCfg)) + miner, seqEng, sequencer := actionsHelpers.SetupSequencerTest(t, sd, logger) + batcher := actionsHelpers.NewL2Batcher(logger, sd.RollupCfg, actionsHelpers.DefaultBatcherCfg(dp), sequencer.RollupClient(), miner.EthClient(), seqEng.EthClient(), seqEng.EngineClient(t, sd.RollupCfg)) // Enable engine P2P sync - verEng, verifier := setupVerifier(t, sd, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{SyncMode: sync.ELSync}) + verEng, verifier := actionsHelpers.SetupVerifier(t, sd, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{SyncMode: sync.ELSync}) seqEngCl, err := sources.NewEngineClient(seqEng.RPCClient(), logger, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(t, err) @@ -819,7 +821,7 @@ func TestELSyncTransitionsToCLSyncAfterNodeRestart(gt *testing.T) { PrepareELSyncedNode(t, miner, sequencer, seqEng, verifier, verEng, seqEngCl, batcher, dp) // Create a new verifier which is essentially a new op-node with the sync mode of ELSync and default geth engine kind. - verifier = NewL2Verifier(t, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), altda.Disabled, verifier.eng, sd.RollupCfg, &sync.Config{SyncMode: sync.ELSync}, DefaultVerifierCfg().SafeHeadListener, nil) + verifier = actionsHelpers.NewL2Verifier(t, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), altda.Disabled, verifier.Eng, sd.RollupCfg, &sync.Config{SyncMode: sync.ELSync}, actionsHelpers.DefaultVerifierCfg().SafeHeadListener, nil) // Build another 10 L1 blocks on the sequencer for i := 0; i < 10; i++ { @@ -843,17 +845,17 @@ func TestELSyncTransitionsToCLSyncAfterNodeRestart(gt *testing.T) { } func TestForcedELSyncCLAfterNodeRestart(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) logger := testlog.Logger(t, log.LevelInfo) captureLog, captureLogHandler := testlog.CaptureLogger(t, log.LevelInfo) - miner, seqEng, sequencer := setupSequencerTest(t, sd, logger) - batcher := NewL2Batcher(logger, sd.RollupCfg, DefaultBatcherCfg(dp), sequencer.RollupClient(), miner.EthClient(), seqEng.EthClient(), seqEng.EngineClient(t, sd.RollupCfg)) + miner, seqEng, sequencer := actionsHelpers.SetupSequencerTest(t, sd, logger) + batcher := actionsHelpers.NewL2Batcher(logger, sd.RollupCfg, actionsHelpers.DefaultBatcherCfg(dp), sequencer.RollupClient(), miner.EthClient(), seqEng.EthClient(), seqEng.EngineClient(t, sd.RollupCfg)) // Enable engine P2P sync - verEng, verifier := setupVerifier(t, sd, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{SyncMode: sync.ELSync}) + verEng, verifier := actionsHelpers.SetupVerifier(t, sd, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{SyncMode: sync.ELSync}) seqEngCl, err := sources.NewEngineClient(seqEng.RPCClient(), logger, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(t, err) @@ -861,7 +863,7 @@ func TestForcedELSyncCLAfterNodeRestart(gt *testing.T) { PrepareELSyncedNode(t, miner, sequencer, seqEng, verifier, verEng, seqEngCl, batcher, dp) // Create a new verifier which is essentially a new op-node with the sync mode of ELSync and erigon engine kind. - verifier2 := NewL2Verifier(t, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), altda.Disabled, verifier.eng, sd.RollupCfg, &sync.Config{SyncMode: sync.ELSync, SupportsPostFinalizationELSync: true}, DefaultVerifierCfg().SafeHeadListener, nil) + verifier2 := actionsHelpers.NewL2Verifier(t, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), altda.Disabled, verifier.Eng, sd.RollupCfg, &sync.Config{SyncMode: sync.ELSync, SupportsPostFinalizationELSync: true}, actionsHelpers.DefaultVerifierCfg().SafeHeadListener, nil) // Build another 10 L1 blocks on the sequencer for i := 0; i < 10; i++ { @@ -889,15 +891,15 @@ func TestForcedELSyncCLAfterNodeRestart(gt *testing.T) { } func TestInvalidPayloadInSpanBatch(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) minTs := hexutil.Uint64(0) // Activate Delta hardfork - applyDeltaTimeOffset(dp, &minTs) + upgradesHelpers.ApplyDeltaTimeOffset(dp, &minTs) dp.DeployConfig.L2BlockTime = 2 - sd := e2eutils.Setup(t, dp, DefaultAlloc) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelInfo) - _, _, miner, sequencer, seqEng, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + _, _, miner, sequencer, seqEng, verifier, _, batcher := actionsHelpers.SetupReorgTestActors(t, dp, sd, log) l2Cl := seqEng.EthClient() rng := rand.New(rand.NewSource(1234)) signer := types.LatestSigner(sd.L2Cfg.Config) @@ -927,7 +929,7 @@ func TestInvalidPayloadInSpanBatch(gt *testing.T) { } // Submit span batch(A1, ..., A7, invalid A8, A9, ..., A12) - batcher.l2ChannelOut = channelOut + batcher.L2ChannelOut = channelOut batcher.ActL2ChannelClose(t) batcher.ActL2BatchSubmit(t) @@ -956,7 +958,7 @@ func TestInvalidPayloadInSpanBatch(gt *testing.T) { data := make([]byte, rand.Intn(100)) gas, err := core.IntrinsicGas(data, nil, false, true, true, false) require.NoError(t, err) - baseFee := seqEng.l2Chain.CurrentBlock().BaseFee + baseFee := seqEng.L2Chain().CurrentBlock().BaseFee tx := types.MustSignNewTx(dp.Secrets.Alice, signer, &types.DynamicFeeTx{ ChainID: sd.L2Cfg.Config.ChainID, Nonce: aliceNonce, @@ -975,7 +977,7 @@ func TestInvalidPayloadInSpanBatch(gt *testing.T) { require.NoError(t, err) } // Submit span batch(B1, A2, ... A12) - batcher.l2ChannelOut = channelOut + batcher.L2ChannelOut = channelOut batcher.ActL2ChannelClose(t) batcher.ActL2BatchSubmit(t) @@ -994,15 +996,15 @@ func TestInvalidPayloadInSpanBatch(gt *testing.T) { } func TestSpanBatchAtomicity_Consolidation(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) minTs := hexutil.Uint64(0) // Activate Delta hardfork - applyDeltaTimeOffset(dp, &minTs) + upgradesHelpers.ApplyDeltaTimeOffset(dp, &minTs) dp.DeployConfig.L2BlockTime = 2 - sd := e2eutils.Setup(t, dp, DefaultAlloc) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelInfo) - _, _, miner, sequencer, seqEng, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + _, _, miner, sequencer, seqEng, verifier, _, batcher := actionsHelpers.SetupReorgTestActors(t, dp, sd, log) seqEngCl, err := sources.NewEngineClient(seqEng.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(t, err) @@ -1036,8 +1038,8 @@ func TestSpanBatchAtomicity_Consolidation(gt *testing.T) { // Start verifier safe sync verifier.ActL1HeadSignal(t) - verifier.l2PipelineIdle = false - for !verifier.l2PipelineIdle { + verifier.L2PipelineIdle = false + for !verifier.L2PipelineIdle { // wait for next pending block verifier.ActL2EventsUntil(t, func(ev event.Event) bool { if event.Is[engine2.SafeDerivedEvent](ev) { // safe updates should only happen once the pending-safe reaches the target. @@ -1062,15 +1064,15 @@ func TestSpanBatchAtomicity_Consolidation(gt *testing.T) { } func TestSpanBatchAtomicity_ForceAdvance(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + t := actionsHelpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams) minTs := hexutil.Uint64(0) // Activate Delta hardfork - applyDeltaTimeOffset(dp, &minTs) + upgradesHelpers.ApplyDeltaTimeOffset(dp, &minTs) dp.DeployConfig.L2BlockTime = 2 - sd := e2eutils.Setup(t, dp, DefaultAlloc) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelInfo) - _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + _, _, miner, sequencer, _, verifier, _, batcher := actionsHelpers.SetupReorgTestActors(t, dp, sd, log) targetHeadNumber := uint64(6) // L1 block time / L2 block time @@ -1092,8 +1094,8 @@ func TestSpanBatchAtomicity_ForceAdvance(gt *testing.T) { // Start verifier safe sync verifier.ActL1HeadSignal(t) - verifier.l2PipelineIdle = false - for !verifier.l2PipelineIdle { + verifier.L2PipelineIdle = false + for !verifier.L2PipelineIdle { // wait for next pending block verifier.ActL2EventsUntil(t, func(ev event.Event) bool { if event.Is[engine2.SafeDerivedEvent](ev) { // safe updates should only happen once the pending-safe reaches the target. diff --git a/op-e2e/actions/dencun_fork_test.go b/op-e2e/actions/upgrades/dencun_fork_test.go similarity index 71% rename from op-e2e/actions/dencun_fork_test.go rename to op-e2e/actions/upgrades/dencun_fork_test.go index ac0484c800b0..a9e3eb2cc256 100644 --- a/op-e2e/actions/dencun_fork_test.go +++ b/op-e2e/actions/upgrades/dencun_fork_test.go @@ -1,9 +1,10 @@ -package actions +package upgrades import ( "context" "testing" + "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/stretchr/testify/require" "github.com/ethereum/go-ethereum/common" @@ -17,15 +18,15 @@ import ( ) func TestDencunL1ForkAfterGenesis(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + t := helpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams) offset := hexutil.Uint64(24) dp.DeployConfig.L1CancunTimeOffset = &offset - sd := e2eutils.Setup(t, dp, DefaultAlloc) + sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) - _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + _, _, miner, sequencer, _, verifier, _, batcher := helpers.SetupReorgTestActors(t, dp, sd, log) - l1Head := miner.l1Chain.CurrentBlock() + l1Head := miner.L1Chain().CurrentBlock() require.False(t, sd.L1Cfg.Config.IsCancun(l1Head.Number, l1Head.Time), "Cancun not active yet") require.Nil(t, l1Head.ExcessBlobGas, "Cancun blob gas not in header") @@ -39,7 +40,7 @@ func TestDencunL1ForkAfterGenesis(gt *testing.T) { miner.ActEmptyBlock(t) // Cancun activates here miner.ActEmptyBlock(t) // verify Cancun is active - l1Head = miner.l1Chain.CurrentBlock() + l1Head = miner.L1Chain().CurrentBlock() require.True(t, sd.L1Cfg.Config.IsCancun(l1Head.Number, l1Head.Time), "Cancun active") require.NotNil(t, l1Head.ExcessBlobGas, "Cancun blob gas in header") @@ -48,7 +49,7 @@ func TestDencunL1ForkAfterGenesis(gt *testing.T) { sequencer.ActBuildToL1Head(t) miner.ActL1StartBlock(12)(t) batcher.ActSubmitAll(t) - miner.ActL1IncludeTx(batcher.batcherAddr)(t) + miner.ActL1IncludeTx(batcher.BatcherAddr)(t) miner.ActL1EndBlock(t) // sync verifier @@ -60,14 +61,14 @@ func TestDencunL1ForkAfterGenesis(gt *testing.T) { } func TestDencunL1ForkAtGenesis(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + t := helpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams) require.Zero(t, *dp.DeployConfig.L1CancunTimeOffset) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) - _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + _, _, miner, sequencer, _, verifier, _, batcher := helpers.SetupReorgTestActors(t, dp, sd, log) - l1Head := miner.l1Chain.CurrentBlock() + l1Head := miner.L1Chain().CurrentBlock() require.True(t, sd.L1Cfg.Config.IsCancun(l1Head.Number, l1Head.Time), "Cancun active at genesis") require.NotNil(t, l1Head.ExcessBlobGas, "Cancun blob gas in header") @@ -81,7 +82,7 @@ func TestDencunL1ForkAtGenesis(gt *testing.T) { miner.ActEmptyBlock(t) // verify Cancun is still active - l1Head = miner.l1Chain.CurrentBlock() + l1Head = miner.L1Chain().CurrentBlock() require.True(t, sd.L1Cfg.Config.IsCancun(l1Head.Number, l1Head.Time), "Cancun active") require.NotNil(t, l1Head.ExcessBlobGas, "Cancun blob gas in header") @@ -90,7 +91,7 @@ func TestDencunL1ForkAtGenesis(gt *testing.T) { sequencer.ActBuildToL1Head(t) miner.ActL1StartBlock(12)(t) batcher.ActSubmitAll(t) - miner.ActL1IncludeTx(batcher.batcherAddr)(t) + miner.ActL1IncludeTx(batcher.BatcherAddr)(t) miner.ActL1EndBlock(t) // sync verifier @@ -117,8 +118,8 @@ func verifyEcotoneBlock(gt *testing.T, header *types.Header) { } func TestDencunL2ForkAfterGenesis(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + t := helpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams) require.Zero(t, *dp.DeployConfig.L1CancunTimeOffset) // This test wil fork on the second block offset := hexutil.Uint64(dp.DeployConfig.L2BlockTime * 2) @@ -127,56 +128,56 @@ func TestDencunL2ForkAfterGenesis(gt *testing.T) { dp.DeployConfig.L2GenesisGraniteTimeOffset = nil // New forks have to be added here, after changing the default deploy config! - sd := e2eutils.Setup(t, dp, DefaultAlloc) + sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) - _, _, _, sequencer, engine, verifier, _, _ := setupReorgTestActors(t, dp, sd, log) + _, _, _, sequencer, engine, verifier, _, _ := helpers.SetupReorgTestActors(t, dp, sd, log) // start op-nodes sequencer.ActL2PipelineFull(t) verifier.ActL2PipelineFull(t) // Genesis block is pre-ecotone - verifyPreEcotoneBlock(gt, engine.l2Chain.CurrentBlock()) + verifyPreEcotoneBlock(gt, engine.L2Chain().CurrentBlock()) // Block before fork block sequencer.ActL2StartBlock(t) sequencer.ActL2EndBlock(t) - verifyPreEcotoneBlock(gt, engine.l2Chain.CurrentBlock()) + verifyPreEcotoneBlock(gt, engine.L2Chain().CurrentBlock()) // Fork block is ecotone sequencer.ActL2StartBlock(t) sequencer.ActL2EndBlock(t) - verifyEcotoneBlock(gt, engine.l2Chain.CurrentBlock()) + verifyEcotoneBlock(gt, engine.L2Chain().CurrentBlock()) // Blocks post fork have Ecotone properties sequencer.ActL2StartBlock(t) sequencer.ActL2EndBlock(t) - verifyEcotoneBlock(gt, engine.l2Chain.CurrentBlock()) + verifyEcotoneBlock(gt, engine.L2Chain().CurrentBlock()) } func TestDencunL2ForkAtGenesis(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + t := helpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams) require.Zero(t, *dp.DeployConfig.L2GenesisEcotoneTimeOffset) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) - _, _, _, sequencer, engine, verifier, _, _ := setupReorgTestActors(t, dp, sd, log) + _, _, _, sequencer, engine, verifier, _, _ := helpers.SetupReorgTestActors(t, dp, sd, log) // start op-nodes sequencer.ActL2PipelineFull(t) verifier.ActL2PipelineFull(t) // Genesis block has ecotone properties - verifyEcotoneBlock(gt, engine.l2Chain.CurrentBlock()) + verifyEcotoneBlock(gt, engine.L2Chain().CurrentBlock()) // Blocks post fork have Ecotone properties sequencer.ActL2StartBlock(t) sequencer.ActL2EndBlock(t) - verifyEcotoneBlock(gt, engine.l2Chain.CurrentBlock()) + verifyEcotoneBlock(gt, engine.L2Chain().CurrentBlock()) } -func aliceSimpleBlobTx(t Testing, dp *e2eutils.DeployParams) *types.Transaction { +func aliceSimpleBlobTx(t helpers.Testing, dp *e2eutils.DeployParams) *types.Transaction { txData := transactions.CreateEmptyBlobTx(true, dp.DeployConfig.L2ChainID) // Manual signer creation, so we can sign a blob tx on the chain, // even though we have disabled cancun signer support in Ecotone. @@ -186,17 +187,17 @@ func aliceSimpleBlobTx(t Testing, dp *e2eutils.DeployParams) *types.Transaction return tx } -func newEngine(t Testing, sd *e2eutils.SetupData, log log.Logger) *L2Engine { +func newEngine(t helpers.Testing, sd *e2eutils.SetupData, log log.Logger) *helpers.L2Engine { jwtPath := e2eutils.WriteDefaultJWT(t) - return NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath) + return helpers.NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath) } // TestDencunBlobTxRPC tries to send a Blob tx to the L2 engine via RPC, it should not be accepted. func TestDencunBlobTxRPC(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + t := helpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) engine := newEngine(t, sd, log) cl := engine.EthClient() @@ -207,31 +208,31 @@ func TestDencunBlobTxRPC(gt *testing.T) { // TestDencunBlobTxInTxPool tries to insert a blob tx directly into the tx pool, it should not be accepted. func TestDencunBlobTxInTxPool(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + t := helpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) engine := newEngine(t, sd, log) tx := aliceSimpleBlobTx(t, dp) - errs := engine.eth.TxPool().Add([]*types.Transaction{tx}, true, true) + errs := engine.Eth.TxPool().Add([]*types.Transaction{tx}, true, true) require.ErrorContains(t, errs[0], "transaction type not supported") } // TestDencunBlobTxInclusion tries to send a Blob tx to the L2 engine, it should not be accepted. func TestDencunBlobTxInclusion(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + t := helpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) - _, engine, sequencer := setupSequencerTest(t, sd, log) + _, engine, sequencer := helpers.SetupSequencerTest(t, sd, log) sequencer.ActL2PipelineFull(t) tx := aliceSimpleBlobTx(t, dp) sequencer.ActL2StartBlock(t) - err := engine.engineApi.IncludeTx(tx, dp.Addresses.Alice) + err := engine.EngineApi.IncludeTx(tx, dp.Addresses.Alice) require.ErrorContains(t, err, "invalid L2 block (tx 1): failed to apply transaction to L2 block (tx 1): transaction type not supported") } diff --git a/op-e2e/actions/ecotone_fork_test.go b/op-e2e/actions/upgrades/ecotone_fork_test.go similarity index 93% rename from op-e2e/actions/ecotone_fork_test.go rename to op-e2e/actions/upgrades/ecotone_fork_test.go index 3237915d6e00..c4135266e162 100644 --- a/op-e2e/actions/ecotone_fork_test.go +++ b/op-e2e/actions/upgrades/ecotone_fork_test.go @@ -1,10 +1,11 @@ -package actions +package upgrades import ( "context" "math/big" "testing" + "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/stretchr/testify/require" "github.com/ethereum/go-ethereum/common" @@ -30,7 +31,7 @@ var ( // verifyCodeHashMatches checks that the has of the code at the given address matches the expected code-hash. // It also sanity-checks that the code is not empty: we should never deploy empty contract codes. // Returns the contract code -func verifyCodeHashMatches(t Testing, client *ethclient.Client, address common.Address, expectedCodeHash common.Hash) []byte { +func verifyCodeHashMatches(t helpers.Testing, client *ethclient.Client, address common.Address, expectedCodeHash common.Hash) []byte { code, err := client.CodeAt(context.Background(), address, nil) require.NoError(t, err) require.NotEmpty(t, code) @@ -40,8 +41,8 @@ func verifyCodeHashMatches(t Testing, client *ethclient.Client, address common.A } func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + t := helpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams) ecotoneOffset := hexutil.Uint64(4) log := testlog.Logger(t, log.LevelDebug) @@ -54,8 +55,8 @@ func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) { // New forks have to be added here... require.NoError(t, dp.DeployConfig.Check(log), "must have valid config") - sd := e2eutils.Setup(t, dp, DefaultAlloc) - _, _, miner, sequencer, engine, verifier, _, _ := setupReorgTestActors(t, dp, sd, log) + sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc) + _, _, miner, sequencer, engine, verifier, _, _ := helpers.SetupReorgTestActors(t, dp, sd, log) ethCl := engine.EthClient() // build a single block to move away from the genesis with 0-values in L1Block contract @@ -238,8 +239,8 @@ func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) { // TestEcotoneBeforeL1 tests that the L2 Ecotone fork can activate before L1 Dencun does func TestEcotoneBeforeL1(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + t := helpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams) offset := hexutil.Uint64(0) farOffset := hexutil.Uint64(10000) dp.DeployConfig.L2GenesisRegolithTimeOffset = &offset @@ -248,19 +249,19 @@ func TestEcotoneBeforeL1(gt *testing.T) { dp.DeployConfig.L2GenesisDeltaTimeOffset = &offset dp.DeployConfig.L2GenesisEcotoneTimeOffset = &offset - sd := e2eutils.Setup(t, dp, DefaultAlloc) + sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc) log := testlog.Logger(t, log.LevelDebug) - _, _, _, sequencer, engine, verifier, _, _ := setupReorgTestActors(t, dp, sd, log) + _, _, _, sequencer, engine, verifier, _, _ := helpers.SetupReorgTestActors(t, dp, sd, log) // start op-nodes sequencer.ActL2PipelineFull(t) verifier.ActL2PipelineFull(t) // Genesis block has ecotone properties - verifyEcotoneBlock(gt, engine.l2Chain.CurrentBlock()) + verifyEcotoneBlock(gt, engine.L2Chain().CurrentBlock()) // Blocks post fork have Ecotone properties sequencer.ActL2StartBlock(t) sequencer.ActL2EndBlock(t) - verifyEcotoneBlock(gt, engine.l2Chain.CurrentBlock()) + verifyEcotoneBlock(gt, engine.L2Chain().CurrentBlock()) } diff --git a/op-e2e/actions/fjord_fork_test.go b/op-e2e/actions/upgrades/fjord_fork_test.go similarity index 94% rename from op-e2e/actions/fjord_fork_test.go rename to op-e2e/actions/upgrades/fjord_fork_test.go index d003c69af394..9444fcfcb7ae 100644 --- a/op-e2e/actions/fjord_fork_test.go +++ b/op-e2e/actions/upgrades/fjord_fork_test.go @@ -1,4 +1,4 @@ -package actions +package upgrades import ( "context" @@ -6,6 +6,7 @@ import ( "math/big" "testing" + "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/ethereum-optimism/optimism/op-service/predeploys" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" @@ -29,8 +30,8 @@ var ( ) func TestFjordNetworkUpgradeTransactions(gt *testing.T) { - t := NewDefaultTesting(gt) - dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams) + t := helpers.NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams) genesisBlock := hexutil.Uint64(0) fjordOffset := hexutil.Uint64(2) @@ -46,8 +47,8 @@ func TestFjordNetworkUpgradeTransactions(gt *testing.T) { dp.DeployConfig.L2GenesisFjordTimeOffset = &fjordOffset require.NoError(t, dp.DeployConfig.Check(log), "must have valid config") - sd := e2eutils.Setup(t, dp, DefaultAlloc) - _, _, _, sequencer, engine, verifier, _, _ := setupReorgTestActors(t, dp, sd, log) + sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc) + _, _, _, sequencer, engine, verifier, _, _ := helpers.SetupReorgTestActors(t, dp, sd, log) ethCl := engine.EthClient() // start op-nodes diff --git a/op-e2e/actions/upgrades/helpers/config.go b/op-e2e/actions/upgrades/helpers/config.go new file mode 100644 index 000000000000..a936d86250a0 --- /dev/null +++ b/op-e2e/actions/upgrades/helpers/config.go @@ -0,0 +1,27 @@ +package helpers + +import ( + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum/go-ethereum/common/hexutil" +) + +// ApplyDeltaTimeOffset adjusts fork configuration to not conflict with the delta overrides +func ApplyDeltaTimeOffset(dp *e2eutils.DeployParams, deltaTimeOffset *hexutil.Uint64) { + dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset + // configure Ecotone to not be before Delta accidentally + if dp.DeployConfig.L2GenesisEcotoneTimeOffset != nil { + if deltaTimeOffset == nil { + dp.DeployConfig.L2GenesisEcotoneTimeOffset = nil + } else if *dp.DeployConfig.L2GenesisEcotoneTimeOffset < *deltaTimeOffset { + dp.DeployConfig.L2GenesisEcotoneTimeOffset = deltaTimeOffset + } + } + // configure Fjord to not be before Delta accidentally + if dp.DeployConfig.L2GenesisFjordTimeOffset != nil { + if deltaTimeOffset == nil { + dp.DeployConfig.L2GenesisFjordTimeOffset = nil + } else if *dp.DeployConfig.L2GenesisFjordTimeOffset < *deltaTimeOffset { + dp.DeployConfig.L2GenesisFjordTimeOffset = deltaTimeOffset + } + } +} diff --git a/op-e2e/actions/span_batch_test.go b/op-e2e/actions/upgrades/span_batch_test.go similarity index 82% rename from op-e2e/actions/span_batch_test.go rename to op-e2e/actions/upgrades/span_batch_test.go index 7eb551c521c7..fc1707b158a0 100644 --- a/op-e2e/actions/span_batch_test.go +++ b/op-e2e/actions/upgrades/span_batch_test.go @@ -1,4 +1,4 @@ -package actions +package upgrades import ( "context" @@ -10,6 +10,8 @@ import ( "math/rand" "testing" + actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" + upgradesHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/upgrades/helpers" "github.com/stretchr/testify/require" "github.com/ethereum/go-ethereum" @@ -31,7 +33,7 @@ import ( // TestDropSpanBatchBeforeHardfork tests behavior of op-node before Delta hardfork. // op-node must drop SpanBatch before Delta hardfork. func TestDropSpanBatchBeforeHardfork(gt *testing.T) { - t := NewDefaultTesting(gt) + t := actionsHelpers.NewDefaultTesting(gt) p := &e2eutils.TestParams{ MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) SequencerWindowSize: 24, @@ -40,15 +42,15 @@ func TestDropSpanBatchBeforeHardfork(gt *testing.T) { } dp := e2eutils.MakeDeployParams(t, p) // do not activate Delta hardfork for verifier - applyDeltaTimeOffset(dp, nil) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + upgradesHelpers.ApplyDeltaTimeOffset(dp, nil) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelError) - miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) - verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + miner, seqEngine, sequencer := actionsHelpers.SetupSequencerTest(t, sd, log) + verifEngine, verifier := actionsHelpers.SetupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) rollupSeqCl := sequencer.RollupClient() // Force batcher to submit SpanBatches to L1. - batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ + batcher := actionsHelpers.NewL2Batcher(log, sd.RollupCfg, &actionsHelpers.BatcherCfg{ MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Batcher, @@ -65,7 +67,7 @@ func TestDropSpanBatchBeforeHardfork(gt *testing.T) { ChainID: sd.L2Cfg.Config.ChainID, Nonce: n, GasTipCap: big.NewInt(2 * params.GWei), - GasFeeCap: new(big.Int).Add(miner.l1Chain.CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), + GasFeeCap: new(big.Int).Add(miner.L1Chain().CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), Gas: params.TxGas, To: &dp.Addresses.Bob, Value: e2eutils.Ether(2), @@ -89,8 +91,8 @@ func TestDropSpanBatchBeforeHardfork(gt *testing.T) { miner.ActL1StartBlock(12)(t) miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) miner.ActL1EndBlock(t) - bl := miner.l1Chain.CurrentBlock() - log.Info("bl", "txs", len(miner.l1Chain.GetBlockByHash(bl.Hash()).Transactions())) + bl := miner.L1Chain().CurrentBlock() + log.Info("bl", "txs", len(miner.L1Chain().GetBlockByHash(bl.Hash()).Transactions())) // Now make enough L1 blocks that the verifier will have to derive a L2 block // It will also eagerly derive the block from the batcher @@ -120,7 +122,7 @@ func TestDropSpanBatchBeforeHardfork(gt *testing.T) { // TestHardforkMiddleOfSpanBatch tests behavior of op-node Delta hardfork. // If Delta activation time is in the middle of time range of a SpanBatch, op-node must drop the batch. func TestHardforkMiddleOfSpanBatch(gt *testing.T) { - t := NewDefaultTesting(gt) + t := actionsHelpers.NewDefaultTesting(gt) p := &e2eutils.TestParams{ MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) SequencerWindowSize: 24, @@ -131,21 +133,21 @@ func TestHardforkMiddleOfSpanBatch(gt *testing.T) { // Activate HF in the middle of the first epoch deltaOffset := hexutil.Uint64(6) - applyDeltaTimeOffset(dp, &deltaOffset) + upgradesHelpers.ApplyDeltaTimeOffset(dp, &deltaOffset) // Applies to HF that goes into Delta. Otherwise we end up with more upgrade txs and things during this case. dp.DeployConfig.L2GenesisEcotoneTimeOffset = nil dp.DeployConfig.L2GenesisFjordTimeOffset = nil dp.DeployConfig.L2GenesisGraniteTimeOffset = nil - sd := e2eutils.Setup(t, dp, DefaultAlloc) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelError) - miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) - verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + miner, seqEngine, sequencer := actionsHelpers.SetupSequencerTest(t, sd, log) + verifEngine, verifier := actionsHelpers.SetupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) minerCl := miner.EthClient() rollupSeqCl := sequencer.RollupClient() // Force batcher to submit SpanBatches to L1. - batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ + batcher := actionsHelpers.NewL2Batcher(log, sd.RollupCfg, &actionsHelpers.BatcherCfg{ MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Batcher, @@ -162,7 +164,7 @@ func TestHardforkMiddleOfSpanBatch(gt *testing.T) { ChainID: sd.L2Cfg.Config.ChainID, Nonce: n, GasTipCap: big.NewInt(2 * params.GWei), - GasFeeCap: new(big.Int).Add(miner.l1Chain.CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), + GasFeeCap: new(big.Int).Add(miner.L1Chain().CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), Gas: params.TxGas, To: &dp.Addresses.Bob, Value: e2eutils.Ether(2), @@ -202,8 +204,8 @@ func TestHardforkMiddleOfSpanBatch(gt *testing.T) { miner.ActL1StartBlock(12)(t) miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) miner.ActL1EndBlock(t) - bl := miner.l1Chain.CurrentBlock() - log.Info("bl", "txs", len(miner.l1Chain.GetBlockByHash(bl.Hash()).Transactions())) + bl := miner.L1Chain().CurrentBlock() + log.Info("bl", "txs", len(miner.L1Chain().GetBlockByHash(bl.Hash()).Transactions())) // Now make enough L1 blocks that the verifier will have to derive a L2 block // It will also eagerly derive the block from the batcher @@ -233,7 +235,7 @@ func TestHardforkMiddleOfSpanBatch(gt *testing.T) { // TestAcceptSingularBatchAfterHardfork tests behavior of op-node after Delta hardfork. // op-node must accept SingularBatch after Delta hardfork. func TestAcceptSingularBatchAfterHardfork(gt *testing.T) { - t := NewDefaultTesting(gt) + t := actionsHelpers.NewDefaultTesting(gt) p := &e2eutils.TestParams{ MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) SequencerWindowSize: 24, @@ -244,15 +246,15 @@ func TestAcceptSingularBatchAfterHardfork(gt *testing.T) { dp := e2eutils.MakeDeployParams(t, p) // activate Delta hardfork for verifier. - applyDeltaTimeOffset(dp, &minTs) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + upgradesHelpers.ApplyDeltaTimeOffset(dp, &minTs) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelError) - miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) - verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + miner, seqEngine, sequencer := actionsHelpers.SetupSequencerTest(t, sd, log) + verifEngine, verifier := actionsHelpers.SetupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) rollupSeqCl := sequencer.RollupClient() // Force batcher to submit SingularBatches to L1. - batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ + batcher := actionsHelpers.NewL2Batcher(log, sd.RollupCfg, &actionsHelpers.BatcherCfg{ MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Batcher, @@ -269,7 +271,7 @@ func TestAcceptSingularBatchAfterHardfork(gt *testing.T) { ChainID: sd.L2Cfg.Config.ChainID, Nonce: n, GasTipCap: big.NewInt(2 * params.GWei), - GasFeeCap: new(big.Int).Add(miner.l1Chain.CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), + GasFeeCap: new(big.Int).Add(miner.L1Chain().CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), Gas: params.TxGas, To: &dp.Addresses.Bob, Value: e2eutils.Ether(2), @@ -293,8 +295,8 @@ func TestAcceptSingularBatchAfterHardfork(gt *testing.T) { miner.ActL1StartBlock(12)(t) miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) miner.ActL1EndBlock(t) - bl := miner.l1Chain.CurrentBlock() - log.Info("bl", "txs", len(miner.l1Chain.GetBlockByHash(bl.Hash()).Transactions())) + bl := miner.L1Chain().CurrentBlock() + log.Info("bl", "txs", len(miner.L1Chain().GetBlockByHash(bl.Hash()).Transactions())) // Now make enough L1 blocks that the verifier will have to derive a L2 block // It will also eagerly derive the block from the batcher @@ -319,7 +321,7 @@ func TestAcceptSingularBatchAfterHardfork(gt *testing.T) { // TestMixOfBatchesAfterHardfork tests behavior of op-node after Delta hardfork. // op-node must accept SingularBatch and SpanBatch in sequence. func TestMixOfBatchesAfterHardfork(gt *testing.T) { - t := NewDefaultTesting(gt) + t := actionsHelpers.NewDefaultTesting(gt) p := &e2eutils.TestParams{ MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) SequencerWindowSize: 24, @@ -330,11 +332,11 @@ func TestMixOfBatchesAfterHardfork(gt *testing.T) { dp := e2eutils.MakeDeployParams(t, p) // Activate Delta hardfork for verifier. - applyDeltaTimeOffset(dp, &minTs) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + upgradesHelpers.ApplyDeltaTimeOffset(dp, &minTs) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelError) - miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) - verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + miner, seqEngine, sequencer := actionsHelpers.SetupSequencerTest(t, sd, log) + verifEngine, verifier := actionsHelpers.SetupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) rollupSeqCl := sequencer.RollupClient() seqEngCl := seqEngine.EthClient() @@ -352,7 +354,7 @@ func TestMixOfBatchesAfterHardfork(gt *testing.T) { ChainID: sd.L2Cfg.Config.ChainID, Nonce: n, GasTipCap: big.NewInt(2 * params.GWei), - GasFeeCap: new(big.Int).Add(miner.l1Chain.CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), + GasFeeCap: new(big.Int).Add(miner.L1Chain().CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), Gas: params.TxGas, To: &dp.Addresses.Bob, Value: e2eutils.Ether(2), @@ -368,7 +370,7 @@ func TestMixOfBatchesAfterHardfork(gt *testing.T) { sequencer.ActBuildToL1Head(t) // Select batcher mode - batcherCfg := BatcherCfg{ + batcherCfg := actionsHelpers.BatcherCfg{ MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Batcher, @@ -376,7 +378,7 @@ func TestMixOfBatchesAfterHardfork(gt *testing.T) { ForceSubmitSingularBatch: i%2 == 1, // Submit SingularBatch for even numbered batches DataAvailabilityType: batcherFlags.CalldataType, } - batcher := NewL2Batcher(log, sd.RollupCfg, &batcherCfg, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) + batcher := actionsHelpers.NewL2Batcher(log, sd.RollupCfg, &batcherCfg, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) // Submit all new blocks batcher.ActSubmitAll(t) @@ -410,7 +412,7 @@ func TestMixOfBatchesAfterHardfork(gt *testing.T) { // TestSpanBatchEmptyChain tests derivation of empty chain using SpanBatch. func TestSpanBatchEmptyChain(gt *testing.T) { - t := NewDefaultTesting(gt) + t := actionsHelpers.NewDefaultTesting(gt) p := &e2eutils.TestParams{ MaxSequencerDrift: 20, SequencerWindowSize: 24, @@ -420,14 +422,14 @@ func TestSpanBatchEmptyChain(gt *testing.T) { dp := e2eutils.MakeDeployParams(t, p) minTs := hexutil.Uint64(0) // Activate Delta hardfork - applyDeltaTimeOffset(dp, &minTs) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + upgradesHelpers.ApplyDeltaTimeOffset(dp, &minTs) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelError) - miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) - _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + miner, seqEngine, sequencer := actionsHelpers.SetupSequencerTest(t, sd, log) + _, verifier := actionsHelpers.SetupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) rollupSeqCl := sequencer.RollupClient() - batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + batcher := actionsHelpers.NewL2Batcher(log, sd.RollupCfg, actionsHelpers.DefaultBatcherCfg(dp), rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) sequencer.ActL2PipelineFull(t) @@ -473,7 +475,7 @@ func TestSpanBatchEmptyChain(gt *testing.T) { // TestSpanBatchLowThroughputChain tests derivation of low-throughput chain using SpanBatch. func TestSpanBatchLowThroughputChain(gt *testing.T) { - t := NewDefaultTesting(gt) + t := actionsHelpers.NewDefaultTesting(gt) p := &e2eutils.TestParams{ MaxSequencerDrift: 20, SequencerWindowSize: 24, @@ -483,14 +485,14 @@ func TestSpanBatchLowThroughputChain(gt *testing.T) { dp := e2eutils.MakeDeployParams(t, p) minTs := hexutil.Uint64(0) // Activate Delta hardfork - applyDeltaTimeOffset(dp, &minTs) - sd := e2eutils.Setup(t, dp, DefaultAlloc) + upgradesHelpers.ApplyDeltaTimeOffset(dp, &minTs) + sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) log := testlog.Logger(t, log.LevelError) - miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) - _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + miner, seqEngine, sequencer := actionsHelpers.SetupSequencerTest(t, sd, log) + _, verifier := actionsHelpers.SetupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) rollupSeqCl := sequencer.RollupClient() - batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + batcher := actionsHelpers.NewL2Batcher(log, sd.RollupCfg, actionsHelpers.DefaultBatcherCfg(dp), rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) cl := seqEngine.EthClient() @@ -521,7 +523,7 @@ func TestSpanBatchLowThroughputChain(gt *testing.T) { totalTxCount := 0 // Make 600 L2 blocks (L1BlockTime / L2BlockTime * 50) including 1~3 txs for i := 0; i < 50; i++ { - for sequencer.engine.UnsafeL2Head().L1Origin.Number < sequencer.syncStatus.L1Head().Number { + for sequencer.L2Unsafe().L1Origin.Number < sequencer.SyncStatus().HeadL1.Number { sequencer.ActL2StartBlock(t) // fill the block with random number of L2 txs for j := 0; j < rand.Intn(3); j++ { @@ -532,7 +534,7 @@ func TestSpanBatchLowThroughputChain(gt *testing.T) { require.NoError(t, err) gas, err := core.IntrinsicGas(data, nil, false, true, true, false) require.NoError(t, err) - baseFee := seqEngine.l2Chain.CurrentBlock().BaseFee + baseFee := seqEngine.L2Chain().CurrentBlock().BaseFee nonce, err := cl.PendingNonceAt(t.Ctx(), addrs[userIdx]) require.NoError(t, err) tx := types.MustSignNewTx(privKeys[userIdx], signer, &types.DynamicFeeTx{ @@ -585,7 +587,7 @@ func TestSpanBatchLowThroughputChain(gt *testing.T) { } func TestBatchEquivalence(gt *testing.T) { - t := NewDefaultTesting(gt) + t := actionsHelpers.NewDefaultTesting(gt) log := testlog.Logger(t, log.LevelError) p := &e2eutils.TestParams{ @@ -597,8 +599,8 @@ func TestBatchEquivalence(gt *testing.T) { // Delta activated deploy config dp := e2eutils.MakeDeployParams(t, p) minTs := hexutil.Uint64(0) - applyDeltaTimeOffset(dp, &minTs) - sdDeltaActivated := e2eutils.Setup(t, dp, DefaultAlloc) + upgradesHelpers.ApplyDeltaTimeOffset(dp, &minTs) + sdDeltaActivated := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc) // Delta deactivated deploy config rcfg := *sdDeltaActivated.RollupCfg @@ -611,18 +613,18 @@ func TestBatchEquivalence(gt *testing.T) { } // Setup sequencer - miner, seqEngine, sequencer := setupSequencerTest(t, sdDeltaActivated, log) + miner, seqEngine, sequencer := actionsHelpers.SetupSequencerTest(t, sdDeltaActivated, log) rollupSeqCl := sequencer.RollupClient() seqEngCl := seqEngine.EthClient() // Setup Delta activated spanVerifier - _, spanVerifier := setupVerifier(t, sdDeltaActivated, log, miner.L1Client(t, sdDeltaActivated.RollupCfg), miner.BlobStore(), &sync.Config{}) + _, spanVerifier := actionsHelpers.SetupVerifier(t, sdDeltaActivated, log, miner.L1Client(t, sdDeltaActivated.RollupCfg), miner.BlobStore(), &sync.Config{}) // Setup Delta deactivated spanVerifier - _, singularVerifier := setupVerifier(t, sdDeltaDeactivated, log, miner.L1Client(t, sdDeltaDeactivated.RollupCfg), miner.BlobStore(), &sync.Config{}) + _, singularVerifier := actionsHelpers.SetupVerifier(t, sdDeltaDeactivated, log, miner.L1Client(t, sdDeltaDeactivated.RollupCfg), miner.BlobStore(), &sync.Config{}) // Setup SpanBatcher - spanBatcher := NewL2Batcher(log, sdDeltaActivated.RollupCfg, &BatcherCfg{ + spanBatcher := actionsHelpers.NewL2Batcher(log, sdDeltaActivated.RollupCfg, &actionsHelpers.BatcherCfg{ MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Batcher, @@ -631,7 +633,7 @@ func TestBatchEquivalence(gt *testing.T) { }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sdDeltaActivated.RollupCfg)) // Setup SingularBatcher - singularBatcher := NewL2Batcher(log, sdDeltaDeactivated.RollupCfg, &BatcherCfg{ + singularBatcher := actionsHelpers.NewL2Batcher(log, sdDeltaDeactivated.RollupCfg, &actionsHelpers.BatcherCfg{ MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Batcher, @@ -660,7 +662,7 @@ func TestBatchEquivalence(gt *testing.T) { sequencer.ActL2PipelineFull(t) totalTxCount := 0 // Build random blocks - for sequencer.engine.UnsafeL2Head().L1Origin.Number < sequencer.syncStatus.L1Head().Number { + for sequencer.L2Unsafe().L1Origin.Number < sequencer.SyncStatus().HeadL1.Number { sequencer.ActL2StartBlock(t) // fill the block with random number of L2 txs for j := 0; j < rand.Intn(3); j++ { @@ -671,7 +673,7 @@ func TestBatchEquivalence(gt *testing.T) { require.NoError(t, err) gas, err := core.IntrinsicGas(data, nil, false, true, true, false) require.NoError(t, err) - baseFee := seqEngine.l2Chain.CurrentBlock().BaseFee + baseFee := seqEngine.L2Chain().CurrentBlock().BaseFee nonce, err := seqEngCl.PendingNonceAt(t.Ctx(), addrs[userIdx]) require.NoError(t, err) tx := types.MustSignNewTx(privKeys[userIdx], signer, &types.DynamicFeeTx{ From 4e2fdf377a594eec61e7f2272e47b9865ac4c2cb Mon Sep 17 00:00:00 2001 From: clabby Date: Tue, 17 Sep 2024 00:51:52 -0400 Subject: [PATCH 159/264] feat(op-e2e): Kona FPP actions test adapter (#11936) * feat(op-e2e): Kona FPP actions test adapter * rebase * lint * review * fix result check --- op-challenger/game/fault/register.go | 2 +- .../fault/trace/vm/kona_server_executor.go | 41 +++++++--- .../trace/vm/kona_server_executor_test.go | 2 +- op-challenger/runner/factory.go | 2 +- op-e2e/actions/helpers/l1_miner.go | 6 +- op-e2e/actions/helpers/l1_replica.go | 2 + op-e2e/actions/helpers/l2_engine.go | 2 + op-e2e/actions/proofs/helpers/env.go | 61 +++++++++------ op-e2e/actions/proofs/helpers/fixture.go | 21 +++-- op-e2e/actions/proofs/helpers/kona.go | 78 +++++++++++++++++++ .../proofs/sequence_window_expiry_test.go | 3 +- 11 files changed, 170 insertions(+), 50 deletions(-) create mode 100644 op-e2e/actions/proofs/helpers/kona.go diff --git a/op-challenger/game/fault/register.go b/op-challenger/game/fault/register.go index 088bd0b0aede..08140164a17c 100644 --- a/op-challenger/game/fault/register.go +++ b/op-challenger/game/fault/register.go @@ -77,7 +77,7 @@ func RegisterGameTypes( registerTasks = append(registerTasks, NewAsteriscRegisterTask(faultTypes.AsteriscGameType, cfg, m, vm.NewOpProgramServerExecutor())) } if cfg.TraceTypeEnabled(faultTypes.TraceTypeAsteriscKona) { - registerTasks = append(registerTasks, NewAsteriscKonaRegisterTask(faultTypes.AsteriscKonaGameType, cfg, m, vm.NewKonaServerExecutor())) + registerTasks = append(registerTasks, NewAsteriscKonaRegisterTask(faultTypes.AsteriscKonaGameType, cfg, m, vm.NewKonaExecutor())) } if cfg.TraceTypeEnabled(faultTypes.TraceTypeFast) { registerTasks = append(registerTasks, NewAlphabetRegisterTask(faultTypes.FastGameType)) diff --git a/op-challenger/game/fault/trace/vm/kona_server_executor.go b/op-challenger/game/fault/trace/vm/kona_server_executor.go index 5dc3a03a6365..dfb358b41448 100644 --- a/op-challenger/game/fault/trace/vm/kona_server_executor.go +++ b/op-challenger/game/fault/trace/vm/kona_server_executor.go @@ -8,35 +8,52 @@ import ( "github.com/ethereum-optimism/optimism/op-node/chaincfg" ) -type KonaServerExecutor struct{} +type KonaExecutor struct { + nativeMode bool + clientBinPath string +} -var _ OracleServerExecutor = (*KonaServerExecutor)(nil) +var _ OracleServerExecutor = (*KonaExecutor)(nil) -func NewKonaServerExecutor() *KonaServerExecutor { - return &KonaServerExecutor{} +func NewKonaExecutor() *KonaExecutor { + return &KonaExecutor{nativeMode: false} } -func (s *KonaServerExecutor) OracleCommand(cfg Config, dataDir string, inputs utils.LocalGameInputs) ([]string, error) { - if cfg.Network == "" { - return nil, errors.New("network is not defined") - } +func NewNativeKonaExecutor(clientBinPath string) *KonaExecutor { + return &KonaExecutor{nativeMode: true, clientBinPath: clientBinPath} +} - chainCfg := chaincfg.ChainByName(cfg.Network) +func (s *KonaExecutor) OracleCommand(cfg Config, dataDir string, inputs utils.LocalGameInputs) ([]string, error) { args := []string{ - cfg.Server, "--server", + cfg.Server, "--l1-node-address", cfg.L1, "--l1-beacon-address", cfg.L1Beacon, "--l2-node-address", cfg.L2, - "--data-dir", dataDir, - "--l2-chain-id", strconv.FormatUint(chainCfg.ChainID, 10), "--l1-head", inputs.L1Head.Hex(), "--l2-head", inputs.L2Head.Hex(), "--l2-output-root", inputs.L2OutputRoot.Hex(), "--l2-claim", inputs.L2Claim.Hex(), "--l2-block-number", inputs.L2BlockNumber.Text(10), + "-v", } + + if s.nativeMode { + args = append(args, "--exec", s.clientBinPath) + } else { + args = append(args, "--server") + args = append(args, "--data-dir", dataDir) + } + if cfg.RollupConfigPath != "" { args = append(args, "--rollup-config-path", cfg.RollupConfigPath) + args = append(args, "--l2-chain-id", "0") + } else { + if cfg.Network == "" { + return nil, errors.New("network is not defined") + } + + chainCfg := chaincfg.ChainByName(cfg.Network) + args = append(args, "--l2-chain-id", strconv.FormatUint(chainCfg.ChainID, 10)) } return args, nil diff --git a/op-challenger/game/fault/trace/vm/kona_server_executor_test.go b/op-challenger/game/fault/trace/vm/kona_server_executor_test.go index 45fb5faa9040..ba690b5c0881 100644 --- a/op-challenger/game/fault/trace/vm/kona_server_executor_test.go +++ b/op-challenger/game/fault/trace/vm/kona_server_executor_test.go @@ -26,7 +26,7 @@ func TestKonaFillHostCommand(t *testing.T) { L2Claim: common.Hash{0x44}, L2BlockNumber: big.NewInt(3333), } - vmConfig := NewKonaServerExecutor() + vmConfig := NewKonaExecutor() args, err := vmConfig.OracleCommand(cfg, dir, inputs) require.NoError(t, err) diff --git a/op-challenger/runner/factory.go b/op-challenger/runner/factory.go index 90e7e885b5aa..203027e4ec3d 100644 --- a/op-challenger/runner/factory.go +++ b/op-challenger/runner/factory.go @@ -46,7 +46,7 @@ func createTraceProvider( prestateProvider := vm.NewPrestateProvider(prestate, stateConverter) return asterisc.NewTraceProvider(logger, m, cfg.Asterisc, vmConfig, prestateProvider, prestate, localInputs, dir, 42), nil case types.TraceTypeAsteriscKona: - vmConfig := vm.NewKonaServerExecutor() + vmConfig := vm.NewKonaExecutor() stateConverter := asterisc.NewStateConverter() prestate, err := getPrestate(prestateHash, cfg.AsteriscKonaAbsolutePreStateBaseURL, cfg.AsteriscKonaAbsolutePreState, dir, stateConverter) if err != nil { diff --git a/op-e2e/actions/helpers/l1_miner.go b/op-e2e/actions/helpers/l1_miner.go index c310f234abc8..5fe5c762d5c9 100644 --- a/op-e2e/actions/helpers/l1_miner.go +++ b/op-e2e/actions/helpers/l1_miner.go @@ -52,7 +52,11 @@ func NewL1Miner(t Testing, log log.Logger, genesis *core.Genesis) *L1Miner { } } -func (s *L1Miner) BlobStore() prefetcher.L1BlobSource { +func (s *L1Miner) BlobSource() prefetcher.L1BlobSource { + return s.blobStore +} + +func (s *L1Miner) BlobStore() *e2eutils.BlobsStore { return s.blobStore } diff --git a/op-e2e/actions/helpers/l1_replica.go b/op-e2e/actions/helpers/l1_replica.go index 7d5b50d39ccc..7b089a4f7fa9 100644 --- a/op-e2e/actions/helpers/l1_replica.go +++ b/op-e2e/actions/helpers/l1_replica.go @@ -67,6 +67,8 @@ func NewL1Replica(t Testing, log log.Logger, genesis *core.Genesis) *L1Replica { Name: "l1-geth", WSHost: "127.0.0.1", WSPort: 0, + HTTPHost: "127.0.0.1", + HTTPPort: 0, WSModules: []string{"debug", "admin", "eth", "txpool", "net", "rpc", "web3", "personal"}, HTTPModules: []string{"debug", "admin", "eth", "txpool", "net", "rpc", "web3", "personal"}, DataDir: "", // in-memory diff --git a/op-e2e/actions/helpers/l2_engine.go b/op-e2e/actions/helpers/l2_engine.go index 4bd8fe118d61..5839a20798d3 100644 --- a/op-e2e/actions/helpers/l2_engine.go +++ b/op-e2e/actions/helpers/l2_engine.go @@ -93,6 +93,8 @@ func newBackend(t e2eutils.TestingBase, genesis *core.Genesis, jwtPath string, o Name: "l2-geth", WSHost: "127.0.0.1", WSPort: 0, + HTTPHost: "127.0.0.1", + HTTPPort: 0, AuthAddr: "127.0.0.1", AuthPort: 0, WSModules: []string{"debug", "admin", "eth", "txpool", "net", "rpc", "web3", "personal"}, diff --git a/op-e2e/actions/proofs/helpers/env.go b/op-e2e/actions/proofs/helpers/env.go index 1ec23eb472f6..d911acff9306 100644 --- a/op-e2e/actions/proofs/helpers/env.go +++ b/op-e2e/actions/proofs/helpers/env.go @@ -8,6 +8,7 @@ import ( batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/fakebeacon" "github.com/ethereum-optimism/optimism/op-program/host" "github.com/ethereum-optimism/optimism/op-program/host/config" "github.com/ethereum-optimism/optimism/op-program/host/kvstore" @@ -155,28 +156,44 @@ func (env *L2FaultProofEnv) RunFaultProofProgram(t helpers.Testing, l2ClaimBlock apply(fixtureInputs) } - // Run the fault proof program from the state transition from L2 block 0 -> 1. - programCfg := NewOpProgramCfg( - t, - env, - fixtureInputs, - ) - withInProcessPrefetcher := host.WithPrefetcher(func(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *config.Config) (host.Prefetcher, error) { - // Set up in-process L1 sources - l1Cl := env.Miner.L1Client(t, env.sd.RollupCfg) - l1BlobFetcher := env.Miner.BlobStore() - - // Set up in-process L2 source - l2ClCfg := sources.L2ClientDefaultConfig(env.sd.RollupCfg, true) - l2RPC := env.Engine.RPCClient() - l2Client, err := host.NewL2Client(l2RPC, env.log, nil, &host.L2ClientConfig{L2ClientConfig: l2ClCfg, L2Head: cfg.L2Head}) - require.NoError(t, err, "failed to create L2 client") - l2DebugCl := &host.L2Source{L2Client: l2Client, DebugClient: sources.NewDebugClient(l2RPC.CallContext)} - - return prefetcher.NewPrefetcher(logger, l1Cl, l1BlobFetcher, l2DebugCl, kv), nil - }) - err = host.FaultProofProgram(t.Ctx(), env.log, programCfg, withInProcessPrefetcher) - tryDumpTestFixture(t, err, t.Name(), env, programCfg) + // Run the fault proof program from the state transition from L2 block l2ClaimBlockNum - 1 -> l2ClaimBlockNum. + workDir := t.TempDir() + if IsKonaConfigured() { + fakeBeacon := fakebeacon.NewBeacon( + env.log, + env.Miner.BlobStore(), + env.sd.L1Cfg.Timestamp, + 12, + ) + require.NoError(t, fakeBeacon.Start("127.0.0.1:0")) + defer fakeBeacon.Close() + + err = RunKonaNative(t, workDir, env, env.Miner.HTTPEndpoint(), fakeBeacon.BeaconAddr(), env.Engine.HTTPEndpoint(), *fixtureInputs) + checkResult(t, err) + } else { + programCfg := NewOpProgramCfg( + t, + env, + fixtureInputs, + ) + withInProcessPrefetcher := host.WithPrefetcher(func(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *config.Config) (host.Prefetcher, error) { + // Set up in-process L1 sources + l1Cl := env.Miner.L1Client(t, env.sd.RollupCfg) + l1BlobFetcher := env.Miner.BlobSource() + + // Set up in-process L2 source + l2ClCfg := sources.L2ClientDefaultConfig(env.sd.RollupCfg, true) + l2RPC := env.Engine.RPCClient() + l2Client, err := host.NewL2Client(l2RPC, env.log, nil, &host.L2ClientConfig{L2ClientConfig: l2ClCfg, L2Head: cfg.L2Head}) + require.NoError(t, err, "failed to create L2 client") + l2DebugCl := &host.L2Source{L2Client: l2Client, DebugClient: sources.NewDebugClient(l2RPC.CallContext)} + + return prefetcher.NewPrefetcher(logger, l1Cl, l1BlobFetcher, l2DebugCl, kv), nil + }) + err = host.FaultProofProgram(t.Ctx(), env.log, programCfg, withInProcessPrefetcher) + checkResult(t, err) + } + tryDumpTestFixture(t, err, t.Name(), env, *fixtureInputs, workDir) } type TestParam func(p *e2eutils.TestParams) diff --git a/op-e2e/actions/proofs/helpers/fixture.go b/op-e2e/actions/proofs/helpers/fixture.go index 26c97de0a0cf..458ce74920ec 100644 --- a/op-e2e/actions/proofs/helpers/fixture.go +++ b/op-e2e/actions/proofs/helpers/fixture.go @@ -12,7 +12,6 @@ import ( "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/ethereum-optimism/optimism/op-program/client/claim" - "github.com/ethereum-optimism/optimism/op-program/host/config" "github.com/ethereum/go-ethereum/common" "github.com/naoina/toml" "github.com/stretchr/testify/require" @@ -48,7 +47,14 @@ type FixtureInputs struct { // Dumps a `fp-tests` test fixture to disk if the `OP_E2E_DUMP_FIXTURES` environment variable is set. // // [fp-tests]: https://github.com/ethereum-optimism/fp-tests -func tryDumpTestFixture(t helpers.Testing, result error, name string, env *L2FaultProofEnv, programCfg *config.Config) { +func tryDumpTestFixture( + t helpers.Testing, + result error, + name string, + env *L2FaultProofEnv, + inputs FixtureInputs, + workDir string, +) { if !dumpFixtures { return } @@ -69,14 +75,7 @@ func tryDumpTestFixture(t helpers.Testing, result error, name string, env *L2Fau fixture := TestFixture{ Name: name, ExpectedStatus: expectedStatus, - Inputs: FixtureInputs{ - L2BlockNumber: programCfg.L2ClaimBlockNumber, - L2Claim: programCfg.L2Claim, - L2Head: programCfg.L2Head, - L2OutputRoot: programCfg.L2OutputRoot, - L2ChainID: env.sd.RollupCfg.L2ChainID.Uint64(), - L1Head: programCfg.L1Head, - }, + Inputs: inputs, } fixturePath := filepath.Join(fixtureDir, name) @@ -100,7 +99,7 @@ func tryDumpTestFixture(t helpers.Testing, result error, name string, env *L2Fau require.NoError(t, os.WriteFile(rollupPath, serRollup, fs.ModePerm), "failed to write rollup") // Copy the witness database into the fixture directory. - cmd := exec.Command("cp", "-r", programCfg.DataDir, filepath.Join(fixturePath, "witness-db")) + cmd := exec.Command("cp", "-r", workDir, filepath.Join(fixturePath, "witness-db")) require.NoError(t, cmd.Run(), "Failed to copy witness DB") // Compress the genesis file. diff --git a/op-e2e/actions/proofs/helpers/kona.go b/op-e2e/actions/proofs/helpers/kona.go new file mode 100644 index 000000000000..289ff2c95895 --- /dev/null +++ b/op-e2e/actions/proofs/helpers/kona.go @@ -0,0 +1,78 @@ +package helpers + +import ( + "encoding/json" + "fmt" + "io/fs" + "math/big" + "os" + "os/exec" + "path/filepath" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" + "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" + "github.com/ethereum-optimism/optimism/op-program/client/claim" + "github.com/stretchr/testify/require" +) + +var konaHostPath, konaClientPath string + +func init() { + konaHostPath = os.Getenv("KONA_HOST_PATH") + konaClientPath = os.Getenv("KONA_CLIENT_PATH") +} + +func IsKonaConfigured() bool { + return konaHostPath != "" && konaClientPath != "" +} + +func RunKonaNative( + t helpers.Testing, + workDir string, + env *L2FaultProofEnv, + l1Rpc string, + l1BeaconRpc string, + l2Rpc string, + fixtureInputs FixtureInputs, +) error { + // Write rollup config to tempdir. + rollupConfigPath := filepath.Join(workDir, "rollup.json") + ser, err := json.Marshal(env.sd.RollupCfg) + require.NoError(t, err) + require.NoError(t, os.WriteFile(rollupConfigPath, ser, fs.ModePerm)) + + // Run the fault proof program from the state transition from L2 block L2Blocknumber - 1 -> L2BlockNumber. + vmCfg := vm.Config{ + L1: l1Rpc, + L1Beacon: l1BeaconRpc, + L2: l2Rpc, + RollupConfigPath: rollupConfigPath, + Server: konaHostPath, + } + inputs := utils.LocalGameInputs{ + L1Head: fixtureInputs.L1Head, + L2Head: fixtureInputs.L2Head, + L2OutputRoot: fixtureInputs.L2OutputRoot, + L2Claim: fixtureInputs.L2Claim, + L2BlockNumber: big.NewInt(int64(fixtureInputs.L2BlockNumber)), + } + hostCmd, err := vm.NewNativeKonaExecutor(konaClientPath).OracleCommand(vmCfg, workDir, inputs) + require.NoError(t, err) + + cmd := exec.Command(hostCmd[0], hostCmd[1:]...) + cmd.Dir = workDir + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stdout + + status := cmd.Run() + switch status := status.(type) { + case *exec.ExitError: + if status.ExitCode() == 1 { + return claim.ErrClaimNotValid + } + return fmt.Errorf("kona exited with status %d", status.ExitCode()) + default: + return status + } +} diff --git a/op-e2e/actions/proofs/sequence_window_expiry_test.go b/op-e2e/actions/proofs/sequence_window_expiry_test.go index 44f58895faac..9a7a281cdcc0 100644 --- a/op-e2e/actions/proofs/sequence_window_expiry_test.go +++ b/op-e2e/actions/proofs/sequence_window_expiry_test.go @@ -5,6 +5,7 @@ import ( actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/ethereum-optimism/optimism/op-e2e/actions/proofs/helpers" + "github.com/ethereum-optimism/optimism/op-program/client/claim" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" ) @@ -63,7 +64,7 @@ func Test_ProgramAction_SequenceWindowExpired(gt *testing.T) { nil, helpers.LatestForkOnly, runSequenceWindowExpireTest, - helpers.ExpectNoError(), + helpers.ExpectError(claim.ErrClaimNotValid), helpers.WithL2Claim(common.HexToHash("0xdeadbeef")), ) } From c72a75e80ba9b90b8d2427965c4f390658ea47b9 Mon Sep 17 00:00:00 2001 From: protolambda Date: Tue, 17 Sep 2024 03:29:38 -0600 Subject: [PATCH 160/264] op-e2e: Organize e2e system tests in subdirs (#11939) * op-e2e: organize system tests * op-e2e: update CI make targets * op-e2e: fix artifacts file paths * op-e2e: Fix paths. * op-e2e: Fix paths again --------- Co-authored-by: Adrian Sutton --- op-e2e/Makefile | 10 +- op-e2e/actions/helpers/user.go | 4 +- op-e2e/devnet/devnet_test.go | 8 +- op-e2e/devnet/setup.go | 13 +- op-e2e/{helper.go => e2e.go} | 20 + op-e2e/{ => e2eutils/opnode}/tracer.go | 2 +- op-e2e/external_geth/main_test.go | 5 +- op-e2e/faultproofs/cannon_benchmark_test.go | 10 +- op-e2e/faultproofs/challenge_preimage_test.go | 1 + op-e2e/faultproofs/multi_test.go | 1 + op-e2e/faultproofs/output_alphabet_test.go | 3 +- op-e2e/faultproofs/output_cannon_test.go | 3 +- op-e2e/faultproofs/precompile_test.go | 15 +- op-e2e/faultproofs/preimages_test.go | 1 + op-e2e/faultproofs/util.go | 22 +- op-e2e/{ => interop}/interop_recipe_test.go | 8 +- op-e2e/interop/interop_test.go | 7 +- op-e2e/interop/supersystem.go | 9 +- op-e2e/{ => opgeth}/fastlz_test.go | 2 +- op-e2e/{ => opgeth}/op_geth.go | 8 +- op-e2e/{ => opgeth}/op_geth_test.go | 98 +- op-e2e/system/altda/altda_test.go | 11 + op-e2e/system/altda/concurrent_test.go | 77 + op-e2e/{ => system/bridge}/bridge_test.go | 14 +- op-e2e/{ => system/bridge}/deposit_test.go | 19 +- op-e2e/system/bridge/rpc_test.go | 55 + .../bridge/validity_test.go} | 151 +- op-e2e/{ => system/bridge}/withdrawal.go | 21 +- op-e2e/system/bridge/withdrawal_test.go | 26 + op-e2e/system/conductor/conductor_test.go | 11 + .../conductor}/sequencer_failover_setup.go | 27 +- .../conductor}/sequencer_failover_test.go | 2 +- .../conductor}/system_adminrpc_test.go | 35 +- .../contracts}/artifactsfs_test.go | 8 +- op-e2e/system/contracts/contracts_test.go | 11 + op-e2e/{ => system/da}/brotli_batcher_test.go | 19 +- op-e2e/system/da/da_test.go | 11 + op-e2e/system/da/dencun_test.go | 53 + op-e2e/{ => system/da}/eip4844_test.go | 25 +- .../{ => system/da}/l1_beacon_client_test.go | 8 +- op-e2e/system/da/multi_test.go | 64 + op-e2e/system/da/startstop_test.go | 131 ++ op-e2e/{ => system/e2esys}/external.go | 2 +- op-e2e/{ => system/e2esys}/setup.go | 34 +- op-e2e/system/fees/fees_test.go | 266 +++ op-e2e/system/fees/gaspriceoracle_test.go | 102 + op-e2e/system/fees/l1info_test.go | 205 ++ .../{ => system/fjord}/check_scripts_test.go | 12 +- op-e2e/system/fjord/fjord_test.go | 11 + .../gastoken/gastoken_test.go} | 25 +- op-e2e/{ => system/helpers}/tx_helper.go | 12 +- .../{ => system/helpers}/withdrawal_helper.go | 14 +- op-e2e/system/p2p/gossip_test.go | 203 ++ op-e2e/system/p2p/p2p_test.go | 11 + op-e2e/system/p2p/reqresp_test.go | 168 ++ .../p2p/txpool_test.go} | 13 +- op-e2e/{ => system/proofs}/build_helper.go | 6 +- op-e2e/system/proofs/proofs_test.go | 11 + op-e2e/system/proofs/proposer_fp_test.go | 77 + op-e2e/system/proofs/proposer_l2oo_test.go | 82 + op-e2e/{ => system/proofs}/system_fpp_test.go | 33 +- op-e2e/system/runcfg/p2p_signer_test.go | 62 + .../system/runcfg/protocol_versions_test.go | 141 ++ op-e2e/system/runcfg/runcfg_test.go | 11 + op-e2e/system/verifier/basic_test.go | 113 ++ op-e2e/system/verifier/confdepth_test.go | 61 + op-e2e/system/verifier/finalize_test.go | 29 + op-e2e/system/verifier/legacy_pending_test.go | 120 ++ .../system/verifier/sequencer_window_test.go | 73 + op-e2e/system/verifier/verifier_test.go | 11 + op-e2e/system_test.go | 1677 ----------------- 71 files changed, 2570 insertions(+), 2044 deletions(-) rename op-e2e/{helper.go => e2e.go} (83%) rename op-e2e/{ => e2eutils/opnode}/tracer.go (98%) rename op-e2e/{ => interop}/interop_recipe_test.go (86%) rename op-e2e/{ => opgeth}/fastlz_test.go (99%) rename op-e2e/{ => opgeth}/op_geth.go (97%) rename op-e2e/{ => opgeth}/op_geth_test.go (94%) create mode 100644 op-e2e/system/altda/altda_test.go create mode 100644 op-e2e/system/altda/concurrent_test.go rename op-e2e/{ => system/bridge}/bridge_test.go (94%) rename op-e2e/{ => system/bridge}/deposit_test.go (88%) create mode 100644 op-e2e/system/bridge/rpc_test.go rename op-e2e/{system_tob_test.go => system/bridge/validity_test.go} (81%) rename op-e2e/{ => system/bridge}/withdrawal.go (88%) create mode 100644 op-e2e/system/bridge/withdrawal_test.go create mode 100644 op-e2e/system/conductor/conductor_test.go rename op-e2e/{ => system/conductor}/sequencer_failover_setup.go (95%) rename op-e2e/{ => system/conductor}/sequencer_failover_test.go (99%) rename op-e2e/{ => system/conductor}/system_adminrpc_test.go (90%) rename op-e2e/{ => system/contracts}/artifactsfs_test.go (87%) create mode 100644 op-e2e/system/contracts/contracts_test.go rename op-e2e/{ => system/da}/brotli_batcher_test.go (87%) create mode 100644 op-e2e/system/da/da_test.go create mode 100644 op-e2e/system/da/dencun_test.go rename op-e2e/{ => system/da}/eip4844_test.go (95%) rename op-e2e/{ => system/da}/l1_beacon_client_test.go (93%) create mode 100644 op-e2e/system/da/multi_test.go create mode 100644 op-e2e/system/da/startstop_test.go rename op-e2e/{ => system/e2esys}/external.go (99%) rename op-e2e/{ => system/e2esys}/setup.go (97%) create mode 100644 op-e2e/system/fees/fees_test.go create mode 100644 op-e2e/system/fees/gaspriceoracle_test.go create mode 100644 op-e2e/system/fees/l1info_test.go rename op-e2e/{ => system/fjord}/check_scripts_test.go (92%) create mode 100644 op-e2e/system/fjord/fjord_test.go rename op-e2e/{custom_gas_token_test.go => system/gastoken/gastoken_test.go} (96%) rename op-e2e/{ => system/helpers}/tx_helper.go (91%) rename op-e2e/{ => system/helpers}/withdrawal_helper.go (91%) create mode 100644 op-e2e/system/p2p/gossip_test.go create mode 100644 op-e2e/system/p2p/p2p_test.go create mode 100644 op-e2e/system/p2p/reqresp_test.go rename op-e2e/{l2_gossip_test.go => system/p2p/txpool_test.go} (74%) rename op-e2e/{ => system/proofs}/build_helper.go (86%) create mode 100644 op-e2e/system/proofs/proofs_test.go create mode 100644 op-e2e/system/proofs/proposer_fp_test.go create mode 100644 op-e2e/system/proofs/proposer_l2oo_test.go rename op-e2e/{ => system/proofs}/system_fpp_test.go (91%) create mode 100644 op-e2e/system/runcfg/p2p_signer_test.go create mode 100644 op-e2e/system/runcfg/protocol_versions_test.go create mode 100644 op-e2e/system/runcfg/runcfg_test.go create mode 100644 op-e2e/system/verifier/basic_test.go create mode 100644 op-e2e/system/verifier/confdepth_test.go create mode 100644 op-e2e/system/verifier/finalize_test.go create mode 100644 op-e2e/system/verifier/legacy_pending_test.go create mode 100644 op-e2e/system/verifier/sequencer_window_test.go create mode 100644 op-e2e/system/verifier/verifier_test.go delete mode 100644 op-e2e/system_test.go diff --git a/op-e2e/Makefile b/op-e2e/Makefile index e33f83e9b6c1..f3f67f8050da 100644 --- a/op-e2e/Makefile +++ b/op-e2e/Makefile @@ -17,7 +17,7 @@ test-external-%: pre-test $(go_test) $(go_test_flags) --externalL2 ./external_$*/ test-ws: pre-test - $(go_test) $(go_test_flags) . ./e2eutils/... + $(go_test) $(go_test_flags) ./system/... ./e2eutils/... ./opgeth/... ./interop/... .PHONY: test-ws test-actions: pre-test @@ -25,7 +25,7 @@ test-actions: pre-test .PHONY: test-actions test-http: pre-test - OP_E2E_USE_HTTP=true $(go_test) $(go_test_flags) . ./e2eutils/... + OP_E2E_USE_HTTP=true $(go_test) $(go_test_flags) ./system/... ./e2eutils/... ./opgeth/... ./interop/... .PHONY: test-http test-cannon: pre-test @@ -71,7 +71,7 @@ clean: .PHONY: clean fuzz: - go test -run NOTAREALTEST -tags cgo_test -v -fuzztime 10s -fuzz FuzzFjordCostFunction ./ - go test -run NOTAREALTEST -tags cgo_test -v -fuzztime 10s -fuzz FuzzFastLzGethSolidity ./ - go test -run NOTAREALTEST -tags cgo_test -v -fuzztime 10s -fuzz FuzzFastLzCgo ./ + go test -run NOTAREALTEST -tags cgo_test -v -fuzztime 10s -fuzz FuzzFjordCostFunction ./opgeth + go test -run NOTAREALTEST -tags cgo_test -v -fuzztime 10s -fuzz FuzzFastLzGethSolidity ./opgeth + go test -run NOTAREALTEST -tags cgo_test -v -fuzztime 10s -fuzz FuzzFastLzCgo ./opgeth diff --git a/op-e2e/actions/helpers/user.go b/op-e2e/actions/helpers/user.go index 401237c0fad3..4df96e67cb6a 100644 --- a/op-e2e/actions/helpers/user.go +++ b/op-e2e/actions/helpers/user.go @@ -24,10 +24,10 @@ import ( "github.com/stretchr/testify/require" "github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain" - e2e "github.com/ethereum-optimism/optimism/op-e2e" legacybindings "github.com/ethereum-optimism/optimism/op-e2e/bindings" "github.com/ethereum-optimism/optimism/op-e2e/config" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + e2ehelpers "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" "github.com/ethereum-optimism/optimism/op-node/bindings" bindingspreview "github.com/ethereum-optimism/optimism/op-node/bindings/preview" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" @@ -449,7 +449,7 @@ func (s *CrossLayerUser) getLatestWithdrawalParams(t Testing) (*withdrawals.Prov header, err := s.L2.env.EthCl.HeaderByNumber(t.Ctx(), l2OutputBlockNr) require.NoError(t, err) - params, err := e2e.ProveWithdrawalParameters(t.Ctx(), s.L2.env.Bindings.ProofClient, s.L2.env.EthCl, s.L2.env.EthCl, s.lastL2WithdrawalTxHash, header, &s.L1.env.Bindings.L2OutputOracle.L2OutputOracleCaller, &s.L1.env.Bindings.DisputeGameFactory.DisputeGameFactoryCaller, &s.L1.env.Bindings.OptimismPortal2.OptimismPortal2Caller) + params, err := e2ehelpers.ProveWithdrawalParameters(t.Ctx(), s.L2.env.Bindings.ProofClient, s.L2.env.EthCl, s.L2.env.EthCl, s.lastL2WithdrawalTxHash, header, &s.L1.env.Bindings.L2OutputOracle.L2OutputOracleCaller, &s.L1.env.Bindings.DisputeGameFactory.DisputeGameFactoryCaller, &s.L1.env.Bindings.OptimismPortal2.OptimismPortal2Caller) require.NoError(t, err) return ¶ms, nil diff --git a/op-e2e/devnet/devnet_test.go b/op-e2e/devnet/devnet_test.go index 2a9b4be8aa5d..8bf7bd7665da 100644 --- a/op-e2e/devnet/devnet_test.go +++ b/op-e2e/devnet/devnet_test.go @@ -6,11 +6,11 @@ import ( "testing" "time" - e2e "github.com/ethereum-optimism/optimism/op-e2e" - "github.com/ethereum-optimism/optimism/op-service/testlog" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/ethereum-optimism/optimism/op-e2e/system/bridge" + "github.com/ethereum-optimism/optimism/op-service/testlog" ) func TestDevnet(t *testing.T) { @@ -29,7 +29,7 @@ func TestDevnet(t *testing.T) { }) t.Run("Withdrawal", func(t *testing.T) { t.Parallel() - e2e.RunWithdrawalsTest(t, sys) + bridge.RunWithdrawalsTest(t, sys) }) } diff --git a/op-e2e/devnet/setup.go b/op-e2e/devnet/setup.go index 8724fcfc4e1f..557caed0388b 100644 --- a/op-e2e/devnet/setup.go +++ b/op-e2e/devnet/setup.go @@ -6,8 +6,9 @@ import ( "os" "path/filepath" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" - e2e "github.com/ethereum-optimism/optimism/op-e2e" "github.com/ethereum-optimism/optimism/op-e2e/config" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" op_service "github.com/ethereum-optimism/optimism/op-service" @@ -29,7 +30,7 @@ type System struct { L1 *ethclient.Client L2 *ethclient.Client Rollup *sources.RollupClient - Cfg e2e.SystemConfig + Cfg e2esys.SystemConfig } func NewSystem(ctx context.Context, lgr log.Logger) (sys *System, err error) { @@ -69,7 +70,7 @@ func NewSystem(ctx context.Context, lgr log.Logger) (sys *System, err error) { } // Incomplete SystemConfig suffices for withdrawal test (only consumer right now) - sys.Cfg = e2e.SystemConfig{ + sys.Cfg = e2esys.SystemConfig{ DeployConfig: deployConfig, L1Deployments: config.L1Deployments.Copy(), Secrets: secrets, @@ -79,9 +80,9 @@ func NewSystem(ctx context.Context, lgr log.Logger) (sys *System, err error) { func (s System) NodeClient(role string) *ethclient.Client { switch role { - case e2e.RoleL1: + case e2esys.RoleL1: return s.L1 - case e2e.RoleSeq, e2e.RoleVerif: + case e2esys.RoleSeq, e2esys.RoleVerif: // we have only one L2 node return s.L2 default: @@ -94,7 +95,7 @@ func (s System) RollupClient(string) *sources.RollupClient { return s.Rollup } -func (s System) Config() e2e.SystemConfig { +func (s System) Config() e2esys.SystemConfig { return s.Cfg } diff --git a/op-e2e/helper.go b/op-e2e/e2e.go similarity index 83% rename from op-e2e/helper.go rename to op-e2e/e2e.go index 441bc3d9275c..ebcf5750e381 100644 --- a/op-e2e/helper.go +++ b/op-e2e/e2e.go @@ -2,13 +2,33 @@ package op_e2e import ( "crypto/md5" + "fmt" "os" + "runtime" "strconv" "strings" + "testing" + "github.com/ethereum-optimism/optimism/op-e2e/config" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" ) +func RunMain(m *testing.M) { + if config.ExternalL2Shim != "" { + fmt.Println("Running tests with external L2 process adapter at ", config.ExternalL2Shim) + // As these are integration tests which launch many other processes, the + // default parallelism makes the tests flaky. This change aims to + // reduce the flakiness of these tests. + maxProcs := runtime.NumCPU() / 4 + if maxProcs == 0 { + maxProcs = 1 + } + runtime.GOMAXPROCS(maxProcs) + } + + os.Exit(m.Run()) +} + var enableParallelTesting bool = os.Getenv("OP_E2E_DISABLE_PARALLEL") != "true" func InitParallel(t e2eutils.TestingBase, args ...func(t e2eutils.TestingBase)) { diff --git a/op-e2e/tracer.go b/op-e2e/e2eutils/opnode/tracer.go similarity index 98% rename from op-e2e/tracer.go rename to op-e2e/e2eutils/opnode/tracer.go index 217c1762082a..33a23b775ce5 100644 --- a/op-e2e/tracer.go +++ b/op-e2e/e2eutils/opnode/tracer.go @@ -1,4 +1,4 @@ -package op_e2e +package opnode import ( "context" diff --git a/op-e2e/external_geth/main_test.go b/op-e2e/external_geth/main_test.go index 8cea0ec81fdb..b971057e0cc2 100644 --- a/op-e2e/external_geth/main_test.go +++ b/op-e2e/external_geth/main_test.go @@ -9,9 +9,10 @@ import ( "testing" "time" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/stretchr/testify/require" - e2e "github.com/ethereum-optimism/optimism/op-e2e" "github.com/ethereum-optimism/optimism/op-e2e/config" "github.com/ethereum-optimism/optimism/op-service/endpoint" ) @@ -37,7 +38,7 @@ func TestShim(t *testing.T) { config.EthNodeVerbosity = config.LegacyLevelDebug - ec := (&e2e.ExternalRunner{ + ec := (&e2esys.ExternalRunner{ Name: "TestShim", BinPath: shimPath, }).Run(t) diff --git a/op-e2e/faultproofs/cannon_benchmark_test.go b/op-e2e/faultproofs/cannon_benchmark_test.go index 57bb0581ac4e..7171d1211764 100644 --- a/op-e2e/faultproofs/cannon_benchmark_test.go +++ b/op-e2e/faultproofs/cannon_benchmark_test.go @@ -11,6 +11,9 @@ import ( "testing" "time" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -23,7 +26,6 @@ import ( "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" - op_e2e "github.com/ethereum-optimism/optimism/op-e2e" "github.com/ethereum-optimism/optimism/op-e2e/bindings" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-service/predeploys" @@ -35,7 +37,7 @@ func TestBenchmarkCannon_FPP(t *testing.T) { op_e2e.InitParallel(t, op_e2e.UsesCannon) ctx := context.Background() - cfg := op_e2e.DefaultSystemConfig(t) + cfg := e2esys.DefaultSystemConfig(t) // We don't need a verifier - just the sequencer is enough delete(cfg.Nodes, "verifier") // Use a small sequencer window size to avoid test timeout while waiting for empty blocks @@ -102,7 +104,7 @@ func TestBenchmarkCannon_FPP(t *testing.T) { // TODO(client-pod#906): Use maximum witness size for assertions against pages allocated by the VM } -func createBigContracts(ctx context.Context, t *testing.T, cfg op_e2e.SystemConfig, client *ethclient.Client, key *ecdsa.PrivateKey, numContracts int) []common.Address { +func createBigContracts(ctx context.Context, t *testing.T, cfg e2esys.SystemConfig, client *ethclient.Client, key *ecdsa.PrivateKey, numContracts int) []common.Address { /* contract Big { bytes constant foo = hex"<24.4 KB of random data>"; @@ -162,7 +164,7 @@ func createBigContracts(ctx context.Context, t *testing.T, cfg op_e2e.SystemConf return addrs } -func callBigContracts(ctx context.Context, t *testing.T, cfg op_e2e.SystemConfig, client *ethclient.Client, key *ecdsa.PrivateKey, addrs []common.Address) *types.Receipt { +func callBigContracts(ctx context.Context, t *testing.T, cfg e2esys.SystemConfig, client *ethclient.Client, key *ecdsa.PrivateKey, addrs []common.Address) *types.Receipt { multicall3, err := bindings.NewMultiCall3(predeploys.MultiCall3Addr, client) require.NoError(t, err) diff --git a/op-e2e/faultproofs/challenge_preimage_test.go b/op-e2e/faultproofs/challenge_preimage_test.go index 226f85c825c1..3bed79ad068e 100644 --- a/op-e2e/faultproofs/challenge_preimage_test.go +++ b/op-e2e/faultproofs/challenge_preimage_test.go @@ -5,6 +5,7 @@ import ( "testing" op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame/preimage" diff --git a/op-e2e/faultproofs/multi_test.go b/op-e2e/faultproofs/multi_test.go index 8073c3e7596b..83b475d60e0d 100644 --- a/op-e2e/faultproofs/multi_test.go +++ b/op-e2e/faultproofs/multi_test.go @@ -5,6 +5,7 @@ import ( "testing" op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame" "github.com/ethereum/go-ethereum/common" diff --git a/op-e2e/faultproofs/output_alphabet_test.go b/op-e2e/faultproofs/output_alphabet_test.go index 3e46c732edb3..9255214ff39b 100644 --- a/op-e2e/faultproofs/output_alphabet_test.go +++ b/op-e2e/faultproofs/output_alphabet_test.go @@ -6,8 +6,9 @@ import ( "testing" "time" - "github.com/ethereum-optimism/optimism/op-challenger/game/types" op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" diff --git a/op-e2e/faultproofs/output_cannon_test.go b/op-e2e/faultproofs/output_cannon_test.go index c5ac078df932..d0abbac7338c 100644 --- a/op-e2e/faultproofs/output_cannon_test.go +++ b/op-e2e/faultproofs/output_cannon_test.go @@ -5,10 +5,11 @@ import ( "fmt" "testing" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" - op_e2e "github.com/ethereum-optimism/optimism/op-e2e" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame/preimage" diff --git a/op-e2e/faultproofs/precompile_test.go b/op-e2e/faultproofs/precompile_test.go index 116864c06e67..82a8c2e397c6 100644 --- a/op-e2e/faultproofs/precompile_test.go +++ b/op-e2e/faultproofs/precompile_test.go @@ -7,6 +7,10 @@ import ( "path/filepath" "testing" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/versions" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -19,7 +23,6 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" "github.com/ethereum-optimism/optimism/op-challenger/metrics" - op_e2e "github.com/ethereum-optimism/optimism/op-e2e" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" @@ -75,7 +78,7 @@ func TestPrecompiles(t *testing.T) { op_e2e.InitParallel(t, op_e2e.UsesCannon) ctx := context.Background() genesisTime := hexutil.Uint64(0) - cfg := op_e2e.EcotoneSystemConfig(t, &genesisTime) + cfg := e2esys.EcotoneSystemConfig(t, &genesisTime) // We don't need a verifier - just the sequencer is enough delete(cfg.Nodes, "verifier") // Use a small sequencer window size to avoid test timeout while waiting for empty blocks @@ -101,7 +104,7 @@ func TestPrecompiles(t *testing.T) { l2Head := agreedL2Output.BlockRef.Hash l2OutputRoot := agreedL2Output.OutputRoot - receipt := op_e2e.SendL2Tx(t, cfg, l2Seq, aliceKey, func(opts *op_e2e.TxOpts) { + receipt := helpers.SendL2Tx(t, cfg, l2Seq, aliceKey, func(opts *helpers.TxOpts) { opts.Gas = 1_000_000 opts.ToAddr = &test.address opts.Nonce = 0 @@ -140,7 +143,7 @@ func TestPrecompiles(t *testing.T) { l2Seq := sys.NodeClient("sequencer") aliceKey := sys.Cfg.Secrets.Alice - receipt := op_e2e.SendL2Tx(t, sys.Cfg, l2Seq, aliceKey, func(opts *op_e2e.TxOpts) { + receipt := helpers.SendL2Tx(t, sys.Cfg, l2Seq, aliceKey, func(opts *helpers.TxOpts) { opts.Gas = 1_000_000 opts.ToAddr = &test.address opts.Nonce = 0 @@ -174,7 +177,7 @@ func TestGranitePrecompiles(t *testing.T) { op_e2e.InitParallel(t, op_e2e.UsesCannon) ctx := context.Background() genesisTime := hexutil.Uint64(0) - cfg := op_e2e.GraniteSystemConfig(t, &genesisTime) + cfg := e2esys.GraniteSystemConfig(t, &genesisTime) // We don't need a verifier - just the sequencer is enough delete(cfg.Nodes, "verifier") // Use a small sequencer window size to avoid test timeout while waiting for empty blocks @@ -242,7 +245,7 @@ func TestGranitePrecompiles(t *testing.T) { runCannon(t, ctx, sys, inputs) } -func runCannon(t *testing.T, ctx context.Context, sys *op_e2e.System, inputs utils.LocalGameInputs, extraVmArgs ...string) { +func runCannon(t *testing.T, ctx context.Context, sys *e2esys.System, inputs utils.LocalGameInputs, extraVmArgs ...string) { l1Endpoint := sys.NodeEndpoint("l1").RPC() l1Beacon := sys.L1BeaconEndpoint().RestHTTP() rollupEndpoint := sys.RollupEndpoint("sequencer").RPC() diff --git a/op-e2e/faultproofs/preimages_test.go b/op-e2e/faultproofs/preimages_test.go index 03acf824daf3..8536fe578a5f 100644 --- a/op-e2e/faultproofs/preimages_test.go +++ b/op-e2e/faultproofs/preimages_test.go @@ -6,6 +6,7 @@ import ( "testing" op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame" preimage "github.com/ethereum-optimism/optimism/op-preimage" "github.com/ethereum-optimism/optimism/op-program/client" diff --git a/op-e2e/faultproofs/util.go b/op-e2e/faultproofs/util.go index c3457b299d5a..5beebafd88a6 100644 --- a/op-e2e/faultproofs/util.go +++ b/op-e2e/faultproofs/util.go @@ -4,8 +4,10 @@ import ( "crypto/ecdsa" "testing" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" + batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" - op_e2e "github.com/ethereum-optimism/optimism/op-e2e" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" @@ -13,16 +15,16 @@ import ( "github.com/stretchr/testify/require" ) -type faultDisputeConfigOpts func(cfg *op_e2e.SystemConfig) +type faultDisputeConfigOpts func(cfg *e2esys.SystemConfig) func WithBatcherStopped() faultDisputeConfigOpts { - return func(cfg *op_e2e.SystemConfig) { + return func(cfg *e2esys.SystemConfig) { cfg.DisableBatcher = true } } func WithBlobBatches() faultDisputeConfigOpts { - return func(cfg *op_e2e.SystemConfig) { + return func(cfg *e2esys.SystemConfig) { cfg.DataAvailabilityType = batcherFlags.BlobsType genesisActivation := hexutil.Uint64(0) @@ -33,7 +35,7 @@ func WithBlobBatches() faultDisputeConfigOpts { } func WithEcotone() faultDisputeConfigOpts { - return func(cfg *op_e2e.SystemConfig) { + return func(cfg *e2esys.SystemConfig) { genesisActivation := hexutil.Uint64(0) cfg.DeployConfig.L1CancunTimeOffset = &genesisActivation cfg.DeployConfig.L2GenesisDeltaTimeOffset = &genesisActivation @@ -42,13 +44,13 @@ func WithEcotone() faultDisputeConfigOpts { } func WithSequencerWindowSize(size uint64) faultDisputeConfigOpts { - return func(cfg *op_e2e.SystemConfig) { + return func(cfg *e2esys.SystemConfig) { cfg.DeployConfig.SequencerWindowSize = size } } -func StartFaultDisputeSystem(t *testing.T, opts ...faultDisputeConfigOpts) (*op_e2e.System, *ethclient.Client) { - cfg := op_e2e.DefaultSystemConfig(t) +func StartFaultDisputeSystem(t *testing.T, opts ...faultDisputeConfigOpts) (*e2esys.System, *ethclient.Client) { + cfg := e2esys.DefaultSystemConfig(t) delete(cfg.Nodes, "verifier") cfg.Nodes["sequencer"].SafeDBPath = t.TempDir() cfg.DeployConfig.SequencerWindowSize = 4 @@ -64,8 +66,8 @@ func StartFaultDisputeSystem(t *testing.T, opts ...faultDisputeConfigOpts) (*op_ return sys, sys.NodeClient("l1") } -func SendKZGPointEvaluationTx(t *testing.T, sys *op_e2e.System, l2Node string, privateKey *ecdsa.PrivateKey) *types.Receipt { - return op_e2e.SendL2Tx(t, sys.Cfg, sys.NodeClient(l2Node), privateKey, func(opts *op_e2e.TxOpts) { +func SendKZGPointEvaluationTx(t *testing.T, sys *e2esys.System, l2Node string, privateKey *ecdsa.PrivateKey) *types.Receipt { + return helpers.SendL2Tx(t, sys.Cfg, sys.NodeClient(l2Node), privateKey, func(opts *helpers.TxOpts) { precompile := common.BytesToAddress([]byte{0x0a}) opts.Gas = 100_000 opts.ToAddr = &precompile diff --git a/op-e2e/interop_recipe_test.go b/op-e2e/interop/interop_recipe_test.go similarity index 86% rename from op-e2e/interop_recipe_test.go rename to op-e2e/interop/interop_recipe_test.go index a7a5b9ee3466..05a2e056c39b 100644 --- a/op-e2e/interop_recipe_test.go +++ b/op-e2e/interop/interop_recipe_test.go @@ -1,4 +1,4 @@ -package op_e2e +package interop import ( "encoding/json" @@ -16,8 +16,6 @@ import ( ) func TestInteropDevRecipe(t *testing.T) { - InitParallel(t) - rec := interopgen.InteropDevRecipe{ L1ChainID: 900100, L2ChainIDs: []uint64{900200, 900201}, @@ -31,8 +29,8 @@ func TestInteropDevRecipe(t *testing.T) { logger := testlog.Logger(t, log.LevelDebug) require.NoError(t, worldCfg.Check(logger)) - fa := foundry.OpenArtifactsDir("../packages/contracts-bedrock/forge-artifacts") - srcFS := foundry.NewSourceMapFS(os.DirFS("../packages/contracts-bedrock")) + fa := foundry.OpenArtifactsDir("../../packages/contracts-bedrock/forge-artifacts") + srcFS := foundry.NewSourceMapFS(os.DirFS("../../packages/contracts-bedrock")) worldDeployment, worldOutput, err := interopgen.Deploy(logger, fa, srcFS, worldCfg) require.NoError(t, err) diff --git a/op-e2e/interop/interop_test.go b/op-e2e/interop/interop_test.go index f88ae7b3348e..6ad12cf44d3d 100644 --- a/op-e2e/interop/interop_test.go +++ b/op-e2e/interop/interop_test.go @@ -6,9 +6,10 @@ import ( "testing" "time" - "github.com/ethereum-optimism/optimism/op-chain-ops/interopgen" - op_e2e "github.com/ethereum-optimism/optimism/op-e2e" "github.com/stretchr/testify/require" + + "github.com/ethereum-optimism/optimism/op-chain-ops/interopgen" + "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" ) // TestInteropTrivial tests a simple interop scenario @@ -60,7 +61,7 @@ func TestInteropTrivial(t *testing.T) { s2.SendL2Tx( chainA, "Alice", - func(l2Opts *op_e2e.TxOpts) { + func(l2Opts *helpers.TxOpts) { l2Opts.ToAddr = &bobAddr l2Opts.Value = big.NewInt(1000000) l2Opts.GasFeeCap = big.NewInt(1_000_000_000) diff --git a/op-e2e/interop/supersystem.go b/op-e2e/interop/supersystem.go index 24ec4aa1046a..5f4273da04e7 100644 --- a/op-e2e/interop/supersystem.go +++ b/op-e2e/interop/supersystem.go @@ -10,6 +10,8 @@ import ( "testing" "time" + "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/stretchr/testify/require" @@ -26,7 +28,6 @@ import ( "github.com/ethereum-optimism/optimism/op-chain-ops/devkeys" "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" "github.com/ethereum-optimism/optimism/op-chain-ops/interopgen" - op_e2e "github.com/ethereum-optimism/optimism/op-e2e" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/fakebeacon" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/opnode" @@ -82,7 +83,7 @@ type SuperSystem interface { // get the user key for a user on an L2 UserKey(id, username string) ecdsa.PrivateKey // send a transaction on an L2 on the given network, from the given user - SendL2Tx(network string, username string, applyTxOpts op_e2e.TxOptsFn) *types.Receipt + SendL2Tx(network string, username string, applyTxOpts helpers.TxOptsFn) *types.Receipt // get the address for a user on an L2 Address(network string, username string) common.Address } @@ -586,11 +587,11 @@ func (s *interopE2ESystem) L2IDs() []string { func (s *interopE2ESystem) SendL2Tx( id string, sender string, - applyTxOpts op_e2e.TxOptsFn, + applyTxOpts helpers.TxOptsFn, ) *types.Receipt { senderSecret := s.UserKey(id, sender) require.NotNil(s.t, senderSecret, "no secret found for sender %s", sender) - return op_e2e.SendL2TxWithID( + return helpers.SendL2TxWithID( s.t, s.l2s[id].chainID, s.L2GethClient(id), diff --git a/op-e2e/fastlz_test.go b/op-e2e/opgeth/fastlz_test.go similarity index 99% rename from op-e2e/fastlz_test.go rename to op-e2e/opgeth/fastlz_test.go index 2323764e4678..5a501962341b 100644 --- a/op-e2e/fastlz_test.go +++ b/op-e2e/opgeth/fastlz_test.go @@ -1,7 +1,7 @@ //go:build cgo_test // +build cgo_test -package op_e2e +package opgeth import ( "context" diff --git a/op-e2e/op_geth.go b/op-e2e/opgeth/op_geth.go similarity index 97% rename from op-e2e/op_geth.go rename to op-e2e/opgeth/op_geth.go index e13f42d8e885..cf48e1d9f787 100644 --- a/op-e2e/op_geth.go +++ b/op-e2e/opgeth/op_geth.go @@ -1,4 +1,4 @@ -package op_e2e +package opgeth import ( "context" @@ -7,6 +7,8 @@ import ( "reflect" "testing" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" "github.com/ethereum-optimism/optimism/op-e2e/config" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" @@ -51,7 +53,7 @@ type OpGeth struct { lgr log.Logger } -func NewOpGeth(t testing.TB, ctx context.Context, cfg *SystemConfig) (*OpGeth, error) { +func NewOpGeth(t testing.TB, ctx context.Context, cfg *e2esys.SystemConfig) (*OpGeth, error) { logger := testlog.Logger(t, log.LevelCrit) l1Genesis, err := genesis.BuildL1DeveloperGenesis(cfg.DeployConfig, config.L1Allocs, config.L1Deployments) @@ -92,7 +94,7 @@ func NewOpGeth(t testing.TB, ctx context.Context, cfg *SystemConfig) (*OpGeth, e require.NoError(t, gethNode.Node.Start()) node = gethNode } else { - externalNode := (&ExternalRunner{ + externalNode := (&e2esys.ExternalRunner{ Name: "l2", BinPath: cfg.ExternalL2Shim, Genesis: l2Genesis, diff --git a/op-e2e/op_geth_test.go b/op-e2e/opgeth/op_geth_test.go similarity index 94% rename from op-e2e/op_geth_test.go rename to op-e2e/opgeth/op_geth_test.go index f34dfb81633b..026c3559575e 100644 --- a/op-e2e/op_geth_test.go +++ b/op-e2e/opgeth/op_geth_test.go @@ -1,4 +1,4 @@ -package op_e2e +package opgeth import ( "context" @@ -7,6 +7,10 @@ import ( "testing" "time" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-service/eth" @@ -32,8 +36,8 @@ var ( // TestMissingGasLimit tests that op-geth cannot build a block without gas limit while optimism is active in the chain config. func TestMissingGasLimit(t *testing.T) { - InitParallel(t) - cfg := DefaultSystemConfig(t) + op_e2e.InitParallel(t) + cfg := e2esys.DefaultSystemConfig(t) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() opGeth, err := NewOpGeth(t, ctx, &cfg) @@ -55,8 +59,8 @@ func TestMissingGasLimit(t *testing.T) { // TestTxGasSameAsBlockGasLimit tests that op-geth rejects transactions that attempt to use the full block gas limit. // The L1 Info deposit always takes gas so the effective gas limit is lower than the full block gas limit. func TestTxGasSameAsBlockGasLimit(t *testing.T) { - InitParallel(t) - cfg := DefaultSystemConfig(t) + op_e2e.InitParallel(t) + cfg := e2esys.DefaultSystemConfig(t) sys, err := cfg.Start(t) require.Nil(t, err, "Error starting up system") @@ -75,8 +79,8 @@ func TestTxGasSameAsBlockGasLimit(t *testing.T) { // TestInvalidDepositInFCU runs an invalid deposit through a FCU/GetPayload/NewPayload/FCU set of calls. // This tests that deposits must always allow the block to be built even if they are invalid. func TestInvalidDepositInFCU(t *testing.T) { - InitParallel(t) - cfg := DefaultSystemConfig(t) + op_e2e.InitParallel(t) + cfg := e2esys.DefaultSystemConfig(t) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() opGeth, err := NewOpGeth(t, ctx, &cfg) @@ -115,8 +119,8 @@ func TestInvalidDepositInFCU(t *testing.T) { // and asserts that the pending block is set to match the latest block at every stage, // for stability and tx-privacy. func TestGethOnlyPendingBlockIsLatest(t *testing.T) { - InitParallel(t) - cfg := DefaultSystemConfig(t) + op_e2e.InitParallel(t) + cfg := e2esys.DefaultSystemConfig(t) cfg.DeployConfig.FundDevAccounts = true ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -241,10 +245,10 @@ func TestPreregolith(t *testing.T) { for _, test := range tests { test := test t.Run("GasUsed_"+test.name, func(t *testing.T) { - InitParallel(t) + op_e2e.InitParallel(t) // Setup an L2 EE and create a client connection to the engine. // We also need to setup a L1 Genesis to create the rollup genesis. - cfg := RegolithSystemConfig(t, test.regolithTime) + cfg := e2esys.RegolithSystemConfig(t, test.regolithTime) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -289,10 +293,10 @@ func TestPreregolith(t *testing.T) { }) t.Run("DepositNonce_"+test.name, func(t *testing.T) { - InitParallel(t) + op_e2e.InitParallel(t) // Setup an L2 EE and create a client connection to the engine. // We also need to setup a L1 Genesis to create the rollup genesis. - cfg := RegolithSystemConfig(t, test.regolithTime) + cfg := e2esys.RegolithSystemConfig(t, test.regolithTime) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -347,8 +351,8 @@ func TestPreregolith(t *testing.T) { }) t.Run("UnusedGasConsumed_"+test.name, func(t *testing.T) { - InitParallel(t) - cfg := RegolithSystemConfig(t, test.regolithTime) + op_e2e.InitParallel(t) + cfg := e2esys.RegolithSystemConfig(t, test.regolithTime) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -388,8 +392,8 @@ func TestPreregolith(t *testing.T) { }) t.Run("AllowSystemTx_"+test.name, func(t *testing.T) { - InitParallel(t) - cfg := RegolithSystemConfig(t, test.regolithTime) + op_e2e.InitParallel(t) + cfg := e2esys.RegolithSystemConfig(t, test.regolithTime) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -424,10 +428,10 @@ func TestRegolith(t *testing.T) { for _, test := range tests { test := test t.Run("GasUsedIsAccurate_"+test.name, func(t *testing.T) { - InitParallel(t) + op_e2e.InitParallel(t) // Setup an L2 EE and create a client connection to the engine. // We also need to setup a L1 Genesis to create the rollup genesis. - cfg := RegolithSystemConfig(t, &test.regolithTime) + cfg := e2esys.RegolithSystemConfig(t, &test.regolithTime) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -475,10 +479,10 @@ func TestRegolith(t *testing.T) { }) t.Run("DepositNonceCorrect_"+test.name, func(t *testing.T) { - InitParallel(t) + op_e2e.InitParallel(t) // Setup an L2 EE and create a client connection to the engine. // We also need to setup a L1 Genesis to create the rollup genesis. - cfg := RegolithSystemConfig(t, &test.regolithTime) + cfg := e2esys.RegolithSystemConfig(t, &test.regolithTime) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -536,8 +540,8 @@ func TestRegolith(t *testing.T) { }) t.Run("ReturnUnusedGasToPool_"+test.name, func(t *testing.T) { - InitParallel(t) - cfg := RegolithSystemConfig(t, &test.regolithTime) + op_e2e.InitParallel(t) + cfg := e2esys.RegolithSystemConfig(t, &test.regolithTime) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -578,8 +582,8 @@ func TestRegolith(t *testing.T) { }) t.Run("RejectSystemTx_"+test.name, func(t *testing.T) { - InitParallel(t) - cfg := RegolithSystemConfig(t, &test.regolithTime) + op_e2e.InitParallel(t) + cfg := e2esys.RegolithSystemConfig(t, &test.regolithTime) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -600,7 +604,7 @@ func TestRegolith(t *testing.T) { }) t.Run("IncludeGasRefunds_"+test.name, func(t *testing.T) { - InitParallel(t) + op_e2e.InitParallel(t) // Simple constructor that is prefixed to the actual contract code // Results in the contract code being returned as the code for the new contract deployPrefixSize := byte(16) @@ -638,7 +642,7 @@ func TestRegolith(t *testing.T) { deployData := append(deployPrefix, sstoreContract...) - cfg := RegolithSystemConfig(t, &test.regolithTime) + cfg := e2esys.RegolithSystemConfig(t, &test.regolithTime) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -735,8 +739,8 @@ func TestPreCanyon(t *testing.T) { test := test t.Run(fmt.Sprintf("ReturnsNilWithdrawals_%s", test.name), func(t *testing.T) { - InitParallel(t) - cfg := CanyonSystemConfig(t, test.canyonTime) + op_e2e.InitParallel(t) + cfg := e2esys.CanyonSystemConfig(t, test.canyonTime) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -755,8 +759,8 @@ func TestPreCanyon(t *testing.T) { }) t.Run(fmt.Sprintf("RejectPushZeroTx_%s", test.name), func(t *testing.T) { - InitParallel(t) - cfg := CanyonSystemConfig(t, test.canyonTime) + op_e2e.InitParallel(t) + cfg := e2esys.CanyonSystemConfig(t, test.canyonTime) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -801,8 +805,8 @@ func TestCanyon(t *testing.T) { for _, test := range tests { test := test t.Run(fmt.Sprintf("ReturnsEmptyWithdrawals_%s", test.name), func(t *testing.T) { - InitParallel(t) - cfg := CanyonSystemConfig(t, &test.canyonTime) + op_e2e.InitParallel(t) + cfg := e2esys.CanyonSystemConfig(t, &test.canyonTime) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -823,8 +827,8 @@ func TestCanyon(t *testing.T) { }) t.Run(fmt.Sprintf("AcceptsPushZeroTxn_%s", test.name), func(t *testing.T) { - InitParallel(t) - cfg := CanyonSystemConfig(t, &test.canyonTime) + op_e2e.InitParallel(t) + cfg := e2esys.CanyonSystemConfig(t, &test.canyonTime) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -869,8 +873,8 @@ func TestPreEcotone(t *testing.T) { test := test t.Run(fmt.Sprintf("NilParentBeaconRoot_%s", test.name), func(t *testing.T) { - InitParallel(t) - cfg := EcotoneSystemConfig(t, test.ecotoneTime) + op_e2e.InitParallel(t) + cfg := e2esys.EcotoneSystemConfig(t, test.ecotoneTime) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -889,8 +893,8 @@ func TestPreEcotone(t *testing.T) { }) t.Run(fmt.Sprintf("RejectTstoreTxn_%s", test.name), func(t *testing.T) { - InitParallel(t) - cfg := EcotoneSystemConfig(t, test.ecotoneTime) + op_e2e.InitParallel(t) + cfg := e2esys.EcotoneSystemConfig(t, test.ecotoneTime) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -937,8 +941,8 @@ func TestEcotone(t *testing.T) { for _, test := range tests { test := test t.Run(fmt.Sprintf("HashParentBeaconBlockRoot_%s", test.name), func(t *testing.T) { - InitParallel(t) - cfg := EcotoneSystemConfig(t, &test.ecotoneTime) + op_e2e.InitParallel(t) + cfg := e2esys.EcotoneSystemConfig(t, &test.ecotoneTime) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -961,8 +965,8 @@ func TestEcotone(t *testing.T) { }) t.Run(fmt.Sprintf("TstoreTxn_%s", test.name), func(t *testing.T) { - InitParallel(t) - cfg := EcotoneSystemConfig(t, &test.ecotoneTime) + op_e2e.InitParallel(t) + cfg := e2esys.EcotoneSystemConfig(t, &test.ecotoneTime) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -1013,8 +1017,8 @@ func TestPreFjord(t *testing.T) { test := test t.Run(fmt.Sprintf("RIP7212_%s", test.name), func(t *testing.T) { - InitParallel(t) - cfg := FjordSystemConfig(t, test.fjordTime) + op_e2e.InitParallel(t) + cfg := e2esys.FjordSystemConfig(t, test.fjordTime) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -1061,8 +1065,8 @@ func TestFjord(t *testing.T) { for _, test := range tests { test := test t.Run(fmt.Sprintf("RIP7212_%s", test.name), func(t *testing.T) { - InitParallel(t) - cfg := FjordSystemConfig(t, &test.fjordTime) + op_e2e.InitParallel(t) + cfg := e2esys.FjordSystemConfig(t, &test.fjordTime) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() diff --git a/op-e2e/system/altda/altda_test.go b/op-e2e/system/altda/altda_test.go new file mode 100644 index 000000000000..9a9546328c02 --- /dev/null +++ b/op-e2e/system/altda/altda_test.go @@ -0,0 +1,11 @@ +package altda + +import ( + "testing" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" +) + +func TestMain(m *testing.M) { + op_e2e.RunMain(m) +} diff --git a/op-e2e/system/altda/concurrent_test.go b/op-e2e/system/altda/concurrent_test.go new file mode 100644 index 000000000000..4d6835b1fc55 --- /dev/null +++ b/op-e2e/system/altda/concurrent_test.go @@ -0,0 +1,77 @@ +package altda + +import ( + "context" + "math/big" + "testing" + "time" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-batcher/flags" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/stretchr/testify/require" +) + +func TestBatcherConcurrentAltDARequests(t *testing.T) { + op_e2e.InitParallel(t) + + numL1TxsExpected := int64(10) + + cfg := e2esys.DefaultSystemConfig(t) + cfg.DeployConfig.UseAltDA = true + cfg.BatcherMaxPendingTransactions = 0 // no limit on parallel txs + // ensures that batcher txs are as small as possible + cfg.BatcherMaxL1TxSizeBytes = derive.FrameV0OverHeadSize + 1 /*version bytes*/ + 1 + cfg.BatcherBatchType = 0 + cfg.DataAvailabilityType = flags.CalldataType + cfg.BatcherMaxConcurrentDARequest = uint64(numL1TxsExpected) + + // disable batcher because we start it manually below + cfg.DisableBatcher = true + sys, err := cfg.Start(t) + require.NoError(t, err, "Error starting up system") + defer sys.Close() + + // make every request take 5 seconds, such that only concurrent requests will be able to make progress fast enough + sys.FakeAltDAServer.SetPutRequestLatency(5 * time.Second) + + l1Client := sys.NodeClient("l1") + l2Seq := sys.NodeClient("sequencer") + + // we wait for numL1TxsExpected L2 blocks to have been produced, just to make sure the sequencer is working properly + _, err = geth.WaitForBlock(big.NewInt(numL1TxsExpected), l2Seq, time.Duration(cfg.DeployConfig.L2BlockTime*uint64(numL1TxsExpected))*time.Second) + require.NoError(t, err, "Waiting for L2 blocks") + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + startingL1BlockNum, err := l1Client.BlockNumber(ctx) + require.NoError(t, err) + + // start batch submission + driver := sys.BatchSubmitter.TestDriver() + err = driver.StartBatchSubmitting() + require.NoError(t, err) + + totalBatcherTxsCount := int64(0) + // wait for up to 5 L1 blocks, expecting 10 L2 batcher txs in them. + // usually only 3 is required, but it's possible additional L1 blocks will be created + // before the batcher starts, so we wait additional blocks. + for i := int64(0); i < 5; i++ { + block, err := geth.WaitForBlock(big.NewInt(int64(startingL1BlockNum)+i), l1Client, time.Duration(cfg.DeployConfig.L1BlockTime*2)*time.Second) + require.NoError(t, err, "Waiting for l1 blocks") + // there are possibly other services (proposer/challenger) in the background sending txs + // so we only count the batcher txs + batcherTxCount, err := transactions.TransactionsBySender(block, cfg.DeployConfig.BatchSenderAddress) + require.NoError(t, err) + totalBatcherTxsCount += int64(batcherTxCount) + + if totalBatcherTxsCount >= numL1TxsExpected { + return + } + } + + t.Fatal("Expected at least 10 transactions from the batcher") +} diff --git a/op-e2e/bridge_test.go b/op-e2e/system/bridge/bridge_test.go similarity index 94% rename from op-e2e/bridge_test.go rename to op-e2e/system/bridge/bridge_test.go index 2846e3218688..655cf612c9ad 100644 --- a/op-e2e/bridge_test.go +++ b/op-e2e/system/bridge/bridge_test.go @@ -1,4 +1,4 @@ -package op_e2e +package bridge import ( "context" @@ -6,6 +6,10 @@ import ( "math/big" "testing" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-e2e/bindings" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/receipts" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions" @@ -20,12 +24,16 @@ import ( "github.com/stretchr/testify/require" ) +func TestMain(m *testing.M) { + op_e2e.RunMain(m) +} + // TestERC20BridgeDeposits tests the the L1StandardBridge bridge ERC20 // functionality. func TestERC20BridgeDeposits(t *testing.T) { - InitParallel(t) + op_e2e.InitParallel(t) - cfg := DefaultSystemConfig(t) + cfg := e2esys.DefaultSystemConfig(t) sys, err := cfg.Start(t) require.Nil(t, err, "Error starting up system") diff --git a/op-e2e/deposit_test.go b/op-e2e/system/bridge/deposit_test.go similarity index 88% rename from op-e2e/deposit_test.go rename to op-e2e/system/bridge/deposit_test.go index c36d8aa44584..d01e9b3f3be9 100644 --- a/op-e2e/deposit_test.go +++ b/op-e2e/system/bridge/deposit_test.go @@ -1,4 +1,4 @@ -package op_e2e +package bridge import ( "context" @@ -6,6 +6,11 @@ import ( "testing" "time" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -16,8 +21,8 @@ import ( ) func TestMintOnRevertedDeposit(t *testing.T) { - InitParallel(t) - cfg := DefaultSystemConfig(t) + op_e2e.InitParallel(t) + cfg := e2esys.DefaultSystemConfig(t) delete(cfg.Nodes, "verifier") sys, err := cfg.Start(t) require.NoError(t, err, "Error starting up system") @@ -44,7 +49,7 @@ func TestMintOnRevertedDeposit(t *testing.T) { toAddr := common.Address{0xff, 0xff} mintAmount := big.NewInt(9_000_000) opts.Value = mintAmount - SendDepositTx(t, cfg, l1Client, l2Verif, opts, func(l2Opts *DepositTxOpts) { + helpers.SendDepositTx(t, cfg, l1Client, l2Verif, opts, func(l2Opts *helpers.DepositTxOpts) { l2Opts.ToAddr = toAddr // trigger a revert by transferring more than we have available l2Opts.Value = new(big.Int).Mul(common.Big2, startBalance) @@ -75,8 +80,8 @@ func TestMintOnRevertedDeposit(t *testing.T) { } func TestDepositTxCreateContract(t *testing.T) { - InitParallel(t) - cfg := DefaultSystemConfig(t) + op_e2e.InitParallel(t) + cfg := e2esys.DefaultSystemConfig(t) delete(cfg.Nodes, "verifier") sys, err := cfg.Start(t) @@ -125,7 +130,7 @@ func TestDepositTxCreateContract(t *testing.T) { deployData := append(deployPrefix, sstoreContract...) - l2Receipt := SendDepositTx(t, cfg, l1Client, l2Client, opts, func(l2Opts *DepositTxOpts) { + l2Receipt := helpers.SendDepositTx(t, cfg, l1Client, l2Client, opts, func(l2Opts *helpers.DepositTxOpts) { l2Opts.Data = deployData l2Opts.Value = common.Big0 l2Opts.IsCreation = true diff --git a/op-e2e/system/bridge/rpc_test.go b/op-e2e/system/bridge/rpc_test.go new file mode 100644 index 000000000000..74a243ac2a93 --- /dev/null +++ b/op-e2e/system/bridge/rpc_test.go @@ -0,0 +1,55 @@ +package bridge + +import ( + "context" + "math/big" + "testing" + "time" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/require" +) + +// TestL2SequencerRPCDepositTx checks that the L2 sequencer will not accept DepositTx type transactions. +// The acceptance of these transactions would allow for arbitrary minting of ETH in L2. +func TestL2SequencerRPCDepositTx(t *testing.T) { + op_e2e.InitParallel(t) + + // Create our system configuration for L1/L2 and start it + cfg := e2esys.DefaultSystemConfig(t) + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + + // Obtain our sequencer, verifier, and transactor keypair. + l2Seq := sys.NodeClient("sequencer") + l2Verif := sys.NodeClient("verifier") + txSigningKey := sys.Cfg.Secrets.Alice + require.Nil(t, err) + + // Create a deposit tx to send over RPC. + tx := types.NewTx(&types.DepositTx{ + SourceHash: common.Hash{}, + From: crypto.PubkeyToAddress(txSigningKey.PublicKey), + To: &common.Address{0xff, 0xff}, + Mint: big.NewInt(1000), + Value: big.NewInt(1000), + Gas: 0, + IsSystemTransaction: false, + Data: nil, + }) + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + err = l2Seq.SendTransaction(ctx, tx) + cancel() + require.Error(t, err, "a DepositTx was accepted by L2 sequencer over RPC when it should not have been.") + + ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) + err = l2Verif.SendTransaction(ctx, tx) + cancel() + require.Error(t, err, "a DepositTx was accepted by L2 verifier over RPC when it should not have been.") +} diff --git a/op-e2e/system_tob_test.go b/op-e2e/system/bridge/validity_test.go similarity index 81% rename from op-e2e/system_tob_test.go rename to op-e2e/system/bridge/validity_test.go index 99668d995acf..d79919015951 100644 --- a/op-e2e/system_tob_test.go +++ b/op-e2e/system/bridge/validity_test.go @@ -1,26 +1,28 @@ -package op_e2e +package bridge import ( "bytes" "context" "crypto/ecdsa" "fmt" - "math" "math/big" "math/rand" "testing" "time" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" + "github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain" legacybindings "github.com/ethereum-optimism/optimism/op-e2e/bindings" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-node/bindings" bindingspreview "github.com/ethereum-optimism/optimism/op-node/bindings/preview" - "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/predeploys" "github.com/ethereum-optimism/optimism/op-service/testutils/fuzzerutils" "github.com/ethereum/go-ethereum/accounts" @@ -36,127 +38,6 @@ import ( "github.com/stretchr/testify/require" ) -// TestGasPriceOracleFeeUpdates checks that the gas price oracle cannot be locked by mis-configuring parameters. -func TestGasPriceOracleFeeUpdates(t *testing.T) { - ctx, ctxCancel := context.WithCancel(context.Background()) - defer ctxCancel() - - InitParallel(t) - maxScalars := eth.EcotoneScalars{ - BaseFeeScalar: math.MaxUint32, - BlobBaseFeeScalar: math.MaxUint32, - } - var cancel context.CancelFunc - - // Create our system configuration for L1/L2 and start it - cfg := DefaultSystemConfig(t) - sys, err := cfg.Start(t) - require.NoError(t, err, "Error starting up system") - - // Obtain our sequencer, verifier, and transactor keypair. - l1Client := sys.NodeClient("l1") - l2Seq := sys.NodeClient("sequencer") - // l2Verif := sys.NodeClient("verifier") - ethPrivKey := cfg.Secrets.SysCfgOwner - - // Bind to the SystemConfig & GasPriceOracle contracts - sysconfig, err := legacybindings.NewSystemConfig(cfg.L1Deployments.SystemConfigProxy, l1Client) - require.NoError(t, err) - gpoContract, err := legacybindings.NewGasPriceOracleCaller(predeploys.GasPriceOracleAddr, l2Seq) - require.NoError(t, err) - - // Obtain our signer. - opts, err := bind.NewKeyedTransactorWithChainID(ethPrivKey, cfg.L1ChainIDBig()) - require.NoError(t, err) - - // Define our L1 transaction timeout duration. - txTimeoutDuration := 10 * time.Duration(cfg.DeployConfig.L1BlockTime) * time.Second - - // Update the gas config, wait for it to show up on L2, & verify that it was set as intended - opts.Context, cancel = context.WithTimeout(ctx, txTimeoutDuration) - tx, err := sysconfig.SetGasConfigEcotone(opts, maxScalars.BaseFeeScalar, maxScalars.BlobBaseFeeScalar) - cancel() - require.NoError(t, err, "SetGasConfigEcotone update tx") - - receipt, err := wait.ForReceiptOK(ctx, l1Client, tx.Hash()) - require.NoError(t, err, "Waiting for sysconfig set gas config update tx") - - _, err = geth.WaitForL1OriginOnL2(sys.RollupConfig, receipt.BlockNumber.Uint64(), l2Seq, txTimeoutDuration) - require.NoError(t, err, "waiting for L2 block to include the sysconfig update") - - baseFeeScalar, err := gpoContract.BaseFeeScalar(&bind.CallOpts{}) - require.NoError(t, err, "reading base fee scalar") - require.Equal(t, baseFeeScalar, maxScalars.BaseFeeScalar) - - blobBaseFeeScalar, err := gpoContract.BlobBaseFeeScalar(&bind.CallOpts{}) - require.NoError(t, err, "reading blob base fee scalar") - require.Equal(t, blobBaseFeeScalar, maxScalars.BlobBaseFeeScalar) - - // Now modify the scalar value & ensure that the gas params can be modified - normalScalars := eth.EcotoneScalars{ - BaseFeeScalar: 1e6, - BlobBaseFeeScalar: 1e6, - } - - opts.Context, cancel = context.WithTimeout(context.Background(), txTimeoutDuration) - tx, err = sysconfig.SetGasConfigEcotone(opts, normalScalars.BaseFeeScalar, normalScalars.BlobBaseFeeScalar) - cancel() - require.NoError(t, err, "SetGasConfigEcotone update tx") - - receipt, err = wait.ForReceiptOK(ctx, l1Client, tx.Hash()) - require.NoError(t, err, "Waiting for sysconfig set gas config update tx") - - _, err = geth.WaitForL1OriginOnL2(sys.RollupConfig, receipt.BlockNumber.Uint64(), l2Seq, txTimeoutDuration) - require.NoError(t, err, "waiting for L2 block to include the sysconfig update") - - baseFeeScalar, err = gpoContract.BaseFeeScalar(&bind.CallOpts{}) - require.NoError(t, err, "reading base fee scalar") - require.Equal(t, baseFeeScalar, normalScalars.BaseFeeScalar) - - blobBaseFeeScalar, err = gpoContract.BlobBaseFeeScalar(&bind.CallOpts{}) - require.NoError(t, err, "reading blob base fee scalar") - require.Equal(t, blobBaseFeeScalar, normalScalars.BlobBaseFeeScalar) -} - -// TestL2SequencerRPCDepositTx checks that the L2 sequencer will not accept DepositTx type transactions. -// The acceptance of these transactions would allow for arbitrary minting of ETH in L2. -func TestL2SequencerRPCDepositTx(t *testing.T) { - InitParallel(t) - - // Create our system configuration for L1/L2 and start it - cfg := DefaultSystemConfig(t) - sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") - - // Obtain our sequencer, verifier, and transactor keypair. - l2Seq := sys.NodeClient("sequencer") - l2Verif := sys.NodeClient("verifier") - txSigningKey := sys.Cfg.Secrets.Alice - require.Nil(t, err) - - // Create a deposit tx to send over RPC. - tx := types.NewTx(&types.DepositTx{ - SourceHash: common.Hash{}, - From: crypto.PubkeyToAddress(txSigningKey.PublicKey), - To: &common.Address{0xff, 0xff}, - Mint: big.NewInt(1000), - Value: big.NewInt(1000), - Gas: 0, - IsSystemTransaction: false, - Data: nil, - }) - - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - err = l2Seq.SendTransaction(ctx, tx) - cancel() - require.Error(t, err, "a DepositTx was accepted by L2 sequencer over RPC when it should not have been.") - - ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) - err = l2Verif.SendTransaction(ctx, tx) - cancel() - require.Error(t, err, "a DepositTx was accepted by L2 verifier over RPC when it should not have been.") -} - // TestAccount defines an account generated by startConfigWithTestAccounts type TestAccount struct { HDPath string @@ -169,7 +50,7 @@ type TestAccount struct { // startConfigWithTestAccounts takes a SystemConfig, generates additional accounts, adds them to the config, so they // are funded on startup, starts the system, and imports the keys into the keystore, and obtains transaction opts for // each account. -func startConfigWithTestAccounts(t *testing.T, cfg *SystemConfig, accountsToGenerate int) (*System, []*TestAccount, error) { +func startConfigWithTestAccounts(t *testing.T, cfg *e2esys.SystemConfig, accountsToGenerate int) (*e2esys.System, []*TestAccount, error) { // Create our test accounts and add them to the pre-mine cfg. testAccounts := make([]*TestAccount, 0) var err error @@ -223,7 +104,7 @@ func startConfigWithTestAccounts(t *testing.T, cfg *SystemConfig, accountsToGene // TestMixedDepositValidity makes a number of deposit transactions, some which will succeed in transferring value, // while others do not. It ensures that the expected nonces/balances match after several interactions. func TestMixedDepositValidity(t *testing.T) { - InitParallel(t) + op_e2e.InitParallel(t) // Define how many deposit txs we'll make. Each deposit mints a fixed amount and transfers up to 1/3 of the user's // balance. As such, this number cannot be too high or else the test will always fail due to lack of balance in L1. const depositTxCount = 15 @@ -232,7 +113,7 @@ func TestMixedDepositValidity(t *testing.T) { const accountUsedToDeposit = 5 // Create our system configuration, funding all accounts we created for L1/L2, and start it - cfg := DefaultSystemConfig(t) + cfg := e2esys.DefaultSystemConfig(t) sys, testAccounts, err := startConfigWithTestAccounts(t, &cfg, accountUsedToDeposit) require.Nil(t, err, "Error starting up system") @@ -315,7 +196,7 @@ func TestMixedDepositValidity(t *testing.T) { } else { transferValue = new(big.Int).Mul(common.Big2, transactor.ExpectedL2Balance) // trigger a revert by trying to transfer our current balance * 2 } - SendDepositTx(t, cfg, l1Client, l2Verif, transactor.Account.L1Opts, func(l2Opts *DepositTxOpts) { + helpers.SendDepositTx(t, cfg, l1Client, l2Verif, transactor.Account.L1Opts, func(l2Opts *helpers.DepositTxOpts) { l2Opts.GasLimit = 100_000 l2Opts.IsCreation = false l2Opts.Data = nil @@ -386,7 +267,7 @@ func TestMixedDepositValidity(t *testing.T) { // TestMixedWithdrawalValidity makes a number of withdrawal transactions and ensures ones with modified parameters are // rejected while unmodified ones are accepted. This runs test cases in different systems. func TestMixedWithdrawalValidity(t *testing.T) { - InitParallel(t) + op_e2e.InitParallel(t) // There are 7 different fields we try modifying to cause a failure, plus one "good" test result we test. for i := 0; i <= 8; i++ { @@ -395,10 +276,10 @@ func TestMixedWithdrawalValidity(t *testing.T) { ctx, bgCancel := context.WithCancel(context.Background()) defer bgCancel() - InitParallel(t) + op_e2e.InitParallel(t) // Create our system configuration, funding all accounts we created for L1/L2, and start it - cfg := DefaultSystemConfig(t) + cfg := e2esys.DefaultSystemConfig(t) cfg.Nodes["sequencer"].SafeDBPath = t.TempDir() cfg.DeployConfig.L2BlockTime = 2 require.LessOrEqual(t, cfg.DeployConfig.FinalizationPeriodSeconds, uint64(6)) @@ -529,7 +410,7 @@ func TestMixedWithdrawalValidity(t *testing.T) { require.Nil(t, err) // Calculate gas fees for the withdrawal in L2 to later adjust our balance. - withdrawalL2GasFee := calcGasFees(receipt.GasUsed, tx.GasTipCap(), tx.GasFeeCap(), header.BaseFee) + withdrawalL2GasFee := helpers.CalcGasFees(receipt.GasUsed, tx.GasTipCap(), tx.GasFeeCap(), header.BaseFee) // Adjust our expected L2 balance (should've decreased by withdraw amount + fees) transactor.ExpectedL2Balance = new(big.Int).Sub(transactor.ExpectedL2Balance, withdrawAmount) @@ -557,7 +438,7 @@ func TestMixedWithdrawalValidity(t *testing.T) { blockCl := ethclient.NewClient(rpcClient) // Now create the withdrawal - params, err := ProveWithdrawalParameters(context.Background(), proofCl, receiptCl, blockCl, tx.Hash(), header, l2OutputOracle, disputeGameFactory, optimismPortal2) + params, err := helpers.ProveWithdrawalParameters(context.Background(), proofCl, receiptCl, blockCl, tx.Hash(), header, l2OutputOracle, disputeGameFactory, optimismPortal2) require.Nil(t, err) // Obtain our withdrawal parameters @@ -662,7 +543,7 @@ func TestMixedWithdrawalValidity(t *testing.T) { // Ensure that withdrawal - gas fees are added to the L1 balance // Fun fact, the fee is greater than the withdrawal amount - withdrawalL1GasFee := calcGasFees(receipt.GasUsed, tx.GasTipCap(), tx.GasFeeCap(), header.BaseFee) + withdrawalL1GasFee := helpers.CalcGasFees(receipt.GasUsed, tx.GasTipCap(), tx.GasFeeCap(), header.BaseFee) transactor.ExpectedL1Balance = new(big.Int).Add(transactor.ExpectedL2Balance, withdrawAmount) transactor.ExpectedL1Balance = new(big.Int).Sub(transactor.ExpectedL2Balance, withdrawalL1GasFee) transactor.ExpectedL1Nonce++ diff --git a/op-e2e/withdrawal.go b/op-e2e/system/bridge/withdrawal.go similarity index 88% rename from op-e2e/withdrawal.go rename to op-e2e/system/bridge/withdrawal.go index a5f44434a8ee..29864db02dbf 100644 --- a/op-e2e/withdrawal.go +++ b/op-e2e/system/bridge/withdrawal.go @@ -1,4 +1,4 @@ -package op_e2e +package bridge import ( "context" @@ -7,6 +7,9 @@ import ( "testing" "time" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" @@ -22,7 +25,7 @@ import ( type CommonSystem interface { NodeClient(role string) *ethclient.Client RollupClient(role string) *sources.RollupClient - Config() SystemConfig + Config() e2esys.SystemConfig TestAccount(int) *ecdsa.PrivateKey } @@ -33,9 +36,9 @@ func RunWithdrawalsTest(t *testing.T, sys CommonSystem) { t.Logf("WithdrawalsTest: running with FP == %t", e2eutils.UseFaultProofs()) cfg := sys.Config() - l1Client := sys.NodeClient(RoleL1) - l2Seq := sys.NodeClient(RoleSeq) - l2Verif := sys.NodeClient(RoleVerif) + l1Client := sys.NodeClient(e2esys.RoleL1) + l2Seq := sys.NodeClient(e2esys.RoleSeq) + l2Verif := sys.NodeClient(e2esys.RoleVerif) // Transactor Account ethPrivKey := sys.TestAccount(0) @@ -55,7 +58,7 @@ func RunWithdrawalsTest(t *testing.T, sys CommonSystem) { mintAmount := big.NewInt(1_000_000_000_000) opts.Value = mintAmount t.Logf("WithdrawalsTest: depositing %v with L2 start balance %v...", mintAmount, startBalanceBeforeDeposit) - SendDepositTx(t, cfg, l1Client, l2Verif, opts, func(l2Opts *DepositTxOpts) { + helpers.SendDepositTx(t, cfg, l1Client, l2Verif, opts, func(l2Opts *helpers.DepositTxOpts) { l2Opts.Value = common.Big0 }) t.Log("WithdrawalsTest: waiting for balance change...") @@ -78,7 +81,7 @@ func RunWithdrawalsTest(t *testing.T, sys CommonSystem) { withdrawAmount := big.NewInt(500_000_000_000) t.Logf("WithdrawalsTest: sending L2 withdrawal for %v...", withdrawAmount) - tx, receipt := SendWithdrawal(t, cfg, l2Seq, ethPrivKey, func(opts *WithdrawalTxOpts) { + tx, receipt := helpers.SendWithdrawal(t, cfg, l2Seq, ethPrivKey, func(opts *helpers.WithdrawalTxOpts) { opts.Value = withdrawAmount opts.VerifyOnClients(l2Verif) }) @@ -97,7 +100,7 @@ func RunWithdrawalsTest(t *testing.T, sys CommonSystem) { // Take fee into account diff = new(big.Int).Sub(startBalanceBeforeWithdrawal, endBalanceAfterWithdrawal) - fees := calcGasFees(receipt.GasUsed, tx.GasTipCap(), tx.GasFeeCap(), header.BaseFee) + fees := helpers.CalcGasFees(receipt.GasUsed, tx.GasTipCap(), tx.GasFeeCap(), header.BaseFee) fees = fees.Add(fees, receipt.L1Fee) diff = diff.Sub(diff, fees) require.Equal(t, withdrawAmount, diff) @@ -109,7 +112,7 @@ func RunWithdrawalsTest(t *testing.T, sys CommonSystem) { require.NoError(t, err) t.Log("WithdrawalsTest: ProveAndFinalizeWithdrawal...") - proveReceipt, finalizeReceipt, resolveClaimReceipt, resolveReceipt := ProveAndFinalizeWithdrawal(t, cfg, sys, RoleVerif, ethPrivKey, receipt) + proveReceipt, finalizeReceipt, resolveClaimReceipt, resolveReceipt := helpers.ProveAndFinalizeWithdrawal(t, cfg, sys, e2esys.RoleVerif, ethPrivKey, receipt) // Verify balance after withdrawal ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) diff --git a/op-e2e/system/bridge/withdrawal_test.go b/op-e2e/system/bridge/withdrawal_test.go new file mode 100644 index 000000000000..9f37240cbdbe --- /dev/null +++ b/op-e2e/system/bridge/withdrawal_test.go @@ -0,0 +1,26 @@ +package bridge + +import ( + "testing" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/stretchr/testify/require" +) + +// TestWithdrawals checks that a deposit and then withdrawal execution succeeds. It verifies the +// balance changes on L1 and L2 and has to include gas fees in the balance checks. +// It does not check that the withdrawal can be executed prior to the end of the finality period. +func TestWithdrawals(t *testing.T) { + op_e2e.InitParallel(t) + + cfg := e2esys.DefaultSystemConfig(t) + cfg.DeployConfig.FinalizationPeriodSeconds = 2 // 2s finalization period + cfg.L1FinalizedDistance = 2 // Finalize quick, don't make the proposer wait too long + + sys, err := cfg.Start(t) + require.NoError(t, err, "Error starting up system") + + RunWithdrawalsTest(t, sys) +} diff --git a/op-e2e/system/conductor/conductor_test.go b/op-e2e/system/conductor/conductor_test.go new file mode 100644 index 000000000000..ec4175807f8c --- /dev/null +++ b/op-e2e/system/conductor/conductor_test.go @@ -0,0 +1,11 @@ +package conductor + +import ( + "testing" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" +) + +func TestMain(m *testing.M) { + op_e2e.RunMain(m) +} diff --git a/op-e2e/sequencer_failover_setup.go b/op-e2e/system/conductor/sequencer_failover_setup.go similarity index 95% rename from op-e2e/sequencer_failover_setup.go rename to op-e2e/system/conductor/sequencer_failover_setup.go index 77f8ef442d81..ea515ecc1e64 100644 --- a/op-e2e/sequencer_failover_setup.go +++ b/op-e2e/system/conductor/sequencer_failover_setup.go @@ -1,4 +1,4 @@ -package op_e2e +package conductor import ( "context" @@ -9,6 +9,11 @@ import ( "testing" "time" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rpc" "github.com/stretchr/testify/require" @@ -60,11 +65,11 @@ func (c *conductor) RPCEndpoint() string { return fmt.Sprintf("http://%s:%d", localhost, c.rpcPort) } -func setupSequencerFailoverTest(t *testing.T) (*System, map[string]*conductor, func()) { - InitParallel(t) +func setupSequencerFailoverTest(t *testing.T) (*e2esys.System, map[string]*conductor, func()) { + op_e2e.InitParallel(t) ctx := context.Background() - sys, conductors, err := retry.Do2(ctx, maxSetupRetries, retryStrategy, func() (*System, map[string]*conductor, error) { + sys, conductors, err := retry.Do2(ctx, maxSetupRetries, retryStrategy, func() (*e2esys.System, map[string]*conductor, error) { return setupHAInfra(t, ctx) }) require.NoError(t, err, "Expected to successfully setup sequencers and conductors after retry") @@ -138,10 +143,10 @@ func setupSequencerFailoverTest(t *testing.T) (*System, map[string]*conductor, f } } -func setupHAInfra(t *testing.T, ctx context.Context) (*System, map[string]*conductor, error) { +func setupHAInfra(t *testing.T, ctx context.Context) (*e2esys.System, map[string]*conductor, error) { startTime := time.Now() - var sys *System + var sys *e2esys.System var conductors map[string]*conductor var err error @@ -267,7 +272,7 @@ func setupConductor( }, nil } -func setupBatcher(t *testing.T, sys *System, conductors map[string]*conductor) { +func setupBatcher(t *testing.T, sys *e2esys.System, conductors map[string]*conductor) { // enable active sequencer follow mode. // in sequencer HA, all batcher / proposer requests will be proxied by conductor so that we can make sure // that requests are always handled by leader. @@ -311,8 +316,8 @@ func setupBatcher(t *testing.T, sys *System, conductors map[string]*conductor) { sys.BatchSubmitter = batcher } -func sequencerFailoverSystemConfig(t *testing.T, ports map[string]int) SystemConfig { - cfg := EcotoneSystemConfig(t, &genesisTime) +func sequencerFailoverSystemConfig(t *testing.T, ports map[string]int) e2esys.SystemConfig { + cfg := e2esys.EcotoneSystemConfig(t, new(hexutil.Uint64)) delete(cfg.Nodes, "sequencer") cfg.Nodes[Sequencer1Name] = sequencerCfg(ports[Sequencer1Name]) cfg.Nodes[Sequencer2Name] = sequencerCfg(ports[Sequencer2Name]) @@ -372,7 +377,7 @@ func waitForLeadership(t *testing.T, c *conductor) error { return wait.For(ctx, 1*time.Second, condition) } -func waitForLeadershipChange(t *testing.T, prev *conductor, prevID string, conductors map[string]*conductor, sys *System) string { +func waitForLeadershipChange(t *testing.T, prev *conductor, prevID string, conductors map[string]*conductor, sys *e2esys.System) string { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() @@ -486,7 +491,7 @@ func findFollower(t *testing.T, conductors map[string]*conductor) (string, *cond return "", nil } -func ensureOnlyOneLeader(t *testing.T, sys *System, conductors map[string]*conductor) { +func ensureOnlyOneLeader(t *testing.T, sys *e2esys.System, conductors map[string]*conductor) { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() diff --git a/op-e2e/sequencer_failover_test.go b/op-e2e/system/conductor/sequencer_failover_test.go similarity index 99% rename from op-e2e/sequencer_failover_test.go rename to op-e2e/system/conductor/sequencer_failover_test.go index c153832b9f76..1b49b989654f 100644 --- a/op-e2e/sequencer_failover_test.go +++ b/op-e2e/system/conductor/sequencer_failover_test.go @@ -1,4 +1,4 @@ -package op_e2e +package conductor import ( "context" diff --git a/op-e2e/system_adminrpc_test.go b/op-e2e/system/conductor/system_adminrpc_test.go similarity index 90% rename from op-e2e/system_adminrpc_test.go rename to op-e2e/system/conductor/system_adminrpc_test.go index aabae9d6047b..5501ece79fff 100644 --- a/op-e2e/system_adminrpc_test.go +++ b/op-e2e/system/conductor/system_adminrpc_test.go @@ -1,4 +1,4 @@ -package op_e2e +package conductor import ( "context" @@ -6,6 +6,11 @@ import ( "testing" "time" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/rpc" "github.com/stretchr/testify/require" @@ -18,9 +23,9 @@ import ( ) func TestStopStartSequencer(t *testing.T) { - InitParallel(t) + op_e2e.InitParallel(t) - cfg := DefaultSystemConfig(t) + cfg := e2esys.DefaultSystemConfig(t) sys, err := cfg.Start(t) require.Nil(t, err, "Error starting up system") @@ -74,13 +79,21 @@ func TestStopStartSequencer(t *testing.T) { ) } +func latestBlock(t *testing.T, client *ethclient.Client) uint64 { + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + blockAfter, err := client.BlockNumber(ctx) + require.Nil(t, err, "Error getting latest block") + return blockAfter +} + func TestPersistSequencerStateWhenChanged(t *testing.T) { - InitParallel(t) + op_e2e.InitParallel(t) ctx := context.Background() dir := t.TempDir() stateFile := dir + "/state.json" - cfg := DefaultSystemConfig(t) + cfg := e2esys.DefaultSystemConfig(t) // We don't need a verifier - just the sequencer is enough delete(cfg.Nodes, "verifier") cfg.Nodes["sequencer"].ConfigPersistence = node.NewConfigPersistence(stateFile) @@ -104,7 +117,7 @@ func TestPersistSequencerStateWhenChanged(t *testing.T) { } func TestLoadSequencerStateOnStarted_Stopped(t *testing.T) { - InitParallel(t) + op_e2e.InitParallel(t) ctx := context.Background() dir := t.TempDir() stateFile := dir + "/state.json" @@ -113,7 +126,7 @@ func TestLoadSequencerStateOnStarted_Stopped(t *testing.T) { configReader := node.NewConfigPersistence(stateFile) require.NoError(t, configReader.SequencerStopped()) - cfg := DefaultSystemConfig(t) + cfg := e2esys.DefaultSystemConfig(t) // We don't need a verifier - just the sequencer is enough delete(cfg.Nodes, "verifier") seqCfg := cfg.Nodes["sequencer"] @@ -136,7 +149,7 @@ func TestLoadSequencerStateOnStarted_Stopped(t *testing.T) { } func TestLoadSequencerStateOnStarted_Started(t *testing.T) { - InitParallel(t) + op_e2e.InitParallel(t) ctx := context.Background() dir := t.TempDir() stateFile := dir + "/state.json" @@ -145,7 +158,7 @@ func TestLoadSequencerStateOnStarted_Started(t *testing.T) { configReader := node.NewConfigPersistence(stateFile) require.NoError(t, configReader.SequencerStarted()) - cfg := DefaultSystemConfig(t) + cfg := e2esys.DefaultSystemConfig(t) // We don't need a verifier - just the sequencer is enough delete(cfg.Nodes, "verifier") seqCfg := cfg.Nodes["sequencer"] @@ -169,10 +182,10 @@ func TestLoadSequencerStateOnStarted_Started(t *testing.T) { } func TestPostUnsafePayload(t *testing.T) { - InitParallel(t) + op_e2e.InitParallel(t) ctx := context.Background() - cfg := DefaultSystemConfig(t) + cfg := e2esys.DefaultSystemConfig(t) cfg.Nodes["verifier"].RPC.EnableAdmin = true cfg.DisableBatcher = true diff --git a/op-e2e/artifactsfs_test.go b/op-e2e/system/contracts/artifactsfs_test.go similarity index 87% rename from op-e2e/artifactsfs_test.go rename to op-e2e/system/contracts/artifactsfs_test.go index 98d23be8e112..a52680a0b2d1 100644 --- a/op-e2e/artifactsfs_test.go +++ b/op-e2e/system/contracts/artifactsfs_test.go @@ -1,9 +1,11 @@ -package op_e2e +package contracts import ( "errors" "testing" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + "github.com/stretchr/testify/require" "github.com/ethereum/go-ethereum/log" @@ -13,9 +15,9 @@ import ( ) func TestArtifacts(t *testing.T) { - InitParallel(t) + op_e2e.InitParallel(t) logger := testlog.Logger(t, log.LevelWarn) // lower this log level to get verbose test dump of all artifacts - af := foundry.OpenArtifactsDir("../packages/contracts-bedrock/forge-artifacts") + af := foundry.OpenArtifactsDir("../../../packages/contracts-bedrock/forge-artifacts") artifacts, err := af.ListArtifacts() require.NoError(t, err) require.NotEmpty(t, artifacts) diff --git a/op-e2e/system/contracts/contracts_test.go b/op-e2e/system/contracts/contracts_test.go new file mode 100644 index 000000000000..da4a081a90ca --- /dev/null +++ b/op-e2e/system/contracts/contracts_test.go @@ -0,0 +1,11 @@ +package contracts + +import ( + "testing" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" +) + +func TestMain(m *testing.M) { + op_e2e.RunMain(m) +} diff --git a/op-e2e/brotli_batcher_test.go b/op-e2e/system/da/brotli_batcher_test.go similarity index 87% rename from op-e2e/brotli_batcher_test.go rename to op-e2e/system/da/brotli_batcher_test.go index ee4a223bf3ea..b44bd5af1623 100644 --- a/op-e2e/brotli_batcher_test.go +++ b/op-e2e/system/da/brotli_batcher_test.go @@ -1,4 +1,4 @@ -package op_e2e +package da import ( "context" @@ -7,6 +7,11 @@ import ( "testing" "time" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" + "github.com/stretchr/testify/require" batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" @@ -19,7 +24,7 @@ import ( "github.com/ethereum/go-ethereum/log" ) -func setupAliceAccount(t *testing.T, cfg SystemConfig, sys *System, ethPrivKey *ecdsa.PrivateKey) { +func setupAliceAccount(t *testing.T, cfg e2esys.SystemConfig, sys *e2esys.System, ethPrivKey *ecdsa.PrivateKey) { l1Client := sys.NodeClient("l1") l2Verif := sys.NodeClient("verifier") @@ -37,7 +42,7 @@ func setupAliceAccount(t *testing.T, cfg SystemConfig, sys *System, ethPrivKey * require.NoError(t, err) mintAmount := big.NewInt(1_000_000_000_000) opts.Value = mintAmount - SendDepositTx(t, cfg, l1Client, l2Verif, opts, func(l2Opts *DepositTxOpts) {}) + helpers.SendDepositTx(t, cfg, l1Client, l2Verif, opts, func(l2Opts *helpers.DepositTxOpts) {}) // Confirm balance ctx, cancel = context.WithTimeout(context.Background(), 15*time.Second) @@ -50,9 +55,9 @@ func setupAliceAccount(t *testing.T, cfg SystemConfig, sys *System, ethPrivKey * } func TestBrotliBatcherFjord(t *testing.T) { - InitParallel(t) + op_e2e.InitParallel(t) - cfg := DefaultSystemConfig(t) + cfg := e2esys.DefaultSystemConfig(t) cfg.DataAvailabilityType = batcherFlags.BlobsType genesisActivation := hexutil.Uint64(0) @@ -62,7 +67,7 @@ func TestBrotliBatcherFjord(t *testing.T) { cfg.DeployConfig.L2GenesisFjordTimeOffset = &genesisActivation // set up batcher to use brotli - sys, err := cfg.Start(t, SystemConfigOption{"compressionAlgo", "brotli", nil}) + sys, err := cfg.Start(t, e2esys.SystemConfigOption{Key: "compressionAlgo", Role: "brotli", Action: nil}) require.Nil(t, err, "Error starting up system") log := testlog.Logger(t, log.LevelInfo) @@ -76,7 +81,7 @@ func TestBrotliBatcherFjord(t *testing.T) { setupAliceAccount(t, cfg, sys, ethPrivKey) // Submit TX to L2 sequencer node - receipt := SendL2Tx(t, cfg, l2Seq, ethPrivKey, func(opts *TxOpts) { + receipt := helpers.SendL2Tx(t, cfg, l2Seq, ethPrivKey, func(opts *helpers.TxOpts) { opts.Value = big.NewInt(1_000_000_000) opts.Nonce = 1 // Already have deposit opts.ToAddr = &common.Address{0xff, 0xff} diff --git a/op-e2e/system/da/da_test.go b/op-e2e/system/da/da_test.go new file mode 100644 index 000000000000..ae5606e8df53 --- /dev/null +++ b/op-e2e/system/da/da_test.go @@ -0,0 +1,11 @@ +package da + +import ( + "testing" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" +) + +func TestMain(m *testing.M) { + op_e2e.RunMain(m) +} diff --git a/op-e2e/system/da/dencun_test.go b/op-e2e/system/da/dencun_test.go new file mode 100644 index 000000000000..4bdaee540c00 --- /dev/null +++ b/op-e2e/system/da/dencun_test.go @@ -0,0 +1,53 @@ +package da + +import ( + "context" + "testing" + "time" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" +) + +// TestSystemE2EDencunAtGenesis tests if L2 finalizes when blobs are present on L1 +func TestSystemE2EDencunAtGenesisWithBlobs(t *testing.T) { + op_e2e.InitParallel(t) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + cfg := e2esys.DefaultSystemConfig(t) + cfg.DeployConfig.L1CancunTimeOffset = new(hexutil.Uint64) + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + + // send a blob-containing txn on l1 + ethPrivKey := sys.Cfg.Secrets.Alice + txData := transactions.CreateEmptyBlobTx(true, sys.Cfg.L1ChainIDBig().Uint64()) + tx := types.MustSignNewTx(ethPrivKey, types.LatestSignerForChainID(cfg.L1ChainIDBig()), txData) + // send blob-containing txn + sendCtx, sendCancel := context.WithTimeout(context.Background(), 15*time.Second) + defer sendCancel() + + l1Client := sys.NodeClient("l1") + err = l1Client.SendTransaction(sendCtx, tx) + require.NoError(t, err, "Sending L1 empty blob tx") + // Wait for transaction on L1 + blockContainsBlob, err := wait.ForReceiptOK(ctx, l1Client, tx.Hash()) + require.Nil(t, err, "Waiting for blob tx on L1") + // end sending blob-containing txns on l1 + l2Client := sys.NodeClient("sequencer") + finalizedBlock, err := geth.WaitForL1OriginOnL2(sys.RollupConfig, blockContainsBlob.BlockNumber.Uint64(), l2Client, 30*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second) + require.Nil(t, err, "Waiting for L1 origin of blob tx on L2") + finalizationTimeout := 30 * time.Duration(cfg.DeployConfig.L1BlockTime) * time.Second + _, err = geth.WaitForBlockToBeSafe(finalizedBlock.Header().Number, l2Client, finalizationTimeout) + require.Nil(t, err, "Waiting for safety of L2 block") +} diff --git a/op-e2e/eip4844_test.go b/op-e2e/system/da/eip4844_test.go similarity index 95% rename from op-e2e/eip4844_test.go rename to op-e2e/system/da/eip4844_test.go index 7069fba72afc..332da11f9d6f 100644 --- a/op-e2e/eip4844_test.go +++ b/op-e2e/system/da/eip4844_test.go @@ -1,4 +1,4 @@ -package op_e2e +package da import ( "context" @@ -7,6 +7,11 @@ import ( "testing" "time" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -38,9 +43,9 @@ func TestSystem4844E2E(t *testing.T) { } func testSystem4844E2E(t *testing.T, multiBlob bool, daType batcherFlags.DataAvailabilityType) { - InitParallel(t) + op_e2e.InitParallel(t) - cfg := EcotoneSystemConfig(t, &genesisTime) + cfg := e2esys.EcotoneSystemConfig(t, new(hexutil.Uint64)) cfg.DataAvailabilityType = daType cfg.BatcherBatchType = derive.SpanBatchType cfg.DeployConfig.L1GenesisBlockBaseFeePerGas = (*hexutil.Big)(big.NewInt(7000)) @@ -62,9 +67,9 @@ func testSystem4844E2E(t *testing.T, multiBlob bool, daType batcherFlags.DataAva // is started, as is required by the function. var jamChan chan error jamCtx, jamCancel := context.WithTimeout(context.Background(), 20*time.Second) - action := SystemConfigOption{ - key: "beforeBatcherStart", - action: func(cfg *SystemConfig, s *System) { + action := e2esys.SystemConfigOption{ + Key: "beforeBatcherStart", + Action: func(cfg *e2esys.SystemConfig, s *e2esys.System) { driver := s.BatchSubmitter.TestDriver() err := driver.JamTxPool(jamCtx) require.NoError(t, err) @@ -108,7 +113,7 @@ func testSystem4844E2E(t *testing.T, multiBlob bool, daType batcherFlags.DataAva require.NoError(t, err) mintAmount := big.NewInt(1_000_000_000_000) opts.Value = mintAmount - SendDepositTx(t, cfg, l1Client, l2Verif, opts, func(l2Opts *DepositTxOpts) {}) + helpers.SendDepositTx(t, cfg, l1Client, l2Verif, opts, func(l2Opts *helpers.DepositTxOpts) {}) // Confirm balance ctx2, cancel2 := context.WithTimeout(context.Background(), 20*time.Second) @@ -120,7 +125,7 @@ func testSystem4844E2E(t *testing.T, multiBlob bool, daType batcherFlags.DataAva require.Equal(t, mintAmount, diff, "Did not get expected balance change") // Submit TX to L2 sequencer node - receipt := SendL2Tx(t, cfg, l2Seq, ethPrivKey, func(opts *TxOpts) { + receipt := helpers.SendL2Tx(t, cfg, l2Seq, ethPrivKey, func(opts *helpers.TxOpts) { opts.Value = big.NewInt(1_000_000_000) opts.Nonce = 1 // Already have deposit opts.ToAddr = &common.Address{0xff, 0xff} @@ -237,9 +242,9 @@ func toIndexedBlobHashes(hs ...common.Hash) []eth.IndexedBlobHash { // We then send a couple of expensive Deposit transactions, which drives up the // gas price. The L1 blob gas limit is set to a low value to speed up this process. func TestBatcherAutoDA(t *testing.T) { - InitParallel(t) + op_e2e.InitParallel(t) - cfg := EcotoneSystemConfig(t, &genesisTime) + cfg := e2esys.EcotoneSystemConfig(t, new(hexutil.Uint64)) cfg.DataAvailabilityType = batcherFlags.AutoType // We set the genesis fee values and block gas limit such that calldata txs are initially cheaper, // but then drive up the base fee over the coming L1 blocks such that blobs become cheaper again. diff --git a/op-e2e/l1_beacon_client_test.go b/op-e2e/system/da/l1_beacon_client_test.go similarity index 93% rename from op-e2e/l1_beacon_client_test.go rename to op-e2e/system/da/l1_beacon_client_test.go index 6d4ffd6207fa..68698a5e3187 100644 --- a/op-e2e/l1_beacon_client_test.go +++ b/op-e2e/system/da/l1_beacon_client_test.go @@ -1,9 +1,11 @@ -package op_e2e +package da import ( "context" "testing" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/fakebeacon" "github.com/ethereum-optimism/optimism/op-service/client" @@ -16,7 +18,7 @@ import ( ) func TestGetVersion(t *testing.T) { - InitParallel(t) + op_e2e.InitParallel(t) l := testlog.Logger(t, log.LevelInfo) @@ -36,7 +38,7 @@ func TestGetVersion(t *testing.T) { } func Test404NotFound(t *testing.T) { - InitParallel(t) + op_e2e.InitParallel(t) l := testlog.Logger(t, log.LevelInfo) diff --git a/op-e2e/system/da/multi_test.go b/op-e2e/system/da/multi_test.go new file mode 100644 index 000000000000..8272930da765 --- /dev/null +++ b/op-e2e/system/da/multi_test.go @@ -0,0 +1,64 @@ +package da + +import ( + "context" + "math/big" + "testing" + "time" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/stretchr/testify/require" +) + +func TestBatcherMultiTx(t *testing.T) { + op_e2e.InitParallel(t) + + cfg := e2esys.DefaultSystemConfig(t) + cfg.BatcherMaxPendingTransactions = 0 // no limit on parallel txs + // ensures that batcher txs are as small as possible + cfg.BatcherMaxL1TxSizeBytes = derive.FrameV0OverHeadSize + 1 /*version bytes*/ + 1 + cfg.DisableBatcher = true + sys, err := cfg.Start(t) + require.NoError(t, err, "Error starting up system") + + l1Client := sys.NodeClient("l1") + l2Seq := sys.NodeClient("sequencer") + + _, err = geth.WaitForBlock(big.NewInt(10), l2Seq, time.Duration(cfg.DeployConfig.L2BlockTime*15)*time.Second) + require.NoError(t, err, "Waiting for L2 blocks") + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + l1Number, err := l1Client.BlockNumber(ctx) + require.NoError(t, err) + + // start batch submission + driver := sys.BatchSubmitter.TestDriver() + err = driver.StartBatchSubmitting() + require.NoError(t, err) + + totalBatcherTxsCount := int64(0) + // wait for up to 5 L1 blocks, usually only 3 is required, but it's + // possible additional L1 blocks will be created before the batcher starts, + // so we wait additional blocks. + for i := int64(0); i < 5; i++ { + block, err := geth.WaitForBlock(big.NewInt(int64(l1Number)+i), l1Client, time.Duration(cfg.DeployConfig.L1BlockTime*2)*time.Second) + require.NoError(t, err, "Waiting for l1 blocks") + // there are possibly other services (proposer/challenger) in the background sending txs + // so we only count the batcher txs + batcherTxCount, err := transactions.TransactionsBySender(block, cfg.DeployConfig.BatchSenderAddress) + require.NoError(t, err) + totalBatcherTxsCount += int64(batcherTxCount) + + if totalBatcherTxsCount >= 10 { + return + } + } + + t.Fatal("Expected at least 10 transactions from the batcher") +} diff --git a/op-e2e/system/da/startstop_test.go b/op-e2e/system/da/startstop_test.go new file mode 100644 index 000000000000..c15c1c039438 --- /dev/null +++ b/op-e2e/system/da/startstop_test.go @@ -0,0 +1,131 @@ +package da + +import ( + "context" + "math/big" + "testing" + "time" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" +) + +// TestSystemBatchType run each system e2e test case in singular batch mode and span batch mode. +// If the test case tests batch submission and advancing safe head, it should be tested in both singular and span batch mode. +func TestSystemBatchType(t *testing.T) { + tests := []struct { + name string + f func(*testing.T, func(*e2esys.SystemConfig)) + }{ + {"StopStartBatcher", StopStartBatcher}, + } + for _, test := range tests { + test := test + t.Run(test.name+"_SingularBatch", func(t *testing.T) { + test.f(t, func(sc *e2esys.SystemConfig) { + sc.BatcherBatchType = derive.SingularBatchType + }) + }) + t.Run(test.name+"_SpanBatch", func(t *testing.T) { + test.f(t, func(sc *e2esys.SystemConfig) { + sc.BatcherBatchType = derive.SpanBatchType + }) + }) + t.Run(test.name+"_SpanBatchMaxBlocks", func(t *testing.T) { + test.f(t, func(sc *e2esys.SystemConfig) { + sc.BatcherBatchType = derive.SpanBatchType + sc.BatcherMaxBlocksPerSpanBatch = 2 + }) + }) + } +} + +func StopStartBatcher(t *testing.T, cfgMod func(*e2esys.SystemConfig)) { + op_e2e.InitParallel(t) + + cfg := e2esys.DefaultSystemConfig(t) + cfgMod(&cfg) + sys, err := cfg.Start(t) + require.NoError(t, err, "Error starting up system") + + rollupClient := sys.RollupClient("verifier") + + l2Seq := sys.NodeClient("sequencer") + l2Verif := sys.NodeClient("verifier") + + // retrieve the initial sync status + seqStatus, err := rollupClient.SyncStatus(context.Background()) + require.NoError(t, err) + + nonce := uint64(0) + sendTx := func() *types.Receipt { + // Submit TX to L2 sequencer node + receipt := helpers.SendL2Tx(t, cfg, l2Seq, cfg.Secrets.Alice, func(opts *helpers.TxOpts) { + opts.ToAddr = &common.Address{0xff, 0xff} + opts.Value = big.NewInt(1_000_000_000) + opts.Nonce = nonce + }) + nonce++ + return receipt + } + // send a transaction + receipt := sendTx() + + // wait until the block the tx was first included in shows up in the safe chain on the verifier + safeBlockInclusionDuration := time.Duration(6*cfg.DeployConfig.L1BlockTime) * time.Second + _, err = geth.WaitForBlock(receipt.BlockNumber, l2Verif, safeBlockInclusionDuration) + require.NoError(t, err, "Waiting for block on verifier") + require.NoError(t, wait.ForProcessingFullBatch(context.Background(), rollupClient)) + + // ensure the safe chain advances + newSeqStatus, err := rollupClient.SyncStatus(context.Background()) + require.NoError(t, err) + require.Greater(t, newSeqStatus.SafeL2.Number, seqStatus.SafeL2.Number, "Safe chain did not advance") + + driver := sys.BatchSubmitter.TestDriver() + // stop the batch submission + err = driver.StopBatchSubmitting(context.Background()) + require.NoError(t, err) + + // wait for any old safe blocks being submitted / derived + time.Sleep(safeBlockInclusionDuration) + + // get the initial sync status + seqStatus, err = rollupClient.SyncStatus(context.Background()) + require.NoError(t, err) + + // send another tx + sendTx() + time.Sleep(safeBlockInclusionDuration) + + // ensure that the safe chain does not advance while the batcher is stopped + newSeqStatus, err = rollupClient.SyncStatus(context.Background()) + require.NoError(t, err) + require.Equal(t, newSeqStatus.SafeL2.Number, seqStatus.SafeL2.Number, "Safe chain advanced while batcher was stopped") + + // start the batch submission + err = driver.StartBatchSubmitting() + require.NoError(t, err) + time.Sleep(safeBlockInclusionDuration) + + // send a third tx + receipt = sendTx() + + // wait until the block the tx was first included in shows up in the safe chain on the verifier + _, err = geth.WaitForBlock(receipt.BlockNumber, l2Verif, safeBlockInclusionDuration) + require.NoError(t, err, "Waiting for block on verifier") + require.NoError(t, wait.ForProcessingFullBatch(context.Background(), rollupClient)) + + // ensure that the safe chain advances after restarting the batcher + newSeqStatus, err = rollupClient.SyncStatus(context.Background()) + require.NoError(t, err) + require.Greater(t, newSeqStatus.SafeL2.Number, seqStatus.SafeL2.Number, "Safe chain did not advance after batcher was restarted") +} diff --git a/op-e2e/external.go b/op-e2e/system/e2esys/external.go similarity index 99% rename from op-e2e/external.go rename to op-e2e/system/e2esys/external.go index 7b83aef4ff66..cfdc4fcb88cc 100644 --- a/op-e2e/external.go +++ b/op-e2e/system/e2esys/external.go @@ -1,4 +1,4 @@ -package op_e2e +package e2esys import ( "encoding/json" diff --git a/op-e2e/setup.go b/op-e2e/system/e2esys/setup.go similarity index 97% rename from op-e2e/setup.go rename to op-e2e/system/e2esys/setup.go index e53867fefb06..832823c608e3 100644 --- a/op-e2e/setup.go +++ b/op-e2e/system/e2esys/setup.go @@ -1,4 +1,4 @@ -package op_e2e +package e2esys import ( "context" @@ -431,25 +431,25 @@ func (sys *System) Close() { require.NoError(sys.t, combinedErr, "Failed to stop system") } -type systemConfigHook func(sCfg *SystemConfig, s *System) +type SystemConfigHook func(sCfg *SystemConfig, s *System) type SystemConfigOption struct { - key string - role string - action systemConfigHook + Key string + Role string + Action SystemConfigHook } type SystemConfigOptions struct { - opts map[string]systemConfigHook + opts map[string]SystemConfigHook } func NewSystemConfigOptions(_opts []SystemConfigOption) (SystemConfigOptions, error) { - opts := make(map[string]systemConfigHook) + opts := make(map[string]SystemConfigHook) for _, opt := range _opts { - if _, ok := opts[opt.key+":"+opt.role]; ok { - return SystemConfigOptions{}, fmt.Errorf("duplicate option for key %s and role %s", opt.key, opt.role) + if _, ok := opts[opt.Key+":"+opt.Role]; ok { + return SystemConfigOptions{}, fmt.Errorf("duplicate option for key %s and role %s", opt.Key, opt.Role) } - opts[opt.key+":"+opt.role] = opt.action + opts[opt.Key+":"+opt.Role] = opt.Action } return SystemConfigOptions{ @@ -457,7 +457,7 @@ func NewSystemConfigOptions(_opts []SystemConfigOption) (SystemConfigOptions, er }, nil } -func (s *SystemConfigOptions) Get(key, role string) (systemConfigHook, bool) { +func (s *SystemConfigOptions) Get(key, role string) (SystemConfigHook, bool) { v, ok := s.opts[key+":"+role] return v, ok } @@ -643,8 +643,8 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste // TODO: refactor testing to allow use of in-process rpc connections instead // of only websockets (which are required for external eth client tests). for name, nodeCfg := range cfg.Nodes { - configureL1(nodeCfg, sys.EthInstances[RoleL1], sys.L1BeaconEndpoint()) - configureL2(nodeCfg, sys.EthInstances[name], cfg.JWTSecret) + ConfigureL1(nodeCfg, sys.EthInstances[RoleL1], sys.L1BeaconEndpoint()) + ConfigureL2(nodeCfg, sys.EthInstances[name], cfg.JWTSecret) } l1Client := sys.NodeClient(RoleL1) @@ -662,7 +662,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste if p, ok := p2pNodes[name]; ok { return p, nil } - h, err := sys.newMockNetPeer() + h, err := sys.NewMockNetPeer() if err != nil { return nil, fmt.Errorf("failed to init p2p host for node %s", name) } @@ -883,7 +883,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste var blackholeIP6 = net.ParseIP("100::") // mocknet doesn't allow us to add a peerstore without fully creating the peer ourselves -func (sys *System) newMockNetPeer() (host.Host, error) { +func (sys *System) NewMockNetPeer() (host.Host, error) { sk, _, err := ic.GenerateECDSAKeyPair(rand.Reader) if err != nil { return nil, err @@ -940,7 +940,7 @@ func (sys *System) TestAccount(idx int) *ecdsa.PrivateKey { } } -func configureL1(rollupNodeCfg *rollupNode.Config, l1Node services.EthInstance, beaconEndpoint endpoint.RestHTTP) { +func ConfigureL1(rollupNodeCfg *rollupNode.Config, l1Node services.EthInstance, beaconEndpoint endpoint.RestHTTP) { rollupNodeCfg.L1 = &rollupNode.L1EndpointConfig{ L1NodeAddr: endpoint.SelectRPC(EnvRPCPreference(), l1Node.UserRPC()), L1TrustRPC: false, @@ -955,7 +955,7 @@ func configureL1(rollupNodeCfg *rollupNode.Config, l1Node services.EthInstance, } } -func configureL2(rollupNodeCfg *rollupNode.Config, l2Node services.EthInstance, jwtSecret [32]byte) { +func ConfigureL2(rollupNodeCfg *rollupNode.Config, l2Node services.EthInstance, jwtSecret [32]byte) { rollupNodeCfg.L2 = &rollupNode.L2EndpointConfig{ L2EngineAddr: endpoint.SelectRPC(EnvRPCPreference(), l2Node.AuthRPC()), L2EngineJWTSecret: jwtSecret, diff --git a/op-e2e/system/fees/fees_test.go b/op-e2e/system/fees/fees_test.go new file mode 100644 index 000000000000..61590313cbc4 --- /dev/null +++ b/op-e2e/system/fees/fees_test.go @@ -0,0 +1,266 @@ +package fees + +import ( + "context" + "math/big" + "testing" + "time" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/bindings" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" + "github.com/ethereum-optimism/optimism/op-service/predeploys" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rpc" + "github.com/stretchr/testify/require" +) + +func TestMain(m *testing.M) { + op_e2e.RunMain(m) +} + +type stateGetterAdapter struct { + ctx context.Context + t *testing.T + client *ethclient.Client + blockNum *big.Int +} + +func (sga *stateGetterAdapter) GetState(addr common.Address, key common.Hash) common.Hash { + sga.t.Helper() + val, err := sga.client.StorageAt(sga.ctx, addr, key, sga.blockNum) + require.NoError(sga.t, err) + var res common.Hash + copy(res[:], val) + return res +} + +// TestFees checks that L1/L2 fees are handled. +func TestFees(t *testing.T) { + t.Run("pre-regolith", func(t *testing.T) { + op_e2e.InitParallel(t) + cfg := e2esys.RegolithSystemConfig(t, nil) + cfg.DeployConfig.L1GenesisBlockBaseFeePerGas = (*hexutil.Big)(big.NewInt(7)) + + testFees(t, cfg) + }) + t.Run("regolith", func(t *testing.T) { + op_e2e.InitParallel(t) + cfg := e2esys.RegolithSystemConfig(t, new(hexutil.Uint64)) + cfg.DeployConfig.L1GenesisBlockBaseFeePerGas = (*hexutil.Big)(big.NewInt(7)) + + testFees(t, cfg) + }) + t.Run("ecotone", func(t *testing.T) { + op_e2e.InitParallel(t) + cfg := e2esys.EcotoneSystemConfig(t, new(hexutil.Uint64)) + cfg.DeployConfig.L1GenesisBlockBaseFeePerGas = (*hexutil.Big)(big.NewInt(7)) + + testFees(t, cfg) + }) + t.Run("fjord", func(t *testing.T) { + op_e2e.InitParallel(t) + cfg := e2esys.DefaultSystemConfig(t) + cfg.DeployConfig.L1GenesisBlockBaseFeePerGas = (*hexutil.Big)(big.NewInt(7)) + + cfg.DeployConfig.L2GenesisRegolithTimeOffset = new(hexutil.Uint64) + cfg.DeployConfig.L2GenesisCanyonTimeOffset = new(hexutil.Uint64) + cfg.DeployConfig.L2GenesisDeltaTimeOffset = new(hexutil.Uint64) + cfg.DeployConfig.L2GenesisEcotoneTimeOffset = new(hexutil.Uint64) + cfg.DeployConfig.L2GenesisFjordTimeOffset = new(hexutil.Uint64) + testFees(t, cfg) + }) +} + +func testFees(t *testing.T, cfg e2esys.SystemConfig) { + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + + l2Seq := sys.NodeClient("sequencer") + l2Verif := sys.NodeClient("verifier") + l1 := sys.NodeClient("l1") + + // Wait for first block after genesis. The genesis block has zero L1Block values and will throw off the GPO checks + _, err = geth.WaitForBlock(big.NewInt(1), l2Verif, time.Minute) + require.NoError(t, err) + + config := sys.L2Genesis().Config + + sga := &stateGetterAdapter{ + ctx: context.Background(), + t: t, + client: l2Seq, + } + + l1CostFn := types.NewL1CostFunc(config, sga) + + // Transactor Account + ethPrivKey := cfg.Secrets.Alice + fromAddr := crypto.PubkeyToAddress(ethPrivKey.PublicKey) + + require.NotEqual(t, cfg.DeployConfig.L2OutputOracleProposer, fromAddr) + require.NotEqual(t, cfg.DeployConfig.BatchSenderAddress, fromAddr) + + // Find gaspriceoracle contract + gpoContract, err := bindings.NewGasPriceOracle(predeploys.GasPriceOracleAddr, l2Seq) + require.Nil(t, err) + + if !sys.RollupConfig.IsEcotone(sys.L2GenesisCfg.Timestamp) { + overhead, err := gpoContract.Overhead(&bind.CallOpts{}) + require.Nil(t, err, "reading gpo overhead") + require.Equal(t, overhead.Uint64(), cfg.DeployConfig.GasPriceOracleOverhead, "wrong gpo overhead") + + scalar, err := gpoContract.Scalar(&bind.CallOpts{}) + require.Nil(t, err, "reading gpo scalar") + feeScalar := cfg.DeployConfig.FeeScalar() + require.Equal(t, scalar, new(big.Int).SetBytes(feeScalar[:]), "wrong gpo scalar") + } else { + _, err := gpoContract.Overhead(&bind.CallOpts{}) + require.ErrorContains(t, err, "deprecated") + _, err = gpoContract.Scalar(&bind.CallOpts{}) + require.ErrorContains(t, err, "deprecated") + } + + decimals, err := gpoContract.Decimals(&bind.CallOpts{}) + require.Nil(t, err, "reading gpo decimals") + + require.Equal(t, decimals.Uint64(), uint64(6), "wrong gpo decimals") + + // BaseFee Recipient + baseFeeRecipientStartBalance, err := l2Seq.BalanceAt(context.Background(), predeploys.BaseFeeVaultAddr, big.NewInt(rpc.EarliestBlockNumber.Int64())) + require.Nil(t, err) + + // L1Fee Recipient + l1FeeRecipientStartBalance, err := l2Seq.BalanceAt(context.Background(), predeploys.L1FeeVaultAddr, big.NewInt(rpc.EarliestBlockNumber.Int64())) + require.Nil(t, err) + + sequencerFeeVaultStartBalance, err := l2Seq.BalanceAt(context.Background(), predeploys.SequencerFeeVaultAddr, big.NewInt(rpc.EarliestBlockNumber.Int64())) + require.Nil(t, err) + + genesisBlock, err := l2Seq.BlockByNumber(context.Background(), big.NewInt(rpc.EarliestBlockNumber.Int64())) + require.NoError(t, err) + + coinbaseStartBalance, err := l2Seq.BalanceAt(context.Background(), genesisBlock.Coinbase(), big.NewInt(rpc.EarliestBlockNumber.Int64())) + require.NoError(t, err) + + // Simple transfer from signer to random account + startBalance, err := l2Seq.BalanceAt(context.Background(), fromAddr, big.NewInt(rpc.EarliestBlockNumber.Int64())) + require.Nil(t, err) + require.Greater(t, startBalance.Uint64(), big.NewInt(params.Ether).Uint64()) + + transferAmount := big.NewInt(params.Ether) + gasTip := big.NewInt(10) + receipt := helpers.SendL2Tx(t, cfg, l2Seq, ethPrivKey, func(opts *helpers.TxOpts) { + opts.ToAddr = &common.Address{0xff, 0xff} + opts.Value = transferAmount + opts.GasTipCap = gasTip + opts.Gas = 21000 + opts.GasFeeCap = big.NewInt(200) + opts.VerifyOnClients(l2Verif) + }) + + require.Equal(t, receipt.Status, types.ReceiptStatusSuccessful) + + header, err := l2Seq.HeaderByNumber(context.Background(), receipt.BlockNumber) + require.Nil(t, err) + + coinbaseEndBalance, err := l2Seq.BalanceAt(context.Background(), header.Coinbase, header.Number) + require.Nil(t, err) + + endBalance, err := l2Seq.BalanceAt(context.Background(), fromAddr, header.Number) + require.Nil(t, err) + + baseFeeRecipientEndBalance, err := l2Seq.BalanceAt(context.Background(), predeploys.BaseFeeVaultAddr, header.Number) + require.Nil(t, err) + + l1Header, err := l1.HeaderByNumber(context.Background(), nil) + require.Nil(t, err) + + l1FeeRecipientEndBalance, err := l2Seq.BalanceAt(context.Background(), predeploys.L1FeeVaultAddr, header.Number) + require.Nil(t, err) + + sequencerFeeVaultEndBalance, err := l2Seq.BalanceAt(context.Background(), predeploys.SequencerFeeVaultAddr, header.Number) + require.Nil(t, err) + + // Diff fee recipient + coinbase balances + baseFeeRecipientDiff := new(big.Int).Sub(baseFeeRecipientEndBalance, baseFeeRecipientStartBalance) + l1FeeRecipientDiff := new(big.Int).Sub(l1FeeRecipientEndBalance, l1FeeRecipientStartBalance) + sequencerFeeVaultDiff := new(big.Int).Sub(sequencerFeeVaultEndBalance, sequencerFeeVaultStartBalance) + coinbaseDiff := new(big.Int).Sub(coinbaseEndBalance, coinbaseStartBalance) + + // Tally L2 Fee + l2Fee := gasTip.Mul(gasTip, new(big.Int).SetUint64(receipt.GasUsed)) + require.Equal(t, sequencerFeeVaultDiff, coinbaseDiff, "coinbase is always sequencer fee vault") + require.Equal(t, l2Fee, coinbaseDiff, "l2 fee mismatch") + require.Equal(t, l2Fee, sequencerFeeVaultDiff) + + // Tally BaseFee + baseFee := new(big.Int).Mul(header.BaseFee, new(big.Int).SetUint64(receipt.GasUsed)) + require.Equal(t, baseFee, baseFeeRecipientDiff, "base fee mismatch") + + // Tally L1 Fee + tx, _, err := l2Seq.TransactionByHash(context.Background(), receipt.TxHash) + require.NoError(t, err, "Should be able to get transaction") + bytes, err := tx.MarshalBinary() + require.Nil(t, err) + + l1Fee := l1CostFn(tx.RollupCostData(), header.Time) + require.Equalf(t, l1Fee, l1FeeRecipientDiff, "L1 fee mismatch: start balance %v, end balance %v", l1FeeRecipientStartBalance, l1FeeRecipientEndBalance) + + gpoEcotone, err := gpoContract.IsEcotone(nil) + require.NoError(t, err) + require.Equal(t, sys.RollupConfig.IsEcotone(header.Time), gpoEcotone, "GPO and chain must have same ecotone view") + + gpoFjord, err := gpoContract.IsFjord(nil) + require.NoError(t, err) + require.Equal(t, sys.RollupConfig.IsFjord(header.Time), gpoFjord, "GPO and chain must have same fjord view") + + gpoL1Fee, err := gpoContract.GetL1Fee(&bind.CallOpts{}, bytes) + require.Nil(t, err) + + adjustedGPOFee := gpoL1Fee + if sys.RollupConfig.IsFjord(header.Time) { + // The fastlz size of the transaction is 102 bytes + require.Equal(t, uint64(102), tx.RollupCostData().FastLzSize) + // Which results in both the fjord cost function and GPO using the minimum value for the fastlz regression: + // Geth Linear Regression: -42.5856 + 102 * 0.8365 = 42.7374 + // GPO Linear Regression: -42.5856 + 170 * 0.8365 = 99.6194 + // The additional 68 (170 vs. 102) is due to the GPO adding 68 bytes to account for the signature. + require.Greater(t, types.MinTransactionSize.Uint64(), uint64(99)) + // Because of this, we don't need to do any adjustment as the GPO and cost func are both bounded to the minimum value. + // However, if the fastlz regression output is ever larger than the minimum, this will require an adjustment. + } else if sys.RollupConfig.IsRegolith(header.Time) { + // if post-regolith, adjust the GPO fee by removing the overhead it adds because of signature data + artificialGPOOverhead := big.NewInt(68 * 16) // it adds 68 bytes to cover signature and RLP data + l1BaseFee := big.NewInt(7) // we assume the L1 basefee is the minimum, 7 + // in our case we already include that, so we subtract it, to do a 1:1 comparison + adjustedGPOFee = new(big.Int).Sub(gpoL1Fee, new(big.Int).Mul(artificialGPOOverhead, l1BaseFee)) + } + require.Equal(t, l1Fee, adjustedGPOFee, "GPO reports L1 fee mismatch") + + require.Equal(t, receipt.L1Fee, l1Fee, "l1 fee in receipt is correct") + if !sys.RollupConfig.IsEcotone(header.Time) { // FeeScalar receipt attribute is removed as of Ecotone + require.Equal(t, + new(big.Float).Mul( + new(big.Float).SetInt(l1Header.BaseFee), + new(big.Float).Mul(new(big.Float).SetInt(receipt.L1GasUsed), receipt.FeeScalar), + ), + new(big.Float).SetInt(receipt.L1Fee), "fee field in receipt matches gas used times scalar times base fee") + } + + // Calculate total fee + baseFeeRecipientDiff.Add(baseFeeRecipientDiff, coinbaseDiff) + totalFee := new(big.Int).Add(baseFeeRecipientDiff, l1FeeRecipientDiff) + balanceDiff := new(big.Int).Sub(startBalance, endBalance) + balanceDiff.Sub(balanceDiff, transferAmount) + require.Equal(t, balanceDiff, totalFee, "balances should add up") +} diff --git a/op-e2e/system/fees/gaspriceoracle_test.go b/op-e2e/system/fees/gaspriceoracle_test.go new file mode 100644 index 000000000000..58a679fa86f0 --- /dev/null +++ b/op-e2e/system/fees/gaspriceoracle_test.go @@ -0,0 +1,102 @@ +package fees + +import ( + "context" + "math" + "testing" + "time" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + legacybindings "github.com/ethereum-optimism/optimism/op-e2e/bindings" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/predeploys" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/stretchr/testify/require" +) + +// TestGasPriceOracleFeeUpdates checks that the gas price oracle cannot be locked by mis-configuring parameters. +func TestGasPriceOracleFeeUpdates(t *testing.T) { + op_e2e.InitParallel(t) + + ctx, ctxCancel := context.WithCancel(context.Background()) + defer ctxCancel() + + maxScalars := eth.EcotoneScalars{ + BaseFeeScalar: math.MaxUint32, + BlobBaseFeeScalar: math.MaxUint32, + } + var cancel context.CancelFunc + + // Create our system configuration for L1/L2 and start it + cfg := e2esys.DefaultSystemConfig(t) + sys, err := cfg.Start(t) + require.NoError(t, err, "Error starting up system") + + // Obtain our sequencer, verifier, and transactor keypair. + l1Client := sys.NodeClient("l1") + l2Seq := sys.NodeClient("sequencer") + // l2Verif := sys.NodeClient("verifier") + ethPrivKey := cfg.Secrets.SysCfgOwner + + // Bind to the SystemConfig & GasPriceOracle contracts + sysconfig, err := legacybindings.NewSystemConfig(cfg.L1Deployments.SystemConfigProxy, l1Client) + require.NoError(t, err) + gpoContract, err := legacybindings.NewGasPriceOracleCaller(predeploys.GasPriceOracleAddr, l2Seq) + require.NoError(t, err) + + // Obtain our signer. + opts, err := bind.NewKeyedTransactorWithChainID(ethPrivKey, cfg.L1ChainIDBig()) + require.NoError(t, err) + + // Define our L1 transaction timeout duration. + txTimeoutDuration := 10 * time.Duration(cfg.DeployConfig.L1BlockTime) * time.Second + + // Update the gas config, wait for it to show up on L2, & verify that it was set as intended + opts.Context, cancel = context.WithTimeout(ctx, txTimeoutDuration) + tx, err := sysconfig.SetGasConfigEcotone(opts, maxScalars.BaseFeeScalar, maxScalars.BlobBaseFeeScalar) + cancel() + require.NoError(t, err, "SetGasConfigEcotone update tx") + + receipt, err := wait.ForReceiptOK(ctx, l1Client, tx.Hash()) + require.NoError(t, err, "Waiting for sysconfig set gas config update tx") + + _, err = geth.WaitForL1OriginOnL2(sys.RollupConfig, receipt.BlockNumber.Uint64(), l2Seq, txTimeoutDuration) + require.NoError(t, err, "waiting for L2 block to include the sysconfig update") + + baseFeeScalar, err := gpoContract.BaseFeeScalar(&bind.CallOpts{}) + require.NoError(t, err, "reading base fee scalar") + require.Equal(t, baseFeeScalar, maxScalars.BaseFeeScalar) + + blobBaseFeeScalar, err := gpoContract.BlobBaseFeeScalar(&bind.CallOpts{}) + require.NoError(t, err, "reading blob base fee scalar") + require.Equal(t, blobBaseFeeScalar, maxScalars.BlobBaseFeeScalar) + + // Now modify the scalar value & ensure that the gas params can be modified + normalScalars := eth.EcotoneScalars{ + BaseFeeScalar: 1e6, + BlobBaseFeeScalar: 1e6, + } + + opts.Context, cancel = context.WithTimeout(context.Background(), txTimeoutDuration) + tx, err = sysconfig.SetGasConfigEcotone(opts, normalScalars.BaseFeeScalar, normalScalars.BlobBaseFeeScalar) + cancel() + require.NoError(t, err, "SetGasConfigEcotone update tx") + + receipt, err = wait.ForReceiptOK(ctx, l1Client, tx.Hash()) + require.NoError(t, err, "Waiting for sysconfig set gas config update tx") + + _, err = geth.WaitForL1OriginOnL2(sys.RollupConfig, receipt.BlockNumber.Uint64(), l2Seq, txTimeoutDuration) + require.NoError(t, err, "waiting for L2 block to include the sysconfig update") + + baseFeeScalar, err = gpoContract.BaseFeeScalar(&bind.CallOpts{}) + require.NoError(t, err, "reading base fee scalar") + require.Equal(t, baseFeeScalar, normalScalars.BaseFeeScalar) + + blobBaseFeeScalar, err = gpoContract.BlobBaseFeeScalar(&bind.CallOpts{}) + require.NoError(t, err, "reading blob base fee scalar") + require.Equal(t, blobBaseFeeScalar, normalScalars.BlobBaseFeeScalar) +} diff --git a/op-e2e/system/fees/l1info_test.go b/op-e2e/system/fees/l1info_test.go new file mode 100644 index 000000000000..2fdd3f70747a --- /dev/null +++ b/op-e2e/system/fees/l1info_test.go @@ -0,0 +1,205 @@ +package fees + +import ( + "context" + "fmt" + "math/big" + "testing" + "time" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/bindings" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/misc/eip4844" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/stretchr/testify/require" +) + +func L1InfoFromState(ctx context.Context, contract *bindings.L1Block, l2Number *big.Int, ecotone bool) (*derive.L1BlockInfo, error) { + var err error + out := &derive.L1BlockInfo{} + opts := bind.CallOpts{ + BlockNumber: l2Number, + Context: ctx, + } + + out.Number, err = contract.Number(&opts) + if err != nil { + return nil, fmt.Errorf("failed to get number: %w", err) + } + + out.Time, err = contract.Timestamp(&opts) + if err != nil { + return nil, fmt.Errorf("failed to get timestamp: %w", err) + } + + out.BaseFee, err = contract.Basefee(&opts) + if err != nil { + return nil, fmt.Errorf("failed to get base fee: %w", err) + } + + blockHashBytes, err := contract.Hash(&opts) + if err != nil { + return nil, fmt.Errorf("failed to get block hash: %w", err) + } + out.BlockHash = common.BytesToHash(blockHashBytes[:]) + + out.SequenceNumber, err = contract.SequenceNumber(&opts) + if err != nil { + return nil, fmt.Errorf("failed to get sequence number: %w", err) + } + + if !ecotone { + overhead, err := contract.L1FeeOverhead(&opts) + if err != nil { + return nil, fmt.Errorf("failed to get l1 fee overhead: %w", err) + } + out.L1FeeOverhead = eth.Bytes32(common.BigToHash(overhead)) + + scalar, err := contract.L1FeeScalar(&opts) + if err != nil { + return nil, fmt.Errorf("failed to get l1 fee scalar: %w", err) + } + out.L1FeeScalar = eth.Bytes32(common.BigToHash(scalar)) + } + + batcherHash, err := contract.BatcherHash(&opts) + if err != nil { + return nil, fmt.Errorf("failed to get batch sender: %w", err) + } + out.BatcherAddr = common.BytesToAddress(batcherHash[:]) + + if ecotone { + blobBaseFeeScalar, err := contract.BlobBaseFeeScalar(&opts) + if err != nil { + return nil, fmt.Errorf("failed to get blob basefee scalar: %w", err) + } + out.BlobBaseFeeScalar = blobBaseFeeScalar + + baseFeeScalar, err := contract.BaseFeeScalar(&opts) + if err != nil { + return nil, fmt.Errorf("failed to get basefee scalar: %w", err) + } + out.BaseFeeScalar = baseFeeScalar + + blobBaseFee, err := contract.BlobBaseFee(&opts) + if err != nil { + return nil, fmt.Errorf("failed to get blob basefee: %w", err) + } + out.BlobBaseFee = blobBaseFee + } + + return out, nil +} + +func TestL1InfoContract(t *testing.T) { + op_e2e.InitParallel(t) + + cfg := e2esys.DefaultSystemConfig(t) + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + + l1Client := sys.NodeClient("l1") + l2Seq := sys.NodeClient("sequencer") + l2Verif := sys.NodeClient("verifier") + + endVerifBlockNumber := big.NewInt(4) + endSeqBlockNumber := big.NewInt(6) + endVerifBlock, err := geth.WaitForBlock(endVerifBlockNumber, l2Verif, time.Minute) + require.Nil(t, err) + endSeqBlock, err := geth.WaitForBlock(endSeqBlockNumber, l2Seq, time.Minute) + require.Nil(t, err) + + seqL1Info, err := bindings.NewL1Block(cfg.L1InfoPredeployAddress, l2Seq) + require.Nil(t, err) + + verifL1Info, err := bindings.NewL1Block(cfg.L1InfoPredeployAddress, l2Verif) + require.Nil(t, err) + + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + defer cancel() + + fillInfoLists := func(start *types.Block, contract *bindings.L1Block, client *ethclient.Client) ([]*derive.L1BlockInfo, []*derive.L1BlockInfo) { + var txList, stateList []*derive.L1BlockInfo + for b := start; ; { + var infoFromTx *derive.L1BlockInfo + infoFromTx, err := derive.L1BlockInfoFromBytes(sys.RollupConfig, b.Time(), b.Transactions()[0].Data()) + require.NoError(t, err) + txList = append(txList, infoFromTx) + + ecotone := sys.RollupConfig.IsEcotone(b.Time()) && !sys.RollupConfig.IsEcotoneActivationBlock(b.Time()) + infoFromState, err := L1InfoFromState(ctx, contract, b.Number(), ecotone) + require.Nil(t, err) + stateList = append(stateList, infoFromState) + + // Genesis L2 block contains no L1 Deposit TX + if b.NumberU64() == 1 { + return txList, stateList + } + b, err = client.BlockByHash(ctx, b.ParentHash()) + require.Nil(t, err) + } + } + + l1InfosFromSequencerTransactions, l1InfosFromSequencerState := fillInfoLists(endSeqBlock, seqL1Info, l2Seq) + l1InfosFromVerifierTransactions, l1InfosFromVerifierState := fillInfoLists(endVerifBlock, verifL1Info, l2Verif) + + l1blocks := make(map[common.Hash]*derive.L1BlockInfo) + maxL1Hash := l1InfosFromSequencerTransactions[0].BlockHash + for h := maxL1Hash; ; { + b, err := l1Client.BlockByHash(ctx, h) + require.Nil(t, err) + + l1blocks[h] = &derive.L1BlockInfo{ + Number: b.NumberU64(), + Time: b.Time(), + BaseFee: b.BaseFee(), + BlockHash: h, + SequenceNumber: 0, // ignored, will be overwritten + BatcherAddr: sys.RollupConfig.Genesis.SystemConfig.BatcherAddr, + } + if sys.RollupConfig.IsEcotone(b.Time()) && !sys.RollupConfig.IsEcotoneActivationBlock(b.Time()) { + scalars, err := sys.RollupConfig.Genesis.SystemConfig.EcotoneScalars() + require.NoError(t, err) + l1blocks[h].BlobBaseFeeScalar = scalars.BlobBaseFeeScalar + l1blocks[h].BaseFeeScalar = scalars.BaseFeeScalar + if excess := b.ExcessBlobGas(); excess != nil { + l1blocks[h].BlobBaseFee = eip4844.CalcBlobFee(*excess) + } else { + l1blocks[h].BlobBaseFee = big.NewInt(1) + } + } else { + l1blocks[h].L1FeeOverhead = sys.RollupConfig.Genesis.SystemConfig.Overhead + l1blocks[h].L1FeeScalar = sys.RollupConfig.Genesis.SystemConfig.Scalar + } + + h = b.ParentHash() + if b.NumberU64() == 0 { + break + } + } + + checkInfoList := func(name string, list []*derive.L1BlockInfo) { + for _, info := range list { + if expected, ok := l1blocks[info.BlockHash]; ok { + expected.SequenceNumber = info.SequenceNumber // the seq nr is not part of the L1 info we know in advance, so we ignore it. + require.Equal(t, expected, info) + } else { + t.Fatalf("Did not find block hash for L1 Info: %v in test %s", info, name) + } + } + } + + checkInfoList("On sequencer with tx", l1InfosFromSequencerTransactions) + checkInfoList("On sequencer with state", l1InfosFromSequencerState) + checkInfoList("On verifier with tx", l1InfosFromVerifierTransactions) + checkInfoList("On verifier with state", l1InfosFromVerifierState) +} diff --git a/op-e2e/check_scripts_test.go b/op-e2e/system/fjord/check_scripts_test.go similarity index 92% rename from op-e2e/check_scripts_test.go rename to op-e2e/system/fjord/check_scripts_test.go index 151d11fa0197..b6115dbd7e0b 100644 --- a/op-e2e/check_scripts_test.go +++ b/op-e2e/system/fjord/check_scripts_test.go @@ -1,9 +1,13 @@ -package op_e2e +package fjord import ( "context" "testing" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/log" @@ -16,7 +20,7 @@ import ( // TestCheckFjordScript ensures the op-chain-ops/cmd/check-fjord script runs successfully // against a test chain with the fjord hardfork activated/unactivated func TestCheckFjordScript(t *testing.T) { - InitParallel(t) + op_e2e.InitParallel(t) genesisActivation := hexutil.Uint64(0) tests := []struct { name string @@ -37,11 +41,11 @@ func TestCheckFjordScript(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - InitParallel(t) + op_e2e.InitParallel(t) log := testlog.Logger(t, log.LevelInfo) - cfg := DefaultSystemConfig(t) + cfg := e2esys.DefaultSystemConfig(t) cfg.DeployConfig.L1CancunTimeOffset = &genesisActivation cfg.DeployConfig.L2GenesisRegolithTimeOffset = &genesisActivation cfg.DeployConfig.L2GenesisCanyonTimeOffset = &genesisActivation diff --git a/op-e2e/system/fjord/fjord_test.go b/op-e2e/system/fjord/fjord_test.go new file mode 100644 index 000000000000..09e2ca47ddd5 --- /dev/null +++ b/op-e2e/system/fjord/fjord_test.go @@ -0,0 +1,11 @@ +package fjord + +import ( + "testing" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" +) + +func TestMain(m *testing.M) { + op_e2e.RunMain(m) +} diff --git a/op-e2e/custom_gas_token_test.go b/op-e2e/system/gastoken/gastoken_test.go similarity index 96% rename from op-e2e/custom_gas_token_test.go rename to op-e2e/system/gastoken/gastoken_test.go index 454e73439aec..445f672743cf 100644 --- a/op-e2e/custom_gas_token_test.go +++ b/op-e2e/system/gastoken/gastoken_test.go @@ -1,4 +1,4 @@ -package op_e2e +package gastoken import ( "context" @@ -7,6 +7,11 @@ import ( "testing" "time" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" + "github.com/ethereum-optimism/optimism/op-e2e/bindings" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/receipts" @@ -22,10 +27,14 @@ import ( "github.com/stretchr/testify/require" ) +func TestMain(m *testing.M) { + op_e2e.RunMain(m) +} + func TestCustomGasToken(t *testing.T) { - InitParallel(t, SkipOnFaultProofs) // Custom Gas Token feature is not yet compatible with fault proofs + op_e2e.InitParallel(t, op_e2e.SkipOnFaultProofs) // Custom Gas Token feature is not yet compatible with fault proofs - cfg := DefaultSystemConfig(t) + cfg := e2esys.DefaultSystemConfig(t) offset := hexutil.Uint64(0) cfg.DeployConfig.L2GenesisRegolithTimeOffset = &offset cfg.DeployConfig.L1CancunTimeOffset = &offset @@ -143,7 +152,7 @@ func TestCustomGasToken(t *testing.T) { require.NoError(t, err) withdrawAmount := big.NewInt(5) - tx, receipt := SendWithdrawal(t, cfg, l2Seq, cfg.Secrets.Alice, func(opts *WithdrawalTxOpts) { + tx, receipt := helpers.SendWithdrawal(t, cfg, l2Seq, cfg.Secrets.Alice, func(opts *helpers.WithdrawalTxOpts) { opts.Value = withdrawAmount opts.VerifyOnClients(l2Verif) }) @@ -157,7 +166,7 @@ func TestCustomGasToken(t *testing.T) { // Take fee into account diff := new(big.Int).Sub(startBalanceBeforeWithdrawal, endBalanceAfterWithdrawal) - fees := calcGasFees(receipt.GasUsed, tx.GasTipCap(), tx.GasFeeCap(), header.BaseFee) + fees := helpers.CalcGasFees(receipt.GasUsed, tx.GasTipCap(), tx.GasFeeCap(), header.BaseFee) fees = fees.Add(fees, receipt.L1Fee) diff = diff.Sub(diff, fees) require.Equal(t, withdrawAmount, diff) @@ -169,7 +178,7 @@ func TestCustomGasToken(t *testing.T) { startETHBalanceBeforeFinalize, err := l1Client.BalanceAt(context.Background(), fromAddr, nil) require.NoError(t, err) - proveReceipt, finalizeReceipt, resolveClaimReceipt, resolveReceipt := ProveAndFinalizeWithdrawal(t, cfg, sys, "verifier", ethPrivKey, receipt) + proveReceipt, finalizeReceipt, resolveClaimReceipt, resolveReceipt := helpers.ProveAndFinalizeWithdrawal(t, cfg, sys, "verifier", ethPrivKey, receipt) // Verify L1 ETH balance change proveFee := new(big.Int).Mul(new(big.Int).SetUint64(proveReceipt.GasUsed), proveReceipt.EffectiveGasPrice) @@ -318,7 +327,7 @@ func TestCustomGasToken(t *testing.T) { withdrawnAmount := it.Event.Value // Finalize the withdrawal - proveReceipt, finalizeReceipt, resolveClaimReceipt, resolveReceipt := ProveAndFinalizeWithdrawal(t, cfg, sys, "verifier", cfg.Secrets.Alice, receipt) + proveReceipt, finalizeReceipt, resolveClaimReceipt, resolveReceipt := helpers.ProveAndFinalizeWithdrawal(t, cfg, sys, "verifier", cfg.Secrets.Alice, receipt) require.Equal(t, types.ReceiptStatusSuccessful, proveReceipt.Status) require.Equal(t, types.ReceiptStatusSuccessful, finalizeReceipt.Status) if e2eutils.UseFaultProofs() { @@ -462,7 +471,7 @@ func callViaSafe(opts *bind.TransactOpts, client *ethclient.Client, safeAddress // setCustomGasToeken enables the Custom Gas Token feature on a chain where it wasn't enabled at genesis. // It reads existing parameters from the SystemConfig contract, inserts the supplied cgtAddress and reinitializes that contract. // To do this it uses the ProxyAdmin and StorageSetter from the supplied cfg. -func setCustomGasToken(t *testing.T, cfg SystemConfig, sys *System, cgtAddress common.Address) { +func setCustomGasToken(t *testing.T, cfg e2esys.SystemConfig, sys *e2esys.System, cgtAddress common.Address) { l1Client := sys.NodeClient("l1") deployerOpts, err := bind.NewKeyedTransactorWithChainID(cfg.Secrets.Deployer, cfg.L1ChainIDBig()) require.NoError(t, err) diff --git a/op-e2e/tx_helper.go b/op-e2e/system/helpers/tx_helper.go similarity index 91% rename from op-e2e/tx_helper.go rename to op-e2e/system/helpers/tx_helper.go index 86885bb862f9..f5cb11aa8a1d 100644 --- a/op-e2e/tx_helper.go +++ b/op-e2e/system/helpers/tx_helper.go @@ -1,4 +1,4 @@ -package op_e2e +package helpers import ( "context" @@ -7,6 +7,8 @@ import ( "testing" "time" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-e2e/bindings" @@ -24,7 +26,7 @@ import ( // The L2 transaction options can be configured by modifying the DepositTxOps value supplied to applyL2Opts // Will verify that the transaction is included with the expected status on L1 and L2 // Returns the receipt of the L2 transaction -func SendDepositTx(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client, l2Client *ethclient.Client, l1Opts *bind.TransactOpts, applyL2Opts DepositTxOptsFn) *types.Receipt { +func SendDepositTx(t *testing.T, cfg e2esys.SystemConfig, l1Client *ethclient.Client, l2Client *ethclient.Client, l1Opts *bind.TransactOpts, applyL2Opts DepositTxOptsFn) *types.Receipt { l2Opts := defaultDepositTxOpts(l1Opts) applyL2Opts(l2Opts) @@ -115,7 +117,7 @@ func SendL2TxWithID(t *testing.T, chainID *big.Int, l2Client *ethclient.Client, return receipt } -func SendL2Tx(t *testing.T, cfg SystemConfig, l2Client *ethclient.Client, privKey *ecdsa.PrivateKey, applyTxOpts TxOptsFn) *types.Receipt { +func SendL2Tx(t *testing.T, cfg e2esys.SystemConfig, l2Client *ethclient.Client, privKey *ecdsa.PrivateKey, applyTxOpts TxOptsFn) *types.Receipt { return SendL2TxWithID(t, cfg.L2ChainIDBig(), l2Client, privKey, applyTxOpts) } @@ -152,9 +154,9 @@ func defaultTxOpts() *TxOpts { } } -// calcGasFees determines the actual cost of the transaction given a specific base fee +// CalcGasFees determines the actual cost of the transaction given a specific base fee // This does not include the L1 data fee charged from L2 transactions. -func calcGasFees(gasUsed uint64, gasTipCap *big.Int, gasFeeCap *big.Int, baseFee *big.Int) *big.Int { +func CalcGasFees(gasUsed uint64, gasTipCap *big.Int, gasFeeCap *big.Int, baseFee *big.Int) *big.Int { x := new(big.Int).Add(gasTipCap, baseFee) // If tip + basefee > gas fee cap, clamp it to the gas fee cap if x.Cmp(gasFeeCap) > 0 { diff --git a/op-e2e/withdrawal_helper.go b/op-e2e/system/helpers/withdrawal_helper.go similarity index 91% rename from op-e2e/withdrawal_helper.go rename to op-e2e/system/helpers/withdrawal_helper.go index e2d1c5a03fa9..b7d11a63060c 100644 --- a/op-e2e/withdrawal_helper.go +++ b/op-e2e/system/helpers/withdrawal_helper.go @@ -1,4 +1,4 @@ -package op_e2e +package helpers import ( "context" @@ -8,6 +8,8 @@ import ( "testing" "time" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics" @@ -37,7 +39,7 @@ type ClientProvider interface { NodeClient(name string) *ethclient.Client } -func SendWithdrawal(t *testing.T, cfg SystemConfig, l2Client *ethclient.Client, privKey *ecdsa.PrivateKey, applyOpts WithdrawalTxOptsFn) (*types.Transaction, *types.Receipt) { +func SendWithdrawal(t *testing.T, cfg e2esys.SystemConfig, l2Client *ethclient.Client, privKey *ecdsa.PrivateKey, applyOpts WithdrawalTxOptsFn) (*types.Transaction, *types.Receipt) { opts := defaultWithdrawalTxOpts() applyOpts(opts) @@ -94,18 +96,18 @@ func defaultWithdrawalTxOpts() *WithdrawalTxOpts { } } -func ProveAndFinalizeWithdrawal(t *testing.T, cfg SystemConfig, clients ClientProvider, l2NodeName string, ethPrivKey *ecdsa.PrivateKey, l2WithdrawalReceipt *types.Receipt) (*types.Receipt, *types.Receipt, *types.Receipt, *types.Receipt) { +func ProveAndFinalizeWithdrawal(t *testing.T, cfg e2esys.SystemConfig, clients ClientProvider, l2NodeName string, ethPrivKey *ecdsa.PrivateKey, l2WithdrawalReceipt *types.Receipt) (*types.Receipt, *types.Receipt, *types.Receipt, *types.Receipt) { params, proveReceipt := ProveWithdrawal(t, cfg, clients, l2NodeName, ethPrivKey, l2WithdrawalReceipt) finalizeReceipt, resolveClaimReceipt, resolveReceipt := FinalizeWithdrawal(t, cfg, clients.NodeClient("l1"), ethPrivKey, proveReceipt, params) return proveReceipt, finalizeReceipt, resolveClaimReceipt, resolveReceipt } -func ProveWithdrawal(t *testing.T, cfg SystemConfig, clients ClientProvider, l2NodeName string, ethPrivKey *ecdsa.PrivateKey, l2WithdrawalReceipt *types.Receipt) (withdrawals.ProvenWithdrawalParameters, *types.Receipt) { +func ProveWithdrawal(t *testing.T, cfg e2esys.SystemConfig, clients ClientProvider, l2NodeName string, ethPrivKey *ecdsa.PrivateKey, l2WithdrawalReceipt *types.Receipt) (withdrawals.ProvenWithdrawalParameters, *types.Receipt) { // Get l2BlockNumber for proof generation ctx, cancel := context.WithTimeout(context.Background(), 40*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second) defer cancel() - l1Client := clients.NodeClient(RoleL1) + l1Client := clients.NodeClient(e2esys.RoleL1) var blockNumber uint64 var err error if e2eutils.UseFaultProofs() { @@ -176,7 +178,7 @@ func ProveWithdrawalParameters(ctx context.Context, proofCl withdrawals.ProofCli } } -func FinalizeWithdrawal(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client, privKey *ecdsa.PrivateKey, withdrawalProofReceipt *types.Receipt, params withdrawals.ProvenWithdrawalParameters) (*types.Receipt, *types.Receipt, *types.Receipt) { +func FinalizeWithdrawal(t *testing.T, cfg e2esys.SystemConfig, l1Client *ethclient.Client, privKey *ecdsa.PrivateKey, withdrawalProofReceipt *types.Receipt, params withdrawals.ProvenWithdrawalParameters) (*types.Receipt, *types.Receipt, *types.Receipt) { // Wait for finalization and then create the Finalized Withdrawal Transaction ctx, cancel := context.WithTimeout(context.Background(), 30*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second) defer cancel() diff --git a/op-e2e/system/p2p/gossip_test.go b/op-e2e/system/p2p/gossip_test.go new file mode 100644 index 000000000000..6958bdffcf4f --- /dev/null +++ b/op-e2e/system/p2p/gossip_test.go @@ -0,0 +1,203 @@ +package p2p + +import ( + "context" + "math/big" + "slices" + "testing" + "time" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/opnode" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" + rollupNode "github.com/ethereum-optimism/optimism/op-node/node" + "github.com/ethereum-optimism/optimism/op-node/p2p" + "github.com/ethereum-optimism/optimism/op-node/rollup/driver" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/retry" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/stretchr/testify/require" +) + +// TestSystemMockP2P sets up a L1 Geth node, a rollup node, and a L2 geth node and then confirms that +// the nodes can sync L2 blocks before they are confirmed on L1. +func TestSystemMockP2P(t *testing.T) { + op_e2e.InitParallel(t) + + cfg := e2esys.DefaultSystemConfig(t) + // Disable batcher, so we don't sync from L1 & set a large sequence window so we only have unsafe blocks + cfg.DisableBatcher = true + cfg.DeployConfig.SequencerWindowSize = 100_000 + cfg.DeployConfig.MaxSequencerDrift = 100_000 + // disable at the start, so we don't miss any gossiped blocks. + cfg.Nodes["sequencer"].Driver.SequencerStopped = true + + // connect the nodes + cfg.P2PTopology = map[string][]string{ + "verifier": {"sequencer"}, + } + + var published, received []common.Hash + seqTracer, verifTracer := new(opnode.FnTracer), new(opnode.FnTracer) + seqTracer.OnPublishL2PayloadFn = func(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) { + published = append(published, payload.ExecutionPayload.BlockHash) + } + verifTracer.OnUnsafeL2PayloadFn = func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) { + received = append(received, payload.ExecutionPayload.BlockHash) + } + cfg.Nodes["sequencer"].Tracer = seqTracer + cfg.Nodes["verifier"].Tracer = verifTracer + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + + // Enable the sequencer now that everyone is ready to receive payloads. + rollupClient := sys.RollupClient("sequencer") + + verifierPeerID := sys.RollupNodes["verifier"].P2P().Host().ID() + check := func() bool { + sequencerBlocksTopicPeers := sys.RollupNodes["sequencer"].P2P().GossipOut().AllBlockTopicsPeers() + return slices.Contains[[]peer.ID](sequencerBlocksTopicPeers, verifierPeerID) + } + + // poll to see if the verifier node is connected & meshed on gossip. + // Without this verifier, we shouldn't start sending blocks around, or we'll miss them and fail the test. + backOffStrategy := retry.Exponential() + for i := 0; i < 10; i++ { + if check() { + break + } + time.Sleep(backOffStrategy.Duration(i)) + } + require.True(t, check(), "verifier must be meshed with sequencer for gossip test to proceed") + + require.NoError(t, rollupClient.StartSequencer(context.Background(), sys.L2GenesisCfg.ToBlock().Hash())) + + l2Seq := sys.NodeClient("sequencer") + l2Verif := sys.NodeClient("verifier") + + // Transactor Account + ethPrivKey := cfg.Secrets.Alice + + // Submit TX to L2 sequencer node + receiptSeq := helpers.SendL2Tx(t, cfg, l2Seq, ethPrivKey, func(opts *helpers.TxOpts) { + opts.ToAddr = &common.Address{0xff, 0xff} + opts.Value = big.NewInt(1_000_000_000) + + // Wait until the block it was first included in shows up in the safe chain on the verifier + opts.VerifyOnClients(l2Verif) + }) + + // Verify that everything that was received was published + require.GreaterOrEqual(t, len(published), len(received)) + require.Subset(t, published, received) + + // Verify that the tx was received via p2p + require.Contains(t, received, receiptSeq.BlockHash) +} + +// TestSystemDenseTopology sets up a dense p2p topology with 3 verifier nodes and 1 sequencer node. +func TestSystemDenseTopology(t *testing.T) { + t.Skip("Skipping dense topology test to avoid flakiness. @refcell address in p2p scoring pr.") + + op_e2e.InitParallel(t) + + cfg := e2esys.DefaultSystemConfig(t) + // slow down L1 blocks so we can see the L2 blocks arrive well before the L1 blocks do. + // Keep the seq window small so the L2 chain is started quick + cfg.DeployConfig.L1BlockTime = 10 + + // Append additional nodes to the system to construct a dense p2p network + cfg.Nodes["verifier2"] = &rollupNode.Config{ + Driver: driver.Config{ + VerifierConfDepth: 0, + SequencerConfDepth: 0, + SequencerEnabled: false, + }, + L1EpochPollInterval: time.Second * 4, + } + cfg.Nodes["verifier3"] = &rollupNode.Config{ + Driver: driver.Config{ + VerifierConfDepth: 0, + SequencerConfDepth: 0, + SequencerEnabled: false, + }, + L1EpochPollInterval: time.Second * 4, + } + cfg.Loggers["verifier2"] = testlog.Logger(t, log.LevelInfo).New("role", "verifier") + cfg.Loggers["verifier3"] = testlog.Logger(t, log.LevelInfo).New("role", "verifier") + + // connect the nodes + cfg.P2PTopology = map[string][]string{ + "verifier": {"sequencer", "verifier2", "verifier3"}, + "verifier2": {"sequencer", "verifier", "verifier3"}, + "verifier3": {"sequencer", "verifier", "verifier2"}, + } + + // Set peer scoring for each node, but without banning + for _, node := range cfg.Nodes { + params, err := p2p.GetScoringParams("light", &node.Rollup) + require.NoError(t, err) + node.P2P = &p2p.Config{ + ScoringParams: params, + BanningEnabled: false, + } + } + + var published, received1, received2, received3 []common.Hash + seqTracer, verifTracer, verifTracer2, verifTracer3 := new(opnode.FnTracer), new(opnode.FnTracer), new(opnode.FnTracer), new(opnode.FnTracer) + seqTracer.OnPublishL2PayloadFn = func(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) { + published = append(published, payload.ExecutionPayload.BlockHash) + } + verifTracer.OnUnsafeL2PayloadFn = func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) { + received1 = append(received1, payload.ExecutionPayload.BlockHash) + } + verifTracer2.OnUnsafeL2PayloadFn = func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) { + received2 = append(received2, payload.ExecutionPayload.BlockHash) + } + verifTracer3.OnUnsafeL2PayloadFn = func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) { + received3 = append(received3, payload.ExecutionPayload.BlockHash) + } + cfg.Nodes["sequencer"].Tracer = seqTracer + cfg.Nodes["verifier"].Tracer = verifTracer + cfg.Nodes["verifier2"].Tracer = verifTracer2 + cfg.Nodes["verifier3"].Tracer = verifTracer3 + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + + l2Seq := sys.NodeClient("sequencer") + l2Verif := sys.NodeClient("verifier") + l2Verif2 := sys.NodeClient("verifier2") + l2Verif3 := sys.NodeClient("verifier3") + + // Transactor Account + ethPrivKey := cfg.Secrets.Alice + + // Submit TX to L2 sequencer node + receiptSeq := helpers.SendL2Tx(t, cfg, l2Seq, ethPrivKey, func(opts *helpers.TxOpts) { + opts.ToAddr = &common.Address{0xff, 0xff} + opts.Value = big.NewInt(1_000_000_000) + + // Wait until the block it was first included in shows up in the safe chain on the verifiers + opts.VerifyOnClients(l2Verif, l2Verif2, l2Verif3) + }) + + // Verify that everything that was received was published + require.GreaterOrEqual(t, len(published), len(received1)) + require.GreaterOrEqual(t, len(published), len(received2)) + require.GreaterOrEqual(t, len(published), len(received3)) + require.ElementsMatch(t, published, received1[:len(published)]) + require.ElementsMatch(t, published, received2[:len(published)]) + require.ElementsMatch(t, published, received3[:len(published)]) + + // Verify that the tx was received via p2p + require.Contains(t, received1, receiptSeq.BlockHash) + require.Contains(t, received2, receiptSeq.BlockHash) + require.Contains(t, received3, receiptSeq.BlockHash) +} diff --git a/op-e2e/system/p2p/p2p_test.go b/op-e2e/system/p2p/p2p_test.go new file mode 100644 index 000000000000..e7aa7b0b9b73 --- /dev/null +++ b/op-e2e/system/p2p/p2p_test.go @@ -0,0 +1,11 @@ +package p2p + +import ( + "testing" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" +) + +func TestMain(m *testing.M) { + op_e2e.RunMain(m) +} diff --git a/op-e2e/system/p2p/reqresp_test.go b/op-e2e/system/p2p/reqresp_test.go new file mode 100644 index 000000000000..d3245d8fd257 --- /dev/null +++ b/op-e2e/system/p2p/reqresp_test.go @@ -0,0 +1,168 @@ +package p2p + +import ( + "context" + "math/big" + "testing" + "time" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/opnode" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" + "github.com/ethereum-optimism/optimism/op-node/metrics" + rollupNode "github.com/ethereum-optimism/optimism/op-node/node" + "github.com/ethereum-optimism/optimism/op-node/p2p" + "github.com/ethereum-optimism/optimism/op-node/rollup/driver" + "github.com/ethereum-optimism/optimism/op-service/endpoint" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/oppprof" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/stretchr/testify/require" +) + +func TestSystemP2PAltSync(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + op_e2e.InitParallel(t) + + cfg := e2esys.DefaultSystemConfig(t) + + // remove default verifier node + delete(cfg.Nodes, "verifier") + // Add more verifier nodes + cfg.Nodes["alice"] = &rollupNode.Config{ + Driver: driver.Config{ + VerifierConfDepth: 0, + SequencerConfDepth: 0, + SequencerEnabled: false, + }, + L1EpochPollInterval: time.Second * 4, + } + cfg.Nodes["bob"] = &rollupNode.Config{ + Driver: driver.Config{ + VerifierConfDepth: 0, + SequencerConfDepth: 0, + SequencerEnabled: false, + }, + L1EpochPollInterval: time.Second * 4, + } + cfg.Loggers["alice"] = testlog.Logger(t, log.LevelInfo).New("role", "alice") + cfg.Loggers["bob"] = testlog.Logger(t, log.LevelInfo).New("role", "bob") + + // connect the nodes + cfg.P2PTopology = map[string][]string{ + "sequencer": {"alice", "bob"}, + "alice": {"sequencer", "bob"}, + "bob": {"alice", "sequencer"}, + } + // Enable the P2P req-resp based sync + cfg.P2PReqRespSync = true + + // Disable batcher, so there will not be any L1 data to sync from + cfg.DisableBatcher = true + + var published []string + seqTracer := new(opnode.FnTracer) + // The sequencer still publishes the blocks to the tracer, even if they do not reach the network due to disabled P2P + seqTracer.OnPublishL2PayloadFn = func(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) { + published = append(published, payload.ExecutionPayload.ID().String()) + } + // Blocks are now received via the RPC based alt-sync method + cfg.Nodes["sequencer"].Tracer = seqTracer + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + + l2Seq := sys.NodeClient("sequencer") + + // Transactor Account + ethPrivKey := cfg.Secrets.Alice + + // Submit a TX to L2 sequencer node + receiptSeq := helpers.SendL2Tx(t, cfg, l2Seq, ethPrivKey, func(opts *helpers.TxOpts) { + opts.ToAddr = &common.Address{0xff, 0xff} + opts.Value = big.NewInt(1_000_000_000) + }) + + // Gossip is able to respond to IWANT messages for the duration of heartbeat_time * message_window = 0.5 * 12 = 6 + // Wait till we pass that, and then we'll have missed some blocks that cannot be retrieved in any way from gossip + time.Sleep(time.Second * 10) + + // set up our syncer node, connect it to alice/bob + cfg.Loggers["syncer"] = testlog.Logger(t, log.LevelInfo).New("role", "syncer") + + // Create a peer, and hook up alice and bob + h, err := sys.NewMockNetPeer() + require.NoError(t, err) + _, err = sys.Mocknet.LinkPeers(sys.RollupNodes["alice"].P2P().Host().ID(), h.ID()) + require.NoError(t, err) + _, err = sys.Mocknet.LinkPeers(sys.RollupNodes["bob"].P2P().Host().ID(), h.ID()) + require.NoError(t, err) + + // Configure the new rollup node that'll be syncing + var syncedPayloads []string + syncNodeCfg := &rollupNode.Config{ + Driver: driver.Config{VerifierConfDepth: 0}, + Rollup: *sys.RollupConfig, + P2PSigner: nil, + RPC: rollupNode.RPCConfig{ + ListenAddr: "127.0.0.1", + ListenPort: 0, + EnableAdmin: true, + }, + P2P: &p2p.Prepared{HostP2P: h, EnableReqRespSync: true}, + Metrics: rollupNode.MetricsConfig{Enabled: false}, // no metrics server + Pprof: oppprof.CLIConfig{}, + L1EpochPollInterval: time.Second * 10, + Tracer: &opnode.FnTracer{ + OnUnsafeL2PayloadFn: func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) { + syncedPayloads = append(syncedPayloads, payload.ExecutionPayload.ID().String()) + }, + }, + } + e2esys.ConfigureL1(syncNodeCfg, sys.EthInstances["l1"], sys.L1BeaconEndpoint()) + syncerL2Engine, err := geth.InitL2("syncer", sys.L2GenesisCfg, cfg.JWTFilePath) + require.NoError(t, err) + require.NoError(t, syncerL2Engine.Node.Start()) + + e2esys.ConfigureL2(syncNodeCfg, syncerL2Engine, cfg.JWTSecret) + + syncerNode, err := rollupNode.New(ctx, syncNodeCfg, cfg.Loggers["syncer"], "", metrics.NewMetrics("")) + require.NoError(t, err) + err = syncerNode.Start(ctx) + require.NoError(t, err) + defer func() { + require.NoError(t, syncerNode.Stop(ctx)) + }() + + // connect alice and bob to our new syncer node + _, err = sys.Mocknet.ConnectPeers(sys.RollupNodes["alice"].P2P().Host().ID(), syncerNode.P2P().Host().ID()) + require.NoError(t, err) + _, err = sys.Mocknet.ConnectPeers(sys.RollupNodes["bob"].P2P().Host().ID(), syncerNode.P2P().Host().ID()) + require.NoError(t, err) + + rpc := syncerL2Engine.UserRPC().(endpoint.ClientRPC).ClientRPC() + l2Verif := ethclient.NewClient(rpc) + + // It may take a while to sync, but eventually we should see the sequenced data show up + receiptVerif, err := wait.ForReceiptOK(ctx, l2Verif, receiptSeq.TxHash) + require.Nil(t, err, "Waiting for L2 tx on verifier") + + require.Equal(t, receiptSeq, receiptVerif) + + // Verify that the tx was received via P2P sync + require.Contains(t, syncedPayloads, eth.BlockID{Hash: receiptVerif.BlockHash, Number: receiptVerif.BlockNumber.Uint64()}.String()) + + // Verify that everything that was received was published + require.GreaterOrEqual(t, len(published), len(syncedPayloads)) + require.Subset(t, published, syncedPayloads) +} diff --git a/op-e2e/l2_gossip_test.go b/op-e2e/system/p2p/txpool_test.go similarity index 74% rename from op-e2e/l2_gossip_test.go rename to op-e2e/system/p2p/txpool_test.go index 401b30af3174..dde89ecdefb1 100644 --- a/op-e2e/l2_gossip_test.go +++ b/op-e2e/system/p2p/txpool_test.go @@ -1,18 +1,23 @@ -package op_e2e +package p2p import ( "math/big" "testing" "time" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" ) func TestTxGossip(t *testing.T) { - InitParallel(t) - cfg := DefaultSystemConfig(t) + op_e2e.InitParallel(t) + cfg := e2esys.DefaultSystemConfig(t) gethOpts := []geth.GethOption{ geth.WithP2P(), } @@ -30,7 +35,7 @@ func TestTxGossip(t *testing.T) { require.NoError(t, err) // Send a transaction to the verifier and it should be gossiped to the sequencer and included in a block. - SendL2Tx(t, cfg, verifClient, cfg.Secrets.Alice, func(opts *TxOpts) { + helpers.SendL2Tx(t, cfg, verifClient, cfg.Secrets.Alice, func(opts *helpers.TxOpts) { opts.ToAddr = &common.Address{0xaa} opts.Value = common.Big1 opts.VerifyOnClients(seqClient, verifClient) diff --git a/op-e2e/build_helper.go b/op-e2e/system/proofs/build_helper.go similarity index 86% rename from op-e2e/build_helper.go rename to op-e2e/system/proofs/build_helper.go index b84240135c68..42201279867b 100644 --- a/op-e2e/build_helper.go +++ b/op-e2e/system/proofs/build_helper.go @@ -1,4 +1,4 @@ -package op_e2e +package proofs import ( "context" @@ -16,11 +16,11 @@ func BuildOpProgramClient(t *testing.T) string { ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) defer cancel() cmd := exec.CommandContext(ctx, "make", "op-program-client") - cmd.Dir = "../op-program" + cmd.Dir = "../../../op-program" var out strings.Builder cmd.Stdout = &out cmd.Stderr = &out require.NoErrorf(t, cmd.Run(), "Failed to build op-program-client: %v", &out) t.Log("Built op-program-client successfully") - return "../op-program/bin/op-program-client" + return "../../../op-program/bin/op-program-client" } diff --git a/op-e2e/system/proofs/proofs_test.go b/op-e2e/system/proofs/proofs_test.go new file mode 100644 index 000000000000..6fff52bd465f --- /dev/null +++ b/op-e2e/system/proofs/proofs_test.go @@ -0,0 +1,11 @@ +package proofs + +import ( + "testing" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" +) + +func TestMain(m *testing.M) { + op_e2e.RunMain(m) +} diff --git a/op-e2e/system/proofs/proposer_fp_test.go b/op-e2e/system/proofs/proposer_fp_test.go new file mode 100644 index 000000000000..4916d9d521a0 --- /dev/null +++ b/op-e2e/system/proofs/proposer_fp_test.go @@ -0,0 +1,77 @@ +package proofs + +import ( + "context" + "math/big" + "testing" + "time" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics" + "github.com/ethereum-optimism/optimism/op-e2e/bindings" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestL2OutputSubmitterFaultProofs(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.SkipOnL2OO) + + cfg := e2esys.DefaultSystemConfig(t) + cfg.NonFinalizedProposals = true // speed up the time till we see output proposals + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + + l1Client := sys.NodeClient("l1") + + rollupClient := sys.RollupClient("sequencer") + + disputeGameFactory, err := bindings.NewDisputeGameFactoryCaller(cfg.L1Deployments.DisputeGameFactoryProxy, l1Client) + require.Nil(t, err) + + initialGameCount, err := disputeGameFactory.GameCount(&bind.CallOpts{}) + require.Nil(t, err) + + l2Verif := sys.NodeClient("verifier") + _, err = geth.WaitForBlock(big.NewInt(6), l2Verif, 10*time.Duration(cfg.DeployConfig.L2BlockTime)*time.Second) + require.Nil(t, err) + + timeoutCh := time.After(15 * time.Second) + ticker := time.NewTicker(1 * time.Second) + defer ticker.Stop() + for { + latestGameCount, err := disputeGameFactory.GameCount(&bind.CallOpts{}) + require.Nil(t, err) + + if latestGameCount.Cmp(initialGameCount) > 0 { + caller := batching.NewMultiCaller(l1Client.Client(), batching.DefaultBatchSize) + committedL2Output, err := disputeGameFactory.GameAtIndex(&bind.CallOpts{}, new(big.Int).Sub(latestGameCount, common.Big1)) + require.Nil(t, err) + proxy, err := contracts.NewFaultDisputeGameContract(context.Background(), metrics.NoopContractMetrics, committedL2Output.Proxy, caller) + require.Nil(t, err) + claim, err := proxy.GetClaim(context.Background(), 0) + require.Nil(t, err) + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + _, gameBlockNumber, err := proxy.GetBlockRange(ctx) + require.Nil(t, err) + l2Output, err := rollupClient.OutputAtBlock(ctx, gameBlockNumber) + require.Nil(t, err) + require.EqualValues(t, l2Output.OutputRoot, claim.Value) + break + } + + select { + case <-timeoutCh: + t.Fatalf("State root oracle not updated") + case <-ticker.C: + } + } +} diff --git a/op-e2e/system/proofs/proposer_l2oo_test.go b/op-e2e/system/proofs/proposer_l2oo_test.go new file mode 100644 index 000000000000..3b737e0971b5 --- /dev/null +++ b/op-e2e/system/proofs/proposer_l2oo_test.go @@ -0,0 +1,82 @@ +package proofs + +import ( + "context" + "math/big" + "testing" + "time" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/bindings" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/stretchr/testify/require" +) + +func TestL2OutputSubmitter(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.SkipOnFaultProofs) + + cfg := e2esys.DefaultSystemConfig(t) + cfg.NonFinalizedProposals = true // speed up the time till we see output proposals + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + + l1Client := sys.NodeClient("l1") + + rollupClient := sys.RollupClient("sequencer") + + // OutputOracle is already deployed + l2OutputOracle, err := bindings.NewL2OutputOracleCaller(cfg.L1Deployments.L2OutputOracleProxy, l1Client) + require.Nil(t, err) + + initialOutputBlockNumber, err := l2OutputOracle.LatestBlockNumber(&bind.CallOpts{}) + require.Nil(t, err) + + // Wait until the second output submission from L2. The output submitter submits outputs from the + // unsafe portion of the chain which gets reorged on startup. The sequencer has an out of date view + // when it creates it's first block and uses and old L1 Origin. It then does not submit a batch + // for that block and subsequently reorgs to match what the verifier derives when running the + // reconcillation process. + l2Verif := sys.NodeClient("verifier") + _, err = geth.WaitForBlock(big.NewInt(6), l2Verif, 10*time.Duration(cfg.DeployConfig.L2BlockTime)*time.Second) + require.Nil(t, err) + + // Wait for batch submitter to update L2 output oracle. + timeoutCh := time.After(15 * time.Second) + ticker := time.NewTicker(1 * time.Second) + defer ticker.Stop() + for { + l2ooBlockNumber, err := l2OutputOracle.LatestBlockNumber(&bind.CallOpts{}) + require.Nil(t, err) + + // Wait for the L2 output oracle to have been changed from the initial + // timestamp set in the contract constructor. + if l2ooBlockNumber.Cmp(initialOutputBlockNumber) > 0 { + // Retrieve the l2 output committed at this updated timestamp. + committedL2Output, err := l2OutputOracle.GetL2OutputAfter(&bind.CallOpts{}, l2ooBlockNumber) + require.NotEqual(t, [32]byte{}, committedL2Output.OutputRoot, "Empty L2 Output") + require.Nil(t, err) + + // Fetch the corresponding L2 block and assert the committed L2 + // output matches the block's state root. + // + // NOTE: This assertion will change once the L2 output format is + // finalized. + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + l2Output, err := rollupClient.OutputAtBlock(ctx, l2ooBlockNumber.Uint64()) + require.Nil(t, err) + require.Equal(t, l2Output.OutputRoot[:], committedL2Output.OutputRoot[:]) + break + } + + select { + case <-timeoutCh: + t.Fatalf("State root oracle not updated") + case <-ticker.C: + } + } +} diff --git a/op-e2e/system_fpp_test.go b/op-e2e/system/proofs/system_fpp_test.go similarity index 91% rename from op-e2e/system_fpp_test.go rename to op-e2e/system/proofs/system_fpp_test.go index fab62fce2ce0..8729f2c7055c 100644 --- a/op-e2e/system_fpp_test.go +++ b/op-e2e/system/proofs/system_fpp_test.go @@ -1,4 +1,4 @@ -package op_e2e +package proofs import ( "context" @@ -6,6 +6,11 @@ import ( "testing" "time" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" + "github.com/stretchr/testify/require" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -86,10 +91,10 @@ func applySpanBatchActivation(active bool, dp *genesis.DeployConfig) { // - update the state root via a tx // - run program func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool, spanBatchActivated bool) { - InitParallel(t) + op_e2e.InitParallel(t) ctx := context.Background() - cfg := DefaultSystemConfig(t) + cfg := e2esys.DefaultSystemConfig(t) // We don't need a verifier - just the sequencer is enough delete(cfg.Nodes, "verifier") // Use a small sequencer window size to avoid test timeout while waiting for empty blocks @@ -117,7 +122,7 @@ func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool, spanBatchActi t.Log("Sending transactions to setup existing state, prior to challenged period") aliceKey := cfg.Secrets.Alice - receipt := SendL2Tx(t, cfg, l2Seq, aliceKey, func(opts *TxOpts) { + receipt := helpers.SendL2Tx(t, cfg, l2Seq, aliceKey, func(opts *helpers.TxOpts) { opts.ToAddr = &cfg.Secrets.Addresses().Bob opts.Value = big.NewInt(1_000) }) @@ -163,7 +168,7 @@ func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool, spanBatchActi require.NoError(t, err, "could not start batch submitter") t.Log("Add a transaction to the next batch after sequence of empty blocks") - receipt = SendL2Tx(t, cfg, l2Seq, aliceKey, func(opts *TxOpts) { + receipt = helpers.SendL2Tx(t, cfg, l2Seq, aliceKey, func(opts *helpers.TxOpts) { opts.ToAddr = &cfg.Secrets.Addresses().Bob opts.Value = big.NewInt(1_000) opts.Nonce = 1 @@ -186,10 +191,10 @@ func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool, spanBatchActi } func testVerifyL2OutputRoot(t *testing.T, detached bool, spanBatchActivated bool) { - InitParallel(t) + op_e2e.InitParallel(t) ctx := context.Background() - cfg := DefaultSystemConfig(t) + cfg := e2esys.DefaultSystemConfig(t) // We don't need a verifier - just the sequencer is enough delete(cfg.Nodes, "verifier") applySpanBatchActivation(spanBatchActivated, cfg.DeployConfig) @@ -209,15 +214,15 @@ func testVerifyL2OutputRoot(t *testing.T, detached bool, spanBatchActivated bool aliceKey := cfg.Secrets.Alice opts, err := bind.NewKeyedTransactorWithChainID(aliceKey, cfg.L1ChainIDBig()) require.Nil(t, err) - SendDepositTx(t, cfg, l1Client, l2Seq, opts, func(l2Opts *DepositTxOpts) { + helpers.SendDepositTx(t, cfg, l1Client, l2Seq, opts, func(l2Opts *helpers.DepositTxOpts) { l2Opts.Value = big.NewInt(100_000_000) }) - SendL2Tx(t, cfg, l2Seq, aliceKey, func(opts *TxOpts) { + helpers.SendL2Tx(t, cfg, l2Seq, aliceKey, func(opts *helpers.TxOpts) { opts.ToAddr = &cfg.Secrets.Addresses().Bob opts.Value = big.NewInt(1_000) opts.Nonce = 1 }) - SendWithdrawal(t, cfg, l2Seq, aliceKey, func(opts *WithdrawalTxOpts) { + helpers.SendWithdrawal(t, cfg, l2Seq, aliceKey, func(opts *helpers.WithdrawalTxOpts) { opts.Value = big.NewInt(500) opts.Nonce = 2 }) @@ -231,14 +236,14 @@ func testVerifyL2OutputRoot(t *testing.T, detached bool, spanBatchActivated bool l2OutputRoot := agreedL2Output.OutputRoot t.Log("Sending transactions to modify existing state, within challenged period") - SendDepositTx(t, cfg, l1Client, l2Seq, opts, func(l2Opts *DepositTxOpts) { + helpers.SendDepositTx(t, cfg, l1Client, l2Seq, opts, func(l2Opts *helpers.DepositTxOpts) { l2Opts.Value = big.NewInt(5_000) }) - SendL2Tx(t, cfg, l2Seq, cfg.Secrets.Bob, func(opts *TxOpts) { + helpers.SendL2Tx(t, cfg, l2Seq, cfg.Secrets.Bob, func(opts *helpers.TxOpts) { opts.ToAddr = &cfg.Secrets.Addresses().Alice opts.Value = big.NewInt(100) }) - SendWithdrawal(t, cfg, l2Seq, aliceKey, func(opts *WithdrawalTxOpts) { + helpers.SendWithdrawal(t, cfg, l2Seq, aliceKey, func(opts *helpers.WithdrawalTxOpts) { opts.Value = big.NewInt(100) opts.Nonce = 4 }) @@ -276,7 +281,7 @@ type FaultProofProgramTestScenario struct { } // testFaultProofProgramScenario runs the fault proof program in several contexts, given a test scenario. -func testFaultProofProgramScenario(t *testing.T, ctx context.Context, sys *System, s *FaultProofProgramTestScenario) { +func testFaultProofProgramScenario(t *testing.T, ctx context.Context, sys *e2esys.System, s *FaultProofProgramTestScenario) { preimageDir := t.TempDir() fppConfig := oppconf.NewConfig(sys.RollupConfig, sys.L2GenesisCfg.Config, s.L1Head, s.L2Head, s.L2OutputRoot, common.Hash(s.L2Claim), s.L2ClaimBlockNumber) fppConfig.L1URL = sys.NodeEndpoint("l1").RPC() diff --git a/op-e2e/system/runcfg/p2p_signer_test.go b/op-e2e/system/runcfg/p2p_signer_test.go new file mode 100644 index 000000000000..91ebfb941319 --- /dev/null +++ b/op-e2e/system/runcfg/p2p_signer_test.go @@ -0,0 +1,62 @@ +package runcfg + +import ( + "context" + "fmt" + "testing" + "time" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/bindings" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-service/retry" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestRuntimeConfigReload(t *testing.T) { + op_e2e.InitParallel(t) + + cfg := e2esys.DefaultSystemConfig(t) + // to speed up the test, make it reload the config more often, and do not impose a long conf depth + cfg.Nodes["verifier"].RuntimeConfigReloadInterval = time.Second * 5 + cfg.Nodes["verifier"].Driver.VerifierConfDepth = 1 + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + + initialRuntimeConfig := sys.RollupNodes["verifier"].RuntimeConfig() + + // close the EL node, since we want to block derivation, to solely rely on the reloading mechanism for updates. + sys.EthInstances["verifier"].Close() + + l1 := sys.NodeClient("l1") + + // Change the system-config via L1 + sysCfgContract, err := bindings.NewSystemConfig(cfg.L1Deployments.SystemConfigProxy, l1) + require.NoError(t, err) + newUnsafeBlocksSigner := common.Address{0x12, 0x23, 0x45} + require.NotEqual(t, initialRuntimeConfig.P2PSequencerAddress(), newUnsafeBlocksSigner, "changing to a different address") + opts, err := bind.NewKeyedTransactorWithChainID(cfg.Secrets.SysCfgOwner, cfg.L1ChainIDBig()) + require.Nil(t, err) + // the unsafe signer address is part of the runtime config + tx, err := sysCfgContract.SetUnsafeBlockSigner(opts, newUnsafeBlocksSigner) + require.NoError(t, err) + + // wait for the change to confirm + _, err = wait.ForReceiptOK(context.Background(), l1, tx.Hash()) + require.NoError(t, err) + + // wait for the address to change + _, err = retry.Do(context.Background(), 10, retry.Fixed(time.Second*10), func() (struct{}, error) { + v := sys.RollupNodes["verifier"].RuntimeConfig().P2PSequencerAddress() + if v == newUnsafeBlocksSigner { + return struct{}{}, nil + } + return struct{}{}, fmt.Errorf("no change yet, seeing %s but looking for %s", v, newUnsafeBlocksSigner) + }) + require.NoError(t, err) +} diff --git a/op-e2e/system/runcfg/protocol_versions_test.go b/op-e2e/system/runcfg/protocol_versions_test.go new file mode 100644 index 000000000000..14e056b04435 --- /dev/null +++ b/op-e2e/system/runcfg/protocol_versions_test.go @@ -0,0 +1,141 @@ +package runcfg + +import ( + "context" + "errors" + "fmt" + "math/big" + "testing" + "time" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/bindings" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/endpoint" + "github.com/ethereum-optimism/optimism/op-service/retry" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/params" + "github.com/stretchr/testify/require" +) + +func TestRecommendedProtocolVersionChange(t *testing.T) { + op_e2e.InitParallel(t) + + cfg := e2esys.DefaultSystemConfig(t) + require.NotEqual(t, common.Address{}, cfg.L1Deployments.ProtocolVersions, "need ProtocolVersions contract deployment") + // to speed up the test, make it reload the config more often, and do not impose a long conf depth + cfg.Nodes["verifier"].RuntimeConfigReloadInterval = time.Second * 5 + cfg.Nodes["verifier"].Driver.VerifierConfDepth = 1 + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + + runtimeConfig := sys.RollupNodes["verifier"].RuntimeConfig() + + // Change the superchain-config via L1 + l1 := sys.NodeClient("l1") + + _, build, major, minor, patch, preRelease := params.OPStackSupport.Parse() + newRecommendedProtocolVersion := params.ProtocolVersionV0{Build: build, Major: major + 1, Minor: minor, Patch: patch, PreRelease: preRelease}.Encode() + require.NotEqual(t, runtimeConfig.RecommendedProtocolVersion(), newRecommendedProtocolVersion, "changing to a different protocol version") + + protVersions, err := bindings.NewProtocolVersions(cfg.L1Deployments.ProtocolVersionsProxy, l1) + require.NoError(t, err) + + // ProtocolVersions contract is owned by same key as SystemConfig in devnet + opts, err := bind.NewKeyedTransactorWithChainID(cfg.Secrets.SysCfgOwner, cfg.L1ChainIDBig()) + require.NoError(t, err) + + // Change recommended protocol version + tx, err := protVersions.SetRecommended(opts, new(big.Int).SetBytes(newRecommendedProtocolVersion[:])) + require.NoError(t, err) + + // wait for the change to confirm + _, err = wait.ForReceiptOK(context.Background(), l1, tx.Hash()) + require.NoError(t, err) + + // wait for the recommended protocol version to change + _, err = retry.Do(context.Background(), 10, retry.Fixed(time.Second*10), func() (struct{}, error) { + v := sys.RollupNodes["verifier"].RuntimeConfig().RecommendedProtocolVersion() + if v == newRecommendedProtocolVersion { + return struct{}{}, nil + } + return struct{}{}, fmt.Errorf("no change yet, seeing %s but looking for %s", v, newRecommendedProtocolVersion) + }) + require.NoError(t, err) +} + +func TestRequiredProtocolVersionChangeAndHalt(t *testing.T) { + op_e2e.InitParallel(t) + + cfg := e2esys.DefaultSystemConfig(t) + // to speed up the test, make it reload the config more often, and do not impose a long conf depth + cfg.Nodes["verifier"].RuntimeConfigReloadInterval = time.Second * 5 + cfg.Nodes["verifier"].Driver.VerifierConfDepth = 1 + // configure halt in verifier op-node + cfg.Nodes["verifier"].RollupHalt = "major" + // configure halt in verifier op-geth node + cfg.GethOptions["verifier"] = append(cfg.GethOptions["verifier"], []geth.GethOption{ + func(ethCfg *ethconfig.Config, nodeCfg *node.Config) error { + ethCfg.RollupHaltOnIncompatibleProtocolVersion = "major" + return nil + }, + }...) + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + + runtimeConfig := sys.RollupNodes["verifier"].RuntimeConfig() + + // Change the superchain-config via L1 + l1 := sys.NodeClient("l1") + + _, build, major, minor, patch, preRelease := params.OPStackSupport.Parse() + newRequiredProtocolVersion := params.ProtocolVersionV0{Build: build, Major: major + 1, Minor: minor, Patch: patch, PreRelease: preRelease}.Encode() + require.NotEqual(t, runtimeConfig.RequiredProtocolVersion(), newRequiredProtocolVersion, "changing to a different protocol version") + + protVersions, err := bindings.NewProtocolVersions(cfg.L1Deployments.ProtocolVersionsProxy, l1) + require.NoError(t, err) + + // ProtocolVersions contract is owned by same key as SystemConfig in devnet + opts, err := bind.NewKeyedTransactorWithChainID(cfg.Secrets.SysCfgOwner, cfg.L1ChainIDBig()) + require.NoError(t, err) + + // Change required protocol version + tx, err := protVersions.SetRequired(opts, new(big.Int).SetBytes(newRequiredProtocolVersion[:])) + require.NoError(t, err) + + // wait for the change to confirm + _, err = wait.ForReceiptOK(context.Background(), l1, tx.Hash()) + require.NoError(t, err) + + // wait for the required protocol version to take effect by halting the verifier that opted in, and halting the op-geth node that opted in. + _, err = retry.Do(context.Background(), 10, retry.Fixed(time.Second*10), func() (struct{}, error) { + if !sys.RollupNodes["verifier"].Stopped() { + return struct{}{}, errors.New("verifier rollup node is not closed yet") + } + return struct{}{}, nil + }) + require.NoError(t, err) + t.Log("verified that op-node closed!") + // Checking if the engine is down is not trivial in op-e2e. + // In op-geth we have halting tests covering the Engine API, in op-e2e we instead check if the API stops. + _, err = retry.Do(context.Background(), 10, retry.Fixed(time.Second*10), func() (struct{}, error) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + available := client.IsURLAvailable(ctx, sys.NodeEndpoint("verifier").(endpoint.HttpRPC).HttpRPC()) + if !available && ctx.Err() == nil { // waiting for client to stop responding to RPC requests (slow dials with timeout don't count) + return struct{}{}, nil + } + return struct{}{}, errors.New("verifier EL node is not closed yet") + }) + require.NoError(t, err) + t.Log("verified that op-geth closed!") +} diff --git a/op-e2e/system/runcfg/runcfg_test.go b/op-e2e/system/runcfg/runcfg_test.go new file mode 100644 index 000000000000..62cb75553816 --- /dev/null +++ b/op-e2e/system/runcfg/runcfg_test.go @@ -0,0 +1,11 @@ +package runcfg + +import ( + "testing" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" +) + +func TestMain(m *testing.M) { + op_e2e.RunMain(m) +} diff --git a/op-e2e/system/verifier/basic_test.go b/op-e2e/system/verifier/basic_test.go new file mode 100644 index 000000000000..effe1f412146 --- /dev/null +++ b/op-e2e/system/verifier/basic_test.go @@ -0,0 +1,113 @@ +package verifier + +import ( + "context" + "math/big" + "testing" + "time" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +func TestSystemE2EDencunAtGenesis(t *testing.T) { + op_e2e.InitParallel(t) + + cfg := e2esys.DefaultSystemConfig(t) + cfg.DeployConfig.L1CancunTimeOffset = new(hexutil.Uint64) + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + + runE2ESystemTest(t, sys) + head, err := sys.NodeClient("l1").BlockByNumber(context.Background(), big.NewInt(0)) + require.NoError(t, err) + require.NotNil(t, head.ExcessBlobGas(), "L1 is building dencun blocks since genesis") +} + +// TestSystemE2E sets up a L1 Geth node, a rollup node, and a L2 geth node and then confirms that L1 deposits are reflected on L2. +// All nodes are run in process (but are the full nodes, not mocked or stubbed). +func TestSystemE2E(t *testing.T) { + op_e2e.InitParallel(t) + + cfg := e2esys.DefaultSystemConfig(t) + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + runE2ESystemTest(t, sys) + +} + +func runE2ESystemTest(t *testing.T, sys *e2esys.System) { + log := testlog.Logger(t, log.LevelInfo) + log.Info("genesis", "l2", sys.RollupConfig.Genesis.L2, "l1", sys.RollupConfig.Genesis.L1, "l2_time", sys.RollupConfig.Genesis.L2Time) + + l1Client := sys.NodeClient("l1") + l2Seq := sys.NodeClient("sequencer") + l2Verif := sys.NodeClient("verifier") + + // Transactor Account + ethPrivKey := sys.Cfg.Secrets.Alice + + // Send Transaction & wait for success + fromAddr := sys.Cfg.Secrets.Addresses().Alice + + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + startBalance, err := l2Verif.BalanceAt(ctx, fromAddr, nil) + require.Nil(t, err) + + // Send deposit transaction + opts, err := bind.NewKeyedTransactorWithChainID(ethPrivKey, sys.Cfg.L1ChainIDBig()) + require.Nil(t, err) + mintAmount := big.NewInt(1_000_000_000_000) + opts.Value = mintAmount + helpers.SendDepositTx(t, sys.Cfg, l1Client, l2Verif, opts, func(l2Opts *helpers.DepositTxOpts) {}) + + // Confirm balance + ctx, cancel = context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + + endBalance, err := wait.ForBalanceChange(ctx, l2Verif, fromAddr, startBalance) + require.Nil(t, err) + + diff := new(big.Int) + diff = diff.Sub(endBalance, startBalance) + require.Equal(t, mintAmount, diff, "Did not get expected balance change") + + // Submit TX to L2 sequencer node + receipt := helpers.SendL2Tx(t, sys.Cfg, l2Seq, ethPrivKey, func(opts *helpers.TxOpts) { + opts.Value = big.NewInt(1_000_000_000) + opts.Nonce = 1 // Already have deposit + opts.ToAddr = &common.Address{0xff, 0xff} + opts.VerifyOnClients(l2Verif) + }) + + // Verify blocks match after batch submission on verifiers and sequencers + verifBlock, err := l2Verif.BlockByNumber(context.Background(), receipt.BlockNumber) + require.Nil(t, err) + seqBlock, err := l2Seq.BlockByNumber(context.Background(), receipt.BlockNumber) + require.Nil(t, err) + require.Equal(t, verifBlock.NumberU64(), seqBlock.NumberU64(), "Verifier and sequencer blocks not the same after including a batch tx") + require.Equal(t, verifBlock.ParentHash(), seqBlock.ParentHash(), "Verifier and sequencer blocks parent hashes not the same after including a batch tx") + require.Equal(t, verifBlock.Hash(), seqBlock.Hash(), "Verifier and sequencer blocks not the same after including a batch tx") + + rollupClient := sys.RollupClient("sequencer") + // basic check that sync status works + seqStatus, err := rollupClient.SyncStatus(context.Background()) + require.Nil(t, err) + require.LessOrEqual(t, seqBlock.NumberU64(), seqStatus.UnsafeL2.Number) + // basic check that version endpoint works + seqVersion, err := rollupClient.Version(context.Background()) + require.Nil(t, err) + require.NotEqual(t, "", seqVersion) +} diff --git a/op-e2e/system/verifier/confdepth_test.go b/op-e2e/system/verifier/confdepth_test.go new file mode 100644 index 000000000000..698496c68331 --- /dev/null +++ b/op-e2e/system/verifier/confdepth_test.go @@ -0,0 +1,61 @@ +package verifier + +import ( + "context" + "testing" + "time" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +// TestConfirmationDepth runs the rollup with both sequencer and verifier not immediately processing the tip of the chain. +func TestConfirmationDepth(t *testing.T) { + op_e2e.InitParallel(t) + + cfg := e2esys.DefaultSystemConfig(t) + cfg.DeployConfig.SequencerWindowSize = 4 + cfg.DeployConfig.MaxSequencerDrift = 10 * cfg.DeployConfig.L1BlockTime + seqConfDepth := uint64(2) + verConfDepth := uint64(5) + cfg.Nodes["sequencer"].Driver.SequencerConfDepth = seqConfDepth + cfg.Nodes["sequencer"].Driver.VerifierConfDepth = 0 + cfg.Nodes["verifier"].Driver.VerifierConfDepth = verConfDepth + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + + log := testlog.Logger(t, log.LevelInfo) + log.Info("genesis", "l2", sys.RollupConfig.Genesis.L2, "l1", sys.RollupConfig.Genesis.L1, "l2_time", sys.RollupConfig.Genesis.L2Time) + + l1Client := sys.NodeClient("l1") + l2Seq := sys.NodeClient("sequencer") + l2Verif := sys.NodeClient("verifier") + + // Wait enough time for the sequencer to submit a block with distance from L1 head, submit it, + // and for the slower verifier to read a full sequence window and cover confirmation depth for reading and some margin + <-time.After(time.Duration((cfg.DeployConfig.SequencerWindowSize+verConfDepth+3)*cfg.DeployConfig.L1BlockTime) * time.Second) + + // within a second, get both L1 and L2 verifier and sequencer block heads + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + l1Head, err := l1Client.BlockByNumber(ctx, nil) + require.NoError(t, err) + l2SeqHead, err := l2Seq.BlockByNumber(ctx, nil) + require.NoError(t, err) + l2VerHead, err := l2Verif.BlockByNumber(ctx, nil) + require.NoError(t, err) + + seqInfo, err := derive.L1BlockInfoFromBytes(sys.RollupConfig, l2SeqHead.Time(), l2SeqHead.Transactions()[0].Data()) + require.NoError(t, err) + require.LessOrEqual(t, seqInfo.Number+seqConfDepth, l1Head.NumberU64(), "the seq L2 head block should have an origin older than the L1 head block by at least the sequencer conf depth") + + verInfo, err := derive.L1BlockInfoFromBytes(sys.RollupConfig, l2VerHead.Time(), l2VerHead.Transactions()[0].Data()) + require.NoError(t, err) + require.LessOrEqual(t, verInfo.Number+verConfDepth, l1Head.NumberU64(), "the ver L2 head block should have an origin older than the L1 head block by at least the verifier conf depth") +} diff --git a/op-e2e/system/verifier/finalize_test.go b/op-e2e/system/verifier/finalize_test.go new file mode 100644 index 000000000000..976d9a9077bf --- /dev/null +++ b/op-e2e/system/verifier/finalize_test.go @@ -0,0 +1,29 @@ +package verifier + +import ( + "math/big" + "testing" + "time" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/stretchr/testify/require" +) + +// TestFinalize tests if L2 finalizes after sufficient time after L1 finalizes +func TestFinalize(t *testing.T) { + op_e2e.InitParallel(t) + + cfg := e2esys.DefaultSystemConfig(t) + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + + l2Seq := sys.NodeClient("sequencer") + + l2Finalized, err := geth.WaitForBlockToBeFinalized(big.NewInt(12), l2Seq, 1*time.Minute) + require.NoError(t, err, "must be able to fetch a finalized L2 block") + require.NotZerof(t, l2Finalized.NumberU64(), "must have finalized L2 block") +} diff --git a/op-e2e/system/verifier/legacy_pending_test.go b/op-e2e/system/verifier/legacy_pending_test.go new file mode 100644 index 000000000000..8a3afee5e091 --- /dev/null +++ b/op-e2e/system/verifier/legacy_pending_test.go @@ -0,0 +1,120 @@ +package verifier + +import ( + "context" + "math/big" + "testing" + "time" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/rpc" + "github.com/stretchr/testify/require" +) + +// TestPendingGasLimit tests the configuration of the gas limit of the pending block, +// and if it does not conflict with the regular gas limit on the verifier or sequencer. +func TestPendingGasLimit(t *testing.T) { + op_e2e.InitParallel(t) + + cfg := e2esys.DefaultSystemConfig(t) + + // configure the L2 gas limit to be high, and the pending gas limits to be lower for resource saving. + cfg.DeployConfig.L2GenesisBlockGasLimit = 30_000_000 + cfg.GethOptions["sequencer"] = append(cfg.GethOptions["sequencer"], []geth.GethOption{ + func(ethCfg *ethconfig.Config, nodeCfg *node.Config) error { + ethCfg.Miner.GasCeil = 10_000_000 + ethCfg.Miner.RollupComputePendingBlock = true + return nil + }, + }...) + cfg.GethOptions["verifier"] = append(cfg.GethOptions["verifier"], []geth.GethOption{ + func(ethCfg *ethconfig.Config, nodeCfg *node.Config) error { + ethCfg.Miner.GasCeil = 9_000_000 + ethCfg.Miner.RollupComputePendingBlock = true + return nil + }, + }...) + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + + log := testlog.Logger(t, log.LevelInfo) + log.Info("genesis", "l2", sys.RollupConfig.Genesis.L2, "l1", sys.RollupConfig.Genesis.L1, "l2_time", sys.RollupConfig.Genesis.L2Time) + + l2Verif := sys.NodeClient("verifier") + l2Seq := sys.NodeClient("sequencer") + + checkGasLimit := func(client *ethclient.Client, number *big.Int, expected uint64) *types.Header { + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + header, err := client.HeaderByNumber(ctx, number) + cancel() + require.NoError(t, err) + require.Equal(t, expected, header.GasLimit) + return header + } + + // check if the gaslimits are matching the expected values, + // and that the verifier/sequencer can use their locally configured gas limit for the pending block. + for { + checkGasLimit(l2Seq, big.NewInt(-1), 10_000_000) + checkGasLimit(l2Verif, big.NewInt(-1), 9_000_000) + checkGasLimit(l2Seq, nil, 30_000_000) + latestVerifHeader := checkGasLimit(l2Verif, nil, 30_000_000) + + // Stop once the verifier passes genesis: + // this implies we checked a new block from the sequencer, on both sequencer and verifier nodes. + if latestVerifHeader.Number.Uint64() > 0 { + break + } + time.Sleep(500 * time.Millisecond) + } +} + +// TestPendingBlockIsLatest tests that we serve the latest block as pending block +func TestPendingBlockIsLatest(t *testing.T) { + op_e2e.InitParallel(t) + + cfg := e2esys.DefaultSystemConfig(t) + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + + l2Seq := sys.NodeClient("sequencer") + + t.Run("block", func(t *testing.T) { + for i := 0; i < 10; i++ { + pending, err := l2Seq.BlockByNumber(context.Background(), big.NewInt(rpc.PendingBlockNumber.Int64())) + require.NoError(t, err) + latest, err := l2Seq.BlockByNumber(context.Background(), nil) + require.NoError(t, err) + if pending.NumberU64() == latest.NumberU64() { + require.Equal(t, pending.Hash(), latest.Hash(), "pending must exactly match latest block") + return + } + // re-try until we have the same number, as the requests are not an atomic bundle, and the sequencer may create a block. + } + t.Fatal("failed to get pending block with same number as latest block") + }) + t.Run("header", func(t *testing.T) { + for i := 0; i < 10; i++ { + pending, err := l2Seq.HeaderByNumber(context.Background(), big.NewInt(rpc.PendingBlockNumber.Int64())) + require.NoError(t, err) + latest, err := l2Seq.HeaderByNumber(context.Background(), nil) + require.NoError(t, err) + if pending.Number.Uint64() == latest.Number.Uint64() { + require.Equal(t, pending.Hash(), latest.Hash(), "pending must exactly match latest header") + return + } + // re-try until we have the same number, as the requests are not an atomic bundle, and the sequencer may create a block. + } + t.Fatal("failed to get pending header with same number as latest header") + }) +} diff --git a/op-e2e/system/verifier/sequencer_window_test.go b/op-e2e/system/verifier/sequencer_window_test.go new file mode 100644 index 000000000000..aa836402e99b --- /dev/null +++ b/op-e2e/system/verifier/sequencer_window_test.go @@ -0,0 +1,73 @@ +package verifier + +import ( + "context" + "math/big" + "testing" + "time" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" + "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestMissingBatchE2E(t *testing.T) { + op_e2e.InitParallel(t) + // Note this test zeroes the balance of the batch-submitter to make the batches unable to go into L1. + // The test logs may look scary, but this is expected: + // 'batcher unable to publish transaction role=batcher err="insufficient funds for gas * price + value"' + + cfg := e2esys.DefaultSystemConfig(t) + // small sequence window size so the test does not take as long + cfg.DeployConfig.SequencerWindowSize = 4 + + // Specifically set batch submitter balance to stop batches from being included + cfg.Premine[cfg.Secrets.Addresses().Batcher] = big.NewInt(0) + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + + l2Seq := sys.NodeClient("sequencer") + l2Verif := sys.NodeClient("verifier") + + seqRollupClient := sys.RollupClient("sequencer") + + // Transactor Account + ethPrivKey := cfg.Secrets.Alice + + // Submit TX to L2 sequencer node + receipt := helpers.SendL2Tx(t, cfg, l2Seq, ethPrivKey, func(opts *helpers.TxOpts) { + opts.ToAddr = &common.Address{0xff, 0xff} + opts.Value = big.NewInt(1_000_000_000) + }) + + // Wait until the block it was first included in shows up in the safe chain on the verifier + _, err = geth.WaitForBlock(receipt.BlockNumber, l2Verif, time.Duration((sys.RollupConfig.SeqWindowSize+4)*cfg.DeployConfig.L1BlockTime)*time.Second) + require.Nil(t, err, "Waiting for block on verifier") + + // Assert that the transaction is not found on the verifier + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + _, err = l2Verif.TransactionReceipt(ctx, receipt.TxHash) + require.Equal(t, ethereum.NotFound, err, "Found transaction in verifier when it should not have been included") + + // Wait a short time for the L2 reorg to occur on the sequencer as well. + err = wait.ForSafeBlock(ctx, seqRollupClient, receipt.BlockNumber.Uint64()) + require.Nil(t, err, "timeout waiting for L2 reorg on sequencer safe head") + + // Assert that the reconciliation process did an L2 reorg on the sequencer to remove the invalid block + ctx2, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + block, err := l2Seq.BlockByNumber(ctx2, receipt.BlockNumber) + if err != nil { + require.Equal(t, "not found", err.Error(), "A not found error indicates the chain must have re-orged back before it") + } else { + require.NotEqual(t, block.Hash(), receipt.BlockHash, "L2 Sequencer did not reorg out transaction on it's safe chain") + } +} diff --git a/op-e2e/system/verifier/verifier_test.go b/op-e2e/system/verifier/verifier_test.go new file mode 100644 index 000000000000..33527b62da24 --- /dev/null +++ b/op-e2e/system/verifier/verifier_test.go @@ -0,0 +1,11 @@ +package verifier + +import ( + "testing" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" +) + +func TestMain(m *testing.M) { + op_e2e.RunMain(m) +} diff --git a/op-e2e/system_test.go b/op-e2e/system_test.go deleted file mode 100644 index 37fbfe0e7ad8..000000000000 --- a/op-e2e/system_test.go +++ /dev/null @@ -1,1677 +0,0 @@ -package op_e2e - -import ( - "context" - "errors" - "fmt" - "math/big" - "os" - "runtime" - "slices" - "testing" - "time" - - "github.com/libp2p/go-libp2p/core/peer" - "github.com/stretchr/testify/require" - - "github.com/ethereum-optimism/optimism/op-batcher/flags" - "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/consensus/misc/eip4844" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/eth/ethconfig" - "github.com/ethereum/go-ethereum/ethclient" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/rpc" - - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" - metrics2 "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics" - "github.com/ethereum-optimism/optimism/op-e2e/bindings" - "github.com/ethereum-optimism/optimism/op-e2e/config" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" - "github.com/ethereum-optimism/optimism/op-node/metrics" - rollupNode "github.com/ethereum-optimism/optimism/op-node/node" - "github.com/ethereum-optimism/optimism/op-node/p2p" - "github.com/ethereum-optimism/optimism/op-node/rollup/derive" - "github.com/ethereum-optimism/optimism/op-node/rollup/driver" - "github.com/ethereum-optimism/optimism/op-service/client" - "github.com/ethereum-optimism/optimism/op-service/endpoint" - "github.com/ethereum-optimism/optimism/op-service/eth" - "github.com/ethereum-optimism/optimism/op-service/oppprof" - "github.com/ethereum-optimism/optimism/op-service/predeploys" - "github.com/ethereum-optimism/optimism/op-service/retry" - "github.com/ethereum-optimism/optimism/op-service/sources/batching" - "github.com/ethereum-optimism/optimism/op-service/testlog" -) - -// TestSystemBatchType run each system e2e test case in singular batch mode and span batch mode. -// If the test case tests batch submission and advancing safe head, it should be tested in both singular and span batch mode. -func TestSystemBatchType(t *testing.T) { - tests := []struct { - name string - f func(*testing.T, func(*SystemConfig)) - }{ - {"StopStartBatcher", StopStartBatcher}, - } - for _, test := range tests { - test := test - t.Run(test.name+"_SingularBatch", func(t *testing.T) { - test.f(t, func(sc *SystemConfig) { - sc.BatcherBatchType = derive.SingularBatchType - }) - }) - t.Run(test.name+"_SpanBatch", func(t *testing.T) { - test.f(t, func(sc *SystemConfig) { - sc.BatcherBatchType = derive.SpanBatchType - }) - }) - t.Run(test.name+"_SpanBatchMaxBlocks", func(t *testing.T) { - test.f(t, func(sc *SystemConfig) { - sc.BatcherBatchType = derive.SpanBatchType - sc.BatcherMaxBlocksPerSpanBatch = 2 - }) - }) - } -} - -func TestMain(m *testing.M) { - if config.ExternalL2Shim != "" { - fmt.Println("Running tests with external L2 process adapter at ", config.ExternalL2Shim) - // As these are integration tests which launch many other processes, the - // default parallelism makes the tests flaky. This change aims to - // reduce the flakiness of these tests. - maxProcs := runtime.NumCPU() / 4 - if maxProcs == 0 { - maxProcs = 1 - } - runtime.GOMAXPROCS(maxProcs) - } - - os.Exit(m.Run()) -} - -func TestL2OutputSubmitter(t *testing.T) { - InitParallel(t, SkipOnFaultProofs) - - cfg := DefaultSystemConfig(t) - cfg.NonFinalizedProposals = true // speed up the time till we see output proposals - - sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") - - l1Client := sys.NodeClient("l1") - - rollupClient := sys.RollupClient("sequencer") - - // OutputOracle is already deployed - l2OutputOracle, err := bindings.NewL2OutputOracleCaller(cfg.L1Deployments.L2OutputOracleProxy, l1Client) - require.Nil(t, err) - - initialOutputBlockNumber, err := l2OutputOracle.LatestBlockNumber(&bind.CallOpts{}) - require.Nil(t, err) - - // Wait until the second output submission from L2. The output submitter submits outputs from the - // unsafe portion of the chain which gets reorged on startup. The sequencer has an out of date view - // when it creates it's first block and uses and old L1 Origin. It then does not submit a batch - // for that block and subsequently reorgs to match what the verifier derives when running the - // reconcillation process. - l2Verif := sys.NodeClient("verifier") - _, err = geth.WaitForBlock(big.NewInt(6), l2Verif, 10*time.Duration(cfg.DeployConfig.L2BlockTime)*time.Second) - require.Nil(t, err) - - // Wait for batch submitter to update L2 output oracle. - timeoutCh := time.After(15 * time.Second) - ticker := time.NewTicker(1 * time.Second) - defer ticker.Stop() - for { - l2ooBlockNumber, err := l2OutputOracle.LatestBlockNumber(&bind.CallOpts{}) - require.Nil(t, err) - - // Wait for the L2 output oracle to have been changed from the initial - // timestamp set in the contract constructor. - if l2ooBlockNumber.Cmp(initialOutputBlockNumber) > 0 { - // Retrieve the l2 output committed at this updated timestamp. - committedL2Output, err := l2OutputOracle.GetL2OutputAfter(&bind.CallOpts{}, l2ooBlockNumber) - require.NotEqual(t, [32]byte{}, committedL2Output.OutputRoot, "Empty L2 Output") - require.Nil(t, err) - - // Fetch the corresponding L2 block and assert the committed L2 - // output matches the block's state root. - // - // NOTE: This assertion will change once the L2 output format is - // finalized. - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - l2Output, err := rollupClient.OutputAtBlock(ctx, l2ooBlockNumber.Uint64()) - require.Nil(t, err) - require.Equal(t, l2Output.OutputRoot[:], committedL2Output.OutputRoot[:]) - break - } - - select { - case <-timeoutCh: - t.Fatalf("State root oracle not updated") - case <-ticker.C: - } - } -} - -func TestL2OutputSubmitterFaultProofs(t *testing.T) { - InitParallel(t, SkipOnL2OO) - - cfg := DefaultSystemConfig(t) - cfg.NonFinalizedProposals = true // speed up the time till we see output proposals - - sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") - - l1Client := sys.NodeClient("l1") - - rollupClient := sys.RollupClient("sequencer") - - disputeGameFactory, err := bindings.NewDisputeGameFactoryCaller(cfg.L1Deployments.DisputeGameFactoryProxy, l1Client) - require.Nil(t, err) - - initialGameCount, err := disputeGameFactory.GameCount(&bind.CallOpts{}) - require.Nil(t, err) - - l2Verif := sys.NodeClient("verifier") - _, err = geth.WaitForBlock(big.NewInt(6), l2Verif, 10*time.Duration(cfg.DeployConfig.L2BlockTime)*time.Second) - require.Nil(t, err) - - timeoutCh := time.After(15 * time.Second) - ticker := time.NewTicker(1 * time.Second) - defer ticker.Stop() - for { - latestGameCount, err := disputeGameFactory.GameCount(&bind.CallOpts{}) - require.Nil(t, err) - - if latestGameCount.Cmp(initialGameCount) > 0 { - caller := batching.NewMultiCaller(l1Client.Client(), batching.DefaultBatchSize) - committedL2Output, err := disputeGameFactory.GameAtIndex(&bind.CallOpts{}, new(big.Int).Sub(latestGameCount, common.Big1)) - require.Nil(t, err) - proxy, err := contracts.NewFaultDisputeGameContract(context.Background(), metrics2.NoopContractMetrics, committedL2Output.Proxy, caller) - require.Nil(t, err) - claim, err := proxy.GetClaim(context.Background(), 0) - require.Nil(t, err) - - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - _, gameBlockNumber, err := proxy.GetBlockRange(ctx) - require.Nil(t, err) - l2Output, err := rollupClient.OutputAtBlock(ctx, gameBlockNumber) - require.Nil(t, err) - require.EqualValues(t, l2Output.OutputRoot, claim.Value) - break - } - - select { - case <-timeoutCh: - t.Fatalf("State root oracle not updated") - case <-ticker.C: - } - } -} - -func TestSystemE2EDencunAtGenesis(t *testing.T) { - InitParallel(t) - - cfg := DefaultSystemConfig(t) - cfg.DeployConfig.L1CancunTimeOffset = &genesisTime - - sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") - - runE2ESystemTest(t, sys) - head, err := sys.NodeClient("l1").BlockByNumber(context.Background(), big.NewInt(0)) - require.NoError(t, err) - require.NotNil(t, head.ExcessBlobGas(), "L1 is building dencun blocks since genesis") -} - -// TestSystemE2EDencunAtGenesis tests if L2 finalizes when blobs are present on L1 -func TestSystemE2EDencunAtGenesisWithBlobs(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - InitParallel(t) - - cfg := DefaultSystemConfig(t) - cfg.DeployConfig.L1CancunTimeOffset = &genesisTime - - sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") - - // send a blob-containing txn on l1 - ethPrivKey := sys.Cfg.Secrets.Alice - txData := transactions.CreateEmptyBlobTx(true, sys.Cfg.L1ChainIDBig().Uint64()) - tx := types.MustSignNewTx(ethPrivKey, types.LatestSignerForChainID(cfg.L1ChainIDBig()), txData) - // send blob-containing txn - sendCtx, sendCancel := context.WithTimeout(context.Background(), 15*time.Second) - defer sendCancel() - - l1Client := sys.NodeClient("l1") - err = l1Client.SendTransaction(sendCtx, tx) - require.NoError(t, err, "Sending L1 empty blob tx") - // Wait for transaction on L1 - blockContainsBlob, err := wait.ForReceiptOK(ctx, l1Client, tx.Hash()) - require.Nil(t, err, "Waiting for blob tx on L1") - // end sending blob-containing txns on l1 - l2Client := sys.NodeClient("sequencer") - finalizedBlock, err := geth.WaitForL1OriginOnL2(sys.RollupConfig, blockContainsBlob.BlockNumber.Uint64(), l2Client, 30*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second) - require.Nil(t, err, "Waiting for L1 origin of blob tx on L2") - finalizationTimeout := 30 * time.Duration(cfg.DeployConfig.L1BlockTime) * time.Second - _, err = geth.WaitForBlockToBeSafe(finalizedBlock.Header().Number, l2Client, finalizationTimeout) - require.Nil(t, err, "Waiting for safety of L2 block") -} - -// TestSystemE2E sets up a L1 Geth node, a rollup node, and a L2 geth node and then confirms that L1 deposits are reflected on L2. -// All nodes are run in process (but are the full nodes, not mocked or stubbed). -func TestSystemE2E(t *testing.T) { - InitParallel(t) - - cfg := DefaultSystemConfig(t) - - sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") - runE2ESystemTest(t, sys) - -} - -func runE2ESystemTest(t *testing.T, sys *System) { - log := testlog.Logger(t, log.LevelInfo) - log.Info("genesis", "l2", sys.RollupConfig.Genesis.L2, "l1", sys.RollupConfig.Genesis.L1, "l2_time", sys.RollupConfig.Genesis.L2Time) - - l1Client := sys.NodeClient("l1") - l2Seq := sys.NodeClient("sequencer") - l2Verif := sys.NodeClient("verifier") - - // Transactor Account - ethPrivKey := sys.Cfg.Secrets.Alice - - // Send Transaction & wait for success - fromAddr := sys.Cfg.Secrets.Addresses().Alice - - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) - defer cancel() - startBalance, err := l2Verif.BalanceAt(ctx, fromAddr, nil) - require.Nil(t, err) - - // Send deposit transaction - opts, err := bind.NewKeyedTransactorWithChainID(ethPrivKey, sys.Cfg.L1ChainIDBig()) - require.Nil(t, err) - mintAmount := big.NewInt(1_000_000_000_000) - opts.Value = mintAmount - SendDepositTx(t, sys.Cfg, l1Client, l2Verif, opts, func(l2Opts *DepositTxOpts) {}) - - // Confirm balance - ctx, cancel = context.WithTimeout(context.Background(), 15*time.Second) - defer cancel() - - endBalance, err := wait.ForBalanceChange(ctx, l2Verif, fromAddr, startBalance) - require.Nil(t, err) - - diff := new(big.Int) - diff = diff.Sub(endBalance, startBalance) - require.Equal(t, mintAmount, diff, "Did not get expected balance change") - - // Submit TX to L2 sequencer node - receipt := SendL2Tx(t, sys.Cfg, l2Seq, ethPrivKey, func(opts *TxOpts) { - opts.Value = big.NewInt(1_000_000_000) - opts.Nonce = 1 // Already have deposit - opts.ToAddr = &common.Address{0xff, 0xff} - opts.VerifyOnClients(l2Verif) - }) - - // Verify blocks match after batch submission on verifiers and sequencers - verifBlock, err := l2Verif.BlockByNumber(context.Background(), receipt.BlockNumber) - require.Nil(t, err) - seqBlock, err := l2Seq.BlockByNumber(context.Background(), receipt.BlockNumber) - require.Nil(t, err) - require.Equal(t, verifBlock.NumberU64(), seqBlock.NumberU64(), "Verifier and sequencer blocks not the same after including a batch tx") - require.Equal(t, verifBlock.ParentHash(), seqBlock.ParentHash(), "Verifier and sequencer blocks parent hashes not the same after including a batch tx") - require.Equal(t, verifBlock.Hash(), seqBlock.Hash(), "Verifier and sequencer blocks not the same after including a batch tx") - - rollupClient := sys.RollupClient("sequencer") - // basic check that sync status works - seqStatus, err := rollupClient.SyncStatus(context.Background()) - require.Nil(t, err) - require.LessOrEqual(t, seqBlock.NumberU64(), seqStatus.UnsafeL2.Number) - // basic check that version endpoint works - seqVersion, err := rollupClient.Version(context.Background()) - require.Nil(t, err) - require.NotEqual(t, "", seqVersion) -} - -// TestConfirmationDepth runs the rollup with both sequencer and verifier not immediately processing the tip of the chain. -func TestConfirmationDepth(t *testing.T) { - InitParallel(t) - - cfg := DefaultSystemConfig(t) - cfg.DeployConfig.SequencerWindowSize = 4 - cfg.DeployConfig.MaxSequencerDrift = 10 * cfg.DeployConfig.L1BlockTime - seqConfDepth := uint64(2) - verConfDepth := uint64(5) - cfg.Nodes["sequencer"].Driver.SequencerConfDepth = seqConfDepth - cfg.Nodes["sequencer"].Driver.VerifierConfDepth = 0 - cfg.Nodes["verifier"].Driver.VerifierConfDepth = verConfDepth - - sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") - - log := testlog.Logger(t, log.LevelInfo) - log.Info("genesis", "l2", sys.RollupConfig.Genesis.L2, "l1", sys.RollupConfig.Genesis.L1, "l2_time", sys.RollupConfig.Genesis.L2Time) - - l1Client := sys.NodeClient("l1") - l2Seq := sys.NodeClient("sequencer") - l2Verif := sys.NodeClient("verifier") - - // Wait enough time for the sequencer to submit a block with distance from L1 head, submit it, - // and for the slower verifier to read a full sequence window and cover confirmation depth for reading and some margin - <-time.After(time.Duration((cfg.DeployConfig.SequencerWindowSize+verConfDepth+3)*cfg.DeployConfig.L1BlockTime) * time.Second) - - // within a second, get both L1 and L2 verifier and sequencer block heads - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - l1Head, err := l1Client.BlockByNumber(ctx, nil) - require.NoError(t, err) - l2SeqHead, err := l2Seq.BlockByNumber(ctx, nil) - require.NoError(t, err) - l2VerHead, err := l2Verif.BlockByNumber(ctx, nil) - require.NoError(t, err) - - seqInfo, err := derive.L1BlockInfoFromBytes(sys.RollupConfig, l2SeqHead.Time(), l2SeqHead.Transactions()[0].Data()) - require.NoError(t, err) - require.LessOrEqual(t, seqInfo.Number+seqConfDepth, l1Head.NumberU64(), "the seq L2 head block should have an origin older than the L1 head block by at least the sequencer conf depth") - - verInfo, err := derive.L1BlockInfoFromBytes(sys.RollupConfig, l2VerHead.Time(), l2VerHead.Transactions()[0].Data()) - require.NoError(t, err) - require.LessOrEqual(t, verInfo.Number+verConfDepth, l1Head.NumberU64(), "the ver L2 head block should have an origin older than the L1 head block by at least the verifier conf depth") -} - -// TestPendingGasLimit tests the configuration of the gas limit of the pending block, -// and if it does not conflict with the regular gas limit on the verifier or sequencer. -func TestPendingGasLimit(t *testing.T) { - InitParallel(t) - - cfg := DefaultSystemConfig(t) - - // configure the L2 gas limit to be high, and the pending gas limits to be lower for resource saving. - cfg.DeployConfig.L2GenesisBlockGasLimit = 30_000_000 - cfg.GethOptions["sequencer"] = append(cfg.GethOptions["sequencer"], []geth.GethOption{ - func(ethCfg *ethconfig.Config, nodeCfg *node.Config) error { - ethCfg.Miner.GasCeil = 10_000_000 - ethCfg.Miner.RollupComputePendingBlock = true - return nil - }, - }...) - cfg.GethOptions["verifier"] = append(cfg.GethOptions["verifier"], []geth.GethOption{ - func(ethCfg *ethconfig.Config, nodeCfg *node.Config) error { - ethCfg.Miner.GasCeil = 9_000_000 - ethCfg.Miner.RollupComputePendingBlock = true - return nil - }, - }...) - - sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") - - log := testlog.Logger(t, log.LevelInfo) - log.Info("genesis", "l2", sys.RollupConfig.Genesis.L2, "l1", sys.RollupConfig.Genesis.L1, "l2_time", sys.RollupConfig.Genesis.L2Time) - - l2Verif := sys.NodeClient("verifier") - l2Seq := sys.NodeClient("sequencer") - - checkGasLimit := func(client *ethclient.Client, number *big.Int, expected uint64) *types.Header { - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - header, err := client.HeaderByNumber(ctx, number) - cancel() - require.NoError(t, err) - require.Equal(t, expected, header.GasLimit) - return header - } - - // check if the gaslimits are matching the expected values, - // and that the verifier/sequencer can use their locally configured gas limit for the pending block. - for { - checkGasLimit(l2Seq, big.NewInt(-1), 10_000_000) - checkGasLimit(l2Verif, big.NewInt(-1), 9_000_000) - checkGasLimit(l2Seq, nil, 30_000_000) - latestVerifHeader := checkGasLimit(l2Verif, nil, 30_000_000) - - // Stop once the verifier passes genesis: - // this implies we checked a new block from the sequencer, on both sequencer and verifier nodes. - if latestVerifHeader.Number.Uint64() > 0 { - break - } - time.Sleep(500 * time.Millisecond) - } -} - -// TestFinalize tests if L2 finalizes after sufficient time after L1 finalizes -func TestFinalize(t *testing.T) { - InitParallel(t) - - cfg := DefaultSystemConfig(t) - - sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") - - l2Seq := sys.NodeClient("sequencer") - - l2Finalized, err := geth.WaitForBlockToBeFinalized(big.NewInt(12), l2Seq, 1*time.Minute) - require.NoError(t, err, "must be able to fetch a finalized L2 block") - require.NotZerof(t, l2Finalized.NumberU64(), "must have finalized L2 block") -} - -func TestMissingBatchE2E(t *testing.T) { - InitParallel(t) - // Note this test zeroes the balance of the batch-submitter to make the batches unable to go into L1. - // The test logs may look scary, but this is expected: - // 'batcher unable to publish transaction role=batcher err="insufficient funds for gas * price + value"' - - cfg := DefaultSystemConfig(t) - // small sequence window size so the test does not take as long - cfg.DeployConfig.SequencerWindowSize = 4 - - // Specifically set batch submitter balance to stop batches from being included - cfg.Premine[cfg.Secrets.Addresses().Batcher] = big.NewInt(0) - - sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") - - l2Seq := sys.NodeClient("sequencer") - l2Verif := sys.NodeClient("verifier") - - seqRollupClient := sys.RollupClient("sequencer") - - // Transactor Account - ethPrivKey := cfg.Secrets.Alice - - // Submit TX to L2 sequencer node - receipt := SendL2Tx(t, cfg, l2Seq, ethPrivKey, func(opts *TxOpts) { - opts.ToAddr = &common.Address{0xff, 0xff} - opts.Value = big.NewInt(1_000_000_000) - }) - - // Wait until the block it was first included in shows up in the safe chain on the verifier - _, err = geth.WaitForBlock(receipt.BlockNumber, l2Verif, time.Duration((sys.RollupConfig.SeqWindowSize+4)*cfg.DeployConfig.L1BlockTime)*time.Second) - require.Nil(t, err, "Waiting for block on verifier") - - // Assert that the transaction is not found on the verifier - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - _, err = l2Verif.TransactionReceipt(ctx, receipt.TxHash) - require.Equal(t, ethereum.NotFound, err, "Found transaction in verifier when it should not have been included") - - // Wait a short time for the L2 reorg to occur on the sequencer as well. - err = wait.ForSafeBlock(ctx, seqRollupClient, receipt.BlockNumber.Uint64()) - require.Nil(t, err, "timeout waiting for L2 reorg on sequencer safe head") - - // Assert that the reconciliation process did an L2 reorg on the sequencer to remove the invalid block - ctx2, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - block, err := l2Seq.BlockByNumber(ctx2, receipt.BlockNumber) - if err != nil { - require.Equal(t, "not found", err.Error(), "A not found error indicates the chain must have re-orged back before it") - } else { - require.NotEqual(t, block.Hash(), receipt.BlockHash, "L2 Sequencer did not reorg out transaction on it's safe chain") - } -} - -func L1InfoFromState(ctx context.Context, contract *bindings.L1Block, l2Number *big.Int, ecotone bool) (*derive.L1BlockInfo, error) { - var err error - out := &derive.L1BlockInfo{} - opts := bind.CallOpts{ - BlockNumber: l2Number, - Context: ctx, - } - - out.Number, err = contract.Number(&opts) - if err != nil { - return nil, fmt.Errorf("failed to get number: %w", err) - } - - out.Time, err = contract.Timestamp(&opts) - if err != nil { - return nil, fmt.Errorf("failed to get timestamp: %w", err) - } - - out.BaseFee, err = contract.Basefee(&opts) - if err != nil { - return nil, fmt.Errorf("failed to get base fee: %w", err) - } - - blockHashBytes, err := contract.Hash(&opts) - if err != nil { - return nil, fmt.Errorf("failed to get block hash: %w", err) - } - out.BlockHash = common.BytesToHash(blockHashBytes[:]) - - out.SequenceNumber, err = contract.SequenceNumber(&opts) - if err != nil { - return nil, fmt.Errorf("failed to get sequence number: %w", err) - } - - if !ecotone { - overhead, err := contract.L1FeeOverhead(&opts) - if err != nil { - return nil, fmt.Errorf("failed to get l1 fee overhead: %w", err) - } - out.L1FeeOverhead = eth.Bytes32(common.BigToHash(overhead)) - - scalar, err := contract.L1FeeScalar(&opts) - if err != nil { - return nil, fmt.Errorf("failed to get l1 fee scalar: %w", err) - } - out.L1FeeScalar = eth.Bytes32(common.BigToHash(scalar)) - } - - batcherHash, err := contract.BatcherHash(&opts) - if err != nil { - return nil, fmt.Errorf("failed to get batch sender: %w", err) - } - out.BatcherAddr = common.BytesToAddress(batcherHash[:]) - - if ecotone { - blobBaseFeeScalar, err := contract.BlobBaseFeeScalar(&opts) - if err != nil { - return nil, fmt.Errorf("failed to get blob basefee scalar: %w", err) - } - out.BlobBaseFeeScalar = blobBaseFeeScalar - - baseFeeScalar, err := contract.BaseFeeScalar(&opts) - if err != nil { - return nil, fmt.Errorf("failed to get basefee scalar: %w", err) - } - out.BaseFeeScalar = baseFeeScalar - - blobBaseFee, err := contract.BlobBaseFee(&opts) - if err != nil { - return nil, fmt.Errorf("failed to get blob basefee: %w", err) - } - out.BlobBaseFee = blobBaseFee - } - - return out, nil -} - -// TestSystemMockP2P sets up a L1 Geth node, a rollup node, and a L2 geth node and then confirms that -// the nodes can sync L2 blocks before they are confirmed on L1. -func TestSystemMockP2P(t *testing.T) { - InitParallel(t) - - cfg := DefaultSystemConfig(t) - // Disable batcher, so we don't sync from L1 & set a large sequence window so we only have unsafe blocks - cfg.DisableBatcher = true - cfg.DeployConfig.SequencerWindowSize = 100_000 - cfg.DeployConfig.MaxSequencerDrift = 100_000 - // disable at the start, so we don't miss any gossiped blocks. - cfg.Nodes["sequencer"].Driver.SequencerStopped = true - - // connect the nodes - cfg.P2PTopology = map[string][]string{ - "verifier": {"sequencer"}, - } - - var published, received []common.Hash - seqTracer, verifTracer := new(FnTracer), new(FnTracer) - seqTracer.OnPublishL2PayloadFn = func(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) { - published = append(published, payload.ExecutionPayload.BlockHash) - } - verifTracer.OnUnsafeL2PayloadFn = func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) { - received = append(received, payload.ExecutionPayload.BlockHash) - } - cfg.Nodes["sequencer"].Tracer = seqTracer - cfg.Nodes["verifier"].Tracer = verifTracer - - sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") - - // Enable the sequencer now that everyone is ready to receive payloads. - rollupClient := sys.RollupClient("sequencer") - - verifierPeerID := sys.RollupNodes["verifier"].P2P().Host().ID() - check := func() bool { - sequencerBlocksTopicPeers := sys.RollupNodes["sequencer"].P2P().GossipOut().AllBlockTopicsPeers() - return slices.Contains[[]peer.ID](sequencerBlocksTopicPeers, verifierPeerID) - } - - // poll to see if the verifier node is connected & meshed on gossip. - // Without this verifier, we shouldn't start sending blocks around, or we'll miss them and fail the test. - backOffStrategy := retry.Exponential() - for i := 0; i < 10; i++ { - if check() { - break - } - time.Sleep(backOffStrategy.Duration(i)) - } - require.True(t, check(), "verifier must be meshed with sequencer for gossip test to proceed") - - require.NoError(t, rollupClient.StartSequencer(context.Background(), sys.L2GenesisCfg.ToBlock().Hash())) - - l2Seq := sys.NodeClient("sequencer") - l2Verif := sys.NodeClient("verifier") - - // Transactor Account - ethPrivKey := cfg.Secrets.Alice - - // Submit TX to L2 sequencer node - receiptSeq := SendL2Tx(t, cfg, l2Seq, ethPrivKey, func(opts *TxOpts) { - opts.ToAddr = &common.Address{0xff, 0xff} - opts.Value = big.NewInt(1_000_000_000) - - // Wait until the block it was first included in shows up in the safe chain on the verifier - opts.VerifyOnClients(l2Verif) - }) - - // Verify that everything that was received was published - require.GreaterOrEqual(t, len(published), len(received)) - require.Subset(t, published, received) - - // Verify that the tx was received via p2p - require.Contains(t, received, receiptSeq.BlockHash) -} - -func TestSystemP2PAltSync(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - InitParallel(t) - - cfg := DefaultSystemConfig(t) - - // remove default verifier node - delete(cfg.Nodes, "verifier") - // Add more verifier nodes - cfg.Nodes["alice"] = &rollupNode.Config{ - Driver: driver.Config{ - VerifierConfDepth: 0, - SequencerConfDepth: 0, - SequencerEnabled: false, - }, - L1EpochPollInterval: time.Second * 4, - } - cfg.Nodes["bob"] = &rollupNode.Config{ - Driver: driver.Config{ - VerifierConfDepth: 0, - SequencerConfDepth: 0, - SequencerEnabled: false, - }, - L1EpochPollInterval: time.Second * 4, - } - cfg.Loggers["alice"] = testlog.Logger(t, log.LevelInfo).New("role", "alice") - cfg.Loggers["bob"] = testlog.Logger(t, log.LevelInfo).New("role", "bob") - - // connect the nodes - cfg.P2PTopology = map[string][]string{ - "sequencer": {"alice", "bob"}, - "alice": {"sequencer", "bob"}, - "bob": {"alice", "sequencer"}, - } - // Enable the P2P req-resp based sync - cfg.P2PReqRespSync = true - - // Disable batcher, so there will not be any L1 data to sync from - cfg.DisableBatcher = true - - var published []string - seqTracer := new(FnTracer) - // The sequencer still publishes the blocks to the tracer, even if they do not reach the network due to disabled P2P - seqTracer.OnPublishL2PayloadFn = func(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) { - published = append(published, payload.ExecutionPayload.ID().String()) - } - // Blocks are now received via the RPC based alt-sync method - cfg.Nodes["sequencer"].Tracer = seqTracer - - sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") - - l2Seq := sys.NodeClient("sequencer") - - // Transactor Account - ethPrivKey := cfg.Secrets.Alice - - // Submit a TX to L2 sequencer node - receiptSeq := SendL2Tx(t, cfg, l2Seq, ethPrivKey, func(opts *TxOpts) { - opts.ToAddr = &common.Address{0xff, 0xff} - opts.Value = big.NewInt(1_000_000_000) - }) - - // Gossip is able to respond to IWANT messages for the duration of heartbeat_time * message_window = 0.5 * 12 = 6 - // Wait till we pass that, and then we'll have missed some blocks that cannot be retrieved in any way from gossip - time.Sleep(time.Second * 10) - - // set up our syncer node, connect it to alice/bob - cfg.Loggers["syncer"] = testlog.Logger(t, log.LevelInfo).New("role", "syncer") - - // Create a peer, and hook up alice and bob - h, err := sys.newMockNetPeer() - require.NoError(t, err) - _, err = sys.Mocknet.LinkPeers(sys.RollupNodes["alice"].P2P().Host().ID(), h.ID()) - require.NoError(t, err) - _, err = sys.Mocknet.LinkPeers(sys.RollupNodes["bob"].P2P().Host().ID(), h.ID()) - require.NoError(t, err) - - // Configure the new rollup node that'll be syncing - var syncedPayloads []string - syncNodeCfg := &rollupNode.Config{ - Driver: driver.Config{VerifierConfDepth: 0}, - Rollup: *sys.RollupConfig, - P2PSigner: nil, - RPC: rollupNode.RPCConfig{ - ListenAddr: "127.0.0.1", - ListenPort: 0, - EnableAdmin: true, - }, - P2P: &p2p.Prepared{HostP2P: h, EnableReqRespSync: true}, - Metrics: rollupNode.MetricsConfig{Enabled: false}, // no metrics server - Pprof: oppprof.CLIConfig{}, - L1EpochPollInterval: time.Second * 10, - Tracer: &FnTracer{ - OnUnsafeL2PayloadFn: func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) { - syncedPayloads = append(syncedPayloads, payload.ExecutionPayload.ID().String()) - }, - }, - } - configureL1(syncNodeCfg, sys.EthInstances["l1"], sys.L1BeaconEndpoint()) - syncerL2Engine, err := geth.InitL2("syncer", sys.L2GenesisCfg, cfg.JWTFilePath) - require.NoError(t, err) - require.NoError(t, syncerL2Engine.Node.Start()) - - configureL2(syncNodeCfg, syncerL2Engine, cfg.JWTSecret) - - syncerNode, err := rollupNode.New(ctx, syncNodeCfg, cfg.Loggers["syncer"], "", metrics.NewMetrics("")) - require.NoError(t, err) - err = syncerNode.Start(ctx) - require.NoError(t, err) - defer func() { - require.NoError(t, syncerNode.Stop(ctx)) - }() - - // connect alice and bob to our new syncer node - _, err = sys.Mocknet.ConnectPeers(sys.RollupNodes["alice"].P2P().Host().ID(), syncerNode.P2P().Host().ID()) - require.NoError(t, err) - _, err = sys.Mocknet.ConnectPeers(sys.RollupNodes["bob"].P2P().Host().ID(), syncerNode.P2P().Host().ID()) - require.NoError(t, err) - - rpc := syncerL2Engine.UserRPC().(endpoint.ClientRPC).ClientRPC() - l2Verif := ethclient.NewClient(rpc) - - // It may take a while to sync, but eventually we should see the sequenced data show up - receiptVerif, err := wait.ForReceiptOK(ctx, l2Verif, receiptSeq.TxHash) - require.Nil(t, err, "Waiting for L2 tx on verifier") - - require.Equal(t, receiptSeq, receiptVerif) - - // Verify that the tx was received via P2P sync - require.Contains(t, syncedPayloads, eth.BlockID{Hash: receiptVerif.BlockHash, Number: receiptVerif.BlockNumber.Uint64()}.String()) - - // Verify that everything that was received was published - require.GreaterOrEqual(t, len(published), len(syncedPayloads)) - require.Subset(t, published, syncedPayloads) -} - -// TestSystemDenseTopology sets up a dense p2p topology with 3 verifier nodes and 1 sequencer node. -func TestSystemDenseTopology(t *testing.T) { - t.Skip("Skipping dense topology test to avoid flakiness. @refcell address in p2p scoring pr.") - - InitParallel(t) - - cfg := DefaultSystemConfig(t) - // slow down L1 blocks so we can see the L2 blocks arrive well before the L1 blocks do. - // Keep the seq window small so the L2 chain is started quick - cfg.DeployConfig.L1BlockTime = 10 - - // Append additional nodes to the system to construct a dense p2p network - cfg.Nodes["verifier2"] = &rollupNode.Config{ - Driver: driver.Config{ - VerifierConfDepth: 0, - SequencerConfDepth: 0, - SequencerEnabled: false, - }, - L1EpochPollInterval: time.Second * 4, - } - cfg.Nodes["verifier3"] = &rollupNode.Config{ - Driver: driver.Config{ - VerifierConfDepth: 0, - SequencerConfDepth: 0, - SequencerEnabled: false, - }, - L1EpochPollInterval: time.Second * 4, - } - cfg.Loggers["verifier2"] = testlog.Logger(t, log.LevelInfo).New("role", "verifier") - cfg.Loggers["verifier3"] = testlog.Logger(t, log.LevelInfo).New("role", "verifier") - - // connect the nodes - cfg.P2PTopology = map[string][]string{ - "verifier": {"sequencer", "verifier2", "verifier3"}, - "verifier2": {"sequencer", "verifier", "verifier3"}, - "verifier3": {"sequencer", "verifier", "verifier2"}, - } - - // Set peer scoring for each node, but without banning - for _, node := range cfg.Nodes { - params, err := p2p.GetScoringParams("light", &node.Rollup) - require.NoError(t, err) - node.P2P = &p2p.Config{ - ScoringParams: params, - BanningEnabled: false, - } - } - - var published, received1, received2, received3 []common.Hash - seqTracer, verifTracer, verifTracer2, verifTracer3 := new(FnTracer), new(FnTracer), new(FnTracer), new(FnTracer) - seqTracer.OnPublishL2PayloadFn = func(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) { - published = append(published, payload.ExecutionPayload.BlockHash) - } - verifTracer.OnUnsafeL2PayloadFn = func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) { - received1 = append(received1, payload.ExecutionPayload.BlockHash) - } - verifTracer2.OnUnsafeL2PayloadFn = func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) { - received2 = append(received2, payload.ExecutionPayload.BlockHash) - } - verifTracer3.OnUnsafeL2PayloadFn = func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) { - received3 = append(received3, payload.ExecutionPayload.BlockHash) - } - cfg.Nodes["sequencer"].Tracer = seqTracer - cfg.Nodes["verifier"].Tracer = verifTracer - cfg.Nodes["verifier2"].Tracer = verifTracer2 - cfg.Nodes["verifier3"].Tracer = verifTracer3 - - sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") - - l2Seq := sys.NodeClient("sequencer") - l2Verif := sys.NodeClient("verifier") - l2Verif2 := sys.NodeClient("verifier2") - l2Verif3 := sys.NodeClient("verifier3") - - // Transactor Account - ethPrivKey := cfg.Secrets.Alice - - // Submit TX to L2 sequencer node - receiptSeq := SendL2Tx(t, cfg, l2Seq, ethPrivKey, func(opts *TxOpts) { - opts.ToAddr = &common.Address{0xff, 0xff} - opts.Value = big.NewInt(1_000_000_000) - - // Wait until the block it was first included in shows up in the safe chain on the verifiers - opts.VerifyOnClients(l2Verif, l2Verif2, l2Verif3) - }) - - // Verify that everything that was received was published - require.GreaterOrEqual(t, len(published), len(received1)) - require.GreaterOrEqual(t, len(published), len(received2)) - require.GreaterOrEqual(t, len(published), len(received3)) - require.ElementsMatch(t, published, received1[:len(published)]) - require.ElementsMatch(t, published, received2[:len(published)]) - require.ElementsMatch(t, published, received3[:len(published)]) - - // Verify that the tx was received via p2p - require.Contains(t, received1, receiptSeq.BlockHash) - require.Contains(t, received2, receiptSeq.BlockHash) - require.Contains(t, received3, receiptSeq.BlockHash) -} - -func TestL1InfoContract(t *testing.T) { - InitParallel(t) - - cfg := DefaultSystemConfig(t) - - sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") - - l1Client := sys.NodeClient("l1") - l2Seq := sys.NodeClient("sequencer") - l2Verif := sys.NodeClient("verifier") - - endVerifBlockNumber := big.NewInt(4) - endSeqBlockNumber := big.NewInt(6) - endVerifBlock, err := geth.WaitForBlock(endVerifBlockNumber, l2Verif, time.Minute) - require.Nil(t, err) - endSeqBlock, err := geth.WaitForBlock(endSeqBlockNumber, l2Seq, time.Minute) - require.Nil(t, err) - - seqL1Info, err := bindings.NewL1Block(cfg.L1InfoPredeployAddress, l2Seq) - require.Nil(t, err) - - verifL1Info, err := bindings.NewL1Block(cfg.L1InfoPredeployAddress, l2Verif) - require.Nil(t, err) - - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - defer cancel() - - fillInfoLists := func(start *types.Block, contract *bindings.L1Block, client *ethclient.Client) ([]*derive.L1BlockInfo, []*derive.L1BlockInfo) { - var txList, stateList []*derive.L1BlockInfo - for b := start; ; { - var infoFromTx *derive.L1BlockInfo - infoFromTx, err := derive.L1BlockInfoFromBytes(sys.RollupConfig, b.Time(), b.Transactions()[0].Data()) - require.NoError(t, err) - txList = append(txList, infoFromTx) - - ecotone := sys.RollupConfig.IsEcotone(b.Time()) && !sys.RollupConfig.IsEcotoneActivationBlock(b.Time()) - infoFromState, err := L1InfoFromState(ctx, contract, b.Number(), ecotone) - require.Nil(t, err) - stateList = append(stateList, infoFromState) - - // Genesis L2 block contains no L1 Deposit TX - if b.NumberU64() == 1 { - return txList, stateList - } - b, err = client.BlockByHash(ctx, b.ParentHash()) - require.Nil(t, err) - } - } - - l1InfosFromSequencerTransactions, l1InfosFromSequencerState := fillInfoLists(endSeqBlock, seqL1Info, l2Seq) - l1InfosFromVerifierTransactions, l1InfosFromVerifierState := fillInfoLists(endVerifBlock, verifL1Info, l2Verif) - - l1blocks := make(map[common.Hash]*derive.L1BlockInfo) - maxL1Hash := l1InfosFromSequencerTransactions[0].BlockHash - for h := maxL1Hash; ; { - b, err := l1Client.BlockByHash(ctx, h) - require.Nil(t, err) - - l1blocks[h] = &derive.L1BlockInfo{ - Number: b.NumberU64(), - Time: b.Time(), - BaseFee: b.BaseFee(), - BlockHash: h, - SequenceNumber: 0, // ignored, will be overwritten - BatcherAddr: sys.RollupConfig.Genesis.SystemConfig.BatcherAddr, - } - if sys.RollupConfig.IsEcotone(b.Time()) && !sys.RollupConfig.IsEcotoneActivationBlock(b.Time()) { - scalars, err := sys.RollupConfig.Genesis.SystemConfig.EcotoneScalars() - require.NoError(t, err) - l1blocks[h].BlobBaseFeeScalar = scalars.BlobBaseFeeScalar - l1blocks[h].BaseFeeScalar = scalars.BaseFeeScalar - if excess := b.ExcessBlobGas(); excess != nil { - l1blocks[h].BlobBaseFee = eip4844.CalcBlobFee(*excess) - } else { - l1blocks[h].BlobBaseFee = big.NewInt(1) - } - } else { - l1blocks[h].L1FeeOverhead = sys.RollupConfig.Genesis.SystemConfig.Overhead - l1blocks[h].L1FeeScalar = sys.RollupConfig.Genesis.SystemConfig.Scalar - } - - h = b.ParentHash() - if b.NumberU64() == 0 { - break - } - } - - checkInfoList := func(name string, list []*derive.L1BlockInfo) { - for _, info := range list { - if expected, ok := l1blocks[info.BlockHash]; ok { - expected.SequenceNumber = info.SequenceNumber // the seq nr is not part of the L1 info we know in advance, so we ignore it. - require.Equal(t, expected, info) - } else { - t.Fatalf("Did not find block hash for L1 Info: %v in test %s", info, name) - } - } - } - - checkInfoList("On sequencer with tx", l1InfosFromSequencerTransactions) - checkInfoList("On sequencer with state", l1InfosFromSequencerState) - checkInfoList("On verifier with tx", l1InfosFromVerifierTransactions) - checkInfoList("On verifier with state", l1InfosFromVerifierState) -} - -// TestWithdrawals checks that a deposit and then withdrawal execution succeeds. It verifies the -// balance changes on L1 and L2 and has to include gas fees in the balance checks. -// It does not check that the withdrawal can be executed prior to the end of the finality period. -func TestWithdrawals(t *testing.T) { - InitParallel(t) - - cfg := DefaultSystemConfig(t) - cfg.DeployConfig.FinalizationPeriodSeconds = 2 // 2s finalization period - cfg.L1FinalizedDistance = 2 // Finalize quick, don't make the proposer wait too long - - sys, err := cfg.Start(t) - require.NoError(t, err, "Error starting up system") - - RunWithdrawalsTest(t, sys) -} - -type stateGetterAdapter struct { - ctx context.Context - t *testing.T - client *ethclient.Client - blockNum *big.Int -} - -func (sga *stateGetterAdapter) GetState(addr common.Address, key common.Hash) common.Hash { - sga.t.Helper() - val, err := sga.client.StorageAt(sga.ctx, addr, key, sga.blockNum) - require.NoError(sga.t, err) - var res common.Hash - copy(res[:], val) - return res -} - -// TestFees checks that L1/L2 fees are handled. -func TestFees(t *testing.T) { - t.Run("pre-regolith", func(t *testing.T) { - InitParallel(t) - cfg := RegolithSystemConfig(t, nil) - cfg.DeployConfig.L1GenesisBlockBaseFeePerGas = (*hexutil.Big)(big.NewInt(7)) - - testFees(t, cfg) - }) - t.Run("regolith", func(t *testing.T) { - InitParallel(t) - cfg := RegolithSystemConfig(t, &genesisTime) - cfg.DeployConfig.L1GenesisBlockBaseFeePerGas = (*hexutil.Big)(big.NewInt(7)) - - testFees(t, cfg) - }) - t.Run("ecotone", func(t *testing.T) { - InitParallel(t) - cfg := EcotoneSystemConfig(t, &genesisTime) - cfg.DeployConfig.L1GenesisBlockBaseFeePerGas = (*hexutil.Big)(big.NewInt(7)) - - testFees(t, cfg) - }) - t.Run("fjord", func(t *testing.T) { - InitParallel(t) - cfg := DefaultSystemConfig(t) - cfg.DeployConfig.L1GenesisBlockBaseFeePerGas = (*hexutil.Big)(big.NewInt(7)) - - cfg.DeployConfig.L2GenesisRegolithTimeOffset = new(hexutil.Uint64) - cfg.DeployConfig.L2GenesisCanyonTimeOffset = new(hexutil.Uint64) - cfg.DeployConfig.L2GenesisDeltaTimeOffset = new(hexutil.Uint64) - cfg.DeployConfig.L2GenesisEcotoneTimeOffset = new(hexutil.Uint64) - cfg.DeployConfig.L2GenesisFjordTimeOffset = new(hexutil.Uint64) - testFees(t, cfg) - }) -} - -func testFees(t *testing.T, cfg SystemConfig) { - sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") - - l2Seq := sys.NodeClient("sequencer") - l2Verif := sys.NodeClient("verifier") - l1 := sys.NodeClient("l1") - - // Wait for first block after genesis. The genesis block has zero L1Block values and will throw off the GPO checks - _, err = geth.WaitForBlock(big.NewInt(1), l2Verif, time.Minute) - require.NoError(t, err) - - config := sys.L2Genesis().Config - - sga := &stateGetterAdapter{ - ctx: context.Background(), - t: t, - client: l2Seq, - } - - l1CostFn := types.NewL1CostFunc(config, sga) - - // Transactor Account - ethPrivKey := cfg.Secrets.Alice - fromAddr := crypto.PubkeyToAddress(ethPrivKey.PublicKey) - - require.NotEqual(t, cfg.DeployConfig.L2OutputOracleProposer, fromAddr) - require.NotEqual(t, cfg.DeployConfig.BatchSenderAddress, fromAddr) - - // Find gaspriceoracle contract - gpoContract, err := bindings.NewGasPriceOracle(predeploys.GasPriceOracleAddr, l2Seq) - require.Nil(t, err) - - if !sys.RollupConfig.IsEcotone(sys.L2GenesisCfg.Timestamp) { - overhead, err := gpoContract.Overhead(&bind.CallOpts{}) - require.Nil(t, err, "reading gpo overhead") - require.Equal(t, overhead.Uint64(), cfg.DeployConfig.GasPriceOracleOverhead, "wrong gpo overhead") - - scalar, err := gpoContract.Scalar(&bind.CallOpts{}) - require.Nil(t, err, "reading gpo scalar") - feeScalar := cfg.DeployConfig.FeeScalar() - require.Equal(t, scalar, new(big.Int).SetBytes(feeScalar[:]), "wrong gpo scalar") - } else { - _, err := gpoContract.Overhead(&bind.CallOpts{}) - require.ErrorContains(t, err, "deprecated") - _, err = gpoContract.Scalar(&bind.CallOpts{}) - require.ErrorContains(t, err, "deprecated") - } - - decimals, err := gpoContract.Decimals(&bind.CallOpts{}) - require.Nil(t, err, "reading gpo decimals") - - require.Equal(t, decimals.Uint64(), uint64(6), "wrong gpo decimals") - - // BaseFee Recipient - baseFeeRecipientStartBalance, err := l2Seq.BalanceAt(context.Background(), predeploys.BaseFeeVaultAddr, big.NewInt(rpc.EarliestBlockNumber.Int64())) - require.Nil(t, err) - - // L1Fee Recipient - l1FeeRecipientStartBalance, err := l2Seq.BalanceAt(context.Background(), predeploys.L1FeeVaultAddr, big.NewInt(rpc.EarliestBlockNumber.Int64())) - require.Nil(t, err) - - sequencerFeeVaultStartBalance, err := l2Seq.BalanceAt(context.Background(), predeploys.SequencerFeeVaultAddr, big.NewInt(rpc.EarliestBlockNumber.Int64())) - require.Nil(t, err) - - genesisBlock, err := l2Seq.BlockByNumber(context.Background(), big.NewInt(rpc.EarliestBlockNumber.Int64())) - require.NoError(t, err) - - coinbaseStartBalance, err := l2Seq.BalanceAt(context.Background(), genesisBlock.Coinbase(), big.NewInt(rpc.EarliestBlockNumber.Int64())) - require.NoError(t, err) - - // Simple transfer from signer to random account - startBalance, err := l2Seq.BalanceAt(context.Background(), fromAddr, big.NewInt(rpc.EarliestBlockNumber.Int64())) - require.Nil(t, err) - require.Greater(t, startBalance.Uint64(), big.NewInt(params.Ether).Uint64()) - - transferAmount := big.NewInt(params.Ether) - gasTip := big.NewInt(10) - receipt := SendL2Tx(t, cfg, l2Seq, ethPrivKey, func(opts *TxOpts) { - opts.ToAddr = &common.Address{0xff, 0xff} - opts.Value = transferAmount - opts.GasTipCap = gasTip - opts.Gas = 21000 - opts.GasFeeCap = big.NewInt(200) - opts.VerifyOnClients(l2Verif) - }) - - require.Equal(t, receipt.Status, types.ReceiptStatusSuccessful) - - header, err := l2Seq.HeaderByNumber(context.Background(), receipt.BlockNumber) - require.Nil(t, err) - - coinbaseEndBalance, err := l2Seq.BalanceAt(context.Background(), header.Coinbase, header.Number) - require.Nil(t, err) - - endBalance, err := l2Seq.BalanceAt(context.Background(), fromAddr, header.Number) - require.Nil(t, err) - - baseFeeRecipientEndBalance, err := l2Seq.BalanceAt(context.Background(), predeploys.BaseFeeVaultAddr, header.Number) - require.Nil(t, err) - - l1Header, err := l1.HeaderByNumber(context.Background(), nil) - require.Nil(t, err) - - l1FeeRecipientEndBalance, err := l2Seq.BalanceAt(context.Background(), predeploys.L1FeeVaultAddr, header.Number) - require.Nil(t, err) - - sequencerFeeVaultEndBalance, err := l2Seq.BalanceAt(context.Background(), predeploys.SequencerFeeVaultAddr, header.Number) - require.Nil(t, err) - - // Diff fee recipient + coinbase balances - baseFeeRecipientDiff := new(big.Int).Sub(baseFeeRecipientEndBalance, baseFeeRecipientStartBalance) - l1FeeRecipientDiff := new(big.Int).Sub(l1FeeRecipientEndBalance, l1FeeRecipientStartBalance) - sequencerFeeVaultDiff := new(big.Int).Sub(sequencerFeeVaultEndBalance, sequencerFeeVaultStartBalance) - coinbaseDiff := new(big.Int).Sub(coinbaseEndBalance, coinbaseStartBalance) - - // Tally L2 Fee - l2Fee := gasTip.Mul(gasTip, new(big.Int).SetUint64(receipt.GasUsed)) - require.Equal(t, sequencerFeeVaultDiff, coinbaseDiff, "coinbase is always sequencer fee vault") - require.Equal(t, l2Fee, coinbaseDiff, "l2 fee mismatch") - require.Equal(t, l2Fee, sequencerFeeVaultDiff) - - // Tally BaseFee - baseFee := new(big.Int).Mul(header.BaseFee, new(big.Int).SetUint64(receipt.GasUsed)) - require.Equal(t, baseFee, baseFeeRecipientDiff, "base fee mismatch") - - // Tally L1 Fee - tx, _, err := l2Seq.TransactionByHash(context.Background(), receipt.TxHash) - require.NoError(t, err, "Should be able to get transaction") - bytes, err := tx.MarshalBinary() - require.Nil(t, err) - - l1Fee := l1CostFn(tx.RollupCostData(), header.Time) - require.Equalf(t, l1Fee, l1FeeRecipientDiff, "L1 fee mismatch: start balance %v, end balance %v", l1FeeRecipientStartBalance, l1FeeRecipientEndBalance) - - gpoEcotone, err := gpoContract.IsEcotone(nil) - require.NoError(t, err) - require.Equal(t, sys.RollupConfig.IsEcotone(header.Time), gpoEcotone, "GPO and chain must have same ecotone view") - - gpoFjord, err := gpoContract.IsFjord(nil) - require.NoError(t, err) - require.Equal(t, sys.RollupConfig.IsFjord(header.Time), gpoFjord, "GPO and chain must have same fjord view") - - gpoL1Fee, err := gpoContract.GetL1Fee(&bind.CallOpts{}, bytes) - require.Nil(t, err) - - adjustedGPOFee := gpoL1Fee - if sys.RollupConfig.IsFjord(header.Time) { - // The fastlz size of the transaction is 102 bytes - require.Equal(t, uint64(102), tx.RollupCostData().FastLzSize) - // Which results in both the fjord cost function and GPO using the minimum value for the fastlz regression: - // Geth Linear Regression: -42.5856 + 102 * 0.8365 = 42.7374 - // GPO Linear Regression: -42.5856 + 170 * 0.8365 = 99.6194 - // The additional 68 (170 vs. 102) is due to the GPO adding 68 bytes to account for the signature. - require.Greater(t, types.MinTransactionSize.Uint64(), uint64(99)) - // Because of this, we don't need to do any adjustment as the GPO and cost func are both bounded to the minimum value. - // However, if the fastlz regression output is ever larger than the minimum, this will require an adjustment. - } else if sys.RollupConfig.IsRegolith(header.Time) { - // if post-regolith, adjust the GPO fee by removing the overhead it adds because of signature data - artificialGPOOverhead := big.NewInt(68 * 16) // it adds 68 bytes to cover signature and RLP data - l1BaseFee := big.NewInt(7) // we assume the L1 basefee is the minimum, 7 - // in our case we already include that, so we subtract it, to do a 1:1 comparison - adjustedGPOFee = new(big.Int).Sub(gpoL1Fee, new(big.Int).Mul(artificialGPOOverhead, l1BaseFee)) - } - require.Equal(t, l1Fee, adjustedGPOFee, "GPO reports L1 fee mismatch") - - require.Equal(t, receipt.L1Fee, l1Fee, "l1 fee in receipt is correct") - if !sys.RollupConfig.IsEcotone(header.Time) { // FeeScalar receipt attribute is removed as of Ecotone - require.Equal(t, - new(big.Float).Mul( - new(big.Float).SetInt(l1Header.BaseFee), - new(big.Float).Mul(new(big.Float).SetInt(receipt.L1GasUsed), receipt.FeeScalar), - ), - new(big.Float).SetInt(receipt.L1Fee), "fee field in receipt matches gas used times scalar times base fee") - } - - // Calculate total fee - baseFeeRecipientDiff.Add(baseFeeRecipientDiff, coinbaseDiff) - totalFee := new(big.Int).Add(baseFeeRecipientDiff, l1FeeRecipientDiff) - balanceDiff := new(big.Int).Sub(startBalance, endBalance) - balanceDiff.Sub(balanceDiff, transferAmount) - require.Equal(t, balanceDiff, totalFee, "balances should add up") -} - -func StopStartBatcher(t *testing.T, cfgMod func(*SystemConfig)) { - InitParallel(t) - - cfg := DefaultSystemConfig(t) - cfgMod(&cfg) - sys, err := cfg.Start(t) - require.NoError(t, err, "Error starting up system") - - rollupClient := sys.RollupClient("verifier") - - l2Seq := sys.NodeClient("sequencer") - l2Verif := sys.NodeClient("verifier") - - // retrieve the initial sync status - seqStatus, err := rollupClient.SyncStatus(context.Background()) - require.NoError(t, err) - - nonce := uint64(0) - sendTx := func() *types.Receipt { - // Submit TX to L2 sequencer node - receipt := SendL2Tx(t, cfg, l2Seq, cfg.Secrets.Alice, func(opts *TxOpts) { - opts.ToAddr = &common.Address{0xff, 0xff} - opts.Value = big.NewInt(1_000_000_000) - opts.Nonce = nonce - }) - nonce++ - return receipt - } - // send a transaction - receipt := sendTx() - - // wait until the block the tx was first included in shows up in the safe chain on the verifier - safeBlockInclusionDuration := time.Duration(6*cfg.DeployConfig.L1BlockTime) * time.Second - _, err = geth.WaitForBlock(receipt.BlockNumber, l2Verif, safeBlockInclusionDuration) - require.NoError(t, err, "Waiting for block on verifier") - require.NoError(t, wait.ForProcessingFullBatch(context.Background(), rollupClient)) - - // ensure the safe chain advances - newSeqStatus, err := rollupClient.SyncStatus(context.Background()) - require.NoError(t, err) - require.Greater(t, newSeqStatus.SafeL2.Number, seqStatus.SafeL2.Number, "Safe chain did not advance") - - driver := sys.BatchSubmitter.TestDriver() - // stop the batch submission - err = driver.StopBatchSubmitting(context.Background()) - require.NoError(t, err) - - // wait for any old safe blocks being submitted / derived - time.Sleep(safeBlockInclusionDuration) - - // get the initial sync status - seqStatus, err = rollupClient.SyncStatus(context.Background()) - require.NoError(t, err) - - // send another tx - sendTx() - time.Sleep(safeBlockInclusionDuration) - - // ensure that the safe chain does not advance while the batcher is stopped - newSeqStatus, err = rollupClient.SyncStatus(context.Background()) - require.NoError(t, err) - require.Equal(t, newSeqStatus.SafeL2.Number, seqStatus.SafeL2.Number, "Safe chain advanced while batcher was stopped") - - // start the batch submission - err = driver.StartBatchSubmitting() - require.NoError(t, err) - time.Sleep(safeBlockInclusionDuration) - - // send a third tx - receipt = sendTx() - - // wait until the block the tx was first included in shows up in the safe chain on the verifier - _, err = geth.WaitForBlock(receipt.BlockNumber, l2Verif, safeBlockInclusionDuration) - require.NoError(t, err, "Waiting for block on verifier") - require.NoError(t, wait.ForProcessingFullBatch(context.Background(), rollupClient)) - - // ensure that the safe chain advances after restarting the batcher - newSeqStatus, err = rollupClient.SyncStatus(context.Background()) - require.NoError(t, err) - require.Greater(t, newSeqStatus.SafeL2.Number, seqStatus.SafeL2.Number, "Safe chain did not advance after batcher was restarted") -} - -func TestBatcherMultiTx(t *testing.T) { - InitParallel(t) - - cfg := DefaultSystemConfig(t) - cfg.BatcherMaxPendingTransactions = 0 // no limit on parallel txs - // ensures that batcher txs are as small as possible - cfg.BatcherMaxL1TxSizeBytes = derive.FrameV0OverHeadSize + 1 /*version bytes*/ + 1 - cfg.DisableBatcher = true - sys, err := cfg.Start(t) - require.NoError(t, err, "Error starting up system") - - l1Client := sys.NodeClient("l1") - l2Seq := sys.NodeClient("sequencer") - - _, err = geth.WaitForBlock(big.NewInt(10), l2Seq, time.Duration(cfg.DeployConfig.L2BlockTime*15)*time.Second) - require.NoError(t, err, "Waiting for L2 blocks") - - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - l1Number, err := l1Client.BlockNumber(ctx) - require.NoError(t, err) - - // start batch submission - driver := sys.BatchSubmitter.TestDriver() - err = driver.StartBatchSubmitting() - require.NoError(t, err) - - totalBatcherTxsCount := int64(0) - // wait for up to 5 L1 blocks, usually only 3 is required, but it's - // possible additional L1 blocks will be created before the batcher starts, - // so we wait additional blocks. - for i := int64(0); i < 5; i++ { - block, err := geth.WaitForBlock(big.NewInt(int64(l1Number)+i), l1Client, time.Duration(cfg.DeployConfig.L1BlockTime*2)*time.Second) - require.NoError(t, err, "Waiting for l1 blocks") - // there are possibly other services (proposer/challenger) in the background sending txs - // so we only count the batcher txs - batcherTxCount, err := transactions.TransactionsBySender(block, cfg.DeployConfig.BatchSenderAddress) - require.NoError(t, err) - totalBatcherTxsCount += int64(batcherTxCount) - - if totalBatcherTxsCount >= 10 { - return - } - } - - t.Fatal("Expected at least 10 transactions from the batcher") -} - -func TestBatcherConcurrentAltDARequests(t *testing.T) { - InitParallel(t) - - numL1TxsExpected := int64(10) - - cfg := DefaultSystemConfig(t) - cfg.DeployConfig.UseAltDA = true - cfg.BatcherMaxPendingTransactions = 0 // no limit on parallel txs - // ensures that batcher txs are as small as possible - cfg.BatcherMaxL1TxSizeBytes = derive.FrameV0OverHeadSize + 1 /*version bytes*/ + 1 - cfg.BatcherBatchType = 0 - cfg.DataAvailabilityType = flags.CalldataType - cfg.BatcherMaxConcurrentDARequest = uint64(numL1TxsExpected) - - // disable batcher because we start it manually below - cfg.DisableBatcher = true - sys, err := cfg.Start(t) - require.NoError(t, err, "Error starting up system") - defer sys.Close() - - // make every request take 5 seconds, such that only concurrent requests will be able to make progress fast enough - sys.FakeAltDAServer.SetPutRequestLatency(5 * time.Second) - - l1Client := sys.NodeClient("l1") - l2Seq := sys.NodeClient("sequencer") - - // we wait for numL1TxsExpected L2 blocks to have been produced, just to make sure the sequencer is working properly - _, err = geth.WaitForBlock(big.NewInt(numL1TxsExpected), l2Seq, time.Duration(cfg.DeployConfig.L2BlockTime*uint64(numL1TxsExpected))*time.Second) - require.NoError(t, err, "Waiting for L2 blocks") - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - startingL1BlockNum, err := l1Client.BlockNumber(ctx) - require.NoError(t, err) - - // start batch submission - driver := sys.BatchSubmitter.TestDriver() - err = driver.StartBatchSubmitting() - require.NoError(t, err) - - totalBatcherTxsCount := int64(0) - // wait for up to 5 L1 blocks, expecting 10 L2 batcher txs in them. - // usually only 3 is required, but it's possible additional L1 blocks will be created - // before the batcher starts, so we wait additional blocks. - for i := int64(0); i < 5; i++ { - block, err := geth.WaitForBlock(big.NewInt(int64(startingL1BlockNum)+i), l1Client, time.Duration(cfg.DeployConfig.L1BlockTime*2)*time.Second) - require.NoError(t, err, "Waiting for l1 blocks") - // there are possibly other services (proposer/challenger) in the background sending txs - // so we only count the batcher txs - batcherTxCount, err := transactions.TransactionsBySender(block, cfg.DeployConfig.BatchSenderAddress) - require.NoError(t, err) - totalBatcherTxsCount += int64(batcherTxCount) - - if totalBatcherTxsCount >= numL1TxsExpected { - return - } - } - - t.Fatal("Expected at least 10 transactions from the batcher") -} - -func latestBlock(t *testing.T, client *ethclient.Client) uint64 { - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - blockAfter, err := client.BlockNumber(ctx) - require.Nil(t, err, "Error getting latest block") - return blockAfter -} - -// TestPendingBlockIsLatest tests that we serve the latest block as pending block -func TestPendingBlockIsLatest(t *testing.T) { - InitParallel(t) - - cfg := DefaultSystemConfig(t) - sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") - - l2Seq := sys.NodeClient("sequencer") - - t.Run("block", func(t *testing.T) { - for i := 0; i < 10; i++ { - // TODO(CLI-4044): pending-block ID change - pending, err := l2Seq.BlockByNumber(context.Background(), big.NewInt(-1)) - require.NoError(t, err) - latest, err := l2Seq.BlockByNumber(context.Background(), nil) - require.NoError(t, err) - if pending.NumberU64() == latest.NumberU64() { - require.Equal(t, pending.Hash(), latest.Hash(), "pending must exactly match latest block") - return - } - // re-try until we have the same number, as the requests are not an atomic bundle, and the sequencer may create a block. - } - t.Fatal("failed to get pending block with same number as latest block") - }) - t.Run("header", func(t *testing.T) { - for i := 0; i < 10; i++ { - // TODO(CLI-4044): pending-block ID change - pending, err := l2Seq.HeaderByNumber(context.Background(), big.NewInt(-1)) - require.NoError(t, err) - latest, err := l2Seq.HeaderByNumber(context.Background(), nil) - require.NoError(t, err) - if pending.Number.Uint64() == latest.Number.Uint64() { - require.Equal(t, pending.Hash(), latest.Hash(), "pending must exactly match latest header") - return - } - // re-try until we have the same number, as the requests are not an atomic bundle, and the sequencer may create a block. - } - t.Fatal("failed to get pending header with same number as latest header") - }) -} - -func TestRuntimeConfigReload(t *testing.T) { - InitParallel(t) - - cfg := DefaultSystemConfig(t) - // to speed up the test, make it reload the config more often, and do not impose a long conf depth - cfg.Nodes["verifier"].RuntimeConfigReloadInterval = time.Second * 5 - cfg.Nodes["verifier"].Driver.VerifierConfDepth = 1 - - sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") - - initialRuntimeConfig := sys.RollupNodes["verifier"].RuntimeConfig() - - // close the EL node, since we want to block derivation, to solely rely on the reloading mechanism for updates. - sys.EthInstances["verifier"].Close() - - l1 := sys.NodeClient("l1") - - // Change the system-config via L1 - sysCfgContract, err := bindings.NewSystemConfig(cfg.L1Deployments.SystemConfigProxy, l1) - require.NoError(t, err) - newUnsafeBlocksSigner := common.Address{0x12, 0x23, 0x45} - require.NotEqual(t, initialRuntimeConfig.P2PSequencerAddress(), newUnsafeBlocksSigner, "changing to a different address") - opts, err := bind.NewKeyedTransactorWithChainID(cfg.Secrets.SysCfgOwner, cfg.L1ChainIDBig()) - require.Nil(t, err) - // the unsafe signer address is part of the runtime config - tx, err := sysCfgContract.SetUnsafeBlockSigner(opts, newUnsafeBlocksSigner) - require.NoError(t, err) - - // wait for the change to confirm - _, err = wait.ForReceiptOK(context.Background(), l1, tx.Hash()) - require.NoError(t, err) - - // wait for the address to change - _, err = retry.Do(context.Background(), 10, retry.Fixed(time.Second*10), func() (struct{}, error) { - v := sys.RollupNodes["verifier"].RuntimeConfig().P2PSequencerAddress() - if v == newUnsafeBlocksSigner { - return struct{}{}, nil - } - return struct{}{}, fmt.Errorf("no change yet, seeing %s but looking for %s", v, newUnsafeBlocksSigner) - }) - require.NoError(t, err) -} - -func TestRecommendedProtocolVersionChange(t *testing.T) { - InitParallel(t) - - cfg := DefaultSystemConfig(t) - require.NotEqual(t, common.Address{}, cfg.L1Deployments.ProtocolVersions, "need ProtocolVersions contract deployment") - // to speed up the test, make it reload the config more often, and do not impose a long conf depth - cfg.Nodes["verifier"].RuntimeConfigReloadInterval = time.Second * 5 - cfg.Nodes["verifier"].Driver.VerifierConfDepth = 1 - - sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") - - runtimeConfig := sys.RollupNodes["verifier"].RuntimeConfig() - - // Change the superchain-config via L1 - l1 := sys.NodeClient("l1") - - _, build, major, minor, patch, preRelease := params.OPStackSupport.Parse() - newRecommendedProtocolVersion := params.ProtocolVersionV0{Build: build, Major: major + 1, Minor: minor, Patch: patch, PreRelease: preRelease}.Encode() - require.NotEqual(t, runtimeConfig.RecommendedProtocolVersion(), newRecommendedProtocolVersion, "changing to a different protocol version") - - protVersions, err := bindings.NewProtocolVersions(cfg.L1Deployments.ProtocolVersionsProxy, l1) - require.NoError(t, err) - - // ProtocolVersions contract is owned by same key as SystemConfig in devnet - opts, err := bind.NewKeyedTransactorWithChainID(cfg.Secrets.SysCfgOwner, cfg.L1ChainIDBig()) - require.NoError(t, err) - - // Change recommended protocol version - tx, err := protVersions.SetRecommended(opts, new(big.Int).SetBytes(newRecommendedProtocolVersion[:])) - require.NoError(t, err) - - // wait for the change to confirm - _, err = wait.ForReceiptOK(context.Background(), l1, tx.Hash()) - require.NoError(t, err) - - // wait for the recommended protocol version to change - _, err = retry.Do(context.Background(), 10, retry.Fixed(time.Second*10), func() (struct{}, error) { - v := sys.RollupNodes["verifier"].RuntimeConfig().RecommendedProtocolVersion() - if v == newRecommendedProtocolVersion { - return struct{}{}, nil - } - return struct{}{}, fmt.Errorf("no change yet, seeing %s but looking for %s", v, newRecommendedProtocolVersion) - }) - require.NoError(t, err) -} - -func TestRequiredProtocolVersionChangeAndHalt(t *testing.T) { - InitParallel(t) - - cfg := DefaultSystemConfig(t) - // to speed up the test, make it reload the config more often, and do not impose a long conf depth - cfg.Nodes["verifier"].RuntimeConfigReloadInterval = time.Second * 5 - cfg.Nodes["verifier"].Driver.VerifierConfDepth = 1 - // configure halt in verifier op-node - cfg.Nodes["verifier"].RollupHalt = "major" - // configure halt in verifier op-geth node - cfg.GethOptions["verifier"] = append(cfg.GethOptions["verifier"], []geth.GethOption{ - func(ethCfg *ethconfig.Config, nodeCfg *node.Config) error { - ethCfg.RollupHaltOnIncompatibleProtocolVersion = "major" - return nil - }, - }...) - - sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") - - runtimeConfig := sys.RollupNodes["verifier"].RuntimeConfig() - - // Change the superchain-config via L1 - l1 := sys.NodeClient("l1") - - _, build, major, minor, patch, preRelease := params.OPStackSupport.Parse() - newRequiredProtocolVersion := params.ProtocolVersionV0{Build: build, Major: major + 1, Minor: minor, Patch: patch, PreRelease: preRelease}.Encode() - require.NotEqual(t, runtimeConfig.RequiredProtocolVersion(), newRequiredProtocolVersion, "changing to a different protocol version") - - protVersions, err := bindings.NewProtocolVersions(cfg.L1Deployments.ProtocolVersionsProxy, l1) - require.NoError(t, err) - - // ProtocolVersions contract is owned by same key as SystemConfig in devnet - opts, err := bind.NewKeyedTransactorWithChainID(cfg.Secrets.SysCfgOwner, cfg.L1ChainIDBig()) - require.NoError(t, err) - - // Change required protocol version - tx, err := protVersions.SetRequired(opts, new(big.Int).SetBytes(newRequiredProtocolVersion[:])) - require.NoError(t, err) - - // wait for the change to confirm - _, err = wait.ForReceiptOK(context.Background(), l1, tx.Hash()) - require.NoError(t, err) - - // wait for the required protocol version to take effect by halting the verifier that opted in, and halting the op-geth node that opted in. - _, err = retry.Do(context.Background(), 10, retry.Fixed(time.Second*10), func() (struct{}, error) { - if !sys.RollupNodes["verifier"].Stopped() { - return struct{}{}, errors.New("verifier rollup node is not closed yet") - } - return struct{}{}, nil - }) - require.NoError(t, err) - t.Log("verified that op-node closed!") - // Checking if the engine is down is not trivial in op-e2e. - // In op-geth we have halting tests covering the Engine API, in op-e2e we instead check if the API stops. - _, err = retry.Do(context.Background(), 10, retry.Fixed(time.Second*10), func() (struct{}, error) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - available := client.IsURLAvailable(ctx, sys.NodeEndpoint("verifier").(endpoint.HttpRPC).HttpRPC()) - if !available && ctx.Err() == nil { // waiting for client to stop responding to RPC requests (slow dials with timeout don't count) - return struct{}{}, nil - } - return struct{}{}, errors.New("verifier EL node is not closed yet") - }) - require.NoError(t, err) - t.Log("verified that op-geth closed!") -} From 45b4b1f01d4b45548bb988b64bdda441108d2018 Mon Sep 17 00:00:00 2001 From: Matt Solomon Date: Tue, 17 Sep 2024 06:14:19 -0700 Subject: [PATCH 161/264] OPSM: miscellaneous fixes and improvements (#11935) * chore: fix comment * feat: add assertions * fix: use method instead of new * refactor: make salt into an input * refactor: unify checkOutput function signatures * chore: update snapshots * test: fix testContractAuth * test: fix checkOutput signatures * fix: update go DeployImplementationsInput struct with salt * pr feedback * chore: semver lock --- op-chain-ops/deployer/opsm/implementations.go | 3 +- op-chain-ops/deployer/opsm/opchain.go | 2 +- op-chain-ops/deployer/opsm/superchain.go | 2 +- .../scripts/DeployImplementations.s.sol | 19 +++- .../scripts/DeployOPChain.s.sol | 49 +++++++++- .../scripts/DeploySuperchain.s.sol | 4 +- packages/contracts-bedrock/semver-lock.json | 4 +- .../snapshots/abi/OPStackManager.json | 30 +++--- .../snapshots/abi/OPStackManagerInterop.json | 30 +++--- .../src/L1/OPStackManager.sol | 94 +++++++------------ .../src/L1/OPStackManagerInterop.sol | 2 +- .../test/DeployImplementations.t.sol | 2 +- .../test/DeployOPChain.t.sol | 2 +- .../test/DeploySuperchain.t.sol | 2 +- packages/contracts-bedrock/test/Specs.t.sol | 2 + 15 files changed, 149 insertions(+), 98 deletions(-) diff --git a/op-chain-ops/deployer/opsm/implementations.go b/op-chain-ops/deployer/opsm/implementations.go index d5b576fb9cb6..c29a73a6437f 100644 --- a/op-chain-ops/deployer/opsm/implementations.go +++ b/op-chain-ops/deployer/opsm/implementations.go @@ -10,6 +10,7 @@ import ( ) type DeployImplementationsInput struct { + Salt common.Hash WithdrawalDelaySeconds *big.Int MinProposalSizeBytes *big.Int ChallengePeriodSeconds *big.Int @@ -42,7 +43,7 @@ type DeployImplementationsOutput struct { DisputeGameFactoryImpl common.Address } -func (output *DeployImplementationsOutput) CheckOutput() error { +func (output *DeployImplementationsOutput) CheckOutput(input common.Address) error { return nil } diff --git a/op-chain-ops/deployer/opsm/opchain.go b/op-chain-ops/deployer/opsm/opchain.go index 6bab3fdbfe75..b67eba701f93 100644 --- a/op-chain-ops/deployer/opsm/opchain.go +++ b/op-chain-ops/deployer/opsm/opchain.go @@ -48,7 +48,7 @@ type DeployOPChainOutput struct { DelayedWETHPermissionlessGameProxy common.Address } -func (output *DeployOPChainOutput) CheckOutput() error { +func (output *DeployOPChainOutput) CheckOutput(input common.Address) error { return nil } diff --git a/op-chain-ops/deployer/opsm/superchain.go b/op-chain-ops/deployer/opsm/superchain.go index 0505d34760a9..d27f85499021 100644 --- a/op-chain-ops/deployer/opsm/superchain.go +++ b/op-chain-ops/deployer/opsm/superchain.go @@ -34,7 +34,7 @@ type DeploySuperchainOutput struct { ProtocolVersionsProxy common.Address } -func (output *DeploySuperchainOutput) CheckOutput() error { +func (output *DeploySuperchainOutput) CheckOutput(input common.Address) error { return nil } diff --git a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol index 5cb6fe9d0c6d..849502c5f00a 100644 --- a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol +++ b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol @@ -33,13 +33,13 @@ import { OptimismPortalInterop } from "src/L1/OptimismPortalInterop.sol"; import { SystemConfigInterop } from "src/L1/SystemConfigInterop.sol"; import { Blueprint } from "src/libraries/Blueprint.sol"; -import { Config } from "scripts/libraries/Config.sol"; import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; import { Solarray } from "scripts/libraries/Solarray.sol"; // See DeploySuperchain.s.sol for detailed comments on the script architecture used here. contract DeployImplementationsInput is CommonBase { + bytes32 internal _salt; uint256 internal _withdrawalDelaySeconds; uint256 internal _minProposalSizeBytes; uint256 internal _challengePeriodSeconds; @@ -85,11 +85,21 @@ contract DeployImplementationsInput is CommonBase { else revert("DeployImplementationsInput: unknown selector"); } + function set(bytes4 sel, bytes32 _value) public { + if (sel == this.salt.selector) _salt = _value; + else revert("DeployImplementationsInput: unknown selector"); + } + function loadInputFile(string memory _infile) public pure { _infile; require(false, "DeployImplementationsInput: not implemented"); } + function salt() public view returns (bytes32) { + // TODO check if implementations are deployed based on code+salt and skip deploy if so. + return _salt; + } + function withdrawalDelaySeconds() public view returns (uint256) { require(_withdrawalDelaySeconds != 0, "DeployImplementationsInput: not set"); return _withdrawalDelaySeconds; @@ -180,7 +190,7 @@ contract DeployImplementationsOutput { require(false, "DeployImplementationsOutput: not implemented"); } - function checkOutput() public { + function checkOutput(DeployImplementationsInput) public { address[] memory addrs = Solarray.addresses( address(this.opsm()), address(this.optimismPortalImpl()), @@ -282,7 +292,7 @@ contract DeployImplementations is Script { // Deploy the OP Stack Manager with the new implementations set. deployOPStackManager(_dii, _dio); - _dio.checkOutput(); + _dio.checkOutput(_dii); } // -------- Deployment Steps -------- @@ -339,7 +349,7 @@ contract DeployImplementations is Script { // First we deploy the blueprints for the singletons deployed by OPSM. // forgefmt: disable-start - bytes32 salt = keccak256(bytes(Config.implSalt())); + bytes32 salt = _dii.salt(); OPStackManager.Blueprints memory blueprints; vm.startBroadcast(msg.sender); @@ -456,6 +466,7 @@ contract DeployImplementations is Script { // "implementations", and when shared contracts are not proxied, they are "singletons". So // here we deploy: // + // - DisputeGameFactory (implementation) // - OptimismPortal2 (implementation) // - DelayedWETH (implementation) // - PreimageOracle (singleton) diff --git a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol index fa306edbd3dd..cf132377a8fb 100644 --- a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol @@ -8,6 +8,9 @@ import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol"; import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; import { Solarray } from "scripts/libraries/Solarray.sol"; +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; +import { Constants } from "src/libraries/Constants.sol"; + import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { AddressManager } from "src/legacy/AddressManager.sol"; @@ -168,7 +171,7 @@ contract DeployOPChainOutput { require(false, "DeployOPChainOutput: not implemented"); } - function checkOutput() public view { + function checkOutput(DeployOPChainInput _doi) public view { // With 16 addresses, we'd get a stack too deep error if we tried to do this inline as a // single call to `Solarray.addresses`. So we split it into two calls. address[] memory addrs1 = Solarray.addresses( @@ -192,6 +195,8 @@ contract DeployOPChainOutput { address(_delayedWETHPermissionlessGameProxy) ); DeployUtils.assertValidContractAddresses(Solarray.extend(addrs1, addrs2)); + + assertValidDeploy(_doi); } function opChainProxyAdmin() public view returns (ProxyAdmin) { @@ -273,6 +278,46 @@ contract DeployOPChainOutput { DeployUtils.assertValidContractAddress(address(_delayedWETHPermissionlessGameProxy)); return _delayedWETHPermissionlessGameProxy; } + + // -------- Assertions on chain architecture -------- + + function assertValidDeploy(DeployOPChainInput _doi) internal view { + // TODO Add other assertions from ChainAssertions.sol here + assertValidSystemConfig(_doi); + } + + function assertValidSystemConfig(DeployOPChainInput _doi) internal view { + // forgefmt: disable-start + require(systemConfigProxy().owner() == _doi.systemConfigOwner(), "SC10"); + require(systemConfigProxy().basefeeScalar() == _doi.basefeeScalar(), "SC20"); + require(systemConfigProxy().blobbasefeeScalar() == _doi.blobBaseFeeScalar(), "SC30"); + require(systemConfigProxy().batcherHash() == bytes32(uint256(uint160(_doi.batcher()))), "SC40"); + require(systemConfigProxy().gasLimit() == uint64(30000000), "SC50");// TODO allow other gas limits? + require(systemConfigProxy().unsafeBlockSigner() == _doi.unsafeBlockSigner(), "SC60"); + require(systemConfigProxy().scalar() >> 248 == 1, "SC70"); + + IResourceMetering.ResourceConfig memory rconfig = Constants.DEFAULT_RESOURCE_CONFIG(); + IResourceMetering.ResourceConfig memory outputConfig = systemConfigProxy().resourceConfig(); + require(outputConfig.maxResourceLimit == rconfig.maxResourceLimit, "SC80"); + require(outputConfig.elasticityMultiplier == rconfig.elasticityMultiplier, "SC90"); + require(outputConfig.baseFeeMaxChangeDenominator == rconfig.baseFeeMaxChangeDenominator, "SC100"); + require(outputConfig.systemTxMaxGas == rconfig.systemTxMaxGas, "SC110"); + require(outputConfig.minimumBaseFee == rconfig.minimumBaseFee, "SC120"); + require(outputConfig.maximumBaseFee == rconfig.maximumBaseFee, "SC130"); + + require(systemConfigProxy().startBlock() == block.number, "SC140"); + require(systemConfigProxy().batchInbox() == _doi.opsm().chainIdToBatchInboxAddress(_doi.l2ChainId()), "SC150"); + + require(systemConfigProxy().l1CrossDomainMessenger() == address(l1CrossDomainMessengerProxy()), "SC160"); + require(systemConfigProxy().l1ERC721Bridge() == address(l1ERC721BridgeProxy()), "SC170"); + require(systemConfigProxy().l1StandardBridge() == address(l1StandardBridgeProxy()), "SC180"); + require(systemConfigProxy().disputeGameFactory() == address(disputeGameFactoryProxy()), "SC190"); + require(systemConfigProxy().optimismPortal() == address(optimismPortalProxy()), "SC200"); + require(systemConfigProxy().optimismMintableERC20Factory() == address(optimismMintableERC20FactoryProxy()), "SC210"); + (address gasPayingToken,) = systemConfigProxy().gasPayingToken(); + require(gasPayingToken == Constants.ETHER, "SC220"); + // forgefmt: disable-end + } } contract DeployOPChain is Script { @@ -345,7 +390,7 @@ contract DeployOPChain is Script { _doo.delayedWETHPermissionlessGameProxy.selector, address(deployOutput.delayedWETHPermissionlessGameProxy) ); - _doo.checkOutput(); + _doo.checkOutput(_doi); } // -------- Utilities -------- diff --git a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol index 5db9788ad813..8c515ea1e272 100644 --- a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol +++ b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol @@ -205,7 +205,7 @@ contract DeploySuperchainOutput is CommonBase { // This function can be called to ensure all outputs are correct. Similar to `writeOutputFile`, // it fetches the output values using external calls to the getter methods for safety. - function checkOutput() public { + function checkOutput(DeploySuperchainInput) public { address[] memory addrs = Solarray.addresses( address(this.superchainProxyAdmin()), address(this.superchainConfigImpl()), @@ -298,7 +298,7 @@ contract DeploySuperchain is Script { transferProxyAdminOwnership(_dsi, _dso); // Output assertions, to make sure outputs were assigned correctly. - _dso.checkOutput(); + _dso.checkOutput(_dsi); } // -------- Deployment Steps -------- diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index d023f61bc244..6d3c80d2b187 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -32,8 +32,8 @@ "sourceCodeHash": "0xde4df0f9633dc0cdb1c9f634003ea5b0f7c5c1aebc407bc1b2f44c0ecf938649" }, "src/L1/OPStackManager.sol": { - "initCodeHash": "0x8081ca5dd48497b74758d1425ad6f025d6fd3cb144b4c5d4335b9a04e78b8474", - "sourceCodeHash": "0xb5fb50a9ddf8c0aee6d0e545f8ef4528f27698f3522cab744cd44ffaef6364d2" + "initCodeHash": "0x31378d0ea88a358f517927f5bc530a5b958f43c5462e4a822388ec70bd45e8d4", + "sourceCodeHash": "0xf8ac1ce2fbaa9aa21bd6c60e0bf863b06ea3bdd1c4ed801ed70ee64c1b534f67" }, "src/L1/OptimismPortal.sol": { "initCodeHash": "0xb7a7a28d5b3b88334e7cb4bc1c5fbbf9f691d934e907a2fed6a30e461eb1c0f6", diff --git a/packages/contracts-bedrock/snapshots/abi/OPStackManager.json b/packages/contracts-bedrock/snapshots/abi/OPStackManager.json index 00cc5980be0a..42369b8ef4dc 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPStackManager.json +++ b/packages/contracts-bedrock/snapshots/abi/OPStackManager.json @@ -55,6 +55,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_l2ChainId", + "type": "uint256" + } + ], + "name": "chainIdToBatchInboxAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [ { @@ -439,17 +458,6 @@ "name": "AddressHasNoCode", "type": "error" }, - { - "inputs": [ - { - "internalType": "string", - "name": "addressName", - "type": "string" - } - ], - "name": "AddressMismatch", - "type": "error" - }, { "inputs": [ { diff --git a/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json b/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json index 00cc5980be0a..42369b8ef4dc 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json +++ b/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json @@ -55,6 +55,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_l2ChainId", + "type": "uint256" + } + ], + "name": "chainIdToBatchInboxAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [ { @@ -439,17 +458,6 @@ "name": "AddressHasNoCode", "type": "error" }, - { - "inputs": [ - { - "internalType": "string", - "name": "addressName", - "type": "string" - } - ], - "name": "AddressMismatch", - "type": "error" - }, { "inputs": [ { diff --git a/packages/contracts-bedrock/src/L1/OPStackManager.sol b/packages/contracts-bedrock/src/L1/OPStackManager.sol index 29413e6388a8..cc35785ea18c 100644 --- a/packages/contracts-bedrock/src/L1/OPStackManager.sol +++ b/packages/contracts-bedrock/src/L1/OPStackManager.sol @@ -2,10 +2,13 @@ pragma solidity 0.8.15; import { Blueprint } from "src/libraries/Blueprint.sol"; +import { Constants } from "src/libraries/Constants.sol"; import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; + import { Proxy } from "src/universal/Proxy.sol"; import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; @@ -145,9 +148,6 @@ contract OPStackManager is ISemver, Initializable { // -------- Errors -------- - /// @notice Throw when two addresses do not match but are expected to. - error AddressMismatch(string addressName); - /// @notice Thrown when an address is the zero address. error AddressNotFound(address who); @@ -203,6 +203,20 @@ contract OPStackManager is ISemver, Initializable { bytes32 salt = bytes32(_input.l2ChainId); DeployOutput memory output; + // -------- TODO: Placeholders -------- + // For contracts we don't yet deploy, we set the outputs to dummy proxies so they have code to pass assertions. + // We do these first, that way the disputeGameFactoryProxy is set when passed to the SystemConfig input. + output.disputeGameFactoryProxy = DisputeGameFactory(deployProxy(l2ChainId, output.opChainProxyAdmin, "1")); + output.disputeGameFactoryImpl = DisputeGameFactory(deployProxy(l2ChainId, output.opChainProxyAdmin, "2")); + output.anchorStateRegistryProxy = AnchorStateRegistry(deployProxy(l2ChainId, output.opChainProxyAdmin, "3")); + output.anchorStateRegistryImpl = AnchorStateRegistry(deployProxy(l2ChainId, output.opChainProxyAdmin, "4")); + output.faultDisputeGame = FaultDisputeGame(deployProxy(l2ChainId, output.opChainProxyAdmin, "5")); + output.permissionedDisputeGame = PermissionedDisputeGame(deployProxy(l2ChainId, output.opChainProxyAdmin, "6")); + output.delayedWETHPermissionedGameProxy = + DelayedWETH(payable(deployProxy(l2ChainId, output.opChainProxyAdmin, "7"))); + output.delayedWETHPermissionlessGameProxy = + DelayedWETH(payable(deployProxy(l2ChainId, output.opChainProxyAdmin, "8"))); + // -------- Deploy Chain Singletons -------- // The ProxyAdmin is the owner of all proxies for the chain. We temporarily set the owner to @@ -264,11 +278,6 @@ contract OPStackManager is ISemver, Initializable { upgradeAndCall(output.opChainProxyAdmin, address(output.optimismMintableERC20FactoryProxy), impl.logic, data); impl = getLatestImplementation("L1CrossDomainMessenger"); - // TODO add this check back in - // require( - // impl.logic == referenceAddressManager.getAddress("OVM_L1CrossDomainMessenger"), - // "OpStackManager: L1CrossDomainMessenger implementation mismatch" - // ); data = encodeL1CrossDomainMessengerInitializer(impl.initializer, output); upgradeAndCall(output.opChainProxyAdmin, address(output.l1CrossDomainMessengerProxy), impl.logic, data); @@ -276,45 +285,10 @@ contract OPStackManager is ISemver, Initializable { data = encodeL1StandardBridgeInitializer(impl.initializer, output); upgradeAndCall(output.opChainProxyAdmin, address(output.l1StandardBridgeProxy), impl.logic, data); - // -------- TODO: Placeholders -------- - // For contracts we don't yet deploy, we set the outputs to dummy proxies so they have code to pass assertions. - output.disputeGameFactoryProxy = DisputeGameFactory(deployProxy(l2ChainId, output.opChainProxyAdmin, "1")); - output.disputeGameFactoryImpl = DisputeGameFactory(deployProxy(l2ChainId, output.opChainProxyAdmin, "2")); - output.anchorStateRegistryProxy = AnchorStateRegistry(deployProxy(l2ChainId, output.opChainProxyAdmin, "3")); - output.anchorStateRegistryImpl = AnchorStateRegistry(deployProxy(l2ChainId, output.opChainProxyAdmin, "4")); - output.faultDisputeGame = FaultDisputeGame(deployProxy(l2ChainId, output.opChainProxyAdmin, "5")); - output.permissionedDisputeGame = PermissionedDisputeGame(deployProxy(l2ChainId, output.opChainProxyAdmin, "6")); - output.delayedWETHPermissionedGameProxy = - DelayedWETH(payable(deployProxy(l2ChainId, output.opChainProxyAdmin, "7"))); - output.delayedWETHPermissionlessGameProxy = - DelayedWETH(payable(deployProxy(l2ChainId, output.opChainProxyAdmin, "8"))); - // -------- Finalize Deployment -------- // Transfer ownership of the ProxyAdmin from this contract to the specified owner. output.opChainProxyAdmin.transferOwnership(_input.roles.opChainProxyAdminOwner); - // Correctness checks. - // TODO these currently fail in tests because the tests use dummy implementation addresses that have no code. - // if (output.systemConfigProxy.owner() != _input.roles.systemConfigOwner) { - // revert AddressMismatch("systemConfigOwner"); - // } - // if (output.systemConfigProxy.l1CrossDomainMessenger() != address(output.l1CrossDomainMessengerProxy)) { - // revert AddressMismatch("l1CrossDomainMessengerProxy"); - // } - // if (output.systemConfigProxy.l1ERC721Bridge() != address(output.l1ERC721BridgeProxy)) { - // revert AddressMismatch("l1ERC721BridgeProxy"); - // } - // if (output.systemConfigProxy.l1StandardBridge() != address(output.l1StandardBridgeProxy)) { - // revert AddressMismatch("l1StandardBridgeProxy"); - // } - // if (output.systemConfigProxy.optimismPortal() != address(output.optimismPortalProxy)) { - // revert AddressMismatch("optimismPortalProxy"); - // } - // if ( - // output.systemConfigProxy.optimismMintableERC20Factory() != - // address(output.optimismMintableERC20FactoryProxy) - // ) revert AddressMismatch("optimismMintableERC20FactoryProxy"); - return output; } @@ -337,7 +311,7 @@ contract OPStackManager is ISemver, Initializable { /// configuration's convention. This convention is `versionByte || keccak256(bytes32(chainId))[:19]`, /// where || denotes concatenation`, versionByte is 0x00, and chainId is a uint256. /// https://specs.optimism.io/protocol/configurability.html#consensus-parameters - function chainIdToBatchInboxAddress(uint256 _l2ChainId) internal pure returns (address) { + function chainIdToBatchInboxAddress(uint256 _l2ChainId) public pure returns (address) { bytes1 versionByte = 0x00; bytes32 hashedChainId = keccak256(bytes.concat(bytes32(_l2ChainId))); bytes19 first19Bytes = bytes19(hashedChainId); @@ -403,7 +377,7 @@ contract OPStackManager is ISemver, Initializable { DeployOutput memory _output ) internal - pure + view virtual returns (bytes memory) { @@ -474,31 +448,33 @@ contract OPStackManager is ISemver, Initializable { DeployOutput memory _output ) internal - pure + view virtual - returns (ResourceMetering.ResourceConfig memory, SystemConfig.Addresses memory) + returns (ResourceMetering.ResourceConfig memory resourceConfig_, SystemConfig.Addresses memory opChainAddrs_) { - // TODO do any of these need to be configurable? are these values correct? - ResourceMetering.ResourceConfig memory referenceResourceConfig = ResourceMetering.ResourceConfig({ - maxResourceLimit: 2e7, - elasticityMultiplier: 10, - baseFeeMaxChangeDenominator: 8, - minimumBaseFee: 1e9, - systemTxMaxGas: 1e6, - maximumBaseFee: 340282366920938463463374607431768211455 - }); + // We use assembly to easily convert from IResourceMetering.ResourceConfig to ResourceMetering.ResourceConfig. + // This is required because we have not yet fully migrated the codebase to be interface-based. + IResourceMetering.ResourceConfig memory resourceConfig = Constants.DEFAULT_RESOURCE_CONFIG(); + assembly ("memory-safe") { + resourceConfig_ := resourceConfig + } - SystemConfig.Addresses memory opChainAddrs = SystemConfig.Addresses({ + opChainAddrs_ = SystemConfig.Addresses({ l1CrossDomainMessenger: address(_output.l1CrossDomainMessengerProxy), l1ERC721Bridge: address(_output.l1ERC721BridgeProxy), l1StandardBridge: address(_output.l1StandardBridgeProxy), disputeGameFactory: address(_output.disputeGameFactoryProxy), optimismPortal: address(_output.optimismPortalProxy), optimismMintableERC20Factory: address(_output.optimismMintableERC20FactoryProxy), - gasPayingToken: address(0) + gasPayingToken: Constants.ETHER }); - return (referenceResourceConfig, opChainAddrs); + assertValidContractAddress(opChainAddrs_.l1CrossDomainMessenger); + assertValidContractAddress(opChainAddrs_.l1ERC721Bridge); + assertValidContractAddress(opChainAddrs_.l1StandardBridge); + assertValidContractAddress(opChainAddrs_.disputeGameFactory); + assertValidContractAddress(opChainAddrs_.optimismPortal); + assertValidContractAddress(opChainAddrs_.optimismMintableERC20Factory); } /// @notice Makes an external call to the target to initialize the proxy with the specified data. diff --git a/packages/contracts-bedrock/src/L1/OPStackManagerInterop.sol b/packages/contracts-bedrock/src/L1/OPStackManagerInterop.sol index 53d33fc9522d..0a4a88625c9d 100644 --- a/packages/contracts-bedrock/src/L1/OPStackManagerInterop.sol +++ b/packages/contracts-bedrock/src/L1/OPStackManagerInterop.sol @@ -25,7 +25,7 @@ contract OPStackManagerInterop is OPStackManager { DeployOutput memory _output ) internal - pure + view virtual override returns (bytes memory) diff --git a/packages/contracts-bedrock/test/DeployImplementations.t.sol b/packages/contracts-bedrock/test/DeployImplementations.t.sol index 078ccf23c4f9..e44082066cb7 100644 --- a/packages/contracts-bedrock/test/DeployImplementations.t.sol +++ b/packages/contracts-bedrock/test/DeployImplementations.t.sol @@ -328,7 +328,7 @@ contract DeployImplementations_Test is Test { // Ensure that `checkOutput` passes. This is called by the `run` function during execution, // so this just acts as a sanity check. It reverts on failure. - dio.checkOutput(); + dio.checkOutput(dii); } function testFuzz_run_largeChallengePeriodSeconds_reverts(uint256 _challengePeriodSeconds) public { diff --git a/packages/contracts-bedrock/test/DeployOPChain.t.sol b/packages/contracts-bedrock/test/DeployOPChain.t.sol index 4f58b5d53299..670cc30a52f6 100644 --- a/packages/contracts-bedrock/test/DeployOPChain.t.sol +++ b/packages/contracts-bedrock/test/DeployOPChain.t.sol @@ -360,7 +360,7 @@ contract DeployOPChain_TestBase is Test { dsi.set(dsi.requiredProtocolVersion.selector, requiredProtocolVersion); dsi.set(dsi.recommendedProtocolVersion.selector, recommendedProtocolVersion); - DeployImplementations deployImplementations = new DeployImplementations(); + DeployImplementations deployImplementations = createDeployImplementationsContract(); (DeployImplementationsInput dii, DeployImplementationsOutput dio) = deployImplementations.etchIOContracts(); deployOPChain = new DeployOPChain(); diff --git a/packages/contracts-bedrock/test/DeploySuperchain.t.sol b/packages/contracts-bedrock/test/DeploySuperchain.t.sol index 04f712b3b0d8..eaf7fe3988a7 100644 --- a/packages/contracts-bedrock/test/DeploySuperchain.t.sol +++ b/packages/contracts-bedrock/test/DeploySuperchain.t.sol @@ -250,7 +250,7 @@ contract DeploySuperchain_Test is Test { // Ensure that `checkOutput` passes. This is called by the `run` function during execution, // so this just acts as a sanity check. It reverts on failure. - dso.checkOutput(); + dso.checkOutput(dsi); } function test_run_io_succeeds() public { diff --git a/packages/contracts-bedrock/test/Specs.t.sol b/packages/contracts-bedrock/test/Specs.t.sol index e9217d655074..558797a70d70 100644 --- a/packages/contracts-bedrock/test/Specs.t.sol +++ b/packages/contracts-bedrock/test/Specs.t.sol @@ -846,6 +846,7 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "OPStackManager", _sel: OPStackManager.initialize.selector }); _addSpec({ _name: "OPStackManager", _sel: OPStackManager.deploy.selector }); _addSpec({ _name: "OPStackManager", _sel: OPStackManager.blueprints.selector }); + _addSpec({ _name: "OPStackManager", _sel: OPStackManager.chainIdToBatchInboxAddress.selector }); // OPStackManagerInterop _addSpec({ _name: "OPStackManagerInterop", _sel: _getSel("version()") }); @@ -857,6 +858,7 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "OPStackManagerInterop", _sel: OPStackManager.initialize.selector }); _addSpec({ _name: "OPStackManagerInterop", _sel: OPStackManager.deploy.selector }); _addSpec({ _name: "OPStackManagerInterop", _sel: OPStackManager.blueprints.selector }); + _addSpec({ _name: "OPStackManagerInterop", _sel: OPStackManager.chainIdToBatchInboxAddress.selector }); // DeputyGuardianModule _addSpec({ From 3b4fcc5ac6c83d607ea293b939b24cb5953e5176 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Wed, 18 Sep 2024 00:10:01 +1000 Subject: [PATCH 162/264] Disable go patches for cannon MT (#11937) * Disable go patches for cannon MT. Fix the prestate file list for devnet to use the binary cannon MT prestates. * Update Makefile --------- Co-authored-by: Inphi --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index fb67b2b12864..aa4590e079ab 100644 --- a/Makefile +++ b/Makefile @@ -133,8 +133,8 @@ reproducible-prestate: ## Builds reproducible-prestate binary make -C ./op-program reproducible-prestate .PHONY: reproducible-prestate -# Include any files required for the devnet to build and run. This appears to be the only one that's actually needed. -DEVNET_CANNON_PRESTATE_FILES := op-program/bin/prestate-proof.json op-program/bin/prestate.json op-program/bin/prestate-proof-mt.json op-program/bin/prestate-mt.json +# Include any files required for the devnet to build and run. +DEVNET_CANNON_PRESTATE_FILES := op-program/bin/prestate-proof.json op-program/bin/prestate.json op-program/bin/prestate-proof-mt.json op-program/bin/prestate-mt.bin.gz $(DEVNET_CANNON_PRESTATE_FILES): @@ -143,12 +143,12 @@ $(DEVNET_CANNON_PRESTATE_FILES): cannon-prestate: op-program cannon ## Generates prestate using cannon and op-program ./cannon/bin/cannon load-elf --path op-program/bin/op-program-client.elf --out op-program/bin/prestate.json --meta op-program/bin/meta.json - ./cannon/bin/cannon run --proof-at '=0' --stop-at '=1' --input op-program/bin/prestate.json --meta op-program/bin/meta.json --proof-fmt 'op-program/bin/%d.json' --output "" + ./cannon/bin/cannon run --proof-at '=0' --stop-at '=1' --input op-program/bin/prestate.json --meta op-program/bin/meta.json --proof-fmt 'op-program/bin/%d.json' --output "" mv op-program/bin/0.json op-program/bin/prestate-proof.json .PHONY: cannon-prestate cannon-prestate-mt: op-program cannon ## Generates prestate using cannon and op-program in the multithreaded cannon format - ./cannon/bin/cannon load-elf --type cannon-mt --path op-program/bin/op-program-client.elf --out op-program/bin/prestate-mt.bin.gz --meta op-program/bin/meta-mt.json + ./cannon/bin/cannon load-elf --type cannon-mt --patch stack --path op-program/bin/op-program-client.elf --out op-program/bin/prestate-mt.bin.gz --meta op-program/bin/meta-mt.json ./cannon/bin/cannon run --proof-at '=0' --stop-at '=1' --input op-program/bin/prestate-mt.bin.gz --meta op-program/bin/meta-mt.json --proof-fmt 'op-program/bin/%d-mt.json' --output "" mv op-program/bin/0-mt.json op-program/bin/prestate-proof-mt.json .PHONY: cannon-prestate From 4490fa8ed23ef55f14192f4165649474423fe427 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 17 Sep 2024 10:11:46 -0400 Subject: [PATCH 163/264] feat: Scaffolding for DeployAuthSystem Script (#11908) * feat: Scaffolding for DeployAuthSystem Script * feat: Remove redundant documentation * Update DeployAuthSystem.s.sol --- .../scripts/DeployAuthSystem.s.sol | 43 ++++++++ .../test/DeployAuthSystem.t.sol | 102 ++++++++++++++++-- 2 files changed, 137 insertions(+), 8 deletions(-) diff --git a/packages/contracts-bedrock/scripts/DeployAuthSystem.s.sol b/packages/contracts-bedrock/scripts/DeployAuthSystem.s.sol index 13ac34ea48c8..ac2f51ee4be1 100644 --- a/packages/contracts-bedrock/scripts/DeployAuthSystem.s.sol +++ b/packages/contracts-bedrock/scripts/DeployAuthSystem.s.sol @@ -76,3 +76,46 @@ contract DeployAuthSystemOutput is CommonBase { return _safe; } } + +contract DeployAuthSystem is Script { + function run(string memory _infile, string memory _outfile) public { + (DeployAuthSystemInput dasi, DeployAuthSystemOutput daso) = etchIOContracts(); + + dasi.loadInputFile(_infile); + + run(dasi, daso); + + daso.writeOutputFile(_outfile); + } + + function run(DeployAuthSystemInput _dasi, DeployAuthSystemOutput _daso) public { + deploySafe(_dasi, _daso); + } + + function deploySafe(DeployAuthSystemInput _dasi, DeployAuthSystemOutput _daso) public { + address[] memory owners = _dasi.owners(); + uint256 threshold = _dasi.threshold(); + + // TODO: replace with a real deployment. The safe deployment logic is fairly complex, so for the purposes of + // this scaffolding PR we'll just etch the code. + address safe = makeAddr("safe"); + vm.etch(safe, type(Safe).runtimeCode); + vm.store(safe, bytes32(uint256(3)), bytes32(uint256(owners.length))); + vm.store(safe, bytes32(uint256(4)), bytes32(uint256(threshold))); + + _daso.set(_daso.safe.selector, safe); + } + + function etchIOContracts() public returns (DeployAuthSystemInput dasi_, DeployAuthSystemOutput daso_) { + (dasi_, daso_) = getIOContracts(); + vm.etch(address(dasi_), type(DeployAuthSystemInput).runtimeCode); + vm.etch(address(daso_), type(DeployAuthSystemOutput).runtimeCode); + vm.allowCheatcodes(address(dasi_)); + vm.allowCheatcodes(address(daso_)); + } + + function getIOContracts() public view returns (DeployAuthSystemInput dasi_, DeployAuthSystemOutput daso_) { + dasi_ = DeployAuthSystemInput(DeployUtils.toIOAddress(msg.sender, "optimism.DeployAuthSystemInput")); + daso_ = DeployAuthSystemOutput(DeployUtils.toIOAddress(msg.sender, "optimism.DeployAuthSystemOutput")); + } +} diff --git a/packages/contracts-bedrock/test/DeployAuthSystem.t.sol b/packages/contracts-bedrock/test/DeployAuthSystem.t.sol index 60eb27ba1c3a..f06e9237cb86 100644 --- a/packages/contracts-bedrock/test/DeployAuthSystem.t.sol +++ b/packages/contracts-bedrock/test/DeployAuthSystem.t.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Test } from "forge-std/Test.sol"; +import { Test, stdStorage, StdStorage } from "forge-std/Test.sol"; import { stdToml } from "forge-std/StdToml.sol"; import { Solarray } from "scripts/libraries/Solarray.sol"; -import { DeployAuthSystemInput, DeployAuthSystemOutput } from "scripts/DeployAuthSystem.s.sol"; +import { DeployAuthSystemInput, DeployAuthSystem, DeployAuthSystemOutput } from "scripts/DeployAuthSystem.s.sol"; contract DeployAuthSystemInput_Test is Test { DeployAuthSystemInput dasi; @@ -68,13 +68,10 @@ contract DeployAuthSystemOutput_Test is Test { function test_set_succeeds() public { address safeAddr = makeAddr("safe"); - // Ensure the address has code, since it's expected to be a contract vm.etch(safeAddr, hex"01"); - // Set the output data daso.set(daso.safe.selector, safeAddr); - // Compare the test data to the getter method assertEq(safeAddr, address(daso.safe()), "100"); } @@ -95,13 +92,11 @@ contract DeployAuthSystemOutput_Test is Test { function test_writeOutputFile_succeeds() public { string memory root = vm.projectRoot(); - // Use the expected data from the test fixture. string memory expOutPath = string.concat(root, "/test/fixtures/test-deploy-auth-system-out.toml"); string memory expOutToml = vm.readFile(expOutPath); address expSafe = expOutToml.readAddress(".safe"); - // Etch code at each address so the code checks pass when settings values. vm.etch(expSafe, hex"01"); daso.set(daso.safe.selector, expSafe); @@ -110,9 +105,100 @@ contract DeployAuthSystemOutput_Test is Test { daso.writeOutputFile(actOutPath); string memory actOutToml = vm.readFile(actOutPath); - // Clean up before asserting so that we don't leave any files behind. vm.removeFile(actOutPath); assertEq(expOutToml, actOutToml); } } + +contract DeployAuthSystem_Test is Test { + using stdStorage for StdStorage; + + DeployAuthSystem deployAuthSystem; + DeployAuthSystemInput dasi; + DeployAuthSystemOutput daso; + + // Define default input variables for testing. + uint256 defaultThreshold = 5; + uint256 defaultOwnersLength = 7; + address[] defaultOwners; + + function setUp() public { + deployAuthSystem = new DeployAuthSystem(); + (dasi, daso) = deployAuthSystem.etchIOContracts(); + for (uint256 i = 0; i < defaultOwnersLength; i++) { + defaultOwners.push(makeAddr(string.concat("owner", vm.toString(i)))); + } + } + + function hash(bytes32 _seed, uint256 _i) internal pure returns (bytes32) { + return keccak256(abi.encode(_seed, _i)); + } + + function testFuzz_run_memory_succeeds(bytes32 _seed) public { + address[] memory _owners = Solarray.addresses( + address(uint160(uint256(hash(_seed, 0)))), + address(uint160(uint256(hash(_seed, 1)))), + address(uint160(uint256(hash(_seed, 2)))), + address(uint160(uint256(hash(_seed, 3)))), + address(uint160(uint256(hash(_seed, 4)))), + address(uint160(uint256(hash(_seed, 5)))), + address(uint160(uint256(hash(_seed, 6)))) + ); + + uint256 threshold = bound(uint256(_seed), 1, _owners.length - 1); + + dasi.set(dasi.owners.selector, _owners); + dasi.set(dasi.threshold.selector, threshold); + + deployAuthSystem.run(dasi, daso); + + assertNotEq(address(daso.safe()), address(0), "100"); + assertEq(daso.safe().getThreshold(), threshold, "200"); + // TODO: the getOwners() method requires iterating over the owners linked list. + // Since we're not yet performing a proper deployment of the Safe, this call will revert. + // assertEq(daso.safe().getOwners().length, _owners.length, "300"); + + // Architecture assertions. + // TODO: these will become relevant as we add more contracts to the auth system, and need to test their + // relationships. + + daso.checkOutput(); + } + + function test_run_io_succeeds() public { + string memory root = vm.projectRoot(); + string memory inpath = string.concat(root, "/test/fixtures/test-deploy-auth-system-in.toml"); + string memory outpath = string.concat(root, "/.testdata/test-deploy-auth-system-out.toml"); + + deployAuthSystem.run(inpath, outpath); + + string memory actOutToml = vm.readFile(outpath); + string memory expOutToml = vm.readFile(string.concat(root, "/test/fixtures/test-deploy-auth-system-out.toml")); + + vm.removeFile(outpath); + assertEq(expOutToml, actOutToml); + } + + function test_run_NullInput_reverts() public { + dasi.set(dasi.owners.selector, defaultOwners); + dasi.set(dasi.threshold.selector, defaultThreshold); + + // Zero out the owners length slot + uint256 slot = 9; + vm.store(address(dasi), bytes32(uint256(9)), bytes32(0)); + vm.expectRevert("DeployAuthSystemInput: owners not set"); + deployAuthSystem.run(dasi, daso); + vm.store(address(dasi), bytes32(uint256(9)), bytes32(defaultOwnersLength)); + + slot = zeroOutSlotForSelector(dasi.threshold.selector); + vm.expectRevert("DeployAuthSystemInput: threshold not set"); + deployAuthSystem.run(dasi, daso); + vm.store(address(dasi), bytes32(slot), bytes32(defaultThreshold)); + } + + function zeroOutSlotForSelector(bytes4 _selector) internal returns (uint256 slot_) { + slot_ = stdstore.enable_packed_slots().target(address(dasi)).sig(_selector).find(); + vm.store(address(dasi), bytes32(slot_), bytes32(0)); + } +} From e7758b25fe3cc413406fab24617d7a995f0b5834 Mon Sep 17 00:00:00 2001 From: Sebastian Stammler Date: Tue, 17 Sep 2024 17:01:08 +0200 Subject: [PATCH 164/264] op-batcher: Add String methods to txRef (#11904) --- op-batcher/batcher/driver.go | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/op-batcher/batcher/driver.go b/op-batcher/batcher/driver.go index 9dbd9e802688..fd56a1cebc6b 100644 --- a/op-batcher/batcher/driver.go +++ b/op-batcher/batcher/driver.go @@ -42,6 +42,25 @@ type txRef struct { isBlob bool } +func (r txRef) String() string { + return r.string(func(id txID) string { return id.String() }) +} + +func (r txRef) TerminalString() string { + return r.string(func(id txID) string { return id.TerminalString() }) +} + +func (r txRef) string(txIDStringer func(txID) string) string { + if r.isCancel { + if r.isBlob { + return "blob-cancellation" + } else { + return "calldata-cancellation" + } + } + return txIDStringer(r.id) +} + type L1Client interface { HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error) @@ -455,7 +474,6 @@ func (l *BatchSubmitter) publishStateToL1(queue *txmgr.Queue[txRef], receiptsCh return } err := l.publishTxToL1(l.killCtx, queue, receiptsCh, daGroup) - if err != nil { if err != io.EOF { l.Log.Error("Error publishing tx to l1", "err", err) From 152c94d7c7a7aec6656e09d2431cd69027049d19 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 17 Sep 2024 11:55:29 -0400 Subject: [PATCH 165/264] feat: Rewrite FP contract distinctions as table (#11940) * feat: Rewrite FP contract distinctions as table * feat: clarify handling of non-MCP contracts * feat: Update pending mcp statuses --- .../scripts/DeployImplementations.s.sol | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol index 849502c5f00a..031dd866b687 100644 --- a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol +++ b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol @@ -452,14 +452,16 @@ contract DeployImplementations is Script { // --- Fault Proofs Contracts --- // The fault proofs contracts are configured as follows: - // - DisputeGameFactory: Proxied, bespoke per chain. - // - AnchorStateRegistry: Proxied, bespoke per chain. - // - FaultDisputeGame: Not proxied, bespoke per chain. - // - PermissionedDisputeGame: Not proxied, bespoke per chain. - // - DelayedWETH: Proxied, and two bespoke ones per chain (one for each DisputeGame). - // - PreimageOracle: Not proxied, shared by all standard chains. - // - MIPS: Not proxied, shared by all standard chains. - // - OptimismPortal2: Proxied, shared by all standard chains. + // | Contract | Proxied | Deployment | MCP Ready | + // |-------------------------|---------|-----------------------------------|------------| + // | DisputeGameFactory | Yes | Bespoke | Yes | + // | AnchorStateRegistry | Yes | Bespoke | No | + // | FaultDisputeGame | No | Bespoke | No | + // | PermissionedDisputeGame | No | Bespoke | No | + // | DelayedWETH | Yes | Two bespoke (one per DisputeGame) | No | + // | PreimageOracle | No | Shared | N/A | + // | MIPS | No | Shared | N/A | + // | OptimismPortal2 | Yes | Shared | No | // // This script only deploys the shared contracts. The bespoke contracts are deployed by // `DeployOPChain.s.sol`. When the shared contracts are proxied, the contracts deployed here are @@ -471,6 +473,9 @@ contract DeployImplementations is Script { // - DelayedWETH (implementation) // - PreimageOracle (singleton) // - MIPS (singleton) + // + // For contracts which are not MCP ready neither the Proxy nor the implementation can be shared, therefore they + // are deployed by `DeployOpChain.s.sol`. function deployOptimismPortalImpl( DeployImplementationsInput _dii, From 1a4c02043897cf080e5a45169d485255e5b52e42 Mon Sep 17 00:00:00 2001 From: protolambda Date: Tue, 17 Sep 2024 10:08:42 -0600 Subject: [PATCH 166/264] op-e2e: fix fuzz cgo build (#11941) --- op-e2e/opgeth/fastlz_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/op-e2e/opgeth/fastlz_test.go b/op-e2e/opgeth/fastlz_test.go index 5a501962341b..5b03ca38eca3 100644 --- a/op-e2e/opgeth/fastlz_test.go +++ b/op-e2e/opgeth/fastlz_test.go @@ -13,6 +13,7 @@ import ( "github.com/ethereum-optimism/optimism/op-e2e/bindings" "github.com/ethereum-optimism/optimism/op-e2e/fastlz" + "github.com/ethereum-optimism/optimism/op-e2e/system/e2esys" "github.com/ethereum-optimism/optimism/op-service/predeploys" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -79,7 +80,7 @@ func FuzzFjordCostFunction(f *testing.F) { f.Add(seed) } - cfg := DefaultSystemConfig(f) + cfg := e2esys.DefaultSystemConfig(f) s := hexutil.Uint64(0) cfg.DeployConfig.L2GenesisCanyonTimeOffset = &s cfg.DeployConfig.L2GenesisDeltaTimeOffset = &s From 418fb5e98061da931fdd5fa57436d7f4fc416500 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Tue, 17 Sep 2024 13:20:36 -0400 Subject: [PATCH 167/264] maint: move WETH contract to correct folders (#11870) Moves WETH98 over to the universal/ folder where it belongs and brings DelayedWETH up to the top of the dispute folder since there is no longer any need for a weth/ subfolder. --- packages/contracts-bedrock/README.md | 2 +- .../scripts/DeployImplementations.s.sol | 2 +- .../scripts/DeployOPChain.s.sol | 2 +- .../scripts/deploy/ChainAssertions.sol | 2 +- .../scripts/deploy/Deploy.s.sol | 2 +- packages/contracts-bedrock/semver-lock.json | 18 +++++++++--------- .../src/L1/OPStackManager.sol | 2 +- .../src/L2/SuperchainWETH.sol | 17 +++++++++++------ packages/contracts-bedrock/src/L2/WETH.sol | 13 +++++++++---- .../src/dispute/{weth => }/DelayedWETH.sol | 13 +++++++------ .../src/dispute/interfaces/IDelayedWETH.sol | 2 +- .../src/{dispute/weth => universal}/WETH98.sol | 2 +- .../interfaces/IWETH.sol | 0 .../test/DeployImplementations.t.sol | 2 +- .../contracts-bedrock/test/DeployOPChain.t.sol | 2 +- packages/contracts-bedrock/test/Specs.t.sol | 2 +- .../test/dispute/DelayedWETH.t.sol | 2 +- .../test/dispute/FaultDisputeGame.t.sol | 2 +- .../test/dispute/PermissionedDisputeGame.t.sol | 2 +- .../test/dispute/WETH98.t.sol | 6 +++++- .../contracts-bedrock/test/setup/Setup.sol | 2 +- 21 files changed, 56 insertions(+), 41 deletions(-) rename packages/contracts-bedrock/src/dispute/{weth => }/DelayedWETH.sol (95%) rename packages/contracts-bedrock/src/{dispute/weth => universal}/WETH98.sol (98%) rename packages/contracts-bedrock/src/{dispute => universal}/interfaces/IWETH.sol (100%) diff --git a/packages/contracts-bedrock/README.md b/packages/contracts-bedrock/README.md index 461dca818b2c..caef04b163bb 100644 --- a/packages/contracts-bedrock/README.md +++ b/packages/contracts-bedrock/README.md @@ -61,7 +61,7 @@ graph LR DisputeGameFactory(DisputeGameFactory) FaultDisputeGame(FaultDisputeGame) AnchorStateRegistry(AnchorStateRegistry) - DelayedWETH(DelayedWETH) + DelayedWETH(DelayedWETH) end subgraph "User Interactions (Permissionless)" diff --git a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol index 031dd866b687..d9046ba24d1d 100644 --- a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol +++ b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol @@ -12,7 +12,7 @@ import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol"; import { ResolvedDelegateProxy } from "src/legacy/ResolvedDelegateProxy.sol"; import { AddressManager } from "src/legacy/AddressManager.sol"; -import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; +import { DelayedWETH } from "src/dispute/DelayedWETH.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol"; import { MIPS } from "src/cannon/MIPS.sol"; diff --git a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol index cf132377a8fb..43239768b335 100644 --- a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol @@ -14,7 +14,7 @@ import { Constants } from "src/libraries/Constants.sol"; import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { AddressManager } from "src/legacy/AddressManager.sol"; -import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; +import { DelayedWETH } from "src/dispute/DelayedWETH.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; diff --git a/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol b/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol index efe20eb7343e..7d39a8c611f0 100644 --- a/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol +++ b/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol @@ -13,7 +13,7 @@ import { ISystemConfigV0 } from "scripts/interfaces/ISystemConfigV0.sol"; // Contracts import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; -import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; +import { DelayedWETH } from "src/dispute/DelayedWETH.sol"; // Libraries import { Constants } from "src/libraries/Constants.sol"; diff --git a/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol b/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol index 5a5506b00a6f..8ab898830b93 100644 --- a/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol @@ -34,7 +34,7 @@ import { ResolvedDelegateProxy } from "src/legacy/ResolvedDelegateProxy.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; -import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; +import { DelayedWETH } from "src/dispute/DelayedWETH.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { MIPS } from "src/cannon/MIPS.sol"; diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 6d3c80d2b187..d153fbec3e58 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -33,7 +33,7 @@ }, "src/L1/OPStackManager.sol": { "initCodeHash": "0x31378d0ea88a358f517927f5bc530a5b958f43c5462e4a822388ec70bd45e8d4", - "sourceCodeHash": "0xf8ac1ce2fbaa9aa21bd6c60e0bf863b06ea3bdd1c4ed801ed70ee64c1b534f67" + "sourceCodeHash": "0x9ed271fbb40f25528652bfecc10d2010a588629047b3aaed2b14247d2fa7b45e" }, "src/L1/OptimismPortal.sol": { "initCodeHash": "0xb7a7a28d5b3b88334e7cb4bc1c5fbbf9f691d934e907a2fed6a30e461eb1c0f6", @@ -132,12 +132,12 @@ "sourceCodeHash": "0xd56922cb04597dea469c65e5a49d4b3c50c171e603601e6f41da9517cae0b11a" }, "src/L2/SuperchainWETH.sol": { - "initCodeHash": "0x3131295bdf487120be7db6b9866d9192db32f379bbeff8f03ac61ebabdb62031", - "sourceCodeHash": "0x031aaacafaa27ad6648876cf06ba0c71d01f600897b58a9bd92ce17f7098a718" + "initCodeHash": "0xaa136fc27006d722867bcd017742cd119e58658d9860826551095775f70739ce", + "sourceCodeHash": "0x2b627b6492c4ca3cc6a457fe48b7d0b1d335125d9c6288f7373b6525542532e8" }, "src/L2/WETH.sol": { - "initCodeHash": "0x789916977b4930eb266f2187a100bc432c12b76e3872931be673a7ef2773507a", - "sourceCodeHash": "0x3f7bd622a788b8d00fe1631b14b761488eedccf56879f7ea2d610dd5ce81efbe" + "initCodeHash": "0x8ccf5227a09f3ee8e450df1f9dc72a538c03226f0182c23976635c2b49859147", + "sourceCodeHash": "0x45d14c2e1c1e0ffa1c840c61010bbbffa976bc84864e084556ea690b05775fa7" }, "src/cannon/MIPS.sol": { "initCodeHash": "0x4043f262804931bbbbecff64f87f2d0bdc4554b4d0a8b22df8fff940e8d239bf", @@ -155,6 +155,10 @@ "initCodeHash": "0x73a094f7d00422c8a765a63f4645f9e2fb508655181f227fd9b338c62c26e106", "sourceCodeHash": "0x7ed9631efb6f5cdec9fb09bc22f0e6248314db6331ed65f0baa462b230733b88" }, + "src/dispute/DelayedWETH.sol": { + "initCodeHash": "0xbda8166b77517df1df1dcef7c307c11a5520188f83555aec9439f6887c419dd0", + "sourceCodeHash": "0x70192d1eae4e16f791d826edf75a825246136fe5f8645b066a401b1dfee3e38c" + }, "src/dispute/DisputeGameFactory.sol": { "initCodeHash": "0xc1a10f65287c414076b68a7de6c238b91bc6252213187bdef35657d0f00f9382", "sourceCodeHash": "0x3d391c58420abe60d8486136a57d7f9c7137f722c80a8d884305617eb31566ef" @@ -163,10 +167,6 @@ "initCodeHash": "0x0084ca38e6ceb3c70ce77ef9769a724e8be5b92457222ef2b09c63bb4b449bf2", "sourceCodeHash": "0xf199eace79690c010d0f252819e62ef7ad165d9af19c1ee47a6aa451cda259b2" }, - "src/dispute/weth/DelayedWETH.sol": { - "initCodeHash": "0x5e7251e2c638c907c8672166f770cf2bd1fda11eed1d629ceb7568fe2b670006", - "sourceCodeHash": "0x6817260542fe6c2acbc081aad9f4b91c1502e8ae75020197213a8f8d15b6463b" - }, "src/legacy/DeployerWhitelist.sol": { "initCodeHash": "0x0b8177ed75b69eddbb9ce6537683f69a9935efed86a1d6faa8feaafbd151c1bd", "sourceCodeHash": "0xc8fe9571fcf8fcb51a4dcb00ffa97f43a9ce811c323c4926e710b28c90a9005f" diff --git a/packages/contracts-bedrock/src/L1/OPStackManager.sol b/packages/contracts-bedrock/src/L1/OPStackManager.sol index cc35785ea18c..62f3d70658cd 100644 --- a/packages/contracts-bedrock/src/L1/OPStackManager.sol +++ b/packages/contracts-bedrock/src/L1/OPStackManager.sol @@ -18,7 +18,7 @@ import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol"; import { ResolvedDelegateProxy } from "src/legacy/ResolvedDelegateProxy.sol"; import { AddressManager } from "src/legacy/AddressManager.sol"; -import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; +import { DelayedWETH } from "src/dispute/DelayedWETH.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; diff --git a/packages/contracts-bedrock/src/L2/SuperchainWETH.sol b/packages/contracts-bedrock/src/L2/SuperchainWETH.sol index d471882b5385..35c2d3d363f4 100644 --- a/packages/contracts-bedrock/src/L2/SuperchainWETH.sol +++ b/packages/contracts-bedrock/src/L2/SuperchainWETH.sol @@ -1,14 +1,19 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { WETH98 } from "src/dispute/weth/WETH98.sol"; +// Contracts +import { WETH98 } from "src/universal/WETH98.sol"; +import { L1Block } from "src/L2/L1Block.sol"; +import { ETHLiquidity } from "src/L2/ETHLiquidity.sol"; + +// Libraries import { Unauthorized, NotCustomGasToken } from "src/libraries/errors/CommonErrors.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; -import { L1Block } from "src/L2/L1Block.sol"; + +// Interfaces +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; -import { ETHLiquidity } from "src/L2/ETHLiquidity.sol"; import { ISuperchainERC20Extensions } from "src/L2/interfaces/ISuperchainERC20.sol"; -import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @title SuperchainWETH /// @notice SuperchainWETH is a version of WETH that can be freely transfrered between chains @@ -16,8 +21,8 @@ import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// do not use a custom gas token. contract SuperchainWETH is WETH98, ISuperchainERC20Extensions, ISemver { /// @notice Semantic version. - /// @custom:semver 1.0.0-beta.2 - string public constant version = "1.0.0-beta.2"; + /// @custom:semver 1.0.0-beta.3 + string public constant version = "1.0.0-beta.3"; /// @inheritdoc WETH98 function deposit() public payable override { diff --git a/packages/contracts-bedrock/src/L2/WETH.sol b/packages/contracts-bedrock/src/L2/WETH.sol index db4df18932b3..80abcbf6dbf0 100644 --- a/packages/contracts-bedrock/src/L2/WETH.sol +++ b/packages/contracts-bedrock/src/L2/WETH.sol @@ -1,16 +1,21 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { WETH98 } from "src/dispute/weth/WETH98.sol"; -import { Predeploys } from "src/libraries/Predeploys.sol"; +// Contracts +import { WETH98 } from "src/universal/WETH98.sol"; import { L1Block } from "src/L2/L1Block.sol"; + +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Interfaces import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @title WETH contract that reads the name and symbol from the L1Block contract. /// Allows for nice rendering of token names for chains using custom gas token. contract WETH is WETH98, ISemver { - /// @custom:semver 1.0.0-beta.1 - string public constant version = "1.0.0-beta.1"; + /// @custom:semver 1.1.0-beta.1 + string public constant version = "1.1.0-beta.1"; /// @notice Returns the name of the wrapped native asset. Will be "Wrapped Ether" /// if the native asset is Ether. diff --git a/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol b/packages/contracts-bedrock/src/dispute/DelayedWETH.sol similarity index 95% rename from packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol rename to packages/contracts-bedrock/src/dispute/DelayedWETH.sol index 7acfea9912e3..d86159c03fa8 100644 --- a/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol +++ b/packages/contracts-bedrock/src/dispute/DelayedWETH.sol @@ -1,13 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Contracts import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { WETH98 } from "src/universal/WETH98.sol"; +// Interfaces +import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { IWETH } from "src/universal/interfaces/IWETH.sol"; import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; -import { IWETH } from "src/dispute/interfaces/IWETH.sol"; -import { WETH98 } from "src/dispute/weth/WETH98.sol"; - import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; /// @custom:proxied true @@ -22,8 +23,8 @@ import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; /// Not the prettiest contract in the world, but it gets the job done. contract DelayedWETH is OwnableUpgradeable, WETH98, IDelayedWETH, ISemver { /// @notice Semantic version. - /// @custom:semver 1.1.1-beta.2 - string public constant version = "1.1.1-beta.2"; + /// @custom:semver 1.2.0-beta.1 + string public constant version = "1.2.0-beta.1"; /// @inheritdoc IDelayedWETH mapping(address => mapping(address => WithdrawalRequest)) public withdrawals; diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IDelayedWETH.sol b/packages/contracts-bedrock/src/dispute/interfaces/IDelayedWETH.sol index 80b90c69b860..241e4ddd54ae 100644 --- a/packages/contracts-bedrock/src/dispute/interfaces/IDelayedWETH.sol +++ b/packages/contracts-bedrock/src/dispute/interfaces/IDelayedWETH.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { IWETH } from "src/dispute/interfaces/IWETH.sol"; +import { IWETH } from "src/universal/interfaces/IWETH.sol"; /// @title IDelayedWETH /// @notice Interface for the DelayedWETH contract. diff --git a/packages/contracts-bedrock/src/dispute/weth/WETH98.sol b/packages/contracts-bedrock/src/universal/WETH98.sol similarity index 98% rename from packages/contracts-bedrock/src/dispute/weth/WETH98.sol rename to packages/contracts-bedrock/src/universal/WETH98.sol index 2b054c7048eb..5665e5f9210f 100644 --- a/packages/contracts-bedrock/src/dispute/weth/WETH98.sol +++ b/packages/contracts-bedrock/src/universal/WETH98.sol @@ -19,7 +19,7 @@ pragma solidity 0.8.15; -import { IWETH } from "src/dispute/interfaces/IWETH.sol"; +import { IWETH } from "src/universal/interfaces/IWETH.sol"; /// @title WETH98 /// @notice WETH98 is a version of WETH9 upgraded for Solidity 0.8.x. diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IWETH.sol b/packages/contracts-bedrock/src/universal/interfaces/IWETH.sol similarity index 100% rename from packages/contracts-bedrock/src/dispute/interfaces/IWETH.sol rename to packages/contracts-bedrock/src/universal/interfaces/IWETH.sol diff --git a/packages/contracts-bedrock/test/DeployImplementations.t.sol b/packages/contracts-bedrock/test/DeployImplementations.t.sol index e44082066cb7..6fd747ea0c09 100644 --- a/packages/contracts-bedrock/test/DeployImplementations.t.sol +++ b/packages/contracts-bedrock/test/DeployImplementations.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; import { Test, stdStorage, StdStorage } from "forge-std/Test.sol"; -import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; +import { DelayedWETH } from "src/dispute/DelayedWETH.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { MIPS } from "src/cannon/MIPS.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; diff --git a/packages/contracts-bedrock/test/DeployOPChain.t.sol b/packages/contracts-bedrock/test/DeployOPChain.t.sol index 670cc30a52f6..43ff82d1daa8 100644 --- a/packages/contracts-bedrock/test/DeployOPChain.t.sol +++ b/packages/contracts-bedrock/test/DeployOPChain.t.sol @@ -15,7 +15,7 @@ import { DeployOPChainInput, DeployOPChain, DeployOPChainOutput } from "scripts/ import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { AddressManager } from "src/legacy/AddressManager.sol"; -import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; +import { DelayedWETH } from "src/dispute/DelayedWETH.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; diff --git a/packages/contracts-bedrock/test/Specs.t.sol b/packages/contracts-bedrock/test/Specs.t.sol index 558797a70d70..cb67549d4c9c 100644 --- a/packages/contracts-bedrock/test/Specs.t.sol +++ b/packages/contracts-bedrock/test/Specs.t.sol @@ -949,7 +949,7 @@ contract Specification_Test is CommonTest { pathExcludes[3] = "src/L1/interfaces/*"; pathExcludes[4] = "src/governance/interfaces/*"; Abi[] memory abis = ForgeArtifacts.getContractFunctionAbis( - "src/{L1,dispute,governance,safe,universal/ProxyAdmin.sol}", pathExcludes + "src/{L1,dispute,governance,safe,universal/ProxyAdmin.sol,universal/WETH98.sol}", pathExcludes ); uint256 numCheckedEntries = 0; diff --git a/packages/contracts-bedrock/test/dispute/DelayedWETH.t.sol b/packages/contracts-bedrock/test/dispute/DelayedWETH.t.sol index 7ee45c9b87b3..57c29a9f7251 100644 --- a/packages/contracts-bedrock/test/dispute/DelayedWETH.t.sol +++ b/packages/contracts-bedrock/test/dispute/DelayedWETH.t.sol @@ -7,7 +7,7 @@ import "src/dispute/lib/Errors.sol"; import { Test } from "forge-std/Test.sol"; import { DisputeGameFactory, IDisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; -import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; +import { DelayedWETH } from "src/dispute/DelayedWETH.sol"; import { Proxy } from "src/universal/Proxy.sol"; import { Burn } from "src/libraries/Burn.sol"; import { CommonTest } from "test/setup/CommonTest.sol"; diff --git a/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol b/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol index b01ecec1811c..a12d0d991a4c 100644 --- a/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol +++ b/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol @@ -6,7 +6,7 @@ import { Vm } from "forge-std/Vm.sol"; import { DisputeGameFactory_Init } from "test/dispute/DisputeGameFactory.t.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { FaultDisputeGame, IDisputeGame } from "src/dispute/FaultDisputeGame.sol"; -import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; +import { DelayedWETH } from "src/dispute/DelayedWETH.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import "src/dispute/lib/Types.sol"; diff --git a/packages/contracts-bedrock/test/dispute/PermissionedDisputeGame.t.sol b/packages/contracts-bedrock/test/dispute/PermissionedDisputeGame.t.sol index 7e118b1efb53..571aab8b8d0f 100644 --- a/packages/contracts-bedrock/test/dispute/PermissionedDisputeGame.t.sol +++ b/packages/contracts-bedrock/test/dispute/PermissionedDisputeGame.t.sol @@ -6,7 +6,7 @@ import { Vm } from "forge-std/Vm.sol"; import { DisputeGameFactory_Init } from "test/dispute/DisputeGameFactory.t.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; -import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; +import { DelayedWETH } from "src/dispute/DelayedWETH.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { PreimageKeyLib } from "src/cannon/PreimageKeyLib.sol"; diff --git a/packages/contracts-bedrock/test/dispute/WETH98.t.sol b/packages/contracts-bedrock/test/dispute/WETH98.t.sol index 6573a9d005c5..a248e1901885 100644 --- a/packages/contracts-bedrock/test/dispute/WETH98.t.sol +++ b/packages/contracts-bedrock/test/dispute/WETH98.t.sol @@ -1,7 +1,11 @@ +// SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Testing import { Test } from "forge-std/Test.sol"; -import { WETH98 } from "src/dispute/weth/WETH98.sol"; + +// Contracts +import { WETH98 } from "src/universal/WETH98.sol"; contract WETH98_Test is Test { event Approval(address indexed src, address indexed guy, uint256 wad); diff --git a/packages/contracts-bedrock/test/setup/Setup.sol b/packages/contracts-bedrock/test/setup/Setup.sol index 01f4e9838cd6..8784db7cef09 100644 --- a/packages/contracts-bedrock/test/setup/Setup.sol +++ b/packages/contracts-bedrock/test/setup/Setup.sol @@ -29,7 +29,7 @@ import { WETH } from "src/L2/WETH.sol"; import { SuperchainWETH } from "src/L2/SuperchainWETH.sol"; import { ETHLiquidity } from "src/L2/ETHLiquidity.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; -import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; +import { DelayedWETH } from "src/dispute/DelayedWETH.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; // Libraries From f78ed7ba4c95123413e5778923fcfbea3ba6fd0b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 12:48:50 -0600 Subject: [PATCH 168/264] dependabot(gomod): bump github.com/prometheus/client_golang (#11946) Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.20.3 to 1.20.4. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.20.3...v1.20.4) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 08dd890d7025..0c4277621384 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,7 @@ require ( github.com/onsi/gomega v1.34.1 github.com/pkg/errors v0.9.1 github.com/pkg/profile v1.7.0 - github.com/prometheus/client_golang v1.20.3 + github.com/prometheus/client_golang v1.20.4 github.com/protolambda/ctxlock v0.1.0 github.com/stretchr/testify v1.9.0 github.com/urfave/cli/v2 v2.27.4 diff --git a/go.sum b/go.sum index cdfe4f7b43f0..015c8a072b23 100644 --- a/go.sum +++ b/go.sum @@ -674,8 +674,8 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4= -github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= +github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= From 110a31db03afe815c9a13d84365f62349580703a Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Tue, 17 Sep 2024 13:05:59 -0600 Subject: [PATCH 169/264] Add L2 genesis generation support to `op-deployer` (#11938) Adds support for generating L2 genesis files to `op-deployer. The L2 initialization config is generated by merging in overrides as specified in the intent into a default config with sane values. The outputted genesis file is stored in the stage as a GZIP-compressed, base64-encoded string. --- op-chain-ops/deployer/apply.go | 5 + .../deployer/integration_test/apply_test.go | 6 +- .../deployers => deployer/opsm}/l2genesis.go | 2 +- op-chain-ops/deployer/pipeline/host.go | 25 +++- .../deployer/pipeline/implementations.go | 1 + op-chain-ops/deployer/pipeline/init.go | 10 ++ op-chain-ops/deployer/pipeline/l2genesis.go | 102 ++++++++++++++ op-chain-ops/deployer/pipeline/opchain.go | 3 +- op-chain-ops/deployer/pipeline/superchain.go | 1 + op-chain-ops/deployer/state/base64.go | 30 +++++ op-chain-ops/deployer/state/base64_test.go | 38 ++++++ op-chain-ops/deployer/state/intent.go | 17 ++- .../deployer/state/l2_initialization.go | 127 ++++++++++++++++++ op-chain-ops/deployer/state/state.go | 17 ++- op-chain-ops/interopgen/deploy.go | 4 +- 15 files changed, 367 insertions(+), 21 deletions(-) rename op-chain-ops/{interopgen/deployers => deployer/opsm}/l2genesis.go (99%) create mode 100644 op-chain-ops/deployer/pipeline/l2genesis.go create mode 100644 op-chain-ops/deployer/state/base64.go create mode 100644 op-chain-ops/deployer/state/base64_test.go create mode 100644 op-chain-ops/deployer/state/l2_initialization.go diff --git a/op-chain-ops/deployer/apply.go b/op-chain-ops/deployer/apply.go index e604eb8a9ffe..c3b374aa129e 100644 --- a/op-chain-ops/deployer/apply.go +++ b/op-chain-ops/deployer/apply.go @@ -149,6 +149,11 @@ func ApplyPipeline( func(ctx context.Context, env *pipeline.Env, intent *state.Intent, st *state.State) error { return pipeline.DeployOPChain(ctx, env, intent, st, chain.ID) }, + }, pipelineStage{ + fmt.Sprintf("generate-l2-genesis-%s", chain.ID.Hex()), + func(ctx context.Context, env *pipeline.Env, intent *state.Intent, st *state.State) error { + return pipeline.GenerateL2Genesis(ctx, env, intent, st, chain.ID) + }, }) } diff --git a/op-chain-ops/deployer/integration_test/apply_test.go b/op-chain-ops/deployer/integration_test/apply_test.go index ca03b4998004..84ad7d52c554 100644 --- a/op-chain-ops/deployer/integration_test/apply_test.go +++ b/op-chain-ops/deployer/integration_test/apply_test.go @@ -112,7 +112,7 @@ func TestEndToEndApply(t *testing.T) { UseFaultProofs: true, FundDevAccounts: true, ContractArtifactsURL: (*state.ArtifactsURL)(artifactsURL), - Chains: []state.ChainIntent{ + Chains: []*state.ChainIntent{ { ID: id.Bytes32(), Roles: state.ChainRoles{ @@ -196,5 +196,9 @@ func TestEndToEndApply(t *testing.T) { require.NotEmpty(t, code, "contracts %s at %s for chain %s has no code", addr.name, addr.addr, chainState.ID) }) } + + t.Run("l2 genesis", func(t *testing.T) { + require.Greater(t, len(chainState.Genesis), 0) + }) } } diff --git a/op-chain-ops/interopgen/deployers/l2genesis.go b/op-chain-ops/deployer/opsm/l2genesis.go similarity index 99% rename from op-chain-ops/interopgen/deployers/l2genesis.go rename to op-chain-ops/deployer/opsm/l2genesis.go index a80f4f69d74b..3567df71858f 100644 --- a/op-chain-ops/interopgen/deployers/l2genesis.go +++ b/op-chain-ops/deployer/opsm/l2genesis.go @@ -1,4 +1,4 @@ -package deployers +package opsm import ( "fmt" diff --git a/op-chain-ops/deployer/pipeline/host.go b/op-chain-ops/deployer/pipeline/host.go index f62a2ee8bfae..abea4e9499df 100644 --- a/op-chain-ops/deployer/pipeline/host.go +++ b/op-chain-ops/deployer/pipeline/host.go @@ -14,6 +14,22 @@ import ( "github.com/ethereum/go-ethereum/log" ) +type BroadcasterFactory func(opts CallScriptBroadcastOpts) (broadcaster.Broadcaster, error) + +func KeyedBroadcaster(opts CallScriptBroadcastOpts) (broadcaster.Broadcaster, error) { + return broadcaster.NewKeyedBroadcaster(broadcaster.KeyedBroadcasterOpts{ + Logger: opts.Logger, + ChainID: opts.L1ChainID, + Client: opts.Client, + Signer: opts.Signer, + From: opts.Deployer, + }) +} + +func DiscardBroadcaster(opts CallScriptBroadcastOpts) (broadcaster.Broadcaster, error) { + return broadcaster.DiscardBroadcaster(), nil +} + type CallScriptBroadcastOpts struct { L1ChainID *big.Int Logger log.Logger @@ -22,19 +38,14 @@ type CallScriptBroadcastOpts struct { Signer opcrypto.SignerFn Client *ethclient.Client Handler func(host *script.Host) error + Broadcaster BroadcasterFactory } func CallScriptBroadcast( ctx context.Context, opts CallScriptBroadcastOpts, ) error { - bcaster, err := broadcaster.NewKeyedBroadcaster(broadcaster.KeyedBroadcasterOpts{ - Logger: opts.Logger, - ChainID: opts.L1ChainID, - Client: opts.Client, - Signer: opts.Signer, - From: opts.Deployer, - }) + bcaster, err := opts.Broadcaster(opts) if err != nil { return fmt.Errorf("failed to create broadcaster: %w", err) } diff --git a/op-chain-ops/deployer/pipeline/implementations.go b/op-chain-ops/deployer/pipeline/implementations.go index e315dc6fbf1d..0a203c0f3119 100644 --- a/op-chain-ops/deployer/pipeline/implementations.go +++ b/op-chain-ops/deployer/pipeline/implementations.go @@ -42,6 +42,7 @@ func DeployImplementations(ctx context.Context, env *Env, intent *state.Intent, Deployer: env.Deployer, Signer: env.Signer, Client: env.L1Client, + Broadcaster: KeyedBroadcaster, Handler: func(host *script.Host) error { host.SetEnvVar("IMPL_SALT", st.Create2Salt.Hex()[2:]) host.ImportState(st.SuperchainDeployment.StateDump) diff --git a/op-chain-ops/deployer/pipeline/init.go b/op-chain-ops/deployer/pipeline/init.go index 55cbe9793d6a..26fbb7c2667c 100644 --- a/op-chain-ops/deployer/pipeline/init.go +++ b/op-chain-ops/deployer/pipeline/init.go @@ -5,6 +5,8 @@ import ( "crypto/rand" "fmt" + "github.com/ethereum-optimism/optimism/op-chain-ops/script" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" @@ -63,6 +65,14 @@ func Init(ctx context.Context, env *Env, intent *state.Intent, st *state.State) return fmt.Errorf("L1 chain ID mismatch: got %d, expected %d", l1ChainID, intent.L1ChainID) } + deployerCode, err := env.L1Client.CodeAt(ctx, script.DeterministicDeployerAddress, nil) + if err != nil { + return fmt.Errorf("failed to get deployer code: %w", err) + } + if len(deployerCode) == 0 { + return fmt.Errorf("deterministic deployer is not deployed on this chain - please deploy it first") + } + // TODO: validate individual L2s return nil diff --git a/op-chain-ops/deployer/pipeline/l2genesis.go b/op-chain-ops/deployer/pipeline/l2genesis.go new file mode 100644 index 000000000000..b7f35d216324 --- /dev/null +++ b/op-chain-ops/deployer/pipeline/l2genesis.go @@ -0,0 +1,102 @@ +package pipeline + +import ( + "bytes" + "compress/gzip" + "context" + "encoding/json" + "fmt" + "math/big" + "os" + + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opsm" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" + "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" + "github.com/ethereum-optimism/optimism/op-chain-ops/script" + "github.com/ethereum/go-ethereum/common" +) + +func GenerateL2Genesis(ctx context.Context, env *Env, intent *state.Intent, st *state.State, chainID common.Hash) error { + lgr := env.Logger.New("stage", "generate-l2-genesis") + + lgr.Info("generating L2 genesis", "id", chainID.Hex()) + + var artifactsFS foundry.StatDirFs + var err error + if intent.ContractArtifactsURL.Scheme == "file" { + fs := os.DirFS(intent.ContractArtifactsURL.Path) + artifactsFS = fs.(foundry.StatDirFs) + } else { + return fmt.Errorf("only file:// artifacts URLs are supported") + } + + thisIntent, err := intent.Chain(chainID) + if err != nil { + return fmt.Errorf("failed to get chain intent: %w", err) + } + + thisChainState, err := st.Chain(chainID) + if err != nil { + return fmt.Errorf("failed to get chain state: %w", err) + } + + initCfg, err := state.CombineL2InitConfig(intent, thisIntent) + if err != nil { + return fmt.Errorf("failed to combine L2 init config: %w", err) + } + + var dump *foundry.ForgeAllocs + err = CallScriptBroadcast( + ctx, + CallScriptBroadcastOpts{ + L1ChainID: big.NewInt(int64(intent.L1ChainID)), + Logger: lgr, + ArtifactsFS: artifactsFS, + Deployer: env.Deployer, + Signer: env.Signer, + Client: env.L1Client, + Broadcaster: DiscardBroadcaster, + Handler: func(host *script.Host) error { + err := opsm.L2Genesis(host, &opsm.L2GenesisInput{ + L1Deployments: opsm.L1Deployments{ + L1CrossDomainMessengerProxy: thisChainState.L1CrossDomainMessengerProxyAddress, + L1StandardBridgeProxy: thisChainState.L1StandardBridgeProxyAddress, + L1ERC721BridgeProxy: thisChainState.L1ERC721BridgeProxyAddress, + }, + L2Config: initCfg, + }) + if err != nil { + return fmt.Errorf("failed to call L2Genesis script: %w", err) + } + + host.Wipe(env.Deployer) + + dump, err = host.StateDump() + if err != nil { + return fmt.Errorf("failed to dump state: %w", err) + } + + return nil + }, + }, + ) + if err != nil { + return fmt.Errorf("failed to call L2Genesis script: %w", err) + } + + var buf bytes.Buffer + gw := gzip.NewWriter(&buf) + if err := json.NewEncoder(gw).Encode(dump); err != nil { + return fmt.Errorf("failed to encode state dump: %w", err) + } + if err := gw.Close(); err != nil { + return fmt.Errorf("failed to close gzip writer: %w", err) + } + thisChainState.Genesis = buf.Bytes() + + if err := env.WriteState(st); err != nil { + return fmt.Errorf("failed to write state: %w", err) + } + + return nil +} diff --git a/op-chain-ops/deployer/pipeline/opchain.go b/op-chain-ops/deployer/pipeline/opchain.go index 6a27ded2d520..c3a18e7b7383 100644 --- a/op-chain-ops/deployer/pipeline/opchain.go +++ b/op-chain-ops/deployer/pipeline/opchain.go @@ -47,6 +47,7 @@ func DeployOPChain(ctx context.Context, env *Env, intent *state.Intent, st *stat Deployer: env.Deployer, Signer: env.Signer, Client: env.L1Client, + Broadcaster: KeyedBroadcaster, Handler: func(host *script.Host) error { host.ImportState(st.ImplementationsDeployment.StateDump) dco, err = opsm.DeployOPChain( @@ -72,7 +73,7 @@ func DeployOPChain(ctx context.Context, env *Env, intent *state.Intent, st *stat return fmt.Errorf("error deploying OP chain: %w", err) } - st.Chains = append(st.Chains, state.ChainState{ + st.Chains = append(st.Chains, &state.ChainState{ ID: chainID, ProxyAdminAddress: dco.OpChainProxyAdmin, diff --git a/op-chain-ops/deployer/pipeline/superchain.go b/op-chain-ops/deployer/pipeline/superchain.go index 3a91c867ff3a..a3c1dc2827a3 100644 --- a/op-chain-ops/deployer/pipeline/superchain.go +++ b/op-chain-ops/deployer/pipeline/superchain.go @@ -44,6 +44,7 @@ func DeploySuperchain(ctx context.Context, env *Env, intent *state.Intent, st *s Deployer: env.Deployer, Signer: env.Signer, Client: env.L1Client, + Broadcaster: KeyedBroadcaster, Handler: func(host *script.Host) error { dso, err = opsm.DeploySuperchain( host, diff --git a/op-chain-ops/deployer/state/base64.go b/op-chain-ops/deployer/state/base64.go new file mode 100644 index 000000000000..23e4379fe5fa --- /dev/null +++ b/op-chain-ops/deployer/state/base64.go @@ -0,0 +1,30 @@ +package state + +import ( + "encoding/base64" + "encoding/json" +) + +type Base64Bytes []byte + +func (b Base64Bytes) MarshalJSON() ([]byte, error) { + if len(b) == 0 { + return []byte(`null`), nil + } + + encoded := base64.StdEncoding.EncodeToString(b) + return []byte(`"` + encoded + `"`), nil +} + +func (b *Base64Bytes) UnmarshalJSON(data []byte) error { + var dataStr string + if err := json.Unmarshal(data, &dataStr); err != nil { + return err + } + decoded, err := base64.StdEncoding.DecodeString(dataStr) + if err != nil { + return err + } + *b = decoded + return nil +} diff --git a/op-chain-ops/deployer/state/base64_test.go b/op-chain-ops/deployer/state/base64_test.go new file mode 100644 index 000000000000..abfa6654cee5 --- /dev/null +++ b/op-chain-ops/deployer/state/base64_test.go @@ -0,0 +1,38 @@ +package state + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestBase64BytesMarshaling(t *testing.T) { + tests := []struct { + name string + in Base64Bytes + out string + }{ + { + name: "empty", + in: Base64Bytes{}, + out: "null", + }, + { + name: "non-empty", + in: Base64Bytes{0x01, 0x02, 0x03}, + out: `"AQID"`, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + data, err := tt.in.MarshalJSON() + require.NoError(t, err) + require.Equal(t, tt.out, string(data)) + + var b Base64Bytes + err = b.UnmarshalJSON(data) + require.NoError(t, err) + require.Equal(t, tt.in, b) + }) + } +} diff --git a/op-chain-ops/deployer/state/intent.go b/op-chain-ops/deployer/state/intent.go index 3c41169e1d45..718026739945 100644 --- a/op-chain-ops/deployer/state/intent.go +++ b/op-chain-ops/deployer/state/intent.go @@ -24,13 +24,16 @@ type Intent struct { ContractArtifactsURL *ArtifactsURL `json:"contractArtifactsURL" toml:"contractArtifactsURL"` - Chains []ChainIntent `json:"chains" toml:"chains"` + Chains []*ChainIntent `json:"chains" toml:"chains"` + + GlobalInitOverrides map[string]any `json:"globalInitOverrides" toml:"globalInitOverrides"` } -func (c Intent) L1ChainIDBig() *big.Int { +func (c *Intent) L1ChainIDBig() *big.Int { return big.NewInt(int64(c.L1ChainID)) } -func (c Intent) Check() error { + +func (c *Intent) Check() error { if c.L1ChainID == 0 { return fmt.Errorf("l1ChainID must be set") } @@ -62,17 +65,17 @@ func (c Intent) Check() error { return nil } -func (c Intent) Chain(id common.Hash) (ChainIntent, error) { +func (c *Intent) Chain(id common.Hash) (*ChainIntent, error) { for i := range c.Chains { if c.Chains[i].ID == id { return c.Chains[i], nil } } - return ChainIntent{}, fmt.Errorf("chain %d not found", id) + return nil, fmt.Errorf("chain %d not found", id) } -func (c Intent) WriteToFile(path string) error { +func (c *Intent) WriteToFile(path string) error { return jsonutil.WriteTOML(c, ioutil.ToAtomicFile(path, 0o755)) } @@ -89,7 +92,7 @@ type ChainIntent struct { Roles ChainRoles `json:"roles" toml:"roles"` - Overrides map[string]any `json:"overrides" toml:"overrides"` + InitOverrides map[string]any `json:"initOverrides" toml:"initOverrides"` } type ChainRoles struct { diff --git a/op-chain-ops/deployer/state/l2_initialization.go b/op-chain-ops/deployer/state/l2_initialization.go new file mode 100644 index 000000000000..9baf98fec0cc --- /dev/null +++ b/op-chain-ops/deployer/state/l2_initialization.go @@ -0,0 +1,127 @@ +package state + +import ( + "encoding/json" + "fmt" + "math/big" + + "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" + "github.com/ethereum/go-ethereum/common/hexutil" +) + +var ( + l2GenesisBlockBaseFeePerGas = hexutil.Big(*(big.NewInt(1000000000))) + + vaultMinWithdrawalAmount = mustHexBigFromHex("0x8ac7230489e80000") +) + +func DefaultL2InitConfig() genesis.L2InitializationConfig { + return genesis.L2InitializationConfig{ + L2GenesisBlockDeployConfig: genesis.L2GenesisBlockDeployConfig{ + L2GenesisBlockGasLimit: 30_000_000, + L2GenesisBlockBaseFeePerGas: &l2GenesisBlockBaseFeePerGas, + }, + L2VaultsDeployConfig: genesis.L2VaultsDeployConfig{ + BaseFeeVaultWithdrawalNetwork: "local", + L1FeeVaultWithdrawalNetwork: "local", + SequencerFeeVaultWithdrawalNetwork: "local", + SequencerFeeVaultMinimumWithdrawalAmount: vaultMinWithdrawalAmount, + BaseFeeVaultMinimumWithdrawalAmount: vaultMinWithdrawalAmount, + L1FeeVaultMinimumWithdrawalAmount: vaultMinWithdrawalAmount, + }, + GovernanceDeployConfig: genesis.GovernanceDeployConfig{ + EnableGovernance: true, + GovernanceTokenSymbol: "OP", + GovernanceTokenName: "Optimism", + }, + GasPriceOracleDeployConfig: genesis.GasPriceOracleDeployConfig{ + GasPriceOracleBaseFeeScalar: 0, + GasPriceOracleBlobBaseFeeScalar: 1000000, + }, + EIP1559DeployConfig: genesis.EIP1559DeployConfig{ + EIP1559Denominator: 50, + EIP1559DenominatorCanyon: 250, + EIP1559Elasticity: 6, + }, + UpgradeScheduleDeployConfig: genesis.UpgradeScheduleDeployConfig{ + L2GenesisRegolithTimeOffset: u64UtilPtr(0), + L2GenesisCanyonTimeOffset: u64UtilPtr(0), + L2GenesisDeltaTimeOffset: u64UtilPtr(0), + L2GenesisEcotoneTimeOffset: u64UtilPtr(0), + L2GenesisFjordTimeOffset: u64UtilPtr(0), + L2GenesisGraniteTimeOffset: u64UtilPtr(0), + UseInterop: false, + }, + L2CoreDeployConfig: genesis.L2CoreDeployConfig{ + L2BlockTime: 2, + FinalizationPeriodSeconds: 12, + MaxSequencerDrift: 600, + SequencerWindowSize: 3600, + ChannelTimeoutBedrock: 300, + SystemConfigStartBlock: 0, + }, + } +} + +func CombineL2InitConfig(intent *Intent, chainIntent *ChainIntent) (genesis.L2InitializationConfig, error) { + cfg := DefaultL2InitConfig() + + var err error + if len(intent.GlobalInitOverrides) > 0 { + cfg, err = mergeJSON(cfg, intent.GlobalInitOverrides) + if err != nil { + return genesis.L2InitializationConfig{}, fmt.Errorf("error merging global L2 overrides: %w", err) + + } + } + + if len(chainIntent.InitOverrides) > 0 { + cfg, err = mergeJSON(cfg, chainIntent.InitOverrides) + if err != nil { + return genesis.L2InitializationConfig{}, fmt.Errorf("error merging chain L2 overrides: %w", err) + } + } + + return cfg, nil +} + +func mergeJSON[T any](in T, overrides ...map[string]any) (T, error) { + var out T + inJSON, err := json.Marshal(in) + if err != nil { + return out, err + } + + var tmpMap map[string]interface{} + if err := json.Unmarshal(inJSON, &tmpMap); err != nil { + return out, err + } + + for _, override := range overrides { + for k, v := range override { + tmpMap[k] = v + } + } + + inJSON, err = json.Marshal(tmpMap) + if err != nil { + return out, err + } + + if err := json.Unmarshal(inJSON, &out); err != nil { + return out, err + } + + return out, nil +} + +func mustHexBigFromHex(hex string) *hexutil.Big { + num := hexutil.MustDecodeBig(hex) + hexBig := hexutil.Big(*num) + return &hexBig +} + +func u64UtilPtr(in uint64) *hexutil.Uint64 { + util := hexutil.Uint64(in) + return &util +} diff --git a/op-chain-ops/deployer/state/state.go b/op-chain-ops/deployer/state/state.go index 315f25b64b76..75fbd60f2dc9 100644 --- a/op-chain-ops/deployer/state/state.go +++ b/op-chain-ops/deployer/state/state.go @@ -1,6 +1,8 @@ package state import ( + "fmt" + "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/ethereum-optimism/optimism/op-service/jsonutil" @@ -32,13 +34,22 @@ type State struct { ImplementationsDeployment *ImplementationsDeployment `json:"implementationsDeployment"` // Chains contains data about L2 chain deployments. - Chains []ChainState `json:"opChainDeployments"` + Chains []*ChainState `json:"opChainDeployments"` } -func (s State) WriteToFile(path string) error { +func (s *State) WriteToFile(path string) error { return jsonutil.WriteJSON(s, ioutil.ToAtomicFile(path, 0o755)) } +func (s *State) Chain(id common.Hash) (*ChainState, error) { + for _, chain := range s.Chains { + if chain.ID == id { + return chain, nil + } + } + return nil, fmt.Errorf("chain not found: %s", id.Hex()) +} + type SuperchainDeployment struct { ProxyAdminAddress common.Address `json:"proxyAdminAddress"` SuperchainConfigProxyAddress common.Address `json:"superchainConfigProxyAddress"` @@ -82,4 +93,6 @@ type ChainState struct { PermissionedDisputeGameAddress common.Address `json:"permissionedDisputeGameAddress"` DelayedWETHPermissionedGameProxyAddress common.Address `json:"delayedWETHPermissionedGameProxyAddress"` DelayedWETHPermissionlessGameProxyAddress common.Address `json:"delayedWETHPermissionlessGameProxyAddress"` + + Genesis Base64Bytes `json:"genesis"` } diff --git a/op-chain-ops/interopgen/deploy.go b/op-chain-ops/interopgen/deploy.go index 65cb474d9f2b..d172184e91da 100644 --- a/op-chain-ops/interopgen/deploy.go +++ b/op-chain-ops/interopgen/deploy.go @@ -219,8 +219,8 @@ func deployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme } func genesisL2(l2Host *script.Host, cfg *L2Config, deployment *L2Deployment) error { - if err := deployers.L2Genesis(l2Host, &deployers.L2GenesisInput{ - L1Deployments: deployers.L1Deployments{ + if err := opsm.L2Genesis(l2Host, &opsm.L2GenesisInput{ + L1Deployments: opsm.L1Deployments{ L1CrossDomainMessengerProxy: deployment.L1CrossDomainMessengerProxy, L1StandardBridgeProxy: deployment.L1StandardBridgeProxy, L1ERC721BridgeProxy: deployment.L1ERC721BridgeProxy, From 290dde274580e93c57ae66aa3b88b5917340d021 Mon Sep 17 00:00:00 2001 From: Matt Solomon Date: Tue, 17 Sep 2024 12:21:00 -0700 Subject: [PATCH 170/264] OPSM: DeployOPChain assertions (#11943) * chore: add BaseDeployIO for the deploy input and output contracts * test: add assertions to DeployOPChain * chore: semver lock * pr feedback --- .../scripts/DeployImplementations.s.sol | 8 +- .../scripts/DeployOPChain.s.sol | 153 ++++++++++++++---- .../scripts/DeploySuperchain.s.sol | 13 +- .../scripts/libraries/DeployUtils.sol | 10 ++ .../scripts/utils/BaseDeployIO.sol | 9 ++ 5 files changed, 154 insertions(+), 39 deletions(-) create mode 100644 packages/contracts-bedrock/scripts/utils/BaseDeployIO.sol diff --git a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol index d9046ba24d1d..5ea8d9a1e13a 100644 --- a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol +++ b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol @@ -2,7 +2,6 @@ pragma solidity 0.8.15; import { Script } from "forge-std/Script.sol"; -import { CommonBase } from "forge-std/Base.sol"; import { LibString } from "@solady/utils/LibString.sol"; @@ -36,9 +35,10 @@ import { Blueprint } from "src/libraries/Blueprint.sol"; import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; import { Solarray } from "scripts/libraries/Solarray.sol"; +import { BaseDeployIO } from "scripts/utils/BaseDeployIO.sol"; // See DeploySuperchain.s.sol for detailed comments on the script architecture used here. -contract DeployImplementationsInput is CommonBase { +contract DeployImplementationsInput is BaseDeployIO { bytes32 internal _salt; uint256 internal _withdrawalDelaySeconds; uint256 internal _minProposalSizeBytes; @@ -153,7 +153,7 @@ contract DeployImplementationsInput is CommonBase { } } -contract DeployImplementationsOutput { +contract DeployImplementationsOutput is BaseDeployIO { OPStackManager internal _opsm; DelayedWETH internal _delayedWETHImpl; OptimismPortal2 internal _optimismPortalImpl; @@ -205,6 +205,8 @@ contract DeployImplementationsOutput { address(this.disputeGameFactoryImpl()) ); DeployUtils.assertValidContractAddresses(addrs); + + // TODO Also add the assertions for the implementation contracts from ChainAssertions.sol } function opsm() public returns (OPStackManager) { diff --git a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol index 43239768b335..2aac28d874e0 100644 --- a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol @@ -7,9 +7,12 @@ import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol"; import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; import { Solarray } from "scripts/libraries/Solarray.sol"; +import { BaseDeployIO } from "scripts/utils/BaseDeployIO.sol"; import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { Constants } from "src/libraries/Constants.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; @@ -28,7 +31,7 @@ import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; -contract DeployOPChainInput { +contract DeployOPChainInput is BaseDeployIO { address internal _opChainProxyAdminOwner; address internal _systemConfigOwner; address internal _batcher; @@ -125,7 +128,7 @@ contract DeployOPChainInput { } } -contract DeployOPChainOutput { +contract DeployOPChainOutput is BaseDeployIO { ProxyAdmin internal _opChainProxyAdmin; AddressManager internal _addressManager; L1ERC721Bridge internal _l1ERC721BridgeProxy; @@ -282,41 +285,125 @@ contract DeployOPChainOutput { // -------- Assertions on chain architecture -------- function assertValidDeploy(DeployOPChainInput _doi) internal view { - // TODO Add other assertions from ChainAssertions.sol here assertValidSystemConfig(_doi); + assertValidL1CrossDomainMessenger(_doi); + assertValidL1StandardBridge(_doi); + assertValidOptimismMintableERC20Factory(_doi); + assertValidOptimismPortal(_doi); + assertValidDisputeGameFactory(_doi); + assertValidDelayedWETHs(_doi); + // TODO Other FP assertions like the dispute games, anchor state registry, etc. + // TODO add initialization assertions } function assertValidSystemConfig(DeployOPChainInput _doi) internal view { - // forgefmt: disable-start - require(systemConfigProxy().owner() == _doi.systemConfigOwner(), "SC10"); - require(systemConfigProxy().basefeeScalar() == _doi.basefeeScalar(), "SC20"); - require(systemConfigProxy().blobbasefeeScalar() == _doi.blobBaseFeeScalar(), "SC30"); - require(systemConfigProxy().batcherHash() == bytes32(uint256(uint160(_doi.batcher()))), "SC40"); - require(systemConfigProxy().gasLimit() == uint64(30000000), "SC50");// TODO allow other gas limits? - require(systemConfigProxy().unsafeBlockSigner() == _doi.unsafeBlockSigner(), "SC60"); - require(systemConfigProxy().scalar() >> 248 == 1, "SC70"); - - IResourceMetering.ResourceConfig memory rconfig = Constants.DEFAULT_RESOURCE_CONFIG(); - IResourceMetering.ResourceConfig memory outputConfig = systemConfigProxy().resourceConfig(); - require(outputConfig.maxResourceLimit == rconfig.maxResourceLimit, "SC80"); - require(outputConfig.elasticityMultiplier == rconfig.elasticityMultiplier, "SC90"); - require(outputConfig.baseFeeMaxChangeDenominator == rconfig.baseFeeMaxChangeDenominator, "SC100"); - require(outputConfig.systemTxMaxGas == rconfig.systemTxMaxGas, "SC110"); - require(outputConfig.minimumBaseFee == rconfig.minimumBaseFee, "SC120"); - require(outputConfig.maximumBaseFee == rconfig.maximumBaseFee, "SC130"); - - require(systemConfigProxy().startBlock() == block.number, "SC140"); - require(systemConfigProxy().batchInbox() == _doi.opsm().chainIdToBatchInboxAddress(_doi.l2ChainId()), "SC150"); - - require(systemConfigProxy().l1CrossDomainMessenger() == address(l1CrossDomainMessengerProxy()), "SC160"); - require(systemConfigProxy().l1ERC721Bridge() == address(l1ERC721BridgeProxy()), "SC170"); - require(systemConfigProxy().l1StandardBridge() == address(l1StandardBridgeProxy()), "SC180"); - require(systemConfigProxy().disputeGameFactory() == address(disputeGameFactoryProxy()), "SC190"); - require(systemConfigProxy().optimismPortal() == address(optimismPortalProxy()), "SC200"); - require(systemConfigProxy().optimismMintableERC20Factory() == address(optimismMintableERC20FactoryProxy()), "SC210"); - (address gasPayingToken,) = systemConfigProxy().gasPayingToken(); - require(gasPayingToken == Constants.ETHER, "SC220"); - // forgefmt: disable-end + SystemConfig systemConfig = systemConfigProxy(); + + DeployUtils.assertInitialized({ _contractAddress: address(systemConfig), _slot: 0, _offset: 0 }); + + require(systemConfig.owner() == _doi.systemConfigOwner(), "SC-10"); + require(systemConfig.basefeeScalar() == _doi.basefeeScalar(), "SC-20"); + require(systemConfig.blobbasefeeScalar() == _doi.blobBaseFeeScalar(), "SC-30"); + require(systemConfig.batcherHash() == bytes32(uint256(uint160(_doi.batcher()))), "SC-40"); + require(systemConfig.gasLimit() == uint64(30000000), "SC-50"); // TODO allow other gas limits? + require(systemConfig.unsafeBlockSigner() == _doi.unsafeBlockSigner(), "SC-60"); + require(systemConfig.scalar() >> 248 == 1, "SC-70"); + + IResourceMetering.ResourceConfig memory rConfig = Constants.DEFAULT_RESOURCE_CONFIG(); + IResourceMetering.ResourceConfig memory outputConfig = systemConfig.resourceConfig(); + require(outputConfig.maxResourceLimit == rConfig.maxResourceLimit, "SC-80"); + require(outputConfig.elasticityMultiplier == rConfig.elasticityMultiplier, "SC-90"); + require(outputConfig.baseFeeMaxChangeDenominator == rConfig.baseFeeMaxChangeDenominator, "SC-100"); + require(outputConfig.systemTxMaxGas == rConfig.systemTxMaxGas, "SC-110"); + require(outputConfig.minimumBaseFee == rConfig.minimumBaseFee, "SC-120"); + require(outputConfig.maximumBaseFee == rConfig.maximumBaseFee, "SC-130"); + + require(systemConfig.startBlock() == block.number, "SC-140"); + require(systemConfig.batchInbox() == _doi.opsm().chainIdToBatchInboxAddress(_doi.l2ChainId()), "SC-150"); + + require(systemConfig.l1CrossDomainMessenger() == address(l1CrossDomainMessengerProxy()), "SC-160"); + require(systemConfig.l1ERC721Bridge() == address(l1ERC721BridgeProxy()), "SC-170"); + require(systemConfig.l1StandardBridge() == address(l1StandardBridgeProxy()), "SC-180"); + require(systemConfig.disputeGameFactory() == address(disputeGameFactoryProxy()), "SC-190"); + require(systemConfig.optimismPortal() == address(optimismPortalProxy()), "SC-200"); + require(systemConfig.optimismMintableERC20Factory() == address(optimismMintableERC20FactoryProxy()), "SC-210"); + (address gasPayingToken,) = systemConfig.gasPayingToken(); + require(gasPayingToken == Constants.ETHER, "SC-220"); + } + + function assertValidL1CrossDomainMessenger(DeployOPChainInput _doi) internal view { + L1CrossDomainMessenger messenger = l1CrossDomainMessengerProxy(); + + DeployUtils.assertInitialized({ _contractAddress: address(messenger), _slot: 0, _offset: 20 }); + + require(address(messenger.OTHER_MESSENGER()) == Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L1xDM-10"); + require(address(messenger.otherMessenger()) == Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L1xDM-20"); + + require(address(messenger.PORTAL()) == address(optimismPortalProxy()), "L1xDM-30"); + require(address(messenger.portal()) == address(optimismPortalProxy()), "L1xDM-40"); + require(address(messenger.superchainConfig()) == address(_doi.opsm().superchainConfig()), "L1xDM-50"); + + bytes32 xdmSenderSlot = vm.load(address(messenger), bytes32(uint256(204))); + require(address(uint160(uint256(xdmSenderSlot))) == Constants.DEFAULT_L2_SENDER, "L1xDM-60"); + } + + function assertValidL1StandardBridge(DeployOPChainInput _doi) internal view { + L1StandardBridge bridge = l1StandardBridgeProxy(); + L1CrossDomainMessenger messenger = l1CrossDomainMessengerProxy(); + + DeployUtils.assertInitialized({ _contractAddress: address(bridge), _slot: 0, _offset: 0 }); + + require(address(bridge.MESSENGER()) == address(messenger), "L1SB-10"); + require(address(bridge.messenger()) == address(messenger), "L1SB-20"); + require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_STANDARD_BRIDGE, "L1SB-30"); + require(address(bridge.otherBridge()) == Predeploys.L2_STANDARD_BRIDGE, "L1SB-40"); + require(address(bridge.superchainConfig()) == address(_doi.opsm().superchainConfig()), "L1SB-50"); + } + + function assertValidOptimismMintableERC20Factory(DeployOPChainInput) internal view { + OptimismMintableERC20Factory factory = optimismMintableERC20FactoryProxy(); + + DeployUtils.assertInitialized({ _contractAddress: address(factory), _slot: 0, _offset: 0 }); + + require(factory.BRIDGE() == address(l1StandardBridgeProxy()), "OMEF-10"); + require(factory.bridge() == address(l1StandardBridgeProxy()), "OMEF-20"); + } + + function assertValidL1ERC721Bridge(DeployOPChainInput _doi) internal view { + L1ERC721Bridge bridge = l1ERC721BridgeProxy(); + + DeployUtils.assertInitialized({ _contractAddress: address(bridge), _slot: 0, _offset: 0 }); + + require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_ERC721_BRIDGE, "LEB-10"); + require(address(bridge.otherBridge()) == Predeploys.L2_ERC721_BRIDGE, "LEB-20"); + + require(address(bridge.MESSENGER()) == address(l1CrossDomainMessengerProxy()), "LEB-30"); + require(address(bridge.messenger()) == address(l1CrossDomainMessengerProxy()), "LEB-40"); + require(address(bridge.superchainConfig()) == address(_doi.opsm().superchainConfig()), "LEB-50"); + } + + function assertValidOptimismPortal(DeployOPChainInput _doi) internal view { + OptimismPortal2 portal = optimismPortalProxy(); + ISuperchainConfig superchainConfig = ISuperchainConfig(address(_doi.opsm().superchainConfig())); + + require(address(portal.disputeGameFactory()) == address(disputeGameFactoryProxy()), "OP-10"); + require(address(portal.systemConfig()) == address(systemConfigProxy()), "OP-20"); + require(address(portal.superchainConfig()) == address(superchainConfig), "OP-30"); + require(portal.guardian() == superchainConfig.guardian(), "OP-40"); + require(portal.paused() == superchainConfig.paused(), "OP-50"); + require(portal.l2Sender() == Constants.DEFAULT_L2_SENDER, "OP-60"); + + // This slot is the custom gas token _balance and this check ensures + // that it stays unset for forwards compatibility with custom gas token. + require(vm.load(address(portal), bytes32(uint256(61))) == bytes32(0)); + } + + function assertValidDisputeGameFactory(DeployOPChainInput) internal view { + // TODO add in once FP support is added. + } + + function assertValidDelayedWETHs(DeployOPChainInput) internal view { + // TODO add in once FP support is added. } } diff --git a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol index 8c515ea1e272..800833ccaa4f 100644 --- a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol +++ b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol @@ -2,7 +2,6 @@ pragma solidity 0.8.15; import { Script } from "forge-std/Script.sol"; -import { CommonBase } from "forge-std/Base.sol"; import { stdToml } from "forge-std/StdToml.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; @@ -12,6 +11,7 @@ import { Proxy } from "src/universal/Proxy.sol"; import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; import { Solarray } from "scripts/libraries/Solarray.sol"; +import { BaseDeployIO } from "scripts/utils/BaseDeployIO.sol"; // This comment block defines the requirements and rationale for the architecture used in this forge // script, along with other scripts that are being written as new Superchain-first deploy scripts to @@ -65,7 +65,10 @@ import { Solarray } from "scripts/libraries/Solarray.sol"; // - `doo` for DeployOPChainInput // - `doo` for DeployOPChainOutput // - etc. -contract DeploySuperchainInput is CommonBase { + +// All contracts of the form `DeployInput` should inherit from `BaseDeployIO`, as it provides +// shared functionality for all deploy scripts, such as access to cheat codes. +contract DeploySuperchainInput is BaseDeployIO { using stdToml for string; // All inputs are set in storage individually. We put any roles first, followed by the remaining @@ -169,7 +172,9 @@ contract DeploySuperchainInput is CommonBase { } } -contract DeploySuperchainOutput is CommonBase { +// All contracts of the form `DeployOutput` should inherit from `BaseDeployIO`, as it provides +// shared functionality for all deploy scripts, such as access to cheat codes. +contract DeploySuperchainOutput is BaseDeployIO { // All outputs are stored in storage individually, with the same rationale as doing so for // inputs, and the same pattern is used below to expose the outputs. ProtocolVersions internal _protocolVersionsImpl; @@ -223,6 +228,8 @@ contract DeploySuperchainOutput is CommonBase { require(actualSuperchainConfigImpl == address(_superchainConfigImpl), "100"); require(actualProtocolVersionsImpl == address(_protocolVersionsImpl), "200"); + + // TODO Also add the assertions for the implementation contracts from ChainAssertions.sol } function superchainProxyAdmin() public view returns (ProxyAdmin) { diff --git a/packages/contracts-bedrock/scripts/libraries/DeployUtils.sol b/packages/contracts-bedrock/scripts/libraries/DeployUtils.sol index d0346ea0d72d..d3586d1b7232 100644 --- a/packages/contracts-bedrock/scripts/libraries/DeployUtils.sol +++ b/packages/contracts-bedrock/scripts/libraries/DeployUtils.sol @@ -47,4 +47,14 @@ library DeployUtils { } } } + + // Asserts that for a given contract the value of a storage slot at an offset is 1. This + // is used to assert that a contract is initialized. + function assertInitialized(address _contractAddress, uint256 _slot, uint256 _offset) internal view { + bytes32 slotVal = vm.load(_contractAddress, bytes32(_slot)); + require( + uint8((uint256(slotVal) >> (_offset * 8)) & 0xFF) == uint8(1), + "Storage value is not 1 at the given slot and offset" + ); + } } diff --git a/packages/contracts-bedrock/scripts/utils/BaseDeployIO.sol b/packages/contracts-bedrock/scripts/utils/BaseDeployIO.sol new file mode 100644 index 000000000000..f8157ae39241 --- /dev/null +++ b/packages/contracts-bedrock/scripts/utils/BaseDeployIO.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { CommonBase } from "forge-std/Base.sol"; + +/// @notice All contracts of the form `DeployInput` and `DeployOutput` should inherit from this contract. +/// It provides a base set of functionality, such as access to cheat codes, that these scripts may need. +/// See the comments in `DeploySuperchain.s.sol` for more information on this pattern. +abstract contract BaseDeployIO is CommonBase { } From 8312d611a645b011ad967279383742bca18cca2e Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 17 Sep 2024 15:35:31 -0400 Subject: [PATCH 171/264] feat: remove dgf impl from DeployOpChain and OPSM (#11942) --- .../deployer/integration_test/apply_test.go | 1 - op-chain-ops/deployer/opsm/opchain.go | 1 - op-chain-ops/deployer/pipeline/opchain.go | 1 - op-chain-ops/deployer/state/state.go | 1 - op-chain-ops/interopgen/deployments.go | 1 - .../scripts/DeployImplementations.s.sol | 9 +++++++- .../scripts/DeployOPChain.s.sol | 10 --------- packages/contracts-bedrock/semver-lock.json | 4 ++-- .../snapshots/abi/OPStackManager.json | 5 ----- .../snapshots/abi/OPStackManagerInterop.json | 5 ----- .../src/L1/OPStackManager.sol | 21 ++++++++++++++++--- .../test/DeployOPChain.t.sol | 11 ---------- 12 files changed, 28 insertions(+), 42 deletions(-) diff --git a/op-chain-ops/deployer/integration_test/apply_test.go b/op-chain-ops/deployer/integration_test/apply_test.go index 84ad7d52c554..55bcd8707354 100644 --- a/op-chain-ops/deployer/integration_test/apply_test.go +++ b/op-chain-ops/deployer/integration_test/apply_test.go @@ -181,7 +181,6 @@ func TestEndToEndApply(t *testing.T) { {"L1CrossDomainMessengerProxyAddress", chainState.L1CrossDomainMessengerProxyAddress}, {"OptimismPortalProxyAddress", chainState.OptimismPortalProxyAddress}, {"DisputeGameFactoryProxyAddress", chainState.DisputeGameFactoryProxyAddress}, - {"DisputeGameFactoryImplAddress", chainState.DisputeGameFactoryImplAddress}, {"AnchorStateRegistryProxyAddress", chainState.AnchorStateRegistryProxyAddress}, {"AnchorStateRegistryImplAddress", chainState.AnchorStateRegistryImplAddress}, {"FaultDisputeGameAddress", chainState.FaultDisputeGameAddress}, diff --git a/op-chain-ops/deployer/opsm/opchain.go b/op-chain-ops/deployer/opsm/opchain.go index b67eba701f93..4e970d455859 100644 --- a/op-chain-ops/deployer/opsm/opchain.go +++ b/op-chain-ops/deployer/opsm/opchain.go @@ -39,7 +39,6 @@ type DeployOPChainOutput struct { // Fault proof contracts below. OptimismPortalProxy common.Address DisputeGameFactoryProxy common.Address - DisputeGameFactoryImpl common.Address AnchorStateRegistryProxy common.Address AnchorStateRegistryImpl common.Address FaultDisputeGame common.Address diff --git a/op-chain-ops/deployer/pipeline/opchain.go b/op-chain-ops/deployer/pipeline/opchain.go index c3a18e7b7383..f3f577cf26a8 100644 --- a/op-chain-ops/deployer/pipeline/opchain.go +++ b/op-chain-ops/deployer/pipeline/opchain.go @@ -85,7 +85,6 @@ func DeployOPChain(ctx context.Context, env *Env, intent *state.Intent, st *stat L1CrossDomainMessengerProxyAddress: dco.L1CrossDomainMessengerProxy, OptimismPortalProxyAddress: dco.OptimismPortalProxy, DisputeGameFactoryProxyAddress: dco.DisputeGameFactoryProxy, - DisputeGameFactoryImplAddress: dco.DisputeGameFactoryImpl, AnchorStateRegistryProxyAddress: dco.AnchorStateRegistryProxy, AnchorStateRegistryImplAddress: dco.AnchorStateRegistryImpl, FaultDisputeGameAddress: dco.FaultDisputeGame, diff --git a/op-chain-ops/deployer/state/state.go b/op-chain-ops/deployer/state/state.go index 75fbd60f2dc9..be679300ffdf 100644 --- a/op-chain-ops/deployer/state/state.go +++ b/op-chain-ops/deployer/state/state.go @@ -86,7 +86,6 @@ type ChainState struct { L1CrossDomainMessengerProxyAddress common.Address `json:"l1CrossDomainMessengerProxyAddress"` OptimismPortalProxyAddress common.Address `json:"optimismPortalProxyAddress"` DisputeGameFactoryProxyAddress common.Address `json:"disputeGameFactoryProxyAddress"` - DisputeGameFactoryImplAddress common.Address `json:"disputeGameFactoryImplAddress"` AnchorStateRegistryProxyAddress common.Address `json:"anchorStateRegistryProxyAddress"` AnchorStateRegistryImplAddress common.Address `json:"anchorStateRegistryImplAddress"` FaultDisputeGameAddress common.Address `json:"faultDisputeGameAddress"` diff --git a/op-chain-ops/interopgen/deployments.go b/op-chain-ops/interopgen/deployments.go index d360ad9292fe..dcb2fb114c26 100644 --- a/op-chain-ops/interopgen/deployments.go +++ b/op-chain-ops/interopgen/deployments.go @@ -45,7 +45,6 @@ type L2OpchainDeployment struct { // Fault proof contracts below. OptimismPortalProxy common.Address `json:"OptimismPortalProxy"` DisputeGameFactoryProxy common.Address `json:"DisputeGameFactoryProxy"` - DisputeGameFactoryImpl common.Address `json:"DisputeGameFactoryImpl"` AnchorStateRegistryProxy common.Address `json:"AnchorStateRegistryProxy"` AnchorStateRegistryImpl common.Address `json:"AnchorStateRegistryImpl"` FaultDisputeGame common.Address `json:"FaultDisputeGame"` diff --git a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol index 5ea8d9a1e13a..8f8c8f4b96c1 100644 --- a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol +++ b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol @@ -363,7 +363,7 @@ contract DeployImplementations is Script { vm.stopBroadcast(); // forgefmt: disable-end - OPStackManager.ImplementationSetter[] memory setters = new OPStackManager.ImplementationSetter[](6); + OPStackManager.ImplementationSetter[] memory setters = new OPStackManager.ImplementationSetter[](7); setters[0] = OPStackManager.ImplementationSetter({ name: "L1ERC721Bridge", info: OPStackManager.Implementation(address(_dio.l1ERC721BridgeImpl()), L1ERC721Bridge.initialize.selector) @@ -390,6 +390,13 @@ contract DeployImplementations is Script { info: OPStackManager.Implementation(address(_dio.l1StandardBridgeImpl()), L1StandardBridge.initialize.selector) }); + setters[6] = OPStackManager.ImplementationSetter({ + name: "DisputeGameFactory", + info: OPStackManager.Implementation( + address(_dio.disputeGameFactoryImpl()), DisputeGameFactory.initialize.selector + ) + }); + // This call contains a broadcast to deploy OPSM which is proxied. OPStackManager opsm = createOPSMContract(_dii, _dio, blueprints, release, setters); diff --git a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol index 2aac28d874e0..3a6369f4cc6d 100644 --- a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol @@ -138,7 +138,6 @@ contract DeployOPChainOutput is BaseDeployIO { L1CrossDomainMessenger internal _l1CrossDomainMessengerProxy; OptimismPortal2 internal _optimismPortalProxy; DisputeGameFactory internal _disputeGameFactoryProxy; - DisputeGameFactory internal _disputeGameFactoryImpl; AnchorStateRegistry internal _anchorStateRegistryProxy; AnchorStateRegistry internal _anchorStateRegistryImpl; FaultDisputeGame internal _faultDisputeGame; @@ -158,7 +157,6 @@ contract DeployOPChainOutput is BaseDeployIO { else if (sel == this.l1CrossDomainMessengerProxy.selector) _l1CrossDomainMessengerProxy = L1CrossDomainMessenger(_addr) ; else if (sel == this.optimismPortalProxy.selector) _optimismPortalProxy = OptimismPortal2(payable(_addr)) ; else if (sel == this.disputeGameFactoryProxy.selector) _disputeGameFactoryProxy = DisputeGameFactory(_addr) ; - else if (sel == this.disputeGameFactoryImpl.selector) _disputeGameFactoryImpl = DisputeGameFactory(_addr) ; else if (sel == this.anchorStateRegistryProxy.selector) _anchorStateRegistryProxy = AnchorStateRegistry(_addr) ; else if (sel == this.anchorStateRegistryImpl.selector) _anchorStateRegistryImpl = AnchorStateRegistry(_addr) ; else if (sel == this.faultDisputeGame.selector) _faultDisputeGame = FaultDisputeGame(_addr) ; @@ -189,7 +187,6 @@ contract DeployOPChainOutput is BaseDeployIO { address[] memory addrs2 = Solarray.addresses( address(_optimismPortalProxy), address(_disputeGameFactoryProxy), - address(_disputeGameFactoryImpl), address(_anchorStateRegistryProxy), address(_anchorStateRegistryImpl), address(_faultDisputeGame), @@ -247,11 +244,6 @@ contract DeployOPChainOutput is BaseDeployIO { return _disputeGameFactoryProxy; } - function disputeGameFactoryImpl() public view returns (DisputeGameFactory) { - DeployUtils.assertValidContractAddress(address(_disputeGameFactoryImpl)); - return _disputeGameFactoryImpl; - } - function anchorStateRegistryProxy() public view returns (AnchorStateRegistry) { DeployUtils.assertValidContractAddress(address(_anchorStateRegistryProxy)); return _anchorStateRegistryProxy; @@ -448,7 +440,6 @@ contract DeployOPChain is Script { vm.label(address(deployOutput.l1CrossDomainMessengerProxy), "l1CrossDomainMessengerProxy"); vm.label(address(deployOutput.optimismPortalProxy), "optimismPortalProxy"); vm.label(address(deployOutput.disputeGameFactoryProxy), "disputeGameFactoryProxy"); - vm.label(address(deployOutput.disputeGameFactoryImpl), "disputeGameFactoryImpl"); vm.label(address(deployOutput.anchorStateRegistryProxy), "anchorStateRegistryProxy"); vm.label(address(deployOutput.anchorStateRegistryImpl), "anchorStateRegistryImpl"); vm.label(address(deployOutput.faultDisputeGame), "faultDisputeGame"); @@ -467,7 +458,6 @@ contract DeployOPChain is Script { _doo.set(_doo.l1CrossDomainMessengerProxy.selector, address(deployOutput.l1CrossDomainMessengerProxy)); _doo.set(_doo.optimismPortalProxy.selector, address(deployOutput.optimismPortalProxy)); _doo.set(_doo.disputeGameFactoryProxy.selector, address(deployOutput.disputeGameFactoryProxy)); - _doo.set(_doo.disputeGameFactoryImpl.selector, address(deployOutput.disputeGameFactoryImpl)); _doo.set(_doo.anchorStateRegistryProxy.selector, address(deployOutput.anchorStateRegistryProxy)); _doo.set(_doo.anchorStateRegistryImpl.selector, address(deployOutput.anchorStateRegistryImpl)); _doo.set(_doo.faultDisputeGame.selector, address(deployOutput.faultDisputeGame)); diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index d153fbec3e58..511ca68be89a 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -32,8 +32,8 @@ "sourceCodeHash": "0xde4df0f9633dc0cdb1c9f634003ea5b0f7c5c1aebc407bc1b2f44c0ecf938649" }, "src/L1/OPStackManager.sol": { - "initCodeHash": "0x31378d0ea88a358f517927f5bc530a5b958f43c5462e4a822388ec70bd45e8d4", - "sourceCodeHash": "0x9ed271fbb40f25528652bfecc10d2010a588629047b3aaed2b14247d2fa7b45e" + "initCodeHash": "0xfcb568c59e2b4fd927b27b3434db657b53571bf64f70bc8453aaf696eda9c3f9", + "sourceCodeHash": "0xfc9069d6967b9b90413fe391805509b178dd134b008a582e4dc64afe14cc1b2a" }, "src/L1/OptimismPortal.sol": { "initCodeHash": "0xb7a7a28d5b3b88334e7cb4bc1c5fbbf9f691d934e907a2fed6a30e461eb1c0f6", diff --git a/packages/contracts-bedrock/snapshots/abi/OPStackManager.json b/packages/contracts-bedrock/snapshots/abi/OPStackManager.json index 42369b8ef4dc..151a9db162bb 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPStackManager.json +++ b/packages/contracts-bedrock/snapshots/abi/OPStackManager.json @@ -185,11 +185,6 @@ "name": "disputeGameFactoryProxy", "type": "address" }, - { - "internalType": "contract DisputeGameFactory", - "name": "disputeGameFactoryImpl", - "type": "address" - }, { "internalType": "contract AnchorStateRegistry", "name": "anchorStateRegistryProxy", diff --git a/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json b/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json index 42369b8ef4dc..151a9db162bb 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json +++ b/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json @@ -185,11 +185,6 @@ "name": "disputeGameFactoryProxy", "type": "address" }, - { - "internalType": "contract DisputeGameFactory", - "name": "disputeGameFactoryImpl", - "type": "address" - }, { "internalType": "contract AnchorStateRegistry", "name": "anchorStateRegistryProxy", diff --git a/packages/contracts-bedrock/src/L1/OPStackManager.sol b/packages/contracts-bedrock/src/L1/OPStackManager.sol index 62f3d70658cd..94c6c9151cec 100644 --- a/packages/contracts-bedrock/src/L1/OPStackManager.sol +++ b/packages/contracts-bedrock/src/L1/OPStackManager.sol @@ -69,7 +69,6 @@ contract OPStackManager is ISemver, Initializable { // Fault proof contracts below. OptimismPortal2 optimismPortalProxy; DisputeGameFactory disputeGameFactoryProxy; - DisputeGameFactory disputeGameFactoryImpl; AnchorStateRegistry anchorStateRegistryProxy; AnchorStateRegistry anchorStateRegistryImpl; FaultDisputeGame faultDisputeGame; @@ -206,8 +205,6 @@ contract OPStackManager is ISemver, Initializable { // -------- TODO: Placeholders -------- // For contracts we don't yet deploy, we set the outputs to dummy proxies so they have code to pass assertions. // We do these first, that way the disputeGameFactoryProxy is set when passed to the SystemConfig input. - output.disputeGameFactoryProxy = DisputeGameFactory(deployProxy(l2ChainId, output.opChainProxyAdmin, "1")); - output.disputeGameFactoryImpl = DisputeGameFactory(deployProxy(l2ChainId, output.opChainProxyAdmin, "2")); output.anchorStateRegistryProxy = AnchorStateRegistry(deployProxy(l2ChainId, output.opChainProxyAdmin, "3")); output.anchorStateRegistryImpl = AnchorStateRegistry(deployProxy(l2ChainId, output.opChainProxyAdmin, "4")); output.faultDisputeGame = FaultDisputeGame(deployProxy(l2ChainId, output.opChainProxyAdmin, "5")); @@ -238,6 +235,8 @@ contract OPStackManager is ISemver, Initializable { output.optimismMintableERC20FactoryProxy = OptimismMintableERC20Factory( deployProxy(l2ChainId, output.opChainProxyAdmin, "OptimismMintableERC20Factory") ); + output.disputeGameFactoryProxy = + DisputeGameFactory(deployProxy(l2ChainId, output.opChainProxyAdmin, "DisputeGameFactory")); // Deploy legacy proxied contracts. output.l1StandardBridgeProxy = L1StandardBridge( @@ -285,6 +284,10 @@ contract OPStackManager is ISemver, Initializable { data = encodeL1StandardBridgeInitializer(impl.initializer, output); upgradeAndCall(output.opChainProxyAdmin, address(output.l1StandardBridgeProxy), impl.logic, data); + impl = getLatestImplementation("DisputeGameFactory"); + data = encodeDisputeGameFactoryInitializer(impl.initializer, _input); + upgradeAndCall(output.opChainProxyAdmin, address(output.disputeGameFactoryProxy), impl.logic, data); + // -------- Finalize Deployment -------- // Transfer ownership of the ProxyAdmin from this contract to the specified owner. output.opChainProxyAdmin.transferOwnership(_input.roles.opChainProxyAdminOwner); @@ -440,6 +443,18 @@ contract OPStackManager is ISemver, Initializable { ); } + function encodeDisputeGameFactoryInitializer( + bytes4 _selector, + DeployInput memory _input + ) + internal + view + virtual + returns (bytes memory) + { + return abi.encodeWithSelector(_selector, _input.roles.opChainProxyAdminOwner); + } + /// @notice Returns default, standard config arguments for the SystemConfig initializer. /// This is used by subclasses to reduce code duplication. function defaultSystemConfigParams( diff --git a/packages/contracts-bedrock/test/DeployOPChain.t.sol b/packages/contracts-bedrock/test/DeployOPChain.t.sol index 43ff82d1daa8..57f67ced77ed 100644 --- a/packages/contracts-bedrock/test/DeployOPChain.t.sol +++ b/packages/contracts-bedrock/test/DeployOPChain.t.sol @@ -121,7 +121,6 @@ contract DeployOPChainOutput_Test is Test { L1CrossDomainMessenger l1CrossDomainMessengerProxy = L1CrossDomainMessenger(makeAddr("l1CrossDomainMessengerProxy")); OptimismPortal2 optimismPortalProxy = OptimismPortal2(payable(makeAddr("optimismPortalProxy"))); DisputeGameFactory disputeGameFactoryProxy = DisputeGameFactory(makeAddr("disputeGameFactoryProxy")); - DisputeGameFactory disputeGameFactoryImpl = DisputeGameFactory(makeAddr("disputeGameFactoryImpl")); AnchorStateRegistry anchorStateRegistryProxy = AnchorStateRegistry(makeAddr("anchorStateRegistryProxy")); AnchorStateRegistry anchorStateRegistryImpl = AnchorStateRegistry(makeAddr("anchorStateRegistryImpl")); FaultDisputeGame faultDisputeGame = FaultDisputeGame(makeAddr("faultDisputeGame")); @@ -144,7 +143,6 @@ contract DeployOPChainOutput_Test is Test { vm.etch(address(l1CrossDomainMessengerProxy), hex"01"); vm.etch(address(optimismPortalProxy), hex"01"); vm.etch(address(disputeGameFactoryProxy), hex"01"); - vm.etch(address(disputeGameFactoryImpl), hex"01"); vm.etch(address(anchorStateRegistryProxy), hex"01"); vm.etch(address(anchorStateRegistryImpl), hex"01"); vm.etch(address(faultDisputeGame), hex"01"); @@ -161,7 +159,6 @@ contract DeployOPChainOutput_Test is Test { doo.set(doo.l1CrossDomainMessengerProxy.selector, address(l1CrossDomainMessengerProxy)); doo.set(doo.optimismPortalProxy.selector, address(optimismPortalProxy)); doo.set(doo.disputeGameFactoryProxy.selector, address(disputeGameFactoryProxy)); - doo.set(doo.disputeGameFactoryImpl.selector, address(disputeGameFactoryImpl)); doo.set(doo.anchorStateRegistryProxy.selector, address(anchorStateRegistryProxy)); doo.set(doo.anchorStateRegistryImpl.selector, address(anchorStateRegistryImpl)); doo.set(doo.faultDisputeGame.selector, address(faultDisputeGame)); @@ -178,7 +175,6 @@ contract DeployOPChainOutput_Test is Test { assertEq(address(l1CrossDomainMessengerProxy), address(doo.l1CrossDomainMessengerProxy()), "700"); assertEq(address(optimismPortalProxy), address(doo.optimismPortalProxy()), "800"); assertEq(address(disputeGameFactoryProxy), address(doo.disputeGameFactoryProxy()), "900"); - assertEq(address(disputeGameFactoryImpl), address(doo.disputeGameFactoryImpl()), "1000"); assertEq(address(anchorStateRegistryProxy), address(doo.anchorStateRegistryProxy()), "1100"); assertEq(address(anchorStateRegistryImpl), address(doo.anchorStateRegistryImpl()), "1200"); assertEq(address(faultDisputeGame), address(doo.faultDisputeGame()), "1300"); @@ -217,9 +213,6 @@ contract DeployOPChainOutput_Test is Test { vm.expectRevert(expectedErr); doo.disputeGameFactoryProxy(); - vm.expectRevert(expectedErr); - doo.disputeGameFactoryImpl(); - vm.expectRevert(expectedErr); doo.anchorStateRegistryProxy(); @@ -279,10 +272,6 @@ contract DeployOPChainOutput_Test is Test { vm.expectRevert(expectedErr); doo.disputeGameFactoryProxy(); - doo.set(doo.disputeGameFactoryImpl.selector, emptyAddr); - vm.expectRevert(expectedErr); - doo.disputeGameFactoryImpl(); - doo.set(doo.anchorStateRegistryProxy.selector, emptyAddr); vm.expectRevert(expectedErr); doo.anchorStateRegistryProxy(); From 668c3fba48ba5e0e5a1222209b49c432dec2382b Mon Sep 17 00:00:00 2001 From: clabby Date: Tue, 17 Sep 2024 16:11:46 -0400 Subject: [PATCH 172/264] fix: Remove `--l2-chain-id` default (#11951) --- op-challenger/game/fault/trace/vm/kona_server_executor.go | 1 - 1 file changed, 1 deletion(-) diff --git a/op-challenger/game/fault/trace/vm/kona_server_executor.go b/op-challenger/game/fault/trace/vm/kona_server_executor.go index dfb358b41448..a8be1c7bc562 100644 --- a/op-challenger/game/fault/trace/vm/kona_server_executor.go +++ b/op-challenger/game/fault/trace/vm/kona_server_executor.go @@ -46,7 +46,6 @@ func (s *KonaExecutor) OracleCommand(cfg Config, dataDir string, inputs utils.Lo if cfg.RollupConfigPath != "" { args = append(args, "--rollup-config-path", cfg.RollupConfigPath) - args = append(args, "--l2-chain-id", "0") } else { if cfg.Network == "" { return nil, errors.New("network is not defined") From 9179225da1e0b594686c16d5d8101fa7e03a013f Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 17 Sep 2024 17:16:05 -0400 Subject: [PATCH 173/264] feat: Add ASR proxy to OPStackManager (#11952) * feat: Add ASR proxy to OPStackManager * feat: Add AnchorStateRegistry blueprint --- .../scripts/DeployImplementations.s.sol | 2 ++ packages/contracts-bedrock/semver-lock.json | 4 ++-- .../snapshots/abi/OPStackManager.json | 10 ++++++++++ .../snapshots/abi/OPStackManagerInterop.json | 10 ++++++++++ .../snapshots/storageLayout/OPStackManager.json | 8 ++++---- .../snapshots/storageLayout/OPStackManagerInterop.json | 8 ++++---- packages/contracts-bedrock/src/L1/OPStackManager.sol | 9 +++++++++ 7 files changed, 41 insertions(+), 10 deletions(-) diff --git a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol index 8f8c8f4b96c1..3cb120adc02f 100644 --- a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol +++ b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol @@ -16,6 +16,7 @@ import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol"; import { MIPS } from "src/cannon/MIPS.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; +import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; @@ -360,6 +361,7 @@ contract DeployImplementations is Script { blueprints.proxyAdmin = deployBytecode(Blueprint.blueprintDeployerBytecode(type(ProxyAdmin).creationCode), salt); blueprints.l1ChugSplashProxy = deployBytecode(Blueprint.blueprintDeployerBytecode(type(L1ChugSplashProxy).creationCode), salt); blueprints.resolvedDelegateProxy = deployBytecode(Blueprint.blueprintDeployerBytecode(type(ResolvedDelegateProxy).creationCode), salt); + blueprints.anchorStateRegistry = deployBytecode(Blueprint.blueprintDeployerBytecode(type(AnchorStateRegistry).creationCode), salt); vm.stopBroadcast(); // forgefmt: disable-end diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 511ca68be89a..8a2ac2ba5b8b 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -32,8 +32,8 @@ "sourceCodeHash": "0xde4df0f9633dc0cdb1c9f634003ea5b0f7c5c1aebc407bc1b2f44c0ecf938649" }, "src/L1/OPStackManager.sol": { - "initCodeHash": "0xfcb568c59e2b4fd927b27b3434db657b53571bf64f70bc8453aaf696eda9c3f9", - "sourceCodeHash": "0xfc9069d6967b9b90413fe391805509b178dd134b008a582e4dc64afe14cc1b2a" + "initCodeHash": "0x022b3f6a80eb637972dd0d9ce8666a037c4b916889f44f86771d8c3add9d615d", + "sourceCodeHash": "0xb085725e18c1a0cc1826b770e403ecad765fce686bb80555bf0f6c3c67b21cba" }, "src/L1/OptimismPortal.sol": { "initCodeHash": "0xb7a7a28d5b3b88334e7cb4bc1c5fbbf9f691d934e907a2fed6a30e461eb1c0f6", diff --git a/packages/contracts-bedrock/snapshots/abi/OPStackManager.json b/packages/contracts-bedrock/snapshots/abi/OPStackManager.json index 151a9db162bb..8f8d68515681 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPStackManager.json +++ b/packages/contracts-bedrock/snapshots/abi/OPStackManager.json @@ -45,6 +45,11 @@ "internalType": "address", "name": "resolvedDelegateProxy", "type": "address" + }, + { + "internalType": "address", + "name": "anchorStateRegistry", + "type": "address" } ], "internalType": "struct OPStackManager.Blueprints", @@ -283,6 +288,11 @@ "internalType": "address", "name": "resolvedDelegateProxy", "type": "address" + }, + { + "internalType": "address", + "name": "anchorStateRegistry", + "type": "address" } ], "internalType": "struct OPStackManager.Blueprints", diff --git a/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json b/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json index 151a9db162bb..8f8d68515681 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json +++ b/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json @@ -45,6 +45,11 @@ "internalType": "address", "name": "resolvedDelegateProxy", "type": "address" + }, + { + "internalType": "address", + "name": "anchorStateRegistry", + "type": "address" } ], "internalType": "struct OPStackManager.Blueprints", @@ -283,6 +288,11 @@ "internalType": "address", "name": "resolvedDelegateProxy", "type": "address" + }, + { + "internalType": "address", + "name": "anchorStateRegistry", + "type": "address" } ], "internalType": "struct OPStackManager.Blueprints", diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OPStackManager.json b/packages/contracts-bedrock/snapshots/storageLayout/OPStackManager.json index e19eff235994..881871a50dd1 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/OPStackManager.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/OPStackManager.json @@ -14,7 +14,7 @@ "type": "bool" }, { - "bytes": "160", + "bytes": "192", "label": "blueprint", "offset": 0, "slot": "1", @@ -24,21 +24,21 @@ "bytes": "32", "label": "latestRelease", "offset": 0, - "slot": "6", + "slot": "7", "type": "string" }, { "bytes": "32", "label": "implementations", "offset": 0, - "slot": "7", + "slot": "8", "type": "mapping(string => mapping(string => struct OPStackManager.Implementation))" }, { "bytes": "32", "label": "systemConfigs", "offset": 0, - "slot": "8", + "slot": "9", "type": "mapping(uint256 => contract SystemConfig)" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OPStackManagerInterop.json b/packages/contracts-bedrock/snapshots/storageLayout/OPStackManagerInterop.json index e19eff235994..881871a50dd1 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/OPStackManagerInterop.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/OPStackManagerInterop.json @@ -14,7 +14,7 @@ "type": "bool" }, { - "bytes": "160", + "bytes": "192", "label": "blueprint", "offset": 0, "slot": "1", @@ -24,21 +24,21 @@ "bytes": "32", "label": "latestRelease", "offset": 0, - "slot": "6", + "slot": "7", "type": "string" }, { "bytes": "32", "label": "implementations", "offset": 0, - "slot": "7", + "slot": "8", "type": "mapping(string => mapping(string => struct OPStackManager.Implementation))" }, { "bytes": "32", "label": "systemConfigs", "offset": 0, - "slot": "8", + "slot": "9", "type": "mapping(uint256 => contract SystemConfig)" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/src/L1/OPStackManager.sol b/packages/contracts-bedrock/src/L1/OPStackManager.sol index 94c6c9151cec..dad32c5628ea 100644 --- a/packages/contracts-bedrock/src/L1/OPStackManager.sol +++ b/packages/contracts-bedrock/src/L1/OPStackManager.sol @@ -101,6 +101,7 @@ contract OPStackManager is ISemver, Initializable { address proxyAdmin; address l1ChugSplashProxy; address resolvedDelegateProxy; + address anchorStateRegistry; } /// @notice Inputs required when initializing the OPStackManager. To avoid 'StackTooDeep' errors, @@ -237,6 +238,8 @@ contract OPStackManager is ISemver, Initializable { ); output.disputeGameFactoryProxy = DisputeGameFactory(deployProxy(l2ChainId, output.opChainProxyAdmin, "DisputeGameFactory")); + output.anchorStateRegistryProxy = + AnchorStateRegistry(deployProxy(l2ChainId, output.opChainProxyAdmin, "AnchorStateRegistry")); // Deploy legacy proxied contracts. output.l1StandardBridgeProxy = L1StandardBridge( @@ -256,6 +259,12 @@ contract OPStackManager is ISemver, Initializable { // Now that all proxies are deployed, we can transfer ownership of the AddressManager to the ProxyAdmin. output.addressManager.transferOwnership(address(output.opChainProxyAdmin)); + // The AnchorStateRegistry Implementation is not MCP Ready, and therefore requires an implementation per chain. + // It must be deployed after the DisputeGameFactoryProxy so that it can be provided as a constructor argument. + output.anchorStateRegistryImpl = AnchorStateRegistry( + Blueprint.deployFrom(blueprint.anchorStateRegistry, salt, abi.encode(output.disputeGameFactoryProxy)) + ); + // -------- Set and Initialize Proxy Implementations -------- Implementation storage impl; bytes memory data; From a7fac3b734b12c3c36cc08e1d90712745d0d2952 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Tue, 17 Sep 2024 18:56:20 -0400 Subject: [PATCH 174/264] ci: run slow Cannon test once per day (#11947) Updates CI to run the (very) slow Cannon go-lint-and-test suite once per day instead of running it on merge since it adds at least 5 minutes to CI. --- .circleci/config.yml | 36 +++++++++++++++++++ .../multithreaded/instrumented_test.go | 4 +++ 2 files changed, 40 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4a4973a8d294..fd56063b8caa 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -29,6 +29,9 @@ parameters: kontrol_dispatch: type: boolean default: false + cannon_full_test_dispatch: + type: boolean + default: false sdk_dispatch: type: boolean default: false @@ -134,6 +137,14 @@ jobs: cannon-go-lint-and-test: docker: - image: <> + parameters: + skip_slow_tests: + type: boolean + default: false + notify: + description: Whether to notify on failure + type: boolean + default: false resource_class: xlarge steps: - checkout @@ -141,6 +152,9 @@ jobs: patterns: cannon,packages/contracts-bedrock/src/cannon,op-preimage,go.mod - attach_workspace: at: "." + - restore_cache: + name: Restore Go modules cache + key: gomod-{{ checksum "go.sum" }} - run: name: prep Cannon results dir command: mkdir -p /tmp/test-results @@ -156,6 +170,7 @@ jobs: - run: name: Cannon Go tests command: | + export SKIP_SLOW_TESTS=<> mkdir -p /testlogs gotestsum --format=testname --junitfile=/tmp/test-results/cannon.xml --jsonfile=/testlogs/log.json \ -- -parallel=8 -coverpkg=github.com/ethereum-optimism/optimism/cannon/... -coverprofile=coverage.out ./... @@ -168,6 +183,11 @@ jobs: - store_artifacts: path: /testlogs when: always + - when: + condition: <> + steps: + - notify-failures-on-develop: + mentions: "@proofs-squad" cannon-build-test-vectors: docker: @@ -1836,6 +1856,8 @@ workflows: - cannon-go-lint-and-test: requires: - contracts-bedrock-build + skip_slow_tests: true + notify: true - cannon-build-test-vectors - shellcheck/check: name: shell-check @@ -2150,6 +2172,20 @@ workflows: - slack - runtimeverification + scheduled-cannon-full-tests: + when: + or: + - equal: [ build_four_hours, <> ] + - equal: [ true, << pipeline.parameters.cannon_full_test_dispatch >> ] + jobs: + - contracts-bedrock-build: + build_command: forge build --skip test --skip scripts + - cannon-go-lint-and-test: + requires: + - contracts-bedrock-build + context: + - slack + scheduled-docker-publish: when: or: diff --git a/cannon/mipsevm/multithreaded/instrumented_test.go b/cannon/mipsevm/multithreaded/instrumented_test.go index 403897a9723d..75a0694e3607 100644 --- a/cannon/mipsevm/multithreaded/instrumented_test.go +++ b/cannon/mipsevm/multithreaded/instrumented_test.go @@ -58,6 +58,10 @@ func TestInstrumentedState_MultithreadedProgram(t *testing.T) { } func TestInstrumentedState_Alloc(t *testing.T) { + if os.Getenv("SKIP_SLOW_TESTS") == "true" { + t.Skip("Skipping slow test because SKIP_SLOW_TESTS is enabled") + } + const MiB = 1024 * 1024 cases := []struct { From e15f6843dda7e38d8d3975d65f5228fa01ed8a18 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Tue, 17 Sep 2024 18:57:25 -0400 Subject: [PATCH 175/264] fix: move IERC20Solady into vendor folder (#11945) An additional "dependency" folder was added in a recent PR, this is the same purpose as the "vendor" folder so the interface added in that PR can simply be moved to the "vendor" folder instead. --- .../src/L2/interfaces/IOptimismSuperchainERC20.sol | 5 +++-- .../contracts-bedrock/src/L2/interfaces/ISuperchainERC20.sol | 3 ++- .../src/{dependency => vendor}/interfaces/IERC20Solady.sol | 0 3 files changed, 5 insertions(+), 3 deletions(-) rename packages/contracts-bedrock/src/{dependency => vendor}/interfaces/IERC20Solady.sol (100%) diff --git a/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20.sol b/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20.sol index 91a51e0fb543..5f537c1f51ec 100644 --- a/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20.sol +++ b/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20.sol @@ -1,8 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { IERC20Solady } from "src/dependency/interfaces/IERC20Solady.sol"; -import { ISuperchainERC20Extensions, ISuperchainERC20Errors } from "./ISuperchainERC20.sol"; +// Interfaces +import { IERC20Solady } from "src/vendor/interfaces/IERC20Solady.sol"; +import { ISuperchainERC20Extensions, ISuperchainERC20Errors } from "src/L2/interfaces/ISuperchainERC20.sol"; /// @title IOptimismSuperchainERC20Extension /// @notice This interface is available on the OptimismSuperchainERC20 contract. diff --git a/packages/contracts-bedrock/src/L2/interfaces/ISuperchainERC20.sol b/packages/contracts-bedrock/src/L2/interfaces/ISuperchainERC20.sol index 78f7ae7fc1d7..fee6a2c2f7bd 100644 --- a/packages/contracts-bedrock/src/L2/interfaces/ISuperchainERC20.sol +++ b/packages/contracts-bedrock/src/L2/interfaces/ISuperchainERC20.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { IERC20Solady } from "src/dependency/interfaces/IERC20Solady.sol"; +// Interfaces +import { IERC20Solady } from "src/vendor/interfaces/IERC20Solady.sol"; /// @title ISuperchainERC20Extensions /// @notice Interface for the extensions to the ERC20 standard that are used by SuperchainERC20. diff --git a/packages/contracts-bedrock/src/dependency/interfaces/IERC20Solady.sol b/packages/contracts-bedrock/src/vendor/interfaces/IERC20Solady.sol similarity index 100% rename from packages/contracts-bedrock/src/dependency/interfaces/IERC20Solady.sol rename to packages/contracts-bedrock/src/vendor/interfaces/IERC20Solady.sol From 518b050bfa1f90b73e706e65b3e28f9022e9d64e Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Tue, 17 Sep 2024 19:21:56 -0400 Subject: [PATCH 176/264] ci: bump semgrep-scan to xlarge (#11948) We're still having resource issues with a large image. Going to bump this to xlarge to see if that will fix it. --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index fd56063b8caa..04f4f5bd7593 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1391,7 +1391,7 @@ jobs: SEMGREP_COMMIT: << pipeline.git.revision >> docker: - image: returntocorp/semgrep - resource_class: large + resource_class: xlarge steps: - checkout - unless: From 9de48fc250fd641337a12f60cd6f979ea56b4e62 Mon Sep 17 00:00:00 2001 From: teddy Date: Tue, 17 Sep 2024 21:02:19 -0300 Subject: [PATCH 177/264] test: invariant tests for OptimismSuperchainERC20 (#11776) * chore: configure medusa with basic supERC20 self-bridging (#19) - used --foundry-compile-all to ensure the test contract under `test/properties` is compiled (otherwise it is not compiled and medusa crashes when it can't find it's compiled representation) - set src,test,script to test/properties/medusa to not waste time compiling contracts that are not required for the medusa campaign - used an atomic bridge, which doesnt allow for testing of several of the proposed invariants fix: delete dead code test: give the fuzzer a head start docs: fix properties order test: document & implement assertions 22, 23 and 24 fix: fixes from self-review test: guide the fuzzer a little bit less previously: initial mint, bound on transfer amount: 146625 calls in 200s now: no initial mint, no bound on transfer amount: 176835 calls in 200s it doesn't seem to slow the fuzzer down fix: fixes after lovely feedback by disco docs: merge both documents and categorized properties by their milestone fix: fixes from parti's review fix: feedback from disco fix: feedback from doc refactor: separate state transitions from pure properties docs: update tested properties refactor: move all assertions into properties contract fix: move function without assertions back into handler test: only use assertion mode fix: improve justfile recipie for medusa * feat: halmos symbolic tests (#21) * feat: introduce OptimismSuperchainERC20 * fix: contract fixes * feat: add snapshots and semver * test: add supports interface tests * test: add invariant test * feat: add parameters to the RelayERC20 event * fix: typo * fix: from param description * fix: event signature and interface pragma * feat: add initializer * feat: use unstructured storage and OZ v5 * feat: update superchain erc20 interfaces * fix: adapt storage to ERC7201 * test: add initializable OZ v5 test * fix: invariant docs * fix: ERC165 implementation * test: improve superc20 invariant (#11) * fix: gas snapshot * chore: configure medusa with basic supERC20 self-bridging - used --foundry-compile-all to ensure the test contract under `test/properties` is compiled (otherwise it is not compiled and medusa crashes when it can't find it's compiled representation) - set src,test,script to test/properties/medusa to not waste time compiling contracts that are not required for the medusa campaign - used an atomic bridge, which doesnt allow for testing of several of the proposed invariants * fix: delete dead code * test: give the fuzzer a head start * feat: create suite for sybolic tests with halmos * test: setup and 3 properties with symbolic tests * chore: remove todo comment * docs: fix properties order * test: document & implement assertions 22, 23 and 24 * fix: fixes from self-review * test: guide the fuzzer a little bit less previously: initial mint, bound on transfer amount: 146625 calls in 200s now: no initial mint, no bound on transfer amount: 176835 calls in 200s it doesn't seem to slow the fuzzer down * feat: add property for burn * refactor: remove symbolic address on mint property * refactor: order the tests based on the property id * feat: checkpoint * chore: set xdomain sender on failing test * chore: enhance mocks * Revert "Merge branch 'chore/setup-medusa' into feat/halmos-symbolic-tests" This reverts commit 945d6b6ad265ea5e3790d7ac9c5bf4d6586eb533, reversing changes made to 5dcb3a89252e9e8fa9b54ba9012e714f7cc96395. * refactor: remove symbolic addresses to make all of the test work * chore: remove console logs * feat: add properties file * chore: polish * refactor: enhance test on property 7 using direct try catch (now works) * fix: review comments * refactor: add symbolic addresses on test functions * feat: create halmos toml * chore: polish test contract and mock * chore: update property * refactor: move symbolic folder into properties one * feat: create advanced tests helper contract * refactor: enhance tests using symbolic addresses instead of concrete ones * chore: remove 0 property natspec * feat: add halmos profile and just script * chore: rename symbolic folder to halmos * feat: add halmos commands to justfile * chore: reorder assertions on one test * refactor: complete test property seven * chore: mark properties as completed * chore: add halmos-cheatcodes dependency * chore: rename advancedtest->halmosbase * chore: minimize mocked messenger * chore: delete empty halmos file * chore: revert changes to medusa.json * docs: update changes to PROPERTIES.md from base branch * test: sendERC20 destination fix * chore: natspec fixes --------- Co-authored-by: agusduha Co-authored-by: 0xng Co-authored-by: teddy * test: remaining protocol properties (#26) * test: cross-user fuzzed bridges + actor setup * test: fuzz properties 8 and 9 * test: properties 7 and 25 * fix: implement doc's feedback * test: superc20 tob properties (#27) * chore: add crytic/properties dependency * test: extend protocol properties so it also covers ToB erc20 properties * chore: small linter fixes * docs: update property list * test: handlers for remaining superc20 state transitions * fix: disable ToB properties we are not using and guide the fuzzer a bit more * fix: disable another ToB property not implemented by solady * chore: remove zero-initializations * fix: feedback from disco * chore: separate fuzz campaign tests in guided vs unguided * test: dont revert on successful unguided relay * test: add fuzzed calls to burn and mint * docs: document the separation of fuzz test functions * chore: move the properties file to its own directory * chore: consistently use fuzz_ and property_ + camelcase * chore: fix typo * chore: camelcase for handlers as well * fix: revert change that broke halmos campaign compile :D * test: fuzz non atomic bridging (#31) * test: changed mocked messenger ABI for message sending but kept assertions the same * docs: add new properties 26&27 * test: queue cross-chain messages and test related properties * test: relay random messages from queue and check associated invariants * chore: rename bridge->senderc20 method for consistency with relayerc20 * test: not-yet-deployed supertokens can get funds sent to them * chore: medusa runs forever by default doable since it also handles SIGINTs gracefully * chore: document the reason behind relay zero and send zero inconsistencies * fix: feedback from doc * fix: walk around possible medusa issue I'm getting an 'unknown opcode 0x4e' in ProtocolAtomic constructor when calling the MockL2ToL2CrossDomainMessenger for the first time * test: unguided handler for sendERC20 * fix: feedback from disco * chore: remove halmos testsuite * chore: foundry migration (#40) * chore: track assertion failures this is so foundry's invariant contract can check that an assertion returned false in the handler, while still allowing `fail_on_revert = false` so we can still take full advantage of medusa's fuzzer & coverage reports * fix: explicitly skip duplicate supertoken deployments * chore: remove duplicated PROPERTIES.md file * chore: expose data to foundry's external invariant checker * test: run medusa fuzzing campaign from within foundry * fix: eagerly check for duplicate deployments * fix: feedback from doc * chore: shoehorn medusa campaign into foundry dir structure * chore: remove PROPERTIES.md file * chore: delete medusa config * docs: limited support for subdirectories in test/invariant * chore: rename contracts to be more sneaky about medusa * docs: rewrite invariant docs in a way compliant with autogen scripts * chore: fixes from rebase * fix: cleanup superc20 invariants (#46) * chore: revert modifications from medusa campaign * docs: extra docs on why ForTest contract is required * doc: add list of all supertoken properties * chore: run forge fmt * ci: allow for testfiles to be deleted * fix: run doc autogen script after rebase --------- Co-authored-by: Disco <131301107+0xDiscotech@users.noreply.github.com> Co-authored-by: agusduha Co-authored-by: 0xng --- .../invariant-docs/OptimismSuperchainERC20.md | 14 +- .../autogen/generate-invariant-docs/main.go | 6 + .../testing/test-heavy-fuzz-modified-tests.sh | 4 + .../invariants/OptimismSuperchainERC20.t.sol | 227 ------------------ .../OptimismSuperchainERC20.t.sol | 83 +++++++ .../OptimismSuperchainERC20/PROPERTIES.md | 82 +++++++ .../fuzz/Protocol.guided.t.sol | 211 ++++++++++++++++ .../fuzz/Protocol.unguided.t.sol | 137 +++++++++++ .../handlers/Protocol.t.sol | 177 ++++++++++++++ .../helpers/Actors.t.sol | 38 +++ .../helpers/CompatibleAssert.t.sol | 28 +++ .../helpers/HandlerGetters.t.sol | 22 ++ .../MockL2ToL2CrossDomainMessenger.t.sol | 118 +++++++++ ...imismSuperchainERC20ForToBProperties.t.sol | 12 + 14 files changed, 928 insertions(+), 231 deletions(-) delete mode 100644 packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20.t.sol create mode 100644 packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/OptimismSuperchainERC20.t.sol create mode 100644 packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/PROPERTIES.md create mode 100644 packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/fuzz/Protocol.guided.t.sol create mode 100644 packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/fuzz/Protocol.unguided.t.sol create mode 100644 packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/handlers/Protocol.t.sol create mode 100644 packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/helpers/Actors.t.sol create mode 100644 packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/helpers/CompatibleAssert.t.sol create mode 100644 packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/helpers/HandlerGetters.t.sol create mode 100644 packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/helpers/MockL2ToL2CrossDomainMessenger.t.sol create mode 100644 packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/helpers/OptimismSuperchainERC20ForToBProperties.t.sol diff --git a/packages/contracts-bedrock/invariant-docs/OptimismSuperchainERC20.md b/packages/contracts-bedrock/invariant-docs/OptimismSuperchainERC20.md index 13d03f304d45..8b5c65ebf213 100644 --- a/packages/contracts-bedrock/invariant-docs/OptimismSuperchainERC20.md +++ b/packages/contracts-bedrock/invariant-docs/OptimismSuperchainERC20.md @@ -1,10 +1,16 @@ # `OptimismSuperchainERC20` Invariants -## Calls to sendERC20 should always succeed as long as the actor has enough balance. Actor's balance should also not increase out of nowhere but instead should decrease by the amount sent. -**Test:** [`OptimismSuperchainERC20.t.sol#L196`](../test/invariants/OptimismSuperchainERC20.t.sol#L196) +## sum of supertoken total supply across all chains is always <= to convert(legacy, super)- convert(super, legacy) +**Test:** [`OptimismSuperchainERC20#L36`](../test/invariants/OptimismSuperchainERC20#L36) -## Calls to relayERC20 should always succeeds when a message is received from another chain. Actor's balance should only increase by the amount relayed. -**Test:** [`OptimismSuperchainERC20.t.sol#L214`](../test/invariants/OptimismSuperchainERC20.t.sol#L214) +## sum of supertoken total supply across all chains is equal to convert(legacy, super)- convert(super, legacy) when all when all cross-chain messages are processed +**Test:** [`OptimismSuperchainERC20#L57`](../test/invariants/OptimismSuperchainERC20#L57) + + +## many other assertion mode invariants are also defined under `test/invariants/OptimismSuperchainERC20/fuzz/` . +**Test:** [`OptimismSuperchainERC20#L80`](../test/invariants/OptimismSuperchainERC20#L80) + +since setting`fail_on_revert=false` also ignores StdAssertion failures, this invariant explicitly asks the handler for assertion test failures \ No newline at end of file diff --git a/packages/contracts-bedrock/scripts/autogen/generate-invariant-docs/main.go b/packages/contracts-bedrock/scripts/autogen/generate-invariant-docs/main.go index 0f0f5c77e63d..457e100edbe3 100644 --- a/packages/contracts-bedrock/scripts/autogen/generate-invariant-docs/main.go +++ b/packages/contracts-bedrock/scripts/autogen/generate-invariant-docs/main.go @@ -77,6 +77,12 @@ func docGen(invariantsDir, docsDir string) error { // Read the contents of the invariant test file. fileName := file.Name() filePath := filepath.Join(invariantsDir, fileName) + // where invariants for a module have their own directory, interpret + // the test file with the same name as the directory as a 'main' of + // sorts, from where documentation is pulled + if file.IsDir() { + filePath = filepath.Join(filePath, strings.Join([]string{fileName, ".t.sol"}, "")) + } fileContents, err := os.ReadFile(filePath) if err != nil { return fmt.Errorf("error reading file %q: %w", filePath, err) diff --git a/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh b/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh index 2649c85a5016..b7a8db6b5912 100755 --- a/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh +++ b/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh @@ -63,6 +63,10 @@ for FILE in $CHANGED_FILES; do echo "skipping $FILE" continue fi + if [ ! -e "$FILE" ] ; then + echo "skipping $FILE since it was deleted" + continue + fi # Get the diff for the file. DIFF=$(git diff origin/develop...HEAD --unified=0 -- "$FILE") diff --git a/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20.t.sol b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20.t.sol deleted file mode 100644 index 673df66a4c20..000000000000 --- a/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20.t.sol +++ /dev/null @@ -1,227 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.25; - -// Testing utilities -import { Test, StdUtils, Vm } from "forge-std/Test.sol"; -import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; - -// Libraries -import { Predeploys } from "src/libraries/Predeploys.sol"; -import { OptimismSuperchainERC20 } from "src/L2/OptimismSuperchainERC20.sol"; -import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; - -/// @title OptimismSuperchainERC20_User -/// @notice Actor contract that interacts with the OptimismSuperchainERC20 contract. -contract OptimismSuperchainERC20_User is StdUtils { - address public immutable receiver; - - /// @notice Cross domain message data. - struct MessageData { - bytes32 id; - uint256 amount; - } - - uint256 public totalAmountSent; - uint256 public totalAmountRelayed; - - /// @notice Flag to indicate if the test has failed. - bool public failed = false; - - /// @notice The Vm contract. - Vm internal vm; - - /// @notice The OptimismSuperchainERC20 contract. - OptimismSuperchainERC20 internal superchainERC20; - - /// @notice Mapping of sent messages. - mapping(bytes32 => bool) internal sent; - - /// @notice Array of unrelayed messages. - MessageData[] internal unrelayed; - - /// @param _vm The Vm contract. - /// @param _superchainERC20 The OptimismSuperchainERC20 contract. - /// @param _balance The initial balance of the contract. - constructor(Vm _vm, OptimismSuperchainERC20 _superchainERC20, uint256 _balance, address _receiver) { - vm = _vm; - superchainERC20 = _superchainERC20; - - // Mint balance to this actor. - vm.prank(Predeploys.L2_STANDARD_BRIDGE); - superchainERC20.mint(address(this), _balance); - receiver = _receiver; - } - - /// @notice Send ERC20 tokens to another chain. - /// @param _amount The amount of ERC20 tokens to send. - /// @param _chainId The chain ID to send the tokens to. - /// @param _messageId The message ID. - function sendERC20(uint256 _amount, uint256 _chainId, bytes32 _messageId) public { - // Make sure we aren't reusing a message ID. - if (sent[_messageId]) { - return; - } - - if (_chainId == block.chainid) return; - - // Bound send amount to our ERC20 balance. - _amount = bound(_amount, 0, superchainERC20.balanceOf(address(this))); - - // Send the amount. - try superchainERC20.sendERC20(receiver, _amount, _chainId) { - // Success. - totalAmountSent += _amount; - } catch { - failed = true; - } - - // Mark message as sent. - sent[_messageId] = true; - unrelayed.push(MessageData({ id: _messageId, amount: _amount })); - } - - /// @notice Relay a message from another chain. - function relayMessage(uint256 _source) public { - // Make sure there are unrelayed messages. - if (unrelayed.length == 0) { - return; - } - - // Grab the latest unrelayed message. - MessageData memory message = unrelayed[unrelayed.length - 1]; - - // Simulate the cross-domain message. - // Make sure the cross-domain message sender is set to this contract. - vm.mockCall( - Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER, - abi.encodeCall(IL2ToL2CrossDomainMessenger.crossDomainMessageSender, ()), - abi.encode(address(superchainERC20)) - ); - - // Simulate the cross-domain message source to any chain. - vm.mockCall( - Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER, - abi.encodeCall(IL2ToL2CrossDomainMessenger.crossDomainMessageSource, ()), - abi.encode(_source) - ); - - // Prank the relayERC20 function. - // Balance will just go back to our own account. - vm.prank(Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER); - try superchainERC20.relayERC20(address(this), receiver, message.amount) { - // Success. - totalAmountRelayed += message.amount; - } catch { - failed = true; - } - - // Remove the message from the unrelayed list. - unrelayed.pop(); - } -} - -/// @title OptimismSuperchainERC20_Invariant -/// @notice Invariant test that checks that sending OptimismSuperchainERC20 always succeeds if the actor has a -/// sufficient balance to do so and that the actor's balance does not increase out of nowhere. -contract OptimismSuperchainERC20_Invariant is Test { - /// @notice Starting balance of the contract. - uint256 public constant STARTING_BALANCE = type(uint128).max; - - /// @notice The OptimismSuperchainERC20 contract implementation. - address internal optimismSuperchainERC20Impl; - - /// @notice The OptimismSuperchainERC20_User actor. - OptimismSuperchainERC20_User internal actor; - - /// @notice The OptimismSuperchainERC20 contract. - OptimismSuperchainERC20 internal optimismSuperchainERC20; - - /// @notice The address that will receive the tokens when relaying messages - address internal receiver = makeAddr("receiver"); - - /// @notice Test setup. - function setUp() public { - // Deploy the L2ToL2CrossDomainMessenger contract. - address _impl = _setImplementationCode(Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER); - _setProxyCode(Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER, _impl); - - // Create a new OptimismSuperchainERC20 implementation. - optimismSuperchainERC20Impl = address(new OptimismSuperchainERC20()); - - // Deploy the OptimismSuperchainERC20 contract. - address _proxy = address(0x123456); - _setProxyCode(_proxy, optimismSuperchainERC20Impl); - optimismSuperchainERC20 = OptimismSuperchainERC20(_proxy); - - // Create a new OptimismSuperchainERC20_User actor. - actor = new OptimismSuperchainERC20_User(vm, optimismSuperchainERC20, STARTING_BALANCE, receiver); - - // Set the target contract. - targetContract(address(actor)); - - // Set the target selectors. - bytes4[] memory selectors = new bytes4[](2); - selectors[0] = actor.sendERC20.selector; - selectors[1] = actor.relayMessage.selector; - FuzzSelector memory selector = FuzzSelector({ addr: address(actor), selectors: selectors }); - targetSelector(selector); - - // Setup assertions - assert(optimismSuperchainERC20.balanceOf(address(actor)) == STARTING_BALANCE); - assert(optimismSuperchainERC20.balanceOf(address(receiver)) == 0); - assert(optimismSuperchainERC20.totalSupply() == STARTING_BALANCE); - } - - /// @notice Sets the bytecode in the implementation address. - function _setImplementationCode(address _addr) internal returns (address) { - string memory cname = Predeploys.getName(_addr); - address impl = Predeploys.predeployToCodeNamespace(_addr); - vm.etch(impl, vm.getDeployedCode(string.concat(cname, ".sol:", cname))); - return impl; - } - - /// @notice Sets the bytecode in the proxy address. - function _setProxyCode(address _addr, address _impl) internal { - bytes memory code = vm.getDeployedCode("universal/Proxy.sol:Proxy"); - vm.etch(_addr, code); - EIP1967Helper.setAdmin(_addr, Predeploys.PROXY_ADMIN); - EIP1967Helper.setImplementation(_addr, _impl); - } - - /// @notice Invariant that checks that sending OptimismSuperchainERC20 always succeeds. - /// @custom:invariant Calls to sendERC20 should always succeed as long as the actor has enough balance. - /// Actor's balance should also not increase out of nowhere but instead should decrease by the - /// amount sent. - function invariant_sendERC20_succeeds() public view { - // Assert that the actor has not failed to send OptimismSuperchainERC20. - assertTrue(!actor.failed()); - - // Assert that the actor has sent more than or equal to the amount relayed. - assertTrue(actor.totalAmountSent() >= actor.totalAmountRelayed()); - - // Assert that the actor's balance has decreased by the amount sent. - assertEq(optimismSuperchainERC20.balanceOf(address(actor)), STARTING_BALANCE - actor.totalAmountSent()); - - // Assert that the total supply of the OptimismSuperchainERC20 contract has decreased by the amount unrelayed. - uint256 _unrelayedAmount = actor.totalAmountSent() - actor.totalAmountRelayed(); - assertEq(optimismSuperchainERC20.totalSupply(), STARTING_BALANCE - _unrelayedAmount); - } - - /// @notice Invariant that checks that relaying OptimismSuperchainERC20 always succeeds. - /// @custom:invariant Calls to relayERC20 should always succeeds when a message is received from another chain. - /// Actor's balance should only increase by the amount relayed. - function invariant_relayERC20_succeeds() public view { - // Assert that the actor has not failed to relay OptimismSuperchainERC20. - assertTrue(!actor.failed()); - - // Assert that the actor has sent more than or equal to the amount relayed. - assertTrue(actor.totalAmountSent() >= actor.totalAmountRelayed()); - - // Assert that the actor's balance has increased by the amount relayed. - assertEq(optimismSuperchainERC20.balanceOf(address(receiver)), actor.totalAmountRelayed()); - - // Assert that the total supply of the OptimismSuperchainERC20 contract has decreased by the amount unrelayed. - uint256 _unrelayedAmount = actor.totalAmountSent() - actor.totalAmountRelayed(); - assertEq(optimismSuperchainERC20.totalSupply(), STARTING_BALANCE - _unrelayedAmount); - } -} diff --git a/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/OptimismSuperchainERC20.t.sol b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/OptimismSuperchainERC20.t.sol new file mode 100644 index 000000000000..d90e90a2f811 --- /dev/null +++ b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/OptimismSuperchainERC20.t.sol @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +// Testing utilities +import { Test, StdUtils, Vm } from "forge-std/Test.sol"; +import { StdInvariant } from "forge-std/StdInvariant.sol"; +import { StdAssertions } from "forge-std/StdAssertions.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; + +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { OptimismSuperchainERC20 } from "src/L2/OptimismSuperchainERC20.sol"; +import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; +import { ProtocolGuided } from "./fuzz/Protocol.guided.t.sol"; +import { ProtocolUnguided } from "./fuzz/Protocol.unguided.t.sol"; +import { HandlerGetters } from "./helpers/HandlerGetters.t.sol"; +import { MockL2ToL2CrossDomainMessenger } from "./helpers/MockL2ToL2CrossDomainMessenger.t.sol"; + +contract OptimismSuperchainERC20Handler is HandlerGetters, ProtocolGuided, ProtocolUnguided { } + +contract OptimismSuperchainERC20Properties is Test { + OptimismSuperchainERC20Handler internal handler; + MockL2ToL2CrossDomainMessenger internal constant MESSENGER = + MockL2ToL2CrossDomainMessenger(Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER); + + function setUp() public { + handler = new OptimismSuperchainERC20Handler(); + targetContract(address(handler)); + } + + // TODO: will need rework after + // - `convert` + /// @custom:invariant sum of supertoken total supply across all chains is always <= to convert(legacy, super)- + /// convert(super, legacy) + function invariant_totalSupplyAcrossChainsEqualsMintsMinusFundsInTransit() external view { + // iterate over unique deploy salts aka supertokens that are supposed to be compatible with each other + for (uint256 deploySaltIndex = 0; deploySaltIndex < handler.deploySaltsLength(); deploySaltIndex++) { + uint256 totalSupply = 0; + (bytes32 currentSalt, uint256 trackedSupply) = handler.totalSupplyAcrossChainsAtIndex(deploySaltIndex); + uint256 fundsInTransit = handler.tokensInTransitForDeploySalt(currentSalt); + // and then over all the (mocked) chain ids where that supertoken could be deployed + for (uint256 validChainId = 0; validChainId < handler.MAX_CHAINS(); validChainId++) { + address supertoken = MESSENGER.superTokenAddresses(validChainId, currentSalt); + if (supertoken != address(0)) { + totalSupply += OptimismSuperchainERC20(supertoken).totalSupply(); + } + } + assertEq(trackedSupply, totalSupply + fundsInTransit); + } + } + + // TODO: will need rework after + // - `convert` + /// @custom:invariant sum of supertoken total supply across all chains is equal to convert(legacy, super)- + /// convert(super, legacy) when all when all cross-chain messages are processed + function invariant_totalSupplyAcrossChainsEqualsMintsWhenQueueIsEmpty() external view { + if (MESSENGER.messageQueueLength() != 0) { + return; + } + // iterate over unique deploy salts aka supertokens that are supposed to be compatible with each other + for (uint256 deploySaltIndex = 0; deploySaltIndex < handler.deploySaltsLength(); deploySaltIndex++) { + uint256 totalSupply = 0; + (bytes32 currentSalt, uint256 trackedSupply) = handler.totalSupplyAcrossChainsAtIndex(deploySaltIndex); + // and then over all the (mocked) chain ids where that supertoken could be deployed + for (uint256 validChainId = 0; validChainId < handler.MAX_CHAINS(); validChainId++) { + address supertoken = MESSENGER.superTokenAddresses(validChainId, currentSalt); + if (supertoken != address(0)) { + totalSupply += OptimismSuperchainERC20(supertoken).totalSupply(); + } + } + assertEq(trackedSupply, totalSupply); + } + } + + /// @custom:invariant many other assertion mode invariants are also defined under + /// `test/invariants/OptimismSuperchainERC20/fuzz/` . + /// + /// since setting`fail_on_revert=false` also ignores StdAssertion failures, this invariant explicitly asks the + /// handler for assertion test failures + function invariant_handlerAssertions() external view { + assertFalse(handler.failed()); + } +} diff --git a/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/PROPERTIES.md b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/PROPERTIES.md new file mode 100644 index 000000000000..18970855ca46 --- /dev/null +++ b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/PROPERTIES.md @@ -0,0 +1,82 @@ +# Supertoken advanced testing + +## Milestones + +The supertoken ecosystem consists of not just the supertoken contract, but the required changes to other contracts for liquidity to reach the former. + +Considering only the supertoken contract is merged into the `develop` branch, and work for the other components is still in progress, we define three milestones for the testing campaign: + +- SupERC20: concerned with only the supertoken contract, the first one to be implemented +- Factories: covers the above + the development of `OptimismSuperchainERC20Factory` and required changes to `OptimismMintableERC20Factory` +- Liquidity Migration: includes the `convert` function on the `L2StandardBridgeInterop` to migrate liquidity from legacy tokens into supertokens + +## Definitions + +- *legacy token:* an OptimismMintableERC20 or L2StandardERC20 token on the suprechain that has either been deployed by the factory after the liquidity migration upgrade to the latter, or has been deployed before it **but** added to factory’s `deployments` mapping as part of the upgrade. This testing campaign is not concerned with tokens on L1 or not listed in the factory’s `deployments` mapping. +- *supertoken:* a SuperchainERC20 contract deployed by the `OptimismSuperchainERC20Factory` + +# Ecosystem properties + +legend: + +- `[ ]`: property not yet tested +- `**[ ]**`: property not yet tested, dev/research team has asked for extra focus on it +- `[X]`: tested/proven property +- `[~]`: partially tested/proven property +- `:(`: property won't be tested due to some limitation + +## Unit test + +| id | milestone | description | tested | +| --- | --- | --- | --- | +| 0 | Factories | supertoken token address does not depend on the executing chain’s chainID | [ ] | +| 1 | Factories | supertoken token address depends on remote token, name, symbol and decimals | [ ] | +| 2 | Liquidity Migration | convert() should only allow converting legacy tokens to supertoken and viceversa | [ ] | +| 3 | Liquidity Migration | convert() only allows migrations between tokens representing the same remote asset | [ ] | +| 4 | Liquidity Migration | convert() only allows migrations from tokens with the same decimals | [ ] | +| 5 | Liquidity Migration | convert() burns the same amount of legacy token that it mints of supertoken, and viceversa | [ ] | +| 25 | SupERC20 | supertokens can't be reinitialized | [x] | + +## Valid state + +| id | milestone | description | tested | +| --- | --- | --- | --- | +| 6 | SupERC20 | calls to sendERC20 succeed as long as caller has enough balance | [x] | +| 7 | SupERC20 | calls to relayERC20 always succeed as long as the cross-domain caller is valid | [~] | + +## Variable transition + +| id | milestone | description | tested | +| --- | --- | --- | --- | +| 8 | SupERC20 | sendERC20 with a value of zero does not modify accounting | [x] | +| 9 | SupERC20 | relayERC20 with a value of zero does not modify accounting | [x] | +| 10 | SupERC20 | sendERC20 decreases the token's totalSupply in the source chain exactly by the input amount | [x] | +| 26 | SupERC20 | sendERC20 decreases the sender's balance in the source chain exactly by the input amount | [x] | +| 27 | SupERC20 | relayERC20 increases sender's balance in the destination chain exactly by the input amount | [x] | +| 11 | SupERC20 | relayERC20 increases the token's totalSupply in the destination chain exactly by the input amount | [ ] | +| 12 | Liquidity Migration | supertoken total supply only increases on calls to mint() by the L2toL2StandardBridge | [~] | +| 13 | Liquidity Migration | supertoken total supply only decreases on calls to burn() by the L2toL2StandardBridge | [ ] | +| 14 | SupERC20 | supertoken total supply starts at zero | [x] | +| 15 | Factories | deploying a supertoken registers its remote token in the factory | [ ] | +| 16 | Factories | deploying an OptimismMintableERC20 registers its remote token in the factory | [ ] | + +## High level + +| id | milestone | description | tested | +| --- | --- | --- | --- | +| 17 | Liquidity Migration | only calls to convert(legacy, super) can increase a supertoken’s total supply across chains | [ ] | +| 18 | Liquidity Migration | only calls to convert(super, legacy) can decrease a supertoken’s total supply across chains | [ ] | +| 19 | Liquidity Migration | sum of supertoken total supply across all chains is always <= to convert(legacy, super)- convert(super, legacy) | [~] | +| 20 | SupERC20 | tokens sendERC20-ed on a source chain to a destination chain can be relayERC20-ed on it as long as the source chain is in the dependency set of the destination chain | [ ] | +| 21 | Liquidity Migration | sum of supertoken total supply across all chains is = to convert(legacy, super)- convert(super, legacy) when all cross-chain messages are processed | [~] | + +## Atomic bridging pseudo-properties + +As another layer of defense, the following properties are defined which assume bridging operations to be atomic (that is, the sequencer and L2Inbox and CrossDomainMessenger contracts are fully abstracted away, `sendERC20` triggering the `relayERC20` call on the same transaction) +It’s worth noting that these properties will not hold for a live system + +| id | milestone | description | tested | +| --- | --- | --- | --- | +| 22 | SupERC20 | sendERC20 decreases sender balance in source chain and increases receiver balance in destination chain exactly by the input amount | [x] | +| 23 | SupERC20 | sendERC20 decreases total supply in source chain and increases it in destination chain exactly by the input amount | [x] | +| 24 | Liquidity Migration | sum of supertoken total supply across all chains is always equal to convert(legacy, super)- convert(super, legacy) | [~] | diff --git a/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/fuzz/Protocol.guided.t.sol b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/fuzz/Protocol.guided.t.sol new file mode 100644 index 000000000000..536a4ea7025a --- /dev/null +++ b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/fuzz/Protocol.guided.t.sol @@ -0,0 +1,211 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +import { MockL2ToL2CrossDomainMessenger } from "../helpers/MockL2ToL2CrossDomainMessenger.t.sol"; +import { OptimismSuperchainERC20 } from "src/L2/OptimismSuperchainERC20.sol"; +import { ProtocolHandler } from "../handlers/Protocol.t.sol"; +import { EnumerableMap } from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; +import { CompatibleAssert } from "../helpers/CompatibleAssert.t.sol"; + +contract ProtocolGuided is ProtocolHandler, CompatibleAssert { + using EnumerableMap for EnumerableMap.Bytes32ToUintMap; + /// @notice deploy a new supertoken with deploy salt determined by params, to the given (of course mocked) chainId + /// @custom:property-id 14 + /// @custom:property supertoken total supply starts at zero + + function fuzz_deployNewSupertoken( + TokenDeployParams memory params, + uint256 chainId + ) + external + validateTokenDeployParams(params) + { + chainId = bound(chainId, 0, MAX_CHAINS - 1); + OptimismSuperchainERC20 supertoken = _deploySupertoken( + remoteTokens[params.remoteTokenIndex], + WORDS[params.nameIndex], + WORDS[params.symbolIndex], + DECIMALS[params.decimalsIndex], + chainId + ); + // 14 + compatibleAssert(supertoken.totalSupply() == 0); + } + + /// @custom:property-id 6 + /// @custom:property calls to sendERC20 succeed as long as caller has enough balance + /// @custom:property-id 22 + /// @custom:property sendERC20 decreases sender balance in source chain and increases receiver balance in + /// destination chain exactly by the input amount + /// @custom:property-id 23 + /// @custom:property sendERC20 decreases total supply in source chain and increases it in destination chain exactly + /// by the input amount + function fuzz_bridgeSupertokenAtomic( + uint256 fromIndex, + uint256 recipientIndex, + uint256 destinationChainId, + uint256 amount + ) + public + withActor(msg.sender) + { + destinationChainId = bound(destinationChainId, 0, MAX_CHAINS - 1); + fromIndex = bound(fromIndex, 0, allSuperTokens.length - 1); + address recipient = getActorByRawIndex(recipientIndex); + OptimismSuperchainERC20 sourceToken = OptimismSuperchainERC20(allSuperTokens[fromIndex]); + OptimismSuperchainERC20 destinationToken = + MESSENGER.crossChainMessageReceiver(address(sourceToken), destinationChainId); + uint256 sourceBalanceBefore = sourceToken.balanceOf(currentActor()); + uint256 sourceSupplyBefore = sourceToken.totalSupply(); + uint256 destinationBalanceBefore = destinationToken.balanceOf(recipient); + uint256 destinationSupplyBefore = destinationToken.totalSupply(); + + MESSENGER.setAtomic(true); + vm.prank(currentActor()); + try sourceToken.sendERC20(recipient, amount, destinationChainId) { + MESSENGER.setAtomic(false); + uint256 sourceBalanceAfter = sourceToken.balanceOf(currentActor()); + uint256 destinationBalanceAfter = destinationToken.balanceOf(recipient); + // no free mint + compatibleAssert( + sourceBalanceBefore + destinationBalanceBefore == sourceBalanceAfter + destinationBalanceAfter + ); + // 22 + compatibleAssert(sourceBalanceBefore - amount == sourceBalanceAfter); + compatibleAssert(destinationBalanceBefore + amount == destinationBalanceAfter); + uint256 sourceSupplyAfter = sourceToken.totalSupply(); + uint256 destinationSupplyAfter = destinationToken.totalSupply(); + // 23 + compatibleAssert(sourceSupplyBefore - amount == sourceSupplyAfter); + compatibleAssert(destinationSupplyBefore + amount == destinationSupplyAfter); + } catch { + MESSENGER.setAtomic(false); + // 6 + compatibleAssert(address(destinationToken) == address(sourceToken) || sourceBalanceBefore < amount); + } + } + + /// @custom:property-id 6 + /// @custom:property calls to sendERC20 succeed as long as caller has enough balance + /// @custom:property-id 26 + /// @custom:property sendERC20 decreases sender balance in source chain exactly by the input amount + /// @custom:property-id 10 + /// @custom:property sendERC20 decreases total supply in source chain exactly by the input amount + function fuzz_sendERC20( + uint256 fromIndex, + uint256 recipientIndex, + uint256 destinationChainId, + uint256 amount + ) + public + withActor(msg.sender) + { + destinationChainId = bound(destinationChainId, 0, MAX_CHAINS - 1); + fromIndex = bound(fromIndex, 0, allSuperTokens.length - 1); + address recipient = getActorByRawIndex(recipientIndex); + OptimismSuperchainERC20 sourceToken = OptimismSuperchainERC20(allSuperTokens[fromIndex]); + OptimismSuperchainERC20 destinationToken = + MESSENGER.crossChainMessageReceiver(address(sourceToken), destinationChainId); + bytes32 deploySalt = MESSENGER.superTokenInitDeploySalts(address(sourceToken)); + uint256 sourceBalanceBefore = sourceToken.balanceOf(currentActor()); + uint256 sourceSupplyBefore = sourceToken.totalSupply(); + + vm.prank(currentActor()); + try sourceToken.sendERC20(recipient, amount, destinationChainId) { + (, uint256 currentlyInTransit) = ghost_tokensInTransit.tryGet(deploySalt); + ghost_tokensInTransit.set(deploySalt, currentlyInTransit + amount); + // 26 + uint256 sourceBalanceAfter = sourceToken.balanceOf(currentActor()); + compatibleAssert(sourceBalanceBefore - amount == sourceBalanceAfter); + // 10 + uint256 sourceSupplyAfter = sourceToken.totalSupply(); + compatibleAssert(sourceSupplyBefore - amount == sourceSupplyAfter); + } catch { + // 6 + compatibleAssert(address(destinationToken) == address(sourceToken) || sourceBalanceBefore < amount); + } + } + + /// @custom:property-id 11 + /// @custom:property relayERC20 increases the token's totalSupply in the destination chain exactly by the input + /// amount + /// @custom:property-id 27 + /// @custom:property relayERC20 increases sender's balance in the destination chain exactly by the input amount + /// @custom:property-id 7 + /// @custom:property calls to relayERC20 always succeed as long as the cross-domain caller is valid + function fuzz_relayERC20(uint256 messageIndex) external { + MockL2ToL2CrossDomainMessenger.CrossChainMessage memory messageToRelay = MESSENGER.messageQueue(messageIndex); + OptimismSuperchainERC20 destinationToken = OptimismSuperchainERC20(messageToRelay.crossDomainMessageSender); + uint256 destinationSupplyBefore = destinationToken.totalSupply(); + uint256 destinationBalanceBefore = destinationToken.balanceOf(messageToRelay.recipient); + + try MESSENGER.relayMessageFromQueue(messageIndex) { + bytes32 deploySalt = MESSENGER.superTokenInitDeploySalts(address(destinationToken)); + (bool success, uint256 currentlyInTransit) = ghost_tokensInTransit.tryGet(deploySalt); + // if sendERC20 didnt intialize this, then test suite is broken + compatibleAssert(success); + ghost_tokensInTransit.set(deploySalt, currentlyInTransit - messageToRelay.amount); + // 11 + compatibleAssert(destinationSupplyBefore + messageToRelay.amount == destinationToken.totalSupply()); + // 27 + compatibleAssert( + destinationBalanceBefore + messageToRelay.amount == destinationToken.balanceOf(messageToRelay.recipient) + ); + } catch { + // 7 + compatibleAssert(false); + } + } + + /// @custom:property-id 8 + /// @custom:property calls to sendERC20 with a value of zero dont modify accounting + // @notice is a subset of fuzz_sendERC20, so we'll just call it + // instead of re-implementing it. Keeping the function for visibility of the property. + function fuzz_sendZeroDoesNotModifyAccounting( + uint256 fromIndex, + uint256 recipientIndex, + uint256 destinationChainId + ) + external + { + fuzz_sendERC20(fromIndex, recipientIndex, destinationChainId, 0); + } + + /// @custom:property-id 9 + /// @custom:property calls to relayERC20 with a value of zero dont modify accounting + /// @custom:property-id 7 + /// @custom:property calls to relayERC20 always succeed as long as the cross-domain caller is valid + /// @notice cant call fuzz_RelayERC20 internally since that pops a + /// random message, which we cannot guarantee has a value of zero + function fuzz_relayZeroDoesNotModifyAccounting( + uint256 fromIndex, + uint256 recipientIndex + ) + external + withActor(msg.sender) + { + fromIndex = bound(fromIndex, 0, allSuperTokens.length - 1); + address recipient = getActorByRawIndex(recipientIndex); + OptimismSuperchainERC20 token = OptimismSuperchainERC20(allSuperTokens[fromIndex]); + uint256 balanceSenderBefore = token.balanceOf(currentActor()); + uint256 balanceRecipientBefore = token.balanceOf(recipient); + uint256 supplyBefore = token.totalSupply(); + + MESSENGER.setCrossDomainMessageSender(address(token)); + vm.prank(address(MESSENGER)); + try token.relayERC20(currentActor(), recipient, 0) { + MESSENGER.setCrossDomainMessageSender(address(0)); + } catch { + // should not revert because of 7, and if it *does* revert, I want the test suite + // to discard the sequence instead of potentially getting another + // error due to the crossDomainMessageSender being manually set + compatibleAssert(false); + } + uint256 balanceSenderAfter = token.balanceOf(currentActor()); + uint256 balanceRecipeintAfter = token.balanceOf(recipient); + uint256 supplyAfter = token.totalSupply(); + compatibleAssert(balanceSenderBefore == balanceSenderAfter); + compatibleAssert(balanceRecipientBefore == balanceRecipeintAfter); + compatibleAssert(supplyBefore == supplyAfter); + } +} diff --git a/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/fuzz/Protocol.unguided.t.sol b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/fuzz/Protocol.unguided.t.sol new file mode 100644 index 000000000000..90cad38baa99 --- /dev/null +++ b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/fuzz/Protocol.unguided.t.sol @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +import { ProtocolHandler } from "../handlers/Protocol.t.sol"; +import { EnumerableMap } from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; +import { OptimismSuperchainERC20 } from "src/L2/OptimismSuperchainERC20.sol"; +import { CompatibleAssert } from "../helpers/CompatibleAssert.t.sol"; + +// TODO: add fuzz_sendERC20 when we implement non-atomic bridging +contract ProtocolUnguided is ProtocolHandler, CompatibleAssert { + using EnumerableMap for EnumerableMap.Bytes32ToUintMap; + + /// @custom:property-id 7 + /// @custom:property calls to relayERC20 always succeed as long as the cross-domain caller is valid + /// @notice this ensures actors cant simply call relayERC20 and get tokens, no matter the system state + /// but there's still some possible work on how hard we can bork the system state with handlers calling + /// the L2ToL2CrossDomainMessenger or bridge directly (pending on non-atomic bridging) + function fuzz_relayERC20( + uint256 tokenIndex, + address sender, + address crossDomainMessageSender, + address recipient, + uint256 amount + ) + external + { + MESSENGER.setCrossDomainMessageSender(crossDomainMessageSender); + address token = allSuperTokens[bound(tokenIndex, 0, allSuperTokens.length)]; + vm.prank(sender); + try OptimismSuperchainERC20(token).relayERC20(sender, recipient, amount) { + MESSENGER.setCrossDomainMessageSender(address(0)); + compatibleAssert(sender == address(MESSENGER)); + compatibleAssert(crossDomainMessageSender == token); + // this increases the supply across chains without a call to + // `mint` by the MESSENGER, so it kind of breaks an invariant, but + // let's walk around that: + bytes32 salt = MESSENGER.superTokenInitDeploySalts(token); + (, uint256 currentValue) = ghost_totalSupplyAcrossChains.tryGet(salt); + ghost_totalSupplyAcrossChains.set(salt, currentValue + amount); + } catch { + compatibleAssert(sender != address(MESSENGER) || crossDomainMessageSender != token); + MESSENGER.setCrossDomainMessageSender(address(0)); + } + } + + /// @custom:property-id 6 + /// @custom:property calls to sendERC20 succeed as long as caller has enough balance + /// @custom:property-id 26 + /// @custom:property sendERC20 decreases sender balance in source chain exactly by the input amount + /// @custom:property-id 10 + /// @custom:property sendERC20 decreases total supply in source chain exactly by the input amount + function fuzz_sendERC20( + address sender, + address recipient, + uint256 fromIndex, + uint256 destinationChainId, + uint256 amount + ) + public + { + destinationChainId = bound(destinationChainId, 0, MAX_CHAINS - 1); + OptimismSuperchainERC20 sourceToken = OptimismSuperchainERC20(allSuperTokens[fromIndex]); + OptimismSuperchainERC20 destinationToken = + MESSENGER.crossChainMessageReceiver(address(sourceToken), destinationChainId); + bytes32 deploySalt = MESSENGER.superTokenInitDeploySalts(address(sourceToken)); + uint256 sourceBalanceBefore = sourceToken.balanceOf(sender); + uint256 sourceSupplyBefore = sourceToken.totalSupply(); + + vm.prank(sender); + try sourceToken.sendERC20(recipient, amount, destinationChainId) { + (, uint256 currentlyInTransit) = ghost_tokensInTransit.tryGet(deploySalt); + ghost_tokensInTransit.set(deploySalt, currentlyInTransit + amount); + // 26 + uint256 sourceBalanceAfter = sourceToken.balanceOf(sender); + compatibleAssert(sourceBalanceBefore - amount == sourceBalanceAfter); + // 10 + uint256 sourceSupplyAfter = sourceToken.totalSupply(); + compatibleAssert(sourceSupplyBefore - amount == sourceSupplyAfter); + } catch { + // 6 + compatibleAssert(address(destinationToken) == address(sourceToken) || sourceBalanceBefore < amount); + } + } + + /// @custom:property-id 12 + /// @custom:property supertoken total supply only increases on calls to mint() by the L2toL2StandardBridge + function fuzz_mint(uint256 tokenIndex, address to, address sender, uint256 amount) external { + address token = allSuperTokens[bound(tokenIndex, 0, allSuperTokens.length)]; + bytes32 salt = MESSENGER.superTokenInitDeploySalts(token); + amount = bound(amount, 0, type(uint256).max - OptimismSuperchainERC20(token).totalSupply()); + vm.prank(sender); + try OptimismSuperchainERC20(token).mint(to, amount) { + compatibleAssert(sender == BRIDGE); + (, uint256 currentValue) = ghost_totalSupplyAcrossChains.tryGet(salt); + ghost_totalSupplyAcrossChains.set(salt, currentValue + amount); + } catch { + compatibleAssert(sender != BRIDGE || to == address(0)); + } + } + + /// @custom:property-id 13 + /// @custom:property supertoken total supply only increases on calls to mint() by the L2toL2StandardBridge + function fuzz_burn(uint256 tokenIndex, address from, address sender, uint256 amount) external { + address token = allSuperTokens[bound(tokenIndex, 0, allSuperTokens.length)]; + bytes32 salt = MESSENGER.superTokenInitDeploySalts(token); + uint256 senderBalance = OptimismSuperchainERC20(token).balanceOf(sender); + vm.prank(sender); + try OptimismSuperchainERC20(token).burn(from, amount) { + compatibleAssert(sender == BRIDGE); + (, uint256 currentValue) = ghost_totalSupplyAcrossChains.tryGet(salt); + ghost_totalSupplyAcrossChains.set(salt, currentValue - amount); + } catch { + compatibleAssert(sender != BRIDGE || senderBalance < amount); + } + } + + /// @custom:property-id 25 + /// @custom:property supertokens can't be reinitialized + function fuzz_initialize( + address sender, + uint256 tokenIndex, + address remoteToken, + string memory name, + string memory symbol, + uint8 decimals + ) + external + { + vm.prank(sender); + // revert is possible in bound, but is not part of the external call + try OptimismSuperchainERC20(allSuperTokens[bound(tokenIndex, 0, allSuperTokens.length)]).initialize( + remoteToken, name, symbol, decimals + ) { + compatibleAssert(false); + } catch { } + } +} diff --git a/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/handlers/Protocol.t.sol b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/handlers/Protocol.t.sol new file mode 100644 index 000000000000..921495b467ab --- /dev/null +++ b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/handlers/Protocol.t.sol @@ -0,0 +1,177 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +import { TestBase } from "forge-std/Base.sol"; +import { StdUtils } from "forge-std/StdUtils.sol"; + +import { ERC1967Proxy } from "@openzeppelin/contracts-v5/proxy/ERC1967/ERC1967Proxy.sol"; +import { EnumerableMap } from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; +import { OptimismSuperchainERC20 } from "src/L2/OptimismSuperchainERC20.sol"; +import { OptimismSuperchainERC20ForToBProperties } from "../helpers/OptimismSuperchainERC20ForToBProperties.t.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { MockL2ToL2CrossDomainMessenger } from "../helpers/MockL2ToL2CrossDomainMessenger.t.sol"; +import { Actors } from "../helpers/Actors.t.sol"; + +contract ProtocolHandler is TestBase, StdUtils, Actors { + using EnumerableMap for EnumerableMap.Bytes32ToUintMap; + + uint8 public constant MAX_CHAINS = 4; + uint8 internal constant INITIAL_TOKENS = 1; + uint8 internal constant INITIAL_SUPERTOKENS = 1; + uint8 internal constant SUPERTOKEN_INITIAL_MINT = 100; + address internal constant BRIDGE = Predeploys.L2_STANDARD_BRIDGE; + MockL2ToL2CrossDomainMessenger internal constant MESSENGER = + MockL2ToL2CrossDomainMessenger(Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER); + OptimismSuperchainERC20 internal superchainERC20Impl; + // NOTE: having more options for this enables the fuzzer to configure + // different supertokens for the same remote token + string[] internal WORDS = ["TOKENS"]; + uint8[] internal DECIMALS = [6, 18]; + + struct TokenDeployParams { + uint8 remoteTokenIndex; + uint8 nameIndex; + uint8 symbolIndex; + uint8 decimalsIndex; + } + + address[] internal remoteTokens; + address[] internal allSuperTokens; + + /// @notice 'real' deploy salt => total supply sum across chains + EnumerableMap.Bytes32ToUintMap internal ghost_totalSupplyAcrossChains; + /// @notice 'real' deploy salt => tokens sendERC20'd but not yet relayERC20'd + EnumerableMap.Bytes32ToUintMap internal ghost_tokensInTransit; + + constructor() { + vm.etch(address(MESSENGER), address(new MockL2ToL2CrossDomainMessenger()).code); + superchainERC20Impl = new OptimismSuperchainERC20ForToBProperties(); + for (uint256 remoteTokenIndex; remoteTokenIndex < INITIAL_TOKENS; remoteTokenIndex++) { + _deployRemoteToken(); + for (uint256 supertokenChainId; supertokenChainId < INITIAL_SUPERTOKENS; supertokenChainId++) { + _deploySupertoken(remoteTokens[remoteTokenIndex], WORDS[0], WORDS[0], DECIMALS[0], supertokenChainId); + } + } + // integrate with all ToB properties using address(this) as the sender + addActor(address(this)); + } + + /// @notice the deploy params are _indexes_ to pick from a pre-defined array of options and limit + /// the amount of supertokens for a given remoteAsset that are incompatible between them, as + /// two supertokens have to share decimals, name, symbol and remoteAsset to be considered + /// the same asset, and therefore bridgable. + modifier validateTokenDeployParams(TokenDeployParams memory params) { + params.remoteTokenIndex = uint8(bound(params.remoteTokenIndex, 0, remoteTokens.length - 1)); + params.nameIndex = uint8(bound(params.nameIndex, 0, WORDS.length - 1)); + params.symbolIndex = uint8(bound(params.symbolIndex, 0, WORDS.length - 1)); + params.decimalsIndex = uint8(bound(params.decimalsIndex, 0, DECIMALS.length - 1)); + _; + } + + function handler_mockNewRemoteToken() external { + _deployRemoteToken(); + } + + /// @notice pick one already-deployed supertoken and mint an arbitrary amount of it + /// necessary so there is something to be bridged :D + /// TODO: will be replaced when testing the factories and `convert()` + function handler_mintSupertoken(uint256 index, uint96 amount) external withActor(msg.sender) { + index = bound(index, 0, allSuperTokens.length - 1); + address addr = allSuperTokens[index]; + vm.prank(BRIDGE); + OptimismSuperchainERC20(addr).mint(currentActor(), amount); + // currentValue will be zero if key is not present + (, uint256 currentValue) = ghost_totalSupplyAcrossChains.tryGet(MESSENGER.superTokenInitDeploySalts(addr)); + ghost_totalSupplyAcrossChains.set(MESSENGER.superTokenInitDeploySalts(addr), currentValue + amount); + } + + /// @notice The ToB properties don't preclude the need for this since they + /// always use address(this) as the caller, which won't get any balance + /// until it's transferred to it somehow + function handler_supERC20Transfer( + uint256 tokenIndex, + uint256 toIndex, + uint256 amount + ) + external + withActor(msg.sender) + { + vm.prank(currentActor()); + OptimismSuperchainERC20(allSuperTokens[bound(tokenIndex, 0, allSuperTokens.length)]).transfer( + getActorByRawIndex(toIndex), amount + ); + } + + function handler_supERC20TransferFrom( + uint256 tokenIndex, + uint256 fromIndex, + uint256 toIndex, + uint256 amount + ) + external + withActor(msg.sender) + { + vm.prank(currentActor()); + OptimismSuperchainERC20(allSuperTokens[bound(tokenIndex, 0, allSuperTokens.length)]).transferFrom( + getActorByRawIndex(fromIndex), getActorByRawIndex(toIndex), amount + ); + } + + function handler_supERC20Approve( + uint256 tokenIndex, + uint256 spenderIndex, + uint256 amount + ) + external + withActor(msg.sender) + { + vm.prank(currentActor()); + OptimismSuperchainERC20(allSuperTokens[bound(tokenIndex, 0, allSuperTokens.length)]).approve( + getActorByRawIndex(spenderIndex), amount + ); + } + + /// @notice deploy a remote token, that supertokens will be a representation of. They are never called, so there + /// is no need to actually deploy a contract for them + function _deployRemoteToken() internal { + // make sure they don't conflict with predeploys/preinstalls/precompiles/other tokens + remoteTokens.push(address(uint160(1000 + remoteTokens.length))); + } + + /// @notice deploy a new supertoken representing remoteToken + /// remoteToken, name, symbol and decimals determine the 'real' deploy salt + /// and supertokens sharing it are interoperable between them + /// we however use the chainId as part of the deploy salt to mock the ability of + /// supertokens to exist on different chains on a single EVM. + function _deploySupertoken( + address remoteToken, + string memory name, + string memory symbol, + uint8 decimals, + uint256 chainId + ) + internal + returns (OptimismSuperchainERC20 supertoken) + { + // this salt would be used in production. Tokens sharing it will be bridgable with each other + bytes32 realSalt = keccak256(abi.encode(remoteToken, name, symbol, decimals)); + // Foundry invariant erroneously show other unrelated invariant breaking + // when this deployment fails due to a create2 collision, so we revert eagerly instead + require(MESSENGER.superTokenAddresses(chainId, realSalt) == address(0), "skip duplicate deployment"); + + // what we use in the tests to walk around two contracts needing two different addresses + // tbf we could be using CREATE1, but this feels more verbose + bytes32 hackySalt = keccak256(abi.encode(remoteToken, name, symbol, decimals, chainId)); + supertoken = OptimismSuperchainERC20( + address( + // TODO: Use the SuperchainERC20 Beacon Proxy + new ERC1967Proxy{ salt: hackySalt }( + address(superchainERC20Impl), + abi.encodeCall(OptimismSuperchainERC20.initialize, (remoteToken, name, symbol, decimals)) + ) + ) + ); + MESSENGER.registerSupertoken(realSalt, chainId, address(supertoken)); + allSuperTokens.push(address(supertoken)); + } +} diff --git a/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/helpers/Actors.t.sol b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/helpers/Actors.t.sol new file mode 100644 index 000000000000..3a7400667518 --- /dev/null +++ b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/helpers/Actors.t.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +import { StdUtils } from "forge-std/StdUtils.sol"; + +/// @notice helper for tracking actors, taking advantage of the fuzzer already using several `msg.sender`s +contract Actors is StdUtils { + mapping(address => bool) private _isActor; + address[] private _actors; + address private _currentActor; + + /// @notice register an actor if it's not already registered + /// usually called with msg.sender as a parameter, to track the actors + /// already provided by the fuzzer + modifier withActor(address who) { + addActor(who); + _currentActor = who; + _; + } + + function addActor(address who) internal { + if (!_isActor[who]) { + _isActor[who] = true; + _actors.push(who); + } + } + + /// @notice get the currently configured actor, should equal msg.sender + function currentActor() internal view returns (address) { + return _currentActor; + } + + /// @notice get one of the actors by index, useful to get another random + /// actor than the one set as currentActor, to perform operations between them + function getActorByRawIndex(uint256 rawIndex) internal view returns (address) { + return _actors[bound(rawIndex, 0, _actors.length - 1)]; + } +} diff --git a/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/helpers/CompatibleAssert.t.sol b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/helpers/CompatibleAssert.t.sol new file mode 100644 index 000000000000..4e69c94c8585 --- /dev/null +++ b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/helpers/CompatibleAssert.t.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-3 +pragma solidity ^0.8.24; + +import { console } from "forge-std/console.sol"; + +/// @title CompatibleAssert +/// @notice meant to add compatibility between medusa assertion tests and +/// foundry invariant test's required architecture +contract CompatibleAssert { + bool public failed; + + function compatibleAssert(bool condition) internal { + compatibleAssert(condition, ""); + } + + function compatibleAssert(bool condition, string memory message) internal { + if (!condition) { + if (bytes(message).length != 0) console.log("Assertion failed: ", message); + else console.log("Assertion failed"); + + // for foundry to call & check + failed = true; + + // for medusa + assert(false); + } + } +} diff --git a/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/helpers/HandlerGetters.t.sol b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/helpers/HandlerGetters.t.sol new file mode 100644 index 000000000000..b081aa48c6bb --- /dev/null +++ b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/helpers/HandlerGetters.t.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-3 +pragma solidity ^0.8.24; + +import { ProtocolHandler } from "../handlers/Protocol.t.sol"; +import { EnumerableMap } from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; + +contract HandlerGetters is ProtocolHandler { + using EnumerableMap for EnumerableMap.Bytes32ToUintMap; + + function deploySaltsLength() external view returns (uint256 length) { + return ghost_totalSupplyAcrossChains.length(); + } + + function totalSupplyAcrossChainsAtIndex(uint256 index) external view returns (bytes32 salt, uint256 supply) { + return ghost_totalSupplyAcrossChains.at(index); + } + + function tokensInTransitForDeploySalt(bytes32 salt) external view returns (uint256 amount) { + (, amount) = ghost_tokensInTransit.tryGet(salt); + return amount; + } +} diff --git a/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/helpers/MockL2ToL2CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/helpers/MockL2ToL2CrossDomainMessenger.t.sol new file mode 100644 index 000000000000..6eb1c30e6799 --- /dev/null +++ b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/helpers/MockL2ToL2CrossDomainMessenger.t.sol @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +import { OptimismSuperchainERC20 } from "src/L2/OptimismSuperchainERC20.sol"; +import { SafeCall } from "src/libraries/SafeCall.sol"; + +contract MockL2ToL2CrossDomainMessenger { + //////////////////////// + // type definitions // + //////////////////////// + struct CrossChainMessage { + address crossDomainMessageSender; + address crossDomainMessageSource; + bytes payload; + address recipient; + uint256 amount; + } + + ///////////////////////////////////////////////////////// + // State vars mocking the L2toL2CrossDomainMessenger // + ///////////////////////////////////////////////////////// + address public crossDomainMessageSender; + address public crossDomainMessageSource; + + /////////////////////////////////////////////////// + // Helpers for cross-chain interaction mocking // + /////////////////////////////////////////////////// + mapping(address supertoken => bytes32 deploySalt) public superTokenInitDeploySalts; + mapping(uint256 chainId => mapping(bytes32 deploySalt => address supertoken)) public superTokenAddresses; + + CrossChainMessage[] private _messageQueue; + bool private _atomic; + + function messageQueue(uint256 rawIndex) external view returns (CrossChainMessage memory) { + return _messageQueue[rawIndex % _messageQueue.length]; + } + + function crossChainMessageReceiver( + address sender, + uint256 destinationChainId + ) + external + view + returns (OptimismSuperchainERC20) + { + return OptimismSuperchainERC20(superTokenAddresses[destinationChainId][superTokenInitDeploySalts[sender]]); + } + + function setCrossDomainMessageSender(address sender) external { + crossDomainMessageSender = sender; + } + + function registerSupertoken(bytes32 deploySalt, uint256 chainId, address token) external { + superTokenAddresses[chainId][deploySalt] = token; + superTokenInitDeploySalts[token] = deploySalt; + } + + function messageQueueLength() public view returns (uint256) { + return _messageQueue.length; + } + + function setAtomic(bool atomic) public { + _atomic = atomic; + } + + function relayMessageFromQueue(uint256 rawIndex) public { + uint256 index = rawIndex % _messageQueue.length; + CrossChainMessage memory message = _messageQueue[index]; + _messageQueue[index] = _messageQueue[_messageQueue.length - 1]; + _messageQueue.pop(); + _relayMessage(message); + } + + function _relayMessage(CrossChainMessage memory message) internal { + crossDomainMessageSender = message.crossDomainMessageSender; + crossDomainMessageSource = message.crossDomainMessageSource; + SafeCall.call(crossDomainMessageSender, 0, message.payload); + crossDomainMessageSender = address(0); + crossDomainMessageSource = address(0); + } + + //////////////////////////////////////////////////////// + // Functions mocking the L2toL2CrossDomainMessenger // + //////////////////////////////////////////////////////// + + /// @notice recipient will not be used since in normal execution it's the same + /// address on a different chain, but here we have to compute it to mock + /// cross-chain messaging + function sendMessage(uint256 chainId, address, /*recipient*/ bytes calldata data) external { + address crossChainRecipient = superTokenAddresses[chainId][superTokenInitDeploySalts[msg.sender]]; + if (crossChainRecipient == msg.sender) { + require(false, "same chain"); + } + (address recipient, uint256 amount) = _decodePayload(data); + + CrossChainMessage memory message = CrossChainMessage({ + crossDomainMessageSender: crossChainRecipient, + crossDomainMessageSource: msg.sender, + payload: data, + recipient: recipient, + amount: amount + }); + + if (_atomic) { + _relayMessage(message); + } else { + _messageQueue.push(message); + } + } + + //////////////////////// + // Internal helpers // + //////////////////////// + + function _decodePayload(bytes calldata payload) internal pure returns (address recipient, uint256 amount) { + (, recipient, amount) = abi.decode(payload[4:], (address, address, uint256)); + } +} diff --git a/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/helpers/OptimismSuperchainERC20ForToBProperties.t.sol b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/helpers/OptimismSuperchainERC20ForToBProperties.t.sol new file mode 100644 index 000000000000..9f80cda92fcc --- /dev/null +++ b/packages/contracts-bedrock/test/invariants/OptimismSuperchainERC20/helpers/OptimismSuperchainERC20ForToBProperties.t.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: AGPL-3 +pragma solidity ^0.8.25; + +import { OptimismSuperchainERC20 } from "src/L2/OptimismSuperchainERC20.sol"; + +contract OptimismSuperchainERC20ForToBProperties is OptimismSuperchainERC20 { + /// @notice This is used by CryticERC20ExternalBasicProperties (only used + /// in Medusa testing campaign)to know which properties to test, and + /// remains here so Medusa and Foundry test campaigns can use a single + /// setup + bool public constant isMintableOrBurnable = true; +} From c186b4882e480fff921af25bfea2d83f4bb5a967 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Tue, 17 Sep 2024 21:17:32 -0400 Subject: [PATCH 178/264] ci: job to check contracts build warnings (#11962) Adds a new compiler job to check for contract build warnings. Other existing build jobs don't compile the entire set of contracts and we do want to be able to check for warnings across the board. --- .circleci/config.yml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 04f4f5bd7593..a6db668c239c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -209,9 +209,7 @@ jobs: parameters: build_command: type: string - default: | - just prebuild - forge build --deny-warnings + default: just build steps: - checkout - install-contracts-dependencies @@ -1616,10 +1614,8 @@ workflows: jobs: - go-mod-download - contracts-bedrock-build: - name: contracts-bedrock-build - build_command: | - # Note: scripts are included, to be available to op-e2e - forge build --skip test + # Build with just core + script contracts. + build_command: forge build --skip test --deny-warnings - contracts-bedrock-tests: # Test everything except PreimageOracle.t.sol since it's slow. name: contracts-bedrock-tests @@ -1629,12 +1625,12 @@ workflows: TEST_FILES=$(echo "$TEST_FILES" | circleci tests split --split-by=timings) TEST_FILES=$(echo "$TEST_FILES" | sed 's|./test/||') MATCH_PATH="./test/{$(echo "$TEST_FILES" | paste -sd "," -)}" - forge test --match-path "$MATCH_PATH" + forge test --deny-warnings --match-path "$MATCH_PATH" - contracts-bedrock-tests: # PreimageOracle test is slow, run it separately to unblock CI. name: contracts-bedrock-tests-preimage-oracle test_parallelism: 1 - test_command: forge test --match-path ./test/cannon/PreimageOracle.t.sol + test_command: forge test --deny-warnings --match-path ./test/cannon/PreimageOracle.t.sol - contracts-bedrock-tests: # Heavily fuzz any fuzz tests that have been added or modified. name: contracts-bedrock-tests-heavy-fuzz-modified @@ -2141,7 +2137,10 @@ workflows: - cannon-prestate: requires: - go-mod-download - - contracts-bedrock-build + - contracts-bedrock-build: + build_command: forge build --skip test + context: + - slack - go-e2e-test: name: op-e2e-cannon-tests<< matrix.variant >> matrix: From 86a74bccde52d60bc33cec057360e97b1412be0f Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Tue, 17 Sep 2024 23:04:53 -0400 Subject: [PATCH 179/264] ci: simplify contract build job inputs (#11965) Simplifies the inputs to contracts-bedrock-build so that it takes a single skip_pattern command instead of allowing the user to specify any build command. --- .circleci/config.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a6db668c239c..f04463f57d64 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -207,9 +207,10 @@ jobs: - image: <> resource_class: xlarge parameters: - build_command: + skip_pattern: + description: Glob pattern of tests to skip type: string - default: just build + default: "" steps: - checkout - install-contracts-dependencies @@ -232,7 +233,7 @@ jobs: working_directory: packages/contracts-bedrock - run: name: Build contracts - command: << parameters.build_command >> + command: forge build --deny-warnings --skip <> environment: FOUNDRY_PROFILE: ci working_directory: packages/contracts-bedrock @@ -1615,7 +1616,7 @@ workflows: - go-mod-download - contracts-bedrock-build: # Build with just core + script contracts. - build_command: forge build --skip test --deny-warnings + skip_pattern: test - contracts-bedrock-tests: # Test everything except PreimageOracle.t.sol since it's slow. name: contracts-bedrock-tests @@ -2138,7 +2139,7 @@ workflows: requires: - go-mod-download - contracts-bedrock-build: - build_command: forge build --skip test + skip_pattern: test context: - slack - go-e2e-test: From ab240150179d15d6676cc998bb29df44e937d148 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Tue, 17 Sep 2024 22:27:56 -0600 Subject: [PATCH 180/264] ci: clean up golang job definitions (#11967) Cleans up a number of golang job definitions. One PR for now just so I can see this all work. --- .circleci/config.yml | 159 ++++++++++++++----------------------------- 1 file changed, 51 insertions(+), 108 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f04463f57d64..0865fbc753fc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -932,7 +932,7 @@ jobs: description: Go Module Name type: string docker: - - image: <> # only used to enable codecov. + - image: <> resource_class: xlarge steps: - checkout @@ -944,13 +944,18 @@ jobs: keys: - golang-build-cache-test-<>-{{ checksum "go.sum" }} - golang-build-cache-test- + - run: + name: Install components + command: | + go version + go install gotest.tools/gotestsum@v1.11.0 - run: name: prep results dir - command: mkdir -p /tmp/test-results && mkdir -p /testlogs + command: mkdir -p /tmp/test-results && mkdir -p /tmp/testlogs - run: name: run tests command: | - gotestsum --format=testname --junitfile=/tmp/test-results/<>.xml --jsonfile=/testlogs/log.json \ + gotestsum --format=testname --junitfile=/tmp/test-results/<>.xml --jsonfile=/tmp/testlogs/log.json \ -- -parallel=8 -coverpkg=github.com/ethereum-optimism/optimism/... -coverprofile=coverage.out ./... working_directory: <> - save_cache: @@ -961,7 +966,7 @@ jobs: - store_test_results: path: /tmp/test-results - store_artifacts: - path: /testlogs + path: /tmp/testlogs when: always go-e2e-test: @@ -1650,25 +1655,17 @@ workflows: requires: - go-mod-download - fuzz-golang: - name: op-challenger-fuzz - package_name: op-challenger - on_changes: op-challenger - requires: ["go-mod-download"] - - fuzz-golang: - name: op-node-fuzz - package_name: op-node - on_changes: op-node - requires: ["go-mod-download"] - - fuzz-golang: - name: op-service-fuzz - package_name: op-service - on_changes: op-service - requires: ["go-mod-download"] - - fuzz-golang: - name: op-chain-ops-fuzz - package_name: op-chain-ops - on_changes: op-chain-ops - requires: ["go-mod-download"] + name: fuzz-golang-<> + requires: + - go-mod-download + on_changes: <> + matrix: + parameters: + package_name: + - op-challenger + - op-node + - op-service + - op-chain-ops - fuzz-golang: name: cannon-fuzz package_name: cannon @@ -1682,50 +1679,28 @@ workflows: uses_artifacts: true requires: ["go-mod-download", "contracts-bedrock-build"] - go-test: - name: op-batcher-tests - module: op-batcher - requires: ["go-mod-download"] - - go-test: - name: op-chain-ops-tests - module: op-chain-ops + name: <>-tests + requires: + - go-mod-download + matrix: + parameters: + module: + - op-batcher + - op-chain-ops + - op-node + - op-proposer + - op-challenger + - op-dispute-mon + - op-conductor + - op-program + - op-service + - op-supervisor - go-test-kurtosis: name: op-chain-ops-integration module: op-chain-ops test_directory: ./deployer/integration_test uses_artifacts: true requires: ["contracts-bedrock-build"] - - go-test: - name: op-node-tests - module: op-node - requires: ["go-mod-download"] - - go-test: - name: op-proposer-tests - module: op-proposer - requires: ["go-mod-download"] - - go-test: - name: op-challenger-tests - module: op-challenger - requires: ["go-mod-download"] - - go-test: - name: op-dispute-mon-tests - module: op-dispute-mon - requires: ["go-mod-download"] - - go-test: - name: op-conductor-tests - module: op-conductor - requires: ["go-mod-download"] - - go-test: - name: op-program-tests - module: op-program - requires: ["go-mod-download"] - - go-test: - name: op-service-tests - module: op-service - requires: ["go-mod-download"] - - go-test: - name: op-supervisor-tests - module: op-supervisor - requires: ["go-mod-download"] - go-e2e-test: name: op-e2e-HTTP-tests<< matrix.variant >> matrix: @@ -1785,54 +1760,22 @@ workflows: - op-e2e-action-tests - op-e2e-action-tests-altda - docker-build: - name: op-node-docker-build - docker_name: op-node + name: <>-docker-build docker_tags: <>,<> - save_image_tag: <> # for devnet later - - docker-build: - name: op-batcher-docker-build - docker_name: op-batcher - docker_tags: <>,<> - save_image_tag: <> # for devnet later - - docker-build: - name: op-program-docker-build - docker_name: op-program - docker_tags: <>,<> - # op-program is not part of the devnet, we don't save it. - - docker-build: - name: op-proposer-docker-build - docker_name: op-proposer - docker_tags: <>,<> - save_image_tag: <> # for devnet later - - docker-build: - name: op-challenger-docker-build - docker_name: op-challenger - docker_tags: <>,<> - save_image_tag: <> # for devnet later - - docker-build: - name: proofs-tools-docker-build - docker_name: proofs-tools - docker_tags: <>,<> - - docker-build: - name: op-dispute-mon-docker-build - docker_name: op-dispute-mon - docker_tags: <>,<> - save_image_tag: <> # for devnet later - - docker-build: - name: op-conductor-docker-build - docker_name: op-conductor - docker_tags: <>,<> - # op-conductor is not part of the devnet, we don't save it. - - docker-build: - name: da-server-docker-build - docker_name: da-server - docker_tags: <>,<> - save_image_tag: <> # for devnet later - - docker-build: - name: op-supervisor-docker-build - docker_name: op-supervisor - docker_tags: <>,<> - # op-supervisor is not (yet) part of the devnet, we don't save it + save_image_tag: <> + matrix: + parameters: + docker_name: + - op-node + - op-batcher + - op-program + - op-proposer + - op-challenger + - proofs-tools + - op-dispute-mon + - op-conductor + - da-server + - op-supervisor - cannon-prestate: requires: - go-mod-download From b6e9a614fb4c3d0f0089d0353f9d3ccc7c0be3df Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Tue, 17 Sep 2024 23:07:59 -0600 Subject: [PATCH 181/264] ci: fix config error in cannon tests (#11969) Fixes a configuration error in the scheduled-cannon-full-tests job. --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0865fbc753fc..07f6a55a3f9a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2122,7 +2122,7 @@ workflows: - equal: [ true, << pipeline.parameters.cannon_full_test_dispatch >> ] jobs: - contracts-bedrock-build: - build_command: forge build --skip test --skip scripts + skip_pattern: test - cannon-go-lint-and-test: requires: - contracts-bedrock-build From c40dfed2ba0731cd0ca632630bba6585e41aad1e Mon Sep 17 00:00:00 2001 From: protolambda Date: Wed, 18 Sep 2024 09:33:20 -0600 Subject: [PATCH 182/264] op-node: lazy-dial the supervisor RPC (#11970) --- op-node/node/client.go | 4 +- op-service/client/lazy_dial.go | 84 +++++++++++++++++++++++++++++ op-service/client/lazy_dial_test.go | 66 +++++++++++++++++++++++ op-service/client/rpc.go | 26 +++++++-- 4 files changed, 173 insertions(+), 7 deletions(-) create mode 100644 op-service/client/lazy_dial.go create mode 100644 op-service/client/lazy_dial_test.go diff --git a/op-node/node/client.go b/op-node/node/client.go index caa290ddbbe8..a561a7678d24 100644 --- a/op-node/node/client.go +++ b/op-node/node/client.go @@ -250,9 +250,9 @@ func (cfg *SupervisorEndpointConfig) Check() error { } func (cfg *SupervisorEndpointConfig) SupervisorClient(ctx context.Context, log log.Logger) (*sources.SupervisorClient, error) { - cl, err := client.NewRPC(ctx, log, cfg.SupervisorAddr) + cl, err := client.NewRPC(ctx, log, cfg.SupervisorAddr, client.WithLazyDial()) if err != nil { - return nil, fmt.Errorf("failed to dial supervisor RPC: %w", err) + return nil, fmt.Errorf("failed to create supervisor RPC: %w", err) } return sources.NewSupervisorClient(cl), nil } diff --git a/op-service/client/lazy_dial.go b/op-service/client/lazy_dial.go new file mode 100644 index 000000000000..f5872778da9e --- /dev/null +++ b/op-service/client/lazy_dial.go @@ -0,0 +1,84 @@ +package client + +import ( + "context" + "errors" + "fmt" + "sync" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/rpc" +) + +// LazyRPC defers connection attempts to the usage of the RPC. +// This allows a websocket connection to be established lazily. +// The underlying RPC should handle reconnects. +type LazyRPC struct { + // mutex to prevent more than one active dial attempt at a time. + mu sync.Mutex + // inner is the actual RPC client. + // It is initialized once. The underlying RPC handles reconnections. + inner RPC + // options to initialize `inner` with. + opts []rpc.ClientOption + endpoint string + // If we have not initialized `inner` yet, + // do not try to do so after closing the client. + closed bool +} + +var _ RPC = (*LazyRPC)(nil) + +func NewLazyRPC(endpoint string, opts ...rpc.ClientOption) *LazyRPC { + return &LazyRPC{ + opts: opts, + endpoint: endpoint, + } +} + +func (l *LazyRPC) dial(ctx context.Context) error { + l.mu.Lock() + defer l.mu.Unlock() + if l.inner != nil { + return nil + } + if l.closed { + return errors.New("cannot dial RPC, client was already closed") + } + underlying, err := rpc.DialOptions(ctx, l.endpoint, l.opts...) + if err != nil { + return fmt.Errorf("failed to dial: %w", err) + } + l.inner = &BaseRPCClient{c: underlying} + return nil +} + +func (l *LazyRPC) Close() { + l.mu.Lock() + defer l.mu.Unlock() + if l.inner != nil { + l.inner.Close() + } + l.closed = true +} + +func (l *LazyRPC) CallContext(ctx context.Context, result any, method string, args ...any) error { + if err := l.dial(ctx); err != nil { + return err + } + return l.inner.CallContext(ctx, result, method, args...) +} + +func (l *LazyRPC) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error { + if err := l.dial(ctx); err != nil { + return err + } + return l.inner.BatchCallContext(ctx, b) +} + +func (l *LazyRPC) EthSubscribe(ctx context.Context, channel any, args ...any) (ethereum.Subscription, error) { + if err := l.dial(ctx); err != nil { + return nil, err + } + return l.inner.EthSubscribe(ctx, channel, args...) +} diff --git a/op-service/client/lazy_dial_test.go b/op-service/client/lazy_dial_test.go new file mode 100644 index 000000000000..79608dc2b236 --- /dev/null +++ b/op-service/client/lazy_dial_test.go @@ -0,0 +1,66 @@ +package client + +import ( + "context" + "net" + "net/http" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/rpc" +) + +type mockServer struct { + count int +} + +func (m *mockServer) Count() { + m.count += 1 +} + +func TestLazyRPC(t *testing.T) { + listener, err := net.Listen("tcp", "127.0.0.1:0") + require.NoError(t, err) + defer listener.Close() + + addr := listener.Addr().String() + + cl := NewLazyRPC("ws://" + addr) + defer cl.Close() + + // At this point the connection is online, but the RPC is not. + // RPC request attempts should fail. + { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*4) + attempt1Err := cl.CallContext(ctx, nil, "foo_count") + cancel() + require.ErrorContains(t, attempt1Err, "i/o timeout") + require.NotNil(t, ctx.Err()) + } + + // Now let's serve a websocket RPC + rpcSrv := rpc.NewServer() + defer rpcSrv.Stop() + wsHandler := rpcSrv.WebsocketHandler([]string{"*"}) + httpSrv := &http.Server{Handler: wsHandler} + defer httpSrv.Close() + + go func() { + _ = httpSrv.Serve(listener) // always non-nil, returned when server exits. + }() + + ms := &mockServer{} + require.NoError(t, node.RegisterApis([]rpc.API{{ + Namespace: "foo", + Service: ms, + }}, nil, rpcSrv)) + + // and see if the lazy-dial client can reach it + require.Equal(t, 0, ms.count) + attempt2Err := cl.CallContext(context.Background(), nil, "foo_count") + require.NoError(t, attempt2Err) + require.Equal(t, 1, ms.count) +} diff --git a/op-service/client/rpc.go b/op-service/client/rpc.go index 0ec2f3896535..f1452c57f0db 100644 --- a/op-service/client/rpc.go +++ b/op-service/client/rpc.go @@ -35,6 +35,7 @@ type rpcConfig struct { backoffAttempts int limit float64 burst int + lazy bool } type RPCOption func(cfg *rpcConfig) error @@ -74,6 +75,17 @@ func WithRateLimit(rateLimit float64, burst int) RPCOption { } } +// WithLazyDial makes the RPC client initialization defer the initial connection attempt, +// and defer to later RPC requests upon subsequent dial errors. +// Any dial-backoff option will be ignored if this option is used. +// This is implemented by wrapping the inner RPC client with a LazyRPC. +func WithLazyDial() RPCOption { + return func(cfg *rpcConfig) error { + cfg.lazy = true + return nil + } +} + // NewRPC returns the correct client.RPC instance for a given RPC url. func NewRPC(ctx context.Context, lgr log.Logger, addr string, opts ...RPCOption) (RPC, error) { var cfg rpcConfig @@ -87,13 +99,17 @@ func NewRPC(ctx context.Context, lgr log.Logger, addr string, opts ...RPCOption) cfg.backoffAttempts = 1 } - underlying, err := dialRPCClientWithBackoff(ctx, lgr, addr, cfg.backoffAttempts, cfg.gethRPCOptions...) - if err != nil { - return nil, err + var wrapped RPC + if cfg.lazy { + wrapped = NewLazyRPC(addr, cfg.gethRPCOptions...) + } else { + underlying, err := dialRPCClientWithBackoff(ctx, lgr, addr, cfg.backoffAttempts, cfg.gethRPCOptions...) + if err != nil { + return nil, err + } + wrapped = &BaseRPCClient{c: underlying} } - var wrapped RPC = &BaseRPCClient{c: underlying} - if cfg.limit != 0 { wrapped = NewRateLimitingClient(wrapped, rate.Limit(cfg.limit), cfg.burst) } From 7a10c3180a55ba7102952b4805e77f37c7d4e8b4 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Wed, 18 Sep 2024 09:50:42 -0600 Subject: [PATCH 183/264] ci: simplify contracts bedrock tests job (#11966) Simplifies the contracts-bedrock-tests job so that it takes more parameters but makes the test command unified. Also replaces the complex script for checking for modified fuzz tests and simply heavily fuzzes all tests within any test files that have changed. --- .circleci/config.yml | 47 ++++-- packages/contracts-bedrock/justfile | 4 - .../testing/test-heavy-fuzz-modified-tests.sh | 147 ------------------ 3 files changed, 31 insertions(+), 167 deletions(-) delete mode 100755 packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 07f6a55a3f9a..1a3cd04e6c9a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -587,9 +587,13 @@ jobs: description: Number of test jobs to run in parallel type: integer default: 4 - test_command: + test_list: description: List of test files to run type: string + test_fuzz_runs: + description: Number of fuzz runs to apply + type: integer + default: 512 test_timeout: description: Timeout for running tests type: string @@ -599,6 +603,15 @@ jobs: - checkout - attach_workspace: { at: "." } - install-contracts-dependencies + - run: + name: Check if test list is empty + command: | + TEST_FILES=$(<>) + if [ -z "$TEST_FILES" ]; then + echo "No test files to run. Exiting early." + circleci-agent step halt + fi + working_directory: packages/contracts-bedrock - check-changed: patterns: contracts-bedrock,op-node - restore_cache: @@ -610,11 +623,11 @@ jobs: - golang-build-cache-contracts-bedrock-tests-{{ checksum "go.sum" }} - golang-build-cache-contracts-bedrock-tests- - run: - name: print dependencies + name: Print dependencies command: just dep-status working_directory: packages/contracts-bedrock - run: - name: print forge version + name: Print forge version command: forge --version working_directory: packages/contracts-bedrock - run: @@ -622,18 +635,24 @@ jobs: command: bash scripts/ops/pull-artifacts.sh working_directory: packages/contracts-bedrock - run: - name: build go-ffi + name: Build go-ffi command: just build-go-ffi working_directory: packages/contracts-bedrock - run: - name: run tests - command: <> + name: Run tests + command: | + TEST_FILES=$(<>) + TEST_FILES=$(echo "$TEST_FILES" | circleci tests split --split-by=timings) + TEST_FILES=$(echo "$TEST_FILES" | sed 's|^test/||') + MATCH_PATH="./test/{$(echo "$TEST_FILES" | paste -sd "," -)}" + export FOUNDRY_INVARIANT_RUNS=<> + forge test --deny-warnings --fuzz-runs <> --match-path "$MATCH_PATH" environment: FOUNDRY_PROFILE: ci working_directory: packages/contracts-bedrock no_output_timeout: <> - run: - name: print failed test traces + name: Print failed test traces command: just test-rerun environment: FOUNDRY_PROFILE: ci @@ -1626,23 +1645,19 @@ workflows: # Test everything except PreimageOracle.t.sol since it's slow. name: contracts-bedrock-tests test_parallelism: 4 - test_command: | - TEST_FILES=$(find . -name "*.t.sol" -not -name "PreimageOracle.t.sol") - TEST_FILES=$(echo "$TEST_FILES" | circleci tests split --split-by=timings) - TEST_FILES=$(echo "$TEST_FILES" | sed 's|./test/||') - MATCH_PATH="./test/{$(echo "$TEST_FILES" | paste -sd "," -)}" - forge test --deny-warnings --match-path "$MATCH_PATH" + test_list: find test -name "*.t.sol" -not -name "PreimageOracle.t.sol" - contracts-bedrock-tests: # PreimageOracle test is slow, run it separately to unblock CI. name: contracts-bedrock-tests-preimage-oracle test_parallelism: 1 - test_command: forge test --deny-warnings --match-path ./test/cannon/PreimageOracle.t.sol + test_list: find test -name "PreimageOracle.t.sol" - contracts-bedrock-tests: - # Heavily fuzz any fuzz tests that have been added or modified. + # Heavily fuzz any fuzz tests within added or modified test files. name: contracts-bedrock-tests-heavy-fuzz-modified test_parallelism: 1 + test_list: git diff origin/develop...HEAD --name-only -- './test/**/*.t.sol' | sed 's|packages/contracts-bedrock/||' test_timeout: 1h - test_command: just test-heavy-fuzz-modified-tests + test_fuzz_runs: 10000 - contracts-bedrock-coverage - contracts-bedrock-checks: requires: diff --git a/packages/contracts-bedrock/justfile b/packages/contracts-bedrock/justfile index bf96fd17cad1..7506681774b2 100644 --- a/packages/contracts-bedrock/justfile +++ b/packages/contracts-bedrock/justfile @@ -29,10 +29,6 @@ test-kontrol-no-build: test-rerun: build-go-ffi forge test --rerun -vvv -# Run extra fuzz iterations for modified fuzz tests. -test-heavy-fuzz-modified-tests: build-go-ffi - ./scripts/testing/test-heavy-fuzz-modified-tests.sh - genesis: forge script scripts/L2Genesis.s.sol:L2Genesis --sig 'runWithStateDump()' diff --git a/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh b/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh deleted file mode 100755 index b7a8db6b5912..000000000000 --- a/packages/contracts-bedrock/scripts/testing/test-heavy-fuzz-modified-tests.sh +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# This script is used to run extra fuzz test iterations on any fuzz tests that -# have been added or modified in a PR. We typically want to run extra fuzz -# iterations when new tests are added to make sure that they are not flaky with -# some small percentage of fuzz runs. -# NOTE: This script is NOT perfect and can only catch changes to fuzz tests -# that are made within the test file itself. It won't catch changes to -# dependencies or other external factors that might impact the behavior of the -# fuzz test. This script may also run fuzz tests that have not actually been -# modified. - -# Set the number of fuzz runs to run. -FUZZ_RUNS=${1:-10000} - -# Set the number of invariant runs to run. -INVARIANT_RUNS=${2:-10000} - -# Verify that FUZZ_RUNS is a number. -if ! [[ "$FUZZ_RUNS" =~ ^[0-9]+$ ]]; then - echo "Fuzz runs must be a number" - exit 1 -fi - -# Trap any errors and exit. -trap 'echo "Script failed at line $LINENO"' ERR - -# Get the various base directories. -SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) -CONTRACTS_BASE=$(dirname "$(dirname "$SCRIPT_DIR")") -ROOT_DIR=$(dirname "$(dirname "$CONTRACTS_BASE")") - -# Change to the root directory. -cd "$ROOT_DIR" - -# Get a list of changed Solidity test files relative to the project root. -CHANGED_FILES=$(git diff origin/develop...HEAD --name-only -- '*.sol') - -# Exit if no changed Solidity files are found. -if [ -z "$CHANGED_FILES" ]; then - echo "No changed Solidity files found" - exit 0 -fi - -# Initialize an array to hold relevant function names. -NEW_OR_MODIFIED_TEST_NAMES="" - -# these tests are too expensive to run heavily -IGNORED_FUZZ_TESTS=("MIPS.t.sol" "MIPS2.t.sol") - -# Process each changed file. -for FILE in $CHANGED_FILES; do - IGNORED=false - for TEST in "${IGNORED_FUZZ_TESTS[@]}"; do - FILENAME=$(basename "$FILE") - if [[ "$TEST" == "$FILENAME" ]]; then - IGNORED=true - break - fi - done - if $IGNORED; then - echo "skipping $FILE" - continue - fi - if [ ! -e "$FILE" ] ; then - echo "skipping $FILE since it was deleted" - continue - fi - - # Get the diff for the file. - DIFF=$(git diff origin/develop...HEAD --unified=0 -- "$FILE") - - # Figure out every modified line. - MODIFIED_LINES=$(echo "$DIFF" | \ - awk '/^@@/ { - split($3, a, ",") - start = substr(a[1], 2) - if (length(a) > 1) - count = a[2] - else - count = 1 - for (i = 0; i < count; i++) - print start + i - }' | sort -n | uniq | xargs) - - # Extract function names and their line numbers from the entire file - FUNCTION_LINES=$(awk '/function testFuzz_|function invariant_/ {print FNR, $0}' "$FILE") - - # If there are no function lines, skip the file. - if [ -z "$FUNCTION_LINES" ]; then - continue - fi - - # Reverse the function lines so we can match the last function modified. - # We'd otherwise end up matching the first function with a line number less - # than the modified line number which is not what we want. - FUNCTION_LINES=$(echo "$FUNCTION_LINES" | sort -r) - - # Process each modified line. - for MODIFIED_LINE_NUM in $MODIFIED_LINES; do - # Check all functions to find the last one where the line number of the - # function is less than or equal to the modified line number. This is - # the function that was most likely modified. - # NOTE: This is not perfect and may accidentally match a function that - # was not actually modified but it works well enough and at least won't - # accidentally miss any modified fuzz tests. - while IFS= read -r func; do - # Get the function line number and name. - FUNC_LINE_NUM=$(echo "$func" | awk '{print $1}') - FUNC_NAME=$(echo "$func" | awk '{print $3}' | sed 's/(.*//') - - # Check if the modified line number is greater than or equal to the - # function line number. If it is, then we've found the closest fuzz - # test that was modified. Again, this is not perfect and may lead - # to false positives but won't lead to false negatives. - if [ "$MODIFIED_LINE_NUM" -ge "$FUNC_LINE_NUM" ]; then - NEW_OR_MODIFIED_TEST_NAMES+="$FUNC_NAME " - break - fi - done <<< "$FUNCTION_LINES" - done -done - -# Remove duplicates and sort. -NEW_OR_MODIFIED_TEST_NAMES=$(echo "$NEW_OR_MODIFIED_TEST_NAMES" | xargs -n1 | sort -u | xargs) - -# Exit if no new or modified fuzz tests are found. -if [ -z "$NEW_OR_MODIFIED_TEST_NAMES" ]; then - echo "No new or modified fuzz tests found" - exit 0 -fi - -# Print the detected tests on different lines. -echo "Detected new or modified fuzz tests:" -for TEST_NAME in $NEW_OR_MODIFIED_TEST_NAMES; do - echo " $TEST_NAME" -done - -# Change to the contracts base directory. -cd "$CONTRACTS_BASE" - -# Set the number of invariant runs. -export FOUNDRY_INVARIANT_RUNS="$INVARIANT_RUNS" - -# Run the detected tests with extra fuzz runs -forge test --match-test "${NEW_OR_MODIFIED_TEST_NAMES// /|}" --fuzz-runs "$FUZZ_RUNS" From d9fe07c975dcd7ae2a120120a6d01d7618c97e77 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Wed, 18 Sep 2024 09:54:58 -0600 Subject: [PATCH 184/264] ci: misc cleanups and simplifications (#11968) Cleanups in a few places, removing unused jobs, etc. --- .circleci/config.yml | 95 ++++++++------------------------------------ 1 file changed, 17 insertions(+), 78 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1a3cd04e6c9a..8e4a477cbba9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -239,28 +239,24 @@ jobs: working_directory: packages/contracts-bedrock - run: name: Generate L2OO allocs - command: DEVNET_L2OO="true" make devnet-allocs - - run: - name: Copy L2OO allocs to .devnet-l2oo - command: cp -r .devnet/ .devnet-l2oo/ + command: | + DEVNET_L2OO="true" make devnet-allocs + cp -r .devnet/ .devnet-l2oo/ - run: name: Generate AltDA allocs - command: DEVNET_ALTDA="true" make devnet-allocs - - run: - name: Copy AltDA allocs to .devnet-altda - command: cp -r .devnet/ .devnet-altda/ + command: | + DEVNET_ALTDA="true" make devnet-allocs + cp -r .devnet/ .devnet-altda/ - run: name: Generate Generic AltDA allocs - command: DEVNET_ALTDA="true" GENERIC_ALTDA="true" make devnet-allocs - - run: - name: Copy AltDA allocs to .devnet-altda - command: cp -r .devnet/ .devnet-altda-generic/ + command: | + DEVNET_ALTDA="true" GENERIC_ALTDA="true" make devnet-allocs + cp -r .devnet/ .devnet-altda-generic/ - run: name: Generate MT-Cannon allocs - command: USE_MT_CANNON="true" make devnet-allocs - - run: - name: Copy MT-Cannon allocs to .devnet-mt-cannon - command: cp -r .devnet/ .devnet-mt-cannon/ + command: | + USE_MT_CANNON="true" make devnet-allocs + cp -r .devnet/ .devnet-mt-cannon/ - run: name: Generate default allocs command: make devnet-allocs @@ -280,38 +276,13 @@ jobs: - "packages/contracts-bedrock/cache" - "packages/contracts-bedrock/artifacts" - "packages/contracts-bedrock/forge-artifacts" - - ".devnet/allocs-l1.json" - - ".devnet/allocs-l2-delta.json" - - ".devnet/allocs-l2-ecotone.json" - - ".devnet/allocs-l2-fjord.json" - - ".devnet/allocs-l2-granite.json" - - ".devnet/addresses.json" - - ".devnet-l2oo/allocs-l1.json" - - ".devnet-l2oo/addresses.json" - - ".devnet-l2oo/allocs-l2-delta.json" - - ".devnet-l2oo/allocs-l2-ecotone.json" - - ".devnet-l2oo/allocs-l2-fjord.json" - - ".devnet-l2oo/allocs-l2-granite.json" - - ".devnet-altda/allocs-l1.json" - - ".devnet-altda/addresses.json" - - ".devnet-altda/allocs-l2-delta.json" - - ".devnet-altda/allocs-l2-ecotone.json" - - ".devnet-altda/allocs-l2-fjord.json" - - ".devnet-altda/allocs-l2-granite.json" - - ".devnet-altda-generic/allocs-l1.json" - - ".devnet-altda-generic/addresses.json" - - ".devnet-altda-generic/allocs-l2-delta.json" - - ".devnet-altda-generic/allocs-l2-ecotone.json" - - ".devnet-altda-generic/allocs-l2-fjord.json" - - ".devnet-altda-generic/allocs-l2-granite.json" - - ".devnet-mt-cannon/allocs-l1.json" - - ".devnet-mt-cannon/addresses.json" - - ".devnet-mt-cannon/allocs-l2-delta.json" - - ".devnet-mt-cannon/allocs-l2-ecotone.json" - - ".devnet-mt-cannon/allocs-l2-fjord.json" - - ".devnet-mt-cannon/allocs-l2-granite.json" - "packages/contracts-bedrock/deploy-config/devnetL1.json" - "packages/contracts-bedrock/deployments/devnetL1" + - ".devnet" + - ".devnet-l2oo" + - ".devnet-altda" + - ".devnet-altda-generic" + - ".devnet-mt-cannon" - notify-failures-on-develop docker-build: @@ -842,15 +813,6 @@ jobs: paths: - "/root/.cache/go-build" - l1-geth-version-check: - docker: - - image: <> - steps: - - checkout - - run: - name: "Check L1 geth version" - command: ./ops/scripts/geth-version-checker.sh || (echo "geth version is wrong, update ci-builder"; false) - go-lint: docker: - image: <> @@ -1542,29 +1504,6 @@ jobs: name: check-generated-mocks command: make generate-mocks-op-service && git diff --exit-code - check-values-match: - parameters: - pattern_file1: - type: string - default: "" - pattern_file2: - type: string - default: "" - file1_path: - type: string - default: "" - file2_path: - type: string - default: "" - docker: - - image: <> - steps: - - checkout - - run: - name: Verify Values Match - command: | - ./ops/scripts/ci-match-values-between-files.sh "<< parameters.file1_path >>" "<< parameters.pattern_file1 >>" "<< parameters.file2_path >>" "<< parameters.pattern_file2 >>" - kontrol-tests: docker: - image: << pipeline.parameters.ci_builder_image >> From 924896be760a3a02d0cc45210896ffa2e91127d5 Mon Sep 17 00:00:00 2001 From: rickck11 Date: Wed, 18 Sep 2024 13:02:04 -0300 Subject: [PATCH 185/264] correct the comment (#11971) --- op-e2e/actions/proofs/helpers/fixture.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op-e2e/actions/proofs/helpers/fixture.go b/op-e2e/actions/proofs/helpers/fixture.go index 458ce74920ec..a0535a275e1a 100644 --- a/op-e2e/actions/proofs/helpers/fixture.go +++ b/op-e2e/actions/proofs/helpers/fixture.go @@ -44,7 +44,7 @@ type FixtureInputs struct { L1Head common.Hash `toml:"l1-head"` } -// Dumps a `fp-tests` test fixture to disk if the `OP_E2E_DUMP_FIXTURES` environment variable is set. +// Dumps a `fp-tests` test fixture to disk if the `OP_E2E_FPP_FIXTURE_DIR` environment variable is set. // // [fp-tests]: https://github.com/ethereum-optimism/fp-tests func tryDumpTestFixture( From 68b52398212a9ab55181ab8f762ac0db4d279928 Mon Sep 17 00:00:00 2001 From: Hamdi Allam Date: Wed, 18 Sep 2024 18:11:44 +0200 Subject: [PATCH 186/264] update op-e2e setup (#11857) --- op-e2e/system/e2esys/setup.go | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/op-e2e/system/e2esys/setup.go b/op-e2e/system/e2esys/setup.go index 832823c608e3..dbfd93450e58 100644 --- a/op-e2e/system/e2esys/setup.go +++ b/op-e2e/system/e2esys/setup.go @@ -33,6 +33,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/node" @@ -266,6 +267,9 @@ type SystemConfig struct { // Explicitly disable batcher, for tests that rely on unsafe L2 payloads DisableBatcher bool + // Explicitly disable setting `RollupSequencerHTTP` to forward txs from sentry nodes + DisableTxForwarder bool + // Configure data-availability type that is used by the batcher. DataAvailabilityType batcherFlags.DataAvailabilityType @@ -610,25 +614,44 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste return nil, err } + // Ordered such that the Sequencer is initialized first. Setup this way so that + // the `RollupSequencerHTTP` GethOption can be supplied to any sentry nodes. + l2Nodes := []string{RoleSeq} for name := range cfg.Nodes { - if name == RoleL1 { - return nil, fmt.Errorf("node name %s is reserved for L1 node", RoleL1) + if name == RoleSeq { + continue } + l2Nodes = append(l2Nodes, name) + } + + for _, name := range l2Nodes { var ethClient services.EthInstance if cfg.ExternalL2Shim == "" { + if name != RoleSeq && !cfg.DisableTxForwarder { + cfg.GethOptions[name] = append(cfg.GethOptions[name], func(ethCfg *ethconfig.Config, nodeCfg *node.Config) error { + ethCfg.RollupSequencerHTTP = sys.EthInstances[RoleSeq].UserRPC().RPC() + return nil + }) + } + l2Geth, err := geth.InitL2(name, l2Genesis, cfg.JWTFilePath, cfg.GethOptions[name]...) if err != nil { return nil, err } - err = l2Geth.Node.Start() - if err != nil { + if err := l2Geth.Node.Start(); err != nil { return nil, err } + ethClient = l2Geth } else { if len(cfg.GethOptions[name]) > 0 { t.Skip("External L2 nodes do not support configuration through GethOptions") } + + if name != RoleSeq && !cfg.DisableTxForwarder { + cfg.Loggers[name].Warn("External L2 nodes do not support `RollupSequencerHTTP` configuration. No tx forwarding support.") + } + ethClient = (&ExternalRunner{ Name: name, BinPath: cfg.ExternalL2Shim, @@ -636,6 +659,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste JWTPath: cfg.JWTFilePath, }).Run(t) } + sys.EthInstances[name] = ethClient } From ae37e02420960e4cbd9aa25d8a10f2ae7deea18b Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Wed, 18 Sep 2024 10:15:39 -0600 Subject: [PATCH 187/264] fix: multiple fuzz flakes (#11981) Fixes a couple of fuzz flakes that were found when fuzzing heavily. --- .../test/L1/DataAvailabilityChallenge.t.sol | 3 +++ .../test/L2/L2ToL2CrossDomainMessenger.t.sol | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/test/L1/DataAvailabilityChallenge.t.sol b/packages/contracts-bedrock/test/L1/DataAvailabilityChallenge.t.sol index 584a28d7a189..5304cf797449 100644 --- a/packages/contracts-bedrock/test/L1/DataAvailabilityChallenge.t.sol +++ b/packages/contracts-bedrock/test/L1/DataAvailabilityChallenge.t.sol @@ -10,6 +10,7 @@ import { import { computeCommitmentKeccak256 } from "src/L1/DataAvailabilityChallenge.sol"; import { Proxy } from "src/universal/Proxy.sol"; import { CommonTest } from "test/setup/CommonTest.sol"; +import { Preinstalls } from "src/libraries/Preinstalls.sol"; contract DataAvailabilityChallengeTest is CommonTest { function setUp() public virtual override { @@ -33,6 +34,8 @@ contract DataAvailabilityChallengeTest is CommonTest { function testWithdraw(address sender, uint256 amount) public { assumePayable(sender); assumeNotPrecompile(sender); + // EntryPoint will revert if using amount > type(uint112).max. + vm.assume(sender != Preinstalls.EntryPoint_v060); vm.assume(sender != address(dataAvailabilityChallenge)); vm.assume(sender.balance == 0); vm.deal(sender, amount); diff --git a/packages/contracts-bedrock/test/L2/L2ToL2CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L2/L2ToL2CrossDomainMessenger.t.sol index 1bf394d1a0d5..66b0b7e83209 100644 --- a/packages/contracts-bedrock/test/L2/L2ToL2CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/L2/L2ToL2CrossDomainMessenger.t.sol @@ -194,8 +194,12 @@ contract L2ToL2CrossDomainMessengerTest is Test { ) external { + // Ensure that the target contract is not a Forge contract. + assumeNotForgeAddress(_target); + // Ensure that the target contract is not CrossL2Inbox or L2ToL2CrossDomainMessenger - vm.assume(_target != Predeploys.CROSS_L2_INBOX && _target != Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER); + vm.assume(_target != Predeploys.CROSS_L2_INBOX); + vm.assume(_target != Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER); // Ensure that the target call is payable if value is sent if (_value > 0) assumePayable(_target); From 7db0f6af91824b98002da5980de9fafd1952931e Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Wed, 18 Sep 2024 10:45:39 -0600 Subject: [PATCH 188/264] maint: add interfaces for L2 bridge/messaging contracts (#11859) First PR for adding interfaces for L2 contracts. Adds interfaces for all of the bridging and message passing contracts. --- .../contracts-bedrock/scripts/L2Genesis.s.sol | 26 +++++----- .../scripts/checks/check-interfaces.sh | 21 ++++---- packages/contracts-bedrock/semver-lock.json | 8 +-- .../src/L1/L1ERC721Bridge.sol | 8 +-- .../L1/interfaces/IL1CrossDomainMessenger.sol | 36 +------------ .../src/L2/CrossDomainOwnable2.sol | 11 ++-- .../src/L2/CrossDomainOwnable3.sol | 11 ++-- .../src/L2/L2CrossDomainMessenger.sol | 19 ++++--- .../L2/interfaces/IL2CrossDomainMessenger.sol | 11 ++++ .../src/L2/interfaces/IL2ERC721Bridge.sol | 18 +++++++ .../src/L2/interfaces/IL2StandardBridge.sol | 46 +++++++++++++++++ .../interfaces/IL2StandardBridgeInterop.sol | 23 +++++++++ .../L2/interfaces/IL2ToL1MessagePasser.sol | 24 +++++++++ .../src/universal/FeeVault.sol | 7 ++- .../test/L1/L1ERC721Bridge.t.sol | 6 +-- .../test/L1/L1StandardBridge.t.sol | 1 - .../test/L2/L2CrossDomainMessenger.t.sol | 18 +++---- .../test/L2/L2ERC721Bridge.t.sol | 4 +- .../test/L2/L2StandardBridge.t.sol | 42 ++++++++-------- .../test/L2/L2StandardBridgeInterop.t.sol | 47 ++++++++--------- .../test/L2/SequencerFeeVault.t.sol | 18 +++---- .../contracts-bedrock/test/setup/Setup.sol | 22 ++++---- .../test/vendor/Initializable.t.sol | 50 +++++++++---------- 23 files changed, 291 insertions(+), 186 deletions(-) create mode 100644 packages/contracts-bedrock/src/L2/interfaces/IL2CrossDomainMessenger.sol create mode 100644 packages/contracts-bedrock/src/L2/interfaces/IL2ERC721Bridge.sol create mode 100644 packages/contracts-bedrock/src/L2/interfaces/IL2StandardBridge.sol create mode 100644 packages/contracts-bedrock/src/L2/interfaces/IL2StandardBridgeInterop.sol create mode 100644 packages/contracts-bedrock/src/L2/interfaces/IL2ToL1MessagePasser.sol diff --git a/packages/contracts-bedrock/scripts/L2Genesis.s.sol b/packages/contracts-bedrock/scripts/L2Genesis.s.sol index 2695a7dcc892..6d1c6bfe6517 100644 --- a/packages/contracts-bedrock/scripts/L2Genesis.s.sol +++ b/packages/contracts-bedrock/scripts/L2Genesis.s.sol @@ -15,18 +15,13 @@ import { Process } from "scripts/libraries/Process.sol"; import { SetPreinstalls } from "scripts/SetPreinstalls.s.sol"; // Contracts -import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol"; import { L1Block } from "src/L2/L1Block.sol"; import { GasPriceOracle } from "src/L2/GasPriceOracle.sol"; -import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; -import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol"; import { BaseFeeVault } from "src/L2/BaseFeeVault.sol"; import { L1FeeVault } from "src/L2/L1FeeVault.sol"; import { OptimismSuperchainERC20Beacon } from "src/L2/OptimismSuperchainERC20Beacon.sol"; import { OptimismMintableERC721Factory } from "src/universal/OptimismMintableERC721Factory.sol"; -import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { StandardBridge } from "src/universal/StandardBridge.sol"; import { FeeVault } from "src/universal/FeeVault.sol"; import { GovernanceToken } from "src/governance/GovernanceToken.sol"; @@ -36,6 +31,11 @@ import { Preinstalls } from "src/libraries/Preinstalls.sol"; // Interfaces import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol"; +import { IL2CrossDomainMessenger } from "src/L2/interfaces/IL2CrossDomainMessenger.sol"; +import { IL2StandardBridge } from "src/L2/interfaces/IL2StandardBridge.sol"; +import { IL2ERC721Bridge } from "src/L2/interfaces/IL2ERC721Bridge.sol"; +import { IStandardBridge } from "src/universal/interfaces/IStandardBridge.sol"; +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; interface IInitializable { function initialize(address _addr) external; @@ -304,10 +304,10 @@ contract L2Genesis is Deployer { function setL2CrossDomainMessenger(address payable _l1CrossDomainMessengerProxy) public { address impl = _setImplementationCode(Predeploys.L2_CROSS_DOMAIN_MESSENGER); - L2CrossDomainMessenger(impl).initialize({ _l1CrossDomainMessenger: CrossDomainMessenger(address(0)) }); + IL2CrossDomainMessenger(impl).initialize({ _l1CrossDomainMessenger: ICrossDomainMessenger(address(0)) }); - L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER).initialize({ - _l1CrossDomainMessenger: CrossDomainMessenger(_l1CrossDomainMessengerProxy) + IL2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER).initialize({ + _l1CrossDomainMessenger: ICrossDomainMessenger(_l1CrossDomainMessengerProxy) }); } @@ -323,10 +323,10 @@ contract L2Genesis is Deployer { impl = _setImplementationCode(Predeploys.L2_STANDARD_BRIDGE); } - L2StandardBridge(payable(impl)).initialize({ _otherBridge: StandardBridge(payable(address(0))) }); + IL2StandardBridge(payable(impl)).initialize({ _otherBridge: IStandardBridge(payable(address(0))) }); - L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).initialize({ - _otherBridge: StandardBridge(_l1StandardBridgeProxy) + IL2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).initialize({ + _otherBridge: IStandardBridge(_l1StandardBridgeProxy) }); } @@ -334,9 +334,9 @@ contract L2Genesis is Deployer { function setL2ERC721Bridge(address payable _l1ERC721BridgeProxy) public { address impl = _setImplementationCode(Predeploys.L2_ERC721_BRIDGE); - L2ERC721Bridge(impl).initialize({ _l1ERC721Bridge: payable(address(0)) }); + IL2ERC721Bridge(impl).initialize({ _l1ERC721Bridge: payable(address(0)) }); - L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE).initialize({ _l1ERC721Bridge: payable(_l1ERC721BridgeProxy) }); + IL2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE).initialize({ _l1ERC721Bridge: payable(_l1ERC721BridgeProxy) }); } /// @notice This predeploy is following the safety invariant #2, diff --git a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh index 435034a3b06d..8da3227311e5 100755 --- a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh +++ b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh @@ -68,9 +68,6 @@ EXCLUDE_CONTRACTS=( "ISuperchainConfig" "IOptimismPortal" "IL1BlockIsthmus" - - # Need to make complex tweaks to the check script for this one - "ISystemConfigInterop" ) # Find all JSON files in the forge-artifacts folder @@ -187,17 +184,23 @@ for interface_file in $JSON_FILES; do # Base contracts aren't allowed to inherit from their interfaces in order # to guarantee a 1:1 match between interfaces and contracts. This means # that the interface will redefine types in the base contract. We normalize - # the ABI as if the interface and contract are the same name + # the ABI as if the interface and contract are the same name. normalize_abi() { + # Here we just remove the leading "I" from any contract, enum, or + # struct type. It's not beautiful but it's good enough for now. It + # would miss certain edge cases like if an interface really is using + # the contract type instead of the interface type but that's unlikely + # to happen in practice and should be an easy fix if it does. local abi="$1" - local interface_name="$2" - local contract_name="$3" - echo "${abi//$interface_name/$contract_name}" + abi="${abi//\"internalType\": \"contract I/\"internalType\": \"contract }" + abi="${abi//\"internalType\": \"enum I/\"internalType\": \"enum }" + abi="${abi//\"internalType\": \"struct I/\"internalType\": \"struct }" + echo "$abi" } # Normalize the ABIs - normalized_interface_abi=$(normalize_abi "$interface_abi" "$contract_name" "$contract_basename") - normalized_contract_abi="$contract_abi" + normalized_interface_abi=$(normalize_abi "$interface_abi") + normalized_contract_abi=$(normalize_abi "$contract_abi") # Use jq to compare the ABIs if ! diff_result=$(diff -u <(echo "$normalized_interface_abi" | jq -S .) <(echo "$normalized_contract_abi" | jq -S .)); then diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 8a2ac2ba5b8b..f28e53aac307 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -20,8 +20,8 @@ "sourceCodeHash": "0xb77342e6b55b835e9597f7a1c4a2d52ddd56f5cfb7cd38da0bcc488c79a9011e" }, "src/L1/L1ERC721Bridge.sol": { - "initCodeHash": "0xda80d225e332f9ab38d5f3ae655df3eea1dd56dbb523036a25c78859d2931ada", - "sourceCodeHash": "0x0454bb88f7b52c362309935fa21ecc8be7bd6f0d888270b8a00677c60c1014cb" + "initCodeHash": "0xfb8b3c51e1790a0b951eaba05ed7368309fbfc7ddc558b4ce1de29da087fb4bd", + "sourceCodeHash": "0xcb125e7f640cf5f372c7bf4f8e36150328914ceef99b6fd5d65ae12b6db430b5" }, "src/L1/L1StandardBridge.sol": { "initCodeHash": "0x2868b09ecbe9f2bbc885605c2886b4c79f1c8e4171626c63776603b1b84698a8", @@ -92,8 +92,8 @@ "sourceCodeHash": "0x927cc729bf5c9f209112df597f649493f276c4c50e17a57f7da02c2be266b192" }, "src/L2/L2CrossDomainMessenger.sol": { - "initCodeHash": "0xe7090ce8119fe373d930baa68c1df585953b7f6e8beea2a0084589d394bcab64", - "sourceCodeHash": "0xea51d4b7a96c3a4c06d73c214208775b6845d5f696198c169ef7c14ea005d451" + "initCodeHash": "0xff39e6cf57acfc04e7f3242d7a45b0b4dec489b5cb3aabb319dae94dfb7ee454", + "sourceCodeHash": "0x60620a3aa6dd85974bb4267fb8c5845ffe8981dd7772b8d9055c0392ed414f77" }, "src/L2/L2ERC721Bridge.sol": { "initCodeHash": "0x827077e1a0ce6c8f9ee1196c409ea77d831efd440992b3969b05259083cdf0bd", diff --git a/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol b/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol index 04ea2a6cc82e..46e7e9f71b4c 100644 --- a/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol +++ b/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.15; // Contracts import { ERC721Bridge } from "src/universal/ERC721Bridge.sol"; -import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; // Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; @@ -14,6 +13,7 @@ import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; +import { IL2ERC721Bridge } from "src/L2/interfaces/IL2ERC721Bridge.sol"; /// @custom:proxied true /// @title L1ERC721Bridge @@ -29,8 +29,8 @@ contract L1ERC721Bridge is ERC721Bridge, ISemver { ISuperchainConfig public superchainConfig; /// @notice Semantic version. - /// @custom:semver 2.1.1-beta.2 - string public constant version = "2.1.1-beta.2"; + /// @custom:semver 2.1.1-beta.3 + string public constant version = "2.1.1-beta.3"; /// @notice Constructs the L1ERC721Bridge contract. constructor() ERC721Bridge() { @@ -109,7 +109,7 @@ contract L1ERC721Bridge is ERC721Bridge, ISemver { // Construct calldata for _l2Token.finalizeBridgeERC721(_to, _tokenId) bytes memory message = abi.encodeWithSelector( - L2ERC721Bridge.finalizeBridgeERC721.selector, _remoteToken, _localToken, _from, _to, _tokenId, _extraData + IL2ERC721Bridge.finalizeBridgeERC721.selector, _remoteToken, _localToken, _from, _to, _tokenId, _extraData ); // Lock token into bridge diff --git a/packages/contracts-bedrock/src/L1/interfaces/IL1CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L1/interfaces/IL1CrossDomainMessenger.sol index 85478cfa257b..bb92e723c7c3 100644 --- a/packages/contracts-bedrock/src/L1/interfaces/IL1CrossDomainMessenger.sol +++ b/packages/contracts-bedrock/src/L1/interfaces/IL1CrossDomainMessenger.sol @@ -1,53 +1,21 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; -interface IL1CrossDomainMessenger { - event FailedRelayedMessage(bytes32 indexed msgHash); - event Initialized(uint8 version); - event RelayedMessage(bytes32 indexed msgHash); - event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit); - event SentMessageExtension1(address indexed sender, uint256 value); - - function MESSAGE_VERSION() external view returns (uint16); - function MIN_GAS_CALLDATA_OVERHEAD() external view returns (uint64); - function MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR() external view returns (uint64); - function MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR() external view returns (uint64); - function OTHER_MESSENGER() external view returns (address); +interface IL1CrossDomainMessenger is ICrossDomainMessenger { function PORTAL() external view returns (address); - function RELAY_CALL_OVERHEAD() external view returns (uint64); - function RELAY_CONSTANT_OVERHEAD() external view returns (uint64); - function RELAY_GAS_CHECK_BUFFER() external view returns (uint64); - function RELAY_RESERVED_GAS() external view returns (uint64); - function baseGas(bytes memory _message, uint32 _minGasLimit) external pure returns (uint64); - function failedMessages(bytes32) external view returns (bool); function initialize( ISuperchainConfig _superchainConfig, IOptimismPortal _portal, ISystemConfig _systemConfig ) external; - function messageNonce() external view returns (uint256); - function otherMessenger() external view returns (address); - function paused() external view returns (bool); function portal() external view returns (address); - function relayMessage( - uint256 _nonce, - address _sender, - address _target, - uint256 _value, - uint256 _minGasLimit, - bytes memory _message - ) - external - payable; - function sendMessage(address _target, bytes memory _message, uint32 _minGasLimit) external payable; - function successfulMessages(bytes32) external view returns (bool); function superchainConfig() external view returns (address); function systemConfig() external view returns (address); function version() external view returns (string memory); - function xDomainMessageSender() external view returns (address); } diff --git a/packages/contracts-bedrock/src/L2/CrossDomainOwnable2.sol b/packages/contracts-bedrock/src/L2/CrossDomainOwnable2.sol index ce14229c9b51..0711daffce3e 100644 --- a/packages/contracts-bedrock/src/L2/CrossDomainOwnable2.sol +++ b/packages/contracts-bedrock/src/L2/CrossDomainOwnable2.sol @@ -1,10 +1,15 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { Predeploys } from "src/libraries/Predeploys.sol"; -import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol"; +// Contracts import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Interfaces +import { IL2CrossDomainMessenger } from "src/L2/interfaces/IL2CrossDomainMessenger.sol"; + /// @title CrossDomainOwnable2 /// @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned /// by contracts on L1. Note that this contract is meant to be used with systems that use @@ -15,7 +20,7 @@ abstract contract CrossDomainOwnable2 is Ownable { /// `xDomainMessageSender` is the owner of the contract. This value is set to the caller /// of the L1CrossDomainMessenger. function _checkOwner() internal view override { - L2CrossDomainMessenger messenger = L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER); + IL2CrossDomainMessenger messenger = IL2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER); require(msg.sender == address(messenger), "CrossDomainOwnable2: caller is not the messenger"); diff --git a/packages/contracts-bedrock/src/L2/CrossDomainOwnable3.sol b/packages/contracts-bedrock/src/L2/CrossDomainOwnable3.sol index 2e4ef7a17c2a..e940a026df05 100644 --- a/packages/contracts-bedrock/src/L2/CrossDomainOwnable3.sol +++ b/packages/contracts-bedrock/src/L2/CrossDomainOwnable3.sol @@ -1,10 +1,15 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { Predeploys } from "src/libraries/Predeploys.sol"; -import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol"; +// Contracts import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Interfaces +import { IL2CrossDomainMessenger } from "src/L2/interfaces/IL2CrossDomainMessenger.sol"; + /// @title CrossDomainOwnable3 /// @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned /// by contracts on either L1 or L2. Note that this contract is meant to be used with @@ -42,7 +47,7 @@ abstract contract CrossDomainOwnable3 is Ownable { if (isLocal) { require(owner() == msg.sender, "CrossDomainOwnable3: caller is not the owner"); } else { - L2CrossDomainMessenger messenger = L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER); + IL2CrossDomainMessenger messenger = IL2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER); require(msg.sender == address(messenger), "CrossDomainOwnable3: caller is not the messenger"); diff --git a/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol index 23c71d3109dd..a77d4c6d3ecd 100644 --- a/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol +++ b/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol @@ -1,15 +1,20 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Contracts +import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; +import { L1Block } from "src/L2/L1Block.sol"; + +// Libraries import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; -import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { ISemver } from "src/universal/interfaces/ISemver.sol"; -import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; import { Constants } from "src/libraries/Constants.sol"; -import { L1Block } from "src/L2/L1Block.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; +// Interfaces +import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { IL2ToL1MessagePasser } from "src/L2/interfaces/IL2ToL1MessagePasser.sol"; + /// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000007 /// @title L2CrossDomainMessenger @@ -17,8 +22,8 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; /// L2 on the L2 side. Users are generally encouraged to use this contract instead of lower /// level message passing contracts. contract L2CrossDomainMessenger is CrossDomainMessenger, ISemver { - /// @custom:semver 2.1.1-beta.1 - string public constant version = "2.1.1-beta.1"; + /// @custom:semver 2.1.1-beta.2 + string public constant version = "2.1.1-beta.2"; /// @notice Constructs the L2CrossDomainMessenger contract. constructor() CrossDomainMessenger() { @@ -41,7 +46,7 @@ contract L2CrossDomainMessenger is CrossDomainMessenger, ISemver { /// @inheritdoc CrossDomainMessenger function _sendMessage(address _to, uint64 _gasLimit, uint256 _value, bytes memory _data) internal override { - L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal{ value: _value }( + IL2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal{ value: _value }( _to, _gasLimit, _data ); } diff --git a/packages/contracts-bedrock/src/L2/interfaces/IL2CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L2/interfaces/IL2CrossDomainMessenger.sol new file mode 100644 index 000000000000..9c6df21ef1d6 --- /dev/null +++ b/packages/contracts-bedrock/src/L2/interfaces/IL2CrossDomainMessenger.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; + +interface IL2CrossDomainMessenger is ICrossDomainMessenger { + function MESSAGE_VERSION() external view returns (uint16); + function initialize(ICrossDomainMessenger _l1CrossDomainMessenger) external; + function l1CrossDomainMessenger() external view returns (ICrossDomainMessenger); + function version() external view returns (string memory); +} diff --git a/packages/contracts-bedrock/src/L2/interfaces/IL2ERC721Bridge.sol b/packages/contracts-bedrock/src/L2/interfaces/IL2ERC721Bridge.sol new file mode 100644 index 000000000000..1bfde1540015 --- /dev/null +++ b/packages/contracts-bedrock/src/L2/interfaces/IL2ERC721Bridge.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { IERC721Bridge } from "src/universal/interfaces/IERC721Bridge.sol"; + +interface IL2ERC721Bridge is IERC721Bridge { + function finalizeBridgeERC721( + address _localToken, + address _remoteToken, + address _from, + address _to, + uint256 _tokenId, + bytes memory _extraData + ) + external; + function initialize(address payable _l1ERC721Bridge) external; + function version() external view returns (string memory); +} diff --git a/packages/contracts-bedrock/src/L2/interfaces/IL2StandardBridge.sol b/packages/contracts-bedrock/src/L2/interfaces/IL2StandardBridge.sol new file mode 100644 index 000000000000..559aa846c53c --- /dev/null +++ b/packages/contracts-bedrock/src/L2/interfaces/IL2StandardBridge.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { IStandardBridge } from "src/universal/interfaces/IStandardBridge.sol"; + +interface IL2StandardBridge is IStandardBridge { + event DepositFinalized( + address indexed l1Token, + address indexed l2Token, + address indexed from, + address to, + uint256 amount, + bytes extraData + ); + event WithdrawalInitiated( + address indexed l1Token, + address indexed l2Token, + address indexed from, + address to, + uint256 amount, + bytes extraData + ); + + receive() external payable; + + function initialize(IStandardBridge _otherBridge) external; + function l1TokenBridge() external view returns (address); + function version() external pure returns (string memory); + function withdraw( + address _l2Token, + uint256 _amount, + uint32 _minGasLimit, + bytes memory _extraData + ) + external + payable; + function withdrawTo( + address _l2Token, + address _to, + uint256 _amount, + uint32 _minGasLimit, + bytes memory _extraData + ) + external + payable; +} diff --git a/packages/contracts-bedrock/src/L2/interfaces/IL2StandardBridgeInterop.sol b/packages/contracts-bedrock/src/L2/interfaces/IL2StandardBridgeInterop.sol new file mode 100644 index 000000000000..1c0327baf3b3 --- /dev/null +++ b/packages/contracts-bedrock/src/L2/interfaces/IL2StandardBridgeInterop.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { IL2StandardBridge } from "src/L2/interfaces/IL2StandardBridge.sol"; + +interface IMintableAndBurnable is IERC20 { + function mint(address, uint256) external; + function burn(address, uint256) external; +} + +interface IL2StandardBridgeInterop is IL2StandardBridge { + error InvalidDecimals(); + error InvalidLegacyERC20Address(); + error InvalidSuperchainERC20Address(); + error InvalidTokenPair(); + + event Converted(address indexed from, address indexed to, address indexed caller, uint256 amount); + + receive() external payable; + + function convert(address _from, address _to, uint256 _amount) external; +} diff --git a/packages/contracts-bedrock/src/L2/interfaces/IL2ToL1MessagePasser.sol b/packages/contracts-bedrock/src/L2/interfaces/IL2ToL1MessagePasser.sol new file mode 100644 index 000000000000..751cf51a40db --- /dev/null +++ b/packages/contracts-bedrock/src/L2/interfaces/IL2ToL1MessagePasser.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IL2ToL1MessagePasser { + event MessagePassed( + uint256 indexed nonce, + address indexed sender, + address indexed target, + uint256 value, + uint256 gasLimit, + bytes data, + bytes32 withdrawalHash + ); + event WithdrawerBalanceBurnt(uint256 indexed amount); + + receive() external payable; + + function MESSAGE_VERSION() external view returns (uint16); + function burn() external; + function initiateWithdrawal(address _target, uint256 _gasLimit, bytes memory _data) external payable; + function messageNonce() external view returns (uint256); + function sentMessages(bytes32) external view returns (bool); + function version() external view returns (string memory); +} diff --git a/packages/contracts-bedrock/src/universal/FeeVault.sol b/packages/contracts-bedrock/src/universal/FeeVault.sol index aa68c5f53b1d..542cd88447a4 100644 --- a/packages/contracts-bedrock/src/universal/FeeVault.sol +++ b/packages/contracts-bedrock/src/universal/FeeVault.sol @@ -1,10 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; +// Libraries import { SafeCall } from "src/libraries/SafeCall.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; +// Interfaces +import { IL2ToL1MessagePasser } from "src/L2/interfaces/IL2ToL1MessagePasser.sol"; + /// @title FeeVault /// @notice The FeeVault contract contains the basic logic for the various different vault contracts /// used to hold fee revenue generated by the L2 system. @@ -102,7 +105,7 @@ abstract contract FeeVault { bool success = SafeCall.send(RECIPIENT, value); require(success, "FeeVault: failed to send ETH to L2 fee recipient"); } else { - L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal{ value: value }({ + IL2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal{ value: value }({ _target: RECIPIENT, _gasLimit: WITHDRAWAL_MIN_GAS, _data: hex"" diff --git a/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol b/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol index f69b73e1fd5e..44feddc5031d 100644 --- a/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol +++ b/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol @@ -6,7 +6,6 @@ import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; // Contracts import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; // Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; @@ -15,6 +14,7 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; +import { IL2ERC721Bridge } from "src/L2/interfaces/IL2ERC721Bridge.sol"; /// @dev Test ERC721 contract. contract TestERC721 is ERC721 { @@ -96,7 +96,7 @@ contract L1ERC721Bridge_Test is Bridge_Initializer { ( address(l2ERC721Bridge), abi.encodeCall( - L2ERC721Bridge.finalizeBridgeERC721, + IL2ERC721Bridge.finalizeBridgeERC721, (address(remoteToken), address(localToken), alice, alice, tokenId, hex"5678") ), 1234 @@ -177,7 +177,7 @@ contract L1ERC721Bridge_Test is Bridge_Initializer { ( address(Predeploys.L2_ERC721_BRIDGE), abi.encodeCall( - L2ERC721Bridge.finalizeBridgeERC721, + IL2ERC721Bridge.finalizeBridgeERC721, (address(remoteToken), address(localToken), alice, bob, tokenId, hex"5678") ), 1234 diff --git a/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol b/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol index afc97afd0b43..abe7196070e8 100644 --- a/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol +++ b/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol @@ -8,7 +8,6 @@ import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; // Contracts import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol"; -import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; // Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; diff --git a/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol index 9892ba51cb3e..1c13ece264fc 100644 --- a/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Testing utilities +// Testing import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { Reverter, ConfigurableCaller } from "test/mocks/Callers.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; @@ -11,20 +11,20 @@ import { Hashing } from "src/libraries/Hashing.sol"; import { Encoding } from "src/libraries/Encoding.sol"; import { Types } from "src/libraries/Types.sol"; import { Constants } from "src/libraries/Constants.sol"; - -// Target contract dependencies -import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol"; -import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; +// Interfaces +import { IL2CrossDomainMessenger } from "src/L2/interfaces/IL2CrossDomainMessenger.sol"; +import { IL2ToL1MessagePasser } from "src/L2/interfaces/IL2ToL1MessagePasser.sol"; + contract L2CrossDomainMessenger_Test is Bridge_Initializer { /// @dev Receiver address for testing address recipient = address(0xabbaacdc); /// @dev Tests that the implementation is initialized correctly. function test_constructor_succeeds() external view { - L2CrossDomainMessenger impl = - L2CrossDomainMessenger(EIP1967Helper.getImplementation(deploy.mustGetAddress("L2CrossDomainMessenger"))); + IL2CrossDomainMessenger impl = + IL2CrossDomainMessenger(EIP1967Helper.getImplementation(deploy.mustGetAddress("L2CrossDomainMessenger"))); assertEq(address(impl.OTHER_MESSENGER()), address(0)); assertEq(address(impl.otherMessenger()), address(0)); assertEq(address(impl.l1CrossDomainMessenger()), address(0)); @@ -50,7 +50,7 @@ contract L2CrossDomainMessenger_Test is Bridge_Initializer { vm.expectCall( address(l2ToL1MessagePasser), abi.encodeWithSelector( - L2ToL1MessagePasser.initiateWithdrawal.selector, + IL2ToL1MessagePasser.initiateWithdrawal.selector, address(l1CrossDomainMessenger), l2CrossDomainMessenger.baseGas(hex"ff", 100), xDomainCallData @@ -238,7 +238,7 @@ contract L2CrossDomainMessenger_Test is Bridge_Initializer { vm.expectCall( address(l2ToL1MessagePasser), abi.encodeWithSelector( - L2ToL1MessagePasser.initiateWithdrawal.selector, + IL2ToL1MessagePasser.initiateWithdrawal.selector, address(l1CrossDomainMessenger), l2CrossDomainMessenger.baseGas(hex"ff", 100), xDomainCallData diff --git a/packages/contracts-bedrock/test/L2/L2ERC721Bridge.t.sol b/packages/contracts-bedrock/test/L2/L2ERC721Bridge.t.sol index dc7490bd8136..664655f38a3b 100644 --- a/packages/contracts-bedrock/test/L2/L2ERC721Bridge.t.sol +++ b/packages/contracts-bedrock/test/L2/L2ERC721Bridge.t.sol @@ -7,11 +7,11 @@ import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; // Contracts import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; import { OptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol"; // Interfaces import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; +import { IL2ERC721Bridge } from "src/L2/interfaces/IL2ERC721Bridge.sol"; contract TestERC721 is ERC721 { constructor() ERC721("Test", "TST") { } @@ -97,7 +97,7 @@ contract L2ERC721Bridge_Test is Bridge_Initializer { ( address(l1ERC721Bridge), abi.encodeCall( - L2ERC721Bridge.finalizeBridgeERC721, + IL2ERC721Bridge.finalizeBridgeERC721, (address(remoteToken), address(localToken), alice, alice, tokenId, hex"5678") ), 1234 diff --git a/packages/contracts-bedrock/test/L2/L2StandardBridge.t.sol b/packages/contracts-bedrock/test/L2/L2StandardBridge.t.sol index 6f794c175a25..3a173e9743b4 100644 --- a/packages/contracts-bedrock/test/L2/L2StandardBridge.t.sol +++ b/packages/contracts-bedrock/test/L2/L2StandardBridge.t.sol @@ -1,33 +1,33 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Testing utilities +// Testing +import { stdStorage, StdStorage } from "forge-std/Test.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; - -// Target contract is imported by the `Bridge_Initializer` import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; -import { stdStorage, StdStorage } from "forge-std/Test.sol"; -import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; -import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; + +// Contracts import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; // Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; import { Hashing } from "src/libraries/Hashing.sol"; import { Types } from "src/libraries/Types.sol"; -// Target contract dependencies -import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; -import { Predeploys } from "src/libraries/Predeploys.sol"; -import { StandardBridge } from "src/universal/StandardBridge.sol"; -import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; +// Interfaces +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; +import { IStandardBridge } from "src/universal/interfaces/IStandardBridge.sol"; +import { IL2ToL1MessagePasser } from "src/L2/interfaces/IL2ToL1MessagePasser.sol"; +import { IL2StandardBridge } from "src/L2/interfaces/IL2StandardBridge.sol"; contract L2StandardBridge_Test is Bridge_Initializer { using stdStorage for StdStorage; /// @dev Test that the bridge's constructor sets the correct values. function test_constructor_succeeds() external view { - L2StandardBridge impl = - L2StandardBridge(payable(EIP1967Helper.getImplementation(deploy.mustGetAddress("L2StandardBridge")))); + IL2StandardBridge impl = + IL2StandardBridge(payable(EIP1967Helper.getImplementation(deploy.mustGetAddress("L2StandardBridge")))); // The implementation contract is initialized with a 0 L1 bridge address, // but the L2 cross-domain-messenger is always set to the predeploy address for both proxy and implementation. assertEq(address(impl.MESSENGER()), Predeploys.L2_CROSS_DOMAIN_MESSENGER, "constructor zero check MESSENGER"); @@ -57,7 +57,7 @@ contract L2StandardBridge_Test is Bridge_Initializer { uint256 nonce = l2CrossDomainMessenger.messageNonce(); bytes memory message = - abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 100, hex""); + abi.encodeWithSelector(IStandardBridge.finalizeBridgeETH.selector, alice, alice, 100, hex""); uint64 baseGas = l2CrossDomainMessenger.baseGas(message, 200_000); bytes memory withdrawalData = abi.encodeWithSelector( ICrossDomainMessenger.relayMessage.selector, @@ -118,7 +118,7 @@ contract L2StandardBridge_Test is Bridge_Initializer { vm.expectCall( Predeploys.L2_TO_L1_MESSAGE_PASSER, abi.encodeWithSelector( - L2ToL1MessagePasser.initiateWithdrawal.selector, + IL2ToL1MessagePasser.initiateWithdrawal.selector, address(l1CrossDomainMessenger), baseGas, withdrawalData @@ -278,7 +278,7 @@ contract PreBridgeERC20 is Bridge_Initializer { assertEq(ERC20(_l2Token).balanceOf(alice), 100); uint256 nonce = l2CrossDomainMessenger.messageNonce(); bytes memory message = abi.encodeWithSelector( - StandardBridge.finalizeBridgeERC20.selector, address(L1Token), _l2Token, alice, alice, 100, hex"" + IStandardBridge.finalizeBridgeERC20.selector, address(L1Token), _l2Token, alice, alice, 100, hex"" ); uint64 baseGas = l2CrossDomainMessenger.baseGas(message, 1000); bytes memory withdrawalData = abi.encodeWithSelector( @@ -323,7 +323,7 @@ contract PreBridgeERC20 is Bridge_Initializer { vm.expectCall( Predeploys.L2_TO_L1_MESSAGE_PASSER, abi.encodeWithSelector( - L2ToL1MessagePasser.initiateWithdrawal.selector, + IL2ToL1MessagePasser.initiateWithdrawal.selector, address(l1CrossDomainMessenger), baseGas, withdrawalData @@ -416,7 +416,7 @@ contract PreBridgeERC20To is Bridge_Initializer { assertEq(ERC20(L2Token).balanceOf(alice), 100); uint256 nonce = l2CrossDomainMessenger.messageNonce(); bytes memory message = abi.encodeWithSelector( - StandardBridge.finalizeBridgeERC20.selector, address(L1Token), _l2Token, alice, bob, 100, hex"" + IStandardBridge.finalizeBridgeERC20.selector, address(L1Token), _l2Token, alice, bob, 100, hex"" ); uint64 baseGas = l2CrossDomainMessenger.baseGas(message, 1000); bytes memory withdrawalData = abi.encodeWithSelector( @@ -486,7 +486,7 @@ contract PreBridgeERC20To is Bridge_Initializer { vm.expectCall( Predeploys.L2_TO_L1_MESSAGE_PASSER, abi.encodeWithSelector( - L2ToL1MessagePasser.initiateWithdrawal.selector, + IL2ToL1MessagePasser.initiateWithdrawal.selector, address(l1CrossDomainMessenger), baseGas, withdrawalData @@ -551,7 +551,7 @@ contract L2StandardBridge_Bridge_Test is Bridge_Initializer { uint256 nonce = l2CrossDomainMessenger.messageNonce(); bytes memory message = - abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, _value, _extraData); + abi.encodeWithSelector(IStandardBridge.finalizeBridgeETH.selector, alice, alice, _value, _extraData); vm.expectCall( address(l2StandardBridge), @@ -604,7 +604,7 @@ contract L2StandardBridge_Bridge_Test is Bridge_Initializer { ); bytes memory message = - abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, bob, _value, _extraData); + abi.encodeWithSelector(IStandardBridge.finalizeBridgeETH.selector, alice, bob, _value, _extraData); // the L2 bridge should call // L2CrossDomainMessenger.sendMessage diff --git a/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol b/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol index 8e90cd611d69..db8ca94e37c8 100644 --- a/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol +++ b/packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol @@ -1,23 +1,20 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Target contract is imported by the `Bridge_Initializer` +// Testing import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; -// Target contract dependencies -import { - L2StandardBridgeInterop, - InvalidDecimals, - InvalidLegacyERC20Address, - InvalidSuperchainERC20Address, - InvalidTokenPair, - IOptimismERC20Factory, - MintableAndBurnable -} from "src/L2/L2StandardBridgeInterop.sol"; +// Libraries +// TODO: Replace Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY with optimismSuperchainERC20Factory +import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Interfaces +import { IL2StandardBridgeInterop, IMintableAndBurnable } from "src/L2/interfaces/IL2StandardBridgeInterop.sol"; import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { IOptimismMintableERC20 } from "src/universal/interfaces/IOptimismMintableERC20.sol"; import { ILegacyMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; +import { IOptimismERC20Factory } from "src/L2/interfaces/IOptimismERC20Factory.sol"; contract L2StandardBridgeInterop_Test is Bridge_Initializer { /// @notice Emitted when a conversion is made. @@ -99,7 +96,7 @@ contract L2StandardBridgeInterop_LegacyToSuper_Test is L2StandardBridgeInterop_T _mockDecimals(_to, _decimalsTo); // Expect the revert with `InvalidDecimals` selector - vm.expectRevert(InvalidDecimals.selector); + vm.expectRevert(IL2StandardBridgeInterop.InvalidDecimals.selector); // Act l2StandardBridge.convert(_from, _to, _amount); @@ -114,7 +111,7 @@ contract L2StandardBridgeInterop_LegacyToSuper_Test is L2StandardBridgeInterop_T _mockDeployments(address(l2OptimismMintableERC20Factory), _from, address(0)); // Expect the revert with `InvalidLegacyERC20Address` selector - vm.expectRevert(InvalidLegacyERC20Address.selector); + vm.expectRevert(IL2StandardBridgeInterop.InvalidLegacyERC20Address.selector); // Act l2StandardBridge.convert(_from, _to, _amount); @@ -142,7 +139,7 @@ contract L2StandardBridgeInterop_LegacyToSuper_Test is L2StandardBridgeInterop_T _mockDeployments(address(l2OptimismSuperchainERC20Factory), _to, address(0)); // Expect the revert with `InvalidSuperchainERC20Address` selector - vm.expectRevert(InvalidSuperchainERC20Address.selector); + vm.expectRevert(IL2StandardBridgeInterop.InvalidSuperchainERC20Address.selector); // Act l2StandardBridge.convert(_from, _to, _amount); @@ -173,7 +170,7 @@ contract L2StandardBridgeInterop_LegacyToSuper_Test is L2StandardBridgeInterop_T _mockDeployments(address(l2OptimismSuperchainERC20Factory), _to, _toRemoteToken); // Expect the revert with `InvalidTokenPair` selector - vm.expectRevert(InvalidTokenPair.selector); + vm.expectRevert(IL2StandardBridgeInterop.InvalidTokenPair.selector); // Act l2StandardBridge.convert(_from, _to, _amount); @@ -204,8 +201,10 @@ contract L2StandardBridgeInterop_LegacyToSuper_Test is L2StandardBridgeInterop_T emit Converted(_from, _to, _caller, _amount); // Mock and expect the `burn` and `mint` functions - _mockAndExpect(_from, abi.encodeWithSelector(MintableAndBurnable.burn.selector, _caller, _amount), abi.encode()); - _mockAndExpect(_to, abi.encodeWithSelector(MintableAndBurnable.mint.selector, _caller, _amount), abi.encode()); + _mockAndExpect( + _from, abi.encodeWithSelector(IMintableAndBurnable.burn.selector, _caller, _amount), abi.encode() + ); + _mockAndExpect(_to, abi.encodeWithSelector(IMintableAndBurnable.mint.selector, _caller, _amount), abi.encode()); // Act vm.prank(_caller); @@ -253,7 +252,7 @@ contract L2StandardBridgeInterop_SuperToLegacy_Test is L2StandardBridgeInterop_T _mockDecimals(_to, _decimalsTo); // Expect the revert with `InvalidDecimals` selector - vm.expectRevert(InvalidDecimals.selector); + vm.expectRevert(IL2StandardBridgeInterop.InvalidDecimals.selector); // Act l2StandardBridge.convert(_from, _to, _amount); @@ -268,7 +267,7 @@ contract L2StandardBridgeInterop_SuperToLegacy_Test is L2StandardBridgeInterop_T _mockDeployments(address(l2OptimismMintableERC20Factory), _to, address(0)); // Expect the revert with `InvalidLegacyERC20Address` selector - vm.expectRevert(InvalidLegacyERC20Address.selector); + vm.expectRevert(IL2StandardBridgeInterop.InvalidLegacyERC20Address.selector); // Act l2StandardBridge.convert(_from, _to, _amount); @@ -296,7 +295,7 @@ contract L2StandardBridgeInterop_SuperToLegacy_Test is L2StandardBridgeInterop_T _mockDeployments(address(l2OptimismSuperchainERC20Factory), _from, address(0)); // Expect the revert with `InvalidSuperchainERC20Address` selector - vm.expectRevert(InvalidSuperchainERC20Address.selector); + vm.expectRevert(IL2StandardBridgeInterop.InvalidSuperchainERC20Address.selector); // Act l2StandardBridge.convert(_from, _to, _amount); @@ -327,7 +326,7 @@ contract L2StandardBridgeInterop_SuperToLegacy_Test is L2StandardBridgeInterop_T _mockDeployments(address(l2OptimismSuperchainERC20Factory), _from, _toRemoteToken); // Expect the revert with `InvalidTokenPair` selector - vm.expectRevert(InvalidTokenPair.selector); + vm.expectRevert(IL2StandardBridgeInterop.InvalidTokenPair.selector); // Act l2StandardBridge.convert(_from, _to, _amount); @@ -358,8 +357,10 @@ contract L2StandardBridgeInterop_SuperToLegacy_Test is L2StandardBridgeInterop_T emit Converted(_from, _to, _caller, _amount); // Mock and expect the `burn` and `mint` functions - _mockAndExpect(_from, abi.encodeWithSelector(MintableAndBurnable.burn.selector, _caller, _amount), abi.encode()); - _mockAndExpect(_to, abi.encodeWithSelector(MintableAndBurnable.mint.selector, _caller, _amount), abi.encode()); + _mockAndExpect( + _from, abi.encodeWithSelector(IMintableAndBurnable.burn.selector, _caller, _amount), abi.encode() + ); + _mockAndExpect(_to, abi.encodeWithSelector(IMintableAndBurnable.mint.selector, _caller, _amount), abi.encode()); // Act vm.prank(_caller); diff --git a/packages/contracts-bedrock/test/L2/SequencerFeeVault.t.sol b/packages/contracts-bedrock/test/L2/SequencerFeeVault.t.sol index da01248c585e..1367e00bbc9c 100644 --- a/packages/contracts-bedrock/test/L2/SequencerFeeVault.t.sol +++ b/packages/contracts-bedrock/test/L2/SequencerFeeVault.t.sol @@ -1,24 +1,20 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Testing utilities +// Testing import { CommonTest } from "test/setup/CommonTest.sol"; import { Reverter } from "test/mocks/Callers.sol"; -import { StandardBridge } from "src/universal/StandardBridge.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; -import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; -import { Hashing } from "src/libraries/Hashing.sol"; -import { Types } from "src/libraries/Types.sol"; - -// Libraries -import { Predeploys } from "src/libraries/Predeploys.sol"; -// Target contract dependencies +// Contracts import { FeeVault } from "src/universal/FeeVault.sol"; - -// Target contract import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol"; +// Libraries +import { Hashing } from "src/libraries/Hashing.sol"; +import { Types } from "src/libraries/Types.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; + contract SequencerFeeVault_Test is CommonTest { address recipient; diff --git a/packages/contracts-bedrock/test/setup/Setup.sol b/packages/contracts-bedrock/test/setup/Setup.sol index 8784db7cef09..4af2b8e62618 100644 --- a/packages/contracts-bedrock/test/setup/Setup.sol +++ b/packages/contracts-bedrock/test/setup/Setup.sol @@ -14,16 +14,11 @@ import { OutputMode, Fork, ForkUtils } from "scripts/libraries/Config.sol"; import { Executables } from "scripts/libraries/Executables.sol"; // Contracts -import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol"; -import { L2StandardBridgeInterop } from "src/L2/L2StandardBridgeInterop.sol"; -import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; -import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; import { BaseFeeVault } from "src/L2/BaseFeeVault.sol"; import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol"; import { L1FeeVault } from "src/L2/L1FeeVault.sol"; import { GasPriceOracle } from "src/L2/GasPriceOracle.sol"; import { L1Block } from "src/L2/L1Block.sol"; -import { LegacyMessagePasser } from "src/legacy/LegacyMessagePasser.sol"; import { FeeVault } from "src/universal/FeeVault.sol"; import { WETH } from "src/L2/WETH.sol"; import { SuperchainWETH } from "src/L2/SuperchainWETH.sol"; @@ -48,10 +43,15 @@ import { IDataAvailabilityChallenge } from "src/L1/interfaces/IDataAvailabilityC import { IL1StandardBridge } from "src/L1/interfaces/IL1StandardBridge.sol"; import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol"; import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; +import { IL2CrossDomainMessenger } from "src/L2/interfaces/IL2CrossDomainMessenger.sol"; +import { IL2StandardBridgeInterop } from "src/L2/interfaces/IL2StandardBridgeInterop.sol"; +import { IL2ToL1MessagePasser } from "src/L2/interfaces/IL2ToL1MessagePasser.sol"; +import { IL2ERC721Bridge } from "src/L2/interfaces/IL2ERC721Bridge.sol"; import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol"; import { IAddressManager } from "src/legacy/interfaces/IAddressManager.sol"; import { IOptimismERC20Factory } from "src/L2/interfaces/IOptimismERC20Factory.sol"; import { IGovernanceToken } from "src/governance/interfaces/IGovernanceToken.sol"; +import { ILegacyMessagePasser } from "src/legacy/interfaces/ILegacyMessagePasser.sol"; /// @title Setup /// @dev This contact is responsible for setting up the contracts in state. It currently @@ -92,20 +92,20 @@ contract Setup { IDataAvailabilityChallenge dataAvailabilityChallenge; // L2 contracts - L2CrossDomainMessenger l2CrossDomainMessenger = - L2CrossDomainMessenger(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER)); - L2StandardBridgeInterop l2StandardBridge = L2StandardBridgeInterop(payable(Predeploys.L2_STANDARD_BRIDGE)); - L2ToL1MessagePasser l2ToL1MessagePasser = L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)); + IL2CrossDomainMessenger l2CrossDomainMessenger = + IL2CrossDomainMessenger(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER)); + IL2StandardBridgeInterop l2StandardBridge = IL2StandardBridgeInterop(payable(Predeploys.L2_STANDARD_BRIDGE)); + IL2ToL1MessagePasser l2ToL1MessagePasser = IL2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)); IOptimismMintableERC20Factory l2OptimismMintableERC20Factory = IOptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); - L2ERC721Bridge l2ERC721Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE); + IL2ERC721Bridge l2ERC721Bridge = IL2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE); BaseFeeVault baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT)); SequencerFeeVault sequencerFeeVault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET)); L1FeeVault l1FeeVault = L1FeeVault(payable(Predeploys.L1_FEE_VAULT)); GasPriceOracle gasPriceOracle = GasPriceOracle(Predeploys.GAS_PRICE_ORACLE); L1Block l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES); - LegacyMessagePasser legacyMessagePasser = LegacyMessagePasser(Predeploys.LEGACY_MESSAGE_PASSER); IGovernanceToken governanceToken = IGovernanceToken(Predeploys.GOVERNANCE_TOKEN); + ILegacyMessagePasser legacyMessagePasser = ILegacyMessagePasser(Predeploys.LEGACY_MESSAGE_PASSER); WETH weth = WETH(payable(Predeploys.WETH)); SuperchainWETH superchainWeth = SuperchainWETH(payable(Predeploys.SUPERCHAIN_WETH)); ETHLiquidity ethLiquidity = ETHLiquidity(Predeploys.ETH_LIQUIDITY); diff --git a/packages/contracts-bedrock/test/vendor/Initializable.t.sol b/packages/contracts-bedrock/test/vendor/Initializable.t.sol index f6ef25608e34..c5c8487e2428 100644 --- a/packages/contracts-bedrock/test/vendor/Initializable.t.sol +++ b/packages/contracts-bedrock/test/vendor/Initializable.t.sol @@ -1,26 +1,32 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { LibString } from "@solady/utils/LibString.sol"; +// Testing import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; + +// Scripts import { Executables } from "scripts/libraries/Executables.sol"; -import { Constants } from "src/libraries/Constants.sol"; -import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; -import { StandardBridge } from "src/universal/StandardBridge.sol"; -import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; -import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; -import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; +import { ForgeArtifacts, StorageSlot } from "scripts/libraries/ForgeArtifacts.sol"; +import { Process } from "scripts/libraries/Process.sol"; + +// Contracts import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; + +// Libraries +import { LibString } from "@solady/utils/LibString.sol"; +import { Constants } from "src/libraries/Constants.sol"; import { GameTypes } from "src/dispute/lib/Types.sol"; -import { ForgeArtifacts, StorageSlot } from "scripts/libraries/ForgeArtifacts.sol"; -import { Process } from "scripts/libraries/Process.sol"; -import { ProtocolVersion } from "src/L1/interfaces/IProtocolVersions.sol"; import "src/dispute/lib/Types.sol"; import "scripts/deploy/Deployer.sol"; +// Interfaces +import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; +import { ProtocolVersion } from "src/L1/interfaces/IProtocolVersions.sol"; + /// @title Initializer_Test /// @dev Ensures that the `initialize()` function on contracts cannot be called more than /// once. This contract inherits from `ERC721Bridge_Initializer` because it is the @@ -264,9 +270,7 @@ contract Initializer_Test is Bridge_Initializer { InitializeableContract({ name: "L2CrossDomainMessenger", target: address(l2CrossDomainMessenger), - initCalldata: abi.encodeCall( - l2CrossDomainMessenger.initialize, (CrossDomainMessenger(address(l1CrossDomainMessenger))) - ) + initCalldata: abi.encodeCall(l2CrossDomainMessenger.initialize, (l1CrossDomainMessenger)) }) ); // L1StandardBridgeImpl @@ -275,8 +279,7 @@ contract Initializer_Test is Bridge_Initializer { name: "L1StandardBridge", target: deploy.mustGetAddress("L1StandardBridge"), initCalldata: abi.encodeCall( - l1StandardBridge.initialize, - (ICrossDomainMessenger(address(l1CrossDomainMessenger)), superchainConfig, systemConfig) + l1StandardBridge.initialize, (l1CrossDomainMessenger, superchainConfig, systemConfig) ) }) ); @@ -286,8 +289,7 @@ contract Initializer_Test is Bridge_Initializer { name: "L1StandardBridgeProxy", target: address(l1StandardBridge), initCalldata: abi.encodeCall( - l1StandardBridge.initialize, - (ICrossDomainMessenger(address(l1CrossDomainMessenger)), superchainConfig, systemConfig) + l1StandardBridge.initialize, (l1CrossDomainMessenger, superchainConfig, systemConfig) ) }) ); @@ -296,7 +298,7 @@ contract Initializer_Test is Bridge_Initializer { InitializeableContract({ name: "L2StandardBridge", target: address(l2StandardBridge), - initCalldata: abi.encodeCall(l2StandardBridge.initialize, (StandardBridge(payable(l1StandardBridge)))) + initCalldata: abi.encodeCall(l2StandardBridge.initialize, (l1StandardBridge)) }) ); // L2StandardBridgeInterop @@ -304,7 +306,7 @@ contract Initializer_Test is Bridge_Initializer { InitializeableContract({ name: "L2StandardBridgeInterop", target: address(l2StandardBridge), - initCalldata: abi.encodeCall(l2StandardBridge.initialize, (StandardBridge(payable(l1StandardBridge)))) + initCalldata: abi.encodeCall(l2StandardBridge.initialize, (l1StandardBridge)) }) ); // L1ERC721BridgeImpl @@ -312,9 +314,7 @@ contract Initializer_Test is Bridge_Initializer { InitializeableContract({ name: "L1ERC721Bridge", target: deploy.mustGetAddress("L1ERC721Bridge"), - initCalldata: abi.encodeCall( - l1ERC721Bridge.initialize, (ICrossDomainMessenger(address(l1CrossDomainMessenger)), superchainConfig) - ) + initCalldata: abi.encodeCall(l1ERC721Bridge.initialize, (l1CrossDomainMessenger, superchainConfig)) }) ); // L1ERC721BridgeProxy @@ -322,9 +322,7 @@ contract Initializer_Test is Bridge_Initializer { InitializeableContract({ name: "L1ERC721BridgeProxy", target: address(l1ERC721Bridge), - initCalldata: abi.encodeCall( - l1ERC721Bridge.initialize, (ICrossDomainMessenger(address(l1CrossDomainMessenger)), superchainConfig) - ) + initCalldata: abi.encodeCall(l1ERC721Bridge.initialize, (l1CrossDomainMessenger, superchainConfig)) }) ); // L2ERC721Bridge From c18ec265ebc50dc7c8dcf31531b05395b6532d2e Mon Sep 17 00:00:00 2001 From: yukionfire Date: Thu, 19 Sep 2024 00:45:50 +0800 Subject: [PATCH 189/264] chore(op-service): use `errors.New` to replace `fmt.Errorf` with no parameters (#11796) --- op-service/dial/active_l2_provider_test.go | 15 ++++++++------- op-service/eth/status.go | 5 +++-- op-service/solabi/util.go | 2 +- op-service/sources/batching/batching.go | 3 ++- op-service/sources/batching/test/abi_stub.go | 2 +- op-service/sources/limit_test.go | 8 ++++---- op-service/sources/types.go | 3 ++- op-service/txmgr/txmgr.go | 12 ++++++------ op-service/txmgr/txmgr_test.go | 4 ++-- op-service/util.go | 2 +- 10 files changed, 30 insertions(+), 26 deletions(-) diff --git a/op-service/dial/active_l2_provider_test.go b/op-service/dial/active_l2_provider_test.go index 31d5a6cc6521..1533ab6849ff 100644 --- a/op-service/dial/active_l2_provider_test.go +++ b/op-service/dial/active_l2_provider_test.go @@ -2,6 +2,7 @@ package dial import ( "context" + "errors" "fmt" "testing" "time" @@ -204,7 +205,7 @@ func TestRollupProvider_FailoverOnErroredSequencer(t *testing.T) { require.NoError(t, err) require.Same(t, primarySequencer, firstSequencerUsed) - primarySequencer.ExpectSequencerActive(true, fmt.Errorf("a test error")) // error-out after that + primarySequencer.ExpectSequencerActive(true, errors.New("a test error")) // error-out after that primarySequencer.MaybeClose() secondarySequencer.ExpectSequencerActive(true, nil) secondSequencerUsed, err := rollupProvider.RollupClient(context.Background()) @@ -231,7 +232,7 @@ func TestEndpointProvider_FailoverOnErroredSequencer(t *testing.T) { require.NoError(t, err) require.Same(t, primaryEthClient, firstSequencerUsed) - primarySequencer.ExpectSequencerActive(true, fmt.Errorf("a test error")) // error out after that + primarySequencer.ExpectSequencerActive(true, errors.New("a test error")) // error out after that primarySequencer.MaybeClose() primaryEthClient.MaybeClose() secondarySequencer.ExpectSequencerActive(true, nil) @@ -465,7 +466,7 @@ func TestRollupProvider_ConstructorErrorOnFirstSequencerOffline(t *testing.T) { ept := setupEndpointProviderTest(t, 2) // First sequencer is dead, second sequencer is active - ept.rollupClients[0].ExpectSequencerActive(false, fmt.Errorf("I am offline")) + ept.rollupClients[0].ExpectSequencerActive(false, errors.New("I am offline")) ept.rollupClients[0].MaybeClose() ept.rollupClients[1].ExpectSequencerActive(true, nil) @@ -482,7 +483,7 @@ func TestEndpointProvider_ConstructorErrorOnFirstSequencerOffline(t *testing.T) ept := setupEndpointProviderTest(t, 2) // First sequencer is dead, second sequencer is active - ept.rollupClients[0].ExpectSequencerActive(false, fmt.Errorf("I am offline")) + ept.rollupClients[0].ExpectSequencerActive(false, errors.New("I am offline")) ept.rollupClients[0].MaybeClose() ept.rollupClients[1].ExpectSequencerActive(true, nil) ept.rollupClients[1].ExpectSequencerActive(true, nil) // see comment in other tests about why we expect this twice @@ -533,7 +534,7 @@ func TestRollupProvider_FailOnAllErroredSequencers(t *testing.T) { // All sequencers are inactive for _, sequencer := range ept.rollupClients { - sequencer.ExpectSequencerActive(true, fmt.Errorf("a test error")) + sequencer.ExpectSequencerActive(true, errors.New("a test error")) sequencer.MaybeClose() } @@ -549,7 +550,7 @@ func TestEndpointProvider_FailOnAllErroredSequencers(t *testing.T) { // All sequencers are inactive for _, sequencer := range ept.rollupClients { - sequencer.ExpectSequencerActive(true, fmt.Errorf("a test error")) + sequencer.ExpectSequencerActive(true, errors.New("a test error")) sequencer.MaybeClose() } @@ -711,7 +712,7 @@ func TestRollupProvider_HandlesManyIndexClientMismatch(t *testing.T) { require.NoError(t, err) // primarySequencer goes down - seq0.ExpectSequencerActive(false, fmt.Errorf("I'm offline now")) + seq0.ExpectSequencerActive(false, errors.New("I'm offline now")) seq0.MaybeClose() ept.setRollupDialOutcome(0, false) // primarySequencer fails to dial // secondarySequencer is inactive, but online diff --git a/op-service/eth/status.go b/op-service/eth/status.go index 3baab5725f26..52e2e9c58cc4 100644 --- a/op-service/eth/status.go +++ b/op-service/eth/status.go @@ -1,18 +1,19 @@ package eth import ( + "errors" "fmt" ) func ForkchoiceUpdateErr(payloadStatus PayloadStatusV1) error { switch payloadStatus.Status { case ExecutionSyncing: - return fmt.Errorf("updated forkchoice, but node is syncing") + return errors.New("updated forkchoice, but node is syncing") case ExecutionAccepted, ExecutionInvalidTerminalBlock, ExecutionInvalidBlockHash: // ACCEPTED, INVALID_TERMINAL_BLOCK, INVALID_BLOCK_HASH are only for execution return fmt.Errorf("unexpected %s status, could not update forkchoice", payloadStatus.Status) case ExecutionInvalid: - return fmt.Errorf("cannot update forkchoice, block is invalid") + return errors.New("cannot update forkchoice, block is invalid") case ExecutionValid: return nil default: diff --git a/op-service/solabi/util.go b/op-service/solabi/util.go index ce26aaf76c58..41c01106a323 100644 --- a/op-service/solabi/util.go +++ b/op-service/solabi/util.go @@ -69,7 +69,7 @@ func ReadUint64(r io.Reader) (uint64, error) { return n, fmt.Errorf("number padding was not empty: %x", readPadding[:]) } if err := binary.Read(r, binary.BigEndian, &n); err != nil { - return 0, fmt.Errorf("expected number length to be 8 bytes") + return 0, errors.New("expected number length to be 8 bytes") } return n, nil } diff --git a/op-service/sources/batching/batching.go b/op-service/sources/batching/batching.go index 0cf88f702704..50fd76da9452 100644 --- a/op-service/sources/batching/batching.go +++ b/op-service/sources/batching/batching.go @@ -2,6 +2,7 @@ package batching import ( "context" + "errors" "fmt" "io" "sync" @@ -176,7 +177,7 @@ func (ibc *IterativeBatchCall[K, V]) Result() ([]V, error) { ibc.resetLock.RLock() if atomic.LoadUint32(&ibc.completed) < uint32(len(ibc.requestsKeys)) { ibc.resetLock.RUnlock() - return nil, fmt.Errorf("results not available yet, Fetch more first") + return nil, errors.New("results not available yet, Fetch more first") } ibc.resetLock.RUnlock() return ibc.requestsValues, nil diff --git a/op-service/sources/batching/test/abi_stub.go b/op-service/sources/batching/test/abi_stub.go index 12b9aecebf2d..431c77c8dbd4 100644 --- a/op-service/sources/batching/test/abi_stub.go +++ b/op-service/sources/batching/test/abi_stub.go @@ -35,7 +35,7 @@ func (c *expectedCall) Matches(rpcMethod string, args ...interface{}) error { } callOpts, ok := args[0].(map[string]any) if !ok { - return fmt.Errorf("arg 0 is not a map[string]any") + return errors.New("arg 0 is not a map[string]any") } actualBlockRef := args[1] to, ok := callOpts["to"].(*common.Address) diff --git a/op-service/sources/limit_test.go b/op-service/sources/limit_test.go index ed59e0287ec1..5bea12046779 100644 --- a/op-service/sources/limit_test.go +++ b/op-service/sources/limit_test.go @@ -2,7 +2,7 @@ package sources import ( "context" - "fmt" + "errors" "net" "sync/atomic" "testing" @@ -97,10 +97,10 @@ func TestLimitClient(t *testing.T) { // None of the clients should return yet } - m.errC <- fmt.Errorf("fake-error") - m.errC <- fmt.Errorf("fake-error") + m.errC <- errors.New("fake-error") + m.errC <- errors.New("fake-error") require.Eventually(t, func() bool { return m.blockedCallers.Load() == 1 }, time.Second, 10*time.Millisecond) - m.errC <- fmt.Errorf("fake-error") + m.errC <- errors.New("fake-error") require.ErrorContains(t, <-errC1, "fake-error") require.ErrorContains(t, <-errC2, "fake-error") diff --git a/op-service/sources/types.go b/op-service/sources/types.go index afb994bd7cc3..f337beb02058 100644 --- a/op-service/sources/types.go +++ b/op-service/sources/types.go @@ -1,6 +1,7 @@ package sources import ( + "errors" "fmt" "math/big" "strings" @@ -229,7 +230,7 @@ func (block *RPCBlock) verify() error { } if block.WithdrawalsRoot != nil { if block.Withdrawals == nil { - return fmt.Errorf("expected withdrawals") + return errors.New("expected withdrawals") } for i, w := range *block.Withdrawals { if w == nil { diff --git a/op-service/txmgr/txmgr.go b/op-service/txmgr/txmgr.go index fac48cf55ce0..f8605f75322b 100644 --- a/op-service/txmgr/txmgr.go +++ b/op-service/txmgr/txmgr.go @@ -376,7 +376,7 @@ func (m *SimpleTxManager) craftTx(ctx context.Context, candidate TxCandidate) (* var txMessage types.TxData if sidecar != nil { if blobBaseFee == nil { - return nil, fmt.Errorf("expected non-nil blobBaseFee") + return nil, errors.New("expected non-nil blobBaseFee") } blobFeeCap := m.calcBlobFeeCap(blobBaseFee) message := &types.BlobTx{ @@ -1036,19 +1036,19 @@ func errStringMatch(err, target error) bool { func finishBlobTx(message *types.BlobTx, chainID, tip, fee, blobFee, value *big.Int) error { var o bool if message.ChainID, o = uint256.FromBig(chainID); o { - return fmt.Errorf("ChainID overflow") + return errors.New("ChainID overflow") } if message.GasTipCap, o = uint256.FromBig(tip); o { - return fmt.Errorf("GasTipCap overflow") + return errors.New("GasTipCap overflow") } if message.GasFeeCap, o = uint256.FromBig(fee); o { - return fmt.Errorf("GasFeeCap overflow") + return errors.New("GasFeeCap overflow") } if message.BlobFeeCap, o = uint256.FromBig(blobFee); o { - return fmt.Errorf("BlobFeeCap overflow") + return errors.New("BlobFeeCap overflow") } if message.Value, o = uint256.FromBig(value); o { - return fmt.Errorf("Value overflow") + return errors.New("Value overflow") } return nil } diff --git a/op-service/txmgr/txmgr_test.go b/op-service/txmgr/txmgr_test.go index e451597cd129..6bafa69464b6 100644 --- a/op-service/txmgr/txmgr_test.go +++ b/op-service/txmgr/txmgr_test.go @@ -669,7 +669,7 @@ func TestTxMgr_EstimateGasFails(t *testing.T) { lastNonce := tx.Nonce() // Mock gas estimation failure. - h.gasPricer.err = fmt.Errorf("execution error") + h.gasPricer.err = errors.New("execution error") _, err = h.mgr.craftTx(context.Background(), candidate) require.ErrorContains(t, err, "failed to estimate gas") @@ -686,7 +686,7 @@ func TestTxMgr_SigningFails(t *testing.T) { cfg := configWithNumConfs(1) cfg.Signer = func(ctx context.Context, from common.Address, tx *types.Transaction) (*types.Transaction, error) { if errorSigning { - return nil, fmt.Errorf("signer error") + return nil, errors.New("signer error") } else { return tx, nil } diff --git a/op-service/util.go b/op-service/util.go index e9dae2ec033f..26960a911c6b 100644 --- a/op-service/util.go +++ b/op-service/util.go @@ -130,5 +130,5 @@ func FindMonorepoRoot(startDir string) (string, error) { } dir = parentDir } - return "", fmt.Errorf("monorepo root not found") + return "", errors.New("monorepo root not found") } From 606e023053232cfc5d96fefae87e2349a7631959 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Wed, 18 Sep 2024 11:58:17 -0600 Subject: [PATCH 190/264] fix(ci): semgrep cli breaking change (#11985) Semgrep CLI tool recently removed the --time option which caused CI to suddenly break. --- .circleci/config.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8e4a477cbba9..e0c54fce2dd3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1397,11 +1397,10 @@ jobs: echo 'export SEMGREP_REPO_NAME=$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME' >> $BASH_ENV - run: name: "Semgrep scan" - # --time shows which rules take the most time # --timeout (in seconds) limits the time per rule and file. # SEMGREP_TIMEOUT is the same, but docs have conflicting defaults (5s in CLI flag, 1800 in some places) # https://semgrep.dev/docs/troubleshooting/semgrep-app#if-the-job-is-aborted-due-to-taking-too-long - command: semgrep ci --time --timeout=100 + command: semgrep ci --timeout=100 # If semgrep hangs, stop the scan after 20m, to prevent a useless 5h job no_output_timeout: 20m - notify-failures-on-develop From 5fe7df248e27d1ef466fd7a767f59f0be1ed144e Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Wed, 18 Sep 2024 13:10:38 -0600 Subject: [PATCH 191/264] ci: correct perms for tag-service.yml (#11961) GITHUB_TOKEN no longer gets write access by default so it needs to be provided with write access explicitly. --- .github/workflows/tag-service.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/tag-service.yml b/.github/workflows/tag-service.yml index 42e06c9debb9..439b48f13d4e 100644 --- a/.github/workflows/tag-service.yml +++ b/.github/workflows/tag-service.yml @@ -36,6 +36,9 @@ on: type: boolean default: false +permissions: + contents: write + jobs: release: runs-on: ubuntu-latest From 213f7627da4ee053f15d746119af2c8304ec3134 Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Wed, 18 Sep 2024 15:02:58 -0600 Subject: [PATCH 192/264] Add inspection commands, fix deployer bugs (#11964) Adds `op-deployer inspection *` commands to expose the generated genesis and rollup configs via the CLI or Golang libraries. Also fixes a bug in deployment - I accidentally deleted the code that set the deployer nonce, so live chain deployments were reverting. --- op-chain-ops/cmd/op-deployer/main.go | 7 + op-chain-ops/deployer/apply.go | 6 + op-chain-ops/deployer/inspect/flags.go | 117 +++++++++++++ op-chain-ops/deployer/inspect/genesis.go | 57 +++++++ op-chain-ops/deployer/inspect/rollup.go | 90 ++++++++++ op-chain-ops/deployer/pipeline/host.go | 6 + op-chain-ops/deployer/pipeline/l2genesis.go | 9 +- op-chain-ops/deployer/state/deploy_config.go | 158 ++++++++++++++++++ .../deployer/state/deploy_config_test.go | 36 ++++ op-chain-ops/deployer/state/intent.go | 4 +- .../deployer/state/l2_initialization.go | 127 -------------- op-chain-ops/deployer/state/state.go | 22 +++ op-chain-ops/foundry/allocs.go | 4 + op-chain-ops/foundry/allocs_test.go | 23 +++ op-chain-ops/genesis/config.go | 45 ++--- op-chain-ops/genesis/genesis.go | 22 +-- op-chain-ops/genesis/layer_two.go | 2 +- .../testdata/test-deploy-config-full.json | 1 + op-chain-ops/interopgen/deploy.go | 4 +- op-e2e/e2eutils/setup.go | 2 +- op-e2e/opgeth/op_geth.go | 4 +- op-e2e/system/e2esys/setup.go | 2 +- op-node/cmd/genesis/cmd.go | 4 +- op-program/client/l2/engine_backend_test.go | 2 +- 24 files changed, 583 insertions(+), 171 deletions(-) create mode 100644 op-chain-ops/deployer/inspect/flags.go create mode 100644 op-chain-ops/deployer/inspect/genesis.go create mode 100644 op-chain-ops/deployer/inspect/rollup.go create mode 100644 op-chain-ops/deployer/state/deploy_config.go create mode 100644 op-chain-ops/deployer/state/deploy_config_test.go delete mode 100644 op-chain-ops/deployer/state/l2_initialization.go diff --git a/op-chain-ops/cmd/op-deployer/main.go b/op-chain-ops/cmd/op-deployer/main.go index dd176f40bea2..cb5dae586acf 100644 --- a/op-chain-ops/cmd/op-deployer/main.go +++ b/op-chain-ops/cmd/op-deployer/main.go @@ -4,6 +4,8 @@ import ( "fmt" "os" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/inspect" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer" "github.com/ethereum-optimism/optimism/op-service/cliapp" "github.com/urfave/cli/v2" @@ -27,6 +29,11 @@ func main() { Flags: cliapp.ProtectFlags(deployer.ApplyFlags), Action: deployer.ApplyCLI(), }, + { + Name: "inspect", + Usage: "inspects the state of a deployment", + Subcommands: inspect.Commands, + }, } app.Writer = os.Stdout app.ErrWriter = os.Stderr diff --git a/op-chain-ops/deployer/apply.go b/op-chain-ops/deployer/apply.go index c3b374aa129e..27de5af4b2ff 100644 --- a/op-chain-ops/deployer/apply.go +++ b/op-chain-ops/deployer/apply.go @@ -162,5 +162,11 @@ func ApplyPipeline( return fmt.Errorf("error in pipeline stage: %w", err) } } + + st.AppliedIntent = intent + if err := env.WriteState(st); err != nil { + return fmt.Errorf("failed to write state: %w", err) + } + return nil } diff --git a/op-chain-ops/deployer/inspect/flags.go b/op-chain-ops/deployer/inspect/flags.go new file mode 100644 index 000000000000..ad3ea679b824 --- /dev/null +++ b/op-chain-ops/deployer/inspect/flags.go @@ -0,0 +1,117 @@ +package inspect + +import ( + "fmt" + + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/pipeline" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" + "github.com/ethereum/go-ethereum/common" + "github.com/urfave/cli/v2" +) + +const ( + OutfileFlagName = "outfile" +) + +var ( + FlagOutfile = &cli.StringFlag{ + Name: OutfileFlagName, + Usage: "output file. set to - to use stdout", + Value: "-", + } +) + +var Flags = []cli.Flag{ + deployer.WorkdirFlag, + FlagOutfile, +} + +var Commands = []*cli.Command{ + { + Name: "genesis", + Usage: "outputs the genesis for an L2 chain", + Args: true, + ArgsUsage: "", + Action: GenesisCLI, + Flags: Flags, + }, + { + Name: "rollup", + Usage: "outputs the rollup config for an L2 chain", + Args: true, + ArgsUsage: "", + Action: RollupCLI, + Flags: Flags, + }, +} + +type cliConfig struct { + Workdir string + Outfile string + ChainID common.Hash +} + +func readConfig(cliCtx *cli.Context) (cliConfig, error) { + var cfg cliConfig + + outfile := cliCtx.String(OutfileFlagName) + if outfile == "" { + return cfg, fmt.Errorf("outfile flag is required") + } + + workdir := cliCtx.String(deployer.WorkdirFlagName) + if workdir == "" { + return cfg, fmt.Errorf("workdir flag is required") + } + + chainIDStr := cliCtx.Args().First() + if chainIDStr == "" { + return cfg, fmt.Errorf("chain-id argument is required") + } + + chainID, err := chainIDStrToHash(chainIDStr) + if err != nil { + return cfg, fmt.Errorf("failed to parse chain ID: %w", err) + } + + return cliConfig{ + Workdir: cliCtx.String(deployer.WorkdirFlagName), + Outfile: cliCtx.String(OutfileFlagName), + ChainID: chainID, + }, nil +} + +type inspectState struct { + GlobalState *state.State + ChainIntent *state.ChainIntent + ChainState *state.ChainState +} + +func bootstrapState(cfg cliConfig) (*inspectState, error) { + env := &pipeline.Env{Workdir: cfg.Workdir} + globalState, err := env.ReadState() + if err != nil { + return nil, fmt.Errorf("failed to read intent: %w", err) + } + + if globalState.AppliedIntent == nil { + return nil, fmt.Errorf("chain state is not applied - run op-deployer apply") + } + + chainIntent, err := globalState.AppliedIntent.Chain(cfg.ChainID) + if err != nil { + return nil, fmt.Errorf("failed to get applied chain intent: %w", err) + } + + chainState, err := globalState.Chain(cfg.ChainID) + if err != nil { + return nil, fmt.Errorf("failed to get chain ID %s: %w", cfg.ChainID.String(), err) + } + + return &inspectState{ + GlobalState: globalState, + ChainIntent: chainIntent, + ChainState: chainState, + }, nil +} diff --git a/op-chain-ops/deployer/inspect/genesis.go b/op-chain-ops/deployer/inspect/genesis.go new file mode 100644 index 000000000000..7e2f13b6d672 --- /dev/null +++ b/op-chain-ops/deployer/inspect/genesis.go @@ -0,0 +1,57 @@ +package inspect + +import ( + "fmt" + "math/big" + "strconv" + "strings" + + "github.com/ethereum-optimism/optimism/op-service/ioutil" + "github.com/ethereum-optimism/optimism/op-service/jsonutil" + "github.com/ethereum/go-ethereum/common" + "github.com/urfave/cli/v2" +) + +func GenesisCLI(cliCtx *cli.Context) error { + cfg, err := readConfig(cliCtx) + if err != nil { + return err + } + + st, err := bootstrapState(cfg) + if err != nil { + return err + } + + genesis, err := st.ChainState.UnmarshalGenesis() + if err != nil { + return fmt.Errorf("failed to unmarshal genesis: %w", err) + } + + if err := jsonutil.WriteJSON(genesis, ioutil.ToStdOutOrFileOrNoop(cfg.Outfile, 0o666)); err != nil { + return fmt.Errorf("failed to write genesis: %w", err) + } + + return nil +} + +func chainIDStrToHash(in string) (common.Hash, error) { + var chainIDBig *big.Int + if strings.HasPrefix(in, "0x") { + in = strings.TrimPrefix(in, "0x") + var ok bool + chainIDBig, ok = new(big.Int).SetString(in, 16) + if !ok { + return common.Hash{}, fmt.Errorf("failed to parse chain ID %s", in) + } + } else { + inUint, err := strconv.ParseUint(in, 10, 64) + if err != nil { + return common.Hash{}, fmt.Errorf("failed to parse chain ID %s: %w", in, err) + } + + chainIDBig = new(big.Int).SetUint64(inUint) + } + + return common.BigToHash(chainIDBig), nil +} diff --git a/op-chain-ops/deployer/inspect/rollup.go b/op-chain-ops/deployer/inspect/rollup.go new file mode 100644 index 000000000000..8d9d39e1c49c --- /dev/null +++ b/op-chain-ops/deployer/inspect/rollup.go @@ -0,0 +1,90 @@ +package inspect + +import ( + "fmt" + + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/pipeline" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" + "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/ioutil" + "github.com/ethereum-optimism/optimism/op-service/jsonutil" + "github.com/ethereum/go-ethereum/common" + "github.com/urfave/cli/v2" +) + +func RollupCLI(cliCtx *cli.Context) error { + cfg, err := readConfig(cliCtx) + if err != nil { + return err + } + + env := &pipeline.Env{Workdir: cfg.Workdir} + globalState, err := env.ReadState() + if err != nil { + return fmt.Errorf("failed to read intent: %w", err) + } + + rollupConfig, err := Rollup(globalState, cfg.ChainID) + if err != nil { + return fmt.Errorf("failed to generate rollup config: %w", err) + } + + if err := jsonutil.WriteJSON(rollupConfig, ioutil.ToStdOutOrFileOrNoop(cfg.Outfile, 0o666)); err != nil { + return fmt.Errorf("failed to write rollup config: %w", err) + } + + return nil +} + +func Rollup(globalState *state.State, chainID common.Hash) (*rollup.Config, error) { + if globalState.AppliedIntent == nil { + return nil, fmt.Errorf("chain state is not applied - run op-deployer apply") + } + + chainIntent, err := globalState.AppliedIntent.Chain(chainID) + if err != nil { + return nil, fmt.Errorf("failed to get applied chain intent: %w", err) + } + + chainState, err := globalState.Chain(chainID) + if err != nil { + return nil, fmt.Errorf("failed to get chain ID %s: %w", chainID.String(), err) + } + + l2Allocs, err := chainState.UnmarshalGenesis() + if err != nil { + return nil, fmt.Errorf("failed to unmarshal genesis: %w", err) + } + + config, err := state.CombineDeployConfig( + globalState.AppliedIntent, + chainIntent, + globalState, + chainState, + ) + if err != nil { + return nil, fmt.Errorf("failed to combine L2 init config: %w", err) + } + + l2GenesisBuilt, err := genesis.BuildL2Genesis(&config, l2Allocs, chainState.StartBlock) + if err != nil { + return nil, fmt.Errorf("failed to build L2 genesis: %w", err) + } + l2GenesisBlock := l2GenesisBuilt.ToBlock() + + rollupConfig, err := config.RollupConfig( + chainState.StartBlock, + l2GenesisBlock.Hash(), + l2GenesisBlock.Number().Uint64(), + ) + if err != nil { + return nil, fmt.Errorf("failed to build rollup config: %w", err) + } + + if err := rollupConfig.Check(); err != nil { + return nil, fmt.Errorf("generated rollup config does not pass validation: %w", err) + } + + return rollupConfig, nil +} diff --git a/op-chain-ops/deployer/pipeline/host.go b/op-chain-ops/deployer/pipeline/host.go index abea4e9499df..71bc9e29e05c 100644 --- a/op-chain-ops/deployer/pipeline/host.go +++ b/op-chain-ops/deployer/pipeline/host.go @@ -68,6 +68,12 @@ func CallScriptBroadcast( return fmt.Errorf("failed to enable cheats: %w", err) } + nonce, err := opts.Client.NonceAt(ctx, opts.Deployer, nil) + if err != nil { + return fmt.Errorf("failed to fetch nonce: %w", err) + } + h.SetNonce(opts.Deployer, nonce) + err = opts.Handler(h) if err != nil { return fmt.Errorf("failed to run handler: %w", err) diff --git a/op-chain-ops/deployer/pipeline/l2genesis.go b/op-chain-ops/deployer/pipeline/l2genesis.go index b7f35d216324..95613fada912 100644 --- a/op-chain-ops/deployer/pipeline/l2genesis.go +++ b/op-chain-ops/deployer/pipeline/l2genesis.go @@ -40,7 +40,7 @@ func GenerateL2Genesis(ctx context.Context, env *Env, intent *state.Intent, st * return fmt.Errorf("failed to get chain state: %w", err) } - initCfg, err := state.CombineL2InitConfig(intent, thisIntent) + initCfg, err := state.CombineDeployConfig(intent, thisIntent, st, thisChainState) if err != nil { return fmt.Errorf("failed to combine L2 init config: %w", err) } @@ -63,7 +63,7 @@ func GenerateL2Genesis(ctx context.Context, env *Env, intent *state.Intent, st * L1StandardBridgeProxy: thisChainState.L1StandardBridgeProxyAddress, L1ERC721BridgeProxy: thisChainState.L1ERC721BridgeProxyAddress, }, - L2Config: initCfg, + L2Config: initCfg.L2InitializationConfig, }) if err != nil { return fmt.Errorf("failed to call L2Genesis script: %w", err) @@ -93,6 +93,11 @@ func GenerateL2Genesis(ctx context.Context, env *Env, intent *state.Intent, st * return fmt.Errorf("failed to close gzip writer: %w", err) } thisChainState.Genesis = buf.Bytes() + startHeader, err := env.L1Client.HeaderByNumber(ctx, nil) + if err != nil { + return fmt.Errorf("failed to get start block: %w", err) + } + thisChainState.StartBlock = startHeader if err := env.WriteState(st); err != nil { return fmt.Errorf("failed to write state: %w", err) diff --git a/op-chain-ops/deployer/state/deploy_config.go b/op-chain-ops/deployer/state/deploy_config.go new file mode 100644 index 000000000000..81801e5865cb --- /dev/null +++ b/op-chain-ops/deployer/state/deploy_config.go @@ -0,0 +1,158 @@ +package state + +import ( + "encoding/json" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + + "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" + "github.com/ethereum/go-ethereum/common/hexutil" +) + +var ( + l2GenesisBlockBaseFeePerGas = hexutil.Big(*(big.NewInt(1000000000))) + + vaultMinWithdrawalAmount = mustHexBigFromHex("0x8ac7230489e80000") +) + +func DefaultDeployConfig() genesis.DeployConfig { + return genesis.DeployConfig{ + L2InitializationConfig: genesis.L2InitializationConfig{ + L2GenesisBlockDeployConfig: genesis.L2GenesisBlockDeployConfig{ + L2GenesisBlockGasLimit: 30_000_000, + L2GenesisBlockBaseFeePerGas: &l2GenesisBlockBaseFeePerGas, + }, + L2VaultsDeployConfig: genesis.L2VaultsDeployConfig{ + BaseFeeVaultWithdrawalNetwork: "local", + L1FeeVaultWithdrawalNetwork: "local", + SequencerFeeVaultWithdrawalNetwork: "local", + SequencerFeeVaultMinimumWithdrawalAmount: vaultMinWithdrawalAmount, + BaseFeeVaultMinimumWithdrawalAmount: vaultMinWithdrawalAmount, + L1FeeVaultMinimumWithdrawalAmount: vaultMinWithdrawalAmount, + }, + GovernanceDeployConfig: genesis.GovernanceDeployConfig{ + EnableGovernance: true, + GovernanceTokenSymbol: "OP", + GovernanceTokenName: "Optimism", + }, + GasPriceOracleDeployConfig: genesis.GasPriceOracleDeployConfig{ + GasPriceOracleBaseFeeScalar: 1368, + GasPriceOracleBlobBaseFeeScalar: 810949, + }, + EIP1559DeployConfig: genesis.EIP1559DeployConfig{ + EIP1559Denominator: 50, + EIP1559DenominatorCanyon: 250, + EIP1559Elasticity: 6, + }, + UpgradeScheduleDeployConfig: genesis.UpgradeScheduleDeployConfig{ + L2GenesisRegolithTimeOffset: u64UtilPtr(0), + L2GenesisCanyonTimeOffset: u64UtilPtr(0), + L2GenesisDeltaTimeOffset: u64UtilPtr(0), + L2GenesisEcotoneTimeOffset: u64UtilPtr(0), + L2GenesisFjordTimeOffset: u64UtilPtr(0), + L2GenesisGraniteTimeOffset: u64UtilPtr(0), + UseInterop: false, + }, + L2CoreDeployConfig: genesis.L2CoreDeployConfig{ + L2BlockTime: 2, + FinalizationPeriodSeconds: 12, + MaxSequencerDrift: 600, + SequencerWindowSize: 3600, + ChannelTimeoutBedrock: 300, + SystemConfigStartBlock: 0, + }, + }, + } +} + +func CombineDeployConfig(intent *Intent, chainIntent *ChainIntent, state *State, chainState *ChainState) (genesis.DeployConfig, error) { + cfg := DefaultDeployConfig() + + var err error + if len(intent.GlobalDeployOverrides) > 0 { + cfg, err = mergeJSON(cfg, intent.GlobalDeployOverrides) + if err != nil { + return genesis.DeployConfig{}, fmt.Errorf("error merging global L2 overrides: %w", err) + + } + } + + if len(chainIntent.DeployOverrides) > 0 { + cfg, err = mergeJSON(cfg, chainIntent.DeployOverrides) + if err != nil { + return genesis.DeployConfig{}, fmt.Errorf("error merging chain L2 overrides: %w", err) + } + } + + cfg.L2ChainID = chainState.ID.Big().Uint64() + cfg.L1DependenciesConfig = genesis.L1DependenciesConfig{ + L1StandardBridgeProxy: chainState.L1StandardBridgeProxyAddress, + L1CrossDomainMessengerProxy: chainState.L1CrossDomainMessengerProxyAddress, + L1ERC721BridgeProxy: chainState.L1ERC721BridgeProxyAddress, + SystemConfigProxy: chainState.SystemConfigProxyAddress, + OptimismPortalProxy: chainState.OptimismPortalProxyAddress, + ProtocolVersionsProxy: state.SuperchainDeployment.ProtocolVersionsProxyAddress, + } + cfg.OperatorDeployConfig = genesis.OperatorDeployConfig{ + BatchSenderAddress: chainIntent.Roles.Batcher, + P2PSequencerAddress: chainIntent.Roles.UnsafeBlockSigner, + } + cfg.BatchInboxAddress = calculateBatchInboxAddr(chainState.ID) + cfg.L1ChainID = intent.L1ChainID + + return cfg, nil +} + +// mergeJSON merges the provided overrides into the input struct. Fields +// must be JSON-serializable for this to work. Overrides are applied in +// order of precedence - i.e., the last overrides will override keys from +// all preceding overrides. +func mergeJSON[T any](in T, overrides ...map[string]any) (T, error) { + var out T + inJSON, err := json.Marshal(in) + if err != nil { + return out, err + } + + var tmpMap map[string]interface{} + if err := json.Unmarshal(inJSON, &tmpMap); err != nil { + return out, err + } + + for _, override := range overrides { + for k, v := range override { + tmpMap[k] = v + } + } + + inJSON, err = json.Marshal(tmpMap) + if err != nil { + return out, err + } + + if err := json.Unmarshal(inJSON, &out); err != nil { + return out, err + } + + return out, nil +} + +func mustHexBigFromHex(hex string) *hexutil.Big { + num := hexutil.MustDecodeBig(hex) + hexBig := hexutil.Big(*num) + return &hexBig +} + +func u64UtilPtr(in uint64) *hexutil.Uint64 { + util := hexutil.Uint64(in) + return &util +} + +func calculateBatchInboxAddr(chainID common.Hash) common.Address { + var out common.Address + copy(out[1:], crypto.Keccak256(chainID[:])[:19]) + return out +} diff --git a/op-chain-ops/deployer/state/deploy_config_test.go b/op-chain-ops/deployer/state/deploy_config_test.go new file mode 100644 index 000000000000..be431b5740ce --- /dev/null +++ b/op-chain-ops/deployer/state/deploy_config_test.go @@ -0,0 +1,36 @@ +package state + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestMergeJSON(t *testing.T) { + type testStruct struct { + A string `json:"a"` + B int `json:"b"` + C bool `json:"c"` + } + + out, err := mergeJSON( + testStruct{ + "hello", + 42, + true, + }, + map[string]any{ + "a": "world", + "c": false, + }, + map[string]any{ + "d": "shouldn't show up", + }, + ) + require.NoError(t, err) + require.EqualValues(t, out, testStruct{ + "world", + 42, + false, + }) +} diff --git a/op-chain-ops/deployer/state/intent.go b/op-chain-ops/deployer/state/intent.go index 718026739945..5b91dbbf7c13 100644 --- a/op-chain-ops/deployer/state/intent.go +++ b/op-chain-ops/deployer/state/intent.go @@ -26,7 +26,7 @@ type Intent struct { Chains []*ChainIntent `json:"chains" toml:"chains"` - GlobalInitOverrides map[string]any `json:"globalInitOverrides" toml:"globalInitOverrides"` + GlobalDeployOverrides map[string]any `json:"globalDeployOverrides" toml:"globalDeployOverrides"` } func (c *Intent) L1ChainIDBig() *big.Int { @@ -92,7 +92,7 @@ type ChainIntent struct { Roles ChainRoles `json:"roles" toml:"roles"` - InitOverrides map[string]any `json:"initOverrides" toml:"initOverrides"` + DeployOverrides map[string]any `json:"deployOverrides" toml:"deployOverrides"` } type ChainRoles struct { diff --git a/op-chain-ops/deployer/state/l2_initialization.go b/op-chain-ops/deployer/state/l2_initialization.go deleted file mode 100644 index 9baf98fec0cc..000000000000 --- a/op-chain-ops/deployer/state/l2_initialization.go +++ /dev/null @@ -1,127 +0,0 @@ -package state - -import ( - "encoding/json" - "fmt" - "math/big" - - "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" - "github.com/ethereum/go-ethereum/common/hexutil" -) - -var ( - l2GenesisBlockBaseFeePerGas = hexutil.Big(*(big.NewInt(1000000000))) - - vaultMinWithdrawalAmount = mustHexBigFromHex("0x8ac7230489e80000") -) - -func DefaultL2InitConfig() genesis.L2InitializationConfig { - return genesis.L2InitializationConfig{ - L2GenesisBlockDeployConfig: genesis.L2GenesisBlockDeployConfig{ - L2GenesisBlockGasLimit: 30_000_000, - L2GenesisBlockBaseFeePerGas: &l2GenesisBlockBaseFeePerGas, - }, - L2VaultsDeployConfig: genesis.L2VaultsDeployConfig{ - BaseFeeVaultWithdrawalNetwork: "local", - L1FeeVaultWithdrawalNetwork: "local", - SequencerFeeVaultWithdrawalNetwork: "local", - SequencerFeeVaultMinimumWithdrawalAmount: vaultMinWithdrawalAmount, - BaseFeeVaultMinimumWithdrawalAmount: vaultMinWithdrawalAmount, - L1FeeVaultMinimumWithdrawalAmount: vaultMinWithdrawalAmount, - }, - GovernanceDeployConfig: genesis.GovernanceDeployConfig{ - EnableGovernance: true, - GovernanceTokenSymbol: "OP", - GovernanceTokenName: "Optimism", - }, - GasPriceOracleDeployConfig: genesis.GasPriceOracleDeployConfig{ - GasPriceOracleBaseFeeScalar: 0, - GasPriceOracleBlobBaseFeeScalar: 1000000, - }, - EIP1559DeployConfig: genesis.EIP1559DeployConfig{ - EIP1559Denominator: 50, - EIP1559DenominatorCanyon: 250, - EIP1559Elasticity: 6, - }, - UpgradeScheduleDeployConfig: genesis.UpgradeScheduleDeployConfig{ - L2GenesisRegolithTimeOffset: u64UtilPtr(0), - L2GenesisCanyonTimeOffset: u64UtilPtr(0), - L2GenesisDeltaTimeOffset: u64UtilPtr(0), - L2GenesisEcotoneTimeOffset: u64UtilPtr(0), - L2GenesisFjordTimeOffset: u64UtilPtr(0), - L2GenesisGraniteTimeOffset: u64UtilPtr(0), - UseInterop: false, - }, - L2CoreDeployConfig: genesis.L2CoreDeployConfig{ - L2BlockTime: 2, - FinalizationPeriodSeconds: 12, - MaxSequencerDrift: 600, - SequencerWindowSize: 3600, - ChannelTimeoutBedrock: 300, - SystemConfigStartBlock: 0, - }, - } -} - -func CombineL2InitConfig(intent *Intent, chainIntent *ChainIntent) (genesis.L2InitializationConfig, error) { - cfg := DefaultL2InitConfig() - - var err error - if len(intent.GlobalInitOverrides) > 0 { - cfg, err = mergeJSON(cfg, intent.GlobalInitOverrides) - if err != nil { - return genesis.L2InitializationConfig{}, fmt.Errorf("error merging global L2 overrides: %w", err) - - } - } - - if len(chainIntent.InitOverrides) > 0 { - cfg, err = mergeJSON(cfg, chainIntent.InitOverrides) - if err != nil { - return genesis.L2InitializationConfig{}, fmt.Errorf("error merging chain L2 overrides: %w", err) - } - } - - return cfg, nil -} - -func mergeJSON[T any](in T, overrides ...map[string]any) (T, error) { - var out T - inJSON, err := json.Marshal(in) - if err != nil { - return out, err - } - - var tmpMap map[string]interface{} - if err := json.Unmarshal(inJSON, &tmpMap); err != nil { - return out, err - } - - for _, override := range overrides { - for k, v := range override { - tmpMap[k] = v - } - } - - inJSON, err = json.Marshal(tmpMap) - if err != nil { - return out, err - } - - if err := json.Unmarshal(inJSON, &out); err != nil { - return out, err - } - - return out, nil -} - -func mustHexBigFromHex(hex string) *hexutil.Big { - num := hexutil.MustDecodeBig(hex) - hexBig := hexutil.Big(*num) - return &hexBig -} - -func u64UtilPtr(in uint64) *hexutil.Uint64 { - util := hexutil.Uint64(in) - return &util -} diff --git a/op-chain-ops/deployer/state/state.go b/op-chain-ops/deployer/state/state.go index be679300ffdf..ab5a875301ba 100644 --- a/op-chain-ops/deployer/state/state.go +++ b/op-chain-ops/deployer/state/state.go @@ -1,8 +1,13 @@ package state import ( + "bytes" + "compress/gzip" + "encoding/json" "fmt" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/ethereum-optimism/optimism/op-service/jsonutil" @@ -94,4 +99,21 @@ type ChainState struct { DelayedWETHPermissionlessGameProxyAddress common.Address `json:"delayedWETHPermissionlessGameProxyAddress"` Genesis Base64Bytes `json:"genesis"` + + StartBlock *types.Header `json:"startBlock"` +} + +func (c *ChainState) UnmarshalGenesis() (*foundry.ForgeAllocs, error) { + gr, err := gzip.NewReader(bytes.NewReader(c.Genesis)) + if err != nil { + return nil, fmt.Errorf("failed to create gzip reader: %w", err) + } + defer gr.Close() + + var allocs foundry.ForgeAllocs + if err := json.NewDecoder(gr).Decode(&allocs); err != nil { + return nil, fmt.Errorf("failed to decode genesis: %w", err) + } + + return &allocs, nil } diff --git a/op-chain-ops/foundry/allocs.go b/op-chain-ops/foundry/allocs.go index b7300511431d..af0c28f4faf0 100644 --- a/op-chain-ops/foundry/allocs.go +++ b/op-chain-ops/foundry/allocs.go @@ -82,6 +82,10 @@ func (d *ForgeAllocs) Copy() *ForgeAllocs { return &ForgeAllocs{Accounts: out} } +func (d ForgeAllocs) MarshalJSON() ([]byte, error) { + return json.Marshal(d.Accounts) +} + func (d *ForgeAllocs) UnmarshalJSON(b []byte) error { // forge, since integrating Alloy, likes to hex-encode everything. type forgeAllocAccount struct { diff --git a/op-chain-ops/foundry/allocs_test.go b/op-chain-ops/foundry/allocs_test.go index a11d69fa9eff..6d19557016cb 100644 --- a/op-chain-ops/foundry/allocs_test.go +++ b/op-chain-ops/foundry/allocs_test.go @@ -1,6 +1,8 @@ package foundry import ( + "encoding/json" + "math/big" "os" "testing" @@ -96,3 +98,24 @@ func TestForgeAllocs_FromState(t *testing.T) { require.Equal(t, "0", allocs.Accounts[contract].Balance.String()) require.Equal(t, uint64(30), allocs.Accounts[contract].Nonce) } + +func TestForgeAllocs_Marshaling(t *testing.T) { + data := &ForgeAllocs{ + Accounts: map[common.Address]types.Account{ + common.HexToAddress("0x12345"): { + Balance: big.NewInt(12345), + Code: []byte{0x01, 0x02, 0x03}, + Nonce: 123, + Storage: map[common.Hash]common.Hash{ + common.HexToHash("0x12345"): common.HexToHash("0x12345"), + }, + }, + }, + } + + out, err := json.Marshal(data) + require.NoError(t, err) + + var in ForgeAllocs + require.NoError(t, json.Unmarshal(out, &in)) +} diff --git a/op-chain-ops/genesis/config.go b/op-chain-ops/genesis/config.go index 9b71fa6649a9..26f675b30e7f 100644 --- a/op-chain-ops/genesis/config.go +++ b/op-chain-ops/genesis/config.go @@ -732,6 +732,8 @@ type L1DependenciesConfig struct { // DAChallengeProxy represents the L1 address of the DataAvailabilityChallenge contract. DAChallengeProxy common.Address `json:"daChallengeProxy"` + + ProtocolVersionsProxy common.Address `json:"protocolVersionsProxy"` } // DependencyContext is the contextual configuration needed to verify the L1 dependencies, @@ -877,7 +879,7 @@ func (d *DeployConfig) SetDeployments(deployments *L1Deployments) { // RollupConfig converts a DeployConfig to a rollup.Config. If Ecotone is active at genesis, the // Overhead value is considered a noop. -func (d *DeployConfig) RollupConfig(l1StartBlock *types.Block, l2GenesisBlockHash common.Hash, l2GenesisBlockNumber uint64) (*rollup.Config, error) { +func (d *DeployConfig) RollupConfig(l1StartBlock *types.Header, l2GenesisBlockHash common.Hash, l2GenesisBlockNumber uint64) (*rollup.Config, error) { if d.OptimismPortalProxy == (common.Address{}) { return nil, errors.New("OptimismPortalProxy cannot be address(0)") } @@ -894,17 +896,19 @@ func (d *DeployConfig) RollupConfig(l1StartBlock *types.Block, l2GenesisBlockHas } } + l1StartTime := l1StartBlock.Time + return &rollup.Config{ Genesis: rollup.Genesis{ L1: eth.BlockID{ Hash: l1StartBlock.Hash(), - Number: l1StartBlock.NumberU64(), + Number: l1StartBlock.Number.Uint64(), }, L2: eth.BlockID{ Hash: l2GenesisBlockHash, Number: l2GenesisBlockNumber, }, - L2Time: l1StartBlock.Time(), + L2Time: l1StartBlock.Time, SystemConfig: eth.SystemConfig{ BatcherAddr: d.BatchSenderAddress, Overhead: eth.Bytes32(common.BigToHash(new(big.Int).SetUint64(d.GasPriceOracleOverhead))), @@ -912,23 +916,24 @@ func (d *DeployConfig) RollupConfig(l1StartBlock *types.Block, l2GenesisBlockHas GasLimit: uint64(d.L2GenesisBlockGasLimit), }, }, - BlockTime: d.L2BlockTime, - MaxSequencerDrift: d.MaxSequencerDrift, - SeqWindowSize: d.SequencerWindowSize, - ChannelTimeoutBedrock: d.ChannelTimeoutBedrock, - L1ChainID: new(big.Int).SetUint64(d.L1ChainID), - L2ChainID: new(big.Int).SetUint64(d.L2ChainID), - BatchInboxAddress: d.BatchInboxAddress, - DepositContractAddress: d.OptimismPortalProxy, - L1SystemConfigAddress: d.SystemConfigProxy, - RegolithTime: d.RegolithTime(l1StartBlock.Time()), - CanyonTime: d.CanyonTime(l1StartBlock.Time()), - DeltaTime: d.DeltaTime(l1StartBlock.Time()), - EcotoneTime: d.EcotoneTime(l1StartBlock.Time()), - FjordTime: d.FjordTime(l1StartBlock.Time()), - GraniteTime: d.GraniteTime(l1StartBlock.Time()), - InteropTime: d.InteropTime(l1StartBlock.Time()), - AltDAConfig: altDA, + BlockTime: d.L2BlockTime, + MaxSequencerDrift: d.MaxSequencerDrift, + SeqWindowSize: d.SequencerWindowSize, + ChannelTimeoutBedrock: d.ChannelTimeoutBedrock, + L1ChainID: new(big.Int).SetUint64(d.L1ChainID), + L2ChainID: new(big.Int).SetUint64(d.L2ChainID), + BatchInboxAddress: d.BatchInboxAddress, + DepositContractAddress: d.OptimismPortalProxy, + L1SystemConfigAddress: d.SystemConfigProxy, + RegolithTime: d.RegolithTime(l1StartTime), + CanyonTime: d.CanyonTime(l1StartTime), + DeltaTime: d.DeltaTime(l1StartTime), + EcotoneTime: d.EcotoneTime(l1StartTime), + FjordTime: d.FjordTime(l1StartTime), + GraniteTime: d.GraniteTime(l1StartTime), + InteropTime: d.InteropTime(l1StartTime), + ProtocolVersionsAddress: d.ProtocolVersionsProxy, + AltDAConfig: altDA, }, nil } diff --git a/op-chain-ops/genesis/genesis.go b/op-chain-ops/genesis/genesis.go index f517912e109a..dc7a44ad7ddf 100644 --- a/op-chain-ops/genesis/genesis.go +++ b/op-chain-ops/genesis/genesis.go @@ -22,7 +22,7 @@ const defaultGasLimit = 30_000_000 var BedrockTransitionBlockExtraData = []byte("BEDROCK") // NewL2Genesis will create a new L2 genesis -func NewL2Genesis(config *DeployConfig, block *types.Block) (*core.Genesis, error) { +func NewL2Genesis(config *DeployConfig, l1StartHeader *types.Header) (*core.Genesis, error) { if config.L2ChainID == 0 { return nil, errors.New("must define L2 ChainID") } @@ -40,6 +40,8 @@ func NewL2Genesis(config *DeployConfig, block *types.Block) (*core.Genesis, erro eip1559Elasticity = 10 } + l1StartTime := l1StartHeader.Time + optimismChainConfig := params.ChainConfig{ ChainID: new(big.Int).SetUint64(config.L2ChainID), HomesteadBlock: big.NewInt(0), @@ -61,14 +63,14 @@ func NewL2Genesis(config *DeployConfig, block *types.Block) (*core.Genesis, erro TerminalTotalDifficulty: big.NewInt(0), TerminalTotalDifficultyPassed: true, BedrockBlock: new(big.Int).SetUint64(uint64(config.L2GenesisBlockNumber)), - RegolithTime: config.RegolithTime(block.Time()), - CanyonTime: config.CanyonTime(block.Time()), - ShanghaiTime: config.CanyonTime(block.Time()), - CancunTime: config.EcotoneTime(block.Time()), - EcotoneTime: config.EcotoneTime(block.Time()), - FjordTime: config.FjordTime(block.Time()), - GraniteTime: config.GraniteTime(block.Time()), - InteropTime: config.InteropTime(block.Time()), + RegolithTime: config.RegolithTime(l1StartTime), + CanyonTime: config.CanyonTime(l1StartTime), + ShanghaiTime: config.CanyonTime(l1StartTime), + CancunTime: config.EcotoneTime(l1StartTime), + EcotoneTime: config.EcotoneTime(l1StartTime), + FjordTime: config.FjordTime(l1StartTime), + GraniteTime: config.GraniteTime(l1StartTime), + InteropTime: config.InteropTime(l1StartTime), Optimism: ¶ms.OptimismConfig{ EIP1559Denominator: eip1559Denom, EIP1559Elasticity: eip1559Elasticity, @@ -102,7 +104,7 @@ func NewL2Genesis(config *DeployConfig, block *types.Block) (*core.Genesis, erro genesis := &core.Genesis{ Config: &optimismChainConfig, Nonce: uint64(config.L2GenesisBlockNonce), - Timestamp: block.Time(), + Timestamp: l1StartTime, ExtraData: extraData, GasLimit: uint64(gasLimit), Difficulty: difficulty.ToInt(), diff --git a/op-chain-ops/genesis/layer_two.go b/op-chain-ops/genesis/layer_two.go index 46c17a4f9c76..5e79b55ce69d 100644 --- a/op-chain-ops/genesis/layer_two.go +++ b/op-chain-ops/genesis/layer_two.go @@ -36,7 +36,7 @@ var ( type AllocsLoader func(mode L2AllocsMode) *foundry.ForgeAllocs // BuildL2Genesis will build the L2 genesis block. -func BuildL2Genesis(config *DeployConfig, dump *foundry.ForgeAllocs, l1StartBlock *types.Block) (*core.Genesis, error) { +func BuildL2Genesis(config *DeployConfig, dump *foundry.ForgeAllocs, l1StartBlock *types.Header) (*core.Genesis, error) { genspec, err := NewL2Genesis(config, l1StartBlock) if err != nil { return nil, err diff --git a/op-chain-ops/genesis/testdata/test-deploy-config-full.json b/op-chain-ops/genesis/testdata/test-deploy-config-full.json index dfe420b2b7f4..1d0702e0218e 100644 --- a/op-chain-ops/genesis/testdata/test-deploy-config-full.json +++ b/op-chain-ops/genesis/testdata/test-deploy-config-full.json @@ -55,6 +55,7 @@ "systemConfigProxy": "0x4200000000000000000000000000000000000061", "optimismPortalProxy": "0x4200000000000000000000000000000000000062", "proxyAdminOwner": "0x0000000000000000000000000000000000000222", + "protocolVersionsProxy": "0x0000000000000000000000000000000000000000", "gasPriceOracleBaseFeeScalar": 0, "gasPriceOracleBlobBaseFeeScalar": 0, "gasPriceOracleOverhead": 2100, diff --git a/op-chain-ops/interopgen/deploy.go b/op-chain-ops/interopgen/deploy.go index d172184e91da..11340c528bfc 100644 --- a/op-chain-ops/interopgen/deploy.go +++ b/op-chain-ops/interopgen/deploy.go @@ -289,7 +289,7 @@ func completeL2(l2Host *script.Host, cfg *L2Config, l1Block *types.Block, deploy }, } // l1Block is used to determine genesis time. - l2Genesis, err := genesis.NewL2Genesis(deployCfg, l1Block) + l2Genesis, err := genesis.NewL2Genesis(deployCfg, l1Block.Header()) if err != nil { return nil, fmt.Errorf("failed to build L2 genesis config: %w", err) } @@ -314,7 +314,7 @@ func completeL2(l2Host *script.Host, cfg *L2Config, l1Block *types.Block, deploy l2Genesis.Alloc = allocs.Accounts l2GenesisBlock := l2Genesis.ToBlock() - rollupCfg, err := deployCfg.RollupConfig(l1Block, l2GenesisBlock.Hash(), l2GenesisBlock.NumberU64()) + rollupCfg, err := deployCfg.RollupConfig(l1Block.Header(), l2GenesisBlock.Hash(), l2GenesisBlock.NumberU64()) if err != nil { return nil, fmt.Errorf("failed to build L2 rollup config: %w", err) } diff --git a/op-e2e/e2eutils/setup.go b/op-e2e/e2eutils/setup.go index a00d3e57d237..52dd6ec2d3ae 100644 --- a/op-e2e/e2eutils/setup.go +++ b/op-e2e/e2eutils/setup.go @@ -134,7 +134,7 @@ func Setup(t require.TestingT, deployParams *DeployParams, alloc *AllocParams) * allocsMode = genesis.L2AllocsEcotone } l2Allocs := config.L2Allocs(allocsMode) - l2Genesis, err := genesis.BuildL2Genesis(deployConf, l2Allocs, l1Block) + l2Genesis, err := genesis.BuildL2Genesis(deployConf, l2Allocs, l1Block.Header()) require.NoError(t, err, "failed to create l2 genesis") if alloc.PrefundTestUsers { for _, addr := range deployParams.Addresses.All() { diff --git a/op-e2e/opgeth/op_geth.go b/op-e2e/opgeth/op_geth.go index cf48e1d9f787..1e15eecbd08a 100644 --- a/op-e2e/opgeth/op_geth.go +++ b/op-e2e/opgeth/op_geth.go @@ -70,7 +70,7 @@ func NewOpGeth(t testing.TB, ctx context.Context, cfg *e2esys.SystemConfig) (*Op allocsMode = genesis.L2AllocsEcotone } l2Allocs := config.L2Allocs(allocsMode) - l2Genesis, err := genesis.BuildL2Genesis(cfg.DeployConfig, l2Allocs, l1Block) + l2Genesis, err := genesis.BuildL2Genesis(cfg.DeployConfig, l2Allocs, l1Block.Header()) require.NoError(t, err) l2GenesisBlock := l2Genesis.ToBlock() @@ -108,7 +108,7 @@ func NewOpGeth(t testing.TB, ctx context.Context, cfg *e2esys.SystemConfig) (*Op require.NoError(t, err) // Finally create the engine client - rollupCfg, err := cfg.DeployConfig.RollupConfig(l1Block, l2GenesisBlock.Hash(), l2GenesisBlock.NumberU64()) + rollupCfg, err := cfg.DeployConfig.RollupConfig(l1Block.Header(), l2GenesisBlock.Hash(), l2GenesisBlock.NumberU64()) require.NoError(t, err) rollupCfg.Genesis = rollupGenesis l2Engine, err := sources.NewEngineClient( diff --git a/op-e2e/system/e2esys/setup.go b/op-e2e/system/e2esys/setup.go index dbfd93450e58..bc4364de9ad4 100644 --- a/op-e2e/system/e2esys/setup.go +++ b/op-e2e/system/e2esys/setup.go @@ -519,7 +519,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste t.Log("Generating L2 genesis", "l2_allocs_mode", string(allocsMode)) l2Allocs := config.L2Allocs(allocsMode) - l2Genesis, err := genesis.BuildL2Genesis(cfg.DeployConfig, l2Allocs, l1Block) + l2Genesis, err := genesis.BuildL2Genesis(cfg.DeployConfig, l2Allocs, l1Block.Header()) if err != nil { return nil, err } diff --git a/op-node/cmd/genesis/cmd.go b/op-node/cmd/genesis/cmd.go index 109d239b87d5..054f29310619 100644 --- a/op-node/cmd/genesis/cmd.go +++ b/op-node/cmd/genesis/cmd.go @@ -191,13 +191,13 @@ var Subcommands = cli.Commands{ } // Build the L2 genesis block - l2Genesis, err := genesis.BuildL2Genesis(config, l2Allocs, l1StartBlock) + l2Genesis, err := genesis.BuildL2Genesis(config, l2Allocs, l1StartBlock.Header()) if err != nil { return fmt.Errorf("error creating l2 genesis: %w", err) } l2GenesisBlock := l2Genesis.ToBlock() - rollupConfig, err := config.RollupConfig(l1StartBlock, l2GenesisBlock.Hash(), l2GenesisBlock.Number().Uint64()) + rollupConfig, err := config.RollupConfig(l1StartBlock.Header(), l2GenesisBlock.Hash(), l2GenesisBlock.Number().Uint64()) if err != nil { return err } diff --git a/op-program/client/l2/engine_backend_test.go b/op-program/client/l2/engine_backend_test.go index 63eeba9285f9..427f256d0a45 100644 --- a/op-program/client/l2/engine_backend_test.go +++ b/op-program/client/l2/engine_backend_test.go @@ -312,7 +312,7 @@ func setupOracle(t *testing.T, blockCount int, headBlockNumber int, enableEcoton } l1Genesis, err := genesis.NewL1Genesis(deployConfig) require.NoError(t, err) - l2Genesis, err := genesis.NewL2Genesis(deployConfig, l1Genesis.ToBlock()) + l2Genesis, err := genesis.NewL2Genesis(deployConfig, l1Genesis.ToBlock().Header()) require.NoError(t, err) l2Genesis.Alloc[fundedAddress] = types.Account{ From eba495d2bc2db72e69cf3a93d8e5b7d6991bac66 Mon Sep 17 00:00:00 2001 From: Blaine Malone Date: Wed, 18 Sep 2024 17:07:53 -0400 Subject: [PATCH 193/264] refactor: Rename OPSM to OPSMProxy for clarity (#11972) * chore(rename): Rename opsm to opsmProxy * fix: Go bindings updated for proxy. * fix: linting * fix: pr comment nits. --- .../deployer/integration_test/apply_test.go | 2 +- op-chain-ops/deployer/opsm/implementations.go | 2 +- op-chain-ops/deployer/opsm/opchain.go | 2 +- .../deployer/pipeline/implementations.go | 2 +- op-chain-ops/deployer/pipeline/opchain.go | 2 +- op-chain-ops/deployer/state/state.go | 2 +- op-chain-ops/interopgen/deploy.go | 2 +- op-chain-ops/interopgen/deployments.go | 2 +- .../scripts/DeployImplementations.s.sol | 20 ++++++++-------- .../scripts/DeployOPChain.s.sol | 24 +++++++++---------- .../test/DeployImplementations.t.sol | 12 +++++----- .../test/DeployOPChain.t.sol | 8 +++---- .../test/L1/OPStackManager.t.sol | 2 +- 13 files changed, 41 insertions(+), 41 deletions(-) diff --git a/op-chain-ops/deployer/integration_test/apply_test.go b/op-chain-ops/deployer/integration_test/apply_test.go index 55bcd8707354..624367ad3677 100644 --- a/op-chain-ops/deployer/integration_test/apply_test.go +++ b/op-chain-ops/deployer/integration_test/apply_test.go @@ -147,7 +147,7 @@ func TestEndToEndApply(t *testing.T) { {"SuperchainConfigImpl", st.SuperchainDeployment.SuperchainConfigImplAddress}, {"ProtocolVersionsProxy", st.SuperchainDeployment.ProtocolVersionsProxyAddress}, {"ProtocolVersionsImpl", st.SuperchainDeployment.ProtocolVersionsImplAddress}, - {"Opsm", st.ImplementationsDeployment.OpsmAddress}, + {"OpsmProxy", st.ImplementationsDeployment.OpsmProxyAddress}, {"DelayedWETHImpl", st.ImplementationsDeployment.DelayedWETHImplAddress}, {"OptimismPortalImpl", st.ImplementationsDeployment.OptimismPortalImplAddress}, {"PreimageOracleSingleton", st.ImplementationsDeployment.PreimageOracleSingletonAddress}, diff --git a/op-chain-ops/deployer/opsm/implementations.go b/op-chain-ops/deployer/opsm/implementations.go index c29a73a6437f..ed20b55f1522 100644 --- a/op-chain-ops/deployer/opsm/implementations.go +++ b/op-chain-ops/deployer/opsm/implementations.go @@ -30,7 +30,7 @@ func (input *DeployImplementationsInput) InputSet() bool { } type DeployImplementationsOutput struct { - Opsm common.Address + OpsmProxy common.Address DelayedWETHImpl common.Address OptimismPortalImpl common.Address PreimageOracleSingleton common.Address diff --git a/op-chain-ops/deployer/opsm/opchain.go b/op-chain-ops/deployer/opsm/opchain.go index 4e970d455859..79ad79569c3f 100644 --- a/op-chain-ops/deployer/opsm/opchain.go +++ b/op-chain-ops/deployer/opsm/opchain.go @@ -20,7 +20,7 @@ type DeployOPChainInput struct { BasefeeScalar uint32 BlobBaseFeeScalar uint32 L2ChainId *big.Int - Opsm common.Address + OpsmProxy common.Address } func (input *DeployOPChainInput) InputSet() bool { diff --git a/op-chain-ops/deployer/pipeline/implementations.go b/op-chain-ops/deployer/pipeline/implementations.go index 0a203c0f3119..f7e2acd1130c 100644 --- a/op-chain-ops/deployer/pipeline/implementations.go +++ b/op-chain-ops/deployer/pipeline/implementations.go @@ -77,7 +77,7 @@ func DeployImplementations(ctx context.Context, env *Env, intent *state.Intent, } st.ImplementationsDeployment = &state.ImplementationsDeployment{ - OpsmAddress: dio.Opsm, + OpsmProxyAddress: dio.OpsmProxy, DelayedWETHImplAddress: dio.DelayedWETHImpl, OptimismPortalImplAddress: dio.OptimismPortalImpl, PreimageOracleSingletonAddress: dio.PreimageOracleSingleton, diff --git a/op-chain-ops/deployer/pipeline/opchain.go b/op-chain-ops/deployer/pipeline/opchain.go index f3f577cf26a8..c6d64255c650 100644 --- a/op-chain-ops/deployer/pipeline/opchain.go +++ b/op-chain-ops/deployer/pipeline/opchain.go @@ -62,7 +62,7 @@ func DeployOPChain(ctx context.Context, env *Env, intent *state.Intent, st *stat BasefeeScalar: 1368, BlobBaseFeeScalar: 801949, L2ChainId: chainID.Big(), - Opsm: st.ImplementationsDeployment.OpsmAddress, + OpsmProxy: st.ImplementationsDeployment.OpsmProxyAddress, }, ) return err diff --git a/op-chain-ops/deployer/state/state.go b/op-chain-ops/deployer/state/state.go index ab5a875301ba..6fdc4f7dbae6 100644 --- a/op-chain-ops/deployer/state/state.go +++ b/op-chain-ops/deployer/state/state.go @@ -65,7 +65,7 @@ type SuperchainDeployment struct { } type ImplementationsDeployment struct { - OpsmAddress common.Address `json:"opsmAddress"` + OpsmProxyAddress common.Address `json:"opsmProxyAddress"` DelayedWETHImplAddress common.Address `json:"delayedWETHImplAddress"` OptimismPortalImplAddress common.Address `json:"optimismPortalImplAddress"` PreimageOracleSingletonAddress common.Address `json:"preimageOracleSingletonAddress"` diff --git a/op-chain-ops/interopgen/deploy.go b/op-chain-ops/interopgen/deploy.go index 11340c528bfc..fde7485e04da 100644 --- a/op-chain-ops/interopgen/deploy.go +++ b/op-chain-ops/interopgen/deploy.go @@ -206,7 +206,7 @@ func deployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme BasefeeScalar: cfg.GasPriceOracleBaseFeeScalar, BlobBaseFeeScalar: cfg.GasPriceOracleBlobBaseFeeScalar, L2ChainId: new(big.Int).SetUint64(cfg.L2ChainID), - Opsm: superDeployment.Opsm, + OpsmProxy: superDeployment.OpsmProxy, }) if err != nil { return nil, fmt.Errorf("failed to deploy L2 OP chain: %w", err) diff --git a/op-chain-ops/interopgen/deployments.go b/op-chain-ops/interopgen/deployments.go index dcb2fb114c26..5b54c2286f9a 100644 --- a/op-chain-ops/interopgen/deployments.go +++ b/op-chain-ops/interopgen/deployments.go @@ -9,7 +9,7 @@ type L1Deployment struct { } type Implementations struct { - Opsm common.Address `json:"OPSM"` // not proxied + OpsmProxy common.Address `json:"OPSMProxy"` DelayedWETHImpl common.Address `json:"DelayedWETHImpl"` OptimismPortalImpl common.Address `json:"OptimismPortalImpl"` PreimageOracleSingleton common.Address `json:"PreimageOracleSingleton"` diff --git a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol index 3cb120adc02f..4c413bfe3edd 100644 --- a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol +++ b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol @@ -155,7 +155,7 @@ contract DeployImplementationsInput is BaseDeployIO { } contract DeployImplementationsOutput is BaseDeployIO { - OPStackManager internal _opsm; + OPStackManager internal _opsmProxy; DelayedWETH internal _delayedWETHImpl; OptimismPortal2 internal _optimismPortalImpl; PreimageOracle internal _preimageOracleSingleton; @@ -171,7 +171,7 @@ contract DeployImplementationsOutput is BaseDeployIO { require(_addr != address(0), "DeployImplementationsOutput: cannot set zero address"); // forgefmt: disable-start - if (sel == this.opsm.selector) _opsm = OPStackManager(payable(_addr)); + if (sel == this.opsmProxy.selector) _opsmProxy = OPStackManager(payable(_addr)); else if (sel == this.optimismPortalImpl.selector) _optimismPortalImpl = OptimismPortal2(payable(_addr)); else if (sel == this.delayedWETHImpl.selector) _delayedWETHImpl = DelayedWETH(payable(_addr)); else if (sel == this.preimageOracleSingleton.selector) _preimageOracleSingleton = PreimageOracle(_addr); @@ -193,7 +193,7 @@ contract DeployImplementationsOutput is BaseDeployIO { function checkOutput(DeployImplementationsInput) public { address[] memory addrs = Solarray.addresses( - address(this.opsm()), + address(this.opsmProxy()), address(this.optimismPortalImpl()), address(this.delayedWETHImpl()), address(this.preimageOracleSingleton()), @@ -210,10 +210,10 @@ contract DeployImplementationsOutput is BaseDeployIO { // TODO Also add the assertions for the implementation contracts from ChainAssertions.sol } - function opsm() public returns (OPStackManager) { - DeployUtils.assertValidContractAddress(address(_opsm)); - DeployUtils.assertImplementationSet(address(_opsm)); - return _opsm; + function opsmProxy() public returns (OPStackManager) { + DeployUtils.assertValidContractAddress(address(_opsmProxy)); + DeployUtils.assertImplementationSet(address(_opsmProxy)); + return _opsmProxy; } function optimismPortalImpl() public view returns (OptimismPortal2) { @@ -400,10 +400,10 @@ contract DeployImplementations is Script { }); // This call contains a broadcast to deploy OPSM which is proxied. - OPStackManager opsm = createOPSMContract(_dii, _dio, blueprints, release, setters); + OPStackManager opsmProxy = createOPSMContract(_dii, _dio, blueprints, release, setters); - vm.label(address(opsm), "OPStackManager"); - _dio.set(_dio.opsm.selector, address(opsm)); + vm.label(address(opsmProxy), "OPStackManager"); + _dio.set(_dio.opsmProxy.selector, address(opsmProxy)); } // --- Core Contracts --- diff --git a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol index 3a6369f4cc6d..fbf8b8054531 100644 --- a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol @@ -43,7 +43,7 @@ contract DeployOPChainInput is BaseDeployIO { uint32 internal _basefeeScalar; uint32 internal _blobBaseFeeScalar; uint256 internal _l2ChainId; - OPStackManager internal _opsm; + OPStackManager internal _opsmProxy; function set(bytes4 _sel, address _addr) public { require(_addr != address(0), "DeployOPChainInput: cannot set zero address"); @@ -53,7 +53,7 @@ contract DeployOPChainInput is BaseDeployIO { else if (_sel == this.unsafeBlockSigner.selector) _unsafeBlockSigner = _addr; else if (_sel == this.proposer.selector) _proposer = _addr; else if (_sel == this.challenger.selector) _challenger = _addr; - else if (_sel == this.opsm.selector) _opsm = OPStackManager(_addr); + else if (_sel == this.opsmProxy.selector) _opsmProxy = OPStackManager(_addr); else revert("DeployOPChainInput: unknown selector"); } @@ -122,9 +122,9 @@ contract DeployOPChainInput is BaseDeployIO { } // TODO: Check that opsm is proxied and it has an implementation. - function opsm() public view returns (OPStackManager) { - require(address(_opsm) != address(0), "DeployOPChainInput: not set"); - return _opsm; + function opsmProxy() public view returns (OPStackManager) { + require(address(_opsmProxy) != address(0), "DeployOPChainInput: not set"); + return _opsmProxy; } } @@ -311,7 +311,7 @@ contract DeployOPChainOutput is BaseDeployIO { require(outputConfig.maximumBaseFee == rConfig.maximumBaseFee, "SC-130"); require(systemConfig.startBlock() == block.number, "SC-140"); - require(systemConfig.batchInbox() == _doi.opsm().chainIdToBatchInboxAddress(_doi.l2ChainId()), "SC-150"); + require(systemConfig.batchInbox() == _doi.opsmProxy().chainIdToBatchInboxAddress(_doi.l2ChainId()), "SC-150"); require(systemConfig.l1CrossDomainMessenger() == address(l1CrossDomainMessengerProxy()), "SC-160"); require(systemConfig.l1ERC721Bridge() == address(l1ERC721BridgeProxy()), "SC-170"); @@ -333,7 +333,7 @@ contract DeployOPChainOutput is BaseDeployIO { require(address(messenger.PORTAL()) == address(optimismPortalProxy()), "L1xDM-30"); require(address(messenger.portal()) == address(optimismPortalProxy()), "L1xDM-40"); - require(address(messenger.superchainConfig()) == address(_doi.opsm().superchainConfig()), "L1xDM-50"); + require(address(messenger.superchainConfig()) == address(_doi.opsmProxy().superchainConfig()), "L1xDM-50"); bytes32 xdmSenderSlot = vm.load(address(messenger), bytes32(uint256(204))); require(address(uint160(uint256(xdmSenderSlot))) == Constants.DEFAULT_L2_SENDER, "L1xDM-60"); @@ -349,7 +349,7 @@ contract DeployOPChainOutput is BaseDeployIO { require(address(bridge.messenger()) == address(messenger), "L1SB-20"); require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_STANDARD_BRIDGE, "L1SB-30"); require(address(bridge.otherBridge()) == Predeploys.L2_STANDARD_BRIDGE, "L1SB-40"); - require(address(bridge.superchainConfig()) == address(_doi.opsm().superchainConfig()), "L1SB-50"); + require(address(bridge.superchainConfig()) == address(_doi.opsmProxy().superchainConfig()), "L1SB-50"); } function assertValidOptimismMintableERC20Factory(DeployOPChainInput) internal view { @@ -371,12 +371,12 @@ contract DeployOPChainOutput is BaseDeployIO { require(address(bridge.MESSENGER()) == address(l1CrossDomainMessengerProxy()), "LEB-30"); require(address(bridge.messenger()) == address(l1CrossDomainMessengerProxy()), "LEB-40"); - require(address(bridge.superchainConfig()) == address(_doi.opsm().superchainConfig()), "LEB-50"); + require(address(bridge.superchainConfig()) == address(_doi.opsmProxy().superchainConfig()), "LEB-50"); } function assertValidOptimismPortal(DeployOPChainInput _doi) internal view { OptimismPortal2 portal = optimismPortalProxy(); - ISuperchainConfig superchainConfig = ISuperchainConfig(address(_doi.opsm().superchainConfig())); + ISuperchainConfig superchainConfig = ISuperchainConfig(address(_doi.opsmProxy().superchainConfig())); require(address(portal.disputeGameFactory()) == address(disputeGameFactoryProxy()), "OP-10"); require(address(portal.systemConfig()) == address(systemConfigProxy()), "OP-20"); @@ -411,7 +411,7 @@ contract DeployOPChain is Script { } function run(DeployOPChainInput _doi, DeployOPChainOutput _doo) public { - OPStackManager opsm = _doi.opsm(); + OPStackManager opsmProxy = _doi.opsmProxy(); OPStackManager.Roles memory roles = OPStackManager.Roles({ opChainProxyAdminOwner: _doi.opChainProxyAdminOwner(), @@ -429,7 +429,7 @@ contract DeployOPChain is Script { }); vm.broadcast(msg.sender); - OPStackManager.DeployOutput memory deployOutput = opsm.deploy(deployInput); + OPStackManager.DeployOutput memory deployOutput = opsmProxy.deploy(deployInput); vm.label(address(deployOutput.opChainProxyAdmin), "opChainProxyAdmin"); vm.label(address(deployOutput.addressManager), "addressManager"); diff --git a/packages/contracts-bedrock/test/DeployImplementations.t.sol b/packages/contracts-bedrock/test/DeployImplementations.t.sol index 6fd747ea0c09..bb28b2fecd67 100644 --- a/packages/contracts-bedrock/test/DeployImplementations.t.sol +++ b/packages/contracts-bedrock/test/DeployImplementations.t.sol @@ -115,12 +115,12 @@ contract DeployImplementationsOutput_Test is Test { } function test_set_succeeds() public { - Proxy opsmProxy = new Proxy(address(0)); - address opsmImpl = address(makeAddr("opsm")); + Proxy proxy = new Proxy(address(0)); + address opsmImpl = address(makeAddr("opsmImpl")); vm.prank(address(0)); - opsmProxy.upgradeTo(opsmImpl); + proxy.upgradeTo(opsmImpl); - OPStackManager opsm = OPStackManager(address(opsmProxy)); + OPStackManager opsmProxy = OPStackManager(address(proxy)); OptimismPortal2 optimismPortalImpl = OptimismPortal2(payable(makeAddr("optimismPortalImpl"))); DelayedWETH delayedWETHImpl = DelayedWETH(payable(makeAddr("delayedWETHImpl"))); PreimageOracle preimageOracleSingleton = PreimageOracle(makeAddr("preimageOracleSingleton")); @@ -146,7 +146,7 @@ contract DeployImplementationsOutput_Test is Test { vm.etch(address(l1StandardBridgeImpl), hex"01"); vm.etch(address(optimismMintableERC20FactoryImpl), hex"01"); vm.etch(address(disputeGameFactoryImpl), hex"01"); - dio.set(dio.opsm.selector, address(opsm)); + dio.set(dio.opsmProxy.selector, address(opsmProxy)); dio.set(dio.optimismPortalImpl.selector, address(optimismPortalImpl)); dio.set(dio.delayedWETHImpl.selector, address(delayedWETHImpl)); dio.set(dio.preimageOracleSingleton.selector, address(preimageOracleSingleton)); @@ -158,7 +158,7 @@ contract DeployImplementationsOutput_Test is Test { dio.set(dio.optimismMintableERC20FactoryImpl.selector, address(optimismMintableERC20FactoryImpl)); dio.set(dio.disputeGameFactoryImpl.selector, address(disputeGameFactoryImpl)); - assertEq(address(opsm), address(dio.opsm()), "50"); + assertEq(address(opsmProxy), address(dio.opsmProxy()), "50"); assertEq(address(optimismPortalImpl), address(dio.optimismPortalImpl()), "100"); assertEq(address(delayedWETHImpl), address(dio.delayedWETHImpl()), "200"); assertEq(address(preimageOracleSingleton), address(dio.preimageOracleSingleton()), "300"); diff --git a/packages/contracts-bedrock/test/DeployOPChain.t.sol b/packages/contracts-bedrock/test/DeployOPChain.t.sol index 57f67ced77ed..b0a4cb15507e 100644 --- a/packages/contracts-bedrock/test/DeployOPChain.t.sol +++ b/packages/contracts-bedrock/test/DeployOPChain.t.sol @@ -60,7 +60,7 @@ contract DeployOPChainInput_Test is Test { doi.set(doi.basefeeScalar.selector, basefeeScalar); doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar); doi.set(doi.l2ChainId.selector, l2ChainId); - doi.set(doi.opsm.selector, address(opsm)); + doi.set(doi.opsmProxy.selector, address(opsm)); // Compare the default inputs to the getter methods. assertEq(opChainProxyAdminOwner, doi.opChainProxyAdminOwner(), "200"); assertEq(systemConfigOwner, doi.systemConfigOwner(), "300"); @@ -71,7 +71,7 @@ contract DeployOPChainInput_Test is Test { assertEq(basefeeScalar, doi.basefeeScalar(), "800"); assertEq(blobBaseFeeScalar, doi.blobBaseFeeScalar(), "900"); assertEq(l2ChainId, doi.l2ChainId(), "1000"); - assertEq(address(opsm), address(doi.opsm()), "1100"); + assertEq(address(opsm), address(doi.opsmProxy()), "1100"); } function test_getters_whenNotSet_revert() public { @@ -374,7 +374,7 @@ contract DeployOPChain_TestBase is Test { deployImplementations.run(dii, dio); // Set the OPStackManager input for DeployOPChain. - opsm = dio.opsm(); + opsm = dio.opsmProxy(); } // See the function of the same name in the `DeployImplementations_Test` contract of @@ -409,7 +409,7 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { doi.set(doi.basefeeScalar.selector, basefeeScalar); doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar); doi.set(doi.l2ChainId.selector, l2ChainId); - doi.set(doi.opsm.selector, address(opsm)); // Not fuzzed since it must be an actual instance. + doi.set(doi.opsmProxy.selector, address(opsm)); // Not fuzzed since it must be an actual instance. deployOPChain.run(doi, doo); diff --git a/packages/contracts-bedrock/test/L1/OPStackManager.t.sol b/packages/contracts-bedrock/test/L1/OPStackManager.t.sol index 289911b06c05..0443c9f0c46d 100644 --- a/packages/contracts-bedrock/test/L1/OPStackManager.t.sol +++ b/packages/contracts-bedrock/test/L1/OPStackManager.t.sol @@ -45,7 +45,7 @@ contract OPStackManager_Deploy_Test is DeployOPChain_TestBase { doi.set(doi.basefeeScalar.selector, basefeeScalar); doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar); doi.set(doi.l2ChainId.selector, l2ChainId); - doi.set(doi.opsm.selector, address(opsm)); + doi.set(doi.opsmProxy.selector, address(opsm)); } // This helper function is used to convert the input struct type defined in DeployOPChain.s.sol From bd97c322ad561c3016a1f39c1d4b5d9e3f8a9aba Mon Sep 17 00:00:00 2001 From: clabby Date: Wed, 18 Sep 2024 22:14:05 -0400 Subject: [PATCH 194/264] feat(op-e2e): Open channel closed after sequence window expiry test (#11993) * feat(op-e2e): Open channel closed after sequence window expiry test Adds a test to the proof actions that proves a block at the safe head after the batcher has opened a channel, allowed the sequence window to expire, and then attempted to close their open channel after the fact. * buffer frame * include extra tx --- op-e2e/actions/proofs/helpers/env.go | 18 ++-- op-e2e/actions/proofs/helpers/fixture.go | 4 +- op-e2e/actions/proofs/helpers/kona.go | 2 +- .../proofs/sequence_window_expiry_test.go | 95 +++++++++++++++++++ 4 files changed, 107 insertions(+), 12 deletions(-) diff --git a/op-e2e/actions/proofs/helpers/env.go b/op-e2e/actions/proofs/helpers/env.go index d911acff9306..df0f7e92bdc2 100644 --- a/op-e2e/actions/proofs/helpers/env.go +++ b/op-e2e/actions/proofs/helpers/env.go @@ -30,8 +30,8 @@ type L2FaultProofEnv struct { Sequencer *helpers.L2Sequencer Engine *helpers.L2Engine engCl *sources.EngineClient - sd *e2eutils.SetupData - dp *e2eutils.DeployParams + Sd *e2eutils.SetupData + Dp *e2eutils.DeployParams Miner *helpers.L1Miner Alice *helpers.CrossLayerUser } @@ -107,8 +107,8 @@ func NewL2FaultProofEnv[c any](t helpers.Testing, testCfg *TestCfg[c], tp *e2eut Sequencer: sequencer, Engine: engine, engCl: engCl, - sd: sd, - dp: dp, + Sd: sd, + Dp: dp, Miner: miner, Alice: alice, } @@ -149,7 +149,7 @@ func (env *L2FaultProofEnv) RunFaultProofProgram(t helpers.Testing, l2ClaimBlock L2Claim: common.Hash(claimRoot.OutputRoot), L2Head: preRoot.BlockRef.Hash, L2OutputRoot: common.Hash(preRoot.OutputRoot), - L2ChainID: env.sd.RollupCfg.L2ChainID.Uint64(), + L2ChainID: env.Sd.RollupCfg.L2ChainID.Uint64(), L1Head: l1Head.Hash(), } for _, apply := range fixtureInputParams { @@ -162,7 +162,7 @@ func (env *L2FaultProofEnv) RunFaultProofProgram(t helpers.Testing, l2ClaimBlock fakeBeacon := fakebeacon.NewBeacon( env.log, env.Miner.BlobStore(), - env.sd.L1Cfg.Timestamp, + env.Sd.L1Cfg.Timestamp, 12, ) require.NoError(t, fakeBeacon.Start("127.0.0.1:0")) @@ -178,11 +178,11 @@ func (env *L2FaultProofEnv) RunFaultProofProgram(t helpers.Testing, l2ClaimBlock ) withInProcessPrefetcher := host.WithPrefetcher(func(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *config.Config) (host.Prefetcher, error) { // Set up in-process L1 sources - l1Cl := env.Miner.L1Client(t, env.sd.RollupCfg) + l1Cl := env.Miner.L1Client(t, env.Sd.RollupCfg) l1BlobFetcher := env.Miner.BlobSource() // Set up in-process L2 source - l2ClCfg := sources.L2ClientDefaultConfig(env.sd.RollupCfg, true) + l2ClCfg := sources.L2ClientDefaultConfig(env.Sd.RollupCfg, true) l2RPC := env.Engine.RPCClient() l2Client, err := host.NewL2Client(l2RPC, env.log, nil, &host.L2ClientConfig{L2ClientConfig: l2ClCfg, L2Head: cfg.L2Head}) require.NoError(t, err, "failed to create L2 client") @@ -238,7 +238,7 @@ func NewOpProgramCfg( fi *FixtureInputs, params ...OpProgramCfgParam, ) *config.Config { - dfault := config.NewConfig(env.sd.RollupCfg, env.sd.L2Cfg.Config, fi.L1Head, fi.L2Head, fi.L2OutputRoot, fi.L2Claim, fi.L2BlockNumber) + dfault := config.NewConfig(env.Sd.RollupCfg, env.Sd.L2Cfg.Config, fi.L1Head, fi.L2Head, fi.L2OutputRoot, fi.L2Claim, fi.L2BlockNumber) if dumpFixtures { dfault.DataDir = t.TempDir() diff --git a/op-e2e/actions/proofs/helpers/fixture.go b/op-e2e/actions/proofs/helpers/fixture.go index a0535a275e1a..892848470897 100644 --- a/op-e2e/actions/proofs/helpers/fixture.go +++ b/op-e2e/actions/proofs/helpers/fixture.go @@ -60,8 +60,8 @@ func tryDumpTestFixture( } name = convertToKebabCase(name) - rollupCfg := env.sd.RollupCfg - l2Genesis := env.sd.L2Cfg + rollupCfg := env.Sd.RollupCfg + l2Genesis := env.Sd.L2Cfg var expectedStatus uint8 if result == nil { diff --git a/op-e2e/actions/proofs/helpers/kona.go b/op-e2e/actions/proofs/helpers/kona.go index 289ff2c95895..9d34a98dda01 100644 --- a/op-e2e/actions/proofs/helpers/kona.go +++ b/op-e2e/actions/proofs/helpers/kona.go @@ -38,7 +38,7 @@ func RunKonaNative( ) error { // Write rollup config to tempdir. rollupConfigPath := filepath.Join(workDir, "rollup.json") - ser, err := json.Marshal(env.sd.RollupCfg) + ser, err := json.Marshal(env.Sd.RollupCfg) require.NoError(t, err) require.NoError(t, os.WriteFile(rollupConfigPath, ser, fs.ModePerm)) diff --git a/op-e2e/actions/proofs/sequence_window_expiry_test.go b/op-e2e/actions/proofs/sequence_window_expiry_test.go index 9a7a281cdcc0..3f5ca9562d4b 100644 --- a/op-e2e/actions/proofs/sequence_window_expiry_test.go +++ b/op-e2e/actions/proofs/sequence_window_expiry_test.go @@ -48,6 +48,86 @@ func runSequenceWindowExpireTest(gt *testing.T, testCfg *helpers.TestCfg[any]) { env.RunFaultProofProgram(t, l2SafeHead.Number.Uint64()/2, testCfg.CheckResult, testCfg.InputParams...) } +// Runs a that proves a block in a chain where the batcher opens a channel, the sequence window expires, and then the +// batcher attempts to close the channel afterwards. +func runSequenceWindowExpire_ChannelCloseAfterWindowExpiry_Test(gt *testing.T, testCfg *helpers.TestCfg[any]) { + t := actionsHelpers.NewDefaultTesting(gt) + tp := helpers.NewTestParams() + env := helpers.NewL2FaultProofEnv(t, testCfg, tp, helpers.NewBatcherCfg()) + + // Mine 2 empty blocks on L2. + for i := 0; i < 2; i++ { + env.Sequencer.ActL2StartBlock(t) + env.Alice.L2.ActResetTxOpts(t) + env.Alice.L2.ActSetTxToAddr(&env.Dp.Addresses.Bob) + env.Alice.L2.ActMakeTx(t) + env.Engine.ActL2IncludeTx(env.Alice.Address())(t) + env.Sequencer.ActL2EndBlock(t) + } + + // Open the channel on L1. + env.Batcher.ActL2BatchBuffer(t) + env.Batcher.ActL2BatchSubmit(t) + env.Miner.ActL1StartBlock(12)(t) + env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t) + env.Miner.ActL1EndBlock(t) + + // Finalize the block with the first channel frame on L1. + env.Miner.ActL1SafeNext(t) + env.Miner.ActL1FinalizeNext(t) + + // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. + env.Sequencer.ActL1HeadSignal(t) + env.Sequencer.ActL2PipelineFull(t) + + // Ensure the safe head is still 0. + l2SafeHead := env.Engine.L2Chain().CurrentSafeBlock() + require.EqualValues(t, 0, l2SafeHead.Number.Uint64()) + + // Cache the next frame data before expiring the sequence window, but don't submit it yet. + env.Batcher.ActL2BatchBuffer(t) + env.Batcher.ActL2ChannelClose(t) + finalFrame := env.Batcher.ReadNextOutputFrame(t) + + // Expire the sequence window by building `SequenceWindow + 1` empty blocks on L1. + for i := 0; i < int(tp.SequencerWindowSize)+1; i++ { + env.Alice.L1.ActResetTxOpts(t) + env.Alice.ActDeposit(t) + + env.Miner.ActL1StartBlock(12)(t) + env.Miner.ActL1IncludeTx(env.Alice.Address())(t) + env.Miner.ActL1EndBlock(t) + + env.Miner.ActL1SafeNext(t) + env.Miner.ActL1FinalizeNext(t) + } + + // Instruct the batcher to closethe channel on L1, after the sequence window + channel timeout has elapsed. + env.Batcher.ActL2BatchSubmitRaw(t, finalFrame) + env.Miner.ActL1StartBlock(12)(t) + env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t) + env.Miner.ActL1EndBlock(t) + + // Finalize the block with the second channel frame on L1. + env.Miner.ActL1SafeNext(t) + env.Miner.ActL1FinalizeNext(t) + + // Ensure the safe head is still 0. + l2SafeHead = env.Engine.L2Chain().CurrentSafeBlock() + require.EqualValues(t, 0, l2SafeHead.Number.Uint64()) + + // Ask the sequencer to derive the deposit-only L2 chain. + env.Sequencer.ActL1HeadSignal(t) + env.Sequencer.ActL2PipelineFull(t) + + // Ensure the safe head advanced forcefully. + l2SafeHead = env.Engine.L2Chain().CurrentSafeBlock() + require.Greater(t, l2SafeHead.Number.Uint64(), uint64(0)) + + // Run the FPP on one of the auto-derived blocks. + env.RunFaultProofProgram(t, l2SafeHead.Number.Uint64()/2, testCfg.CheckResult, testCfg.InputParams...) +} + func Test_ProgramAction_SequenceWindowExpired(gt *testing.T) { matrix := helpers.NewMatrix[any]() defer matrix.Run(gt) @@ -67,4 +147,19 @@ func Test_ProgramAction_SequenceWindowExpired(gt *testing.T) { helpers.ExpectError(claim.ErrClaimNotValid), helpers.WithL2Claim(common.HexToHash("0xdeadbeef")), ) + matrix.AddTestCase( + "ChannelCloseAfterWindowExpiry-HonestClaim", + nil, + helpers.LatestForkOnly, + runSequenceWindowExpire_ChannelCloseAfterWindowExpiry_Test, + helpers.ExpectNoError(), + ) + matrix.AddTestCase( + "ChannelCloseAfterWindowExpiry-JunkClaim", + nil, + helpers.LatestForkOnly, + runSequenceWindowExpire_ChannelCloseAfterWindowExpiry_Test, + helpers.ExpectError(claim.ErrClaimNotValid), + helpers.WithL2Claim(common.HexToHash("0xdeadbeef")), + ) } From e2a19f45514c382d14fd3ce6f8aa966b0ea76275 Mon Sep 17 00:00:00 2001 From: clabby Date: Wed, 18 Sep 2024 23:22:10 -0400 Subject: [PATCH 195/264] feat(op-e2e): Channel timeout late submission test (#11995) * feat(op-e2e): Channel timeout late submission test * remove finalization of l1 chain --- op-e2e/actions/proofs/channel_timeout_test.go | 161 ++++++++++++++---- op-e2e/actions/proofs/helpers/env.go | 6 +- 2 files changed, 135 insertions(+), 32 deletions(-) diff --git a/op-e2e/actions/proofs/channel_timeout_test.go b/op-e2e/actions/proofs/channel_timeout_test.go index f4ab00a86538..1e97a5e38d3a 100644 --- a/op-e2e/actions/proofs/channel_timeout_test.go +++ b/op-e2e/actions/proofs/channel_timeout_test.go @@ -5,28 +5,17 @@ import ( actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" "github.com/ethereum-optimism/optimism/op-e2e/actions/proofs/helpers" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-program/client/claim" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" ) -// Run a test that exercises the channel timeout functionality in `op-program`. -// -// Steps: -// 1. Build `NumL2Blocks` empty blocks on L2. -// 2. Buffer the first half of the L2 blocks in the batcher, and submit the frame data. -// 3. Time out the channel by mining `ChannelTimeout + 1` empty blocks on L1. -// 4. Submit the channel frame data across 2 transactions. -// 5. Instruct the sequencer to derive the L2 chain. -// 6. Run the FPP on the safe head. +// Run a test that submits the first channel frame, times out the channel, and then resubmits the full channel. func runChannelTimeoutTest(gt *testing.T, testCfg *helpers.TestCfg[any]) { t := actionsHelpers.NewDefaultTesting(gt) - tp := helpers.NewTestParams(func(tp *e2eutils.TestParams) { - // Set the channel timeout to 10 blocks, 12x lower than the sequencing window. - tp.ChannelTimeout = 10 - }) + tp := helpers.NewTestParams() env := helpers.NewL2FaultProofEnv(t, testCfg, tp, helpers.NewBatcherCfg()) + channelTimeout := env.Sd.ChainSpec.ChannelTimeout(0) const NumL2Blocks = 10 @@ -40,16 +29,16 @@ func runChannelTimeoutTest(gt *testing.T, testCfg *helpers.TestCfg[any]) { for i := 0; i < NumL2Blocks/2; i++ { env.Batcher.ActL2BatchBuffer(t) } - env.Batcher.ActL2BatchSubmit(t) + firstFrame := env.Batcher.ReadNextOutputFrame(t) + env.Batcher.ActL2BatchSubmitRaw(t, firstFrame) - // Instruct the batcher to submit the first channel frame to L1, and include the transaction. + // Include the batcher transaction. env.Miner.ActL1StartBlock(12)(t) env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t) env.Miner.ActL1EndBlock(t) // Finalize the block with the first channel frame on L1. env.Miner.ActL1SafeNext(t) - env.Miner.ActL1FinalizeNext(t) // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. env.Sequencer.ActL1HeadSignal(t) @@ -59,11 +48,10 @@ func runChannelTimeoutTest(gt *testing.T, testCfg *helpers.TestCfg[any]) { l2SafeHead := env.Engine.L2Chain().CurrentSafeBlock() require.Equal(t, uint64(0), l2SafeHead.Number.Uint64()) - // Time out the channel by mining `ChannelTimeout + 1` empty blocks on L1. - for i := uint64(0); i < tp.ChannelTimeout+1; i++ { + // Time out the channel by mining `channelTimeout + 1` empty blocks on L1. + for i := uint64(0); i < channelTimeout+1; i++ { env.Miner.ActEmptyBlock(t) env.Miner.ActL1SafeNext(t) - env.Miner.ActL1FinalizeNext(t) } // Instruct the sequencer to derive the L2 chain - the channel should now be timed out. @@ -77,24 +65,124 @@ func runChannelTimeoutTest(gt *testing.T, testCfg *helpers.TestCfg[any]) { // Instruct the batcher to submit the blocks to L1 in a new channel, // submitted across 2 transactions. for i := 0; i < 2; i++ { - // Buffer half of the L2 chain's blocks. - for j := 0; j < NumL2Blocks/2; j++ { - env.Batcher.ActL2BatchBuffer(t) - } - - // Close the channel on the second iteration. - if i == 1 { + if i == 0 { + // Re-submit the first frame + env.Batcher.ActL2BatchSubmitRaw(t, firstFrame) + } else { + // Buffer half of the L2 chain's blocks. + for j := 0; j < NumL2Blocks/2; j++ { + env.Batcher.ActL2BatchBuffer(t) + } env.Batcher.ActL2ChannelClose(t) + env.Batcher.ActL2BatchSubmit(t) } - env.Batcher.ActL2BatchSubmit(t) env.Miner.ActL1StartBlock(12)(t) env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t) env.Miner.ActL1EndBlock(t) // Finalize the block with the frame data on L1. env.Miner.ActL1SafeNext(t) - env.Miner.ActL1FinalizeNext(t) + } + + // Instruct the sequencer to derive the L2 chain. + env.Sequencer.ActL1HeadSignal(t) + env.Sequencer.ActL2PipelineFull(t) + + // Ensure the safe head has still advanced to L2 block # NumL2Blocks. + l2SafeHead = env.Engine.L2Chain().CurrentSafeBlock() + require.EqualValues(t, NumL2Blocks, l2SafeHead.Number.Uint64()) + + // Run the FPP on L2 block # NumL2Blocks/2. + env.RunFaultProofProgram(t, NumL2Blocks/2, testCfg.CheckResult, testCfg.InputParams...) +} + +func runChannelTimeoutTest_CloseChannelLate(gt *testing.T, testCfg *helpers.TestCfg[any]) { + t := actionsHelpers.NewDefaultTesting(gt) + tp := helpers.NewTestParams() + env := helpers.NewL2FaultProofEnv(t, testCfg, tp, helpers.NewBatcherCfg()) + channelTimeout := env.Sd.ChainSpec.ChannelTimeout(0) + + const NumL2Blocks = 10 + + // Build NumL2Blocks empty blocks on L2 + for i := 0; i < NumL2Blocks; i++ { + env.Sequencer.ActL2StartBlock(t) + env.Sequencer.ActL2EndBlock(t) + } + + // Buffer the first half of L2 blocks in the batcher, and submit it. + for i := 0; i < NumL2Blocks/2; i++ { + env.Batcher.ActL2BatchBuffer(t) + } + firstFrame := env.Batcher.ReadNextOutputFrame(t) + env.Batcher.ActL2BatchSubmitRaw(t, firstFrame) + + // Instruct the batcher to submit the first channel frame to L1, and include the transaction. + env.Miner.ActL1StartBlock(12)(t) + env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t) + env.Miner.ActL1EndBlock(t) + + // Finalize the block with the first channel frame on L1. + env.Miner.ActL1SafeNext(t) + + // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. + env.Sequencer.ActL1HeadSignal(t) + env.Sequencer.ActL2PipelineFull(t) + + // Ensure that the safe head has not advanced - the channel is incomplete. + l2SafeHead := env.Engine.L2Chain().CurrentSafeBlock() + require.Equal(t, uint64(0), l2SafeHead.Number.Uint64()) + + // Time out the channel by mining `channelTimeout + 1` empty blocks on L1. + for i := uint64(0); i < channelTimeout+1; i++ { + env.Miner.ActEmptyBlock(t) + env.Miner.ActL1SafeNext(t) + } + + // Instruct the sequencer to derive the L2 chain. + env.Sequencer.ActL1HeadSignal(t) + env.Sequencer.ActL2PipelineFull(t) + + // Ensure the safe head has still not advanced. + l2SafeHead = env.Engine.L2Chain().CurrentSafeBlock() + require.Equal(t, uint64(0), l2SafeHead.Number.Uint64()) + + // Cache the second and final frame of the channel from the batcher, but do not submit it yet. + for i := 0; i < NumL2Blocks/2; i++ { + env.Batcher.ActL2BatchBuffer(t) + } + env.Batcher.ActL2ChannelClose(t) + finalFrame := env.Batcher.ReadNextOutputFrame(t) + + // Submit the final frame of the timed out channel, now that the channel has timed out. + env.Batcher.ActL2BatchSubmitRaw(t, finalFrame) + + // Instruct the batcher to submit the second channel frame to L1, and include the transaction. + env.Miner.ActL1StartBlock(12)(t) + env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t) + env.Miner.ActL1EndBlock(t) + + // Finalize the block with the second channel frame on L1. + env.Miner.ActL1SafeNext(t) + + // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. + env.Sequencer.ActL1HeadSignal(t) + env.Sequencer.ActL2PipelineFull(t) + + // Ensure the safe head has still not advanced. + l2SafeHead = env.Engine.L2Chain().CurrentSafeBlock() + require.Equal(t, uint64(0), l2SafeHead.Number.Uint64()) + + // Instruct the batcher to submit the blocks to L1 in a new channel. + for _, frame := range [][]byte{firstFrame, finalFrame} { + env.Batcher.ActL2BatchSubmitRaw(t, frame) + env.Miner.ActL1StartBlock(12)(t) + env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t) + env.Miner.ActL1EndBlock(t) + + // Finalize the block with the resubmitted channel frames on L1. + env.Miner.ActL1SafeNext(t) } // Instruct the sequencer to derive the L2 chain. @@ -128,4 +216,19 @@ func Test_ProgramAction_ChannelTimeout(gt *testing.T) { helpers.ExpectError(claim.ErrClaimNotValid), helpers.WithL2Claim(common.HexToHash("0xdeadbeef")), ) + matrix.AddTestCase( + "CloseChannelLate-HonestClaim", + nil, + helpers.LatestForkOnly, + runChannelTimeoutTest_CloseChannelLate, + helpers.ExpectNoError(), + ) + matrix.AddTestCase( + "CloseChannelLate-JunkClaim", + nil, + helpers.LatestForkOnly, + runChannelTimeoutTest_CloseChannelLate, + helpers.ExpectError(claim.ErrClaimNotValid), + helpers.WithL2Claim(common.HexToHash("0xdeadbeef")), + ) } diff --git a/op-e2e/actions/proofs/helpers/env.go b/op-e2e/actions/proofs/helpers/env.go index df0f7e92bdc2..6d970cfbe0d6 100644 --- a/op-e2e/actions/proofs/helpers/env.go +++ b/op-e2e/actions/proofs/helpers/env.go @@ -38,7 +38,7 @@ type L2FaultProofEnv struct { func NewL2FaultProofEnv[c any](t helpers.Testing, testCfg *TestCfg[c], tp *e2eutils.TestParams, batcherCfg *helpers.BatcherCfg) *L2FaultProofEnv { log := testlog.Logger(t, log.LvlDebug) - dp := NewDeployParams(t, func(dp *e2eutils.DeployParams) { + dp := NewDeployParams(t, tp, func(dp *e2eutils.DeployParams) { genesisBlock := hexutil.Uint64(0) // Enable cancun always @@ -208,8 +208,8 @@ func NewTestParams(params ...TestParam) *e2eutils.TestParams { type DeployParam func(p *e2eutils.DeployParams) -func NewDeployParams(t helpers.Testing, params ...DeployParam) *e2eutils.DeployParams { - dfault := e2eutils.MakeDeployParams(t, NewTestParams()) +func NewDeployParams(t helpers.Testing, tp *e2eutils.TestParams, params ...DeployParam) *e2eutils.DeployParams { + dfault := e2eutils.MakeDeployParams(t, tp) for _, apply := range params { apply(dfault) } From c9a4a7caebf925292dcf1e655d541c07ed44e676 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Wed, 18 Sep 2024 21:38:24 -0600 Subject: [PATCH 196/264] ci: separate invariant runs from fuzz runs (#11982) Using 10k invariant runs would be ridiculously slow. --- .circleci/config.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e0c54fce2dd3..c4182af49189 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -565,6 +565,14 @@ jobs: description: Number of fuzz runs to apply type: integer default: 512 + test_invariant_runs: + description: Number of invariant runs to apply + type: integer + default: 32 + test_invariant_depth: + description: Depth of invariant runs + type: integer + default: 64 test_timeout: description: Timeout for running tests type: string @@ -616,7 +624,8 @@ jobs: TEST_FILES=$(echo "$TEST_FILES" | circleci tests split --split-by=timings) TEST_FILES=$(echo "$TEST_FILES" | sed 's|^test/||') MATCH_PATH="./test/{$(echo "$TEST_FILES" | paste -sd "," -)}" - export FOUNDRY_INVARIANT_RUNS=<> + export FOUNDRY_INVARIANT_RUNS=<> + export FOUNDRY_INVARIANT_DEPTH=<> forge test --deny-warnings --fuzz-runs <> --match-path "$MATCH_PATH" environment: FOUNDRY_PROFILE: ci @@ -1596,6 +1605,8 @@ workflows: test_list: git diff origin/develop...HEAD --name-only -- './test/**/*.t.sol' | sed 's|packages/contracts-bedrock/||' test_timeout: 1h test_fuzz_runs: 10000 + test_invariant_runs: 128 + test_invariant_depth: 512 - contracts-bedrock-coverage - contracts-bedrock-checks: requires: From 9ab67384f72e2ae5a3d949721f66e5ed8dcb434e Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Thu, 19 Sep 2024 13:47:31 +1000 Subject: [PATCH 197/264] ci: Restore ci-builder docker release and remove invalid op-challenger-big-docker-release (#11997) --- .circleci/config.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c4182af49189..756cd35f02db 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1958,13 +1958,13 @@ workflows: requires: - op-supervisor-docker-release - docker-build: - name: op-challenger-big-docker-release + name: proofs-tools-docker-release filters: tags: - only: /^op-challenger\/v.*/ + only: /^proofs-tools\/v.*/ branches: ignore: /.*/ - docker_name: ci-builder + docker_name: proofs-tools docker_tags: <>,latest publish: true release: true @@ -1974,13 +1974,13 @@ workflows: requires: - hold - docker-build: - name: proofs-tools-docker-release + name: ci-builder-docker-release filters: tags: - only: /^proofs-tools\/v.*/ + only: /^ci-builder\/v.*/ branches: ignore: /.*/ - docker_name: proofs-tools + docker_name: ci-builder docker_tags: <>,latest publish: true release: true From d4b1003d4ec985ebe65ed4ba8e8ae2886e29b0c6 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Wed, 18 Sep 2024 22:24:29 -0600 Subject: [PATCH 198/264] maint(ci): clean up release job (#11996) Cleans up the release job by turning it into a matrix. --- .circleci/config.yml | 237 ++++++++----------------------------------- 1 file changed, 45 insertions(+), 192 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 756cd35f02db..1534facdf621 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1775,6 +1775,7 @@ workflows: not: equal: [ scheduled_pipeline, << pipeline.trigger_source >> ] jobs: + # Wait for approval on the release - hold: type: approval filters: @@ -1782,227 +1783,79 @@ workflows: only: /^(da-server|ci-builder(-rust)?|proofs-tools|ufm-[a-z0-9\-]*|op-[a-z0-9\-]*)\/v.*/ branches: ignore: /.*/ + # Standard (medium) cross-platform docker images go here - docker-build: - name: op-node-docker-release - filters: - tags: - only: /^op-node\/v.*/ - branches: - ignore: /.*/ - docker_name: op-node + matrix: + parameters: + docker_name: + - op-node + - op-batcher + - op-proposer + - op-challenger + - op-dispute-mon + - op-conductor + - da-server + - op-ufm + - op-supervisor + name: <>-docker-release docker_tags: <> - requires: ['hold'] platforms: "linux/amd64,linux/arm64" publish: true release: true - context: - - oplabs-gcr-release - - check-cross-platform: - name: op-node-cross-platform - op_component: op-node - requires: - - op-node-docker-release - - docker-build: - name: op-batcher-docker-release filters: tags: - only: /^op-batcher\/v.*/ + only: /^<>\/v.*/ branches: ignore: /.*/ - docker_name: op-batcher - docker_tags: <> - requires: ['hold'] - platforms: "linux/amd64,linux/arm64" - publish: true - release: true context: - oplabs-gcr-release - - check-cross-platform: - name: op-batcher-cross-platform - op_component: op-batcher requires: - - op-batcher-docker-release - - docker-build: - name: op-proposer-docker-release - filters: - tags: - only: /^op-proposer\/v.*/ - branches: - ignore: /.*/ - docker_name: op-proposer - docker_tags: <> - requires: ['hold'] - platforms: "linux/amd64,linux/arm64" - publish: true - release: true - context: - - oplabs-gcr-release + - hold + # Checks for cross-platform images go here - check-cross-platform: - name: op-proposer-cross-platform - op_component: op-proposer + matrix: + parameters: + op_component: + - op-node + - op-batcher + - op-proposer + - op-challenger + - op-dispute-mon + - op-conductor + - da-server + - op-ufm + - op-supervisor + name: <>-cross-platform requires: + - op-node-docker-release + - op-batcher-docker-release - op-proposer-docker-release - - docker-build: - name: op-challenger-docker-release - filters: - tags: - only: /^op-challenger\/v.*/ - branches: - ignore: /.*/ - docker_name: op-challenger - docker_tags: <> - requires: ['hold'] - platforms: "linux/amd64,linux/arm64" - publish: true - release: true - context: - - oplabs-gcr-release - - check-cross-platform: - name: op-challenger-cross-platform - op_component: op-challenger - requires: - op-challenger-docker-release - - docker-build: - name: op-dispute-mon-docker-release - filters: - tags: - only: /^op-dispute-mon\/v.*/ - branches: - ignore: /.*/ - docker_name: op-dispute-mon - docker_tags: <> - requires: ['hold'] - platforms: "linux/amd64,linux/arm64" - publish: true - release: true - context: - - oplabs-gcr-release - - check-cross-platform: - name: op-dispute-mon-cross-platform - op_component: op-dispute-mon - requires: - op-dispute-mon-docker-release - - docker-build: - name: op-conductor-docker-release - filters: - tags: - only: /^op-conductor\/v.*/ - branches: - ignore: /.*/ - docker_name: op-conductor - docker_tags: <> - requires: ['hold'] - platforms: "linux/amd64,linux/arm64" - publish: true - release: true - context: - - oplabs-gcr-release - - check-cross-platform: - name: op-conductor-cross-platform - op_component: op-conductor - requires: - op-conductor-docker-release - - docker-build: - name: da-server-docker-release - filters: - tags: - only: /^da-server\/v.*/ - branches: - ignore: /.*/ - docker_name: da-server - docker_tags: <> - requires: ['hold'] - platforms: "linux/amd64,linux/arm64" - publish: true - release: true - context: - - oplabs-gcr-release - - check-cross-platform: - name: da-server-cross-platform - op_component: da-server - requires: - da-server-docker-release - - docker-build: - name: op-ufm-docker-release - filters: - tags: - only: /^op-ufm\/v.*/ - branches: - ignore: /.*/ - docker_name: op-ufm - docker_tags: <> - publish: true - release: true - context: - - oplabs-gcr-release - requires: - - hold - - docker-build: - name: op-supervisor-docker-release - filters: - tags: - only: /^op-supervisor\/v.*/ - branches: - ignore: /.*/ - docker_name: op-supervisor - docker_tags: <> - requires: ['hold'] - platforms: "linux/amd64,linux/arm64" - publish: true - release: true - context: - - oplabs-gcr-release - - check-cross-platform: - name: op-supervisor-cross-platform - op_component: op-supervisor - requires: + - op-ufm-docker-release - op-supervisor-docker-release + # Standard (xlarge) AMD-only docker images go here - docker-build: - name: proofs-tools-docker-release - filters: - tags: - only: /^proofs-tools\/v.*/ - branches: - ignore: /.*/ - docker_name: proofs-tools - docker_tags: <>,latest - publish: true - release: true + matrix: + parameters: + docker_name: + - ci-builder + - ci-builder-rust + - proofs-tools + name: <>-docker-release resource_class: xlarge - context: - - oplabs-gcr - requires: - - hold - - docker-build: - name: ci-builder-docker-release - filters: - tags: - only: /^ci-builder\/v.*/ - branches: - ignore: /.*/ - docker_name: ci-builder - docker_tags: <>,latest + docker_tags: <> publish: true release: true - resource_class: xlarge - context: - - oplabs-gcr - requires: - - hold - - docker-build: - name: ci-builder-rust-docker-release filters: tags: - only: /^ci-builder-rust\/v.*/ + only: /^<>\/v.*/ branches: ignore: /.*/ - docker_name: ci-builder-rust - docker_tags: <>,latest - publish: true - release: true - resource_class: xlarge context: - - oplabs-gcr + - oplabs-gcr-release requires: - hold From a080bd23666513269ff241f1b7bc3bce74b6ad15 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Thu, 19 Sep 2024 00:54:32 -0600 Subject: [PATCH 199/264] maint(ci): clean up scheduled docker publish (#11999) Same idea again, cleaning up the scheduled docker publish with the same technique as the previous PR. --- .circleci/config.yml | 128 +++++++++---------------------------------- 1 file changed, 25 insertions(+), 103 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1534facdf621..4f3706e24340 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1954,106 +1954,18 @@ workflows: - equal: [ true, << pipeline.parameters.docker_publish_dispatch >> ] jobs: - docker-build: - name: op-node-docker-publish - docker_name: op-node - docker_tags: <>,<> - platforms: "linux/amd64,linux/arm64" - publish: true - context: - - oplabs-gcr - - slack - - check-cross-platform: - name: op-node-cross-platform - op_component: op-node - requires: - - op-node-docker-publish - - docker-build: - name: op-batcher-docker-publish - docker_name: op-batcher - docker_tags: <>,<> - platforms: "linux/amd64,linux/arm64" - publish: true - context: - - oplabs-gcr - - slack - - check-cross-platform: - name: op-batcher-cross-platform - op_component: op-batcher - requires: - - op-batcher-docker-publish - - docker-build: - name: op-program-docker-publish - docker_name: op-program - docker_tags: <>,<> - platforms: "linux/amd64,linux/arm64" - publish: true - context: - - oplabs-gcr - - slack - - check-cross-platform: - name: op-program-cross-platform - op_component: op-program - requires: - - op-program-docker-publish - - docker-build: - name: op-proposer-docker-publish - docker_name: op-proposer - docker_tags: <>,<> - platforms: "linux/amd64,linux/arm64" - publish: true - context: - - oplabs-gcr - - slack - - check-cross-platform: - name: op-proposer-cross-platform - op_component: op-proposer - requires: - - op-proposer-docker-publish - - docker-build: - name: op-challenger-docker-publish - docker_name: op-challenger - docker_tags: <>,<> - platforms: "linux/amd64,linux/arm64" - publish: true - context: - - oplabs-gcr - - slack - - check-cross-platform: - name: op-challenger-cross-platform - op_component: op-challenger - requires: - - op-challenger-docker-publish - - docker-build: - name: op-dispute-mon-docker-publish - docker_name: op-dispute-mon - docker_tags: <>,<> - platforms: "linux/amd64,linux/arm64" - publish: true - context: - - oplabs-gcr - - slack - - check-cross-platform: - name: op-dispute-mon-cross-platform - op_component: op-dispute-mon - requires: - - op-dispute-mon-docker-publish - - docker-build: - name: op-conductor-docker-publish - docker_name: op-conductor - docker_tags: <>,<> - platforms: "linux/amd64,linux/arm64" - publish: true - context: - - oplabs-gcr - - slack - - check-cross-platform: - name: op-conductor-cross-platform - op_component: op-conductor - requires: - - op-conductor-docker-publish - - docker-build: - name: op-supervisor-docker-publish - docker_name: op-supervisor + matrix: + parameters: + docker_name: + - op-node + - op-batcher + - op-program + - op-proposer + - op-challenger + - op-dispute-mon + - op-conductor + - op-supervisor + name: <>-docker-publish docker_tags: <>,<> platforms: "linux/amd64,linux/arm64" publish: true @@ -2061,10 +1973,20 @@ workflows: - oplabs-gcr - slack - check-cross-platform: - name: op-supervisor-cross-platform - op_component: op-supervisor + matrix: + parameters: + op_component: + - op-node + - op-batcher + - op-program + - op-proposer + - op-challenger + - op-dispute-mon + - op-conductor + - op-supervisor + name: <>-cross-platform requires: - - op-supervisor-docker-publish + - <>-docker-publish - docker-build: name: contracts-bedrock-docker-publish docker_name: contracts-bedrock From 57f9fbf823520dbffceec82cd73220a1dfc1b978 Mon Sep 17 00:00:00 2001 From: Matt Solomon Date: Thu, 19 Sep 2024 07:38:13 -0700 Subject: [PATCH 200/264] OPSM: More assertions (#11994) * refactor: rename var for clarity * test: add more assertions from ChainAssertions, and some new ones * chore: ensure unique, clear, consistent revert string IDs also sorts methods alphabetically for clarity * fix: var name after rebase * style: forge fmt * revert proxyAdmin -> superchainProxyAdmin name change for now * Update packages/contracts-bedrock/scripts/DeployImplementations.s.sol Co-authored-by: Maurelian * chore: small tweaks from pr feedback --------- Co-authored-by: Maurelian --- .../scripts/DeployImplementations.s.sol | 175 +++++++++++++++++- .../scripts/DeployOPChain.s.sol | 87 +++++---- .../scripts/DeploySuperchain.s.sol | 59 +++++- .../scripts/libraries/DeployUtils.sol | 10 +- .../test/DeploySuperchain.t.sol | 4 +- .../fixtures/test-deploy-superchain-in.toml | 2 +- 6 files changed, 286 insertions(+), 51 deletions(-) diff --git a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol index 4c413bfe3edd..b68b4243c195 100644 --- a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol +++ b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol @@ -5,6 +5,12 @@ import { Script } from "forge-std/Script.sol"; import { LibString } from "@solady/utils/LibString.sol"; +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; + +import { Constants } from "src/libraries/Constants.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; + import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { Proxy } from "src/universal/Proxy.sol"; import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol"; @@ -191,7 +197,7 @@ contract DeployImplementationsOutput is BaseDeployIO { require(false, "DeployImplementationsOutput: not implemented"); } - function checkOutput(DeployImplementationsInput) public { + function checkOutput(DeployImplementationsInput _dii) public { address[] memory addrs = Solarray.addresses( address(this.opsmProxy()), address(this.optimismPortalImpl()), @@ -207,7 +213,7 @@ contract DeployImplementationsOutput is BaseDeployIO { ); DeployUtils.assertValidContractAddresses(addrs); - // TODO Also add the assertions for the implementation contracts from ChainAssertions.sol + assertValidDeploy(_dii); } function opsmProxy() public returns (OPStackManager) { @@ -265,6 +271,171 @@ contract DeployImplementationsOutput is BaseDeployIO { DeployUtils.assertValidContractAddress(address(_disputeGameFactoryImpl)); return _disputeGameFactoryImpl; } + + // -------- Deployment Assertions -------- + function assertValidDeploy(DeployImplementationsInput _dii) public { + assertValidDelayedWETHImpl(_dii); + assertValidDisputeGameFactoryImpl(_dii); + assertValidL1CrossDomainMessengerImpl(_dii); + assertValidL1ERC721BridgeImpl(_dii); + assertValidL1StandardBridgeImpl(_dii); + assertValidMipsSingleton(_dii); + assertValidOpsmProxy(_dii); + assertValidOpsmImpl(_dii); + assertValidOptimismMintableERC20FactoryImpl(_dii); + assertValidOptimismPortalImpl(_dii); + assertValidPreimageOracleSingleton(_dii); + assertValidSystemConfigImpl(_dii); + } + + function assertValidOpsmProxy(DeployImplementationsInput _dii) internal { + // First we check the proxy as itself. + Proxy proxy = Proxy(payable(address(opsmProxy()))); + vm.prank(address(0)); + address admin = proxy.admin(); + require(admin == address(_dii.superchainProxyAdmin()), "OPSMP-10"); + + // Then we check the proxy as OPSM. + DeployUtils.assertInitialized({ _contractAddress: address(opsmProxy()), _slot: 0, _offset: 0 }); + require(address(opsmProxy().superchainConfig()) == address(_dii.superchainConfigProxy()), "OPSMP-20"); + require(address(opsmProxy().protocolVersions()) == address(_dii.protocolVersionsProxy()), "OPSMP-30"); + require(LibString.eq(opsmProxy().latestRelease(), _dii.release()), "OPSMP-50"); // Initial release is latest. + } + + function assertValidOpsmImpl(DeployImplementationsInput _dii) internal { + Proxy proxy = Proxy(payable(address(opsmProxy()))); + vm.prank(address(0)); + OPStackManager impl = OPStackManager(proxy.implementation()); + DeployUtils.assertInitialized({ _contractAddress: address(impl), _slot: 0, _offset: 0 }); + require(address(impl.superchainConfig()) == address(_dii.superchainConfigProxy()), "OPSMI-10"); + require(address(impl.protocolVersions()) == address(_dii.protocolVersionsProxy()), "OPSMI-20"); + } + + function assertValidOptimismPortalImpl(DeployImplementationsInput) internal view { + OptimismPortal2 portal = optimismPortalImpl(); + + DeployUtils.assertInitialized({ _contractAddress: address(portal), _slot: 0, _offset: 0 }); + + require(address(portal.disputeGameFactory()) == address(0), "PORTAL-10"); + require(address(portal.systemConfig()) == address(0), "PORTAL-20"); + require(address(portal.superchainConfig()) == address(0), "PORTAL-30"); + require(portal.l2Sender() == Constants.DEFAULT_L2_SENDER, "PORTAL-40"); + + // This slot is the custom gas token _balance and this check ensures + // that it stays unset for forwards compatibility with custom gas token. + require(vm.load(address(portal), bytes32(uint256(61))) == bytes32(0), "PORTAL-50"); + } + + function assertValidDelayedWETHImpl(DeployImplementationsInput _dii) internal view { + DelayedWETH delayedWETH = delayedWETHImpl(); + + DeployUtils.assertInitialized({ _contractAddress: address(delayedWETH), _slot: 0, _offset: 0 }); + + require(delayedWETH.owner() == address(0), "DW-10"); + require(delayedWETH.delay() == _dii.withdrawalDelaySeconds(), "DW-20"); + require(delayedWETH.config() == ISuperchainConfig(address(0)), "DW-30"); + } + + function assertValidPreimageOracleSingleton(DeployImplementationsInput _dii) internal view { + PreimageOracle oracle = preimageOracleSingleton(); + + require(oracle.minProposalSize() == _dii.minProposalSizeBytes(), "PO-10"); + require(oracle.challengePeriod() == _dii.challengePeriodSeconds(), "PO-20"); + } + + function assertValidMipsSingleton(DeployImplementationsInput) internal view { + MIPS mips = mipsSingleton(); + + require(address(mips.oracle()) == address(preimageOracleSingleton()), "MIPS-10"); + } + + function assertValidSystemConfigImpl(DeployImplementationsInput) internal view { + SystemConfig systemConfig = systemConfigImpl(); + + DeployUtils.assertInitialized({ _contractAddress: address(systemConfig), _slot: 0, _offset: 0 }); + + require(systemConfig.owner() == address(0xdead), "SYSCON-10"); + require(systemConfig.overhead() == 0, "SYSCON-20"); + require(systemConfig.scalar() == uint256(0x01) << 248, "SYSCON-30"); + require(systemConfig.basefeeScalar() == 0, "SYSCON-40"); + require(systemConfig.blobbasefeeScalar() == 0, "SYSCON-50"); + require(systemConfig.batcherHash() == bytes32(0), "SYSCON-60"); + require(systemConfig.gasLimit() == 1, "SYSCON-70"); + require(systemConfig.unsafeBlockSigner() == address(0), "SYSCON-80"); + + IResourceMetering.ResourceConfig memory resourceConfig = systemConfig.resourceConfig(); + require(resourceConfig.maxResourceLimit == 1, "SYSCON-90"); + require(resourceConfig.elasticityMultiplier == 1, "SYSCON-100"); + require(resourceConfig.baseFeeMaxChangeDenominator == 2, "SYSCON-110"); + require(resourceConfig.systemTxMaxGas == 0, "SYSCON-120"); + require(resourceConfig.minimumBaseFee == 0, "SYSCON-130"); + require(resourceConfig.maximumBaseFee == 0, "SYSCON-140"); + + require(systemConfig.startBlock() == type(uint256).max, "SYSCON-150"); + require(systemConfig.batchInbox() == address(0), "SYSCON-160"); + require(systemConfig.l1CrossDomainMessenger() == address(0), "SYSCON-170"); + require(systemConfig.l1ERC721Bridge() == address(0), "SYSCON-180"); + require(systemConfig.l1StandardBridge() == address(0), "SYSCON-190"); + require(systemConfig.disputeGameFactory() == address(0), "SYSCON-200"); + require(systemConfig.optimismPortal() == address(0), "SYSCON-210"); + require(systemConfig.optimismMintableERC20Factory() == address(0), "SYSCON-220"); + } + + function assertValidL1CrossDomainMessengerImpl(DeployImplementationsInput) internal view { + L1CrossDomainMessenger messenger = l1CrossDomainMessengerImpl(); + + DeployUtils.assertInitialized({ _contractAddress: address(messenger), _slot: 0, _offset: 20 }); + + require(address(messenger.OTHER_MESSENGER()) == Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L1xDM-10"); + require(address(messenger.otherMessenger()) == Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L1xDM-20"); + require(address(messenger.PORTAL()) == address(0), "L1xDM-30"); + require(address(messenger.portal()) == address(0), "L1xDM-40"); + require(address(messenger.superchainConfig()) == address(0), "L1xDM-50"); + + bytes32 xdmSenderSlot = vm.load(address(messenger), bytes32(uint256(204))); + require(address(uint160(uint256(xdmSenderSlot))) == Constants.DEFAULT_L2_SENDER, "L1xDM-60"); + } + + function assertValidL1ERC721BridgeImpl(DeployImplementationsInput) internal view { + L1ERC721Bridge bridge = l1ERC721BridgeImpl(); + + DeployUtils.assertInitialized({ _contractAddress: address(bridge), _slot: 0, _offset: 0 }); + + require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_ERC721_BRIDGE, "L721B-10"); + require(address(bridge.otherBridge()) == Predeploys.L2_ERC721_BRIDGE, "L721B-20"); + require(address(bridge.MESSENGER()) == address(0), "L721B-30"); + require(address(bridge.messenger()) == address(0), "L721B-40"); + require(address(bridge.superchainConfig()) == address(0), "L721B-50"); + } + + function assertValidL1StandardBridgeImpl(DeployImplementationsInput) internal view { + L1StandardBridge bridge = l1StandardBridgeImpl(); + + DeployUtils.assertInitialized({ _contractAddress: address(bridge), _slot: 0, _offset: 0 }); + + require(address(bridge.MESSENGER()) == address(0), "L1SB-10"); + require(address(bridge.messenger()) == address(0), "L1SB-20"); + require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_STANDARD_BRIDGE, "L1SB-30"); + require(address(bridge.otherBridge()) == Predeploys.L2_STANDARD_BRIDGE, "L1SB-40"); + require(address(bridge.superchainConfig()) == address(0), "L1SB-50"); + } + + function assertValidOptimismMintableERC20FactoryImpl(DeployImplementationsInput) internal view { + OptimismMintableERC20Factory factory = optimismMintableERC20FactoryImpl(); + + DeployUtils.assertInitialized({ _contractAddress: address(factory), _slot: 0, _offset: 0 }); + + require(address(factory.BRIDGE()) == address(0), "MERC20F-10"); + require(address(factory.bridge()) == address(0), "MERC20F-20"); + } + + function assertValidDisputeGameFactoryImpl(DeployImplementationsInput) internal view { + DisputeGameFactory factory = disputeGameFactoryImpl(); + + DeployUtils.assertInitialized({ _contractAddress: address(factory), _slot: 0, _offset: 0 }); + + require(address(factory.owner()) == address(0), "DG-10"); + } } contract DeployImplementations is Script { diff --git a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol index fbf8b8054531..a13c1e581eac 100644 --- a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol @@ -274,16 +274,17 @@ contract DeployOPChainOutput is BaseDeployIO { return _delayedWETHPermissionlessGameProxy; } - // -------- Assertions on chain architecture -------- + // -------- Deployment Assertions -------- function assertValidDeploy(DeployOPChainInput _doi) internal view { - assertValidSystemConfig(_doi); + assertValidDelayedWETHs(_doi); + assertValidDisputeGameFactory(_doi); assertValidL1CrossDomainMessenger(_doi); + assertValidL1ERC721Bridge(_doi); assertValidL1StandardBridge(_doi); assertValidOptimismMintableERC20Factory(_doi); assertValidOptimismPortal(_doi); - assertValidDisputeGameFactory(_doi); - assertValidDelayedWETHs(_doi); + assertValidSystemConfig(_doi); // TODO Other FP assertions like the dispute games, anchor state registry, etc. // TODO add initialization assertions } @@ -293,34 +294,38 @@ contract DeployOPChainOutput is BaseDeployIO { DeployUtils.assertInitialized({ _contractAddress: address(systemConfig), _slot: 0, _offset: 0 }); - require(systemConfig.owner() == _doi.systemConfigOwner(), "SC-10"); - require(systemConfig.basefeeScalar() == _doi.basefeeScalar(), "SC-20"); - require(systemConfig.blobbasefeeScalar() == _doi.blobBaseFeeScalar(), "SC-30"); - require(systemConfig.batcherHash() == bytes32(uint256(uint160(_doi.batcher()))), "SC-40"); - require(systemConfig.gasLimit() == uint64(30000000), "SC-50"); // TODO allow other gas limits? - require(systemConfig.unsafeBlockSigner() == _doi.unsafeBlockSigner(), "SC-60"); - require(systemConfig.scalar() >> 248 == 1, "SC-70"); + require(systemConfig.owner() == _doi.systemConfigOwner(), "SYSCON-10"); + require(systemConfig.basefeeScalar() == _doi.basefeeScalar(), "SYSCON-20"); + require(systemConfig.blobbasefeeScalar() == _doi.blobBaseFeeScalar(), "SYSCON-30"); + require(systemConfig.batcherHash() == bytes32(uint256(uint160(_doi.batcher()))), "SYSCON-40"); + require(systemConfig.gasLimit() == uint64(30000000), "SYSCON-50"); // TODO allow other gas limits? + require(systemConfig.unsafeBlockSigner() == _doi.unsafeBlockSigner(), "SYSCON-60"); + require(systemConfig.scalar() >> 248 == 1, "SYSCON-70"); IResourceMetering.ResourceConfig memory rConfig = Constants.DEFAULT_RESOURCE_CONFIG(); IResourceMetering.ResourceConfig memory outputConfig = systemConfig.resourceConfig(); - require(outputConfig.maxResourceLimit == rConfig.maxResourceLimit, "SC-80"); - require(outputConfig.elasticityMultiplier == rConfig.elasticityMultiplier, "SC-90"); - require(outputConfig.baseFeeMaxChangeDenominator == rConfig.baseFeeMaxChangeDenominator, "SC-100"); - require(outputConfig.systemTxMaxGas == rConfig.systemTxMaxGas, "SC-110"); - require(outputConfig.minimumBaseFee == rConfig.minimumBaseFee, "SC-120"); - require(outputConfig.maximumBaseFee == rConfig.maximumBaseFee, "SC-130"); - - require(systemConfig.startBlock() == block.number, "SC-140"); - require(systemConfig.batchInbox() == _doi.opsmProxy().chainIdToBatchInboxAddress(_doi.l2ChainId()), "SC-150"); - - require(systemConfig.l1CrossDomainMessenger() == address(l1CrossDomainMessengerProxy()), "SC-160"); - require(systemConfig.l1ERC721Bridge() == address(l1ERC721BridgeProxy()), "SC-170"); - require(systemConfig.l1StandardBridge() == address(l1StandardBridgeProxy()), "SC-180"); - require(systemConfig.disputeGameFactory() == address(disputeGameFactoryProxy()), "SC-190"); - require(systemConfig.optimismPortal() == address(optimismPortalProxy()), "SC-200"); - require(systemConfig.optimismMintableERC20Factory() == address(optimismMintableERC20FactoryProxy()), "SC-210"); + require(outputConfig.maxResourceLimit == rConfig.maxResourceLimit, "SYSCON-80"); + require(outputConfig.elasticityMultiplier == rConfig.elasticityMultiplier, "SYSCON-90"); + require(outputConfig.baseFeeMaxChangeDenominator == rConfig.baseFeeMaxChangeDenominator, "SYSCON-100"); + require(outputConfig.systemTxMaxGas == rConfig.systemTxMaxGas, "SYSCON-110"); + require(outputConfig.minimumBaseFee == rConfig.minimumBaseFee, "SYSCON-120"); + require(outputConfig.maximumBaseFee == rConfig.maximumBaseFee, "SYSCON-130"); + + require(systemConfig.startBlock() == block.number, "SYSCON-140"); + require( + systemConfig.batchInbox() == _doi.opsmProxy().chainIdToBatchInboxAddress(_doi.l2ChainId()), "SYSCON-150" + ); + + require(systemConfig.l1CrossDomainMessenger() == address(l1CrossDomainMessengerProxy()), "SYSCON-160"); + require(systemConfig.l1ERC721Bridge() == address(l1ERC721BridgeProxy()), "SYSCON-170"); + require(systemConfig.l1StandardBridge() == address(l1StandardBridgeProxy()), "SYSCON-180"); + require(systemConfig.disputeGameFactory() == address(disputeGameFactoryProxy()), "SYSCON-190"); + require(systemConfig.optimismPortal() == address(optimismPortalProxy()), "SYSCON-200"); + require( + systemConfig.optimismMintableERC20Factory() == address(optimismMintableERC20FactoryProxy()), "SYSCON-210" + ); (address gasPayingToken,) = systemConfig.gasPayingToken(); - require(gasPayingToken == Constants.ETHER, "SC-220"); + require(gasPayingToken == Constants.ETHER, "SYSCON-220"); } function assertValidL1CrossDomainMessenger(DeployOPChainInput _doi) internal view { @@ -357,8 +362,8 @@ contract DeployOPChainOutput is BaseDeployIO { DeployUtils.assertInitialized({ _contractAddress: address(factory), _slot: 0, _offset: 0 }); - require(factory.BRIDGE() == address(l1StandardBridgeProxy()), "OMEF-10"); - require(factory.bridge() == address(l1StandardBridgeProxy()), "OMEF-20"); + require(factory.BRIDGE() == address(l1StandardBridgeProxy()), "MERC20F-10"); + require(factory.bridge() == address(l1StandardBridgeProxy()), "MERC20F-20"); } function assertValidL1ERC721Bridge(DeployOPChainInput _doi) internal view { @@ -366,24 +371,24 @@ contract DeployOPChainOutput is BaseDeployIO { DeployUtils.assertInitialized({ _contractAddress: address(bridge), _slot: 0, _offset: 0 }); - require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_ERC721_BRIDGE, "LEB-10"); - require(address(bridge.otherBridge()) == Predeploys.L2_ERC721_BRIDGE, "LEB-20"); + require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_ERC721_BRIDGE, "L721B-10"); + require(address(bridge.otherBridge()) == Predeploys.L2_ERC721_BRIDGE, "L721B-20"); - require(address(bridge.MESSENGER()) == address(l1CrossDomainMessengerProxy()), "LEB-30"); - require(address(bridge.messenger()) == address(l1CrossDomainMessengerProxy()), "LEB-40"); - require(address(bridge.superchainConfig()) == address(_doi.opsmProxy().superchainConfig()), "LEB-50"); + require(address(bridge.MESSENGER()) == address(l1CrossDomainMessengerProxy()), "L721B-30"); + require(address(bridge.messenger()) == address(l1CrossDomainMessengerProxy()), "L721B-40"); + require(address(bridge.superchainConfig()) == address(_doi.opsmProxy().superchainConfig()), "L721B-50"); } function assertValidOptimismPortal(DeployOPChainInput _doi) internal view { OptimismPortal2 portal = optimismPortalProxy(); ISuperchainConfig superchainConfig = ISuperchainConfig(address(_doi.opsmProxy().superchainConfig())); - require(address(portal.disputeGameFactory()) == address(disputeGameFactoryProxy()), "OP-10"); - require(address(portal.systemConfig()) == address(systemConfigProxy()), "OP-20"); - require(address(portal.superchainConfig()) == address(superchainConfig), "OP-30"); - require(portal.guardian() == superchainConfig.guardian(), "OP-40"); - require(portal.paused() == superchainConfig.paused(), "OP-50"); - require(portal.l2Sender() == Constants.DEFAULT_L2_SENDER, "OP-60"); + require(address(portal.disputeGameFactory()) == address(disputeGameFactoryProxy()), "PORTAL-10"); + require(address(portal.systemConfig()) == address(systemConfigProxy()), "PORTAL-20"); + require(address(portal.superchainConfig()) == address(superchainConfig), "PORTAL-30"); + require(portal.guardian() == superchainConfig.guardian(), "PORTAL-40"); + require(portal.paused() == superchainConfig.paused(), "PORTAL-50"); + require(portal.l2Sender() == Constants.DEFAULT_L2_SENDER, "PORTAL-60"); // This slot is the custom gas token _balance and this check ensures // that it stays unset for forwards compatibility with custom gas token. diff --git a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol index 800833ccaa4f..f1cfdbcf571d 100644 --- a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol +++ b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol @@ -210,7 +210,7 @@ contract DeploySuperchainOutput is BaseDeployIO { // This function can be called to ensure all outputs are correct. Similar to `writeOutputFile`, // it fetches the output values using external calls to the getter methods for safety. - function checkOutput(DeploySuperchainInput) public { + function checkOutput(DeploySuperchainInput _dsi) public { address[] memory addrs = Solarray.addresses( address(this.superchainProxyAdmin()), address(this.superchainConfigImpl()), @@ -230,6 +230,7 @@ contract DeploySuperchainOutput is BaseDeployIO { require(actualProtocolVersionsImpl == address(_protocolVersionsImpl), "200"); // TODO Also add the assertions for the implementation contracts from ChainAssertions.sol + assertValidDeploy(_dsi); } function superchainProxyAdmin() public view returns (ProxyAdmin) { @@ -256,6 +257,62 @@ contract DeploySuperchainOutput is BaseDeployIO { DeployUtils.assertValidContractAddress(address(_protocolVersionsProxy)); return _protocolVersionsProxy; } + + // -------- Deployment Assertions -------- + function assertValidDeploy(DeploySuperchainInput _dsi) public { + assertValidSuperchainProxyAdmin(_dsi); + assertValidSuperchainConfig(_dsi); + assertValidProtocolVersions(_dsi); + } + + function assertValidSuperchainProxyAdmin(DeploySuperchainInput _dsi) internal view { + require(superchainProxyAdmin().owner() == _dsi.proxyAdminOwner(), "SPA-10"); + } + + function assertValidSuperchainConfig(DeploySuperchainInput _dsi) internal { + // Proxy checks. + SuperchainConfig superchainConfig = superchainConfigProxy(); + DeployUtils.assertInitialized({ _contractAddress: address(superchainConfig), _slot: 0, _offset: 0 }); + require(superchainConfig.guardian() == _dsi.guardian(), "SUPCON-10"); + require(superchainConfig.paused() == _dsi.paused(), "SUPCON-20"); + + vm.startPrank(address(0)); + require( + Proxy(payable(address(superchainConfig))).implementation() == address(superchainConfigImpl()), "SUPCON-30" + ); + require(Proxy(payable(address(superchainConfig))).admin() == address(superchainProxyAdmin()), "SUPCON-40"); + vm.stopPrank(); + + // Implementation checks + superchainConfig = superchainConfigImpl(); + require(superchainConfig.guardian() == address(0), "SUPCON-50"); + require(superchainConfig.paused() == false, "SUPCON-60"); + } + + function assertValidProtocolVersions(DeploySuperchainInput _dsi) internal { + // Proxy checks. + ProtocolVersions pv = protocolVersionsProxy(); + DeployUtils.assertInitialized({ _contractAddress: address(pv), _slot: 0, _offset: 0 }); + require(pv.owner() == _dsi.protocolVersionsOwner(), "PV-10"); + require( + ProtocolVersion.unwrap(pv.required()) == ProtocolVersion.unwrap(_dsi.requiredProtocolVersion()), "PV-20" + ); + require( + ProtocolVersion.unwrap(pv.recommended()) == ProtocolVersion.unwrap(_dsi.recommendedProtocolVersion()), + "PV-30" + ); + + vm.startPrank(address(0)); + require(Proxy(payable(address(pv))).implementation() == address(protocolVersionsImpl()), "PV-40"); + require(Proxy(payable(address(pv))).admin() == address(superchainProxyAdmin()), "PV-50"); + vm.stopPrank(); + + // Implementation checks. + pv = protocolVersionsImpl(); + require(pv.owner() == address(0xdead), "PV-60"); + require(ProtocolVersion.unwrap(pv.required()) == 0, "PV-70"); + require(ProtocolVersion.unwrap(pv.recommended()) == 0, "PV-80"); + } } // For all broadcasts in this script we explicitly specify the deployer as `msg.sender` because for diff --git a/packages/contracts-bedrock/scripts/libraries/DeployUtils.sol b/packages/contracts-bedrock/scripts/libraries/DeployUtils.sol index d3586d1b7232..cf8eaf7cb69f 100644 --- a/packages/contracts-bedrock/scripts/libraries/DeployUtils.sol +++ b/packages/contracts-bedrock/scripts/libraries/DeployUtils.sol @@ -48,13 +48,15 @@ library DeployUtils { } } - // Asserts that for a given contract the value of a storage slot at an offset is 1. This - // is used to assert that a contract is initialized. + // Asserts that for a given contract the value of a storage slot at an offset is 1 or + // `type(uint8).max`. The value is set to 1 when a contract is initialized, and set to + // `type(uint8).max` when `_disableInitializers` is called. function assertInitialized(address _contractAddress, uint256 _slot, uint256 _offset) internal view { bytes32 slotVal = vm.load(_contractAddress, bytes32(_slot)); + uint8 value = uint8((uint256(slotVal) >> (_offset * 8)) & 0xFF); require( - uint8((uint256(slotVal) >> (_offset * 8)) & 0xFF) == uint8(1), - "Storage value is not 1 at the given slot and offset" + value == 1 || value == type(uint8).max, + "Value at the given slot and offset does not indicate initialization" ); } } diff --git a/packages/contracts-bedrock/test/DeploySuperchain.t.sol b/packages/contracts-bedrock/test/DeploySuperchain.t.sol index eaf7fe3988a7..1d6650b1cce1 100644 --- a/packages/contracts-bedrock/test/DeploySuperchain.t.sol +++ b/packages/contracts-bedrock/test/DeploySuperchain.t.sol @@ -284,8 +284,8 @@ contract DeploySuperchain_Test is Test { uint256 slot = zeroOutSlotForSelector(dsi.proxyAdminOwner.selector); vm.expectRevert("DeploySuperchainInput: proxyAdminOwner not set"); deploySuperchain.run(dsi, dso); - vm.store(address(dsi), bytes32(slot), bytes32(uint256(uint160(defaultProxyAdminOwner)))); // Restore the value - // we just tested. + // Restore the value we just tested. + vm.store(address(dsi), bytes32(slot), bytes32(uint256(uint160(defaultProxyAdminOwner)))); slot = zeroOutSlotForSelector(dsi.protocolVersionsOwner.selector); vm.expectRevert("DeploySuperchainInput: protocolVersionsOwner not set"); diff --git a/packages/contracts-bedrock/test/fixtures/test-deploy-superchain-in.toml b/packages/contracts-bedrock/test/fixtures/test-deploy-superchain-in.toml index 4cbcce25d004..0900e71635d7 100644 --- a/packages/contracts-bedrock/test/fixtures/test-deploy-superchain-in.toml +++ b/packages/contracts-bedrock/test/fixtures/test-deploy-superchain-in.toml @@ -5,4 +5,4 @@ recommendedProtocolVersion = 2 [roles] proxyAdminOwner = "0x51f0348a9fA2aAbaB45E82825Fbd13d406e04497" protocolVersionsOwner = "0xeEB4cc05dC0dE43c465f97cfc703D165418CA93A" -guardian = "0xE5DbA98c65F4B9EB0aeEBb3674fE64f88509a1eC" \ No newline at end of file +guardian = "0xE5DbA98c65F4B9EB0aeEBb3674fE64f88509a1eC" From 4b8d23e190123ef11bd2438cc771f3cf1fb31e31 Mon Sep 17 00:00:00 2001 From: Inphi Date: Thu, 19 Sep 2024 10:49:26 -0400 Subject: [PATCH 201/264] op-challenger: Support MT-Cannon in run-trace (#11934) * op-challenger: Support MT-Cannon in run-trace * .. * fix multi_test.go * annotate metrics with mt-cannon * preserve prestate encoding; use separate dir for mt-cannon * Update op-challenger/cmd/run_trace.go Co-authored-by: Adrian Sutton --------- Co-authored-by: Adrian Sutton --- op-challenger/cmd/run_trace.go | 20 +++- .../game/fault/trace/prestates/multi.go | 4 +- .../game/fault/trace/prestates/multi_test.go | 78 ++++++++------- op-challenger/runner/metrics.go | 13 ++- op-challenger/runner/runner.go | 95 +++++++++++++------ op-service/ioutil/atomic.go | 17 +++- op-service/ioutil/atomic_test.go | 36 ++++++- 7 files changed, 188 insertions(+), 75 deletions(-) diff --git a/op-challenger/cmd/run_trace.go b/op-challenger/cmd/run_trace.go index a3438807837b..86f35bd79474 100644 --- a/op-challenger/cmd/run_trace.go +++ b/op-challenger/cmd/run_trace.go @@ -2,10 +2,13 @@ package main import ( "context" + "fmt" "github.com/ethereum-optimism/optimism/op-challenger/flags" "github.com/ethereum-optimism/optimism/op-challenger/runner" + opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/cliapp" + "github.com/ethereum/go-ethereum/common" "github.com/urfave/cli/v2" ) @@ -24,11 +27,18 @@ func RunTrace(ctx *cli.Context, _ context.CancelCauseFunc) (cliapp.Lifecycle, er if err := cfg.Check(); err != nil { return nil, err } - return runner.NewRunner(logger, cfg), nil + if ctx.IsSet(addMTCannonPrestate.Name) && cfg.CannonAbsolutePreStateBaseURL == nil { + return nil, fmt.Errorf("flag %v is required when using %v", flags.CannonPreStateFlag.Name, addMTCannonPrestate.Name) + } + var mtPrestate common.Hash + if ctx.IsSet(addMTCannonPrestate.Name) { + mtPrestate = common.HexToHash(ctx.String(addMTCannonPrestate.Name)) + } + return runner.NewRunner(logger, cfg, mtPrestate), nil } func runTraceFlags() []cli.Flag { - return flags.Flags + return append(flags.Flags, addMTCannonPrestate) } var RunTraceCommand = &cli.Command{ @@ -38,3 +48,9 @@ var RunTraceCommand = &cli.Command{ Action: cliapp.LifecycleCmd(RunTrace), Flags: runTraceFlags(), } + +var addMTCannonPrestate = &cli.StringFlag{ + Name: "add-mt-cannon-prestate", + Usage: "Use this prestate to run MT-Cannon compatibility tests", + EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "ADD_MT_CANNON_PRESTATE"), +} diff --git a/op-challenger/game/fault/trace/prestates/multi.go b/op-challenger/game/fault/trace/prestates/multi.go index 8178def730b9..03abbbc56486 100644 --- a/op-challenger/game/fault/trace/prestates/multi.go +++ b/op-challenger/game/fault/trace/prestates/multi.go @@ -75,8 +75,8 @@ func (m *MultiPrestateProvider) fetchPrestate(hash common.Hash, fileType string, if resp.StatusCode != http.StatusOK { return fmt.Errorf("%w from url %v: status %v", ErrPrestateUnavailable, prestateUrl, resp.StatusCode) } - tmpFile := dest + ".tmp" + fileType // Preserve the file type extension so compression is applied correctly - out, err := ioutil.NewAtomicWriterCompressed(tmpFile, 0o644) + tmpFile := dest + ".tmp" + fileType // Preserve the file type extension so state decoding is applied correctly + out, err := ioutil.NewAtomicWriter(tmpFile, 0o644) if err != nil { return fmt.Errorf("failed to open atomic writer for %v: %w", dest, err) } diff --git a/op-challenger/game/fault/trace/prestates/multi_test.go b/op-challenger/game/fault/trace/prestates/multi_test.go index 830a704b09c1..7b09b81bdc67 100644 --- a/op-challenger/game/fault/trace/prestates/multi_test.go +++ b/op-challenger/game/fault/trace/prestates/multi_test.go @@ -18,40 +18,44 @@ import ( ) func TestDownloadPrestate(t *testing.T) { - dir := t.TempDir() - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - _, _ = w.Write([]byte(r.URL.Path)) - })) - defer server.Close() - hash := common.Hash{0xaa} - provider := NewMultiPrestateProvider(parseURL(t, server.URL), dir, &stubStateConverter{hash: hash}) - path, err := provider.PrestatePath(hash) - require.NoError(t, err) - in, err := ioutil.OpenDecompressed(path) - require.NoError(t, err) - defer in.Close() - content, err := io.ReadAll(in) - require.NoError(t, err) - require.Equal(t, "/"+hash.Hex()+".bin.gz", string(content)) + for _, ext := range supportedFileTypes { + t.Run(ext, func(t *testing.T) { + dir := t.TempDir() + server := prestateHTTPServer(ext) + defer server.Close() + hash := common.Hash{0xaa} + provider := NewMultiPrestateProvider(parseURL(t, server.URL), dir, &stubStateConverter{hash: hash}) + path, err := provider.PrestatePath(hash) + require.NoError(t, err) + in, err := os.Open(path) + require.NoError(t, err) + defer in.Close() + content, err := io.ReadAll(in) + require.NoError(t, err) + require.Equal(t, "/"+hash.Hex()+ext, string(content)) + }) + } } func TestCreateDirectory(t *testing.T) { - dir := t.TempDir() - dir = filepath.Join(dir, "test") - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - _, _ = w.Write([]byte(r.URL.Path)) - })) - defer server.Close() - hash := common.Hash{0xaa} - provider := NewMultiPrestateProvider(parseURL(t, server.URL), dir, &stubStateConverter{hash: hash}) - path, err := provider.PrestatePath(hash) - require.NoError(t, err) - in, err := ioutil.OpenDecompressed(path) - require.NoError(t, err) - defer in.Close() - content, err := io.ReadAll(in) - require.NoError(t, err) - require.Equal(t, "/"+hash.Hex()+".bin.gz", string(content)) + for _, ext := range supportedFileTypes { + t.Run(ext, func(t *testing.T) { + dir := t.TempDir() + dir = filepath.Join(dir, "test") + server := prestateHTTPServer(ext) + defer server.Close() + hash := common.Hash{0xaa} + provider := NewMultiPrestateProvider(parseURL(t, server.URL), dir, &stubStateConverter{hash: hash}) + path, err := provider.PrestatePath(hash) + require.NoError(t, err) + in, err := os.Open(path) + require.NoError(t, err) + defer in.Close() + content, err := io.ReadAll(in) + require.NoError(t, err) + require.Equal(t, "/"+hash.Hex()+ext, string(content)) + }) + } } func TestExistingPrestate(t *testing.T) { @@ -114,7 +118,7 @@ func TestStorePrestateWithCorrectExtension(t *testing.T) { path, err := provider.PrestatePath(hash) require.NoError(t, err) require.Truef(t, strings.HasSuffix(path, ext), "Expected path %v to have extension %v", path, ext) - in, err := ioutil.OpenDecompressed(path) + in, err := os.Open(path) require.NoError(t, err) defer in.Close() content, err := io.ReadAll(in) @@ -161,6 +165,16 @@ func parseURL(t *testing.T, str string) *url.URL { return parsed } +func prestateHTTPServer(ext string) *httptest.Server { + return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if strings.HasSuffix(r.URL.Path, ext) { + _, _ = w.Write([]byte(r.URL.Path)) + } else { + w.WriteHeader(http.StatusNotFound) + } + })) +} + type stubStateConverter struct { err error hash common.Hash diff --git a/op-challenger/runner/metrics.go b/op-challenger/runner/metrics.go index e15ad95adc1b..1f347b62aa68 100644 --- a/op-challenger/runner/metrics.go +++ b/op-challenger/runner/metrics.go @@ -4,7 +4,6 @@ import ( "time" contractMetrics "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" "github.com/prometheus/client_golang/prometheus" ) @@ -100,14 +99,14 @@ func (m *Metrics) RecordVmMemoryUsed(vmType string, memoryUsed uint64) { m.vmLastMemoryUsed.WithLabelValues(vmType).Set(float64(memoryUsed)) } -func (m *Metrics) RecordSuccess(vmType types.TraceType) { - m.successTotal.WithLabelValues(vmType.String()).Inc() +func (m *Metrics) RecordSuccess(vmType string) { + m.successTotal.WithLabelValues(vmType).Inc() } -func (m *Metrics) RecordFailure(vmType types.TraceType) { - m.failuresTotal.WithLabelValues(vmType.String()).Inc() +func (m *Metrics) RecordFailure(vmType string) { + m.failuresTotal.WithLabelValues(vmType).Inc() } -func (m *Metrics) RecordInvalid(vmType types.TraceType) { - m.invalidTotal.WithLabelValues(vmType.String()).Inc() +func (m *Metrics) RecordInvalid(vmType string) { + m.invalidTotal.WithLabelValues(vmType).Inc() } diff --git a/op-challenger/runner/runner.go b/op-challenger/runner/runner.go index 8c46f0f0a6bf..73f8ec8718ed 100644 --- a/op-challenger/runner/runner.go +++ b/op-challenger/runner/runner.go @@ -36,15 +36,16 @@ type Metricer interface { vm.Metricer contractMetrics.ContractMetricer - RecordFailure(vmType types.TraceType) - RecordInvalid(vmType types.TraceType) - RecordSuccess(vmType types.TraceType) + RecordFailure(vmType string) + RecordInvalid(vmType string) + RecordSuccess(vmType string) } type Runner struct { - log log.Logger - cfg *config.Config - m Metricer + log log.Logger + cfg *config.Config + addMTCannonPrestate common.Hash + m Metricer running atomic.Bool ctx context.Context @@ -53,11 +54,12 @@ type Runner struct { metricsSrv *httputil.HTTPServer } -func NewRunner(logger log.Logger, cfg *config.Config) *Runner { +func NewRunner(logger log.Logger, cfg *config.Config, mtCannonPrestate common.Hash) *Runner { return &Runner{ - log: logger, - cfg: cfg, - m: NewMetrics(), + log: logger, + cfg: cfg, + addMTCannonPrestate: mtCannonPrestate, + m: NewMetrics(), } } @@ -97,16 +99,7 @@ func (r *Runner) loop(ctx context.Context, traceType types.TraceType, client *so t := time.NewTicker(1 * time.Minute) defer t.Stop() for { - if err := r.runOnce(ctx, traceType, client, caller); errors.Is(err, ErrUnexpectedStatusCode) { - r.log.Error("Incorrect status code", "type", traceType, "err", err) - r.m.RecordInvalid(traceType) - } else if err != nil { - r.log.Error("Failed to run", "type", traceType, "err", err) - r.m.RecordFailure(traceType) - } else { - r.log.Info("Successfully verified output root", "type", traceType) - r.m.RecordSuccess(traceType) - } + r.runAndRecordOnce(ctx, traceType, client, caller) select { case <-t.C: case <-ctx.Done(): @@ -115,21 +108,63 @@ func (r *Runner) loop(ctx context.Context, traceType types.TraceType, client *so } } -func (r *Runner) runOnce(ctx context.Context, traceType types.TraceType, client *sources.RollupClient, caller *batching.MultiCaller) error { +func (r *Runner) runAndRecordOnce(ctx context.Context, traceType types.TraceType, client *sources.RollupClient, caller *batching.MultiCaller) { + recordError := func(err error, traceType string, m Metricer, log log.Logger) { + if errors.Is(err, ErrUnexpectedStatusCode) { + log.Error("Incorrect status code", "type", traceType, "err", err) + m.RecordInvalid(traceType) + } else if err != nil { + log.Error("Failed to run", "type", traceType, "err", err) + m.RecordFailure(traceType) + } else { + log.Info("Successfully verified output root", "type", traceType) + m.RecordSuccess(traceType) + } + } + prestateHash, err := r.getPrestateHash(ctx, traceType, caller) if err != nil { - return err + recordError(err, traceType.String(), r.m, r.log) + return } localInputs, err := r.createGameInputs(ctx, client) if err != nil { - return err + recordError(err, traceType.String(), r.m, r.log) + return } - dir, err := r.prepDatadir(traceType) - if err != nil { - return err - } - logger := r.log.New("l1", localInputs.L1Head, "l2", localInputs.L2Head, "l2Block", localInputs.L2BlockNumber, "claim", localInputs.L2Claim, "type", traceType) + + inputsLogger := r.log.New("l1", localInputs.L1Head, "l2", localInputs.L2Head, "l2Block", localInputs.L2BlockNumber, "claim", localInputs.L2Claim) + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + dir, err := r.prepDatadir(traceType.String()) + if err != nil { + recordError(err, traceType.String(), r.m, r.log) + return + } + err = r.runOnce(ctx, inputsLogger.With("type", traceType), traceType, prestateHash, localInputs, dir) + recordError(err, traceType.String(), r.m, r.log) + }() + + if r.addMTCannonPrestate != (common.Hash{}) { + wg.Add(1) + go func() { + defer wg.Done() + dir, err := r.prepDatadir("mt-cannon") + if err != nil { + recordError(err, traceType.String(), r.m, r.log) + return + } + err = r.runOnce(ctx, inputsLogger.With("type", "mt-cannon"), types.TraceTypeCannon, r.addMTCannonPrestate, localInputs, dir) + recordError(err, traceType.String(), r.m, r.log.With("mt-cannon", true)) + }() + } + wg.Wait() +} + +func (r *Runner) runOnce(ctx context.Context, logger log.Logger, traceType types.TraceType, prestateHash common.Hash, localInputs utils.LocalGameInputs, dir string) error { provider, err := createTraceProvider(logger, r.m, r.cfg, prestateHash, traceType, localInputs, dir) if err != nil { return fmt.Errorf("failed to create trace provider: %w", err) @@ -144,8 +179,8 @@ func (r *Runner) runOnce(ctx context.Context, traceType types.TraceType, client return nil } -func (r *Runner) prepDatadir(traceType types.TraceType) (string, error) { - dir := filepath.Join(r.cfg.Datadir, traceType.String()) +func (r *Runner) prepDatadir(traceType string) (string, error) { + dir := filepath.Join(r.cfg.Datadir, traceType) if err := os.RemoveAll(dir); err != nil { return "", fmt.Errorf("failed to remove old dir: %w", err) } diff --git a/op-service/ioutil/atomic.go b/op-service/ioutil/atomic.go index 7fc24d01900c..3cc38c1e6d97 100644 --- a/op-service/ioutil/atomic.go +++ b/op-service/ioutil/atomic.go @@ -17,6 +17,17 @@ type AtomicWriter struct { // NOTE: It's vital to check if an error is returned from Close() as it may indicate the file could not be renamed // If path ends in .gz the contents written will be gzipped. func NewAtomicWriterCompressed(path string, perm os.FileMode) (*AtomicWriter, error) { + return newAtomicWriter(path, perm, true) +} + +// NewAtomicWriter creates a io.WriteCloser that performs an atomic write. +// The contents are initially written to a temporary file and only renamed into place when the writer is closed. +// NOTE: It's vital to check if an error is returned from Close() as it may indicate the file could not be renamed +func NewAtomicWriter(path string, perm os.FileMode) (*AtomicWriter, error) { + return newAtomicWriter(path, perm, false) +} + +func newAtomicWriter(path string, perm os.FileMode, compressByFileType bool) (*AtomicWriter, error) { f, err := os.CreateTemp(filepath.Dir(path), filepath.Base(path)) if err != nil { return nil, err @@ -25,10 +36,14 @@ func NewAtomicWriterCompressed(path string, perm os.FileMode) (*AtomicWriter, er _ = f.Close() return nil, err } + out := io.WriteCloser(f) + if compressByFileType { + out = CompressByFileType(path, f) + } return &AtomicWriter{ dest: path, temp: f.Name(), - out: CompressByFileType(path, f), + out: out, }, nil } diff --git a/op-service/ioutil/atomic_test.go b/op-service/ioutil/atomic_test.go index 46f2f19a5058..5d46911287a5 100644 --- a/op-service/ioutil/atomic_test.go +++ b/op-service/ioutil/atomic_test.go @@ -70,7 +70,7 @@ func TestAtomicWriter_AbortAfterClose(t *testing.T) { require.ErrorIs(t, f.Abort(), os.ErrClosed) } -func TestAtomicWriter_ApplyGzip(t *testing.T) { +func TestAtomicWriterCompressed_ApplyGzip(t *testing.T) { tests := []struct { name string filename string @@ -108,3 +108,37 @@ func TestAtomicWriter_ApplyGzip(t *testing.T) { }) } } + +func TestAtomicWriter_ApplyGzip(t *testing.T) { + tests := []struct { + name string + filename string + }{ + {"Uncompressed", "test.notgz"}, + {"Gzipped", "test.gz"}, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + data := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0} + dir := t.TempDir() + path := filepath.Join(dir, test.filename) + out, err := NewAtomicWriter(path, 0o644) + require.NoError(t, err) + defer out.Close() + _, err = out.Write(data) + require.NoError(t, err) + require.NoError(t, out.Close()) + + writtenData, err := os.ReadFile(path) + require.NoError(t, err) + require.Equal(t, data, writtenData, "should not have compressed data on disk") + + in, err := os.Open(path) + require.NoError(t, err) + readData, err := io.ReadAll(in) + require.NoError(t, err) + require.Equal(t, data, readData) + }) + } +} From 2afa7a4b13bb013f7772551a26688ad6c2a9cc72 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Thu, 19 Sep 2024 09:17:47 -0600 Subject: [PATCH 202/264] feat: add remaining L2 interfaces (#11984) One more PR for adding L2 interfaces. --- .../invariant-docs/ETHLiquidity.md | 2 +- .../invariant-docs/SuperchainWETH.md | 2 +- .../contracts-bedrock/scripts/L2Genesis.s.sol | 14 +++--- packages/contracts-bedrock/semver-lock.json | 48 +++++++++---------- .../src/L1/OptimismPortal.sol | 10 ++-- .../src/L1/OptimismPortal2.sol | 10 ++-- .../contracts-bedrock/src/L2/ETHLiquidity.sol | 17 ++++--- .../src/L2/GasPriceOracle.sol | 31 ++++++------ packages/contracts-bedrock/src/L2/L1Block.sol | 4 +- .../src/L2/L1BlockIsthmus.sol | 3 ++ .../src/L2/L2CrossDomainMessenger.sol | 8 ++-- .../src/L2/L2StandardBridge.sol | 8 ++-- .../src/L2/SuperchainWETH.sol | 20 ++++---- packages/contracts-bedrock/src/L2/WETH.sol | 10 ++-- .../src/L2/interfaces/IBaseFeeVault.sol | 8 ++++ .../src/L2/interfaces/IETHLiquidity.sol | 14 ++++++ .../src/L2/interfaces/IGasPriceOracle.sol | 23 +++++++++ .../src/L2/interfaces/IL1Block.sol | 39 +++++++++++++++ .../src/L2/interfaces/IL1FeeVault.sol | 8 ++++ .../src/L2/interfaces/ISequencerFeeVault.sol | 9 ++++ .../src/L2/interfaces/ISuperchainWETH.sol | 33 +++++++++++++ .../src/legacy/L1BlockNumber.sol | 11 +++-- .../src/universal/interfaces/IFeeVault.sol | 23 +++++++++ .../test/L1/OptimismPortal.t.sol | 28 +++++------ .../test/L1/OptimismPortal2.t.sol | 30 ++++++------ .../test/L1/SystemConfig.t.sol | 18 +++---- .../contracts-bedrock/test/L2/L1Block.t.sol | 5 +- .../test/L2/SuperchainWETH.t.sol | 18 +++---- .../test/invariants/ETHLiquidity.t.sol | 11 +++-- .../test/invariants/SuperchainWETH.t.sol | 13 +++-- .../test/legacy/L1BlockNumber.t.sol | 10 ++-- .../contracts-bedrock/test/setup/Setup.sol | 33 +++++++------ 32 files changed, 348 insertions(+), 173 deletions(-) create mode 100644 packages/contracts-bedrock/src/L2/interfaces/IBaseFeeVault.sol create mode 100644 packages/contracts-bedrock/src/L2/interfaces/IETHLiquidity.sol create mode 100644 packages/contracts-bedrock/src/L2/interfaces/IGasPriceOracle.sol create mode 100644 packages/contracts-bedrock/src/L2/interfaces/IL1Block.sol create mode 100644 packages/contracts-bedrock/src/L2/interfaces/IL1FeeVault.sol create mode 100644 packages/contracts-bedrock/src/L2/interfaces/ISequencerFeeVault.sol create mode 100644 packages/contracts-bedrock/src/L2/interfaces/ISuperchainWETH.sol create mode 100644 packages/contracts-bedrock/src/universal/interfaces/IFeeVault.sol diff --git a/packages/contracts-bedrock/invariant-docs/ETHLiquidity.md b/packages/contracts-bedrock/invariant-docs/ETHLiquidity.md index bbf6eb061476..495c5556db02 100644 --- a/packages/contracts-bedrock/invariant-docs/ETHLiquidity.md +++ b/packages/contracts-bedrock/invariant-docs/ETHLiquidity.md @@ -1,5 +1,5 @@ # `ETHLiquidity` Invariants ## Calls to mint/burn repeatedly should never cause the actor's balance to increase beyond the starting balance. -**Test:** [`ETHLiquidity.t.sol#L83`](../test/invariants/ETHLiquidity.t.sol#L83) +**Test:** [`ETHLiquidity.t.sol#L86`](../test/invariants/ETHLiquidity.t.sol#L86) diff --git a/packages/contracts-bedrock/invariant-docs/SuperchainWETH.md b/packages/contracts-bedrock/invariant-docs/SuperchainWETH.md index 4b52a6146f14..afdb4a7b35c6 100644 --- a/packages/contracts-bedrock/invariant-docs/SuperchainWETH.md +++ b/packages/contracts-bedrock/invariant-docs/SuperchainWETH.md @@ -1,5 +1,5 @@ # `SuperchainWETH` Invariants ## Calls to sendERC20 should always succeed as long as the actor has less than uint248 wei which is much greater than the total ETH supply. Actor's balance should also not increase out of nowhere. -**Test:** [`SuperchainWETH.t.sol#L181`](../test/invariants/SuperchainWETH.t.sol#L181) +**Test:** [`SuperchainWETH.t.sol#L184`](../test/invariants/SuperchainWETH.t.sol#L184) diff --git a/packages/contracts-bedrock/scripts/L2Genesis.s.sol b/packages/contracts-bedrock/scripts/L2Genesis.s.sol index 6d1c6bfe6517..ceae376ee5c2 100644 --- a/packages/contracts-bedrock/scripts/L2Genesis.s.sol +++ b/packages/contracts-bedrock/scripts/L2Genesis.s.sol @@ -15,8 +15,6 @@ import { Process } from "scripts/libraries/Process.sol"; import { SetPreinstalls } from "scripts/SetPreinstalls.s.sol"; // Contracts -import { L1Block } from "src/L2/L1Block.sol"; -import { GasPriceOracle } from "src/L2/GasPriceOracle.sol"; import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol"; import { BaseFeeVault } from "src/L2/BaseFeeVault.sol"; import { L1FeeVault } from "src/L2/L1FeeVault.sol"; @@ -31,11 +29,13 @@ import { Preinstalls } from "src/libraries/Preinstalls.sol"; // Interfaces import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol"; -import { IL2CrossDomainMessenger } from "src/L2/interfaces/IL2CrossDomainMessenger.sol"; import { IL2StandardBridge } from "src/L2/interfaces/IL2StandardBridge.sol"; import { IL2ERC721Bridge } from "src/L2/interfaces/IL2ERC721Bridge.sol"; import { IStandardBridge } from "src/universal/interfaces/IStandardBridge.sol"; import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; +import { IL2CrossDomainMessenger } from "src/L2/interfaces/IL2CrossDomainMessenger.sol"; +import { IGasPriceOracle } from "src/L2/interfaces/IGasPriceOracle.sol"; +import { IL1Block } from "src/L2/interfaces/IL1Block.sol"; interface IInitializable { function initialize(address _addr) external; @@ -568,14 +568,14 @@ contract L2Genesis is Deployer { require(Preinstalls.BeaconBlockRoots.code.length > 0, "L2Genesis: must have beacon-block-roots contract"); console.log("Activating ecotone in GasPriceOracle contract"); - vm.prank(L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).DEPOSITOR_ACCOUNT()); - GasPriceOracle(Predeploys.GAS_PRICE_ORACLE).setEcotone(); + vm.prank(IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).DEPOSITOR_ACCOUNT()); + IGasPriceOracle(Predeploys.GAS_PRICE_ORACLE).setEcotone(); } function activateFjord() public { console.log("Activating fjord in GasPriceOracle contract"); - vm.prank(L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).DEPOSITOR_ACCOUNT()); - GasPriceOracle(Predeploys.GAS_PRICE_ORACLE).setFjord(); + vm.prank(IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).DEPOSITOR_ACCOUNT()); + IGasPriceOracle(Predeploys.GAS_PRICE_ORACLE).setFjord(); } /// @notice Sets the bytecode in state diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index f28e53aac307..41e5f39a1b03 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -36,15 +36,15 @@ "sourceCodeHash": "0xb085725e18c1a0cc1826b770e403ecad765fce686bb80555bf0f6c3c67b21cba" }, "src/L1/OptimismPortal.sol": { - "initCodeHash": "0xb7a7a28d5b3b88334e7cb4bc1c5fbbf9f691d934e907a2fed6a30e461eb1c0f6", - "sourceCodeHash": "0x17404b6cc3f62f66786c314e2abdf021a19c00845e2cbb2ec7796f2fa469991c" + "initCodeHash": "0xbe2c0c81b3459014f287d8c89cdc0d27dde5d1f44e5d024fa1e4773ddc47c190", + "sourceCodeHash": "0xb3dd8068477dd304ef1562acf69c2ce460b08cc36aef53b5bbe489fd7d992104" }, "src/L1/OptimismPortal2.sol": { - "initCodeHash": "0xa5e9f45888a4a7cd6bf50c63bd6414181dd6ffdfc2afbcbe31046c0abc199a28", - "sourceCodeHash": "0xdcecbbd01e867f6b93b3d57f22de946237d56341606bdabb53257e017117f10a" + "initCodeHash": "0xc94c609e04ab8ffee880806550dffff53478dfffdfb079f7c487abe0e2996f3c", + "sourceCodeHash": "0x3fb97859f66c078573753b6ba5ec370449ab03b8eca9e7779fce8db5bb23b7c0" }, "src/L1/OptimismPortalInterop.sol": { - "initCodeHash": "0x8bac6679aaf2c593d22fbe6b558509eef004959846e842181e5cc55e14b36ada", + "initCodeHash": "0x1c8372865dbf38225de4d843ca696a17f0d9e3cacf13c10a3d065ba19bdca05e", "sourceCodeHash": "0xe6a7794799915f408cb57c73af266670de8a3f02408d3dbc2c97db25d3e42635" }, "src/L1/ProtocolVersions.sol": { @@ -72,39 +72,39 @@ "sourceCodeHash": "0xd219408d99f627770dfcdb3243a183dec7429372787f0aec3bdbff5b3c294f2a" }, "src/L2/ETHLiquidity.sol": { - "initCodeHash": "0x1d9958d75fd502f018408ed5585d541b156435ac9c163009135b866d66f8f6ee", - "sourceCodeHash": "0xdd96f3fd6199dbdd8f3e480a517431b5884ea60078639ee8471df703593bf2ac" + "initCodeHash": "0x713c18f95a6a746d0703f475f3ae10c106c9b9ecb64d881a2e61b8969b581371", + "sourceCodeHash": "0x0b6afdc52d1ae88d9e4bbb5dc00920e7a6bd1e9d6595bfdbae64874190f39df0" }, "src/L2/GasPriceOracle.sol": { - "initCodeHash": "0xa1aae095643272e2dd08f8121dd4425cc8d4fd798cd39db63e4b957863efa8c1", - "sourceCodeHash": "0xaef30eab756a3804a241f57c8bb787179376477f6344a6ae49771d532153c9d3" + "initCodeHash": "0x03947f33b80774b92214083374262fe6a4defa61da548391b44d471f2e87e9e7", + "sourceCodeHash": "0x4f21025d4b5c9c74cf7040db6f8e9ce605b82931e3012fee51d3f5d9fbd7b73f" }, "src/L2/L1Block.sol": { - "initCodeHash": "0x21a09e366c69cae22f8fa3f3e1ddbbfed19408dee19f482a3d60ae699bebf462", - "sourceCodeHash": "0x254a5709e04e5a3b0a3e73253525457d956fde5299b22da4033012a44070ea09" + "initCodeHash": "0xd12353c5bf71c6765cc9292eecf262f216e67f117f4ba6287796a5207dbca00f", + "sourceCodeHash": "0xfe3a9585d9bfca8428e12759cab68a3114374e5c37371cfe08bb1976a9a5a041" }, "src/L2/L1BlockIsthmus.sol": { - "initCodeHash": "0x93b0a4bc7a0990e5c4e7081fce10f729f4d1c8e9128a7931a610152b786dc461", - "sourceCodeHash": "0x6e4927fb8c26273694257696ff286ed0382d8bd1ecaf02abec51aa4b53922c68" + "initCodeHash": "0xb7a7a113056e4ac44824350b79fed5ea423e880223edcf1220e8f8b3172f50c5", + "sourceCodeHash": "0x6be7e7402c4dfc10e1407e070712a3f9f352db45f8a8ab296e8f6bc56a341f47" }, "src/L2/L1FeeVault.sol": { "initCodeHash": "0x3bfcd57e25ad54b66c374f63e24e33a6cf107044aa8f5f69ef21202c380b5c5b", "sourceCodeHash": "0x927cc729bf5c9f209112df597f649493f276c4c50e17a57f7da02c2be266b192" }, "src/L2/L2CrossDomainMessenger.sol": { - "initCodeHash": "0xff39e6cf57acfc04e7f3242d7a45b0b4dec489b5cb3aabb319dae94dfb7ee454", - "sourceCodeHash": "0x60620a3aa6dd85974bb4267fb8c5845ffe8981dd7772b8d9055c0392ed414f77" + "initCodeHash": "0xcc4527d21cceeedbb3cbf8e7028e22fe12bc1ab30365dbebd0713499451b959d", + "sourceCodeHash": "0x66e4ae82b58693cb394d70159308d50270ccdd56c495c5e2aaf55de1fdc78695" }, "src/L2/L2ERC721Bridge.sol": { "initCodeHash": "0x827077e1a0ce6c8f9ee1196c409ea77d831efd440992b3969b05259083cdf0bd", "sourceCodeHash": "0x51a44e1fcef9483cc58ba0c9895cb3eec675785145428ece9aa7acd1a1a5b57c" }, "src/L2/L2StandardBridge.sol": { - "initCodeHash": "0x01692b613e3d4e649d877a0fd8f0798a26401ba8ccc4cda0e61f1f9079729320", - "sourceCodeHash": "0xca7d45b137fb66a941cbfe97a914c8bda78462c86ddd90085b6e2275cfb6da92" + "initCodeHash": "0x651eed10044d0b19b7e4eba864345df15e252be1401f39a552ec0d2f9c4df064", + "sourceCodeHash": "0xb55e58b5d4912edf05026878a5f5ac8019372212ed2a77843775d595fbf51b84" }, "src/L2/L2StandardBridgeInterop.sol": { - "initCodeHash": "0x5c9ef6b0817f715d1b8b097f3fc19e33bc54453426ca12bb48e4cea143076339", + "initCodeHash": "0x9bc28e8511a4593362c2517ff90b26f9c1ecee382cce3950b47ca08892a872ef", "sourceCodeHash": "0x6c814f4536d9fb8f384ed2195957f868abd15252e36d6dd243f3d60349a61994" }, "src/L2/L2ToL1MessagePasser.sol": { @@ -132,12 +132,12 @@ "sourceCodeHash": "0xd56922cb04597dea469c65e5a49d4b3c50c171e603601e6f41da9517cae0b11a" }, "src/L2/SuperchainWETH.sol": { - "initCodeHash": "0xaa136fc27006d722867bcd017742cd119e58658d9860826551095775f70739ce", - "sourceCodeHash": "0x2b627b6492c4ca3cc6a457fe48b7d0b1d335125d9c6288f7373b6525542532e8" + "initCodeHash": "0xd8766c7ab41d34d935febf5b48289f947804634bde38f8e346075b9f2d867275", + "sourceCodeHash": "0x6c1691c0fb5c86f1fd67e23495725c2cd86567556602e8cc0f28104ad6114bf4" }, "src/L2/WETH.sol": { - "initCodeHash": "0x8ccf5227a09f3ee8e450df1f9dc72a538c03226f0182c23976635c2b49859147", - "sourceCodeHash": "0x45d14c2e1c1e0ffa1c840c61010bbbffa976bc84864e084556ea690b05775fa7" + "initCodeHash": "0xfb253765520690623f177941c2cd9eba23e4c6d15063bccdd5e98081329d8956", + "sourceCodeHash": "0x2ab6be69795109a1ee04c5693a34d6ce0ff90b62e404cdeb18178bab18d06784" }, "src/cannon/MIPS.sol": { "initCodeHash": "0x4043f262804931bbbbecff64f87f2d0bdc4554b4d0a8b22df8fff940e8d239bf", @@ -172,8 +172,8 @@ "sourceCodeHash": "0xc8fe9571fcf8fcb51a4dcb00ffa97f43a9ce811c323c4926e710b28c90a9005f" }, "src/legacy/L1BlockNumber.sol": { - "initCodeHash": "0xfc43380228388659578368ec31b4581404ad3f3d30f3fcedccd461b1feaeebb4", - "sourceCodeHash": "0x1dbbf96cf6514bfa7b553cebaec1da2f32b9b154cd80134adb7c129ee109da74" + "initCodeHash": "0x542955f1a84b304eaf291f76633b03e4c87c2654f7eff46c3bea94d27346ea1f", + "sourceCodeHash": "0x898c239e6367a0971a075df18030a033cdada26983fa8a5cd6e7b88ec90d4958" }, "src/legacy/LegacyMessagePasser.sol": { "initCodeHash": "0xefc6ed9e325c2d614ea0d28c3eabfff1b345f7c6054e90253c6a091c29508267", diff --git a/packages/contracts-bedrock/src/L1/OptimismPortal.sol b/packages/contracts-bedrock/src/L1/OptimismPortal.sol index 24eaccf8cc47..885f37574212 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortal.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortal.sol @@ -4,7 +4,6 @@ pragma solidity 0.8.15; // Contracts import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; -import { L1Block } from "src/L2/L1Block.sol"; // Libraries import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; @@ -19,11 +18,12 @@ import "src/libraries/PortalErrors.sol"; // Interfaces import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; -import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { IL1Block } from "src/L2/interfaces/IL1Block.sol"; /// @custom:proxied true /// @title OptimismPortal @@ -134,9 +134,9 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver { } /// @notice Semantic version. - /// @custom:semver 2.8.1-beta.2 + /// @custom:semver 2.8.1-beta.3 function version() public pure virtual returns (string memory) { - return "2.8.1-beta.2"; + return "2.8.1-beta.3"; } /// @notice Constructs the OptimismPortal contract. @@ -592,7 +592,7 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver { uint256(0), // value uint64(SYSTEM_DEPOSIT_GAS_LIMIT), // gasLimit false, // isCreation, - abi.encodeCall(L1Block.setGasPayingToken, (_token, _decimals, _name, _symbol)) + abi.encodeCall(IL1Block.setGasPayingToken, (_token, _decimals, _name, _symbol)) ) ); } diff --git a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol index 526c699f5256..3a75269a2020 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol @@ -4,7 +4,6 @@ pragma solidity 0.8.15; // Contracts import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; -import { L1Block } from "src/L2/L1Block.sol"; // Libraries import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; @@ -20,12 +19,13 @@ import "src/dispute/lib/Types.sol"; // Interfaces import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol"; import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; -import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { IL1Block } from "src/L2/interfaces/IL1Block.sol"; /// @custom:proxied true /// @title OptimismPortal2 @@ -164,9 +164,9 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { } /// @notice Semantic version. - /// @custom:semver 3.11.0-beta.4 + /// @custom:semver 3.11.0-beta.5 function version() public pure virtual returns (string memory) { - return "3.11.0-beta.4"; + return "3.11.0-beta.5"; } /// @notice Constructs the OptimismPortal contract. @@ -606,7 +606,7 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { uint256(0), // value uint64(SYSTEM_DEPOSIT_GAS_LIMIT), // gasLimit false, // isCreation, - abi.encodeCall(L1Block.setGasPayingToken, (_token, _decimals, _name, _symbol)) + abi.encodeCall(IL1Block.setGasPayingToken, (_token, _decimals, _name, _symbol)) ) ); } diff --git a/packages/contracts-bedrock/src/L2/ETHLiquidity.sol b/packages/contracts-bedrock/src/L2/ETHLiquidity.sol index 881b2b28a45a..6118288df77d 100644 --- a/packages/contracts-bedrock/src/L2/ETHLiquidity.sol +++ b/packages/contracts-bedrock/src/L2/ETHLiquidity.sol @@ -1,11 +1,16 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Contracts +import { SafeSend } from "src/universal/SafeSend.sol"; + +// Libraries import { Unauthorized, NotCustomGasToken } from "src/libraries/errors/CommonErrors.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; -import { L1Block } from "src/L2/L1Block.sol"; -import { SafeSend } from "src/universal/SafeSend.sol"; + +// Interfaces import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { IL1Block } from "src/L2/interfaces/IL1Block.sol"; /// @title ETHLiquidity /// @notice The ETHLiquidity contract allows other contracts to access ETH liquidity without @@ -18,13 +23,13 @@ contract ETHLiquidity is ISemver { event LiquidityMinted(address indexed caller, uint256 value); /// @notice Semantic version. - /// @custom:semver 1.0.0-beta.2 - string public constant version = "1.0.0-beta.2"; + /// @custom:semver 1.0.0-beta.3 + string public constant version = "1.0.0-beta.3"; /// @notice Allows an address to lock ETH liquidity into this contract. function burn() external payable { if (msg.sender != Predeploys.SUPERCHAIN_WETH) revert Unauthorized(); - if (L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken()) revert NotCustomGasToken(); + if (IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken()) revert NotCustomGasToken(); emit LiquidityBurned(msg.sender, msg.value); } @@ -32,7 +37,7 @@ contract ETHLiquidity is ISemver { /// @param _amount The amount of liquidity to unlock. function mint(uint256 _amount) external { if (msg.sender != Predeploys.SUPERCHAIN_WETH) revert Unauthorized(); - if (L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken()) revert NotCustomGasToken(); + if (IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken()) revert NotCustomGasToken(); new SafeSend{ value: _amount }(payable(msg.sender)); emit LiquidityMinted(msg.sender, _amount); } diff --git a/packages/contracts-bedrock/src/L2/GasPriceOracle.sol b/packages/contracts-bedrock/src/L2/GasPriceOracle.sol index 63a58038eab5..862e4bb07913 100644 --- a/packages/contracts-bedrock/src/L2/GasPriceOracle.sol +++ b/packages/contracts-bedrock/src/L2/GasPriceOracle.sol @@ -1,11 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { ISemver } from "src/universal/interfaces/ISemver.sol"; +// Libraries +import { LibZip } from "@solady/utils/LibZip.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; -import { L1Block } from "src/L2/L1Block.sol"; import { Constants } from "src/libraries/Constants.sol"; -import { LibZip } from "@solady/utils/LibZip.sol"; + +// Interfaces +import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { IL1Block } from "src/L2/interfaces/IL1Block.sol"; /// @custom:proxied true /// @custom:predeploy 0x420000000000000000000000000000000000000F @@ -26,8 +29,8 @@ contract GasPriceOracle is ISemver { uint256 public constant DECIMALS = 6; /// @notice Semantic version. - /// @custom:semver 1.3.1-beta.1 - string public constant version = "1.3.1-beta.1"; + /// @custom:semver 1.3.1-beta.2 + string public constant version = "1.3.1-beta.2"; /// @notice This is the intercept value for the linear regression used to estimate the final size of the /// compressed transaction. @@ -114,7 +117,7 @@ contract GasPriceOracle is ISemver { /// @return Current fee overhead. function overhead() public view returns (uint256) { require(!isEcotone, "GasPriceOracle: overhead() is deprecated"); - return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeOverhead(); + return IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeOverhead(); } /// @custom:legacy @@ -122,31 +125,31 @@ contract GasPriceOracle is ISemver { /// @return Current fee scalar. function scalar() public view returns (uint256) { require(!isEcotone, "GasPriceOracle: scalar() is deprecated"); - return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeScalar(); + return IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeScalar(); } /// @notice Retrieves the latest known L1 base fee. /// @return Latest known L1 base fee. function l1BaseFee() public view returns (uint256) { - return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).basefee(); + return IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).basefee(); } /// @notice Retrieves the current blob base fee. /// @return Current blob base fee. function blobBaseFee() public view returns (uint256) { - return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).blobBaseFee(); + return IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).blobBaseFee(); } /// @notice Retrieves the current base fee scalar. /// @return Current base fee scalar. function baseFeeScalar() public view returns (uint32) { - return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).baseFeeScalar(); + return IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).baseFeeScalar(); } /// @notice Retrieves the current blob base fee scalar. /// @return Current blob base fee scalar. function blobBaseFeeScalar() public view returns (uint32) { - return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).blobBaseFeeScalar(); + return IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).blobBaseFeeScalar(); } /// @custom:legacy @@ -173,7 +176,7 @@ contract GasPriceOracle is ISemver { if (isEcotone) { return l1GasUsed; } - return l1GasUsed + L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeOverhead(); + return l1GasUsed + IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeOverhead(); } /// @notice Computation of the L1 portion of the fee for Bedrock. @@ -181,8 +184,8 @@ contract GasPriceOracle is ISemver { /// @return L1 fee that should be paid for the tx function _getL1FeeBedrock(bytes memory _data) internal view returns (uint256) { uint256 l1GasUsed = _getCalldataGas(_data); - uint256 fee = (l1GasUsed + L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeOverhead()) * l1BaseFee() - * L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeScalar(); + uint256 fee = (l1GasUsed + IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeOverhead()) * l1BaseFee() + * IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeScalar(); return fee / (10 ** DECIMALS); } diff --git a/packages/contracts-bedrock/src/L2/L1Block.sol b/packages/contracts-bedrock/src/L2/L1Block.sol index ffcca0bf7ceb..c61f45b83629 100644 --- a/packages/contracts-bedrock/src/L2/L1Block.sol +++ b/packages/contracts-bedrock/src/L2/L1Block.sol @@ -57,9 +57,9 @@ contract L1Block is ISemver, IGasToken { /// @notice The latest L1 blob base fee. uint256 public blobBaseFee; - /// @custom:semver 1.5.1-beta.1 + /// @custom:semver 1.5.1-beta.2 function version() public pure virtual returns (string memory) { - return "1.5.1-beta.1"; + return "1.5.1-beta.2"; } /// @notice Returns the gas paying token, its decimals, name and symbol. diff --git a/packages/contracts-bedrock/src/L2/L1BlockIsthmus.sol b/packages/contracts-bedrock/src/L2/L1BlockIsthmus.sol index bd848aba3e81..c9643659030e 100644 --- a/packages/contracts-bedrock/src/L2/L1BlockIsthmus.sol +++ b/packages/contracts-bedrock/src/L2/L1BlockIsthmus.sol @@ -1,7 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Contracts import { L1Block } from "src/L2/L1Block.sol"; + +// Libraries import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; import { StaticConfig } from "src/libraries/StaticConfig.sol"; diff --git a/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol index a77d4c6d3ecd..bbfc82578ab6 100644 --- a/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol +++ b/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.15; // Contracts import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { L1Block } from "src/L2/L1Block.sol"; // Libraries import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; @@ -14,6 +13,7 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; // Interfaces import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { IL2ToL1MessagePasser } from "src/L2/interfaces/IL2ToL1MessagePasser.sol"; +import { IL1Block } from "src/L2/interfaces/IL1Block.sol"; /// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000007 @@ -22,8 +22,8 @@ import { IL2ToL1MessagePasser } from "src/L2/interfaces/IL2ToL1MessagePasser.sol /// L2 on the L2 side. Users are generally encouraged to use this contract instead of lower /// level message passing contracts. contract L2CrossDomainMessenger is CrossDomainMessenger, ISemver { - /// @custom:semver 2.1.1-beta.2 - string public constant version = "2.1.1-beta.2"; + /// @custom:semver 2.1.1-beta.3 + string public constant version = "2.1.1-beta.3"; /// @notice Constructs the L2CrossDomainMessenger contract. constructor() CrossDomainMessenger() { @@ -53,7 +53,7 @@ contract L2CrossDomainMessenger is CrossDomainMessenger, ISemver { /// @inheritdoc CrossDomainMessenger function gasPayingToken() internal view override returns (address addr_, uint8 decimals_) { - (addr_, decimals_) = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).gasPayingToken(); + (addr_, decimals_) = IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).gasPayingToken(); } /// @inheritdoc CrossDomainMessenger diff --git a/packages/contracts-bedrock/src/L2/L2StandardBridge.sol b/packages/contracts-bedrock/src/L2/L2StandardBridge.sol index 5cf6ebecfb5d..1c7e2e307cc3 100644 --- a/packages/contracts-bedrock/src/L2/L2StandardBridge.sol +++ b/packages/contracts-bedrock/src/L2/L2StandardBridge.sol @@ -4,7 +4,6 @@ pragma solidity 0.8.15; // Contracts import { StandardBridge } from "src/universal/StandardBridge.sol"; import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; -import { L1Block } from "src/L2/L1Block.sol"; // Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; @@ -12,6 +11,7 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; // Interfaces import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; +import { IL1Block } from "src/L2/interfaces/IL1Block.sol"; /// @custom:proxied true /// @custom:predeploy 0x4200000000000000000000000000000000000010 @@ -58,9 +58,9 @@ contract L2StandardBridge is StandardBridge, ISemver { ); /// @notice Semantic version. - /// @custom:semver 1.11.1-beta.1 + /// @custom:semver 1.11.1-beta.2 function version() public pure virtual returns (string memory) { - return "1.11.1-beta.1"; + return "1.11.1-beta.2"; } /// @notice Constructs the L2StandardBridge contract. @@ -86,7 +86,7 @@ contract L2StandardBridge is StandardBridge, ISemver { /// @inheritdoc StandardBridge function gasPayingToken() internal view override returns (address addr_, uint8 decimals_) { - (addr_, decimals_) = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).gasPayingToken(); + (addr_, decimals_) = IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).gasPayingToken(); } /// @custom:legacy diff --git a/packages/contracts-bedrock/src/L2/SuperchainWETH.sol b/packages/contracts-bedrock/src/L2/SuperchainWETH.sol index 35c2d3d363f4..a672918ffea1 100644 --- a/packages/contracts-bedrock/src/L2/SuperchainWETH.sol +++ b/packages/contracts-bedrock/src/L2/SuperchainWETH.sol @@ -3,8 +3,6 @@ pragma solidity 0.8.15; // Contracts import { WETH98 } from "src/universal/WETH98.sol"; -import { L1Block } from "src/L2/L1Block.sol"; -import { ETHLiquidity } from "src/L2/ETHLiquidity.sol"; // Libraries import { Unauthorized, NotCustomGasToken } from "src/libraries/errors/CommonErrors.sol"; @@ -14,6 +12,8 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; import { ISuperchainERC20Extensions } from "src/L2/interfaces/ISuperchainERC20.sol"; +import { IL1Block } from "src/L2/interfaces/IL1Block.sol"; +import { IETHLiquidity } from "src/L2/interfaces/IETHLiquidity.sol"; /// @title SuperchainWETH /// @notice SuperchainWETH is a version of WETH that can be freely transfrered between chains @@ -21,18 +21,18 @@ import { ISuperchainERC20Extensions } from "src/L2/interfaces/ISuperchainERC20.s /// do not use a custom gas token. contract SuperchainWETH is WETH98, ISuperchainERC20Extensions, ISemver { /// @notice Semantic version. - /// @custom:semver 1.0.0-beta.3 - string public constant version = "1.0.0-beta.3"; + /// @custom:semver 1.0.0-beta.4 + string public constant version = "1.0.0-beta.4"; /// @inheritdoc WETH98 function deposit() public payable override { - if (L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken()) revert NotCustomGasToken(); + if (IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken()) revert NotCustomGasToken(); super.deposit(); } /// @inheritdoc WETH98 function withdraw(uint256 wad) public override { - if (L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken()) revert NotCustomGasToken(); + if (IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken()) revert NotCustomGasToken(); super.withdraw(wad); } @@ -42,8 +42,8 @@ contract SuperchainWETH is WETH98, ISuperchainERC20Extensions, ISemver { _burn(msg.sender, wad); // Burn to ETHLiquidity contract. - if (!L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken()) { - ETHLiquidity(Predeploys.ETH_LIQUIDITY).burn{ value: wad }(); + if (!IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken()) { + IETHLiquidity(Predeploys.ETH_LIQUIDITY).burn{ value: wad }(); } // Send message to other chain. @@ -65,8 +65,8 @@ contract SuperchainWETH is WETH98, ISuperchainERC20Extensions, ISemver { if (messenger.crossDomainMessageSender() != address(this)) revert Unauthorized(); // Mint from ETHLiquidity contract. - if (!L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken()) { - ETHLiquidity(Predeploys.ETH_LIQUIDITY).mint(wad); + if (!IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken()) { + IETHLiquidity(Predeploys.ETH_LIQUIDITY).mint(wad); } // Get source chain ID. diff --git a/packages/contracts-bedrock/src/L2/WETH.sol b/packages/contracts-bedrock/src/L2/WETH.sol index 80abcbf6dbf0..fb24f0747338 100644 --- a/packages/contracts-bedrock/src/L2/WETH.sol +++ b/packages/contracts-bedrock/src/L2/WETH.sol @@ -3,29 +3,29 @@ pragma solidity 0.8.15; // Contracts import { WETH98 } from "src/universal/WETH98.sol"; -import { L1Block } from "src/L2/L1Block.sol"; // Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; // Interfaces import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { IL1Block } from "src/L2/interfaces/IL1Block.sol"; /// @title WETH contract that reads the name and symbol from the L1Block contract. /// Allows for nice rendering of token names for chains using custom gas token. contract WETH is WETH98, ISemver { - /// @custom:semver 1.1.0-beta.1 - string public constant version = "1.1.0-beta.1"; + /// @custom:semver 1.1.0-beta.2 + string public constant version = "1.1.0-beta.2"; /// @notice Returns the name of the wrapped native asset. Will be "Wrapped Ether" /// if the native asset is Ether. function name() external view override returns (string memory name_) { - name_ = string.concat("Wrapped ", L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).gasPayingTokenName()); + name_ = string.concat("Wrapped ", IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).gasPayingTokenName()); } /// @notice Returns the symbol of the wrapped native asset. Will be "WETH" if the /// native asset is Ether. function symbol() external view override returns (string memory symbol_) { - symbol_ = string.concat("W", L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).gasPayingTokenSymbol()); + symbol_ = string.concat("W", IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).gasPayingTokenSymbol()); } } diff --git a/packages/contracts-bedrock/src/L2/interfaces/IBaseFeeVault.sol b/packages/contracts-bedrock/src/L2/interfaces/IBaseFeeVault.sol new file mode 100644 index 000000000000..2c21ac00964a --- /dev/null +++ b/packages/contracts-bedrock/src/L2/interfaces/IBaseFeeVault.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { IFeeVault } from "src/universal/interfaces/IFeeVault.sol"; + +interface IBaseFeeVault is IFeeVault { + function version() external view returns (string memory); +} diff --git a/packages/contracts-bedrock/src/L2/interfaces/IETHLiquidity.sol b/packages/contracts-bedrock/src/L2/interfaces/IETHLiquidity.sol new file mode 100644 index 000000000000..de463f543b71 --- /dev/null +++ b/packages/contracts-bedrock/src/L2/interfaces/IETHLiquidity.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IETHLiquidity { + error NotCustomGasToken(); + error Unauthorized(); + + event LiquidityBurned(address indexed caller, uint256 value); + event LiquidityMinted(address indexed caller, uint256 value); + + function burn() external payable; + function mint(uint256 _amount) external; + function version() external view returns (string memory); +} diff --git a/packages/contracts-bedrock/src/L2/interfaces/IGasPriceOracle.sol b/packages/contracts-bedrock/src/L2/interfaces/IGasPriceOracle.sol new file mode 100644 index 000000000000..4ab0ef854c8a --- /dev/null +++ b/packages/contracts-bedrock/src/L2/interfaces/IGasPriceOracle.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IGasPriceOracle { + function DECIMALS() external view returns (uint256); + function baseFee() external view returns (uint256); + function baseFeeScalar() external view returns (uint32); + function blobBaseFee() external view returns (uint256); + function blobBaseFeeScalar() external view returns (uint32); + function decimals() external pure returns (uint256); + function gasPrice() external view returns (uint256); + function getL1Fee(bytes memory _data) external view returns (uint256); + function getL1FeeUpperBound(uint256 _unsignedTxSize) external view returns (uint256); + function getL1GasUsed(bytes memory _data) external view returns (uint256); + function isEcotone() external view returns (bool); + function isFjord() external view returns (bool); + function l1BaseFee() external view returns (uint256); + function overhead() external view returns (uint256); + function scalar() external view returns (uint256); + function setEcotone() external; + function setFjord() external; + function version() external view returns (string memory); +} diff --git a/packages/contracts-bedrock/src/L2/interfaces/IL1Block.sol b/packages/contracts-bedrock/src/L2/interfaces/IL1Block.sol new file mode 100644 index 000000000000..6ef4c2984ae4 --- /dev/null +++ b/packages/contracts-bedrock/src/L2/interfaces/IL1Block.sol @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IL1Block { + error NotDepositor(); + + event GasPayingTokenSet(address indexed token, uint8 indexed decimals, bytes32 name, bytes32 symbol); + + function DEPOSITOR_ACCOUNT() external pure returns (address addr_); + function baseFeeScalar() external view returns (uint32); + function basefee() external view returns (uint256); + function batcherHash() external view returns (bytes32); + function blobBaseFee() external view returns (uint256); + function blobBaseFeeScalar() external view returns (uint32); + function gasPayingToken() external view returns (address addr_, uint8 decimals_); + function gasPayingTokenName() external view returns (string memory name_); + function gasPayingTokenSymbol() external view returns (string memory symbol_); + function hash() external view returns (bytes32); + function isCustomGasToken() external view returns (bool); + function l1FeeOverhead() external view returns (uint256); + function l1FeeScalar() external view returns (uint256); + function number() external view returns (uint64); + function sequenceNumber() external view returns (uint64); + function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external; + function setL1BlockValues( + uint64 _number, + uint64 _timestamp, + uint256 _basefee, + bytes32 _hash, + uint64 _sequenceNumber, + bytes32 _batcherHash, + uint256 _l1FeeOverhead, + uint256 _l1FeeScalar + ) + external; + function setL1BlockValuesEcotone() external; + function timestamp() external view returns (uint64); + function version() external pure returns (string memory); +} diff --git a/packages/contracts-bedrock/src/L2/interfaces/IL1FeeVault.sol b/packages/contracts-bedrock/src/L2/interfaces/IL1FeeVault.sol new file mode 100644 index 000000000000..539933762046 --- /dev/null +++ b/packages/contracts-bedrock/src/L2/interfaces/IL1FeeVault.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { IFeeVault } from "src/universal/interfaces/IFeeVault.sol"; + +interface IL1FeeVault is IFeeVault { + function version() external view returns (string memory); +} diff --git a/packages/contracts-bedrock/src/L2/interfaces/ISequencerFeeVault.sol b/packages/contracts-bedrock/src/L2/interfaces/ISequencerFeeVault.sol new file mode 100644 index 000000000000..d6643b6054be --- /dev/null +++ b/packages/contracts-bedrock/src/L2/interfaces/ISequencerFeeVault.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { IFeeVault } from "src/universal/interfaces/IFeeVault.sol"; + +interface ISequencerFeeVault is IFeeVault { + function version() external view returns (string memory); + function l1FeeWallet() external view returns (address); +} diff --git a/packages/contracts-bedrock/src/L2/interfaces/ISuperchainWETH.sol b/packages/contracts-bedrock/src/L2/interfaces/ISuperchainWETH.sol new file mode 100644 index 000000000000..7c755e11e869 --- /dev/null +++ b/packages/contracts-bedrock/src/L2/interfaces/ISuperchainWETH.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface ISuperchainWETH { + error NotCustomGasToken(); + error Unauthorized(); + + event Approval(address indexed src, address indexed guy, uint256 wad); + event Deposit(address indexed dst, uint256 wad); + event RelayERC20(address indexed from, address indexed to, uint256 amount, uint256 source); + event SendERC20(address indexed from, address indexed to, uint256 amount, uint256 destination); + event Transfer(address indexed src, address indexed dst, uint256 wad); + event Withdrawal(address indexed src, uint256 wad); + + fallback() external payable; + + receive() external payable; + + function allowance(address, address) external view returns (uint256); + function approve(address guy, uint256 wad) external returns (bool); + function balanceOf(address) external view returns (uint256); + function decimals() external view returns (uint8); + function deposit() external payable; + function name() external view returns (string memory); + function relayERC20(address from, address dst, uint256 wad) external; + function sendERC20(address dst, uint256 wad, uint256 chainId) external; + function symbol() external view returns (string memory); + function totalSupply() external view returns (uint256); + function transfer(address dst, uint256 wad) external returns (bool); + function transferFrom(address src, address dst, uint256 wad) external returns (bool); + function version() external view returns (string memory); + function withdraw(uint256 wad) external; +} diff --git a/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol b/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol index 9e98a76b18b1..19a595a3fad3 100644 --- a/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol +++ b/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol @@ -1,9 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { L1Block } from "src/L2/L1Block.sol"; +// Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Interfaces import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { IL1Block } from "src/L2/interfaces/IL1Block.sol"; /// @custom:legacy true /// @custom:proxied true @@ -15,8 +18,8 @@ import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// contract instead. contract L1BlockNumber is ISemver { /// @notice Semantic version. - /// @custom:semver 1.1.1-beta.1 - string public constant version = "1.1.1-beta.1"; + /// @custom:semver 1.1.1-beta.2 + string public constant version = "1.1.1-beta.2"; /// @notice Returns the L1 block number. receive() external payable { @@ -39,6 +42,6 @@ contract L1BlockNumber is ISemver { /// @notice Retrieves the latest L1 block number. /// @return Latest L1 block number. function getL1BlockNumber() public view returns (uint256) { - return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).number(); + return IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).number(); } } diff --git a/packages/contracts-bedrock/src/universal/interfaces/IFeeVault.sol b/packages/contracts-bedrock/src/universal/interfaces/IFeeVault.sol new file mode 100644 index 000000000000..1742a0029c7d --- /dev/null +++ b/packages/contracts-bedrock/src/universal/interfaces/IFeeVault.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IFeeVault { + enum WithdrawalNetwork { + L1, + L2 + } + + event Withdrawal(uint256 value, address to, address from); + event Withdrawal(uint256 value, address to, address from, WithdrawalNetwork withdrawalNetwork); + + receive() external payable; + + function MIN_WITHDRAWAL_AMOUNT() external view returns (uint256); + function RECIPIENT() external view returns (address); + function WITHDRAWAL_NETWORK() external view returns (WithdrawalNetwork); + function minWithdrawalAmount() external view returns (uint256 amount_); + function recipient() external view returns (address recipient_); + function totalProcessed() external view returns (uint256); + function withdraw() external; + function withdrawalNetwork() external view returns (WithdrawalNetwork network_); +} diff --git a/packages/contracts-bedrock/test/L1/OptimismPortal.t.sol b/packages/contracts-bedrock/test/L1/OptimismPortal.t.sol index 35c9d0fb4ee5..0472c0781ce8 100644 --- a/packages/contracts-bedrock/test/L1/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/L1/OptimismPortal.t.sol @@ -1,33 +1,33 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Testing utilities +// Testing import { stdError } from "forge-std/Test.sol"; import { VmSafe } from "forge-std/Vm.sol"; - +import { MockERC20 } from "solmate/test/utils/mocks/MockERC20.sol"; import { CommonTest } from "test/setup/CommonTest.sol"; import { NextImpl } from "test/mocks/NextImpl.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; +// Contracts +import { Proxy } from "src/universal/Proxy.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; + // Libraries import { Types } from "src/libraries/Types.sol"; import { Hashing } from "src/libraries/Hashing.sol"; import { Constants } from "src/libraries/Constants.sol"; - -// Target contract dependencies -import { Proxy } from "src/universal/Proxy.sol"; -import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; -import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; -import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; -import { L1Block } from "src/L2/L1Block.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; -import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; -import { MockERC20 } from "solmate/test/utils/mocks/MockERC20.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import "src/libraries/PortalErrors.sol"; +// Interfaces +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; +import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; +import { IL1Block } from "src/L2/interfaces/IL1Block.sol"; +import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; + contract OptimismPortal_Test is CommonTest { address depositor; @@ -462,7 +462,7 @@ contract OptimismPortal_Test is CommonTest { uint256(0), // value uint64(200_000), // gasLimit false, // isCreation, - abi.encodeCall(L1Block.setGasPayingToken, (_token, _decimals, _name, _symbol)) + abi.encodeCall(IL1Block.setGasPayingToken, (_token, _decimals, _name, _symbol)) ) ); @@ -497,7 +497,7 @@ contract OptimismPortal_Test is CommonTest { _value: 0, _gasLimit: 200_000, _isCreation: false, - _data: abi.encodeCall(L1Block.setGasPayingToken, (_token, 18, name, symbol)) + _data: abi.encodeCall(IL1Block.setGasPayingToken, (_token, 18, name, symbol)) }); VmSafe.Log[] memory logs = vm.getRecordedLogs(); diff --git a/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol b/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol index c0423ff2806e..810f0a84e589 100644 --- a/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol +++ b/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol @@ -1,34 +1,34 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Testing utilities +// Testing import { stdError } from "forge-std/Test.sol"; import { VmSafe } from "forge-std/Vm.sol"; - +import { MockERC20 } from "solmate/test/utils/mocks/MockERC20.sol"; import { CommonTest } from "test/setup/CommonTest.sol"; import { NextImpl } from "test/mocks/NextImpl.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; +// Contracts +import { Proxy } from "src/universal/Proxy.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { FaultDisputeGame, IDisputeGame } from "src/dispute/FaultDisputeGame.sol"; + // Libraries import { Types } from "src/libraries/Types.sol"; import { Hashing } from "src/libraries/Hashing.sol"; import { Constants } from "src/libraries/Constants.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; - -// Target contract dependencies -import { Proxy } from "src/universal/Proxy.sol"; -import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; -import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; -import { L1Block } from "src/L2/L1Block.sol"; -import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; -import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; -import { MockERC20 } from "solmate/test/utils/mocks/MockERC20.sol"; - -import { FaultDisputeGame, IDisputeGame } from "src/dispute/FaultDisputeGame.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import "src/dispute/lib/Types.sol"; import "src/libraries/PortalErrors.sol"; +// Interfaces +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; +import { IL1Block } from "src/L2/interfaces/IL1Block.sol"; +import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; + contract OptimismPortal2_Test is CommonTest { address depositor; @@ -316,7 +316,7 @@ contract OptimismPortal2_Test is CommonTest { uint256(0), // value uint64(200_000), // gasLimit false, // isCreation, - abi.encodeCall(L1Block.setGasPayingToken, (_token, _decimals, _name, _symbol)) + abi.encodeCall(IL1Block.setGasPayingToken, (_token, _decimals, _name, _symbol)) ) ); @@ -351,7 +351,7 @@ contract OptimismPortal2_Test is CommonTest { _value: 0, _gasLimit: 200_000, _isCreation: false, - _data: abi.encodeCall(L1Block.setGasPayingToken, (_token, 18, name, symbol)) + _data: abi.encodeCall(IL1Block.setGasPayingToken, (_token, 18, name, symbol)) }); VmSafe.Log[] memory logs = vm.getRecordedLogs(); diff --git a/packages/contracts-bedrock/test/L1/SystemConfig.t.sol b/packages/contracts-bedrock/test/L1/SystemConfig.t.sol index 8b21fbcf3646..ddfafc0edb2f 100644 --- a/packages/contracts-bedrock/test/L1/SystemConfig.t.sol +++ b/packages/contracts-bedrock/test/L1/SystemConfig.t.sol @@ -1,23 +1,23 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Testing utilities +// Testing import { CommonTest } from "test/setup/CommonTest.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; + +// Contracts import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { Proxy } from "src/universal/Proxy.sol"; // Libraries import { Constants } from "src/libraries/Constants.sol"; -import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; - -// Target contract dependencies -import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; -import { Proxy } from "src/universal/Proxy.sol"; -import { L1Block } from "src/L2/L1Block.sol"; import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; -// Target contract +// Interfaces +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; +import { IL1Block } from "src/L2/interfaces/IL1Block.sol"; contract SystemConfig_Init is CommonTest { event ConfigUpdate(uint256 indexed version, ISystemConfig.UpdateType indexed updateType, bytes data); @@ -467,7 +467,7 @@ contract SystemConfig_Init_CustomGasToken is SystemConfig_Init { uint256(0), // value uint64(200_000), // gasLimit false, // isCreation, - abi.encodeCall(L1Block.setGasPayingToken, (address(token), 18, bytes32("Silly"), bytes32("SIL"))) + abi.encodeCall(IL1Block.setGasPayingToken, (address(token), 18, bytes32("Silly"), bytes32("SIL"))) ) ); diff --git a/packages/contracts-bedrock/test/L2/L1Block.t.sol b/packages/contracts-bedrock/test/L2/L1Block.t.sol index ce67a6692223..762553a2ff2f 100644 --- a/packages/contracts-bedrock/test/L2/L1Block.t.sol +++ b/packages/contracts-bedrock/test/L2/L1Block.t.sol @@ -1,15 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Testing utilities +// Testing import { CommonTest } from "test/setup/CommonTest.sol"; // Libraries import { Encoding } from "src/libraries/Encoding.sol"; import { Constants } from "src/libraries/Constants.sol"; - -// Target contract -import { L1Block } from "src/L2/L1Block.sol"; import "src/libraries/L1BlockErrors.sol"; contract L1BlockTest is CommonTest { diff --git a/packages/contracts-bedrock/test/L2/SuperchainWETH.t.sol b/packages/contracts-bedrock/test/L2/SuperchainWETH.t.sol index f01a90f7aec0..361e982d7324 100644 --- a/packages/contracts-bedrock/test/L2/SuperchainWETH.t.sol +++ b/packages/contracts-bedrock/test/L2/SuperchainWETH.t.sol @@ -1,14 +1,16 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Testing utilities +// Testing import { CommonTest } from "test/setup/CommonTest.sol"; -// Contract imports -import { Unauthorized, NotCustomGasToken } from "src/libraries/errors/CommonErrors.sol"; +// Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; +import { Unauthorized, NotCustomGasToken } from "src/libraries/errors/CommonErrors.sol"; + +// Interfaces import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; -import { ETHLiquidity } from "src/L2/ETHLiquidity.sol"; +import { IETHLiquidity } from "src/L2/interfaces/IETHLiquidity.sol"; /// @title SuperchainWETH_Test /// @notice Contract for testing the SuperchainWETH contract. @@ -148,7 +150,7 @@ contract SuperchainWETH_Test is CommonTest { emit Transfer(_caller, address(0), _amount); vm.expectEmit(address(superchainWeth)); emit SendERC20(_caller, _recipient, _amount, _chainId); - vm.expectCall(Predeploys.ETH_LIQUIDITY, abi.encodeCall(ETHLiquidity.burn, ()), 1); + vm.expectCall(Predeploys.ETH_LIQUIDITY, abi.encodeCall(IETHLiquidity.burn, ()), 1); vm.expectCall( Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER, abi.encodeCall( @@ -190,7 +192,7 @@ contract SuperchainWETH_Test is CommonTest { emit Transfer(alice, address(0), _amount); vm.expectEmit(address(superchainWeth)); emit SendERC20(alice, bob, _amount, _chainId); - vm.expectCall(Predeploys.ETH_LIQUIDITY, abi.encodeCall(ETHLiquidity.burn, ()), 0); + vm.expectCall(Predeploys.ETH_LIQUIDITY, abi.encodeCall(IETHLiquidity.burn, ()), 0); vm.expectCall( Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER, abi.encodeCall( @@ -255,7 +257,7 @@ contract SuperchainWETH_Test is CommonTest { // Act vm.expectEmit(address(superchainWeth)); emit RelayERC20(_sender, bob, _amount, _chainId); - vm.expectCall(Predeploys.ETH_LIQUIDITY, abi.encodeCall(ETHLiquidity.mint, (_amount)), 1); + vm.expectCall(Predeploys.ETH_LIQUIDITY, abi.encodeCall(IETHLiquidity.mint, (_amount)), 1); vm.prank(Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER); superchainWeth.relayERC20(_sender, bob, _amount); @@ -298,7 +300,7 @@ contract SuperchainWETH_Test is CommonTest { // Act vm.expectEmit(address(superchainWeth)); emit RelayERC20(_sender, bob, _amount, _chainId); - vm.expectCall(Predeploys.ETH_LIQUIDITY, abi.encodeCall(ETHLiquidity.mint, (_amount)), 0); + vm.expectCall(Predeploys.ETH_LIQUIDITY, abi.encodeCall(IETHLiquidity.mint, (_amount)), 0); vm.prank(Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER); superchainWeth.relayERC20(_sender, bob, _amount); diff --git a/packages/contracts-bedrock/test/invariants/ETHLiquidity.t.sol b/packages/contracts-bedrock/test/invariants/ETHLiquidity.t.sol index a7da876adb3b..8d1221a792c1 100644 --- a/packages/contracts-bedrock/test/invariants/ETHLiquidity.t.sol +++ b/packages/contracts-bedrock/test/invariants/ETHLiquidity.t.sol @@ -1,13 +1,16 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Testing import { StdUtils } from "forge-std/Test.sol"; import { Vm } from "forge-std/Vm.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; +// Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; -import { ETHLiquidity } from "src/L2/ETHLiquidity.sol"; -import { CommonTest } from "test/setup/CommonTest.sol"; +// Interfaces +import { IETHLiquidity } from "src/L2/interfaces/IETHLiquidity.sol"; /// @title ETHLiquidity_User /// @notice Actor contract that interacts with the ETHLiquidity contract. Always pretends to be the @@ -20,12 +23,12 @@ contract ETHLiquidity_User is StdUtils { Vm internal vm; /// @notice The ETHLiquidity contract. - ETHLiquidity internal liquidity; + IETHLiquidity internal liquidity; /// @param _vm The Vm contract. /// @param _liquidity The ETHLiquidity contract. /// @param _balance The initial balance of the contract. - constructor(Vm _vm, ETHLiquidity _liquidity, uint256 _balance) { + constructor(Vm _vm, IETHLiquidity _liquidity, uint256 _balance) { vm = _vm; liquidity = _liquidity; vm.deal(Predeploys.SUPERCHAIN_WETH, _balance); diff --git a/packages/contracts-bedrock/test/invariants/SuperchainWETH.t.sol b/packages/contracts-bedrock/test/invariants/SuperchainWETH.t.sol index 4d3d39724f1f..1e761b7ea162 100644 --- a/packages/contracts-bedrock/test/invariants/SuperchainWETH.t.sol +++ b/packages/contracts-bedrock/test/invariants/SuperchainWETH.t.sol @@ -1,14 +1,17 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Testing import { StdUtils } from "forge-std/Test.sol"; import { Vm } from "forge-std/Vm.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; +// Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; -import { SuperchainWETH } from "src/L2/SuperchainWETH.sol"; -import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; -import { CommonTest } from "test/setup/CommonTest.sol"; +// Interfaces +import { ISuperchainWETH } from "src/L2/interfaces/ISuperchainWETH.sol"; +import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; /// @title SuperchainWETH_User /// @notice Actor contract that interacts with the SuperchainWETH contract. @@ -26,7 +29,7 @@ contract SuperchainWETH_User is StdUtils { Vm internal vm; /// @notice The SuperchainWETH contract. - SuperchainWETH internal weth; + ISuperchainWETH internal weth; /// @notice Mapping of sent messages. mapping(bytes32 => bool) internal sent; @@ -37,7 +40,7 @@ contract SuperchainWETH_User is StdUtils { /// @param _vm The Vm contract. /// @param _weth The SuperchainWETH contract. /// @param _balance The initial balance of the contract. - constructor(Vm _vm, SuperchainWETH _weth, uint256 _balance) { + constructor(Vm _vm, ISuperchainWETH _weth, uint256 _balance) { vm = _vm; weth = _weth; vm.deal(address(this), _balance); diff --git a/packages/contracts-bedrock/test/legacy/L1BlockNumber.t.sol b/packages/contracts-bedrock/test/legacy/L1BlockNumber.t.sol index 3fad97699232..633a324e4043 100644 --- a/packages/contracts-bedrock/test/legacy/L1BlockNumber.t.sol +++ b/packages/contracts-bedrock/test/legacy/L1BlockNumber.t.sol @@ -1,15 +1,15 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -// Testing utilities +// Testing import { Test } from "forge-std/Test.sol"; -// Target contract dependencies +// Contracts +import { L1BlockNumber } from "src/legacy/L1BlockNumber.sol"; import { L1Block } from "src/L2/L1Block.sol"; -import { Predeploys } from "src/libraries/Predeploys.sol"; -// Target contract -import { L1BlockNumber } from "src/legacy/L1BlockNumber.sol"; +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; contract L1BlockNumberTest is Test { L1Block lb; diff --git a/packages/contracts-bedrock/test/setup/Setup.sol b/packages/contracts-bedrock/test/setup/Setup.sol index 4af2b8e62618..f2b29e8f1a91 100644 --- a/packages/contracts-bedrock/test/setup/Setup.sol +++ b/packages/contracts-bedrock/test/setup/Setup.sol @@ -14,15 +14,6 @@ import { OutputMode, Fork, ForkUtils } from "scripts/libraries/Config.sol"; import { Executables } from "scripts/libraries/Executables.sol"; // Contracts -import { BaseFeeVault } from "src/L2/BaseFeeVault.sol"; -import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol"; -import { L1FeeVault } from "src/L2/L1FeeVault.sol"; -import { GasPriceOracle } from "src/L2/GasPriceOracle.sol"; -import { L1Block } from "src/L2/L1Block.sol"; -import { FeeVault } from "src/universal/FeeVault.sol"; -import { WETH } from "src/L2/WETH.sol"; -import { SuperchainWETH } from "src/L2/SuperchainWETH.sol"; -import { ETHLiquidity } from "src/L2/ETHLiquidity.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { DelayedWETH } from "src/dispute/DelayedWETH.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; @@ -50,6 +41,14 @@ import { IL2ERC721Bridge } from "src/L2/interfaces/IL2ERC721Bridge.sol"; import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol"; import { IAddressManager } from "src/legacy/interfaces/IAddressManager.sol"; import { IOptimismERC20Factory } from "src/L2/interfaces/IOptimismERC20Factory.sol"; +import { IBaseFeeVault } from "src/L2/interfaces/IBaseFeeVault.sol"; +import { ISequencerFeeVault } from "src/L2/interfaces/ISequencerFeeVault.sol"; +import { IL1FeeVault } from "src/L2/interfaces/IL1FeeVault.sol"; +import { IGasPriceOracle } from "src/L2/interfaces/IGasPriceOracle.sol"; +import { IL1Block } from "src/L2/interfaces/IL1Block.sol"; +import { ISuperchainWETH } from "src/L2/interfaces/ISuperchainWETH.sol"; +import { IETHLiquidity } from "src/L2/interfaces/IETHLiquidity.sol"; +import { IWETH } from "src/universal/interfaces/IWETH.sol"; import { IGovernanceToken } from "src/governance/interfaces/IGovernanceToken.sol"; import { ILegacyMessagePasser } from "src/legacy/interfaces/ILegacyMessagePasser.sol"; @@ -99,16 +98,16 @@ contract Setup { IOptimismMintableERC20Factory l2OptimismMintableERC20Factory = IOptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); IL2ERC721Bridge l2ERC721Bridge = IL2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE); - BaseFeeVault baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT)); - SequencerFeeVault sequencerFeeVault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET)); - L1FeeVault l1FeeVault = L1FeeVault(payable(Predeploys.L1_FEE_VAULT)); - GasPriceOracle gasPriceOracle = GasPriceOracle(Predeploys.GAS_PRICE_ORACLE); - L1Block l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES); + IBaseFeeVault baseFeeVault = IBaseFeeVault(payable(Predeploys.BASE_FEE_VAULT)); + ISequencerFeeVault sequencerFeeVault = ISequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET)); + IL1FeeVault l1FeeVault = IL1FeeVault(payable(Predeploys.L1_FEE_VAULT)); + IGasPriceOracle gasPriceOracle = IGasPriceOracle(Predeploys.GAS_PRICE_ORACLE); + IL1Block l1Block = IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES); IGovernanceToken governanceToken = IGovernanceToken(Predeploys.GOVERNANCE_TOKEN); ILegacyMessagePasser legacyMessagePasser = ILegacyMessagePasser(Predeploys.LEGACY_MESSAGE_PASSER); - WETH weth = WETH(payable(Predeploys.WETH)); - SuperchainWETH superchainWeth = SuperchainWETH(payable(Predeploys.SUPERCHAIN_WETH)); - ETHLiquidity ethLiquidity = ETHLiquidity(Predeploys.ETH_LIQUIDITY); + IWETH weth = IWETH(payable(Predeploys.WETH)); + ISuperchainWETH superchainWeth = ISuperchainWETH(payable(Predeploys.SUPERCHAIN_WETH)); + IETHLiquidity ethLiquidity = IETHLiquidity(Predeploys.ETH_LIQUIDITY); // TODO: Replace with OptimismSuperchainERC20Factory when updating pragmas IOptimismERC20Factory l2OptimismSuperchainERC20Factory = From ff338bc169e346e0f811f59c376d312a7346b602 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Thu, 19 Sep 2024 11:22:59 -0600 Subject: [PATCH 203/264] feat: clean up TODOs and add CI check (#12005) * maint: clean up TODO tags Cleans up existing TODO tags, particularly those that referenced old Linear issues. Updates the todo-checker script to allow <#issue> as well as . * feat(ci): add todo-issues check to main CI Updates the main CI workflow to run the todo-issues check. For now this check will ignore any bare TODOs. We can update the script later to reject bare TODOs. --- .circleci/config.yml | 2 ++ cannon/mipsevm/multithreaded/instrumented_test.go | 2 +- op-e2e/opgeth/op_geth_test.go | 2 +- op-node/flags/flags.go | 2 +- op-node/node/node.go | 2 +- op-node/p2p/node.go | 2 +- op-node/p2p/sync.go | 4 ++-- op-node/rollup/engine/engine_controller.go | 2 +- op-node/rollup/engine/engine_update.go | 2 +- op-service/metrics/cli.go | 2 +- op-service/metrics/http.go | 4 ++-- op-service/oppprof/cli.go | 2 +- op-service/rpc/cli.go | 2 +- op-service/txmgr/txmgr.go | 6 +++--- ops/scripts/todo-checker.sh | 6 +++--- 15 files changed, 22 insertions(+), 20 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4f3706e24340..9fbc00b4859f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1763,6 +1763,8 @@ workflows: skip_slow_tests: true notify: true - cannon-build-test-vectors + - todo-issues: + name: todo-issues-check - shellcheck/check: name: shell-check # We don't need the `exclude` key as the orb detects the `.shellcheckrc` diff --git a/cannon/mipsevm/multithreaded/instrumented_test.go b/cannon/mipsevm/multithreaded/instrumented_test.go index 75a0694e3607..b3ce2d95eac3 100644 --- a/cannon/mipsevm/multithreaded/instrumented_test.go +++ b/cannon/mipsevm/multithreaded/instrumented_test.go @@ -20,7 +20,7 @@ func vmFactory(state *State, po mipsevm.PreimageOracle, stdOut, stdErr io.Writer func TestInstrumentedState_OpenMips(t *testing.T) { t.Parallel() - // TODO(cp-903): Add mt-specific tests here + // TODO: Add mt-specific tests here testutil.RunVMTests_OpenMips(t, CreateEmptyState, vmFactory, "clone.bin") } diff --git a/op-e2e/opgeth/op_geth_test.go b/op-e2e/opgeth/op_geth_test.go index 026c3559575e..0f27e7b7f047 100644 --- a/op-e2e/opgeth/op_geth_test.go +++ b/op-e2e/opgeth/op_geth_test.go @@ -129,7 +129,7 @@ func TestGethOnlyPendingBlockIsLatest(t *testing.T) { defer opGeth.Close() checkPending := func(stage string, number uint64) { - // TODO(CLI-4044): pending-block ID change + // TODO: pending-block ID change pendingBlock, err := opGeth.L2Client.BlockByNumber(ctx, big.NewInt(-1)) require.NoError(t, err, "failed to fetch pending block at stage "+stage) require.Equal(t, number, pendingBlock.NumberU64(), "pending block must have expected number") diff --git a/op-node/flags/flags.go b/op-node/flags/flags.go index dcb1597ce6e5..54334c150296 100644 --- a/op-node/flags/flags.go +++ b/op-node/flags/flags.go @@ -259,7 +259,7 @@ var ( MetricsAddrFlag = &cli.StringFlag{ Name: "metrics.addr", Usage: "Metrics listening address", - Value: "0.0.0.0", // TODO(CLI-4159): Switch to 127.0.0.1 + Value: "0.0.0.0", // TODO: Switch to 127.0.0.1 EnvVars: prefixEnvVars("METRICS_ADDR"), Category: OperationsCategory, } diff --git a/op-node/node/node.go b/op-node/node/node.go index d0853a63a79a..9d9f6a4343ac 100644 --- a/op-node/node/node.go +++ b/op-node/node/node.go @@ -490,7 +490,7 @@ func (n *OpNode) initP2P(cfg *Config) (err error) { panic("p2p node already initialized") } if n.p2pEnabled() { - // TODO(protocol-quest/97): Use EL Sync instead of CL Alt sync for fetching missing blocks in the payload queue. + // TODO(protocol-quest#97): Use EL Sync instead of CL Alt sync for fetching missing blocks in the payload queue. n.p2pNode, err = p2p.NewNodeP2P(n.resourcesCtx, &cfg.Rollup, n.log, cfg.P2P, n, n.l2Source, n.runCfg, n.metrics, false) if err != nil { return diff --git a/op-node/p2p/node.go b/op-node/p2p/node.go index 70f7dbc67c0b..85da1686acd7 100644 --- a/op-node/p2p/node.go +++ b/op-node/p2p/node.go @@ -79,7 +79,7 @@ func NewNodeP2P( } if n.host == nil { // See prior comment about n.host optionality: - // TODO(CLI-4016): host is not optional, NodeP2P as a whole is. + // TODO: host is not optional, NodeP2P as a whole is. panic("host is not optional if p2p is enabled") } return &n, nil diff --git a/op-node/p2p/sync.go b/op-node/p2p/sync.go index b838d000caf4..c8777fe51f92 100644 --- a/op-node/p2p/sync.go +++ b/op-node/p2p/sync.go @@ -57,7 +57,7 @@ const ( // If the client hits a request error, it counts as a lot of rate-limit tokens for syncing from that peer: // we rather sync from other servers. We'll try again later, // and eventually kick the peer based on degraded scoring if it's really not serving us well. - // TODO(CLI-4009): Use a backoff rather than this mechanism. + // TODO: Use a backoff rather than this mechanism. clientErrRateCost = peerServerBlocksBurst ) @@ -310,7 +310,7 @@ func NewSyncClient(log log.Logger, cfg *rollup.Config, host HostNewStream, rcv r } // never errors with positive LRU cache size - // TODO(CLI-3733): if we had an LRU based on on total payloads size, instead of payload count, + // TODO: if we had an LRU based on on total payloads size, instead of payload count, // we can safely buffer more data in the happy case. q, _ := simplelru.NewLRU[common.Hash, syncResult](100, c.onQuarantineEvict) c.quarantine = q diff --git a/op-node/rollup/engine/engine_controller.go b/op-node/rollup/engine/engine_controller.go index a5d4b5c4e881..4ac8b88a50cf 100644 --- a/op-node/rollup/engine/engine_controller.go +++ b/op-node/rollup/engine/engine_controller.go @@ -25,7 +25,7 @@ const ( // We transition between the 4 EL states linearly. We spend the majority of the time in the second & fourth. // We only want to EL sync if there is no finalized block & once we finish EL sync we need to mark the last block // as finalized so we can switch to consolidation - // TODO(protocol-quest/91): We can restart EL sync & still consolidate if there finalized blocks on the execution client if the + // TODO(protocol-quest#91): We can restart EL sync & still consolidate if there finalized blocks on the execution client if the // execution client is running in archive mode. In some cases we may want to switch back from CL to EL sync, but that is complicated. syncStatusWillStartEL // First if we are directed to EL sync, check that nothing has been finalized yet syncStatusStartedEL // Perform our EL sync diff --git a/op-node/rollup/engine/engine_update.go b/op-node/rollup/engine/engine_update.go index 8f100709bcc1..c79dbdcd0f4d 100644 --- a/op-node/rollup/engine/engine_update.go +++ b/op-node/rollup/engine/engine_update.go @@ -104,7 +104,7 @@ func startPayload(ctx context.Context, eng ExecEngine, fc eth.ForkchoiceState, a } switch fcRes.PayloadStatus.Status { - // TODO(proto): snap sync - specify explicit different error type if node is syncing + // TODO: snap sync - specify explicit different error type if node is syncing case eth.ExecutionInvalid, eth.ExecutionInvalidBlockHash: return eth.PayloadID{}, BlockInsertPayloadErr, eth.ForkchoiceUpdateErr(fcRes.PayloadStatus) case eth.ExecutionValid: diff --git a/op-service/metrics/cli.go b/op-service/metrics/cli.go index dcbe3d0af2ed..d5c8151b889a 100644 --- a/op-service/metrics/cli.go +++ b/op-service/metrics/cli.go @@ -37,7 +37,7 @@ func CLIFlags(envPrefix string) []cli.Flag { &cli.StringFlag{ Name: ListenAddrFlagName, Usage: "Metrics listening address", - Value: defaultListenAddr, // TODO(CLI-4159): Switch to 127.0.0.1 + Value: defaultListenAddr, // TODO: Switch to 127.0.0.1 EnvVars: opservice.PrefixEnvVar(envPrefix, "METRICS_ADDR"), }, &cli.IntFlag{ diff --git a/op-service/metrics/http.go b/op-service/metrics/http.go index 8640fe02a6f2..60609c563dca 100644 --- a/op-service/metrics/http.go +++ b/op-service/metrics/http.go @@ -65,7 +65,7 @@ var LatencyBuckets = []float64{.025, .05, .1, .25, .5, 1, 2.5, 5, 10, 25, 50, 10 func NewPromHTTPRecorder(r *prometheus.Registry, ns string) HTTPRecorder { return &PromHTTPRecorder{ - // TODO(INF-509): remove this in the future when services opted in to HTTPRequestLatency + // TODO: remove this in the future when services opted in to HTTPRequestLatency HTTPRequestDuration: promauto.With(r).NewHistogramVec(prometheus.HistogramOpts{ Namespace: ns, Name: "http_request_duration_ms", @@ -104,7 +104,7 @@ func NewPromHTTPRecorder(r *prometheus.Registry, ns string) HTTPRecorder { } func (p *PromHTTPRecorder) RecordHTTPRequestDuration(params *HTTPParams, dur time.Duration) { - // TODO(INF-509): remove this in the future when services opted in to new metric + // TODO: remove this in the future when services opted in to new metric p.HTTPRequestDuration.WithLabelValues(params.Method, strconv.Itoa(params.StatusCode)). Observe(float64(dur.Milliseconds())) diff --git a/op-service/oppprof/cli.go b/op-service/oppprof/cli.go index d6ccb8566960..6c2c33a14711 100644 --- a/op-service/oppprof/cli.go +++ b/op-service/oppprof/cli.go @@ -76,7 +76,7 @@ func CLIFlagsWithCategory(envPrefix string, category string) []cli.Flag { &cli.StringFlag{ Name: ListenAddrFlagName, Usage: "pprof listening address", - Value: defaultListenAddr, // TODO(CLI-4159): Switch to 127.0.0.1 + Value: defaultListenAddr, // TODO: Switch to 127.0.0.1 EnvVars: opservice.PrefixEnvVar(envPrefix, "PPROF_ADDR"), Category: category, }, diff --git a/op-service/rpc/cli.go b/op-service/rpc/cli.go index 99cb2dd6c9b2..ef957765e19f 100644 --- a/op-service/rpc/cli.go +++ b/op-service/rpc/cli.go @@ -21,7 +21,7 @@ func CLIFlags(envPrefix string) []cli.Flag { &cli.StringFlag{ Name: ListenAddrFlagName, Usage: "rpc listening address", - Value: "0.0.0.0", // TODO(CLI-4159): Switch to 127.0.0.1 + Value: "0.0.0.0", // TODO: Switch to 127.0.0.1 EnvVars: opservice.PrefixEnvVar(envPrefix, "RPC_ADDR"), }, &cli.IntFlag{ diff --git a/op-service/txmgr/txmgr.go b/op-service/txmgr/txmgr.go index f8605f75322b..a0e944f8a5be 100644 --- a/op-service/txmgr/txmgr.go +++ b/op-service/txmgr/txmgr.go @@ -110,7 +110,7 @@ type ETHBackend interface { SendTransaction(ctx context.Context, tx *types.Transaction) error // These functions are used to estimate what the base fee & priority fee should be set to. - // TODO(CLI-3318): Maybe need a generic interface to support different RPC providers + // TODO: Maybe need a generic interface to support different RPC providers HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) SuggestGasTipCap(ctx context.Context) (*big.Int, error) // NonceAt returns the account nonce of the given account. @@ -983,7 +983,7 @@ func updateFees(oldTip, oldFeeCap, newTip, newBaseFee *big.Int, isBlobTx bool, l return newTip, newFeeCap } else if newTip.Cmp(thresholdTip) >= 0 && newFeeCap.Cmp(thresholdFeeCap) < 0 { // Tip has gone up, but base fee is flat or down. - // TODO(CLI-3714): Do we need to recalculate the FC here? + // TODO: Do we need to recalculate the FC here? lgr.Debug("Using new tip and threshold feecap") return newTip, thresholdFeeCap } else if newTip.Cmp(thresholdTip) < 0 && newFeeCap.Cmp(thresholdFeeCap) >= 0 { @@ -993,7 +993,7 @@ func updateFees(oldTip, oldFeeCap, newTip, newBaseFee *big.Int, isBlobTx bool, l return thresholdTip, calcGasFeeCap(newBaseFee, thresholdTip) } else { - // TODO(CLI-3713): Should we skip the bump in this case? + // TODO: Should we skip the bump in this case? lgr.Debug("Using threshold tip and threshold feecap") return thresholdTip, thresholdFeeCap } diff --git a/ops/scripts/todo-checker.sh b/ops/scripts/todo-checker.sh index d90d97fc47c9..4aebcf1a957d 100755 --- a/ops/scripts/todo-checker.sh +++ b/ops/scripts/todo-checker.sh @@ -65,10 +65,10 @@ for todo in $todos; do # * TODO(repo#): (Default org "ethereum-optimism") # * TODO(org/repo#): # - # Check if it's just a number - if [[ $ISSUE_REFERENCE =~ ^[0-9]+$ ]]; then + # Check if it's just a number or a number with a leading # + if [[ $ISSUE_REFERENCE =~ ^[0-9]+$ ]] || [[ $ISSUE_REFERENCE =~ ^#([0-9]+)$ ]]; then REPO_FULL="$ORG/$REPO" - ISSUE_NUM="$ISSUE_REFERENCE" + ISSUE_NUM="${ISSUE_REFERENCE#\#}" # Remove leading # if present # Check for org_name/repo_name#number format elif [[ $ISSUE_REFERENCE =~ ^([^/]+)/([^#]+)#([0-9]+)$ ]]; then REPO_FULL="${BASH_REMATCH[1]}/${BASH_REMATCH[2]}" From 4806d83e7a432ecb33b52de13360cc0fbae5067c Mon Sep 17 00:00:00 2001 From: Inphi Date: Thu, 19 Sep 2024 13:41:00 -0400 Subject: [PATCH 204/264] contracts: Add more MIPS2 tests (#12003) * contracts: Add more MIPS2 tests * remove unused var --- .../contracts-bedrock/test/cannon/MIPS2.t.sol | 205 +++++++++++++++++- 1 file changed, 203 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/test/cannon/MIPS2.t.sol b/packages/contracts-bedrock/test/cannon/MIPS2.t.sol index 969486265ff6..4c02d7a0bdd1 100644 --- a/packages/contracts-bedrock/test/cannon/MIPS2.t.sol +++ b/packages/contracts-bedrock/test/cannon/MIPS2.t.sol @@ -2463,8 +2463,209 @@ contract MIPS2_Test is CommonTest { assertEq(postState, outputState(expect), "unexpected post state"); } - // TODO(client-pod#959): Port over the remaining single-threaded tests from MIPS.t.sol - // TODO(client-pod#959): Assert unimplemented syscalls + function test_sll_succeeds() external { + uint8 shiftamt = 4; + uint32 insn = encodespec(0x0, 0x9, 0x8, uint16(shiftamt) << 6); // sll t0, t1, 3 + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = + constructMIPSState(0, insn, 0x4, 0); + thread.registers[9] = 0x20; // t1 + updateThreadStacks(state, thread); + + uint32 result = thread.registers[9] << shiftamt; + MIPS2.State memory expect = arithmeticPostState(state, thread, 8, /* t0 */ result); + + bytes32 postState = mips.step( + encodeState(state), bytes.concat(abi.encodePacked(encodeThread(thread), EMPTY_THREAD_ROOT), memProof), 0 + ); + assertEq(postState, outputState(expect), "unexpected post state"); + } + + function test_srl_succeeds() external { + uint8 shiftamt = 4; + uint32 insn = encodespec(0x0, 0x9, 0x8, uint16(shiftamt) << 6 | 2); // srl t0, t1, 3 + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = + constructMIPSState(0, insn, 0x4, 0); + thread.registers[9] = 0x20; // t1 + updateThreadStacks(state, thread); + + uint32 result = thread.registers[9] >> shiftamt; + MIPS2.State memory expect = arithmeticPostState(state, thread, 8, /* t0 */ result); + + bytes32 postState = mips.step( + encodeState(state), bytes.concat(abi.encodePacked(encodeThread(thread), EMPTY_THREAD_ROOT), memProof), 0 + ); + assertEq(postState, outputState(expect), "unexpected post state"); + } + + function test_sra_succeeds() external { + uint8 shiftamt = 4; + uint32 insn = encodespec(0x0, 0x9, 0x8, uint16(shiftamt) << 6 | 3); // sra t0, t1, 3 + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = + constructMIPSState(0, insn, 0x4, 0); + thread.registers[9] = 0x80_00_00_20; // t1 + updateThreadStacks(state, thread); + + uint32 result = 0xF8_00_00_02; // 4 shifts while preserving sign bit + MIPS2.State memory expect = arithmeticPostState(state, thread, 8, /* t0 */ result); + + bytes32 postState = mips.step( + encodeState(state), bytes.concat(abi.encodePacked(encodeThread(thread), EMPTY_THREAD_ROOT), memProof), 0 + ); + assertEq(postState, outputState(expect), "unexpected post state"); + } + + function test_sllv_succeeds() external { + uint32 insn = encodespec(0xa, 0x9, 0x8, 4); // sllv t0, t1, t2 + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = + constructMIPSState(0, insn, 0x4, 0); + thread.registers[9] = 0x20; // t1 + thread.registers[10] = 4; // t2 + updateThreadStacks(state, thread); + + uint32 result = thread.registers[9] << thread.registers[10]; + MIPS2.State memory expect = arithmeticPostState(state, thread, 8, /* t0 */ result); + + bytes32 postState = mips.step( + encodeState(state), bytes.concat(abi.encodePacked(encodeThread(thread), EMPTY_THREAD_ROOT), memProof), 0 + ); + assertEq(postState, outputState(expect), "unexpected post state"); + } + + function test_srlv_succeeds() external { + uint32 insn = encodespec(0xa, 0x9, 0x8, 6); // srlv t0, t1, t2 + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = + constructMIPSState(0, insn, 0x4, 0); + thread.registers[9] = 0x20_00; // t1 + thread.registers[10] = 4; // t2 + updateThreadStacks(state, thread); + + uint32 result = thread.registers[9] >> thread.registers[10]; + MIPS2.State memory expect = arithmeticPostState(state, thread, 8, /* t0 */ result); + + bytes32 postState = mips.step( + encodeState(state), bytes.concat(abi.encodePacked(encodeThread(thread), EMPTY_THREAD_ROOT), memProof), 0 + ); + assertEq(postState, outputState(expect), "unexpected post state"); + } + + function test_lui_succeeds() external { + uint32 insn = encodeitype(0xf, 0x0, 0x8, 0x4); // lui $t0, 0x04 + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = + constructMIPSState(0, insn, 0x4, 0); + updateThreadStacks(state, thread); + + MIPS2.State memory expect = arithmeticPostState(state, thread, 8, /* t0 */ 0x00_04_00_00); + bytes32 postState = mips.step( + encodeState(state), bytes.concat(abi.encodePacked(encodeThread(thread), EMPTY_THREAD_ROOT), memProof), 0 + ); + assertEq(postState, outputState(expect), "unexpected post state"); + } + + function test_clo_succeeds() external { + uint32 insn = encodespec2(0x9, 0x0, 0x8, 0x21); // clo t0, t1 + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = + constructMIPSState(0, insn, 0x4, 0); + thread.registers[9] = 0xFF_00_00_00; // t1 + updateThreadStacks(state, thread); + + MIPS2.State memory expect = arithmeticPostState(state, thread, 8, /* t0 */ 8); + bytes32 postState = mips.step( + encodeState(state), bytes.concat(abi.encodePacked(encodeThread(thread), EMPTY_THREAD_ROOT), memProof), 0 + ); + assertEq(postState, outputState(expect), "unexpected post state"); + } + + function test_clz_succeeds() external { + uint32 insn = encodespec2(0x9, 0x0, 0x8, 0x20); // clz t0, t1 + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = + constructMIPSState(0, insn, 0x4, 0); + thread.registers[9] = 0x00_00_F0_00; // t1 + updateThreadStacks(state, thread); + + MIPS2.State memory expect = arithmeticPostState(state, thread, 8, /* t0 */ 16); + bytes32 postState = mips.step( + encodeState(state), bytes.concat(abi.encodePacked(encodeThread(thread), EMPTY_THREAD_ROOT), memProof), 0 + ); + assertEq(postState, outputState(expect), "unexpected post state"); + } + + function test_preimage_read_succeeds() external { + uint32 pc = 0x0; + uint32 insn = 0x0000000c; // syscall + uint32 a1 = 0x4; + uint32 a1_val = 0x0000abba; + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = + constructMIPSState(0, insn, a1, a1_val); + state.preimageKey = bytes32(uint256(1) << 248 | 0x01); + state.preimageOffset = 8; // start reading past the pre-image length prefix + thread.registers[2] = 4003; // read syscall + thread.registers[4] = 5; // fd + thread.registers[5] = a1; // addr + thread.registers[6] = 4; // count + threading.createThread(); + threading.replaceCurrent(thread); + bytes memory threadWitness = threading.witness(); + finalizeThreadingState(threading, state); + + MIPS2.ThreadState memory expectThread = copyThread(thread); + expectThread.pc = thread.nextPC; + expectThread.nextPC = thread.nextPC + 4; + expectThread.registers[2] = 4; // return + expectThread.registers[7] = 0; // errno + threading.replaceCurrent(expectThread); + + // prime the pre-image oracle + bytes32 word = bytes32(uint256(0xdeadbeef) << 224); + uint8 size = 4; + uint8 partOffset = 8; + oracle.loadLocalData(uint256(state.preimageKey), 0, word, size, partOffset); + + MIPS2.State memory expect = copyState(state); + expect.preimageOffset += 4; + expect.step = state.step + 1; + expect.stepsSinceLastContextSwitch = state.stepsSinceLastContextSwitch + 1; + // recompute merkle root of written pre-image + (expect.memRoot,) = ffi.getCannonMemoryProof(pc, insn, a1, 0xdeadbeef); + finalizeThreadingState(threading, expect); + + bytes32 postState = mips.step(encodeState(state), bytes.concat(threadWitness, memProof), 0); + assertEq(postState, outputState(expect), "unexpected post state"); + } + + function test_preimage_write_succeeds() external { + uint32 insn = 0x0000000c; // syscall + uint32 a1 = 0x4; + uint32 a1_val = 0x0000abba; + (MIPS2.State memory state, MIPS2.ThreadState memory thread, bytes memory memProof) = + constructMIPSState(0, insn, a1, a1_val); + state.preimageKey = bytes32(0); + state.preimageOffset = 1; + thread.registers[2] = 4004; // write syscall + thread.registers[4] = 6; // fd + thread.registers[5] = a1; // addr + thread.registers[6] = 4; // count + threading.createThread(); + threading.replaceCurrent(thread); + bytes memory threadWitness = threading.witness(); + finalizeThreadingState(threading, state); + + MIPS2.ThreadState memory expectThread = copyThread(thread); + expectThread.pc = thread.nextPC; + expectThread.nextPC = thread.nextPC + 4; + expectThread.registers[2] = 4; // return + expectThread.registers[7] = 0; // errno + threading.replaceCurrent(expectThread); + + MIPS2.State memory expect = copyState(state); + expect.preimageKey = bytes32(uint256(0xabba)); + expect.preimageOffset = 0; + expect.step = state.step + 1; + expect.stepsSinceLastContextSwitch = state.stepsSinceLastContextSwitch + 1; + finalizeThreadingState(threading, expect); + + bytes32 postState = mips.step(encodeState(state), bytes.concat(threadWitness, memProof), 0); + assertEq(postState, outputState(expect), "unexpected post state"); + } /// @dev Modifies the MIPS2 State based on threading state function finalizeThreadingState(Threading _threading, MIPS2.State memory _state) internal view { From 29dd98b0adf9d7ff31909faa3fe73999d6768398 Mon Sep 17 00:00:00 2001 From: mbaxter Date: Thu, 19 Sep 2024 14:07:23 -0400 Subject: [PATCH 205/264] cannon: Clean up fuzz test todos (#12009) * cannon: Add memory assertions to FuzzStatePreimageRead * cannon: Rework hint write fuzz test to assert hint expectations * cannon: Update FuzzStatePreimageWrite to assert on expected preimageKey * cannon: Remove validation skipping logic from test util * cannon: Cleanup - simplify code * cannon: Cleanup - dedupe code --- .../multithreaded/testutil/mutators.go | 9 +- .../mipsevm/multithreaded/testutil/thread.go | 8 +- .../mipsevm/singlethreaded/testutil/state.go | 14 +- cannon/mipsevm/tests/fuzz_evm_common_test.go | 123 +++++++++++++----- cannon/mipsevm/testutil/rand.go | 63 ++++++--- cannon/mipsevm/testutil/state.go | 52 ++++---- 6 files changed, 178 insertions(+), 91 deletions(-) diff --git a/cannon/mipsevm/multithreaded/testutil/mutators.go b/cannon/mipsevm/multithreaded/testutil/mutators.go index 529f496f950f..a44ba23a4fac 100644 --- a/cannon/mipsevm/multithreaded/testutil/mutators.go +++ b/cannon/mipsevm/multithreaded/testutil/mutators.go @@ -2,7 +2,6 @@ package testutil import ( "math" - "math/rand" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -23,14 +22,14 @@ func NewStateMutatorMultiThreaded(state *multithreaded.State) testutil.StateMuta } func (m *StateMutatorMultiThreaded) Randomize(randSeed int64) { - r := rand.New(rand.NewSource(randSeed)) + r := testutil.NewRandHelper(randSeed) - step := testutil.RandStep(r) + step := r.RandStep() - m.state.PreimageKey = testutil.RandHash(r) + m.state.PreimageKey = r.RandHash() m.state.PreimageOffset = r.Uint32() m.state.Step = step - m.state.LastHint = testutil.RandHint(r) + m.state.LastHint = r.RandHint() m.state.StepsSinceLastContextSwitch = uint64(r.Intn(exec.SchedQuantum)) // Randomize memory-related fields diff --git a/cannon/mipsevm/multithreaded/testutil/thread.go b/cannon/mipsevm/multithreaded/testutil/thread.go index 217ab94e8185..f5b1d29a8dd6 100644 --- a/cannon/mipsevm/multithreaded/testutil/thread.go +++ b/cannon/mipsevm/multithreaded/testutil/thread.go @@ -1,19 +1,17 @@ package testutil import ( - "math/rand" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" "github.com/ethereum-optimism/optimism/cannon/mipsevm/testutil" ) func RandomThread(randSeed int64) *multithreaded.ThreadState { - r := rand.New(rand.NewSource(randSeed)) + r := testutil.NewRandHelper(randSeed) thread := multithreaded.CreateEmptyThread() - pc := testutil.RandPC(r) + pc := r.RandPC() - thread.Registers = *testutil.RandRegisters(r) + thread.Registers = *r.RandRegisters() thread.Cpu.PC = pc thread.Cpu.NextPC = pc + 4 thread.Cpu.HI = r.Uint32() diff --git a/cannon/mipsevm/singlethreaded/testutil/state.go b/cannon/mipsevm/singlethreaded/testutil/state.go index f09b56175af9..079827500e45 100644 --- a/cannon/mipsevm/singlethreaded/testutil/state.go +++ b/cannon/mipsevm/singlethreaded/testutil/state.go @@ -1,8 +1,6 @@ package testutil import ( - "math/rand" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -15,12 +13,12 @@ type StateMutatorSingleThreaded struct { } func (m *StateMutatorSingleThreaded) Randomize(randSeed int64) { - r := rand.New(rand.NewSource(randSeed)) + r := testutil.NewRandHelper(randSeed) - pc := testutil.RandPC(r) - step := testutil.RandStep(r) + pc := r.RandPC() + step := r.RandStep() - m.state.PreimageKey = testutil.RandHash(r) + m.state.PreimageKey = r.RandHash() m.state.PreimageOffset = r.Uint32() m.state.Cpu.PC = pc m.state.Cpu.NextPC = pc + 4 @@ -28,8 +26,8 @@ func (m *StateMutatorSingleThreaded) Randomize(randSeed int64) { m.state.Cpu.LO = r.Uint32() m.state.Heap = r.Uint32() m.state.Step = step - m.state.LastHint = testutil.RandHint(r) - m.state.Registers = *testutil.RandRegisters(r) + m.state.LastHint = r.RandHint() + m.state.Registers = *r.RandRegisters() } var _ testutil.StateMutator = (*StateMutatorSingleThreaded)(nil) diff --git a/cannon/mipsevm/tests/fuzz_evm_common_test.go b/cannon/mipsevm/tests/fuzz_evm_common_test.go index 2f68706b60d3..2b85727679b1 100644 --- a/cannon/mipsevm/tests/fuzz_evm_common_test.go +++ b/cannon/mipsevm/tests/fuzz_evm_common_test.go @@ -2,10 +2,11 @@ package tests import ( "bytes" + "encoding/binary" + "math" "os" "testing" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/require" @@ -216,24 +217,29 @@ func FuzzStateHintRead(f *testing.F) { func FuzzStatePreimageRead(f *testing.F) { versions := GetMipsVersionTestCases(f) - f.Fuzz(func(t *testing.T, addr uint32, count uint32, preimageOffset uint32, seed int64) { + f.Fuzz(func(t *testing.T, addr uint32, pc uint32, count uint32, preimageOffset uint32, seed int64) { for _, v := range versions { t.Run(v.Name, func(t *testing.T) { + effAddr := addr & 0xFF_FF_FF_FC + pc = pc & 0xFF_FF_FF_FC + preexistingMemoryVal := [4]byte{0xFF, 0xFF, 0xFF, 0xFF} preimageValue := []byte("hello world") - if preimageOffset >= uint32(len(preimageValue)) { + preimageData := testutil.AddPreimageLengthPrefix(preimageValue) + if preimageOffset >= uint32(len(preimageData)) || pc == effAddr { t.SkipNow() } preimageKey := preimage.Keccak256Key(crypto.Keccak256Hash(preimageValue)).PreimageKey() oracle := testutil.StaticOracle(t, preimageValue) goVm := v.VMFactory(oracle, os.Stdout, os.Stderr, testutil.CreateLogger(), - testutil.WithRandomization(seed), testutil.WithPreimageKey(preimageKey), testutil.WithPreimageOffset(preimageOffset)) + testutil.WithRandomization(seed), testutil.WithPreimageKey(preimageKey), testutil.WithPreimageOffset(preimageOffset), testutil.WithPCAndNextPC(pc)) state := goVm.GetState() state.GetRegistersRef()[2] = exec.SysRead state.GetRegistersRef()[4] = exec.FdPreimageRead state.GetRegistersRef()[5] = addr state.GetRegistersRef()[6] = count state.GetMemory().SetMemory(state.GetPC(), syscallInsn) + state.GetMemory().SetMemory(effAddr, binary.BigEndian.Uint32(preexistingMemoryVal[:])) step := state.GetStep() alignment := addr & 3 @@ -242,7 +248,7 @@ func FuzzStatePreimageRead(f *testing.F) { writeLen = count } // Cap write length to remaining bytes of the preimage - preimageDataLen := uint32(len(preimageValue) + 8) // Data len includes a length prefix + preimageDataLen := uint32(len(preimageData)) if preimageOffset+writeLen > preimageDataLen { writeLen = preimageDataLen - preimageOffset } @@ -254,18 +260,18 @@ func FuzzStatePreimageRead(f *testing.F) { expected.Registers[2] = writeLen expected.Registers[7] = 0 // no error expected.PreimageOffset += writeLen + if writeLen > 0 { + // Expect a memory write + expectedMemory := preexistingMemoryVal + copy(expectedMemory[alignment:], preimageData[preimageOffset:preimageOffset+writeLen]) + expected.ExpectMemoryWrite(effAddr, binary.BigEndian.Uint32(expectedMemory[:])) + } stepWitness, err := goVm.Step(true) require.NoError(t, err) require.True(t, stepWitness.HasPreimage()) - // TODO(cp-983) - Do stricter validation of expected memory - expected.Validate(t, state, testutil.SkipMemoryValidation) - if writeLen == 0 { - // Note: We are not asserting a memory root change when writeLen > 0 because we may not necessarily - // modify memory - it's possible we just write the leading zero bytes of the length prefix - require.Equal(t, expected.MemoryRoot, common.Hash(state.GetMemory().MerkleRoot())) - } + expected.Validate(t, state) testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, nil) }) } @@ -274,43 +280,80 @@ func FuzzStatePreimageRead(f *testing.F) { func FuzzStateHintWrite(f *testing.F) { versions := GetMipsVersionTestCases(f) - f.Fuzz(func(t *testing.T, addr uint32, count uint32, randSeed int64) { + f.Fuzz(func(t *testing.T, addr uint32, count uint32, hint1, hint2, hint3 []byte, randSeed int64) { for _, v := range versions { t.Run(v.Name, func(t *testing.T) { - preimageData := []byte("hello world") - preimageKey := preimage.Keccak256Key(crypto.Keccak256Hash(preimageData)).PreimageKey() - // TODO(cp-983) - use testutil.HintTrackingOracle, validate expected hints - oracle := testutil.StaticOracle(t, preimageData) // only used for hinting + // Make sure pc does not overlap with hint data in memory + pc := uint32(0) + if addr <= 8 { + addr += 8 + } + + // Set up hint data + r := testutil.NewRandHelper(randSeed) + hints := [][]byte{hint1, hint2, hint3} + hintData := make([]byte, 0) + for _, hint := range hints { + prefixedHint := testutil.AddHintLengthPrefix(hint) + hintData = append(hintData, prefixedHint...) + } + lastHintLen := math.Round(r.Fraction() * float64(len(hintData))) + lastHint := hintData[:int(lastHintLen)] + expectedBytesToProcess := int(count) + int(lastHintLen) + if expectedBytesToProcess > len(hintData) { + // Add an extra hint to span the rest of the hint data + randomHint := r.RandomBytes(t, expectedBytesToProcess) + prefixedHint := testutil.AddHintLengthPrefix(randomHint) + hintData = append(hintData, prefixedHint...) + hints = append(hints, randomHint) + } + // Set up state + oracle := &testutil.HintTrackingOracle{} goVm := v.VMFactory(oracle, os.Stdout, os.Stderr, testutil.CreateLogger(), - testutil.WithRandomization(randSeed), testutil.WithPreimageKey(preimageKey)) + testutil.WithRandomization(randSeed), testutil.WithLastHint(lastHint), testutil.WithPCAndNextPC(pc)) state := goVm.GetState() state.GetRegistersRef()[2] = exec.SysWrite state.GetRegistersRef()[4] = exec.FdHintWrite state.GetRegistersRef()[5] = addr state.GetRegistersRef()[6] = count step := state.GetStep() - - // Set random data at the target memory range - randBytes := testutil.RandomBytes(t, randSeed, count) - err := state.GetMemory().SetMemoryRange(addr, bytes.NewReader(randBytes)) + err := state.GetMemory().SetMemoryRange(addr, bytes.NewReader(hintData[int(lastHintLen):])) require.NoError(t, err) - // Set instruction state.GetMemory().SetMemory(state.GetPC(), syscallInsn) + // Set up expectations expected := testutil.NewExpectedState(state) expected.Step += 1 expected.PC = state.GetCpu().NextPC expected.NextPC = state.GetCpu().NextPC + 4 expected.Registers[2] = count expected.Registers[7] = 0 // no error + // Figure out hint expectations + var expectedHints [][]byte + expectedLastHint := make([]byte, 0) + byteIndex := 0 + for _, hint := range hints { + hintDataLength := len(hint) + 4 // Hint data + prefix + hintLastByteIndex := hintDataLength + byteIndex - 1 + if hintLastByteIndex < expectedBytesToProcess { + expectedHints = append(expectedHints, hint) + } else { + expectedLastHint = hintData[byteIndex:expectedBytesToProcess] + break + } + byteIndex += hintDataLength + } + expected.LastHint = expectedLastHint + // Run state transition stepWitness, err := goVm.Step(true) require.NoError(t, err) require.False(t, stepWitness.HasPreimage()) - // TODO(cp-983) - validate expected hints - expected.Validate(t, state, testutil.SkipHintValidation) + // Validate + require.Equal(t, expectedHints, oracle.Hints()) + expected.Validate(t, state) testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, nil) }) } @@ -322,23 +365,33 @@ func FuzzStatePreimageWrite(f *testing.F) { f.Fuzz(func(t *testing.T, addr uint32, count uint32, seed int64) { for _, v := range versions { t.Run(v.Name, func(t *testing.T) { + // Make sure pc does not overlap with preimage data in memory + pc := uint32(0) + if addr <= 8 { + addr += 8 + } + effAddr := addr & 0xFF_FF_FF_FC + preexistingMemoryVal := [4]byte{0x12, 0x34, 0x56, 0x78} preimageData := []byte("hello world") preimageKey := preimage.Keccak256Key(crypto.Keccak256Hash(preimageData)).PreimageKey() oracle := testutil.StaticOracle(t, preimageData) goVm := v.VMFactory(oracle, os.Stdout, os.Stderr, testutil.CreateLogger(), - testutil.WithRandomization(seed), testutil.WithPreimageKey(preimageKey), testutil.WithPreimageOffset(128)) + testutil.WithRandomization(seed), testutil.WithPreimageKey(preimageKey), testutil.WithPreimageOffset(128), testutil.WithPCAndNextPC(pc)) state := goVm.GetState() state.GetRegistersRef()[2] = exec.SysWrite state.GetRegistersRef()[4] = exec.FdPreimageWrite state.GetRegistersRef()[5] = addr state.GetRegistersRef()[6] = count state.GetMemory().SetMemory(state.GetPC(), syscallInsn) + state.GetMemory().SetMemory(effAddr, binary.BigEndian.Uint32(preexistingMemoryVal[:])) step := state.GetStep() - sz := 4 - (addr & 0x3) - if sz < count { - count = sz + expectBytesWritten := count + alignment := addr & 0x3 + sz := 4 - alignment + if sz < expectBytesWritten { + expectBytesWritten = sz } expected := testutil.NewExpectedState(state) @@ -346,15 +399,21 @@ func FuzzStatePreimageWrite(f *testing.F) { expected.PC = state.GetCpu().NextPC expected.NextPC = state.GetCpu().NextPC + 4 expected.PreimageOffset = 0 - expected.Registers[2] = count + expected.Registers[2] = expectBytesWritten expected.Registers[7] = 0 // No error + expected.PreimageKey = preimageKey + if expectBytesWritten > 0 { + // Copy original preimage key, but shift it left by expectBytesWritten + copy(expected.PreimageKey[:], preimageKey[expectBytesWritten:]) + // Copy memory data to rightmost expectedBytesWritten + copy(expected.PreimageKey[32-expectBytesWritten:], preexistingMemoryVal[alignment:]) + } stepWitness, err := goVm.Step(true) require.NoError(t, err) require.False(t, stepWitness.HasPreimage()) - // TODO(cp-983) - validate preimage key - expected.Validate(t, state, testutil.SkipPreimageKeyValidation) + expected.Validate(t, state) testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, nil) }) } diff --git a/cannon/mipsevm/testutil/rand.go b/cannon/mipsevm/testutil/rand.go index 2364c7ad5e92..96ff0eb6318b 100644 --- a/cannon/mipsevm/testutil/rand.go +++ b/cannon/mipsevm/testutil/rand.go @@ -1,53 +1,82 @@ package testutil import ( + "encoding/binary" "math/rand" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" ) -func RandHash(r *rand.Rand) common.Hash { +type RandHelper struct { + r *rand.Rand +} + +func NewRandHelper(seed int64) *RandHelper { + r := rand.New(rand.NewSource(seed)) + return &RandHelper{r: r} +} + +func (h *RandHelper) Uint32() uint32 { + return h.r.Uint32() +} + +func (h *RandHelper) Fraction() float64 { + return h.r.Float64() +} + +func (h *RandHelper) Intn(n int) int { + return h.r.Intn(n) +} + +func (h *RandHelper) RandHash() common.Hash { var bytes [32]byte - _, err := r.Read(bytes[:]) + _, err := h.r.Read(bytes[:]) if err != nil { panic(err) } return bytes } -func RandHint(r *rand.Rand) []byte { - count := r.Intn(10) +func (h *RandHelper) RandHint() []byte { - bytes := make([]byte, count) - _, err := r.Read(bytes[:]) - if err != nil { - panic(err) + bytesCount := h.r.Intn(24) + bytes := make([]byte, bytesCount) + + if bytesCount >= 8 { + // Set up a reasonable length prefix + nextHintLen := uint64(h.r.Intn(30)) + binary.BigEndian.PutUint64(bytes, nextHintLen) + + _, err := h.r.Read(bytes[8:]) + if err != nil { + panic(err) + } } + return bytes } -func RandRegisters(r *rand.Rand) *[32]uint32 { +func (h *RandHelper) RandRegisters() *[32]uint32 { registers := new([32]uint32) for i := 0; i < 32; i++ { - registers[i] = r.Uint32() + registers[i] = h.r.Uint32() } return registers } -func RandomBytes(t require.TestingT, seed int64, length uint32) []byte { - r := rand.New(rand.NewSource(seed)) +func (h *RandHelper) RandomBytes(t require.TestingT, length int) []byte { randBytes := make([]byte, length) - if _, err := r.Read(randBytes); err != nil { + if _, err := h.r.Read(randBytes); err != nil { require.NoError(t, err) } return randBytes } -func RandPC(r *rand.Rand) uint32 { - return AlignPC(r.Uint32()) +func (h *RandHelper) RandPC() uint32 { + return AlignPC(h.r.Uint32()) } -func RandStep(r *rand.Rand) uint64 { - return BoundStep(r.Uint64()) +func (h *RandHelper) RandStep() uint64 { + return BoundStep(h.r.Uint64()) } diff --git a/cannon/mipsevm/testutil/state.go b/cannon/mipsevm/testutil/state.go index 3aee7a4539c5..86d5cfb2b6ad 100644 --- a/cannon/mipsevm/testutil/state.go +++ b/cannon/mipsevm/testutil/state.go @@ -1,8 +1,8 @@ package testutil import ( + "encoding/binary" "fmt" - "slices" "testing" "github.com/ethereum/go-ethereum/common" @@ -13,10 +13,22 @@ import ( "github.com/ethereum-optimism/optimism/cannon/mipsevm/memory" ) -func CopyRegisters(state mipsevm.FPVMState) *[32]uint32 { - copy := new([32]uint32) - *copy = *state.GetRegistersRef() - return copy +func AddHintLengthPrefix(data []byte) []byte { + dataLen := len(data) + prefixed := make([]byte, 0, dataLen+4) + prefixed = binary.BigEndian.AppendUint32(prefixed, uint32(dataLen)) + prefixed = append(prefixed, data...) + + return prefixed +} + +func AddPreimageLengthPrefix(data []byte) []byte { + dataLen := len(data) + prefixed := make([]byte, 0, dataLen+8) + prefixed = binary.BigEndian.AppendUint64(prefixed, uint64(dataLen)) + prefixed = append(prefixed, data...) + + return prefixed } type StateMutator interface { @@ -48,6 +60,13 @@ func WithNextPC(nextPC uint32) StateOption { } } +func WithPCAndNextPC(pc uint32) StateOption { + return func(state StateMutator) { + state.SetPC(pc) + state.SetNextPC(pc + 4) + } +} + func WithHeap(addr uint32) StateOption { return func(state StateMutator) { state.SetHeap(addr) @@ -150,19 +169,8 @@ func (e *ExpectedState) ExpectMemoryWrite(addr uint32, val uint32) { e.MemoryRoot = e.expectedMemory.MerkleRoot() } -type StateValidationFlags int - -// TODO(cp-983) - Remove these validation hacks -const ( - SkipMemoryValidation StateValidationFlags = iota - SkipHintValidation - SkipPreimageKeyValidation -) - -func (e *ExpectedState) Validate(t testing.TB, actualState mipsevm.FPVMState, flags ...StateValidationFlags) { - if !slices.Contains(flags, SkipPreimageKeyValidation) { - require.Equal(t, e.PreimageKey, actualState.GetPreimageKey(), fmt.Sprintf("Expect preimageKey = %v", e.PreimageKey)) - } +func (e *ExpectedState) Validate(t testing.TB, actualState mipsevm.FPVMState) { + require.Equal(t, e.PreimageKey, actualState.GetPreimageKey(), fmt.Sprintf("Expect preimageKey = %v", e.PreimageKey)) require.Equal(t, e.PreimageOffset, actualState.GetPreimageOffset(), fmt.Sprintf("Expect preimageOffset = %v", e.PreimageOffset)) require.Equal(t, e.PC, actualState.GetCpu().PC, fmt.Sprintf("Expect PC = 0x%x", e.PC)) require.Equal(t, e.NextPC, actualState.GetCpu().NextPC, fmt.Sprintf("Expect nextPC = 0x%x", e.NextPC)) @@ -172,11 +180,7 @@ func (e *ExpectedState) Validate(t testing.TB, actualState mipsevm.FPVMState, fl require.Equal(t, e.ExitCode, actualState.GetExitCode(), fmt.Sprintf("Expect exitCode = 0x%x", e.ExitCode)) require.Equal(t, e.Exited, actualState.GetExited(), fmt.Sprintf("Expect exited = %v", e.Exited)) require.Equal(t, e.Step, actualState.GetStep(), fmt.Sprintf("Expect step = %d", e.Step)) - if !slices.Contains(flags, SkipHintValidation) { - require.Equal(t, e.LastHint, actualState.GetLastHint(), fmt.Sprintf("Expect lastHint = %v", e.LastHint)) - } + require.Equal(t, e.LastHint, actualState.GetLastHint(), fmt.Sprintf("Expect lastHint = %v", e.LastHint)) require.Equal(t, e.Registers, *actualState.GetRegistersRef(), fmt.Sprintf("Expect registers = %v", e.Registers)) - if !slices.Contains(flags, SkipMemoryValidation) { - require.Equal(t, e.MemoryRoot, common.Hash(actualState.GetMemory().MerkleRoot()), fmt.Sprintf("Expect memory root = %v", e.MemoryRoot)) - } + require.Equal(t, e.MemoryRoot, common.Hash(actualState.GetMemory().MerkleRoot()), fmt.Sprintf("Expect memory root = %v", e.MemoryRoot)) } From 08a43698b2bfe4b9f0990fb39b6e50634362b475 Mon Sep 17 00:00:00 2001 From: mbaxter Date: Thu, 19 Sep 2024 14:15:48 -0400 Subject: [PATCH 206/264] cannon: Clean up program patching (#11944) * cannon: Cut todo, reorganize syscalls * cannon: Rename patchGo to patchGoGC, add comments, cut TODO * cannon: Only allow gc patching for single-threaded Cannon * cannon: Cut patch flag from load-elf command altogether --- Makefile | 2 +- cannon/cmd/load_elf.go | 62 +++++++++++++--------------- cannon/mipsevm/exec/mips_syscalls.go | 7 +--- cannon/mipsevm/program/patch.go | 7 ++-- cannon/mipsevm/testutil/elf.go | 6 +-- 5 files changed, 37 insertions(+), 47 deletions(-) diff --git a/Makefile b/Makefile index aa4590e079ab..41057910a489 100644 --- a/Makefile +++ b/Makefile @@ -148,7 +148,7 @@ cannon-prestate: op-program cannon ## Generates prestate using cannon and op-pro .PHONY: cannon-prestate cannon-prestate-mt: op-program cannon ## Generates prestate using cannon and op-program in the multithreaded cannon format - ./cannon/bin/cannon load-elf --type cannon-mt --patch stack --path op-program/bin/op-program-client.elf --out op-program/bin/prestate-mt.bin.gz --meta op-program/bin/meta-mt.json + ./cannon/bin/cannon load-elf --type cannon-mt --path op-program/bin/op-program-client.elf --out op-program/bin/prestate-mt.bin.gz --meta op-program/bin/meta-mt.json ./cannon/bin/cannon run --proof-at '=0' --stop-at '=1' --input op-program/bin/prestate-mt.bin.gz --meta op-program/bin/meta-mt.json --proof-fmt 'op-program/bin/%d-mt.json' --output "" mv op-program/bin/0-mt.json op-program/bin/prestate-proof-mt.json .PHONY: cannon-prestate diff --git a/cannon/cmd/load_elf.go b/cannon/cmd/load_elf.go index 8a1fbacbfcce..a6b9e0e5897a 100644 --- a/cannon/cmd/load_elf.go +++ b/cannon/cmd/load_elf.go @@ -4,15 +4,15 @@ import ( "debug/elf" "fmt" + "github.com/urfave/cli/v2" + "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/program" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" "github.com/ethereum-optimism/optimism/cannon/mipsevm/versions" "github.com/ethereum-optimism/optimism/cannon/serialize" "github.com/ethereum-optimism/optimism/op-service/ioutil" - "github.com/urfave/cli/v2" - - "github.com/ethereum-optimism/optimism/cannon/mipsevm/program" - "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" "github.com/ethereum-optimism/optimism/op-service/jsonutil" ) @@ -29,15 +29,9 @@ var ( TakesFile: true, Required: true, } - LoadELFPatchFlag = &cli.StringSliceFlag{ - Name: "patch", - Usage: "Type of patching to do", - Value: cli.NewStringSlice("go", "stack"), - Required: false, - } LoadELFOutFlag = &cli.PathFlag{ Name: "out", - Usage: "Output path to write JSON state to. State is dumped to stdout if set to -. Not written if empty.", + Usage: "Output path to write state to. State is dumped to stdout if set to '-'. Not written if empty. Use file extension '.bin', '.bin.gz', or '.json' for binary, compressed binary, or JSON formats.", Value: "state.json", Required: false, } @@ -67,14 +61,31 @@ func vmTypeFromString(ctx *cli.Context) (VMType, error) { } func LoadELF(ctx *cli.Context) error { + elfPath := ctx.Path(LoadELFPathFlag.Name) + elfProgram, err := elf.Open(elfPath) + if err != nil { + return fmt.Errorf("failed to open ELF file %q: %w", elfPath, err) + } + if elfProgram.Machine != elf.EM_MIPS { + return fmt.Errorf("ELF is not big-endian MIPS R3000, but got %q", elfProgram.Machine.String()) + } + var createInitialState func(f *elf.File) (mipsevm.FPVMState, error) + var patcher = program.PatchStack if vmType, err := vmTypeFromString(ctx); err != nil { return err } else if vmType == cannonVMType { createInitialState = func(f *elf.File) (mipsevm.FPVMState, error) { return program.LoadELF(f, singlethreaded.CreateInitialState) } + patcher = func(state mipsevm.FPVMState) error { + err := program.PatchGoGC(elfProgram, state) + if err != nil { + return err + } + return program.PatchStack(state) + } } else if vmType == mtVMType { createInitialState = func(f *elf.File) (mipsevm.FPVMState, error) { return program.LoadELF(f, multithreaded.CreateInitialState) @@ -82,30 +93,14 @@ func LoadELF(ctx *cli.Context) error { } else { return fmt.Errorf("invalid VM type: %q", vmType) } - elfPath := ctx.Path(LoadELFPathFlag.Name) - elfProgram, err := elf.Open(elfPath) - if err != nil { - return fmt.Errorf("failed to open ELF file %q: %w", elfPath, err) - } - if elfProgram.Machine != elf.EM_MIPS { - return fmt.Errorf("ELF is not big-endian MIPS R3000, but got %q", elfProgram.Machine.String()) - } + state, err := createInitialState(elfProgram) if err != nil { return fmt.Errorf("failed to load ELF data into VM state: %w", err) } - for _, typ := range ctx.StringSlice(LoadELFPatchFlag.Name) { - switch typ { - case "stack": - err = program.PatchStack(state) - case "go": - err = program.PatchGo(elfProgram, state) - default: - return fmt.Errorf("unrecognized form of patching: %q", typ) - } - if err != nil { - return fmt.Errorf("failed to apply patch %s: %w", typ, err) - } + err = patcher(state) + if err != nil { + return fmt.Errorf("failed to patch state: %w", err) } meta, err := program.MakeMetadata(elfProgram) if err != nil { @@ -125,13 +120,12 @@ func LoadELF(ctx *cli.Context) error { var LoadELFCommand = &cli.Command{ Name: "load-elf", - Usage: "Load ELF file into Cannon JSON state", - Description: "Load ELF file into Cannon JSON state, optionally patch out functions", + Usage: "Load ELF file into Cannon state", + Description: "Load ELF file into Cannon state", Action: LoadELF, Flags: []cli.Flag{ LoadELFVMTypeFlag, LoadELFPathFlag, - LoadELFPatchFlag, LoadELFOutFlag, LoadELFMetaFlag, }, diff --git a/cannon/mipsevm/exec/mips_syscalls.go b/cannon/mipsevm/exec/mips_syscalls.go index 71a14e4fe5e2..caf3b9bec630 100644 --- a/cannon/mipsevm/exec/mips_syscalls.go +++ b/cannon/mipsevm/exec/mips_syscalls.go @@ -59,12 +59,7 @@ const ( SysLlseek = 4140 SysMinCore = 4217 SysTgkill = 4266 -) - -// Profiling-related syscalls -// Should be able to ignore if we patch out prometheus calls and disable memprofiling -// TODO(cp-903) - Update patching for mt-cannon so that these can be ignored -const ( + // Profiling-related syscalls SysSetITimer = 4104 SysTimerCreate = 4257 SysTimerSetTime = 4258 diff --git a/cannon/mipsevm/program/patch.go b/cannon/mipsevm/program/patch.go index 0380d3bfcc87..e8e2e3ebc085 100644 --- a/cannon/mipsevm/program/patch.go +++ b/cannon/mipsevm/program/patch.go @@ -11,9 +11,9 @@ import ( "github.com/ethereum-optimism/optimism/cannon/mipsevm/memory" ) -// TODO(cp-903) Consider breaking up go patching into performance and threading-related patches so we can -// selectively apply the perf patching to MTCannon -func PatchGo(f *elf.File, st mipsevm.FPVMState) error { +// PatchGoGC patches out garbage-collection-related symbols to disable garbage collection +// and improves performance by patching out floating-point-related symbols +func PatchGoGC(f *elf.File, st mipsevm.FPVMState) error { symbols, err := f.Symbols() if err != nil { return fmt.Errorf("failed to read symbols data, cannot patch program: %w", err) @@ -53,6 +53,7 @@ func PatchGo(f *elf.File, st mipsevm.FPVMState) error { return nil } +// PatchStack sets up the program's initial stack frame and stack pointer func PatchStack(st mipsevm.FPVMState) error { // setup stack pointer sp := uint32(0x7f_ff_d0_00) diff --git a/cannon/mipsevm/testutil/elf.go b/cannon/mipsevm/testutil/elf.go index 683f98702653..b5b63cdeb1d3 100644 --- a/cannon/mipsevm/testutil/elf.go +++ b/cannon/mipsevm/testutil/elf.go @@ -9,7 +9,7 @@ import ( "github.com/ethereum-optimism/optimism/cannon/mipsevm/program" ) -func LoadELFProgram[T mipsevm.FPVMState](t require.TestingT, name string, initState program.CreateInitialFPVMState[T], doPatchGo bool) (T, *program.Metadata) { +func LoadELFProgram[T mipsevm.FPVMState](t require.TestingT, name string, initState program.CreateInitialFPVMState[T], doPatchGoGC bool) (T, *program.Metadata) { elfProgram, err := elf.Open(name) require.NoError(t, err, "open ELF file") meta, err := program.MakeMetadata(elfProgram) @@ -18,8 +18,8 @@ func LoadELFProgram[T mipsevm.FPVMState](t require.TestingT, name string, initSt state, err := program.LoadELF(elfProgram, initState) require.NoError(t, err, "load ELF into state") - if doPatchGo { - err = program.PatchGo(elfProgram, state) + if doPatchGoGC { + err = program.PatchGoGC(elfProgram, state) require.NoError(t, err, "apply Go runtime patches") } From 7105bad6736fcb9f45ac83d9ef45605adbf8fdfe Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Thu, 19 Sep 2024 13:51:55 -0600 Subject: [PATCH 207/264] feat(ci): check contract semver matches natspec (#11992) Adds a new check to CI that verifies that the semver string defined in the contract matches the string defined in natspec. --- .circleci/config.yml | 135 ++++++------------ packages/contracts-bedrock/justfile | 20 +++ .../scripts/checks/check-semver-diff.sh | 88 ++++++++++++ .../checks/check-semver-natspec-match.sh | 74 ++++++++++ .../scripts/checks/utils/semver-utils.sh | 24 ++++ packages/contracts-bedrock/semver-lock.json | 12 +- .../OptimismMintableERC20Factory.sol | 4 +- .../src/universal/OptimismMintableERC721.sol | 4 +- .../OptimismMintableERC721Factory.sol | 4 +- 9 files changed, 258 insertions(+), 107 deletions(-) create mode 100755 packages/contracts-bedrock/scripts/checks/check-semver-diff.sh create mode 100755 packages/contracts-bedrock/scripts/checks/check-semver-natspec-match.sh create mode 100755 packages/contracts-bedrock/scripts/checks/utils/semver-utils.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 9fbc00b4859f..7478b054ee20 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -133,6 +133,23 @@ commands: branch_pattern: develop mentions: "<< parameters.mentions >>" + run-contracts-check: + parameters: + command: + description: Just command that runs the check + type: string + steps: + - run: + name: <> + command: | + git reset --hard + just <> + git diff --quiet --exit-code + working_directory: packages/contracts-bedrock + when: always + environment: + FOUNDRY_PROFILE: ci + jobs: cannon-go-lint-and-test: docker: @@ -658,102 +675,30 @@ jobs: - setup_remote_docker: docker_layer_caching: true - run: - name: forge version + name: print forge version command: forge --version - - run: - # Semver lock must come second because one of the later steps may modify the cache & force a contracts rebuild. - name: semver lock - command: | - just semver-lock - git diff --exit-code semver-lock.json || echo "export SEMVER_LOCK_STATUS=1" >> "$BASH_ENV" - working_directory: packages/contracts-bedrock - - run: - name: check deploy configs - command: just validate-deploy-configs || echo "export DEPLOY_CONFIGS_STATUS=1" >> "$BASH_ENV" - working_directory: packages/contracts-bedrock - - run: - name: lint - command: | - just lint-check || echo "export LINT_STATUS=1" >> "$BASH_ENV" - working_directory: packages/contracts-bedrock - - run: - name: gas snapshot - command: | - just gas-snapshot-check || echo "export GAS_SNAPSHOT_STATUS=1" >> "$BASH_ENV" - environment: - FOUNDRY_PROFILE: ci - working_directory: packages/contracts-bedrock - no_output_timeout: 15m - - run: - name: invariant docs - command: | - just autogen-invariant-docs - git diff --exit-code ./invariant-docs/*.md || echo "export INVARIANT_DOCS_STATUS=1" >> "$BASH_ENV" - working_directory: packages/contracts-bedrock - - run: - name: snapshots - command: | - just snapshots-check-no-build || echo "export SNAPSHOTS_STATUS=1" >> "$BASH_ENV" - working_directory: packages/contracts-bedrock - - run: - name: kontrol deployment - command: | - just kontrol-deployment-check || echo "export KONTROL_DEPLOYMENT_STATUS=1" >> "$BASH_ENV" - working_directory: packages/contracts-bedrock - - run: - name: interfaces - command: | - just interfaces-check-no-build || echo "export INTERFACES_STATUS=1" >> "$BASH_ENV" - working_directory: packages/contracts-bedrock - - run: - name: size check - command: | - forge build --sizes --skip "/**/test/**" --skip "/**/scripts/**" || echo "export SIZE_CHECK=1" >> "$BASH_ENV" - environment: - FOUNDRY_PROFILE: ci - working_directory: packages/contracts-bedrock - - run: - name: check statuses - command: | - if [[ "$LINT_STATUS" -ne 0 ]]; then - echo "Linting failed, see job output for details." - FAILED=1 - fi - if [[ "$GAS_SNAPSHOT_STATUS" -ne 0 ]]; then - echo "Gas snapshot failed, see job output for details." - FAILED=1 - fi - if [[ "$SEMVER_LOCK_STATUS" -ne 0 ]]; then - echo "Semver lock failed, see job output for details." - FAILED=1 - fi - if [[ "$INVARIANT_DOCS_STATUS" -ne 0 ]]; then - echo "Invariant docs failed, see job output for details." - FAILED=1 - fi - if [[ "$DEPLOY_CONFIGS_STATUS" -ne 0 ]]; then - echo "Deploy config check failed, see job output for details." - FAILED=1 - fi - if [[ "$SNAPSHOTS_STATUS" -ne 0 ]]; then - echo "Snapshots check failed, see job output for details." - FAILED=1 - fi - if [[ "$KONTROL_DEPLOYMENT_STATUS" -ne 0 ]]; then - echo "Kontrol deployment check failed, see job output for details." - FAILED=1 - fi - if [[ "$INTERFACES_STATUS" -ne 0 ]]; then - echo "Interface check failed, see job output for details." - FAILED=1 - fi - if [[ "$SIZE_CHECK" -ne 0 ]]; then - echo "Contract(s) exceed size limit, see job output for details." - FAILED=1 - fi - if [[ "$FAILED" -ne 0 ]]; then - exit 1 - fi + - run-contracts-check: + command: semver-lock + - run-contracts-check: + command: semver-diff-check-no-build + - run-contracts-check: + command: semver-natspec-check-no-build + - run-contracts-check: + command: validate-deploy-configs + - run-contracts-check: + command: lint + - run-contracts-check: + command: gas-snapshot-check + - run-contracts-check: + command: autogen-invariant-docs + - run-contracts-check: + command: snapshots-check-no-build + - run-contracts-check: + command: kontrol-deployment-check + - run-contracts-check: + command: interfaces-check-no-build + - run-contracts-check: + command: size-check contracts-bedrock-validate-spacers: docker: diff --git a/packages/contracts-bedrock/justfile b/packages/contracts-bedrock/justfile index 7506681774b2..a1f0a0836d14 100644 --- a/packages/contracts-bedrock/justfile +++ b/packages/contracts-bedrock/justfile @@ -96,6 +96,26 @@ interfaces-check-no-build: # artifacts can cause the script to detect issues incorrectly.2 interfaces-check: clean build interfaces-check-no-build +# Checks that the size of the contracts is within the limit. +size-check: + forge build --sizes --skip "/**/test/**" --skip "/**/scripts/**" + +# Checks that any contracts with a modified semver lock also have a modified semver version. +# Does not build contracts. +semver-diff-check-no-build: + ./scripts/checks/check-semver-diff.sh + +# Checks that any contracts with a modified semver lock also have a modified semver version. +semver-diff-check: build semver-diff-check-no-build + +# Checks that semver natspec is equal to the actual semver version. +# Does not build contracts. +semver-natspec-check-no-build: + ./scripts/checks/check-semver-natspec-match.sh + +# Checks that semver natspec is equal to the actual semver version. +semver-natspec-check: build semver-natspec-check-no-build + semver-lock: forge script scripts/autogen/SemverLock.s.sol diff --git a/packages/contracts-bedrock/scripts/checks/check-semver-diff.sh b/packages/contracts-bedrock/scripts/checks/check-semver-diff.sh new file mode 100755 index 000000000000..15a3ebb50da2 --- /dev/null +++ b/packages/contracts-bedrock/scripts/checks/check-semver-diff.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Grab the directory of the contracts-bedrock package. +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +# Load semver-utils. +# shellcheck source=/dev/null +source "$SCRIPT_DIR/utils/semver-utils.sh" + +# Path to semver-lock.json. +SEMVER_LOCK="semver-lock.json" + +# Create a temporary directory. +temp_dir=$(mktemp -d) +trap 'rm -rf "$temp_dir"' EXIT + +# Exit early if semver-lock.json has not changed. +if ! git diff origin/develop...HEAD --name-only | grep -q "$SEMVER_LOCK"; then + echo "No changes detected in semver-lock.json" + exit 0 +fi + +# Get the upstream semver-lock.json. +git show origin/develop:packages/contracts-bedrock/semver-lock.json > "$temp_dir/upstream_semver_lock.json" + +# Copy the local semver-lock.json. +cp "$SEMVER_LOCK" "$temp_dir/local_semver_lock.json" + +# Get the changed contracts. +changed_contracts=$(jq -r ' + def changes: + to_entries as $local + | input as $upstream + | $local | map( + select( + .key as $key + | .value != $upstream[$key] + ) + ) | map(.key); + changes[] +' "$temp_dir/local_semver_lock.json" "$temp_dir/upstream_semver_lock.json") + +# Flag to track if any errors are detected. +has_errors=false + +# Check each changed contract for a semver version change. +for contract in $changed_contracts; do + # Check if the contract file exists. + if [ ! -f "$contract" ]; then + echo "❌ Error: Contract file $contract not found" + has_errors=true + continue + fi + + # Extract the old and new source files. + old_source_file="$temp_dir/old_${contract##*/}" + new_source_file="$temp_dir/new_${contract##*/}" + git show origin/develop:packages/contracts-bedrock/"$contract" > "$old_source_file" 2>/dev/null || true + cp "$contract" "$new_source_file" + + # Extract the old and new versions. + old_version=$(extract_version "$old_source_file" 2>/dev/null || echo "N/A") + new_version=$(extract_version "$new_source_file" 2>/dev/null || echo "N/A") + + # Check if the versions were extracted successfully. + if [ "$old_version" = "N/A" ] || [ "$new_version" = "N/A" ]; then + echo "❌ Error: unable to extract version for $contract" + echo " this is probably a bug in check-semver-diff.sh" + echo " please report or fix the issue if possible" + has_errors=true + fi + + # Check if the version changed. + if [ "$old_version" = "$new_version" ]; then + echo "❌ Error: src/$contract has changes in semver-lock.json but no version change" + echo " Old version: $old_version" + echo " New version: $new_version" + has_errors=true + else + echo "✅ $contract: version changed from $old_version to $new_version" + fi +done + +# Exit with error if any issues were found. +if [ "$has_errors" = true ]; then + exit 1 +fi diff --git a/packages/contracts-bedrock/scripts/checks/check-semver-natspec-match.sh b/packages/contracts-bedrock/scripts/checks/check-semver-natspec-match.sh new file mode 100755 index 000000000000..de4de3f8497a --- /dev/null +++ b/packages/contracts-bedrock/scripts/checks/check-semver-natspec-match.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Grab the directory of the contracts-bedrock package +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +CONTRACTS_BASE=$(dirname "$(dirname "$SCRIPT_DIR")") +ARTIFACTS_DIR="$CONTRACTS_BASE/forge-artifacts" +CONTRACTS_DIR="$CONTRACTS_BASE/src" + +# Load semver-utils +# shellcheck source=/dev/null +source "$SCRIPT_DIR/utils/semver-utils.sh" + +# Flag to track if any errors are detected +has_errors=false + +# Iterate through each artifact file +for artifact_file in "$ARTIFACTS_DIR"/**/*.json; do + # Get the contract name and find the corresponding source file + contract_name=$(basename "$artifact_file" .json) + contract_file=$(find "$CONTRACTS_DIR" -name "$contract_name.sol") + + # Try to extract version as a constant + raw_metadata=$(jq -r '.rawMetadata' "$artifact_file") + artifact_version=$(echo "$raw_metadata" | jq -r '.output.devdoc.stateVariables.version."custom:semver"') + + is_constant=true + if [ "$artifact_version" = "null" ]; then + # If not found as a constant, try to extract as a function + artifact_version=$(echo "$raw_metadata" | jq -r '.output.devdoc.methods."version()"."custom:semver"') + is_constant=false + fi + + # If @custom:semver is not found in either location, skip this file + if [ "$artifact_version" = "null" ]; then + continue + fi + + # If source file is not found, report an error + if [ -z "$contract_file" ]; then + echo "❌ $contract_name: Source file not found" + continue + fi + + # Extract version from source based on whether it's a constant or function + if [ "$is_constant" = true ]; then + source_version=$(extract_constant_version "$contract_file") + else + source_version=$(extract_function_version "$contract_file") + fi + + # If source version is not found, report an error + if [ "$source_version" = "" ]; then + echo "❌ Error: failed to find version string for $contract_name" + echo " this is probably a bug in check-contract-semver.sh" + echo " please report or fix the issue if possible" + has_errors=true + fi + + # Compare versions + if [ "$source_version" != "$artifact_version" ]; then + echo "❌ Error: $contract_name has different semver in code and devdoc" + echo " Code: $source_version" + echo " Devdoc: $artifact_version" + has_errors=true + else + echo "✅ $contract_name: code: $source_version, devdoc: $artifact_version" + fi +done + +# If any errors were detected, exit with a non-zero status +if [ "$has_errors" = true ]; then + exit 1 +fi diff --git a/packages/contracts-bedrock/scripts/checks/utils/semver-utils.sh b/packages/contracts-bedrock/scripts/checks/utils/semver-utils.sh new file mode 100755 index 000000000000..5f8d80156a45 --- /dev/null +++ b/packages/contracts-bedrock/scripts/checks/utils/semver-utils.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Function to extract version from contract source as a constant +extract_constant_version() { + local file=$1 + grep -o 'string.*constant.*version.*=.*"[^"]*"' "$file" | sed 's/.*"\([^"]*\)".*/\1/' || echo "" +} + +# Function to extract version from contract source as a function +extract_function_version() { + local file=$1 + sed -n '/function.*version()/,/return/p' "$file" | grep -o '"[^"]*"' | sed 's/"//g' || echo "" +} + +# Function to extract version from either constant or function +extract_version() { + local file=$1 + version=$(extract_constant_version "$file") + if [ -z "$version" ]; then + version=$(extract_function_version "$file") + fi + echo "$version" +} diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 41e5f39a1b03..7aa4b286383c 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -212,16 +212,16 @@ "sourceCodeHash": "0x740b4043436d1b314ee3ba145acfcde60b6abd8416ea594f2b8e890b5d0bce6b" }, "src/universal/OptimismMintableERC20Factory.sol": { - "initCodeHash": "0x3ebd2297c0af2856a432daf29d186d0751f7edb1c777abbe136953038cf5d1ba", - "sourceCodeHash": "0xf8425f65eb5520d55710907d67a9d6fa277263285e1b79ba299815d1c76919a3" + "initCodeHash": "0x9cd4102d3ca811d5dc67ae99ce7de95812264575a789f96a6057600e55dcab64", + "sourceCodeHash": "0xc70c8c11d6e754eabe746bbee47a5e1051f71f7a83913f62ebcce8db989a1357" }, "src/universal/OptimismMintableERC721.sol": { - "initCodeHash": "0x5a995fc043f8268a6d5c6284ad85b0de21328cd47277114aeba2c03484deaf91", - "sourceCodeHash": "0xbf186922941d49e75d25bcac2a480c3e3ffed9bdd79a3fdca5a6c79bcbe94735" + "initCodeHash": "0xec037be7fc28e072944b0a9e55d4278b92d6c68ccb41049ab52eafca59c6e023", + "sourceCodeHash": "0x5ea7c1b0cef5609f25c4193f5795fc9ce8f3ae08dbbf2945afe38e5af58f32c3" }, "src/universal/OptimismMintableERC721Factory.sol": { - "initCodeHash": "0x9c6181eff40822a78562a30eaefb338c0841284e3b1036371348d185ec5e285f", - "sourceCodeHash": "0x8be6e661af4b8079567fb2cd368e0f6bf9c11185472c5a75bec1172820d553e0" + "initCodeHash": "0x1e247d46b5ac3cc8ac6b51193917cd5b88ff00fbea7bf768c65fa35a115f8607", + "sourceCodeHash": "0x1c4bc4727f08d80e8364561b49397ee57bb485072cb004b7a430559cbfa019a6" }, "src/universal/StorageSetter.sol": { "initCodeHash": "0x00b8b883597e67e5c3548e7ba4139ed720893c0acb217dd170bec520cefdfab5", diff --git a/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol b/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol index 6ae271603312..e179c6408dad 100644 --- a/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol +++ b/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol @@ -48,8 +48,8 @@ contract OptimismMintableERC20Factory is ISemver, Initializable, IOptimismERC20F /// the OptimismMintableERC20 token contract since this contract /// is responsible for deploying OptimismMintableERC20 contracts. /// @notice Semantic version. - /// @custom:semver 1.10.1-beta.1 - string public constant version = "1.10.1-beta.2"; + /// @custom:semver 1.10.1-beta.3 + string public constant version = "1.10.1-beta.3"; /// @notice Constructs the OptimismMintableERC20Factory contract. constructor() { diff --git a/packages/contracts-bedrock/src/universal/OptimismMintableERC721.sol b/packages/contracts-bedrock/src/universal/OptimismMintableERC721.sol index 63e8f72460f0..955a34072205 100644 --- a/packages/contracts-bedrock/src/universal/OptimismMintableERC721.sol +++ b/packages/contracts-bedrock/src/universal/OptimismMintableERC721.sol @@ -32,8 +32,8 @@ contract OptimismMintableERC721 is ERC721Enumerable, IOptimismMintableERC721, IS } /// @notice Semantic version. - /// @custom:semver 1.3.1-beta.1 - string public constant version = "1.3.1-beta.1"; + /// @custom:semver 1.3.1-beta.2 + string public constant version = "1.3.1-beta.2"; /// @param _bridge Address of the bridge on this network. /// @param _remoteChainId Chain ID where the remote token is deployed. diff --git a/packages/contracts-bedrock/src/universal/OptimismMintableERC721Factory.sol b/packages/contracts-bedrock/src/universal/OptimismMintableERC721Factory.sol index bb84504868f3..e9bc81524f86 100644 --- a/packages/contracts-bedrock/src/universal/OptimismMintableERC721Factory.sol +++ b/packages/contracts-bedrock/src/universal/OptimismMintableERC721Factory.sol @@ -23,8 +23,8 @@ contract OptimismMintableERC721Factory is ISemver { event OptimismMintableERC721Created(address indexed localToken, address indexed remoteToken, address deployer); /// @notice Semantic version. - /// @custom:semver 1.4.1-beta.1 - string public constant version = "1.4.1-beta.1"; + /// @custom:semver 1.4.1-beta.2 + string public constant version = "1.4.1-beta.2"; /// @notice The semver MUST be bumped any time that there is a change in /// the OptimismMintableERC721 token contract since this contract From a1f912a1879b313ff531b5de0bc8c91670e8e924 Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Thu, 19 Sep 2024 14:04:20 -0600 Subject: [PATCH 208/264] maint(ct): link to external mermaid diagrams in specs (#12012) Updates the contracts README to use the mermaid diagrams in specs to avoid duplicated documentation. --- packages/contracts-bedrock/README.md | 213 +-------------------------- 1 file changed, 1 insertion(+), 212 deletions(-) diff --git a/packages/contracts-bedrock/README.md b/packages/contracts-bedrock/README.md index caef04b163bb..cc687ce6ae97 100644 --- a/packages/contracts-bedrock/README.md +++ b/packages/contracts-bedrock/README.md @@ -9,11 +9,6 @@ High-level information about these contracts can be found within this README and ## Table of Contents - [Architecture Overview](#architecture-overview) - - [Core L1 Smart Contracts](#core-l1-smart-contracts) - - [Notes for Core L1 Smart Contracts](#notes-for-core-l1-smart-contracts) - - [Core L2 Smart Contracts](#core-l2-smart-contracts) - - [Notes for Core L2 Smart Contracts](#notes-for-core-l2-smart-contracts) - - [Smart Contract Proxies](#smart-contract-proxies) - [External Usage](#external-usage) - [Using OP Stack Contracts in Solidity](#using-op-stack-contracts-in-solidity) - [Using OP Stack Contracts in JavaScript](#using-op-stack-contracts-in-javascript) @@ -36,213 +31,7 @@ High-level information about these contracts can be found within this README and ## Architecture Overview -> **NOTE**: Smart contract names in the architecture diagrams below are links to source code. Click them! - -### Core L1 Smart Contracts - -Below you'll find an architecture diagram describing the core L1 smart contracts for the OP Stack. -Smart contracts that are considered "peripheral" and not core to the operation of the OP Stack system are described separately. - -```mermaid -graph LR - subgraph "External Contracts" - ExternalERC20(External ERC20 Contracts) - ExternalERC721(External ERC721 Contracts) - end - - subgraph "L1 Smart Contracts" - BatchDataEOA(Batch Inbox Address) - L1StandardBridge(L1StandardBridge) - L1ERC721Bridge(L1ERC721Bridge) - L1CrossDomainMessenger(L1CrossDomainMessenger) - OptimismPortal(OptimismPortal) - SuperchainConfig(SuperchainConfig) - SystemConfig(SystemConfig) - DisputeGameFactory(DisputeGameFactory) - FaultDisputeGame(FaultDisputeGame) - AnchorStateRegistry(AnchorStateRegistry) - DelayedWETH(DelayedWETH) - end - - subgraph "User Interactions (Permissionless)" - Users(Users) - Challengers(Challengers) - end - - subgraph "System Interactions" - Guardian(Guardian) - Batcher(Batcher) - end - - subgraph "Layer 2 Interactions" - L2Nodes(Layer 2 Nodes) - end - - L2Nodes -.->|fetch transaction batches| BatchDataEOA - L2Nodes -.->|fetch deposit events| OptimismPortal - - Batcher -->|publish transaction batches| BatchDataEOA - - ExternalERC20 <-->|mint/burn/transfer tokens| L1StandardBridge - ExternalERC721 <-->|mint/burn/transfer tokens| L1ERC721Bridge - - L1StandardBridge <-->|send/receive messages| L1CrossDomainMessenger - L1StandardBridge -.->|query pause state| SuperchainConfig - - L1ERC721Bridge <-->|send/receive messages| L1CrossDomainMessenger - L1ERC721Bridge -.->|query pause state| SuperchainConfig - - L1CrossDomainMessenger <-->|send/receive messages| OptimismPortal - L1CrossDomainMessenger -.->|query pause state| SuperchainConfig - - OptimismPortal -.->|query pause state| SuperchainConfig - OptimismPortal -.->|query config| SystemConfig - OptimismPortal -.->|query state proposals| DisputeGameFactory - - DisputeGameFactory -->|generate instances| FaultDisputeGame - - FaultDisputeGame -->|store bonds| DelayedWETH - FaultDisputeGame -->|query/update anchor states| AnchorStateRegistry - - Users <-->|deposit/withdraw ETH/ERC20s| L1StandardBridge - Users <-->|deposit/withdraw ERC721s| L1ERC721Bridge - Users -->|prove/execute withdrawals| OptimismPortal - - Challengers -->|propose output roots| DisputeGameFactory - Challengers -->|verify/challenge/defend proposals| FaultDisputeGame - - Guardian -->|pause/unpause| SuperchainConfig - Guardian -->|safety net actions| OptimismPortal - Guardian -->|safety net actions| DisputeGameFactory - Guardian -->|safety net actions| DelayedWETH - - classDef extContracts stroke:#ff9,stroke-width:2px; - classDef l1Contracts stroke:#bbf,stroke-width:2px; - classDef l1EOA stroke:#bbb,stroke-width:2px; - classDef userInt stroke:#f9a,stroke-width:2px; - classDef systemUser stroke:#f9a,stroke-width:2px; - classDef l2Nodes stroke:#333,stroke-width:2px - class ExternalERC20,ExternalERC721 extContracts; - class L1StandardBridge,L1ERC721Bridge,L1CrossDomainMessenger,OptimismPortal,SuperchainConfig,SystemConfig,DisputeGameFactory,FaultDisputeGame,DelayedWETH,AnchorStateRegistry l1Contracts; - class BatchDataEOA l1EOA; - class Users,Challengers userInt; - class Batcher,Guardian systemUser; - class L2Nodes l2Nodes; -``` - -#### Notes for Core L1 Smart Contracts - -- The `Batch Data Address` described above (**highlighted in GREY**) is *not* a smart contract and is instead simply an arbitrarily chosen account that is assumed to have no known private key. This account is typically chosen as the account `0xFF0000....` where `` is chain ID of the Layer 2 network for which the data is being posted. For instance, for OP Mainnet, this account is chosen as `0xFF00000000000000000000000000000000000010`. However, this is not a strict requirement and some OP Stack chains may not follow this convention. -- Smart contracts that sit behind `Proxy` contracts are **highlighted in BLUE**. Refer to the [Smart Contract Proxies](#smart-contract-proxies) section below to understand how these proxies are designed. - - The `L1CrossDomainMessenger` contract sits behind the [`ResolvedDelegateProxy`](https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/legacy/ResolvedDelegateProxy.sol) contract, a legacy proxy contract type used within older versions of the OP Stack. This proxy type is used exclusively for the `L1CrossDomainMessenger` to maintain backwards compatibility. - - The `L1StandardBridge` contract sits behind the [`L1ChugSplashProxy`](https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol) contract, a legacy proxy contract type used within older versions of the OP Stack. This proxy type is used exclusively for the `L1StandardBridge` contract to maintain backwards compatibility. - -### Core L2 Smart Contracts - -Here you'll find an architecture diagram describing the core OP Stack smart contracts that exist natively on the L2 chain itself. - -```mermaid -graph LR - subgraph "Layer 1 (Ethereum)" - L1SmartContracts(L1 Smart Contracts) - end - - subgraph "L2 Client" - L2Node(L2 Node) - end - - subgraph "L2 System Contracts" - L1Block(L1Block) - GasPriceOracle(GasPriceOracle) - L1FeeVault(L1FeeVault) - BaseFeeVault(BaseFeeVault) - SequencerFeeVault(SequencerFeeVault) - end - - subgraph "L2 Bridge Contracts" - L2CrossDomainMessenger(L2CrossDomainMessenger) - L2ToL1MessagePasser(L2ToL1MessagePasser) - L2StandardBridge(L2StandardBridge) - L2ERC721Bridge(L2ERC721Bridge) - end - - subgraph "Transactions" - DepositTransaction(Deposit Transaction) - UserTransaction(User Transaction) - end - - subgraph "External Contracts" - ExternalERC20(External ERC20 Contracts) - ExternalERC721(External ERC721 Contracts) - end - - subgraph "Remaining L2 Universe" - OtherContracts(Any Contracts and Addresses) - end - - L2Node -.->|derives chain from| L1SmartContracts - L2Node -->|updates| L1Block - L2Node -->|distributes fees to| L1FeeVault - L2Node -->|distributes fees to| BaseFeeVault - L2Node -->|distributes fees to| SequencerFeeVault - L2Node -->|derives from deposits| DepositTransaction - L2Node -->|derives from chain data| UserTransaction - - UserTransaction -->|can trigger| OtherContracts - DepositTransaction -->|maybe triggers| L2CrossDomainMessenger - DepositTransaction -->|can trigger| OtherContracts - - ExternalERC20 <-->|mint/burn/transfer| L2StandardBridge - ExternalERC721 <-->|mint/burn/transfer| L2ERC721Bridge - - L2StandardBridge <-->|sends/receives messages| L2CrossDomainMessenger - L2ERC721Bridge <-->|sends/receives messages| L2CrossDomainMessenger - GasPriceOracle -.->|queries| L1Block - L2CrossDomainMessenger -->|sends messages| L2ToL1MessagePasser - - classDef extContracts stroke:#ff9,stroke-width:2px; - classDef l2Contracts stroke:#bbf,stroke-width:2px; - classDef transactions stroke:#fba,stroke-width:2px; - classDef l2Node stroke:#f9a,stroke-width:2px; - - class ExternalERC20,ExternalERC721 extContracts; - class L2CrossDomainMessenger,L2ToL1MessagePasser,L2StandardBridge,L2ERC721Bridge l2Contracts; - class L1Block,L1FeeVault,BaseFeeVault,SequencerFeeVault,GasPriceOracle l2Contracts; - class UserTransaction,DepositTransaction transactions; - class L2Node l2Node; -``` - -#### Notes for Core L2 Smart Contracts - -- Contracts highlighted as "L2 System Contracts" are updated or mutated automatically as part of the chain derivation process. Users typically do not mutate these contracts directly, except in the case of the `FeeVault` contracts where any user may trigger a withdrawal of collected fees to the pre-determined withdrawal address. -- Smart contracts that sit behind `Proxy` contracts are **highlighted in BLUE**. Refer to the [Smart Contract Proxies](#smart-contract-proxies) section below to understand how these proxies are designed. -- User interactions for the "L2 Bridge Contracts" have been omitted from this diagram but largely follow the same user interactions described in the architecture diagram for the [Core L1 Smart Contracts](#core-l1-smart-contracts). - -### Smart Contract Proxies - -Most L1 and L2 smart contracts for OP Stack chains today sit behind `Proxy` contracts that themselves are managed by a `ProxyAdmin` contract. -The `ProxyAdmin` contract is controlled by some `owner` address that can be any EOA or smart contract. -Below you'll find a diagram that explains the behavior of the typical proxy contract. - -```mermaid -graph LR - ProxyAdminOwner(Proxy Admin Owner) - ProxyAdmin(ProxyAdmin) - - subgraph "Logical Smart Contract" - Proxy(Proxy) - Implementation(Implementation) - end - - ProxyAdminOwner -->|manages| ProxyAdmin - ProxyAdmin -->|upgrades| Proxy - Proxy -->|delegatecall| Implementation - - classDef l1Contracts stroke:#bbf,stroke-width:2px; - classDef systemUser stroke:#f9a,stroke-width:2px; - class Proxy l1Contracts; - class ProxyAdminOwner systemUser; -``` +Refer to the [Optimism Overview page within the OP Stack Specs](https://specs.optimism.io/protocol/overview.html#architecture-overview) for a detailed architecture overview of core L1 contracts, core L2 contracts, and smart contract proxies. ## External Usage From 54ae1e4109d03c8e566f9573b75bbb6552589074 Mon Sep 17 00:00:00 2001 From: Inphi Date: Thu, 19 Sep 2024 17:42:08 -0400 Subject: [PATCH 209/264] op-program: Reproducible MT-Cannon prestate (#12011) * op-program: Reproducible MT-Cannon prestate * fix mt-cannon proof gen --- op-program/Dockerfile.repro | 6 ++++++ op-program/Makefile | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/op-program/Dockerfile.repro b/op-program/Dockerfile.repro index 7d9dfc807240..12e52ec5b5a5 100644 --- a/op-program/Dockerfile.repro +++ b/op-program/Dockerfile.repro @@ -36,11 +36,15 @@ RUN --mount=type=cache,target=/root/.cache/go-build cd op-program && make op-pro # Run the op-program-client.elf binary directly through cannon's load-elf subcommand. RUN /app/cannon/bin/cannon load-elf --path /app/op-program/bin/op-program-client.elf --out /app/op-program/bin/prestate.json --meta "" +RUN /app/cannon/bin/cannon load-elf --type cannon-mt --path /app/op-program/bin/op-program-client.elf --out /app/op-program/bin/prestate-mt.bin.gz --meta "" # Generate the prestate proof containing the absolute pre-state hash. RUN /app/cannon/bin/cannon run --proof-at '=0' --stop-at '=1' --input /app/op-program/bin/prestate.json --meta "" --proof-fmt '/app/op-program/bin/%d.json' --output "" RUN mv /app/op-program/bin/0.json /app/op-program/bin/prestate-proof.json +RUN /app/cannon/bin/cannon run --proof-at '=0' --stop-at '=1' --input /app/op-program/bin/prestate-mt.bin.gz --meta "" --proof-fmt '/app/op-program/bin/%d-mt.json' --output "" +RUN mv /app/op-program/bin/0-mt.json /app/op-program/bin/prestate-proof-mt.json + # Exports files to the specified output location. # Writing files to host requires buildkit to be enabled. # e.g. `BUILDKIT=1 docker build ...` @@ -49,3 +53,5 @@ COPY --from=builder /app/op-program/bin/op-program . COPY --from=builder /app/op-program/bin/op-program-client.elf . COPY --from=builder /app/op-program/bin/prestate.json . COPY --from=builder /app/op-program/bin/prestate-proof.json . +COPY --from=builder /app/op-program/bin/prestate-mt.bin.gz . +COPY --from=builder /app/op-program/bin/prestate-proof-mt.json . diff --git a/op-program/Makefile b/op-program/Makefile index 29e439a28f44..d8c134d9656a 100644 --- a/op-program/Makefile +++ b/op-program/Makefile @@ -36,8 +36,10 @@ op-program-client-riscv: reproducible-prestate: @docker build --output ./bin/ --progress plain -f Dockerfile.repro ../ - @echo "Absolute prestate hash:" + @echo "Cannon Absolute prestate hash: " @cat ./bin/prestate-proof.json | jq -r .pre + @echo "MT-Cannon Absolute prestate hash: " + @cat ./bin/prestate-proof-mt.json | jq -r .pre .PHONY: reproducible-prestate clean: From cea1f940897bb2e5e02e22847e3ec98ec504713c Mon Sep 17 00:00:00 2001 From: mbaxter Date: Thu, 19 Sep 2024 18:12:27 -0400 Subject: [PATCH 210/264] cannon: Fix makefile phony target (#12014) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 41057910a489..6b1abdd37f00 100644 --- a/Makefile +++ b/Makefile @@ -151,7 +151,7 @@ cannon-prestate-mt: op-program cannon ## Generates prestate using cannon and op- ./cannon/bin/cannon load-elf --type cannon-mt --path op-program/bin/op-program-client.elf --out op-program/bin/prestate-mt.bin.gz --meta op-program/bin/meta-mt.json ./cannon/bin/cannon run --proof-at '=0' --stop-at '=1' --input op-program/bin/prestate-mt.bin.gz --meta op-program/bin/meta-mt.json --proof-fmt 'op-program/bin/%d-mt.json' --output "" mv op-program/bin/0-mt.json op-program/bin/prestate-proof-mt.json -.PHONY: cannon-prestate +.PHONY: cannon-prestate-mt mod-tidy: ## Cleans up unused dependencies in Go modules # Below GOPRIVATE line allows mod-tidy to be run immediately after From 45a266e746c5a9977424ef9a9fa8869f7ceb75da Mon Sep 17 00:00:00 2001 From: smartcontracts Date: Thu, 19 Sep 2024 17:11:51 -0600 Subject: [PATCH 211/264] maint(ci): remove autogenerated invariant docs (#11988) Removes autogenerated invariant docs from the contracts package. These autogenerated docs create confusion about where invariants should be defined (the answer is in the specs) and no one actually looks at them anyway. Just adds an additional step into CI for minimal benefit. --- .circleci/config.yml | 2 - packages/contracts-bedrock/CONTRIBUTING.md | 1 - .../invariant-docs/AddressAliasHelper.md | 6 - .../invariant-docs/Burn.Eth.md | 6 - .../invariant-docs/Burn.Gas.md | 6 - .../invariant-docs/CrossDomainMessenger.md | 15 - .../invariant-docs/ETHLiquidity.md | 5 - .../invariant-docs/Encoding.md | 11 - .../invariant-docs/FaultDisputeGame.md | 6 - .../invariant-docs/Hashing.md | 16 -- .../invariant-docs/InvariantTest.sol.md | 2 - .../invariant-docs/L2OutputOracle.md | 6 - .../invariant-docs/OptimismPortal.md | 21 -- .../invariant-docs/OptimismPortal2.md | 21 -- .../invariant-docs/OptimismSuperchainERC20.md | 16 -- .../invariant-docs/README.md | 53 ---- .../invariant-docs/ResourceMetering.md | 36 --- .../invariant-docs/SafeCall.md | 11 - .../invariant-docs/SuperchainWETH.md | 5 - .../invariant-docs/SystemConfig.md | 6 - packages/contracts-bedrock/justfile | 5 +- .../autogen/generate-invariant-docs/main.go | 262 ------------------ 22 files changed, 1 insertion(+), 517 deletions(-) delete mode 100644 packages/contracts-bedrock/invariant-docs/AddressAliasHelper.md delete mode 100644 packages/contracts-bedrock/invariant-docs/Burn.Eth.md delete mode 100644 packages/contracts-bedrock/invariant-docs/Burn.Gas.md delete mode 100644 packages/contracts-bedrock/invariant-docs/CrossDomainMessenger.md delete mode 100644 packages/contracts-bedrock/invariant-docs/ETHLiquidity.md delete mode 100644 packages/contracts-bedrock/invariant-docs/Encoding.md delete mode 100644 packages/contracts-bedrock/invariant-docs/FaultDisputeGame.md delete mode 100644 packages/contracts-bedrock/invariant-docs/Hashing.md delete mode 100644 packages/contracts-bedrock/invariant-docs/InvariantTest.sol.md delete mode 100644 packages/contracts-bedrock/invariant-docs/L2OutputOracle.md delete mode 100644 packages/contracts-bedrock/invariant-docs/OptimismPortal.md delete mode 100644 packages/contracts-bedrock/invariant-docs/OptimismPortal2.md delete mode 100644 packages/contracts-bedrock/invariant-docs/OptimismSuperchainERC20.md delete mode 100644 packages/contracts-bedrock/invariant-docs/README.md delete mode 100644 packages/contracts-bedrock/invariant-docs/ResourceMetering.md delete mode 100644 packages/contracts-bedrock/invariant-docs/SafeCall.md delete mode 100644 packages/contracts-bedrock/invariant-docs/SuperchainWETH.md delete mode 100644 packages/contracts-bedrock/invariant-docs/SystemConfig.md delete mode 100644 packages/contracts-bedrock/scripts/autogen/generate-invariant-docs/main.go diff --git a/.circleci/config.yml b/.circleci/config.yml index 7478b054ee20..97efd49e8697 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -689,8 +689,6 @@ jobs: command: lint - run-contracts-check: command: gas-snapshot-check - - run-contracts-check: - command: autogen-invariant-docs - run-contracts-check: command: snapshots-check-no-build - run-contracts-check: diff --git a/packages/contracts-bedrock/CONTRIBUTING.md b/packages/contracts-bedrock/CONTRIBUTING.md index 02a5bc8dad4c..a249ae5bedca 100644 --- a/packages/contracts-bedrock/CONTRIBUTING.md +++ b/packages/contracts-bedrock/CONTRIBUTING.md @@ -68,7 +68,6 @@ You can run `just -l` to list them all, some of the key ones are: 1 `just gas-snapshot` Generates the gas snapshot for the smart contracts. 1. `just semver-lock` Generates the semver lockfile. 1. `just snapshots` Generates the storage and ABI snapshots. -1. `just autogen-invariant-docs` Generates the invariant test documentation. 1. `just clean` Removes all build artifacts for `forge` and `go` compilations. 1. `just validate-spacers` Validates the positions of the storage slot spacers. 1. `just validate-deploy-configs` Validates the deployment configurations in `deploy-config` diff --git a/packages/contracts-bedrock/invariant-docs/AddressAliasHelper.md b/packages/contracts-bedrock/invariant-docs/AddressAliasHelper.md deleted file mode 100644 index f7787a436122..000000000000 --- a/packages/contracts-bedrock/invariant-docs/AddressAliasHelper.md +++ /dev/null @@ -1,6 +0,0 @@ -# `AddressAliasHelper` Invariants - -## Address aliases are always able to be undone. -**Test:** [`AddressAliasHelper.t.sol#L48`](../test/invariants/AddressAliasHelper.t.sol#L48) - -Asserts that an address that has been aliased with `applyL1ToL2Alias` can always be unaliased with `undoL1ToL2Alias`. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/Burn.Eth.md b/packages/contracts-bedrock/invariant-docs/Burn.Eth.md deleted file mode 100644 index eb11cba92315..000000000000 --- a/packages/contracts-bedrock/invariant-docs/Burn.Eth.md +++ /dev/null @@ -1,6 +0,0 @@ -# `Burn.Eth` Invariants - -## `eth(uint256)` always burns the exact amount of eth passed. -**Test:** [`Burn.Eth.t.sol#L66`](../test/invariants/Burn.Eth.t.sol#L66) - -Asserts that when `Burn.eth(uint256)` is called, it always burns the exact amount of ETH passed to the function. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/Burn.Gas.md b/packages/contracts-bedrock/invariant-docs/Burn.Gas.md deleted file mode 100644 index 5c343bca23fd..000000000000 --- a/packages/contracts-bedrock/invariant-docs/Burn.Gas.md +++ /dev/null @@ -1,6 +0,0 @@ -# `Burn.Gas` Invariants - -## `gas(uint256)` always burns at least the amount of gas passed. -**Test:** [`Burn.Gas.t.sol#L66`](../test/invariants/Burn.Gas.t.sol#L66) - -Asserts that when `Burn.gas(uint256)` is called, it always burns at least the amount of gas passed to the function. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/CrossDomainMessenger.md b/packages/contracts-bedrock/invariant-docs/CrossDomainMessenger.md deleted file mode 100644 index 4329859f24a3..000000000000 --- a/packages/contracts-bedrock/invariant-docs/CrossDomainMessenger.md +++ /dev/null @@ -1,15 +0,0 @@ -# `CrossDomainMessenger` Invariants - -## A call to `relayMessage` should succeed if at least the minimum gas limit can be supplied to the target context, there is enough gas to complete execution of `relayMessage` after the target context's execution is finished, and the target context did not revert. -**Test:** [`CrossDomainMessenger.t.sol#L143`](../test/invariants/CrossDomainMessenger.t.sol#L143) - -There are two minimum gas limits here: -- The outer min gas limit is for the call from the `OptimismPortal` to the `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function with the `message` and inner limit. -- The inner min gas limit is for the call from the `L1CrossDomainMessenger` to the target contract. - -## A call to `relayMessage` should assign the message hash to the `failedMessages` mapping if not enough gas is supplied to forward `minGasLimit` to the target context or if there is not enough gas to complete execution of `relayMessage` after the target context's execution is finished. -**Test:** [`CrossDomainMessenger.t.sol#L176`](../test/invariants/CrossDomainMessenger.t.sol#L176) - -There are two minimum gas limits here: -- The outer min gas limit is for the call from the `OptimismPortal` to the `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function with the `message` and inner limit. -- The inner min gas limit is for the call from the `L1CrossDomainMessenger` to the target contract. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/ETHLiquidity.md b/packages/contracts-bedrock/invariant-docs/ETHLiquidity.md deleted file mode 100644 index 495c5556db02..000000000000 --- a/packages/contracts-bedrock/invariant-docs/ETHLiquidity.md +++ /dev/null @@ -1,5 +0,0 @@ -# `ETHLiquidity` Invariants - -## Calls to mint/burn repeatedly should never cause the actor's balance to increase beyond the starting balance. -**Test:** [`ETHLiquidity.t.sol#L86`](../test/invariants/ETHLiquidity.t.sol#L86) - diff --git a/packages/contracts-bedrock/invariant-docs/Encoding.md b/packages/contracts-bedrock/invariant-docs/Encoding.md deleted file mode 100644 index 460eff43df77..000000000000 --- a/packages/contracts-bedrock/invariant-docs/Encoding.md +++ /dev/null @@ -1,11 +0,0 @@ -# `Encoding` Invariants - -## `convertRoundTripAToB` never fails. -**Test:** [`Encoding.t.sol#L73`](../test/invariants/Encoding.t.sol#L73) - -Asserts that a raw versioned nonce can be encoded / decoded to reach the same raw value. - -## `convertRoundTripBToA` never fails. -**Test:** [`Encoding.t.sol#L82`](../test/invariants/Encoding.t.sol#L82) - -Asserts that an encoded versioned nonce can always be decoded / re-encoded to reach the same encoded value. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/FaultDisputeGame.md b/packages/contracts-bedrock/invariant-docs/FaultDisputeGame.md deleted file mode 100644 index c54eb974cff7..000000000000 --- a/packages/contracts-bedrock/invariant-docs/FaultDisputeGame.md +++ /dev/null @@ -1,6 +0,0 @@ -# `FaultDisputeGame` Invariants - -## FaultDisputeGame always returns all ETH on total resolution -**Test:** [`FaultDisputeGame.t.sol#L33`](../test/invariants/FaultDisputeGame.t.sol#L33) - -The FaultDisputeGame contract should always return all ETH in the contract to the correct recipients upon resolution of all outstanding claims. There may never be any ETH left in the contract after a full resolution. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/Hashing.md b/packages/contracts-bedrock/invariant-docs/Hashing.md deleted file mode 100644 index acf407876d3c..000000000000 --- a/packages/contracts-bedrock/invariant-docs/Hashing.md +++ /dev/null @@ -1,16 +0,0 @@ -# `Hashing` Invariants - -## `hashCrossDomainMessage` reverts if `version` is > `1`. -**Test:** [`Hashing.t.sol#L119`](../test/invariants/Hashing.t.sol#L119) - -The `hashCrossDomainMessage` function should always revert if the `version` passed is > `1`. - -## `version` = `0`: `hashCrossDomainMessage` and `hashCrossDomainMessageV0` are equivalent. -**Test:** [`Hashing.t.sol#L129`](../test/invariants/Hashing.t.sol#L129) - -If the version passed is 0, `hashCrossDomainMessage` and `hashCrossDomainMessageV0` should be equivalent. - -## `version` = `1`: `hashCrossDomainMessage` and `hashCrossDomainMessageV1` are equivalent. -**Test:** [`Hashing.t.sol#L140`](../test/invariants/Hashing.t.sol#L140) - -If the version passed is 1, `hashCrossDomainMessage` and `hashCrossDomainMessageV1` should be equivalent. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/InvariantTest.sol.md b/packages/contracts-bedrock/invariant-docs/InvariantTest.sol.md deleted file mode 100644 index bd27f490f563..000000000000 --- a/packages/contracts-bedrock/invariant-docs/InvariantTest.sol.md +++ /dev/null @@ -1,2 +0,0 @@ -# `InvariantTest.sol` Invariants - diff --git a/packages/contracts-bedrock/invariant-docs/L2OutputOracle.md b/packages/contracts-bedrock/invariant-docs/L2OutputOracle.md deleted file mode 100644 index 18804304e71c..000000000000 --- a/packages/contracts-bedrock/invariant-docs/L2OutputOracle.md +++ /dev/null @@ -1,6 +0,0 @@ -# `L2OutputOracle` Invariants - -## The block number of the output root proposals should monotonically increase. -**Test:** [`L2OutputOracle.t.sol#L58`](../test/invariants/L2OutputOracle.t.sol#L58) - -When a new output is submitted, it should never be allowed to correspond to a block number that is less than the current output. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/OptimismPortal.md b/packages/contracts-bedrock/invariant-docs/OptimismPortal.md deleted file mode 100644 index b1b2c38cb278..000000000000 --- a/packages/contracts-bedrock/invariant-docs/OptimismPortal.md +++ /dev/null @@ -1,21 +0,0 @@ -# `OptimismPortal` Invariants - -## Deposits of any value should always succeed unless `_to` = `address(0)` or `_isCreation` = `true`. -**Test:** [`OptimismPortal.t.sol#L151`](../test/invariants/OptimismPortal.t.sol#L151) - -All deposits, barring creation transactions and transactions sent to `address(0)`, should always succeed. - -## `finalizeWithdrawalTransaction` should revert if the finalization period has not elapsed. -**Test:** [`OptimismPortal.t.sol#L174`](../test/invariants/OptimismPortal.t.sol#L174) - -A withdrawal that has been proven should not be able to be finalized until after the finalization period has elapsed. - -## `finalizeWithdrawalTransaction` should revert if the withdrawal has already been finalized. -**Test:** [`OptimismPortal.t.sol#L204`](../test/invariants/OptimismPortal.t.sol#L204) - -Ensures that there is no chain of calls that can be made that allows a withdrawal to be finalized twice. - -## A withdrawal should **always** be able to be finalized `FINALIZATION_PERIOD_SECONDS` after it was successfully proven. -**Test:** [`OptimismPortal.t.sol#L233`](../test/invariants/OptimismPortal.t.sol#L233) - -This invariant asserts that there is no chain of calls that can be made that will prevent a withdrawal from being finalized exactly `FINALIZATION_PERIOD_SECONDS` after it was successfully proven. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/OptimismPortal2.md b/packages/contracts-bedrock/invariant-docs/OptimismPortal2.md deleted file mode 100644 index b3c1eb0d4576..000000000000 --- a/packages/contracts-bedrock/invariant-docs/OptimismPortal2.md +++ /dev/null @@ -1,21 +0,0 @@ -# `OptimismPortal2` Invariants - -## Deposits of any value should always succeed unless `_to` = `address(0)` or `_isCreation` = `true`. -**Test:** [`OptimismPortal2.t.sol#L163`](../test/invariants/OptimismPortal2.t.sol#L163) - -All deposits, barring creation transactions and transactions sent to `address(0)`, should always succeed. - -## `finalizeWithdrawalTransaction` should revert if the proof maturity period has not elapsed. -**Test:** [`OptimismPortal2.t.sol#L185`](../test/invariants/OptimismPortal2.t.sol#L185) - -A withdrawal that has been proven should not be able to be finalized until after the proof maturity period has elapsed. - -## `finalizeWithdrawalTransaction` should revert if the withdrawal has already been finalized. -**Test:** [`OptimismPortal2.t.sol#L214`](../test/invariants/OptimismPortal2.t.sol#L214) - -Ensures that there is no chain of calls that can be made that allows a withdrawal to be finalized twice. - -## A withdrawal should **always** be able to be finalized `PROOF_MATURITY_DELAY_SECONDS` after it was successfully proven, if the game has resolved and passed the air-gap. -**Test:** [`OptimismPortal2.t.sol#L242`](../test/invariants/OptimismPortal2.t.sol#L242) - -This invariant asserts that there is no chain of calls that can be made that will prevent a withdrawal from being finalized exactly `PROOF_MATURITY_DELAY_SECONDS` after it was successfully proven and the game has resolved and passed the air-gap. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/OptimismSuperchainERC20.md b/packages/contracts-bedrock/invariant-docs/OptimismSuperchainERC20.md deleted file mode 100644 index 8b5c65ebf213..000000000000 --- a/packages/contracts-bedrock/invariant-docs/OptimismSuperchainERC20.md +++ /dev/null @@ -1,16 +0,0 @@ -# `OptimismSuperchainERC20` Invariants - -## sum of supertoken total supply across all chains is always <= to convert(legacy, super)- convert(super, legacy) -**Test:** [`OptimismSuperchainERC20#L36`](../test/invariants/OptimismSuperchainERC20#L36) - - - -## sum of supertoken total supply across all chains is equal to convert(legacy, super)- convert(super, legacy) when all when all cross-chain messages are processed -**Test:** [`OptimismSuperchainERC20#L57`](../test/invariants/OptimismSuperchainERC20#L57) - - - -## many other assertion mode invariants are also defined under `test/invariants/OptimismSuperchainERC20/fuzz/` . -**Test:** [`OptimismSuperchainERC20#L80`](../test/invariants/OptimismSuperchainERC20#L80) - -since setting`fail_on_revert=false` also ignores StdAssertion failures, this invariant explicitly asks the handler for assertion test failures \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/README.md b/packages/contracts-bedrock/invariant-docs/README.md deleted file mode 100644 index cfa87fb4c167..000000000000 --- a/packages/contracts-bedrock/invariant-docs/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# Invariant Docs - -This directory contains documentation for all defined invariant tests within `contracts-bedrock`. - - - - -## Table of Contents -- [AddressAliasHelper](./AddressAliasHelper.md) -- [Burn.Eth](./Burn.Eth.md) -- [Burn.Gas](./Burn.Gas.md) -- [CrossDomainMessenger](./CrossDomainMessenger.md) -- [ETHLiquidity](./ETHLiquidity.md) -- [Encoding](./Encoding.md) -- [FaultDisputeGame](./FaultDisputeGame.md) -- [Hashing](./Hashing.md) -- [InvariantTest.sol](./InvariantTest.sol.md) -- [L2OutputOracle](./L2OutputOracle.md) -- [OptimismPortal](./OptimismPortal.md) -- [OptimismPortal2](./OptimismPortal2.md) -- [OptimismSuperchainERC20](./OptimismSuperchainERC20.md) -- [ResourceMetering](./ResourceMetering.md) -- [SafeCall](./SafeCall.md) -- [SuperchainWETH](./SuperchainWETH.md) -- [SystemConfig](./SystemConfig.md) - - -## Usage - -To auto-generate documentation for invariant tests, run `just autogen-invariant-docs`. - -## Documentation Standard - -In order for an invariant test file to be picked up by the [docgen script](../scripts/autogen/generate-invariant-docs.ts), it must -adhere to the following conventions: - -### Forge Invariants - -All `forge` invariant tests must exist within the `contracts/test/invariants` folder, and the file name should be -`.t.sol`, where `` is the name of the contract that is being tested. - -All tests within `forge` invariant files should follow the convention: - -```solidity -/** - * @custom:invariant - * - * <longDescription> - */ -function invariant_<shortDescription>() external { - // ... -} -``` diff --git a/packages/contracts-bedrock/invariant-docs/ResourceMetering.md b/packages/contracts-bedrock/invariant-docs/ResourceMetering.md deleted file mode 100644 index 2f97937d2b84..000000000000 --- a/packages/contracts-bedrock/invariant-docs/ResourceMetering.md +++ /dev/null @@ -1,36 +0,0 @@ -# `ResourceMetering` Invariants - -## The base fee should increase if the last block used more than the target amount of gas. -**Test:** [`ResourceMetering.t.sol#L166`](../test/invariants/ResourceMetering.t.sol#L166) - -If the last block used more than the target amount of gas (and there were no empty blocks in between), ensure this block's baseFee increased, but not by more than the max amount per block. - -## The base fee should decrease if the last block used less than the target amount of gas. -**Test:** [`ResourceMetering.t.sol#L175`](../test/invariants/ResourceMetering.t.sol#L175) - -If the previous block used less than the target amount of gas, the base fee should decrease, but not more than the max amount. - -## A block's base fee should never be below `MINIMUM_BASE_FEE`. -**Test:** [`ResourceMetering.t.sol#L183`](../test/invariants/ResourceMetering.t.sol#L183) - -This test asserts that a block's base fee can never drop below the `MINIMUM_BASE_FEE` threshold. - -## A block can never consume more than `MAX_RESOURCE_LIMIT` gas. -**Test:** [`ResourceMetering.t.sol#L191`](../test/invariants/ResourceMetering.t.sol#L191) - -This test asserts that a block can never consume more than the `MAX_RESOURCE_LIMIT` gas threshold. - -## The base fee can never be raised more than the max base fee change. -**Test:** [`ResourceMetering.t.sol#L201`](../test/invariants/ResourceMetering.t.sol#L201) - -After a block consumes more gas than the target gas, the base fee cannot be raised more than the maximum amount allowed. The max base fee change (per-block) is derived as follows: `prevBaseFee / BASE_FEE_MAX_CHANGE_DENOMINATOR` - -## The base fee can never be lowered more than the max base fee change. -**Test:** [`ResourceMetering.t.sol#L211`](../test/invariants/ResourceMetering.t.sol#L211) - -After a block consumes less than the target gas, the base fee cannot be lowered more than the maximum amount allowed. The max base fee change (per-block) is derived as follows: `prevBaseFee / BASE_FEE_MAX_CHANGE_DENOMINATOR` - -## The `maxBaseFeeChange` calculation over multiple blocks can never underflow. -**Test:** [`ResourceMetering.t.sol#L220`](../test/invariants/ResourceMetering.t.sol#L220) - -When calculating the `maxBaseFeeChange` after multiple empty blocks, the calculation should never be allowed to underflow. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/SafeCall.md b/packages/contracts-bedrock/invariant-docs/SafeCall.md deleted file mode 100644 index 19ac6d851030..000000000000 --- a/packages/contracts-bedrock/invariant-docs/SafeCall.md +++ /dev/null @@ -1,11 +0,0 @@ -# `SafeCall` Invariants - -## If `callWithMinGas` performs a call, then it must always provide at least the specified minimum gas limit to the subcontext. -**Test:** [`SafeCall.t.sol#L33`](../test/invariants/SafeCall.t.sol#L33) - -If the check for remaining gas in `SafeCall.callWithMinGas` passes, the subcontext of the call below it must be provided at least `minGas` gas. - -## `callWithMinGas` reverts if there is not enough gas to pass to the subcontext. -**Test:** [`SafeCall.t.sol#L66`](../test/invariants/SafeCall.t.sol#L66) - -If there is not enough gas in the callframe to ensure that `callWithMinGas` can provide the specified minimum gas limit to the subcontext of the call, then `callWithMinGas` must revert. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/SuperchainWETH.md b/packages/contracts-bedrock/invariant-docs/SuperchainWETH.md deleted file mode 100644 index afdb4a7b35c6..000000000000 --- a/packages/contracts-bedrock/invariant-docs/SuperchainWETH.md +++ /dev/null @@ -1,5 +0,0 @@ -# `SuperchainWETH` Invariants - -## Calls to sendERC20 should always succeed as long as the actor has less than uint248 wei which is much greater than the total ETH supply. Actor's balance should also not increase out of nowhere. -**Test:** [`SuperchainWETH.t.sol#L184`](../test/invariants/SuperchainWETH.t.sol#L184) - diff --git a/packages/contracts-bedrock/invariant-docs/SystemConfig.md b/packages/contracts-bedrock/invariant-docs/SystemConfig.md deleted file mode 100644 index b3d711972f6b..000000000000 --- a/packages/contracts-bedrock/invariant-docs/SystemConfig.md +++ /dev/null @@ -1,6 +0,0 @@ -# `SystemConfig` Invariants - -## Gas limit boundaries -**Test:** [`SystemConfig.t.sol#L71`](../test/invariants/SystemConfig.t.sol#L71) - -The gas limit of the `SystemConfig` contract can never be lower than the hard-coded lower bound or higher than the hard-coded upper bound. The lower bound must never be higher than the upper bound. \ No newline at end of file diff --git a/packages/contracts-bedrock/justfile b/packages/contracts-bedrock/justfile index a1f0a0836d14..e59dd8b03b99 100644 --- a/packages/contracts-bedrock/justfile +++ b/packages/contracts-bedrock/justfile @@ -13,9 +13,6 @@ build: prebuild build-go-ffi: cd scripts/go-ffi && go build -autogen-invariant-docs: - go run ./scripts/autogen/generate-invariant-docs . - test: build-go-ffi forge test @@ -133,7 +130,7 @@ clean: rm -rf ./artifacts ./forge-artifacts ./cache ./scripts/go-ffi/go-ffi ./deployments/hardhat/* find ./.testdata -mindepth 1 -not -name '.gitkeep' -delete -pre-pr-no-build: gas-snapshot-no-build snapshots-no-build semver-lock autogen-invariant-docs lint +pre-pr-no-build: gas-snapshot-no-build snapshots-no-build semver-lock lint pre-pr: clean build-go-ffi build pre-pr-no-build diff --git a/packages/contracts-bedrock/scripts/autogen/generate-invariant-docs/main.go b/packages/contracts-bedrock/scripts/autogen/generate-invariant-docs/main.go deleted file mode 100644 index 457e100edbe3..000000000000 --- a/packages/contracts-bedrock/scripts/autogen/generate-invariant-docs/main.go +++ /dev/null @@ -1,262 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "os" - "path/filepath" - "slices" - "strings" -) - -const ( - NatspecInv = "@custom:invariant" - BaseInvariantGhUrl = "../test/invariants/" -) - -// Contract represents an invariant test contract -type Contract struct { - Name string - FileName string - Docs []InvariantDoc -} - -// InvariantDoc represents the documentation of an invariant -type InvariantDoc struct { - Header string - Desc string - LineNo int -} - -var writtenFiles []string - -// Generate the docs -func main() { - flag.Parse() - if flag.NArg() != 1 { - fmt.Println("Expected path of contracts-bedrock as CLI argument") - os.Exit(1) - } - rootDir := flag.Arg(0) - - invariantsDir := filepath.Join(rootDir, "test/invariants") - fmt.Printf("invariants dir: %s\n", invariantsDir) - docsDir := filepath.Join(rootDir, "invariant-docs") - fmt.Printf("invariant docs dir: %s\n", docsDir) - - // Forge - fmt.Println("Generating docs for forge invariants...") - if err := docGen(invariantsDir, docsDir); err != nil { - fmt.Printf("Failed to generate invariant docs: %v\n", err) - os.Exit(1) - } - - fmt.Println("Generating table-of-contents...") - // Generate an updated table of contents - if err := tocGen(docsDir); err != nil { - fmt.Printf("Failed to generate TOC of docs: %v\n", err) - os.Exit(1) - } - fmt.Println("Done!") -} - -// Lazy-parses all test files in the `test/invariants` directory -// to generate documentation on all invariant tests. -func docGen(invariantsDir, docsDir string) error { - - // Grab all files within the invariants test dir - files, err := os.ReadDir(invariantsDir) - if err != nil { - return fmt.Errorf("error reading directory: %w", err) - } - - // Array to store all found invariant documentation comments. - var docs []Contract - - for _, file := range files { - // Read the contents of the invariant test file. - fileName := file.Name() - filePath := filepath.Join(invariantsDir, fileName) - // where invariants for a module have their own directory, interpret - // the test file with the same name as the directory as a 'main' of - // sorts, from where documentation is pulled - if file.IsDir() { - filePath = filepath.Join(filePath, strings.Join([]string{fileName, ".t.sol"}, "")) - } - fileContents, err := os.ReadFile(filePath) - if err != nil { - return fmt.Errorf("error reading file %q: %w", filePath, err) - } - - // Split the file into individual lines and trim whitespace. - lines := strings.Split(string(fileContents), "\n") - for i, line := range lines { - lines[i] = strings.TrimSpace(line) - } - - // Create an object to store all invariant test docs for the current contract - name := strings.Replace(fileName, ".t.sol", "", 1) - contract := Contract{Name: name, FileName: fileName} - - var currentDoc InvariantDoc - - // Loop through all lines to find comments. - for i := 0; i < len(lines); i++ { - line := lines[i] - - // We have an invariant doc - if strings.HasPrefix(line, "/// "+NatspecInv) { - // Assign the header of the invariant doc. - currentDoc = InvariantDoc{ - Header: strings.TrimSpace(strings.Replace(line, "/// "+NatspecInv, "", 1)), - Desc: "", - } - i++ - - // If the header is multi-line, continue appending to the `currentDoc`'s header. - for { - if i >= len(lines) { - break - } - line = lines[i] - i++ - if !(strings.HasPrefix(line, "///") && strings.TrimSpace(line) != "///") { - break - } - currentDoc.Header += " " + strings.TrimSpace(strings.Replace(line, "///", "", 1)) - } - - // Process the description - for { - if i >= len(lines) { - break - } - line = lines[i] - i++ - if !strings.HasPrefix(line, "///") { - break - } - line = strings.TrimSpace(strings.Replace(line, "///", "", 1)) - - // If the line has any contents, insert it into the desc. - // Otherwise, consider it a linebreak. - if len(line) > 0 { - currentDoc.Desc += line + " " - } else { - currentDoc.Desc += "\n" - } - } - - // Set the line number of the test - currentDoc.LineNo = i - - // Add the doc to the contract - contract.Docs = append(contract.Docs, currentDoc) - } - } - - // Add the contract to the array of docs - docs = append(docs, contract) - } - - for _, contract := range docs { - filePath := filepath.Join(docsDir, contract.Name+".md") - alreadyWritten := slices.Contains(writtenFiles, filePath) - - // If the file has already been written, append the extra docs to the end. - // Otherwise, write the file from scratch. - var fileContent string - if alreadyWritten { - existingContent, err := os.ReadFile(filePath) - if err != nil { - return fmt.Errorf("error reading existing file %q: %w", filePath, err) - } - fileContent = string(existingContent) + "\n" + renderContractDoc(contract, false) - } else { - fileContent = renderContractDoc(contract, true) - } - - err = os.WriteFile(filePath, []byte(fileContent), 0644) - if err != nil { - return fmt.Errorf("error writing file %q: %w", filePath, err) - } - - if !alreadyWritten { - writtenFiles = append(writtenFiles, filePath) - } - } - - _, _ = fmt.Fprintf(os.Stderr, - "Generated invariant test documentation for:\n"+ - " - %d contracts\n"+ - " - %d invariant tests\n"+ - "successfully!\n", - len(docs), - func() int { - total := 0 - for _, contract := range docs { - total += len(contract.Docs) - } - return total - }(), - ) - return nil -} - -// Generate a table of contents for all invariant docs and place it in the README. -func tocGen(docsDir string) error { - autoTOCPrefix := "<!-- START autoTOC -->\n" - autoTOCPostfix := "<!-- END autoTOC -->\n" - - files, err := os.ReadDir(docsDir) - if err != nil { - return fmt.Errorf("error reading directory %q: %w", docsDir, err) - } - - // Generate a table of contents section. - var tocList []string - for _, file := range files { - fileName := file.Name() - if fileName != "README.md" { - tocList = append(tocList, fmt.Sprintf("- [%s](./%s)", strings.Replace(fileName, ".md", "", 1), fileName)) - } - } - toc := fmt.Sprintf("%s\n## Table of Contents\n%s\n%s", - autoTOCPrefix, strings.Join(tocList, "\n"), autoTOCPostfix) - - // Write the table of contents to the README. - readmePath := filepath.Join(docsDir, "README.md") - readmeContents, err := os.ReadFile(readmePath) - if err != nil { - return fmt.Errorf("error reading README file %q: %w", readmePath, err) - } - readmeParts := strings.Split(string(readmeContents), autoTOCPrefix) - above := readmeParts[0] - readmeParts = strings.Split(readmeParts[1], autoTOCPostfix) - below := readmeParts[1] - err = os.WriteFile(readmePath, []byte(above+toc+below), 0644) - if err != nil { - return fmt.Errorf("error writing README file %q: %w", readmePath, err) - } - return nil -} - -// Render a `Contract` object into valid markdown. -func renderContractDoc(contract Contract, header bool) string { - var sb strings.Builder - - if header { - sb.WriteString(fmt.Sprintf("# `%s` Invariants\n", contract.Name)) - } - sb.WriteString("\n") - - for i, doc := range contract.Docs { - line := fmt.Sprintf("%s#L%d", contract.FileName, doc.LineNo) - sb.WriteString(fmt.Sprintf("## %s\n**Test:** [`%s`](%s%s)\n\n%s", doc.Header, line, BaseInvariantGhUrl, line, doc.Desc)) - if i != len(contract.Docs)-1 { - sb.WriteString("\n\n") - } - } - - return sb.String() -} From 43ec97dd2d0d9c62c5afd02c244c5f223f00739e Mon Sep 17 00:00:00 2001 From: Inphi <mlaw2501@gmail.com> Date: Thu, 19 Sep 2024 19:44:17 -0400 Subject: [PATCH 212/264] vm-runner: User-provided mt-cannon absolute prestate URL (#12016) * vm-runner: User-provided mt-cannon absolute prestate URL * placate semgrep --- op-challenger/cmd/run_trace.go | 51 ++++++++++++++++++++++++++------- op-challenger/runner/factory.go | 22 ++++++++++++++ op-challenger/runner/runner.go | 43 +++++++++++++++++++-------- 3 files changed, 93 insertions(+), 23 deletions(-) diff --git a/op-challenger/cmd/run_trace.go b/op-challenger/cmd/run_trace.go index 86f35bd79474..c1d2261230f9 100644 --- a/op-challenger/cmd/run_trace.go +++ b/op-challenger/cmd/run_trace.go @@ -2,9 +2,13 @@ package main import ( "context" + "errors" "fmt" + "net/url" + "github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-challenger/flags" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" "github.com/ethereum-optimism/optimism/op-challenger/runner" opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/cliapp" @@ -27,18 +31,36 @@ func RunTrace(ctx *cli.Context, _ context.CancelCauseFunc) (cliapp.Lifecycle, er if err := cfg.Check(); err != nil { return nil, err } - if ctx.IsSet(addMTCannonPrestate.Name) && cfg.CannonAbsolutePreStateBaseURL == nil { - return nil, fmt.Errorf("flag %v is required when using %v", flags.CannonPreStateFlag.Name, addMTCannonPrestate.Name) + if err := checkMTCannonFlags(ctx, cfg); err != nil { + return nil, err } + var mtPrestate common.Hash - if ctx.IsSet(addMTCannonPrestate.Name) { - mtPrestate = common.HexToHash(ctx.String(addMTCannonPrestate.Name)) + var mtPrestateURL *url.URL + if ctx.IsSet(addMTCannonPrestateFlag.Name) { + mtPrestate = common.HexToHash(ctx.String(addMTCannonPrestateFlag.Name)) + mtPrestateURL, err = url.Parse(ctx.String(addMTCannonPrestateURLFlag.Name)) + if err != nil { + return nil, fmt.Errorf("invalid mt-cannon prestate url (%v): %w", ctx.String(addMTCannonPrestateFlag.Name), err) + } + } + return runner.NewRunner(logger, cfg, mtPrestate, mtPrestateURL), nil +} + +func checkMTCannonFlags(ctx *cli.Context, cfg *config.Config) error { + if ctx.IsSet(addMTCannonPrestateFlag.Name) || ctx.IsSet(addMTCannonPrestateURLFlag.Name) { + if ctx.IsSet(addMTCannonPrestateFlag.Name) != ctx.IsSet(addMTCannonPrestateURLFlag.Name) { + return fmt.Errorf("both flag %v and %v must be set when running MT-Cannon traces", addMTCannonPrestateURLFlag.Name, addMTCannonPrestateFlag.Name) + } + if cfg.Cannon == (vm.Config{}) { + return errors.New("required Cannon vm configuration for mt-cannon traces is missing") + } } - return runner.NewRunner(logger, cfg, mtPrestate), nil + return nil } func runTraceFlags() []cli.Flag { - return append(flags.Flags, addMTCannonPrestate) + return append(flags.Flags, addMTCannonPrestateFlag, addMTCannonPrestateURLFlag) } var RunTraceCommand = &cli.Command{ @@ -49,8 +71,15 @@ var RunTraceCommand = &cli.Command{ Flags: runTraceFlags(), } -var addMTCannonPrestate = &cli.StringFlag{ - Name: "add-mt-cannon-prestate", - Usage: "Use this prestate to run MT-Cannon compatibility tests", - EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "ADD_MT_CANNON_PRESTATE"), -} +var ( + addMTCannonPrestateFlag = &cli.StringFlag{ + Name: "add-mt-cannon-prestate", + Usage: "Use this prestate to run MT-Cannon compatibility tests", + EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "ADD_MT_CANNON_PRESTATE"), + } + addMTCannonPrestateURLFlag = &cli.StringFlag{ + Name: "add-mt-cannon-prestate-url", + Usage: "Use this prestate URL to run MT-Cannon compatibility tests", + EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "ADD_MT_CANNON_PRESTATE_URL"), + } +) diff --git a/op-challenger/runner/factory.go b/op-challenger/runner/factory.go index 203027e4ec3d..898afdbbf1b7 100644 --- a/op-challenger/runner/factory.go +++ b/op-challenger/runner/factory.go @@ -58,6 +58,28 @@ func createTraceProvider( return nil, errors.New("invalid trace type") } +func createMTTraceProvider( + logger log.Logger, + m vm.Metricer, + vmConfig vm.Config, + prestateHash common.Hash, + absolutePrestateBaseURL *url.URL, + traceType types.TraceType, + localInputs utils.LocalGameInputs, + dir string, +) (types.TraceProvider, error) { + executor := vm.NewOpProgramServerExecutor() + stateConverter := cannon.NewStateConverter() + + prestateSource := prestates.NewMultiPrestateProvider(absolutePrestateBaseURL, filepath.Join(dir, "prestates"), cannon.NewStateConverter()) + prestatePath, err := prestateSource.PrestatePath(prestateHash) + if err != nil { + return nil, fmt.Errorf("failed to get prestate %v: %w", prestateHash, err) + } + prestateProvider := vm.NewPrestateProvider(prestatePath, stateConverter) + return cannon.NewTraceProvider(logger, m, vmConfig, executor, prestateProvider, prestatePath, localInputs, dir, 42), nil +} + func getPrestate(prestateHash common.Hash, prestateBaseUrl *url.URL, prestatePath string, dataDir string, stateConverter vm.StateConverter) (string, error) { prestateSource := prestates.NewPrestateSource( prestateBaseUrl, diff --git a/op-challenger/runner/runner.go b/op-challenger/runner/runner.go index 73f8ec8718ed..f5c95439357e 100644 --- a/op-challenger/runner/runner.go +++ b/op-challenger/runner/runner.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "math/big" + "net/url" "os" "path/filepath" "sync" @@ -42,10 +43,11 @@ type Metricer interface { } type Runner struct { - log log.Logger - cfg *config.Config - addMTCannonPrestate common.Hash - m Metricer + log log.Logger + cfg *config.Config + addMTCannonPrestate common.Hash + addMTCannonPrestateURL *url.URL + m Metricer running atomic.Bool ctx context.Context @@ -54,12 +56,13 @@ type Runner struct { metricsSrv *httputil.HTTPServer } -func NewRunner(logger log.Logger, cfg *config.Config, mtCannonPrestate common.Hash) *Runner { +func NewRunner(logger log.Logger, cfg *config.Config, mtCannonPrestate common.Hash, mtCannonPrestateURL *url.URL) *Runner { return &Runner{ - log: logger, - cfg: cfg, - addMTCannonPrestate: mtCannonPrestate, - m: NewMetrics(), + log: logger, + cfg: cfg, + addMTCannonPrestate: mtCannonPrestate, + addMTCannonPrestateURL: mtCannonPrestateURL, + m: NewMetrics(), } } @@ -148,16 +151,17 @@ func (r *Runner) runAndRecordOnce(ctx context.Context, traceType types.TraceType recordError(err, traceType.String(), r.m, r.log) }() - if r.addMTCannonPrestate != (common.Hash{}) { + if r.addMTCannonPrestate != (common.Hash{}) && r.addMTCannonPrestateURL != nil { wg.Add(1) go func() { defer wg.Done() dir, err := r.prepDatadir("mt-cannon") if err != nil { - recordError(err, traceType.String(), r.m, r.log) + recordError(err, "mt-cannon", r.m, r.log) return } - err = r.runOnce(ctx, inputsLogger.With("type", "mt-cannon"), types.TraceTypeCannon, r.addMTCannonPrestate, localInputs, dir) + logger := inputsLogger.With("type", "mt-cannon") + err = r.runMTOnce(ctx, logger, traceType, prestateHash, localInputs, dir) recordError(err, traceType.String(), r.m, r.log.With("mt-cannon", true)) }() } @@ -179,6 +183,21 @@ func (r *Runner) runOnce(ctx context.Context, logger log.Logger, traceType types return nil } +func (r *Runner) runMTOnce(ctx context.Context, logger log.Logger, traceType types.TraceType, prestateHash common.Hash, localInputs utils.LocalGameInputs, dir string) error { + provider, err := createMTTraceProvider(logger, r.m, r.cfg.Cannon, r.addMTCannonPrestate, r.addMTCannonPrestateURL, types.TraceTypeCannon, localInputs, dir) + if err != nil { + return fmt.Errorf("failed to create trace provider: %w", err) + } + hash, err := provider.Get(ctx, types.RootPosition) + if err != nil { + return fmt.Errorf("failed to execute trace provider: %w", err) + } + if hash[0] != mipsevm.VMStatusValid { + return fmt.Errorf("%w: %v", ErrUnexpectedStatusCode, hash) + } + return nil +} + func (r *Runner) prepDatadir(traceType string) (string, error) { dir := filepath.Join(r.cfg.Datadir, traceType) if err := os.RemoveAll(dir); err != nil { From eaf4d3ed1e05ebfbe95606b33035cb0d27e63347 Mon Sep 17 00:00:00 2001 From: smartcontracts <kelvin@optimism.io> Date: Thu, 19 Sep 2024 19:06:41 -0600 Subject: [PATCH 213/264] maint: fix dispute interfaces (#12010) Fixes the existing dispute interfaces and makes them match the same style that we're using for all other interfaces. --- .../scripts/checks/check-interfaces.sh | 18 +- .../scripts/deploy/ChainAssertions.sol | 10 +- .../scripts/deploy/Deploy.s.sol | 176 ++++++++++-------- .../scripts/fpac/FPACOPS.s.sol | 47 +++-- .../scripts/fpac/FPACOPS2.s.sol | 89 +++++---- .../fpac/viz/FaultDisputeGameViz.s.sol | 15 +- packages/contracts-bedrock/semver-lock.json | 20 +- .../snapshots/abi/DeputyGuardianModule.json | 2 +- .../snapshots/abi/DisputeGameFactory.json | 2 +- .../snapshots/storageLayout/DelayedWETH.json | 2 +- .../storageLayout/FaultDisputeGame.json | 4 +- .../PermissionedDisputeGame.json | 4 +- .../src/L2/interfaces/IL1BlockIsthmus.sol | 8 +- .../src/dispute/AnchorStateRegistry.sol | 32 ++-- .../src/dispute/DelayedWETH.sol | 44 +++-- .../src/dispute/DisputeGameFactory.sol | 99 ++++++++-- .../src/dispute/FaultDisputeGame.sol | 159 ++++++++++++---- .../src/dispute/PermissionedDisputeGame.sol | 16 +- .../interfaces/IAnchorStateRegistry.sol | 35 ++-- .../src/dispute/interfaces/IDelayedWETH.sol | 44 ++--- .../src/dispute/interfaces/IDisputeGame.sol | 55 +----- .../interfaces/IDisputeGameFactory.sol | 135 ++++---------- .../dispute/interfaces/IFaultDisputeGame.sol | 152 ++++++++------- .../src/dispute/interfaces/IInitializable.sol | 4 - .../interfaces/IPermissionedDisputeGame.sol | 11 ++ .../src/safe/DeputyGuardianModule.sol | 14 +- .../test/L1/OptimismPortal2.t.sol | 7 +- .../test/actors/FaultDisputeActors.sol | 22 ++- .../test/dispute/AnchorStateRegistry.t.sol | 8 +- .../test/dispute/DelayedWETH.t.sol | 14 +- .../test/dispute/DisputeGameFactory.t.sol | 14 +- .../test/dispute/FaultDisputeGame.t.sol | 76 ++++---- .../dispute/PermissionedDisputeGame.t.sol | 60 +++--- .../test/invariants/FaultDisputeGame.t.sol | 10 +- .../test/invariants/OptimismPortal2.t.sol | 21 ++- .../test/safe/DeputyGuardianModule.t.sol | 19 +- .../contracts-bedrock/test/setup/Setup.sol | 20 +- .../test/vendor/Initializable.t.sol | 10 +- 38 files changed, 815 insertions(+), 663 deletions(-) create mode 100644 packages/contracts-bedrock/src/dispute/interfaces/IPermissionedDisputeGame.sol diff --git a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh index 8da3227311e5..628ecbbe2a4b 100755 --- a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh +++ b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh @@ -48,26 +48,24 @@ EXCLUDE_CONTRACTS=( "KontrolCheatsBase" # TODO: Interfaces that need to be fixed - "IPreimageOracle" - "IOptimismMintableERC721" - "IFaultDisputeGame" "IOptimismSuperchainERC20" - "IInitializable" + "IOptimismMintableERC721" "IOptimismMintableERC20" "ILegacyMintableERC20" + "IInitializable" + "IPreimageOracle" + "ICrossL2Inbox" + "IL2ToL2CrossDomainMessenger" "MintableAndBurnable" - "IDisputeGameFactory" "IWETH" "IDelayedWETH" - "IAnchorStateRegistry" - "ICrossL2Inbox" - "IL1CrossDomainMessenger" - "IL2ToL2CrossDomainMessenger" + + # TODO: Kontrol interfaces that need to be removed "IL1ERC721Bridge" "IL1StandardBridge" + "IL1CrossDomainMessenger" "ISuperchainConfig" "IOptimismPortal" - "IL1BlockIsthmus" ) # Find all JSON files in the forge-artifacts folder diff --git a/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol b/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol index 7d39a8c611f0..7e5a9164f466 100644 --- a/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol +++ b/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol @@ -12,8 +12,6 @@ import { ISystemConfigV0 } from "scripts/interfaces/ISystemConfigV0.sol"; // Contracts import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; -import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; -import { DelayedWETH } from "src/dispute/DelayedWETH.sol"; // Libraries import { Constants } from "src/libraries/Constants.sol"; @@ -31,6 +29,8 @@ import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; import { IL1StandardBridge } from "src/L1/interfaces/IL1StandardBridge.sol"; import { ProtocolVersion, IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol"; +import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol"; +import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol"; library ChainAssertions { @@ -183,7 +183,7 @@ library ChainAssertions { /// @notice Asserts that the DisputeGameFactory is setup correctly function checkDisputeGameFactory(Types.ContractSet memory _contracts, address _expectedOwner) internal view { console.log("Running chain assertions on the DisputeGameFactory"); - DisputeGameFactory factory = DisputeGameFactory(_contracts.DisputeGameFactory); + IDisputeGameFactory factory = IDisputeGameFactory(_contracts.DisputeGameFactory); // Check that the contract is initialized assertSlotValueIsOne({ _contractAddress: address(factory), _slot: 0, _offset: 0 }); @@ -202,7 +202,7 @@ library ChainAssertions { view { console.log("Running chain assertions on the DelayedWETH"); - DelayedWETH weth = DelayedWETH(payable(_contracts.DelayedWETH)); + IDelayedWETH weth = IDelayedWETH(payable(_contracts.DelayedWETH)); // Check that the contract is initialized assertSlotValueIsOne({ _contractAddress: address(weth), _slot: 0, _offset: 0 }); @@ -228,7 +228,7 @@ library ChainAssertions { view { console.log("Running chain assertions on the permissioned DelayedWETH"); - DelayedWETH weth = DelayedWETH(payable(_contracts.PermissionedDelayedWETH)); + IDelayedWETH weth = IDelayedWETH(payable(_contracts.PermissionedDelayedWETH)); // Check that the contract is initialized assertSlotValueIsOne({ _contractAddress: address(weth), _slot: 0, _offset: 0 }); diff --git a/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol b/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol index 8ab898830b93..722cd7c61ecf 100644 --- a/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol @@ -31,11 +31,6 @@ import { Proxy } from "src/universal/Proxy.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol"; import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol"; import { ResolvedDelegateProxy } from "src/legacy/ResolvedDelegateProxy.sol"; -import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; -import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; -import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; -import { DelayedWETH } from "src/dispute/DelayedWETH.sol"; -import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { MIPS } from "src/cannon/MIPS.sol"; import { MIPS2 } from "src/cannon/MIPS2.sol"; @@ -61,6 +56,10 @@ import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; import { IL1StandardBridge } from "src/L1/interfaces/IL1StandardBridge.sol"; import { IProtocolVersions, ProtocolVersion } from "src/L1/interfaces/IProtocolVersions.sol"; import { IBigStepper } from "src/dispute/interfaces/IBigStepper.sol"; +import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol"; +import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; +import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; +import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol"; import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol"; @@ -80,8 +79,8 @@ contract Deploy is Deployer { /// to finally adopt PUSHN and get rid of stack too deep once and for all. /// Someday we will look back and laugh about stack too deep, today is not that day. struct FaultDisputeGameParams { - AnchorStateRegistry anchorStateRegistry; - DelayedWETH weth; + IAnchorStateRegistry anchorStateRegistry; + IDelayedWETH weth; GameType gameType; Claim absolutePrestate; IBigStepper faultVm; @@ -766,10 +765,7 @@ contract Deploy is Deployer { /// @notice Deploy the DisputeGameFactory function deployDisputeGameFactory() public broadcast returns (address addr_) { - console.log("Deploying DisputeGameFactory implementation"); - DisputeGameFactory factory = new DisputeGameFactory{ salt: _implSalt() }(); - save("DisputeGameFactory", address(factory)); - console.log("DisputeGameFactory deployed at %s", address(factory)); + IDisputeGameFactory factory = IDisputeGameFactory(_deploy("DisputeGameFactory", hex"")); // Override the `DisputeGameFactory` contract to the deployed implementation. This is necessary to check the // `DisputeGameFactory` implementation alongside dependent contracts, which are always proxies. @@ -781,10 +777,7 @@ contract Deploy is Deployer { } function deployDelayedWETH() public broadcast returns (address addr_) { - console.log("Deploying DelayedWETH implementation"); - DelayedWETH weth = new DelayedWETH{ salt: _implSalt() }(cfg.faultGameWithdrawalDelay()); - save("DelayedWETH", address(weth)); - console.log("DelayedWETH deployed at %s", address(weth)); + IDelayedWETH weth = IDelayedWETH(payable(_deploy("DelayedWETH", abi.encode(cfg.faultGameWithdrawalDelay())))); // Override the `DelayedWETH` contract to the deployed implementation. This is necessary // to check the `DelayedWETH` implementation alongside dependent contracts, which are @@ -856,11 +849,8 @@ contract Deploy is Deployer { /// @notice Deploy the AnchorStateRegistry function deployAnchorStateRegistry() public broadcast returns (address addr_) { - console.log("Deploying AnchorStateRegistry implementation"); - AnchorStateRegistry anchorStateRegistry = - new AnchorStateRegistry{ salt: _implSalt() }(DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy"))); - save("AnchorStateRegistry", address(anchorStateRegistry)); - console.log("AnchorStateRegistry deployed at %s", address(anchorStateRegistry)); + IAnchorStateRegistry anchorStateRegistry = + IAnchorStateRegistry(_deploy("AnchorStateRegistry", abi.encode(mustGetAddress("DisputeGameFactoryProxy")))); addr_ = address(anchorStateRegistry); } @@ -958,10 +948,10 @@ contract Deploy is Deployer { _upgradeAndCallViaSafe({ _proxy: payable(disputeGameFactoryProxy), _implementation: disputeGameFactory, - _innerCallData: abi.encodeCall(DisputeGameFactory.initialize, (msg.sender)) + _innerCallData: abi.encodeCall(IDisputeGameFactory.initialize, (msg.sender)) }); - string memory version = DisputeGameFactory(disputeGameFactoryProxy).version(); + string memory version = IDisputeGameFactory(disputeGameFactoryProxy).version(); console.log("DisputeGameFactory version: %s", version); ChainAssertions.checkDisputeGameFactory({ _contracts: _proxiesUnstrict(), _expectedOwner: msg.sender }); @@ -976,10 +966,10 @@ contract Deploy is Deployer { _upgradeAndCallViaSafe({ _proxy: payable(delayedWETHProxy), _implementation: delayedWETH, - _innerCallData: abi.encodeCall(DelayedWETH.initialize, (msg.sender, ISuperchainConfig(superchainConfigProxy))) + _innerCallData: abi.encodeCall(IDelayedWETH.initialize, (msg.sender, ISuperchainConfig(superchainConfigProxy))) }); - string memory version = DelayedWETH(payable(delayedWETHProxy)).version(); + string memory version = IDelayedWETH(payable(delayedWETHProxy)).version(); console.log("DelayedWETH version: %s", version); ChainAssertions.checkDelayedWETH({ @@ -999,10 +989,10 @@ contract Deploy is Deployer { _upgradeAndCallViaSafe({ _proxy: payable(delayedWETHProxy), _implementation: delayedWETH, - _innerCallData: abi.encodeCall(DelayedWETH.initialize, (msg.sender, ISuperchainConfig(superchainConfigProxy))) + _innerCallData: abi.encodeCall(IDelayedWETH.initialize, (msg.sender, ISuperchainConfig(superchainConfigProxy))) }); - string memory version = DelayedWETH(payable(delayedWETHProxy)).version(); + string memory version = IDelayedWETH(payable(delayedWETHProxy)).version(); console.log("DelayedWETH version: %s", version); ChainAssertions.checkPermissionedDelayedWETH({ @@ -1019,36 +1009,36 @@ contract Deploy is Deployer { address anchorStateRegistry = mustGetAddress("AnchorStateRegistry"); ISuperchainConfig superchainConfig = ISuperchainConfig(mustGetAddress("SuperchainConfigProxy")); - AnchorStateRegistry.StartingAnchorRoot[] memory roots = new AnchorStateRegistry.StartingAnchorRoot[](5); - roots[0] = AnchorStateRegistry.StartingAnchorRoot({ + IAnchorStateRegistry.StartingAnchorRoot[] memory roots = new IAnchorStateRegistry.StartingAnchorRoot[](5); + roots[0] = IAnchorStateRegistry.StartingAnchorRoot({ gameType: GameTypes.CANNON, outputRoot: OutputRoot({ root: Hash.wrap(cfg.faultGameGenesisOutputRoot()), l2BlockNumber: cfg.faultGameGenesisBlock() }) }); - roots[1] = AnchorStateRegistry.StartingAnchorRoot({ + roots[1] = IAnchorStateRegistry.StartingAnchorRoot({ gameType: GameTypes.PERMISSIONED_CANNON, outputRoot: OutputRoot({ root: Hash.wrap(cfg.faultGameGenesisOutputRoot()), l2BlockNumber: cfg.faultGameGenesisBlock() }) }); - roots[2] = AnchorStateRegistry.StartingAnchorRoot({ + roots[2] = IAnchorStateRegistry.StartingAnchorRoot({ gameType: GameTypes.ALPHABET, outputRoot: OutputRoot({ root: Hash.wrap(cfg.faultGameGenesisOutputRoot()), l2BlockNumber: cfg.faultGameGenesisBlock() }) }); - roots[3] = AnchorStateRegistry.StartingAnchorRoot({ + roots[3] = IAnchorStateRegistry.StartingAnchorRoot({ gameType: GameTypes.ASTERISC, outputRoot: OutputRoot({ root: Hash.wrap(cfg.faultGameGenesisOutputRoot()), l2BlockNumber: cfg.faultGameGenesisBlock() }) }); - roots[4] = AnchorStateRegistry.StartingAnchorRoot({ + roots[4] = IAnchorStateRegistry.StartingAnchorRoot({ gameType: GameTypes.FAST, outputRoot: OutputRoot({ root: Hash.wrap(cfg.faultGameGenesisOutputRoot()), @@ -1059,10 +1049,10 @@ contract Deploy is Deployer { _upgradeAndCallViaSafe({ _proxy: payable(anchorStateRegistryProxy), _implementation: anchorStateRegistry, - _innerCallData: abi.encodeCall(AnchorStateRegistry.initialize, (roots, superchainConfig)) + _innerCallData: abi.encodeCall(IAnchorStateRegistry.initialize, (roots, superchainConfig)) }); - string memory version = AnchorStateRegistry(payable(anchorStateRegistryProxy)).version(); + string memory version = IAnchorStateRegistry(payable(anchorStateRegistryProxy)).version(); console.log("AnchorStateRegistry version: %s", version); } @@ -1331,7 +1321,7 @@ contract Deploy is Deployer { _innerCallData: abi.encodeCall( IOptimismPortal2.initialize, ( - DisputeGameFactory(disputeGameFactoryProxy), + IDisputeGameFactory(disputeGameFactoryProxy), ISystemConfig(systemConfigProxy), ISuperchainConfig(superchainConfigProxy), GameType.wrap(uint32(cfg.respectedGameType())) @@ -1378,7 +1368,7 @@ contract Deploy is Deployer { /// @notice Transfer ownership of the DisputeGameFactory contract to the final system owner function transferDisputeGameFactoryOwnership() public broadcast { console.log("Transferring DisputeGameFactory ownership to Safe"); - DisputeGameFactory disputeGameFactory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); + IDisputeGameFactory disputeGameFactory = IDisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); address owner = disputeGameFactory.owner(); address safe = mustGetAddress("SystemOwnerSafe"); @@ -1392,7 +1382,7 @@ contract Deploy is Deployer { /// @notice Transfer ownership of the DelayedWETH contract to the final system owner function transferDelayedWETHOwnership() public broadcast { console.log("Transferring DelayedWETH ownership to Safe"); - DelayedWETH weth = DelayedWETH(mustGetAddress("DelayedWETHProxy")); + IDelayedWETH weth = IDelayedWETH(mustGetAddress("DelayedWETHProxy")); address owner = weth.owner(); address safe = mustGetAddress("SystemOwnerSafe"); @@ -1406,7 +1396,7 @@ contract Deploy is Deployer { /// @notice Transfer ownership of the permissioned DelayedWETH contract to the final system owner function transferPermissionedDelayedWETHOwnership() public broadcast { console.log("Transferring permissioned DelayedWETH ownership to Safe"); - DelayedWETH weth = DelayedWETH(mustGetAddress("PermissionedDelayedWETHProxy")); + IDelayedWETH weth = IDelayedWETH(mustGetAddress("PermissionedDelayedWETHProxy")); address owner = weth.owner(); address safe = mustGetAddress("SystemOwnerSafe"); @@ -1483,15 +1473,15 @@ contract Deploy is Deployer { /// @notice Sets the implementation for the `CANNON` game type in the `DisputeGameFactory` function setCannonFaultGameImplementation(bool _allowUpgrade) public broadcast { console.log("Setting Cannon FaultDisputeGame implementation"); - DisputeGameFactory factory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); - DelayedWETH weth = DelayedWETH(mustGetAddress("DelayedWETHProxy")); + IDisputeGameFactory factory = IDisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); + IDelayedWETH weth = IDelayedWETH(mustGetAddress("DelayedWETHProxy")); // Set the Cannon FaultDisputeGame implementation in the factory. _setFaultGameImplementation({ _factory: factory, _allowUpgrade: _allowUpgrade, _params: FaultDisputeGameParams({ - anchorStateRegistry: AnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")), + anchorStateRegistry: IAnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")), weth: weth, gameType: GameTypes.CANNON, absolutePrestate: loadMipsAbsolutePrestate(), @@ -1505,15 +1495,15 @@ contract Deploy is Deployer { /// @notice Sets the implementation for the `PERMISSIONED_CANNON` game type in the `DisputeGameFactory` function setPermissionedCannonFaultGameImplementation(bool _allowUpgrade) public broadcast { console.log("Setting Cannon PermissionedDisputeGame implementation"); - DisputeGameFactory factory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); - DelayedWETH weth = DelayedWETH(mustGetAddress("PermissionedDelayedWETHProxy")); + IDisputeGameFactory factory = IDisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); + IDelayedWETH weth = IDelayedWETH(mustGetAddress("PermissionedDelayedWETHProxy")); // Set the Cannon FaultDisputeGame implementation in the factory. _setFaultGameImplementation({ _factory: factory, _allowUpgrade: _allowUpgrade, _params: FaultDisputeGameParams({ - anchorStateRegistry: AnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")), + anchorStateRegistry: IAnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")), weth: weth, gameType: GameTypes.PERMISSIONED_CANNON, absolutePrestate: loadMipsAbsolutePrestate(), @@ -1527,15 +1517,15 @@ contract Deploy is Deployer { /// @notice Sets the implementation for the `ALPHABET` game type in the `DisputeGameFactory` function setAlphabetFaultGameImplementation(bool _allowUpgrade) public onlyDevnet broadcast { console.log("Setting Alphabet FaultDisputeGame implementation"); - DisputeGameFactory factory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); - DelayedWETH weth = DelayedWETH(mustGetAddress("DelayedWETHProxy")); + IDisputeGameFactory factory = IDisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); + IDelayedWETH weth = IDelayedWETH(mustGetAddress("DelayedWETHProxy")); Claim outputAbsolutePrestate = Claim.wrap(bytes32(cfg.faultGameAbsolutePrestate())); _setFaultGameImplementation({ _factory: factory, _allowUpgrade: _allowUpgrade, _params: FaultDisputeGameParams({ - anchorStateRegistry: AnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")), + anchorStateRegistry: IAnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")), weth: weth, gameType: GameTypes.ALPHABET, absolutePrestate: outputAbsolutePrestate, @@ -1550,8 +1540,8 @@ contract Deploy is Deployer { /// @notice Sets the implementation for the `ALPHABET` game type in the `DisputeGameFactory` function setFastFaultGameImplementation(bool _allowUpgrade) public onlyDevnet broadcast { console.log("Setting Fast FaultDisputeGame implementation"); - DisputeGameFactory factory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); - DelayedWETH weth = DelayedWETH(mustGetAddress("DelayedWETHProxy")); + IDisputeGameFactory factory = IDisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); + IDelayedWETH weth = IDelayedWETH(mustGetAddress("DelayedWETHProxy")); Claim outputAbsolutePrestate = Claim.wrap(bytes32(cfg.faultGameAbsolutePrestate())); PreimageOracle fastOracle = new PreimageOracle(cfg.preimageOracleMinProposalSize(), 0); @@ -1559,7 +1549,7 @@ contract Deploy is Deployer { _factory: factory, _allowUpgrade: _allowUpgrade, _params: FaultDisputeGameParams({ - anchorStateRegistry: AnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")), + anchorStateRegistry: IAnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")), weth: weth, gameType: GameTypes.FAST, absolutePrestate: outputAbsolutePrestate, @@ -1573,7 +1563,7 @@ contract Deploy is Deployer { /// @notice Sets the implementation for the given fault game type in the `DisputeGameFactory`. function _setFaultGameImplementation( - DisputeGameFactory _factory, + IDisputeGameFactory _factory, bool _allowUpgrade, FaultDisputeGameParams memory _params ) @@ -1591,36 +1581,47 @@ contract Deploy is Deployer { if (rawGameType != GameTypes.PERMISSIONED_CANNON.raw()) { _factory.setImplementation( _params.gameType, - new FaultDisputeGame({ - _gameType: _params.gameType, - _absolutePrestate: _params.absolutePrestate, - _maxGameDepth: _params.maxGameDepth, - _splitDepth: cfg.faultGameSplitDepth(), - _clockExtension: Duration.wrap(uint64(cfg.faultGameClockExtension())), - _maxClockDuration: _params.maxClockDuration, - _vm: _params.faultVm, - _weth: _params.weth, - _anchorStateRegistry: _params.anchorStateRegistry, - _l2ChainId: cfg.l2ChainID() - }) + IDisputeGame( + _deploy( + "FaultDisputeGame", + string.concat("FaultDisputeGame_", vm.toString(rawGameType)), + abi.encode( + _params.gameType, + _params.absolutePrestate, + _params.maxGameDepth, + cfg.faultGameSplitDepth(), + cfg.faultGameClockExtension(), + _params.maxClockDuration, + _params.faultVm, + _params.weth, + IAnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")), + cfg.l2ChainID() + ) + ) + ) ); } else { _factory.setImplementation( _params.gameType, - new PermissionedDisputeGame({ - _gameType: _params.gameType, - _absolutePrestate: _params.absolutePrestate, - _maxGameDepth: _params.maxGameDepth, - _splitDepth: cfg.faultGameSplitDepth(), - _clockExtension: Duration.wrap(uint64(cfg.faultGameClockExtension())), - _maxClockDuration: Duration.wrap(uint64(cfg.faultGameMaxClockDuration())), - _vm: _params.faultVm, - _weth: _params.weth, - _anchorStateRegistry: _params.anchorStateRegistry, - _l2ChainId: cfg.l2ChainID(), - _proposer: cfg.l2OutputOracleProposer(), - _challenger: cfg.l2OutputOracleChallenger() - }) + IDisputeGame( + _deploy( + "PermissionedDisputeGame", + abi.encode( + _params.gameType, + _params.absolutePrestate, + _params.maxGameDepth, + cfg.faultGameSplitDepth(), + cfg.faultGameClockExtension(), + _params.maxClockDuration, + _params.faultVm, + _params.weth, + _params.anchorStateRegistry, + cfg.l2ChainID(), + cfg.l2OutputOracleProposer(), + cfg.l2OutputOracleChallenger() + ) + ) + ) ); } @@ -1678,7 +1679,22 @@ contract Deploy is Deployer { /// @param _name The name of the contract. /// @param _constructorParams The constructor parameters. function _deploy(string memory _name, bytes memory _constructorParams) internal returns (address addr_) { - console.log("Deploying %s", _name); + return _deploy(_name, _name, _constructorParams); + } + + /// @notice Deploys a contract via CREATE2. + /// @param _name The name of the contract. + /// @param _nickname The nickname of the contract. + /// @param _constructorParams The constructor parameters. + function _deploy( + string memory _name, + string memory _nickname, + bytes memory _constructorParams + ) + internal + returns (address addr_) + { + console.log("Deploying %s", _nickname); bytes32 salt = _implSalt(); bytes memory initCode = abi.encodePacked(vm.getCode(_name), _constructorParams); address preComputedAddress = vm.computeCreate2Address(salt, keccak256(initCode)); @@ -1687,7 +1703,7 @@ contract Deploy is Deployer { addr_ := create2(0, add(initCode, 0x20), mload(initCode), salt) } require(addr_ != address(0), "deployment failed"); - save(_name, addr_); - console.log("%s deployed at %s", _name, addr_); + save(_nickname, addr_); + console.log("%s deployed at %s", _nickname, addr_); } } diff --git a/packages/contracts-bedrock/scripts/fpac/FPACOPS.s.sol b/packages/contracts-bedrock/scripts/fpac/FPACOPS.s.sol index cc00d1a8c866..2dc07b525bd0 100644 --- a/packages/contracts-bedrock/scripts/fpac/FPACOPS.s.sol +++ b/packages/contracts-bedrock/scripts/fpac/FPACOPS.s.sol @@ -1,13 +1,22 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Scripts +import { StdAssertions } from "forge-std/StdAssertions.sol"; +import "scripts/deploy/Deploy.s.sol"; + +// Contracts import { Proxy } from "src/universal/Proxy.sol"; + +// Libraries +import "src/dispute/lib/Types.sol"; + +// Interfaces import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; -import { AnchorStateRegistry, IAnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; +import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; -import { StdAssertions } from "forge-std/StdAssertions.sol"; -import "src/dispute/lib/Types.sol"; -import "scripts/deploy/Deploy.s.sol"; +import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; +import { IPermissionedDisputeGame } from "src/dispute/interfaces/IPermissionedDisputeGame.sol"; /// @notice Deploys the Fault Proof Alpha Chad contracts. contract FPACOPS is Deploy, StdAssertions { @@ -70,11 +79,11 @@ contract FPACOPS is Deploy, StdAssertions { address dgfProxy = mustGetAddress("DisputeGameFactoryProxy"); Proxy(payable(dgfProxy)).upgradeToAndCall( - mustGetAddress("DisputeGameFactory"), abi.encodeCall(DisputeGameFactory.initialize, msg.sender) + mustGetAddress("DisputeGameFactory"), abi.encodeCall(IDisputeGameFactory.initialize, msg.sender) ); // Set the initialization bonds for the FaultDisputeGame and PermissionedDisputeGame. - DisputeGameFactory dgf = DisputeGameFactory(dgfProxy); + IDisputeGameFactory dgf = IDisputeGameFactory(dgfProxy); dgf.setInitBond(GameTypes.CANNON, 0.08 ether); dgf.setInitBond(GameTypes.PERMISSIONED_CANNON, 0.08 ether); } @@ -86,7 +95,7 @@ contract FPACOPS is Deploy, StdAssertions { address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy"); Proxy(payable(wethProxy)).upgradeToAndCall( mustGetAddress("DelayedWETH"), - abi.encodeCall(DelayedWETH.initialize, (msg.sender, ISuperchainConfig(superchainConfigProxy))) + abi.encodeCall(IDelayedWETH.initialize, (msg.sender, ISuperchainConfig(superchainConfigProxy))) ); } @@ -95,15 +104,15 @@ contract FPACOPS is Deploy, StdAssertions { address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy"); ISuperchainConfig superchainConfig = ISuperchainConfig(superchainConfigProxy); - AnchorStateRegistry.StartingAnchorRoot[] memory roots = new AnchorStateRegistry.StartingAnchorRoot[](2); - roots[0] = AnchorStateRegistry.StartingAnchorRoot({ + IAnchorStateRegistry.StartingAnchorRoot[] memory roots = new IAnchorStateRegistry.StartingAnchorRoot[](2); + roots[0] = IAnchorStateRegistry.StartingAnchorRoot({ gameType: GameTypes.CANNON, outputRoot: OutputRoot({ root: Hash.wrap(cfg.faultGameGenesisOutputRoot()), l2BlockNumber: cfg.faultGameGenesisBlock() }) }); - roots[1] = AnchorStateRegistry.StartingAnchorRoot({ + roots[1] = IAnchorStateRegistry.StartingAnchorRoot({ gameType: GameTypes.PERMISSIONED_CANNON, outputRoot: OutputRoot({ root: Hash.wrap(cfg.faultGameGenesisOutputRoot()), @@ -114,14 +123,14 @@ contract FPACOPS is Deploy, StdAssertions { address asrProxy = mustGetAddress("AnchorStateRegistryProxy"); Proxy(payable(asrProxy)).upgradeToAndCall( mustGetAddress("AnchorStateRegistry"), - abi.encodeCall(AnchorStateRegistry.initialize, (roots, superchainConfig)) + abi.encodeCall(IAnchorStateRegistry.initialize, (roots, superchainConfig)) ); } /// @notice Transfers admin rights of the `DisputeGameFactoryProxy` to the `ProxyAdmin` and sets the /// `DisputeGameFactory` owner to the `SystemOwnerSafe`. function transferDGFOwnershipFinal(address _proxyAdmin, address _systemOwnerSafe) internal broadcast { - DisputeGameFactory dgf = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); + IDisputeGameFactory dgf = IDisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); // Transfer the ownership of the DisputeGameFactory to the SystemOwnerSafe. dgf.transferOwnership(_systemOwnerSafe); @@ -134,7 +143,7 @@ contract FPACOPS is Deploy, StdAssertions { /// @notice Transfers admin rights of the `DelayedWETHProxy` to the `ProxyAdmin` and sets the /// `DelayedWETH` owner to the `SystemOwnerSafe`. function transferWethOwnershipFinal(address _proxyAdmin, address _systemOwnerSafe) internal broadcast { - DelayedWETH weth = DelayedWETH(mustGetAddress("DelayedWETHProxy")); + IDelayedWETH weth = IDelayedWETH(mustGetAddress("DelayedWETHProxy")); // Transfer the ownership of the DelayedWETH to the SystemOwnerSafe. weth.transferOwnership(_systemOwnerSafe); @@ -146,7 +155,7 @@ contract FPACOPS is Deploy, StdAssertions { /// @notice Transfers admin rights of the `AnchorStateRegistryProxy` to the `ProxyAdmin`. function transferAnchorStateOwnershipFinal(address _proxyAdmin) internal broadcast { - AnchorStateRegistry asr = AnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")); + IAnchorStateRegistry asr = IAnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")); // Transfer the admin rights of the AnchorStateRegistryProxy to the ProxyAdmin. Proxy prox = Proxy(payable(address(asr))); @@ -163,7 +172,7 @@ contract FPACOPS is Deploy, StdAssertions { // Ensure the contracts are owned by the correct entities. address dgfProxyAddr = mustGetAddress("DisputeGameFactoryProxy"); - DisputeGameFactory dgfProxy = DisputeGameFactory(dgfProxyAddr); + IDisputeGameFactory dgfProxy = IDisputeGameFactory(dgfProxyAddr); assertEq(address(uint160(uint256(vm.load(dgfProxyAddr, Constants.PROXY_OWNER_ADDRESS)))), _proxyAdmin); ChainAssertions.checkDisputeGameFactory(contracts, _systemOwnerSafe); address wethProxyAddr = mustGetAddress("DelayedWETHProxy"); @@ -181,7 +190,7 @@ contract FPACOPS is Deploy, StdAssertions { assertEq(address(mips.oracle()), address(oracle)); // Check the AnchorStateRegistry configuration. - AnchorStateRegistry asr = AnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")); + IAnchorStateRegistry asr = IAnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")); (Hash root1, uint256 l2BlockNumber1) = asr.anchors(GameTypes.CANNON); (Hash root2, uint256 l2BlockNumber2) = asr.anchors(GameTypes.PERMISSIONED_CANNON); assertEq(root1.raw(), cfg.faultGameGenesisOutputRoot()); @@ -190,7 +199,7 @@ contract FPACOPS is Deploy, StdAssertions { assertEq(l2BlockNumber2, cfg.faultGameGenesisBlock()); // Check the FaultDisputeGame configuration. - FaultDisputeGame gameImpl = FaultDisputeGame(payable(address(dgfProxy.gameImpls(GameTypes.CANNON)))); + IFaultDisputeGame gameImpl = IFaultDisputeGame(payable(address(dgfProxy.gameImpls(GameTypes.CANNON)))); assertEq(gameImpl.maxGameDepth(), cfg.faultGameMaxDepth()); assertEq(gameImpl.splitDepth(), cfg.faultGameSplitDepth()); assertEq(gameImpl.clockExtension().raw(), cfg.faultGameClockExtension()); @@ -201,8 +210,8 @@ contract FPACOPS is Deploy, StdAssertions { assertEq(address(gameImpl.vm()), address(mips)); // Check the security override yoke configuration. - PermissionedDisputeGame soyGameImpl = - PermissionedDisputeGame(payable(address(dgfProxy.gameImpls(GameTypes.PERMISSIONED_CANNON)))); + IPermissionedDisputeGame soyGameImpl = + IPermissionedDisputeGame(payable(address(dgfProxy.gameImpls(GameTypes.PERMISSIONED_CANNON)))); assertEq(soyGameImpl.proposer(), cfg.l2OutputOracleProposer()); assertEq(soyGameImpl.challenger(), cfg.l2OutputOracleChallenger()); assertEq(soyGameImpl.maxGameDepth(), cfg.faultGameMaxDepth()); diff --git a/packages/contracts-bedrock/scripts/fpac/FPACOPS2.s.sol b/packages/contracts-bedrock/scripts/fpac/FPACOPS2.s.sol index 4d5f3e4d9af3..0f5962a50d02 100644 --- a/packages/contracts-bedrock/scripts/fpac/FPACOPS2.s.sol +++ b/packages/contracts-bedrock/scripts/fpac/FPACOPS2.s.sol @@ -1,13 +1,22 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Scripts +import { StdAssertions } from "forge-std/StdAssertions.sol"; +import "scripts/deploy/Deploy.s.sol"; + +// Contracts import { Proxy } from "src/universal/Proxy.sol"; + +// Libraries +import "src/dispute/lib/Types.sol"; + +// Interfaces import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; -import { AnchorStateRegistry, IAnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; +import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; -import { StdAssertions } from "forge-std/StdAssertions.sol"; -import "src/dispute/lib/Types.sol"; -import "scripts/deploy/Deploy.s.sol"; +import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; +import { IPermissionedDisputeGame } from "src/dispute/interfaces/IPermissionedDisputeGame.sol"; /// @notice Deploys new implementations of the FaultDisputeGame contract and its dependencies /// assuming that the DisputeGameFactory contract does not need to be modified. Assumes @@ -85,18 +94,21 @@ contract FPACOPS2 is Deploy, StdAssertions { save( "CannonFaultDisputeGame", address( - new FaultDisputeGame({ - _gameType: GameTypes.CANNON, - _absolutePrestate: loadMipsAbsolutePrestate(), - _maxGameDepth: cfg.faultGameMaxDepth(), - _splitDepth: cfg.faultGameSplitDepth(), - _clockExtension: Duration.wrap(uint64(cfg.faultGameClockExtension())), - _maxClockDuration: Duration.wrap(uint64(cfg.faultGameMaxClockDuration())), - _vm: IBigStepper(mustGetAddress("Mips")), - _weth: DelayedWETH(mustGetAddress("DelayedWETHProxy")), - _anchorStateRegistry: AnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")), - _l2ChainId: cfg.l2ChainID() - }) + _deploy( + "FaultDisputeGame", + abi.encode( + GameTypes.CANNON, + loadMipsAbsolutePrestate(), + cfg.faultGameMaxDepth(), + cfg.faultGameSplitDepth(), + Duration.wrap(uint64(cfg.faultGameClockExtension())), + Duration.wrap(uint64(cfg.faultGameMaxClockDuration())), + IBigStepper(mustGetAddress("Mips")), + IDelayedWETH(mustGetAddress("DelayedWETHProxy")), + IAnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")), + cfg.l2ChainID() + ) + ) ) ); } @@ -108,20 +120,23 @@ contract FPACOPS2 is Deploy, StdAssertions { save( "PermissionedDisputeGame", address( - new PermissionedDisputeGame({ - _gameType: GameTypes.PERMISSIONED_CANNON, - _absolutePrestate: loadMipsAbsolutePrestate(), - _maxGameDepth: cfg.faultGameMaxDepth(), - _splitDepth: cfg.faultGameSplitDepth(), - _clockExtension: Duration.wrap(uint64(cfg.faultGameClockExtension())), - _maxClockDuration: Duration.wrap(uint64(cfg.faultGameMaxClockDuration())), - _vm: IBigStepper(mustGetAddress("Mips")), - _weth: DelayedWETH(mustGetAddress("PermissionedDelayedWETHProxy")), - _anchorStateRegistry: AnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")), - _l2ChainId: cfg.l2ChainID(), - _proposer: cfg.l2OutputOracleProposer(), - _challenger: cfg.l2OutputOracleChallenger() - }) + _deploy( + "PermissionedDisputeGame", + abi.encode( + GameTypes.PERMISSIONED_CANNON, + loadMipsAbsolutePrestate(), + cfg.faultGameMaxDepth(), + cfg.faultGameSplitDepth(), + Duration.wrap(uint64(cfg.faultGameClockExtension())), + Duration.wrap(uint64(cfg.faultGameMaxClockDuration())), + IBigStepper(mustGetAddress("Mips")), + IDelayedWETH(mustGetAddress("PermissionedDelayedWETHProxy")), + IAnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")), + cfg.l2ChainID(), + cfg.l2OutputOracleProposer(), + cfg.l2OutputOracleChallenger() + ) + ) ) ); } @@ -134,7 +149,7 @@ contract FPACOPS2 is Deploy, StdAssertions { address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy"); Proxy(payable(wethProxy)).upgradeToAndCall( mustGetAddress("DelayedWETH"), - abi.encodeCall(DelayedWETH.initialize, (msg.sender, ISuperchainConfig(superchainConfigProxy))) + abi.encodeCall(IDelayedWETH.initialize, (msg.sender, ISuperchainConfig(superchainConfigProxy))) ); } @@ -146,7 +161,7 @@ contract FPACOPS2 is Deploy, StdAssertions { address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy"); Proxy(payable(wethProxy)).upgradeToAndCall( mustGetAddress("DelayedWETH"), - abi.encodeCall(DelayedWETH.initialize, (msg.sender, ISuperchainConfig(superchainConfigProxy))) + abi.encodeCall(IDelayedWETH.initialize, (msg.sender, ISuperchainConfig(superchainConfigProxy))) ); } @@ -155,7 +170,7 @@ contract FPACOPS2 is Deploy, StdAssertions { function transferWethOwnershipFinal(address _proxyAdmin, address _systemOwnerSafe) internal broadcast { console.log("Transferring ownership of DelayedWETHProxy"); - DelayedWETH weth = DelayedWETH(mustGetAddress("DelayedWETHProxy")); + IDelayedWETH weth = IDelayedWETH(mustGetAddress("DelayedWETHProxy")); // Transfer the ownership of the DelayedWETH to the SystemOwnerSafe. weth.transferOwnership(_systemOwnerSafe); @@ -170,7 +185,7 @@ contract FPACOPS2 is Deploy, StdAssertions { function transferPermissionedWETHOwnershipFinal(address _proxyAdmin, address _systemOwnerSafe) internal broadcast { console.log("Transferring ownership of permissioned DelayedWETHProxy"); - DelayedWETH weth = DelayedWETH(mustGetAddress("PermissionedDelayedWETHProxy")); + IDelayedWETH weth = IDelayedWETH(mustGetAddress("PermissionedDelayedWETHProxy")); // Transfer the ownership of the DelayedWETH to the SystemOwnerSafe. weth.transferOwnership(_systemOwnerSafe); @@ -214,11 +229,11 @@ contract FPACOPS2 is Deploy, StdAssertions { assertEq(address(mips.oracle()), address(oracle)); // Grab ASR - AnchorStateRegistry asr = AnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")); + IAnchorStateRegistry asr = IAnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")); // Verify FaultDisputeGame configuration. address gameAddr = mustGetAddress("CannonFaultDisputeGame"); - FaultDisputeGame gameImpl = FaultDisputeGame(payable(gameAddr)); + IFaultDisputeGame gameImpl = IFaultDisputeGame(payable(gameAddr)); assertEq(gameImpl.maxGameDepth(), cfg.faultGameMaxDepth()); assertEq(gameImpl.splitDepth(), cfg.faultGameSplitDepth()); assertEq(gameImpl.clockExtension().raw(), cfg.faultGameClockExtension()); @@ -230,7 +245,7 @@ contract FPACOPS2 is Deploy, StdAssertions { // Verify security override yoke configuration. address soyGameAddr = mustGetAddress("PermissionedDisputeGame"); - PermissionedDisputeGame soyGameImpl = PermissionedDisputeGame(payable(soyGameAddr)); + IPermissionedDisputeGame soyGameImpl = IPermissionedDisputeGame(payable(soyGameAddr)); assertEq(soyGameImpl.proposer(), cfg.l2OutputOracleProposer()); assertEq(soyGameImpl.challenger(), cfg.l2OutputOracleChallenger()); assertEq(soyGameImpl.maxGameDepth(), cfg.faultGameMaxDepth()); diff --git a/packages/contracts-bedrock/scripts/fpac/viz/FaultDisputeGameViz.s.sol b/packages/contracts-bedrock/scripts/fpac/viz/FaultDisputeGameViz.s.sol index f03897dd0c26..2e0dd45e4ebe 100644 --- a/packages/contracts-bedrock/scripts/fpac/viz/FaultDisputeGameViz.s.sol +++ b/packages/contracts-bedrock/scripts/fpac/viz/FaultDisputeGameViz.s.sol @@ -1,18 +1,21 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.15; +// Testing +import { FaultDisputeGame_Init } from "test/dispute/FaultDisputeGame.t.sol"; + +// Scripts import { Script } from "forge-std/Script.sol"; import { console2 as console } from "forge-std/console2.sol"; - -import { FaultDisputeGame_Init } from "test/dispute/FaultDisputeGame.t.sol"; -import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; -import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; -import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; import { Process } from "scripts/libraries/Process.sol"; +// Libraries import "src/dispute/lib/Types.sol"; import "src/dispute/lib/Errors.sol"; +// Interfaces +import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; + /** * @title FaultDisputeGameViz * @dev To run this script, make sure to install the `dagviz` & `eth_abi` python packages. @@ -43,7 +46,7 @@ contract FaultDisputeGameViz is Script, FaultDisputeGame_Init { * @dev Entry point */ function remote(address _addr) public { - gameProxy = FaultDisputeGame(payable(_addr)); + gameProxy = IFaultDisputeGame(payable(_addr)); buildGraph(); console.log("Saved graph to `./dispute_game.svg"); } diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 7aa4b286383c..91897e737ccf 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -152,20 +152,20 @@ "sourceCodeHash": "0xdb9421a552e6d7581b3db9e4c2a02d8210ad6ca66ba0f8703d77f7cd4b8e132b" }, "src/dispute/AnchorStateRegistry.sol": { - "initCodeHash": "0x73a094f7d00422c8a765a63f4645f9e2fb508655181f227fd9b338c62c26e106", - "sourceCodeHash": "0x7ed9631efb6f5cdec9fb09bc22f0e6248314db6331ed65f0baa462b230733b88" + "initCodeHash": "0x13d00eef8c3f769863fc766180acc8586f5da309ca0a098e67d4d90bd3243341", + "sourceCodeHash": "0x39a23c91d4c5380d285f49660b858d39f3fa27bdbfbc72e0e14587e7c57dfae9" }, "src/dispute/DelayedWETH.sol": { - "initCodeHash": "0xbda8166b77517df1df1dcef7c307c11a5520188f83555aec9439f6887c419dd0", - "sourceCodeHash": "0x70192d1eae4e16f791d826edf75a825246136fe5f8645b066a401b1dfee3e38c" + "initCodeHash": "0x835b322de7d5c84b415e99f2cb1000411df18995b5476f2116ac6f897f2d0910", + "sourceCodeHash": "0xdbd64724b73f8f9d6f1cc72bb662a99b9955ab72950a8f6ffeb1d2454997f60b" }, "src/dispute/DisputeGameFactory.sol": { - "initCodeHash": "0xc1a10f65287c414076b68a7de6c238b91bc6252213187bdef35657d0f00f9382", - "sourceCodeHash": "0x3d391c58420abe60d8486136a57d7f9c7137f722c80a8d884305617eb31566ef" + "initCodeHash": "0xb91623cca41e63e6e5a75c681b0d9ef7cb8bf68e7ff5e202a217629899fae099", + "sourceCodeHash": "0xc8f21c777b2c5a37c2d2f92e8eeceba3b231b500a7d9cb0b607b774478f8be6b" }, "src/dispute/FaultDisputeGame.sol": { - "initCodeHash": "0x0084ca38e6ceb3c70ce77ef9769a724e8be5b92457222ef2b09c63bb4b449bf2", - "sourceCodeHash": "0xf199eace79690c010d0f252819e62ef7ad165d9af19c1ee47a6aa451cda259b2" + "initCodeHash": "0xdb724dfd12dcea804d1adbc5a7e919625615c62b940035cf4b9115ea3a63e0ae", + "sourceCodeHash": "0x223428ee91532af397cef72356430ff59221e0ac0cbf697a881d36bb1d672392" }, "src/legacy/DeployerWhitelist.sol": { "initCodeHash": "0x0b8177ed75b69eddbb9ce6537683f69a9935efed86a1d6faa8feaafbd151c1bd", @@ -196,8 +196,8 @@ "sourceCodeHash": "0x3a0a294932d6deba043f6a2b46b4e8477ee96e7fb054d7e7229a43ce4352c68d" }, "src/safe/DeputyGuardianModule.sol": { - "initCodeHash": "0x785cb529957f4d42d1659f2c37967dce7c621f3c6e06550600897205c2551a88", - "sourceCodeHash": "0xc8df2c0ae90cff18ddd4d2b8e2d44689e3c4c98e96c746c4ee9baaebf6a80ec4" + "initCodeHash": "0x308212d163aad169a5e42ce703a1ce36f5425ad96037850c0747177041f6596e", + "sourceCodeHash": "0xde1a289c1cb0bf92138daf8f3db7457be2f84bedaa111b536f646dd6e121718c" }, "src/safe/LivenessGuard.sol": { "initCodeHash": "0xfd74ff89e7b689b38ab97515d64429ffaf6c0cd1ea6488c6a4743a0665419c85", diff --git a/packages/contracts-bedrock/snapshots/abi/DeputyGuardianModule.json b/packages/contracts-bedrock/snapshots/abi/DeputyGuardianModule.json index 6e5c45fc3d8a..f1006749351e 100644 --- a/packages/contracts-bedrock/snapshots/abi/DeputyGuardianModule.json +++ b/packages/contracts-bedrock/snapshots/abi/DeputyGuardianModule.json @@ -74,7 +74,7 @@ { "inputs": [ { - "internalType": "contract AnchorStateRegistry", + "internalType": "contract IAnchorStateRegistry", "name": "_registry", "type": "address" }, diff --git a/packages/contracts-bedrock/snapshots/abi/DisputeGameFactory.json b/packages/contracts-bedrock/snapshots/abi/DisputeGameFactory.json index d4ae9165f9d7..205b9861d18b 100644 --- a/packages/contracts-bedrock/snapshots/abi/DisputeGameFactory.json +++ b/packages/contracts-bedrock/snapshots/abi/DisputeGameFactory.json @@ -81,7 +81,7 @@ "type": "bytes" } ], - "internalType": "struct IDisputeGameFactory.GameSearchResult[]", + "internalType": "struct DisputeGameFactory.GameSearchResult[]", "name": "games_", "type": "tuple[]" } diff --git a/packages/contracts-bedrock/snapshots/storageLayout/DelayedWETH.json b/packages/contracts-bedrock/snapshots/storageLayout/DelayedWETH.json index b20b276476e9..4e8b771cd9bb 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/DelayedWETH.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/DelayedWETH.json @@ -53,7 +53,7 @@ "label": "withdrawals", "offset": 0, "slot": "103", - "type": "mapping(address => mapping(address => struct IDelayedWETH.WithdrawalRequest))" + "type": "mapping(address => mapping(address => struct DelayedWETH.WithdrawalRequest))" }, { "bytes": "20", diff --git a/packages/contracts-bedrock/snapshots/storageLayout/FaultDisputeGame.json b/packages/contracts-bedrock/snapshots/storageLayout/FaultDisputeGame.json index f87fa588ed9c..ec02f23d2e6d 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/FaultDisputeGame.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/FaultDisputeGame.json @@ -46,7 +46,7 @@ "label": "claimData", "offset": 0, "slot": "2", - "type": "struct IFaultDisputeGame.ClaimData[]" + "type": "struct FaultDisputeGame.ClaimData[]" }, { "bytes": "32", @@ -81,7 +81,7 @@ "label": "resolutionCheckpoints", "offset": 0, "slot": "7", - "type": "mapping(uint256 => struct IFaultDisputeGame.ResolutionCheckpoint)" + "type": "mapping(uint256 => struct FaultDisputeGame.ResolutionCheckpoint)" }, { "bytes": "64", diff --git a/packages/contracts-bedrock/snapshots/storageLayout/PermissionedDisputeGame.json b/packages/contracts-bedrock/snapshots/storageLayout/PermissionedDisputeGame.json index f87fa588ed9c..ec02f23d2e6d 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/PermissionedDisputeGame.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/PermissionedDisputeGame.json @@ -46,7 +46,7 @@ "label": "claimData", "offset": 0, "slot": "2", - "type": "struct IFaultDisputeGame.ClaimData[]" + "type": "struct FaultDisputeGame.ClaimData[]" }, { "bytes": "32", @@ -81,7 +81,7 @@ "label": "resolutionCheckpoints", "offset": 0, "slot": "7", - "type": "mapping(uint256 => struct IFaultDisputeGame.ResolutionCheckpoint)" + "type": "mapping(uint256 => struct FaultDisputeGame.ResolutionCheckpoint)" }, { "bytes": "64", diff --git a/packages/contracts-bedrock/src/L2/interfaces/IL1BlockIsthmus.sol b/packages/contracts-bedrock/src/L2/interfaces/IL1BlockIsthmus.sol index a622a1fa3fee..7ff15eda51b0 100644 --- a/packages/contracts-bedrock/src/L2/interfaces/IL1BlockIsthmus.sol +++ b/packages/contracts-bedrock/src/L2/interfaces/IL1BlockIsthmus.sol @@ -1,9 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -interface IL1BlockIsthmus { - type ConfigType is uint8; +enum ConfigType { + SET_GAS_PAYING_TOKEN, + ADD_DEPENDENCY, + REMOVE_DEPENDENCY +} +interface IL1BlockIsthmus { error AlreadyDependency(); error CantRemovedDependency(); error DependencySetSizeTooLarge(); diff --git a/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol b/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol index 1f238e29ac8b..5486d83f7684 100644 --- a/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol +++ b/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol @@ -1,26 +1,28 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Contracts import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; -import { ISemver } from "src/universal/interfaces/ISemver.sol"; -import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; +// Libraries +import "src/dispute/lib/Types.sol"; +import { Unauthorized } from "src/libraries/errors/CommonErrors.sol"; +import { UnregisteredGame, InvalidGameStatus } from "src/dispute/lib/Errors.sol"; + +// Interfaces +import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; -import "src/dispute/lib/Types.sol"; -import { Unauthorized } from "src/libraries/errors/CommonErrors.sol"; -import { UnregisteredGame, InvalidGameStatus } from "src/dispute/lib/Errors.sol"; - /// @custom:proxied true /// @title AnchorStateRegistry /// @notice The AnchorStateRegistry is a contract that stores the latest "anchor" state for each available /// FaultDisputeGame type. The anchor state is the latest state that has been proposed on L1 and was not /// challenged within the challenge period. By using stored anchor states, new FaultDisputeGame instances can /// be initialized with a more recent starting state which reduces the amount of required offchain computation. -contract AnchorStateRegistry is Initializable, IAnchorStateRegistry, ISemver { +contract AnchorStateRegistry is Initializable, ISemver { /// @notice Describes an initial anchor state for a game type. struct StartingAnchorRoot { GameType gameType; @@ -28,13 +30,13 @@ contract AnchorStateRegistry is Initializable, IAnchorStateRegistry, ISemver { } /// @notice Semantic version. - /// @custom:semver 2.0.1-beta.2 - string public constant version = "2.0.1-beta.2"; + /// @custom:semver 2.0.1-beta.3 + string public constant version = "2.0.1-beta.3"; /// @notice DisputeGameFactory address. IDisputeGameFactory internal immutable DISPUTE_GAME_FACTORY; - /// @inheritdoc IAnchorStateRegistry + /// @notice Returns the anchor state for the given game type. mapping(GameType => OutputRoot) public anchors; /// @notice Address of the SuperchainConfig contract. @@ -63,12 +65,15 @@ contract AnchorStateRegistry is Initializable, IAnchorStateRegistry, ISemver { superchainConfig = _superchainConfig; } - /// @inheritdoc IAnchorStateRegistry + /// @notice Returns the DisputeGameFactory address. + /// @return DisputeGameFactory address. function disputeGameFactory() external view returns (IDisputeGameFactory) { return DISPUTE_GAME_FACTORY; } - /// @inheritdoc IAnchorStateRegistry + /// @notice Callable by FaultDisputeGame contracts to update the anchor state. Pulls the anchor state directly from + /// the FaultDisputeGame contract and stores it in the registry if the new anchor state is valid and the + /// state is newer than the current anchor state. function tryUpdateAnchorState() external { // Grab the game and game data. IFaultDisputeGame game = IFaultDisputeGame(msg.sender); @@ -96,7 +101,8 @@ contract AnchorStateRegistry is Initializable, IAnchorStateRegistry, ISemver { anchors[gameType] = OutputRoot({ l2BlockNumber: game.l2BlockNumber(), root: Hash.wrap(game.rootClaim().raw()) }); } - /// @inheritdoc IAnchorStateRegistry + /// @notice Sets the anchor state given the game. + /// @param _game The game to set the anchor state for. function setAnchorState(IFaultDisputeGame _game) external { if (msg.sender != superchainConfig.guardian()) revert Unauthorized(); diff --git a/packages/contracts-bedrock/src/dispute/DelayedWETH.sol b/packages/contracts-bedrock/src/dispute/DelayedWETH.sol index d86159c03fa8..42b6022d12fe 100644 --- a/packages/contracts-bedrock/src/dispute/DelayedWETH.sol +++ b/packages/contracts-bedrock/src/dispute/DelayedWETH.sol @@ -7,8 +7,6 @@ import { WETH98 } from "src/universal/WETH98.sol"; // Interfaces import { ISemver } from "src/universal/interfaces/ISemver.sol"; -import { IWETH } from "src/universal/interfaces/IWETH.sol"; -import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; /// @custom:proxied true @@ -21,12 +19,23 @@ import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; /// is meant to sit behind a proxy contract and has an owner address that can pull WETH from any account and /// can recover ETH from the contract itself. Variable and function naming vaguely follows the vibe of WETH9. /// Not the prettiest contract in the world, but it gets the job done. -contract DelayedWETH is OwnableUpgradeable, WETH98, IDelayedWETH, ISemver { +contract DelayedWETH is OwnableUpgradeable, WETH98, ISemver { + /// @notice Represents a withdrawal request. + struct WithdrawalRequest { + uint256 amount; + uint256 timestamp; + } + + /// @notice Emitted when an unwrap is started. + /// @param src The address that started the unwrap. + /// @param wad The amount of WETH that was unwrapped. + event Unwrap(address indexed src, uint256 wad); + /// @notice Semantic version. - /// @custom:semver 1.2.0-beta.1 - string public constant version = "1.2.0-beta.1"; + /// @custom:semver 1.2.0-beta.2 + string public constant version = "1.2.0-beta.2"; - /// @inheritdoc IDelayedWETH + /// @notice Returns a withdrawal request for the given address. mapping(address => mapping(address => WithdrawalRequest)) public withdrawals; /// @notice Withdrawal delay in seconds. @@ -50,12 +59,15 @@ contract DelayedWETH is OwnableUpgradeable, WETH98, IDelayedWETH, ISemver { config = _config; } - /// @inheritdoc IDelayedWETH + /// @notice Returns the withdrawal delay in seconds. + /// @return The withdrawal delay in seconds. function delay() external view returns (uint256) { return DELAY_SECONDS; } - /// @inheritdoc IDelayedWETH + /// @notice Unlocks withdrawals for the sender's account, after a time delay. + /// @param _guy Sub-account to unlock. + /// @param _wad The amount of WETH to unlock. function unlock(address _guy, uint256 _wad) external { // Note that the unlock function can be called by any address, but the actual unlocking capability still only // gives the msg.sender the ability to withdraw from the account. As long as the unlock and withdraw functions @@ -67,12 +79,15 @@ contract DelayedWETH is OwnableUpgradeable, WETH98, IDelayedWETH, ISemver { wd.amount += _wad; } - /// @inheritdoc IWETH - function withdraw(uint256 _wad) public override(WETH98, IWETH) { + /// @notice Withdraws an amount of ETH. + /// @param _wad The amount of ETH to withdraw. + function withdraw(uint256 _wad) public override { withdraw(msg.sender, _wad); } - /// @inheritdoc IDelayedWETH + /// @notice Extension to withdrawal, must provide a sub-account to withdraw from. + /// @param _guy Sub-account to withdraw from. + /// @param _wad The amount of WETH to withdraw. function withdraw(address _guy, uint256 _wad) public { require(!config.paused(), "DelayedWETH: contract is paused"); WithdrawalRequest storage wd = withdrawals[msg.sender][_guy]; @@ -83,7 +98,8 @@ contract DelayedWETH is OwnableUpgradeable, WETH98, IDelayedWETH, ISemver { super.withdraw(_wad); } - /// @inheritdoc IDelayedWETH + /// @notice Allows the owner to recover from error cases by pulling ETH out of the contract. + /// @param _wad The amount of WETH to recover. function recover(uint256 _wad) external { require(msg.sender == owner(), "DelayedWETH: not owner"); uint256 amount = _wad < address(this).balance ? _wad : address(this).balance; @@ -91,7 +107,9 @@ contract DelayedWETH is OwnableUpgradeable, WETH98, IDelayedWETH, ISemver { require(success, "DelayedWETH: recover failed"); } - /// @inheritdoc IDelayedWETH + /// @notice Allows the owner to recover from error cases by pulling ETH from a specific owner. + /// @param _guy The address to recover the WETH from. + /// @param _wad The amount of WETH to recover. function hold(address _guy, uint256 _wad) external { require(msg.sender == owner(), "DelayedWETH: not owner"); allowance[_guy][msg.sender] = _wad; diff --git a/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol b/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol index b9d384dd4483..dee8dd75ec60 100644 --- a/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol +++ b/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol @@ -1,34 +1,62 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { LibClone } from "@solady/utils/LibClone.sol"; +// Contracts import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import { ISemver } from "src/universal/interfaces/ISemver.sol"; - -import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; -import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol"; +// Libraries +import { LibClone } from "@solady/utils/LibClone.sol"; import "src/dispute/lib/Types.sol"; import "src/dispute/lib/Errors.sol"; +// Interfaces +import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; + /// @custom:proxied true /// @title DisputeGameFactory /// @notice A factory contract for creating `IDisputeGame` contracts. All created dispute games are stored in both a /// mapping and an append only array. The timestamp of the creation time of the dispute game is packed tightly /// into the storage slot with the address of the dispute game to make offchain discoverability of playable /// dispute games easier. -contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, ISemver { +contract DisputeGameFactory is OwnableUpgradeable, ISemver { /// @dev Allows for the creation of clone proxies with immutable arguments. using LibClone for address; + /// @notice Emitted when a new dispute game is created + /// @param disputeProxy The address of the dispute game proxy + /// @param gameType The type of the dispute game proxy's implementation + /// @param rootClaim The root claim of the dispute game + event DisputeGameCreated(address indexed disputeProxy, GameType indexed gameType, Claim indexed rootClaim); + + /// @notice Emitted when a new game implementation added to the factory + /// @param impl The implementation contract for the given `GameType`. + /// @param gameType The type of the DisputeGame. + event ImplementationSet(address indexed impl, GameType indexed gameType); + + /// @notice Emitted when a game type's initialization bond is updated + /// @param gameType The type of the DisputeGame. + /// @param newBond The new bond (in wei) for initializing the game type. + event InitBondUpdated(GameType indexed gameType, uint256 indexed newBond); + + /// @notice Information about a dispute game found in a `findLatestGames` search. + struct GameSearchResult { + uint256 index; + GameId metadata; + Timestamp timestamp; + Claim rootClaim; + bytes extraData; + } + /// @notice Semantic version. - /// @custom:semver 1.0.1-beta.1 - string public constant version = "1.0.1-beta.1"; + /// @custom:semver 1.0.1-beta.2 + string public constant version = "1.0.1-beta.2"; - /// @inheritdoc IDisputeGameFactory + /// @notice `gameImpls` is a mapping that maps `GameType`s to their respective + /// `IDisputeGame` implementations. mapping(GameType => IDisputeGame) public gameImpls; - /// @inheritdoc IDisputeGameFactory + /// @notice Returns the required bonds for initializing a dispute game of the given type. mapping(GameType => uint256) public initBonds; /// @notice Mapping of a hash of `gameType || rootClaim || extraData` to the deployed `IDisputeGame` clone (where @@ -51,12 +79,21 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, ISemver _transferOwnership(_owner); } - /// @inheritdoc IDisputeGameFactory + /// @notice The total number of dispute games created by this factory. + /// @return gameCount_ The total number of dispute games created by this factory. function gameCount() external view returns (uint256 gameCount_) { gameCount_ = _disputeGameList.length; } - /// @inheritdoc IDisputeGameFactory + /// @notice `games` queries an internal mapping that maps the hash of + /// `gameType ++ rootClaim ++ extraData` to the deployed `DisputeGame` clone. + /// @dev `++` equates to concatenation. + /// @param _gameType The type of the DisputeGame - used to decide the proxy implementation + /// @param _rootClaim The root claim of the DisputeGame. + /// @param _extraData Any extra data that should be provided to the created dispute game. + /// @return proxy_ The clone of the `DisputeGame` created with the given parameters. + /// Returns `address(0)` if nonexistent. + /// @return timestamp_ The timestamp of the creation of the dispute game. function games( GameType _gameType, Claim _rootClaim, @@ -71,7 +108,13 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, ISemver (proxy_, timestamp_) = (IDisputeGame(proxy), timestamp); } - /// @inheritdoc IDisputeGameFactory + /// @notice `gameAtIndex` returns the dispute game contract address and its creation timestamp + /// at the given index. Each created dispute game increments the underlying index. + /// @param _index The index of the dispute game. + /// @return gameType_ The type of the DisputeGame - used to decide the proxy implementation. + /// @return timestamp_ The timestamp of the creation of the dispute game. + /// @return proxy_ The clone of the `DisputeGame` created with the given parameters. + /// Returns `address(0)` if nonexistent. function gameAtIndex(uint256 _index) external view @@ -81,7 +124,11 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, ISemver (gameType_, timestamp_, proxy_) = (gameType, timestamp, IDisputeGame(proxy)); } - /// @inheritdoc IDisputeGameFactory + /// @notice Creates a new DisputeGame proxy contract. + /// @param _gameType The type of the DisputeGame - used to decide the proxy implementation. + /// @param _rootClaim The root claim of the DisputeGame. + /// @param _extraData Any extra data that should be provided to the created dispute game. + /// @return proxy_ The address of the created DisputeGame proxy. function create( GameType _gameType, Claim _rootClaim, @@ -132,7 +179,13 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, ISemver emit DisputeGameCreated(address(proxy_), _gameType, _rootClaim); } - /// @inheritdoc IDisputeGameFactory + /// @notice Returns a unique identifier for the given dispute game parameters. + /// @dev Hashes the concatenation of `gameType . rootClaim . extraData` + /// without expanding memory. + /// @param _gameType The type of the DisputeGame. + /// @param _rootClaim The root claim of the DisputeGame. + /// @param _extraData Any extra data that should be provided to the created dispute game. + /// @return uuid_ The unique identifier for the given dispute game parameters. function getGameUUID( GameType _gameType, Claim _rootClaim, @@ -145,7 +198,11 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, ISemver uuid_ = Hash.wrap(keccak256(abi.encode(_gameType, _rootClaim, _extraData))); } - /// @inheritdoc IDisputeGameFactory + /// @notice Finds the `_n` most recent `GameId`'s of type `_gameType` starting at `_start`. If there are less than + /// `_n` games of type `_gameType` starting at `_start`, then the returned array will be shorter than `_n`. + /// @param _gameType The type of game to find. + /// @param _start The index to start the reverse search from. + /// @param _n The number of games to find. function findLatestGames( GameType _gameType, uint256 _start, @@ -196,13 +253,19 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, ISemver } } - /// @inheritdoc IDisputeGameFactory + /// @notice Sets the implementation contract for a specific `GameType`. + /// @dev May only be called by the `owner`. + /// @param _gameType The type of the DisputeGame. + /// @param _impl The implementation contract for the given `GameType`. function setImplementation(GameType _gameType, IDisputeGame _impl) external onlyOwner { gameImpls[_gameType] = _impl; emit ImplementationSet(address(_impl), _gameType); } - /// @inheritdoc IDisputeGameFactory + /// @notice Sets the bond (in wei) for initializing a game type. + /// @dev May only be called by the `owner`. + /// @param _gameType The type of the DisputeGame. + /// @param _initBond The bond (in wei) for initializing a game type. function setInitBond(GameType _gameType, uint256 _initBond) external onlyOwner { initBonds[_gameType] = _initBond; emit InitBondUpdated(_gameType, _initBond); diff --git a/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol b/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol index d4e668dfb1cc..a11cdd9be0c8 100644 --- a/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol +++ b/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol @@ -1,29 +1,63 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { FixedPointMathLib } from "@solady/utils/FixedPointMathLib.sol"; +// Libraries import { Math } from "@openzeppelin/contracts/utils/math/Math.sol"; - -import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; -import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; -import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; -import { IInitializable } from "src/dispute/interfaces/IInitializable.sol"; -import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol"; -import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; - +import { FixedPointMathLib } from "@solady/utils/FixedPointMathLib.sol"; import { Clone } from "@solady/utils/Clone.sol"; -import { Types } from "src/libraries/Types.sol"; -import { ISemver } from "src/universal/interfaces/ISemver.sol"; - import { Types } from "src/libraries/Types.sol"; import { Hashing } from "src/libraries/Hashing.sol"; import { RLPReader } from "src/libraries/rlp/RLPReader.sol"; import "src/dispute/lib/Types.sol"; import "src/dispute/lib/Errors.sol"; +// Interfaces +import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; +import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; +import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol"; +import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; + /// @title FaultDisputeGame /// @notice An implementation of the `IFaultDisputeGame` interface. -contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { +contract FaultDisputeGame is Clone, ISemver { + //////////////////////////////////////////////////////////////// + // Structs // + //////////////////////////////////////////////////////////////// + + /// @notice The `ClaimData` struct represents the data associated with a Claim. + struct ClaimData { + uint32 parentIndex; + address counteredBy; + address claimant; + uint128 bond; + Claim claim; + Position position; + Clock clock; + } + + /// @notice The `ResolutionCheckpoint` struct represents the data associated with an in-progress claim resolution. + struct ResolutionCheckpoint { + bool initialCheckpointComplete; + uint32 subgameIndex; + Position leftmostPosition; + address counteredBy; + } + + //////////////////////////////////////////////////////////////// + // Events // + //////////////////////////////////////////////////////////////// + + /// @notice Emitted when the game is resolved. + /// @param status The status of the game after resolution. + event Resolved(GameStatus indexed status); + + /// @notice Emitted when a new claim is added to the DAG by `claimant` + /// @param parentIndex The index within the `claimData` array of the parent claim + /// @param claim The claim being added + /// @param claimant The address of the claimant + event Move(uint256 indexed parentIndex, Claim indexed claim, address indexed claimant); + //////////////////////////////////////////////////////////////// // State Vars // //////////////////////////////////////////////////////////////// @@ -70,8 +104,8 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { uint256 internal constant HEADER_BLOCK_NUMBER_INDEX = 8; /// @notice Semantic version. - /// @custom:semver 1.3.1-beta.2 - string public constant version = "1.3.1-beta.2"; + /// @custom:semver 1.3.1-beta.3 + string public constant version = "1.3.1-beta.3"; /// @notice The starting timestamp of the game Timestamp public createdAt; @@ -79,7 +113,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { /// @notice The timestamp of the game's global resolution. Timestamp public resolvedAt; - /// @inheritdoc IDisputeGame + /// @notice Returns the current status of the game. GameStatus public status; /// @notice Flag for the `initialize` function to prevent re-initialization. @@ -178,7 +212,8 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { L2_CHAIN_ID = _l2ChainId; } - /// @inheritdoc IInitializable + /// @notice Initializes the contract. + /// @dev This function may only be called once. function initialize() public payable virtual { // SAFETY: Any revert in this function will bubble up to the DisputeGameFactory and // prevent the game from being created. @@ -255,7 +290,17 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { // `IFaultDisputeGame` impl // //////////////////////////////////////////////////////////////// - /// @inheritdoc IFaultDisputeGame + /// @notice Perform an instruction step via an on-chain fault proof processor. + /// @dev This function should point to a fault proof processor in order to execute + /// a step in the fault proof program on-chain. The interface of the fault proof + /// processor contract should adhere to the `IBigStepper` interface. + /// @param _claimIndex The index of the challenged claim within `claimData`. + /// @param _isAttack Whether or not the step is an attack or a defense. + /// @param _stateData The stateData of the step is the preimage of the claim at the given + /// prestate, which is at `_stateIndex` if the move is an attack and `_claimIndex` if + /// the move is a defense. If the step is an attack on the first instruction, it is + /// the absolute prestate of the fault proof VM. + /// @param _proof Proof to access memory nodes in the VM's merkle state tree. function step( uint256 _claimIndex, bool _isAttack, @@ -452,17 +497,28 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { emit Move(_challengeIndex, _claim, msg.sender); } - /// @inheritdoc IFaultDisputeGame + /// @notice Attack a disagreed upon `Claim`. + /// @param _disputed The `Claim` being attacked. + /// @param _parentIndex Index of the `Claim` to attack in the `claimData` array. This must match the `_disputed` + /// claim. + /// @param _claim The `Claim` at the relative attack position. function attack(Claim _disputed, uint256 _parentIndex, Claim _claim) external payable { move(_disputed, _parentIndex, _claim, true); } - /// @inheritdoc IFaultDisputeGame + /// @notice Defend an agreed upon `Claim`. + /// @notice _disputed The `Claim` being defended. + /// @param _parentIndex Index of the claim to defend in the `claimData` array. This must match the `_disputed` + /// claim. + /// @param _claim The `Claim` at the relative defense position. function defend(Claim _disputed, uint256 _parentIndex, Claim _claim) external payable { move(_disputed, _parentIndex, _claim, false); } - /// @inheritdoc IFaultDisputeGame + /// @notice Posts the requested local data to the VM's `PreimageOralce`. + /// @param _ident The local identifier of the data to post. + /// @param _execLeafIdx The index of the leaf claim in an execution subgame that requires the local data for a step. + /// @param _partOffset The offset of the data to post. function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) external { // INVARIANT: Local data can only be added if the game is currently in progress. if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress(); @@ -501,7 +557,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { } } - /// @inheritdoc IFaultDisputeGame + /// @notice Returns the number of children that still need to be resolved in order to fully resolve a subgame rooted + /// at `_claimIndex`. + /// @param _claimIndex The subgame root claim's index within `claimData`. + /// @return numRemainingChildren_ The number of children that still need to be checked to resolve the subgame. function getNumToResolve(uint256 _claimIndex) public view returns (uint256 numRemainingChildren_) { ResolutionCheckpoint storage checkpoint = resolutionCheckpoints[_claimIndex]; uint256[] storage challengeIndices = subgames[_claimIndex]; @@ -510,17 +569,17 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { numRemainingChildren_ = challengeIndicesLen - checkpoint.subgameIndex; } - /// @inheritdoc IFaultDisputeGame + /// @notice The l2BlockNumber of the disputed output root in the `L2OutputOracle`. function l2BlockNumber() public pure returns (uint256 l2BlockNumber_) { l2BlockNumber_ = _getArgUint256(0x54); } - /// @inheritdoc IFaultDisputeGame + /// @notice Only the starting block number of the game. function startingBlockNumber() external view returns (uint256 startingBlockNumber_) { startingBlockNumber_ = startingOutputRoot.l2BlockNumber; } - /// @inheritdoc IFaultDisputeGame + /// @notice Starting output root and block number of the game. function startingRootHash() external view returns (Hash startingRootHash_) { startingRootHash_ = startingOutputRoot.root; } @@ -577,7 +636,12 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { // `IDisputeGame` impl // //////////////////////////////////////////////////////////////// - /// @inheritdoc IDisputeGame + /// @notice If all necessary information has been gathered, this function should mark the game + /// status as either `CHALLENGER_WINS` or `DEFENDER_WINS` and return the status of + /// the resolved game. It is at this stage that the bonds should be awarded to the + /// necessary parties. + /// @dev May only be called if the `status` is `IN_PROGRESS`. + /// @return status_ The status of the game after resolution. function resolve() external returns (GameStatus status_) { // INVARIANT: Resolution cannot occur unless the game is currently in progress. if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress(); @@ -596,7 +660,17 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { ANCHOR_STATE_REGISTRY.tryUpdateAnchorState(); } - /// @inheritdoc IFaultDisputeGame + /// @notice Resolves the subgame rooted at the given claim index. `_numToResolve` specifies how many children of + /// the subgame will be checked in this call. If `_numToResolve` is less than the number of children, an + /// internal cursor will be updated and this function may be called again to complete resolution of the + /// subgame. + /// @dev This function must be called bottom-up in the DAG + /// A subgame is a tree of claims that has a maximum depth of 1. + /// A subgame root claims is valid if, and only if, all of its child claims are invalid. + /// At the deepest level in the DAG, a claim is invalid if there's a successful step against it. + /// @param _claimIndex The index of the subgame root claim to resolve. + /// @param _numToResolve The number of subgames to resolve in this call. If the input is `0`, and this is the first + /// page, this function will attempt to check all of the subgame's children at once. function resolveClaim(uint256 _claimIndex, uint256 _numToResolve) external { // INVARIANT: Resolution cannot occur unless the game is currently in progress. if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress(); @@ -698,34 +772,51 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { } } - /// @inheritdoc IDisputeGame - function gameType() public view override returns (GameType gameType_) { + /// @notice Getter for the game type. + /// @dev The reference impl should be entirely different depending on the type (fault, validity) + /// i.e. The game type should indicate the security model. + /// @return gameType_ The type of proof system being used. + function gameType() public view returns (GameType gameType_) { gameType_ = GAME_TYPE; } - /// @inheritdoc IDisputeGame + /// @notice Getter for the creator of the dispute game. + /// @dev `clones-with-immutable-args` argument #1 + /// @return creator_ The creator of the dispute game. function gameCreator() public pure returns (address creator_) { creator_ = _getArgAddress(0x00); } - /// @inheritdoc IDisputeGame + /// @notice Getter for the root claim. + /// @dev `clones-with-immutable-args` argument #2 + /// @return rootClaim_ The root claim of the DisputeGame. function rootClaim() public pure returns (Claim rootClaim_) { rootClaim_ = Claim.wrap(_getArgBytes32(0x14)); } - /// @inheritdoc IDisputeGame + /// @notice Getter for the parent hash of the L1 block when the dispute game was created. + /// @dev `clones-with-immutable-args` argument #3 + /// @return l1Head_ The parent hash of the L1 block when the dispute game was created. function l1Head() public pure returns (Hash l1Head_) { l1Head_ = Hash.wrap(_getArgBytes32(0x34)); } - /// @inheritdoc IDisputeGame + /// @notice Getter for the extra data. + /// @dev `clones-with-immutable-args` argument #4 + /// @return extraData_ Any extra data supplied to the dispute game contract by the creator. function extraData() public pure returns (bytes memory extraData_) { // The extra data starts at the second word within the cwia calldata and // is 32 bytes long. extraData_ = _getArgBytes(0x54, 0x20); } - /// @inheritdoc IDisputeGame + /// @notice A compliant implementation of this interface should return the components of the + /// game UUID's preimage provided in the cwia payload. The preimage of the UUID is + /// constructed as `keccak256(gameType . rootClaim . extraData)` where `.` denotes + /// concatenation. + /// @return gameType_ The type of proof system being used. + /// @return rootClaim_ The root claim of the DisputeGame. + /// @return extraData_ Any extra data supplied to the dispute game contract by the creator. function gameData() external view returns (GameType gameType_, Claim rootClaim_, bytes memory extraData_) { gameType_ = gameType(); rootClaim_ = rootClaim(); diff --git a/packages/contracts-bedrock/src/dispute/PermissionedDisputeGame.sol b/packages/contracts-bedrock/src/dispute/PermissionedDisputeGame.sol index 8e6741552489..abd8a8896cc3 100644 --- a/packages/contracts-bedrock/src/dispute/PermissionedDisputeGame.sol +++ b/packages/contracts-bedrock/src/dispute/PermissionedDisputeGame.sol @@ -1,12 +1,18 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; -import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; -import { FaultDisputeGame, IFaultDisputeGame, IBigStepper, IInitializable } from "src/dispute/FaultDisputeGame.sol"; +// Contracts +import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; + +// Libraries import "src/dispute/lib/Types.sol"; import "src/dispute/lib/Errors.sol"; +// Interfaces +import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; +import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; +import { IBigStepper } from "src/dispute/interfaces/IBigStepper.sol"; + /// @title PermissionedDisputeGame /// @notice PermissionedDisputeGame is a contract that inherits from `FaultDisputeGame`, and contains two roles: /// - The `challenger` role, which is allowed to challenge a dispute. @@ -73,7 +79,7 @@ contract PermissionedDisputeGame is FaultDisputeGame { CHALLENGER = _challenger; } - /// @inheritdoc IFaultDisputeGame + /// @inheritdoc FaultDisputeGame function step( uint256 _claimIndex, bool _isAttack, @@ -106,7 +112,7 @@ contract PermissionedDisputeGame is FaultDisputeGame { super.move(_disputed, _challengeIndex, _claim, _isAttack); } - /// @inheritdoc IInitializable + /// @notice Initializes the contract. function initialize() public payable override { // The creator of the dispute game must be the proposer EOA. if (tx.origin != PROPOSER) revert BadAuth(); diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IAnchorStateRegistry.sol b/packages/contracts-bedrock/src/dispute/interfaces/IAnchorStateRegistry.sol index dd7724538e58..e0bc9ef53e8b 100644 --- a/packages/contracts-bedrock/src/dispute/interfaces/IAnchorStateRegistry.sol +++ b/packages/contracts-bedrock/src/dispute/interfaces/IAnchorStateRegistry.sol @@ -3,27 +3,30 @@ pragma solidity ^0.8.0; import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol"; - +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import "src/dispute/lib/Types.sol"; -/// @title IAnchorStateRegistry -/// @notice Describes a contract that stores the anchor state for each game type. interface IAnchorStateRegistry { - /// @notice Returns the anchor state for the given game type. - /// @param _gameType The game type to get the anchor state for. - /// @return The anchor state for the given game type. - function anchors(GameType _gameType) external view returns (Hash, uint256); + struct StartingAnchorRoot { + GameType gameType; + OutputRoot outputRoot; + } - /// @notice Returns the DisputeGameFactory address. - /// @return DisputeGameFactory address. - function disputeGameFactory() external view returns (IDisputeGameFactory); + error InvalidGameStatus(); + error Unauthorized(); + error UnregisteredGame(); - /// @notice Callable by FaultDisputeGame contracts to update the anchor state. Pulls the anchor state directly from - /// the FaultDisputeGame contract and stores it in the registry if the new anchor state is valid and the - /// state is newer than the current anchor state. - function tryUpdateAnchorState() external; + event Initialized(uint8 version); - /// @notice Sets the anchor state given the game. - /// @param _game The game to set the anchor state for. + function anchors(GameType) external view returns (Hash root, uint256 l2BlockNumber); + function disputeGameFactory() external view returns (IDisputeGameFactory); + function initialize( + StartingAnchorRoot[] memory _startingAnchorRoots, + ISuperchainConfig _superchainConfig + ) + external; function setAnchorState(IFaultDisputeGame _game) external; + function superchainConfig() external view returns (ISuperchainConfig); + function tryUpdateAnchorState() external; + function version() external view returns (string memory); } diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IDelayedWETH.sol b/packages/contracts-bedrock/src/dispute/interfaces/IDelayedWETH.sol index 241e4ddd54ae..7a7b36052f3d 100644 --- a/packages/contracts-bedrock/src/dispute/interfaces/IDelayedWETH.sol +++ b/packages/contracts-bedrock/src/dispute/interfaces/IDelayedWETH.sol @@ -2,47 +2,29 @@ pragma solidity ^0.8.0; import { IWETH } from "src/universal/interfaces/IWETH.sol"; +import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; -/// @title IDelayedWETH -/// @notice Interface for the DelayedWETH contract. interface IDelayedWETH is IWETH { - /// @notice Represents a withdrawal request. struct WithdrawalRequest { uint256 amount; uint256 timestamp; } - /// @notice Emitted when an unwrap is started. - /// @param src The address that started the unwrap. - /// @param wad The amount of WETH that was unwrapped. event Unwrap(address indexed src, uint256 wad); - /// @notice Returns the withdrawal delay in seconds. - /// @return The withdrawal delay in seconds. - function delay() external view returns (uint256); - - /// @notice Returns a withdrawal request for the given address. - /// @param _owner The address to query the withdrawal request of. - /// @param _guy Sub-account to query the withdrawal request of. - /// @return The withdrawal request for the given address-subaccount pair. - function withdrawals(address _owner, address _guy) external view returns (uint256, uint256); + fallback() external payable; + receive() external payable; - /// @notice Unlocks withdrawals for the sender's account, after a time delay. - /// @param _guy Sub-account to unlock. - /// @param _wad The amount of WETH to unlock. + function config() external view returns (ISuperchainConfig); + function delay() external view returns (uint256); + function hold(address _guy, uint256 _wad) external; + function initialize(address _owner, ISuperchainConfig _config) external; + function owner() external view returns (address); + function recover(uint256 _wad) external; + function transferOwnership(address newOwner) external; + function renounceOwnership() external; function unlock(address _guy, uint256 _wad) external; - - /// @notice Extension to withdrawal, must provide a sub-account to withdraw from. - /// @param _guy Sub-account to withdraw from. - /// @param _wad The amount of WETH to withdraw. function withdraw(address _guy, uint256 _wad) external; - - /// @notice Allows the owner to recover from error cases by pulling ETH out of the contract. - /// @param _wad The amount of WETH to recover. - function recover(uint256 _wad) external; - - /// @notice Allows the owner to recover from error cases by pulling ETH from a specific owner. - /// @param _guy The address to recover the WETH from. - /// @param _wad The amount of WETH to recover. - function hold(address _guy, uint256 _wad) external; + function withdrawals(address _owner, address _guy) external view returns (uint256, uint256); + function version() external view returns (string memory); } diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGame.sol b/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGame.sol index 7e9389b4ddaf..f5a650202d0c 100644 --- a/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGame.sol +++ b/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGame.sol @@ -2,68 +2,19 @@ pragma solidity ^0.8.0; import { IInitializable } from "src/dispute/interfaces/IInitializable.sol"; - import "src/dispute/lib/Types.sol"; -/// @title IDisputeGame -/// @notice The generic interface for a DisputeGame contract. interface IDisputeGame is IInitializable { - /// @notice Emitted when the game is resolved. - /// @param status The status of the game after resolution. event Resolved(GameStatus indexed status); - /// @notice Returns the timestamp that the DisputeGame contract was created at. - /// @return createdAt_ The timestamp that the DisputeGame contract was created at. - function createdAt() external view returns (Timestamp createdAt_); - - /// @notice Returns the timestamp that the DisputeGame contract was resolved at. - /// @return resolvedAt_ The timestamp that the DisputeGame contract was resolved at. - function resolvedAt() external view returns (Timestamp resolvedAt_); - - /// @notice Returns the current status of the game. - /// @return status_ The current status of the game. - function status() external view returns (GameStatus status_); - - /// @notice Getter for the game type. - /// @dev The reference impl should be entirely different depending on the type (fault, validity) - /// i.e. The game type should indicate the security model. - /// @return gameType_ The type of proof system being used. + function createdAt() external view returns (Timestamp); + function resolvedAt() external view returns (Timestamp); + function status() external view returns (GameStatus); function gameType() external view returns (GameType gameType_); - - /// @notice Getter for the creator of the dispute game. - /// @dev `clones-with-immutable-args` argument #1 - /// @return creator_ The creator of the dispute game. function gameCreator() external pure returns (address creator_); - - /// @notice Getter for the root claim. - /// @dev `clones-with-immutable-args` argument #2 - /// @return rootClaim_ The root claim of the DisputeGame. function rootClaim() external pure returns (Claim rootClaim_); - - /// @notice Getter for the parent hash of the L1 block when the dispute game was created. - /// @dev `clones-with-immutable-args` argument #3 - /// @return l1Head_ The parent hash of the L1 block when the dispute game was created. function l1Head() external pure returns (Hash l1Head_); - - /// @notice Getter for the extra data. - /// @dev `clones-with-immutable-args` argument #4 - /// @return extraData_ Any extra data supplied to the dispute game contract by the creator. function extraData() external pure returns (bytes memory extraData_); - - /// @notice If all necessary information has been gathered, this function should mark the game - /// status as either `CHALLENGER_WINS` or `DEFENDER_WINS` and return the status of - /// the resolved game. It is at this stage that the bonds should be awarded to the - /// necessary parties. - /// @dev May only be called if the `status` is `IN_PROGRESS`. - /// @return status_ The status of the game after resolution. function resolve() external returns (GameStatus status_); - - /// @notice A compliant implementation of this interface should return the components of the - /// game UUID's preimage provided in the cwia payload. The preimage of the UUID is - /// constructed as `keccak256(gameType . rootClaim . extraData)` where `.` denotes - /// concatenation. - /// @return gameType_ The type of proof system being used. - /// @return rootClaim_ The root claim of the DisputeGame. - /// @return extraData_ Any extra data supplied to the dispute game contract by the creator. function gameData() external view returns (GameType gameType_, Claim rootClaim_, bytes memory extraData_); } diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGameFactory.sol b/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGameFactory.sol index 5021de04d62a..68bee806843a 100644 --- a/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGameFactory.sol +++ b/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGameFactory.sol @@ -1,30 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { IDisputeGame } from "./IDisputeGame.sol"; - +import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; import "src/dispute/lib/Types.sol"; -/// @title IDisputeGameFactory -/// @notice The interface for a DisputeGameFactory contract. interface IDisputeGameFactory { - /// @notice Emitted when a new dispute game is created - /// @param disputeProxy The address of the dispute game proxy - /// @param gameType The type of the dispute game proxy's implementation - /// @param rootClaim The root claim of the dispute game - event DisputeGameCreated(address indexed disputeProxy, GameType indexed gameType, Claim indexed rootClaim); - - /// @notice Emitted when a new game implementation added to the factory - /// @param impl The implementation contract for the given `GameType`. - /// @param gameType The type of the DisputeGame. - event ImplementationSet(address indexed impl, GameType indexed gameType); - - /// @notice Emitted when a game type's initialization bond is updated - /// @param gameType The type of the DisputeGame. - /// @param newBond The new bond (in wei) for initializing the game type. - event InitBondUpdated(GameType indexed gameType, uint256 indexed newBond); - - /// @notice Information about a dispute game found in a `findLatestGames` search. struct GameSearchResult { uint256 index; GameId metadata; @@ -33,85 +13,46 @@ interface IDisputeGameFactory { bytes extraData; } - /// @notice The total number of dispute games created by this factory. - /// @return gameCount_ The total number of dispute games created by this factory. - function gameCount() external view returns (uint256 gameCount_); + error GameAlreadyExists(Hash uuid); + error IncorrectBondAmount(); + error NoImplementation(GameType gameType); - /// @notice `games` queries an internal mapping that maps the hash of - /// `gameType ++ rootClaim ++ extraData` to the deployed `DisputeGame` clone. - /// @dev `++` equates to concatenation. - /// @param _gameType The type of the DisputeGame - used to decide the proxy implementation - /// @param _rootClaim The root claim of the DisputeGame. - /// @param _extraData Any extra data that should be provided to the created dispute game. - /// @return proxy_ The clone of the `DisputeGame` created with the given parameters. - /// Returns `address(0)` if nonexistent. - /// @return timestamp_ The timestamp of the creation of the dispute game. - function games( + event DisputeGameCreated(address indexed disputeProxy, GameType indexed gameType, Claim indexed rootClaim); + event ImplementationSet(address indexed impl, GameType indexed gameType); + event InitBondUpdated(GameType indexed gameType, uint256 indexed newBond); + event Initialized(uint8 version); + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + function create( GameType _gameType, Claim _rootClaim, - bytes calldata _extraData + bytes memory _extraData + ) + external + payable + returns (IDisputeGame proxy_); + function findLatestGames( + GameType _gameType, + uint256 _start, + uint256 _n ) external view - returns (IDisputeGame proxy_, Timestamp timestamp_); - - /// @notice `gameAtIndex` returns the dispute game contract address and its creation timestamp - /// at the given index. Each created dispute game increments the underlying index. - /// @param _index The index of the dispute game. - /// @return gameType_ The type of the DisputeGame - used to decide the proxy implementation. - /// @return timestamp_ The timestamp of the creation of the dispute game. - /// @return proxy_ The clone of the `DisputeGame` created with the given parameters. - /// Returns `address(0)` if nonexistent. + returns (GameSearchResult[] memory games_); function gameAtIndex(uint256 _index) external view returns (GameType gameType_, Timestamp timestamp_, IDisputeGame proxy_); - - /// @notice `gameImpls` is a mapping that maps `GameType`s to their respective - /// `IDisputeGame` implementations. - /// @param _gameType The type of the dispute game. - /// @return impl_ The address of the implementation of the game type. - /// Will be cloned on creation of a new dispute game with the given `gameType`. - function gameImpls(GameType _gameType) external view returns (IDisputeGame impl_); - - /// @notice Returns the required bonds for initializing a dispute game of the given type. - /// @param _gameType The type of the dispute game. - /// @return bond_ The required bond for initializing a dispute game of the given type. - function initBonds(GameType _gameType) external view returns (uint256 bond_); - - /// @notice Creates a new DisputeGame proxy contract. - /// @param _gameType The type of the DisputeGame - used to decide the proxy implementation. - /// @param _rootClaim The root claim of the DisputeGame. - /// @param _extraData Any extra data that should be provided to the created dispute game. - /// @return proxy_ The address of the created DisputeGame proxy. - function create( + function gameCount() external view returns (uint256 gameCount_); + function gameImpls(GameType) external view returns (IDisputeGame); + function games( GameType _gameType, Claim _rootClaim, - bytes calldata _extraData + bytes memory _extraData ) external - payable - returns (IDisputeGame proxy_); - - /// @notice Sets the implementation contract for a specific `GameType`. - /// @dev May only be called by the `owner`. - /// @param _gameType The type of the DisputeGame. - /// @param _impl The implementation contract for the given `GameType`. - function setImplementation(GameType _gameType, IDisputeGame _impl) external; - - /// @notice Sets the bond (in wei) for initializing a game type. - /// @dev May only be called by the `owner`. - /// @param _gameType The type of the DisputeGame. - /// @param _initBond The bond (in wei) for initializing a game type. - function setInitBond(GameType _gameType, uint256 _initBond) external; - - /// @notice Returns a unique identifier for the given dispute game parameters. - /// @dev Hashes the concatenation of `gameType . rootClaim . extraData` - /// without expanding memory. - /// @param _gameType The type of the DisputeGame. - /// @param _rootClaim The root claim of the DisputeGame. - /// @param _extraData Any extra data that should be provided to the created dispute game. - /// @return uuid_ The unique identifier for the given dispute game parameters. + view + returns (IDisputeGame proxy_, Timestamp timestamp_); function getGameUUID( GameType _gameType, Claim _rootClaim, @@ -120,18 +61,12 @@ interface IDisputeGameFactory { external pure returns (Hash uuid_); - - /// @notice Finds the `_n` most recent `GameId`'s of type `_gameType` starting at `_start`. If there are less than - /// `_n` games of type `_gameType` starting at `_start`, then the returned array will be shorter than `_n`. - /// @param _gameType The type of game to find. - /// @param _start The index to start the reverse search from. - /// @param _n The number of games to find. - function findLatestGames( - GameType _gameType, - uint256 _start, - uint256 _n - ) - external - view - returns (GameSearchResult[] memory games_); + function initBonds(GameType) external view returns (uint256); + function initialize(address _owner) external; + function owner() external view returns (address); + function renounceOwnership() external; + function setImplementation(GameType _gameType, IDisputeGame _impl) external; + function setInitBond(GameType _gameType, uint256 _initBond) external; + function transferOwnership(address newOwner) external; + function version() external view returns (string memory); } diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IFaultDisputeGame.sol b/packages/contracts-bedrock/src/dispute/interfaces/IFaultDisputeGame.sol index 43de378ac06d..3d9621c54ed2 100644 --- a/packages/contracts-bedrock/src/dispute/interfaces/IFaultDisputeGame.sol +++ b/packages/contracts-bedrock/src/dispute/interfaces/IFaultDisputeGame.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { IDisputeGame } from "./IDisputeGame.sol"; - +import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; +import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; +import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; +import { IBigStepper } from "src/dispute/interfaces/IBigStepper.sol"; +import { Types } from "src/libraries/Types.sol"; import "src/dispute/lib/Types.sol"; -/// @title IFaultDisputeGame -/// @notice The interface for a fault proof backed dispute game. interface IFaultDisputeGame is IDisputeGame { - /// @notice The `ClaimData` struct represents the data associated with a Claim. struct ClaimData { uint32 parentIndex; address counteredBy; @@ -19,7 +19,6 @@ interface IFaultDisputeGame is IDisputeGame { Clock clock; } - /// @notice The `ResolutionCheckpoint` struct represents the data associated with an in-progress claim resolution. struct ResolutionCheckpoint { bool initialCheckpointComplete; uint32 subgameIndex; @@ -27,73 +26,90 @@ interface IFaultDisputeGame is IDisputeGame { address counteredBy; } - /// @notice Emitted when a new claim is added to the DAG by `claimant` - /// @param parentIndex The index within the `claimData` array of the parent claim - /// @param claim The claim being added - /// @param claimant The address of the claimant + error AlreadyInitialized(); + error AnchorRootNotFound(); + error BlockNumberMatches(); + error BondTransferFailed(); + error CannotDefendRootClaim(); + error ClaimAboveSplit(); + error ClaimAlreadyExists(); + error ClaimAlreadyResolved(); + error ClockNotExpired(); + error ClockTimeExceeded(); + error ContentLengthMismatch(); + error DuplicateStep(); + error EmptyItem(); + error GameDepthExceeded(); + error GameNotInProgress(); + error IncorrectBondAmount(); + error InvalidChallengePeriod(); + error InvalidClockExtension(); + error InvalidDataRemainder(); + error InvalidDisputedClaimIndex(); + error InvalidHeader(); + error InvalidHeaderRLP(); + error InvalidLocalIdent(); + error InvalidOutputRootProof(); + error InvalidParent(); + error InvalidPrestate(); + error InvalidSplitDepth(); + error L2BlockNumberChallenged(); + error MaxDepthTooLarge(); + error NoCreditToClaim(); + error OutOfOrderResolution(); + error UnexpectedList(); + error UnexpectedRootClaim(Claim rootClaim); + error UnexpectedString(); + error ValidStep(); + event Move(uint256 indexed parentIndex, Claim indexed claim, address indexed claimant); - /// @notice Attack a disagreed upon `Claim`. - /// @param _disputed The `Claim` being attacked. - /// @param _parentIndex Index of the `Claim` to attack in the `claimData` array. This must match the `_disputed` - /// claim. - /// @param _claim The `Claim` at the relative attack position. + function absolutePrestate() external view returns (Claim absolutePrestate_); + function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) external; + function anchorStateRegistry() external view returns (IAnchorStateRegistry registry_); function attack(Claim _disputed, uint256 _parentIndex, Claim _claim) external payable; - - /// @notice Defend an agreed upon `Claim`. - /// @notice _disputed The `Claim` being defended. - /// @param _parentIndex Index of the claim to defend in the `claimData` array. This must match the `_disputed` - /// claim. - /// @param _claim The `Claim` at the relative defense position. + function challengeRootL2Block(Types.OutputRootProof memory _outputRootProof, bytes memory _headerRLP) external; + function claimCredit(address _recipient) external; + function claimData(uint256) + external + view + returns ( + uint32 parentIndex, + address counteredBy, + address claimant, + uint128 bond, + Claim claim, + Position position, + Clock clock + ); + function claimDataLen() external view returns (uint256 len_); + function claims(Hash) external view returns (bool); + function clockExtension() external view returns (Duration clockExtension_); + function credit(address) external view returns (uint256); function defend(Claim _disputed, uint256 _parentIndex, Claim _claim) external payable; - - /// @notice Perform an instruction step via an on-chain fault proof processor. - /// @dev This function should point to a fault proof processor in order to execute - /// a step in the fault proof program on-chain. The interface of the fault proof - /// processor contract should adhere to the `IBigStepper` interface. - /// @param _claimIndex The index of the challenged claim within `claimData`. - /// @param _isAttack Whether or not the step is an attack or a defense. - /// @param _stateData The stateData of the step is the preimage of the claim at the given - /// prestate, which is at `_stateIndex` if the move is an attack and `_claimIndex` if - /// the move is a defense. If the step is an attack on the first instruction, it is - /// the absolute prestate of the fault proof VM. - /// @param _proof Proof to access memory nodes in the VM's merkle state tree. - function step(uint256 _claimIndex, bool _isAttack, bytes calldata _stateData, bytes calldata _proof) external; - - /// @notice Posts the requested local data to the VM's `PreimageOralce`. - /// @param _ident The local identifier of the data to post. - /// @param _execLeafIdx The index of the leaf claim in an execution subgame that requires the local data for a step. - /// @param _partOffset The offset of the data to post. - function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) external; - - /// @notice Resolves the subgame rooted at the given claim index. `_numToResolve` specifies how many children of - /// the subgame will be checked in this call. If `_numToResolve` is less than the number of children, an - /// internal cursor will be updated and this function may be called again to complete resolution of the - /// subgame. - /// @dev This function must be called bottom-up in the DAG - /// A subgame is a tree of claims that has a maximum depth of 1. - /// A subgame root claims is valid if, and only if, all of its child claims are invalid. - /// At the deepest level in the DAG, a claim is invalid if there's a successful step against it. - /// @param _claimIndex The index of the subgame root claim to resolve. - /// @param _numToResolve The number of subgames to resolve in this call. If the input is `0`, and this is the first - /// page, this function will attempt to check all of the subgame's children at once. - function resolveClaim(uint256 _claimIndex, uint256 _numToResolve) external; - - /// @notice Returns the number of children that still need to be resolved in order to fully resolve a subgame rooted - /// at `_claimIndex`. - /// @param _claimIndex The subgame root claim's index within `claimData`. - /// @return numRemainingChildren_ The number of children that still need to be checked to resolve the subgame. + function getChallengerDuration(uint256 _claimIndex) external view returns (Duration duration_); function getNumToResolve(uint256 _claimIndex) external view returns (uint256 numRemainingChildren_); - - /// @notice The l2BlockNumber of the disputed output root in the `L2OutputOracle`. - function l2BlockNumber() external view returns (uint256 l2BlockNumber_); - - /// @notice Starting output root and block number of the game. - function startingOutputRoot() external view returns (Hash startingRoot_, uint256 l2BlockNumber_); - - /// @notice Only the starting block number of the game. + function getRequiredBond(Position _position) external view returns (uint256 requiredBond_); + function l2BlockNumber() external pure returns (uint256 l2BlockNumber_); + function l2BlockNumberChallenged() external view returns (bool); + function l2BlockNumberChallenger() external view returns (address); + function l2ChainId() external view returns (uint256 l2ChainId_); + function maxClockDuration() external view returns (Duration maxClockDuration_); + function maxGameDepth() external view returns (uint256 maxGameDepth_); + function move(Claim _disputed, uint256 _challengeIndex, Claim _claim, bool _isAttack) external payable; + function resolutionCheckpoints(uint256) + external + view + returns (bool initialCheckpointComplete, uint32 subgameIndex, Position leftmostPosition, address counteredBy); + function resolveClaim(uint256 _claimIndex, uint256 _numToResolve) external; + function resolvedSubgames(uint256) external view returns (bool); + function splitDepth() external view returns (uint256 splitDepth_); function startingBlockNumber() external view returns (uint256 startingBlockNumber_); - - /// @notice Only the starting output root of the game. + function startingOutputRoot() external view returns (Hash root, uint256 l2BlockNumber); function startingRootHash() external view returns (Hash startingRootHash_); + function step(uint256 _claimIndex, bool _isAttack, bytes memory _stateData, bytes memory _proof) external; + function subgames(uint256, uint256) external view returns (uint256); + function version() external view returns (string memory); + function vm() external view returns (IBigStepper vm_); + function weth() external view returns (IDelayedWETH weth_); } diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IInitializable.sol b/packages/contracts-bedrock/src/dispute/interfaces/IInitializable.sol index 5968b45f9bfb..a3bb74b82f3a 100644 --- a/packages/contracts-bedrock/src/dispute/interfaces/IInitializable.sol +++ b/packages/contracts-bedrock/src/dispute/interfaces/IInitializable.sol @@ -1,10 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -/// @title IInitializable -/// @notice An interface for initializable contracts. interface IInitializable { - /// @notice Initializes the contract. - /// @dev This function may only be called once. function initialize() external payable; } diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IPermissionedDisputeGame.sol b/packages/contracts-bedrock/src/dispute/interfaces/IPermissionedDisputeGame.sol new file mode 100644 index 000000000000..3872a769f892 --- /dev/null +++ b/packages/contracts-bedrock/src/dispute/interfaces/IPermissionedDisputeGame.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; + +interface IPermissionedDisputeGame is IFaultDisputeGame { + error BadAuth(); + + function proposer() external view returns (address proposer_); + function challenger() external view returns (address challenger_); +} diff --git a/packages/contracts-bedrock/src/safe/DeputyGuardianModule.sol b/packages/contracts-bedrock/src/safe/DeputyGuardianModule.sol index 4b80c9da9200..0882910d5072 100644 --- a/packages/contracts-bedrock/src/safe/DeputyGuardianModule.sol +++ b/packages/contracts-bedrock/src/safe/DeputyGuardianModule.sol @@ -5,14 +5,12 @@ pragma solidity 0.8.15; import { GnosisSafe as Safe } from "safe-contracts/GnosisSafe.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; -// Contracts -import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; - // Libraries import { Unauthorized } from "src/libraries/PortalErrors.sol"; import "src/dispute/lib/Types.sol"; // Interfaces +import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; @@ -50,8 +48,8 @@ contract DeputyGuardianModule is ISemver { address internal immutable DEPUTY_GUARDIAN; /// @notice Semantic version. - /// @custom:semver 2.0.1-beta.2 - string public constant version = "2.0.1-beta.2"; + /// @custom:semver 2.0.1-beta.3 + string public constant version = "2.0.1-beta.3"; // Constructor to initialize the Safe and baseModule instances constructor(Safe _safe, ISuperchainConfig _superchainConfig, address _deputyGuardian) { @@ -118,12 +116,12 @@ contract DeputyGuardianModule is ISemver { /// @notice Calls the Security Council Safe's `execTransactionFromModuleReturnData()`, with the arguments /// necessary to call `setAnchorState()` on the `AnchorStateRegistry` contract. /// Only the deputy guardian can call this function. - /// @param _registry The `AnchorStateRegistry` contract instance. + /// @param _registry The `IAnchorStateRegistry` contract instance. /// @param _game The `IFaultDisputeGame` contract instance. - function setAnchorState(AnchorStateRegistry _registry, IFaultDisputeGame _game) external { + function setAnchorState(IAnchorStateRegistry _registry, IFaultDisputeGame _game) external { _onlyDeputyGuardian(); - bytes memory data = abi.encodeCall(AnchorStateRegistry.setAnchorState, (_game)); + bytes memory data = abi.encodeCall(IAnchorStateRegistry.setAnchorState, (_game)); (bool success, bytes memory returnData) = SAFE.execTransactionFromModuleReturnData(address(_registry), 0, data, Enum.Operation.Call); if (!success) { diff --git a/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol b/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol index 810f0a84e589..c131995c1a6b 100644 --- a/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol +++ b/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol @@ -12,7 +12,6 @@ import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; // Contracts import { Proxy } from "src/universal/Proxy.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; -import { FaultDisputeGame, IDisputeGame } from "src/dispute/FaultDisputeGame.sol"; // Libraries import { Types } from "src/libraries/Types.sol"; @@ -28,6 +27,8 @@ import "src/libraries/PortalErrors.sol"; import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { IL1Block } from "src/L2/interfaces/IL1Block.sol"; import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; +import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; +import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; contract OptimismPortal2_Test is CommonTest { address depositor; @@ -423,7 +424,7 @@ contract OptimismPortal2_FinalizeWithdrawal_Test is CommonTest { // Reusable default values for a test withdrawal Types.WithdrawalTransaction _defaultTx; - FaultDisputeGame game; + IFaultDisputeGame game; uint256 _proposedGameIndex; uint256 _proposedBlockNumber; bytes32 _stateRoot; @@ -462,7 +463,7 @@ contract OptimismPortal2_FinalizeWithdrawal_Test is CommonTest { /// @dev Setup the system for a ready-to-use state. function setUp() public virtual override { _proposedBlockNumber = 0xFF; - game = FaultDisputeGame( + game = IFaultDisputeGame( payable( address( disputeGameFactory.create( diff --git a/packages/contracts-bedrock/test/actors/FaultDisputeActors.sol b/packages/contracts-bedrock/test/actors/FaultDisputeActors.sol index 181fc87266ac..20f18eddc3c0 100644 --- a/packages/contracts-bedrock/test/actors/FaultDisputeActors.sol +++ b/packages/contracts-bedrock/test/actors/FaultDisputeActors.sol @@ -1,13 +1,15 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.15; +// Testing import { CommonBase } from "forge-std/Base.sol"; -import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; -import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; - +// Libraries import "src/dispute/lib/Types.sol"; +// Interfaces +import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; + /// @title GameSolver /// @notice The `GameSolver` contract is a contract that can produce an array of available /// moves for a given `FaultDisputeGame` contract, from the eyes of an honest @@ -15,7 +17,7 @@ import "src/dispute/lib/Types.sol"; /// it suggests. abstract contract GameSolver is CommonBase { /// @notice The `FaultDisputeGame` proxy that the `GameSolver` will be solving. - FaultDisputeGame public immutable GAME; + IFaultDisputeGame public immutable GAME; /// @notice The split depth of the game uint256 internal immutable SPLIT_DEPTH; /// @notice The max depth of the game @@ -55,7 +57,7 @@ abstract contract GameSolver is CommonBase { } constructor( - FaultDisputeGame _gameProxy, + IFaultDisputeGame _gameProxy, uint256[] memory _l2Outputs, bytes memory _trace, bytes memory _preStateData @@ -89,7 +91,7 @@ contract HonestGameSolver is GameSolver { } constructor( - FaultDisputeGame _gameProxy, + IFaultDisputeGame _gameProxy, uint256[] memory _l2Outputs, bytes memory _trace, bytes memory _preStateData @@ -223,7 +225,7 @@ contract HonestGameSolver is GameSolver { move_ = Move({ kind: isAttack ? MoveKind.Attack : MoveKind.Defend, value: bond, - data: abi.encodeCall(FaultDisputeGame.move, (disputed, _challengeIndex, claimAt(_movePos), isAttack)) + data: abi.encodeCall(IFaultDisputeGame.move, (disputed, _challengeIndex, claimAt(_movePos), isAttack)) }); } @@ -263,7 +265,7 @@ contract HonestGameSolver is GameSolver { move_ = Move({ kind: MoveKind.Step, value: 0, - data: abi.encodeCall(FaultDisputeGame.step, (_challengeIndex, isAttack, preStateTrace, hex"")) + data: abi.encodeCall(IFaultDisputeGame.step, (_challengeIndex, isAttack, preStateTrace, hex"")) }); } @@ -366,10 +368,10 @@ abstract contract DisputeActor { /// that this actor *can* be dishonest if the trace is faulty, but it will always follow /// the rules of the honest actor. contract HonestDisputeActor is DisputeActor { - FaultDisputeGame public immutable GAME; + IFaultDisputeGame public immutable GAME; constructor( - FaultDisputeGame _gameProxy, + IFaultDisputeGame _gameProxy, uint256[] memory _l2Outputs, bytes memory _trace, bytes memory _preStateData diff --git a/packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol b/packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol index 96729cdb7215..b5dbac76f6c6 100644 --- a/packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol +++ b/packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol @@ -1,12 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.15; +// Testing +import { Test } from "forge-std/Test.sol"; +import { FaultDisputeGame_Init, _changeClaimStatus } from "test/dispute/FaultDisputeGame.t.sol"; + +// Libraries import "src/dispute/lib/Types.sol"; import "src/dispute/lib/Errors.sol"; -import { Test } from "forge-std/Test.sol"; -import { FaultDisputeGame_Init, IDisputeGame, _changeClaimStatus } from "test/dispute/FaultDisputeGame.t.sol"; - contract AnchorStateRegistry_Init is FaultDisputeGame_Init { function setUp() public virtual override { // Duplicating the initialization/setup logic of FaultDisputeGame_Test. diff --git a/packages/contracts-bedrock/test/dispute/DelayedWETH.t.sol b/packages/contracts-bedrock/test/dispute/DelayedWETH.t.sol index 57c29a9f7251..bde1e1b9f893 100644 --- a/packages/contracts-bedrock/test/dispute/DelayedWETH.t.sol +++ b/packages/contracts-bedrock/test/dispute/DelayedWETH.t.sol @@ -1,17 +1,15 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.15; -import "src/dispute/lib/Types.sol"; -import "src/dispute/lib/Errors.sol"; - +// Testing import { Test } from "forge-std/Test.sol"; -import { DisputeGameFactory, IDisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; -import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; -import { DelayedWETH } from "src/dispute/DelayedWETH.sol"; -import { Proxy } from "src/universal/Proxy.sol"; -import { Burn } from "src/libraries/Burn.sol"; import { CommonTest } from "test/setup/CommonTest.sol"; +// Libraries +import { Burn } from "src/libraries/Burn.sol"; +import "src/dispute/lib/Types.sol"; +import "src/dispute/lib/Errors.sol"; + contract DelayedWETH_Init is CommonTest { event Approval(address indexed src, address indexed guy, uint256 wad); event Transfer(address indexed src, address indexed dst, uint256 wad); diff --git a/packages/contracts-bedrock/test/dispute/DisputeGameFactory.t.sol b/packages/contracts-bedrock/test/dispute/DisputeGameFactory.t.sol index 09a087fb5d77..6c3ed2a18944 100644 --- a/packages/contracts-bedrock/test/dispute/DisputeGameFactory.t.sol +++ b/packages/contracts-bedrock/test/dispute/DisputeGameFactory.t.sol @@ -1,14 +1,20 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.15; +// Testing +import { Test } from "forge-std/Test.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; + +// Contracts +import { Proxy } from "src/universal/Proxy.sol"; + +// Libraries import "src/dispute/lib/Types.sol"; import "src/dispute/lib/Errors.sol"; -import { Test } from "forge-std/Test.sol"; -import { DisputeGameFactory, IDisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; +// Interfaces +import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol"; import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; -import { Proxy } from "src/universal/Proxy.sol"; -import { CommonTest } from "test/setup/CommonTest.sol"; contract DisputeGameFactory_Init is CommonTest { FakeClone fakeClone; diff --git a/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol b/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol index a12d0d991a4c..bc6537e460e4 100644 --- a/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol +++ b/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol @@ -1,35 +1,41 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.15; +// Testing import { Test } from "forge-std/Test.sol"; import { Vm } from "forge-std/Vm.sol"; import { DisputeGameFactory_Init } from "test/dispute/DisputeGameFactory.t.sol"; -import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; -import { FaultDisputeGame, IDisputeGame } from "src/dispute/FaultDisputeGame.sol"; -import { DelayedWETH } from "src/dispute/DelayedWETH.sol"; +import { AlphabetVM } from "test/mocks/AlphabetVM.sol"; + +// Contracts import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; +import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; +import { DisputeActor, HonestDisputeActor } from "test/actors/FaultDisputeActors.sol"; -import "src/dispute/lib/Types.sol"; -import "src/dispute/lib/Errors.sol"; +// Libraries import { Types } from "src/libraries/Types.sol"; import { Hashing } from "src/libraries/Hashing.sol"; import { RLPWriter } from "src/libraries/rlp/RLPWriter.sol"; import { LibClock } from "src/dispute/lib/LibUDT.sol"; import { LibPosition } from "src/dispute/lib/LibPosition.sol"; +import "src/dispute/lib/Types.sol"; +import "src/dispute/lib/Errors.sol"; + +// Interfaces +import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; import { IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol"; import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; -import { AlphabetVM } from "test/mocks/AlphabetVM.sol"; - -import { DisputeActor, HonestDisputeActor } from "test/actors/FaultDisputeActors.sol"; +import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; +import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; contract FaultDisputeGame_Init is DisputeGameFactory_Init { /// @dev The type of the game being tested. GameType internal constant GAME_TYPE = GameType.wrap(0); /// @dev The implementation of the game. - FaultDisputeGame internal gameImpl; + IFaultDisputeGame internal gameImpl; /// @dev The `Clone` proxy of the game. - FaultDisputeGame internal gameProxy; + IFaultDisputeGame internal gameProxy; /// @dev The extra data passed to the game for initialization. bytes internal extraData; @@ -51,23 +57,27 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init { AlphabetVM _vm = new AlphabetVM(absolutePrestate, oracle); // Deploy an implementation of the fault game - gameImpl = new FaultDisputeGame({ - _gameType: GAME_TYPE, - _absolutePrestate: absolutePrestate, - _maxGameDepth: 2 ** 3, - _splitDepth: 2 ** 2, - _clockExtension: Duration.wrap(3 hours), - _maxClockDuration: Duration.wrap(3.5 days), - _vm: _vm, - _weth: delayedWeth, - _anchorStateRegistry: anchorStateRegistry, - _l2ChainId: 10 - }); + gameImpl = IFaultDisputeGame( + address( + new FaultDisputeGame({ + _gameType: GAME_TYPE, + _absolutePrestate: absolutePrestate, + _maxGameDepth: 2 ** 3, + _splitDepth: 2 ** 2, + _clockExtension: Duration.wrap(3 hours), + _maxClockDuration: Duration.wrap(3.5 days), + _vm: _vm, + _weth: delayedWeth, + _anchorStateRegistry: anchorStateRegistry, + _l2ChainId: 10 + }) + ) + ); // Register the game implementation with the factory. disputeGameFactory.setImplementation(GAME_TYPE, gameImpl); // Create a new game. - gameProxy = FaultDisputeGame(payable(address(disputeGameFactory.create(GAME_TYPE, rootClaim, extraData)))); + gameProxy = IFaultDisputeGame(payable(address(disputeGameFactory.create(GAME_TYPE, rootClaim, extraData)))); // Check immutables assertEq(gameProxy.gameType().raw(), GAME_TYPE.raw()); @@ -125,7 +135,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { _clockExtension: Duration.wrap(3 hours), _maxClockDuration: Duration.wrap(3.5 days), _vm: alphabetVM, - _weth: DelayedWETH(payable(address(0))), + _weth: IDelayedWETH(payable(address(0))), _anchorStateRegistry: IAnchorStateRegistry(address(0)), _l2ChainId: 10 }); @@ -156,7 +166,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { _clockExtension: Duration.wrap(3 hours), _maxClockDuration: Duration.wrap(3.5 days), _vm: alphabetVM, - _weth: DelayedWETH(payable(address(0))), + _weth: IDelayedWETH(payable(address(0))), _anchorStateRegistry: IAnchorStateRegistry(address(0)), _l2ChainId: 10 }); @@ -178,7 +188,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { _clockExtension: Duration.wrap(3 hours), _maxClockDuration: Duration.wrap(3.5 days), _vm: alphabetVM, - _weth: DelayedWETH(payable(address(0))), + _weth: IDelayedWETH(payable(address(0))), _anchorStateRegistry: IAnchorStateRegistry(address(0)), _l2ChainId: 10 }); @@ -200,7 +210,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { _clockExtension: Duration.wrap(3 hours), _maxClockDuration: Duration.wrap(3.5 days), _vm: alphabetVM, - _weth: DelayedWETH(payable(address(0))), + _weth: IDelayedWETH(payable(address(0))), _anchorStateRegistry: IAnchorStateRegistry(address(0)), _l2ChainId: 10 }); @@ -230,7 +240,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { _clockExtension: Duration.wrap(_clockExtension), _maxClockDuration: Duration.wrap(_maxClockDuration), _vm: alphabetVM, - _weth: DelayedWETH(payable(address(0))), + _weth: IDelayedWETH(payable(address(0))), _anchorStateRegistry: IAnchorStateRegistry(address(0)), _l2ChainId: 10 }); @@ -278,7 +288,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { Claim claim = _dummyClaim(); vm.expectRevert(abi.encodeWithSelector(UnexpectedRootClaim.selector, claim)); gameProxy = - FaultDisputeGame(payable(address(disputeGameFactory.create(GAME_TYPE, claim, abi.encode(_blockNumber))))); + IFaultDisputeGame(payable(address(disputeGameFactory.create(GAME_TYPE, claim, abi.encode(_blockNumber))))); } /// @dev Tests that the proxy receives ETH from the dispute game factory. @@ -287,7 +297,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { vm.deal(address(this), _value); assertEq(address(gameProxy).balance, 0); - gameProxy = FaultDisputeGame( + gameProxy = IFaultDisputeGame( payable(address(disputeGameFactory.create{ value: _value }(GAME_TYPE, ROOT_CLAIM, abi.encode(1)))) ); assertEq(address(gameProxy).balance, 0); @@ -315,7 +325,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { Claim claim = _dummyClaim(); vm.expectRevert(abi.encodeWithSelector(BadExtraData.selector)); - gameProxy = FaultDisputeGame(payable(address(disputeGameFactory.create(GAME_TYPE, claim, _extraData)))); + gameProxy = IFaultDisputeGame(payable(address(disputeGameFactory.create(GAME_TYPE, claim, _extraData)))); } /// @dev Tests that the game is initialized with the correct data. @@ -2568,10 +2578,10 @@ contract FaultDispute_1v1_Actors_Test is FaultDisputeGame_Init { contract ClaimCreditReenter { Vm internal immutable vm; - FaultDisputeGame internal immutable GAME; + IFaultDisputeGame internal immutable GAME; uint256 public numCalls; - constructor(FaultDisputeGame _gameProxy, Vm _vm) { + constructor(IFaultDisputeGame _gameProxy, Vm _vm) { GAME = _gameProxy; vm = _vm; } diff --git a/packages/contracts-bedrock/test/dispute/PermissionedDisputeGame.t.sol b/packages/contracts-bedrock/test/dispute/PermissionedDisputeGame.t.sol index 571aab8b8d0f..8a3639b71cdf 100644 --- a/packages/contracts-bedrock/test/dispute/PermissionedDisputeGame.t.sol +++ b/packages/contracts-bedrock/test/dispute/PermissionedDisputeGame.t.sol @@ -1,24 +1,26 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.15; +// Testing import { Test } from "forge-std/Test.sol"; import { Vm } from "forge-std/Vm.sol"; import { DisputeGameFactory_Init } from "test/dispute/DisputeGameFactory.t.sol"; -import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; +import { AlphabetVM } from "test/mocks/AlphabetVM.sol"; + +// Contracts import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; -import { DelayedWETH } from "src/dispute/DelayedWETH.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; -import { PreimageKeyLib } from "src/cannon/PreimageKeyLib.sol"; +import { DelayedWETH } from "src/dispute/DelayedWETH.sol"; +// Libraries +import { Types } from "src/libraries/Types.sol"; import "src/dispute/lib/Types.sol"; import "src/dispute/lib/Errors.sol"; -import { Types } from "src/libraries/Types.sol"; -import { LibClock } from "src/dispute/lib/LibUDT.sol"; -import { LibPosition } from "src/dispute/lib/LibPosition.sol"; -import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol"; -import { AlphabetVM } from "test/mocks/AlphabetVM.sol"; -import { DisputeActor, HonestDisputeActor } from "test/actors/FaultDisputeActors.sol"; +// Interfaces +import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol"; +import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; +import { IPermissionedDisputeGame } from "src/dispute/interfaces/IPermissionedDisputeGame.sol"; contract PermissionedDisputeGame_Init is DisputeGameFactory_Init { /// @dev The type of the game being tested. @@ -29,9 +31,9 @@ contract PermissionedDisputeGame_Init is DisputeGameFactory_Init { address internal constant CHALLENGER = address(0xfacadec); /// @dev The implementation of the game. - PermissionedDisputeGame internal gameImpl; + IPermissionedDisputeGame internal gameImpl; /// @dev The `Clone` proxy of the game. - PermissionedDisputeGame internal gameProxy; + IPermissionedDisputeGame internal gameProxy; /// @dev The extra data passed to the game for initialization. bytes internal extraData; @@ -48,29 +50,33 @@ contract PermissionedDisputeGame_Init is DisputeGameFactory_Init { AlphabetVM _vm = new AlphabetVM(absolutePrestate, new PreimageOracle(0, 0)); // Use a 7 day delayed WETH to simulate withdrawals. - DelayedWETH _weth = new DelayedWETH(7 days); + IDelayedWETH _weth = IDelayedWETH(payable(new DelayedWETH(7 days))); // Deploy an implementation of the fault game - gameImpl = new PermissionedDisputeGame({ - _gameType: GAME_TYPE, - _absolutePrestate: absolutePrestate, - _maxGameDepth: 2 ** 3, - _splitDepth: 2 ** 2, - _clockExtension: Duration.wrap(3 hours), - _maxClockDuration: Duration.wrap(3.5 days), - _vm: _vm, - _weth: _weth, - _anchorStateRegistry: anchorStateRegistry, - _l2ChainId: 10, - _proposer: PROPOSER, - _challenger: CHALLENGER - }); + gameImpl = IPermissionedDisputeGame( + address( + new PermissionedDisputeGame({ + _gameType: GAME_TYPE, + _absolutePrestate: absolutePrestate, + _maxGameDepth: 2 ** 3, + _splitDepth: 2 ** 2, + _clockExtension: Duration.wrap(3 hours), + _maxClockDuration: Duration.wrap(3.5 days), + _vm: _vm, + _weth: _weth, + _anchorStateRegistry: anchorStateRegistry, + _l2ChainId: 10, + _proposer: PROPOSER, + _challenger: CHALLENGER + }) + ) + ); // Register the game implementation with the factory. disputeGameFactory.setImplementation(GAME_TYPE, gameImpl); // Create a new game. vm.prank(PROPOSER, PROPOSER); gameProxy = - PermissionedDisputeGame(payable(address(disputeGameFactory.create(GAME_TYPE, rootClaim, extraData)))); + IPermissionedDisputeGame(payable(address(disputeGameFactory.create(GAME_TYPE, rootClaim, extraData)))); // Check immutables assertEq(gameProxy.proposer(), PROPOSER); diff --git a/packages/contracts-bedrock/test/invariants/FaultDisputeGame.t.sol b/packages/contracts-bedrock/test/invariants/FaultDisputeGame.t.sol index 295b9f315abf..49bf2a106bbf 100644 --- a/packages/contracts-bedrock/test/invariants/FaultDisputeGame.t.sol +++ b/packages/contracts-bedrock/test/invariants/FaultDisputeGame.t.sol @@ -1,14 +1,18 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Testing import { Vm } from "forge-std/Vm.sol"; import { StdUtils } from "forge-std/StdUtils.sol"; -import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; import { FaultDisputeGame_Init } from "test/dispute/FaultDisputeGame.t.sol"; +// Libraries import "src/dispute/lib/Types.sol"; import "src/dispute/lib/Errors.sol"; +// Interfaces +import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; + contract FaultDisputeGame_Solvency_Invariant is FaultDisputeGame_Init { Claim internal constant ROOT_CLAIM = Claim.wrap(bytes32(uint256(10))); Claim internal constant ABSOLUTE_PRESTATE = Claim.wrap(bytes32((uint256(3) << 248) | uint256(0))); @@ -73,12 +77,12 @@ contract FaultDisputeGame_Solvency_Invariant is FaultDisputeGame_Init { } contract RandomClaimActor is StdUtils { - FaultDisputeGame internal immutable GAME; + IFaultDisputeGame internal immutable GAME; Vm internal immutable VM; uint256 public totalBonded; - constructor(FaultDisputeGame _gameProxy, Vm _vm) { + constructor(IFaultDisputeGame _gameProxy, Vm _vm) { GAME = _gameProxy; VM = _vm; } diff --git a/packages/contracts-bedrock/test/invariants/OptimismPortal2.t.sol b/packages/contracts-bedrock/test/invariants/OptimismPortal2.t.sol index ef96f3eb5c4f..dec4525a0094 100644 --- a/packages/contracts-bedrock/test/invariants/OptimismPortal2.t.sol +++ b/packages/contracts-bedrock/test/invariants/OptimismPortal2.t.sol @@ -1,23 +1,26 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Testing import { StdUtils } from "forge-std/Test.sol"; import { Vm } from "forge-std/Vm.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; -import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; -import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; +// Contracts import { ResourceMetering } from "src/L1/ResourceMetering.sol"; -import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; -import { Constants } from "src/libraries/Constants.sol"; -import { CommonTest } from "test/setup/CommonTest.sol"; -import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; +// Libraries +import { Constants } from "src/libraries/Constants.sol"; import { Types } from "src/libraries/Types.sol"; - -import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; import "src/dispute/lib/Types.sol"; import "src/libraries/PortalErrors.sol"; +// Interfaces +import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; +import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; +import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; + contract OptimismPortal2_Depositor is StdUtils, ResourceMetering { Vm internal vm; IOptimismPortal2 internal portal; @@ -118,7 +121,7 @@ contract OptimismPortal2_Invariant_Harness is CommonTest { // Create a dispute game with the output root we've proposed. _proposedBlockNumber = 0xFF; - FaultDisputeGame game = FaultDisputeGame( + IFaultDisputeGame game = IFaultDisputeGame( payable( address( disputeGameFactory.create( diff --git a/packages/contracts-bedrock/test/safe/DeputyGuardianModule.t.sol b/packages/contracts-bedrock/test/safe/DeputyGuardianModule.t.sol index 9ebc60d6100d..84824a5ff694 100644 --- a/packages/contracts-bedrock/test/safe/DeputyGuardianModule.t.sol +++ b/packages/contracts-bedrock/test/safe/DeputyGuardianModule.t.sol @@ -1,18 +1,23 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +// Testing import { CommonTest } from "test/setup/CommonTest.sol"; import { ForgeArtifacts, Abi } from "scripts/libraries/ForgeArtifacts.sol"; import { GnosisSafe as Safe } from "safe-contracts/GnosisSafe.sol"; import "test/safe-tools/SafeTestTools.sol"; -import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; -import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; -import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; +// Contracts import { DeputyGuardianModule } from "src/safe/DeputyGuardianModule.sol"; +// Libraries import "src/dispute/lib/Types.sol"; +// Interfaces +import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; +import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; +import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; + contract DeputyGuardianModule_TestInit is CommonTest, SafeTestTools { using SafeTestLib for SafeInstance; @@ -152,13 +157,13 @@ contract DeputyGuardianModule_Unpause_TestFail is DeputyGuardianModule_Unpause_T contract DeputyGuardianModule_SetAnchorState_TestFail is DeputyGuardianModule_TestInit { function test_setAnchorState_notDeputyGuardian_reverts() external { - AnchorStateRegistry asr = AnchorStateRegistry(makeAddr("asr")); + IAnchorStateRegistry asr = IAnchorStateRegistry(makeAddr("asr")); vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector)); deputyGuardianModule.setAnchorState(asr, IFaultDisputeGame(address(0))); } function test_setAnchorState_targetReverts_reverts() external { - AnchorStateRegistry asr = AnchorStateRegistry(makeAddr("asr")); + IAnchorStateRegistry asr = IAnchorStateRegistry(makeAddr("asr")); vm.mockCallRevert( address(asr), abi.encodeWithSelector(asr.setAnchorState.selector), @@ -174,10 +179,10 @@ contract DeputyGuardianModule_SetAnchorState_TestFail is DeputyGuardianModule_Te contract DeputyGuardianModule_SetAnchorState_Test is DeputyGuardianModule_TestInit { function test_setAnchorState_succeeds() external { - AnchorStateRegistry asr = AnchorStateRegistry(makeAddr("asr")); + IAnchorStateRegistry asr = IAnchorStateRegistry(makeAddr("asr")); vm.mockCall( address(asr), - abi.encodeWithSelector(AnchorStateRegistry.setAnchorState.selector, IFaultDisputeGame(address(0))), + abi.encodeWithSelector(IAnchorStateRegistry.setAnchorState.selector, IFaultDisputeGame(address(0))), "" ); vm.expectEmit(address(safeInstance.safe)); diff --git a/packages/contracts-bedrock/test/setup/Setup.sol b/packages/contracts-bedrock/test/setup/Setup.sol index f2b29e8f1a91..3a09519203ac 100644 --- a/packages/contracts-bedrock/test/setup/Setup.sol +++ b/packages/contracts-bedrock/test/setup/Setup.sol @@ -13,11 +13,6 @@ import { L2Genesis, L1Dependencies } from "scripts/L2Genesis.s.sol"; import { OutputMode, Fork, ForkUtils } from "scripts/libraries/Config.sol"; import { Executables } from "scripts/libraries/Executables.sol"; -// Contracts -import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; -import { DelayedWETH } from "src/dispute/DelayedWETH.sol"; -import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; - // Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; import { Preinstalls } from "src/libraries/Preinstalls.sol"; @@ -34,6 +29,9 @@ import { IDataAvailabilityChallenge } from "src/L1/interfaces/IDataAvailabilityC import { IL1StandardBridge } from "src/L1/interfaces/IL1StandardBridge.sol"; import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol"; import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; +import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol"; +import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; +import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; import { IL2CrossDomainMessenger } from "src/L2/interfaces/IL2CrossDomainMessenger.sol"; import { IL2StandardBridgeInterop } from "src/L2/interfaces/IL2StandardBridgeInterop.sol"; import { IL2ToL1MessagePasser } from "src/L2/interfaces/IL2ToL1MessagePasser.sol"; @@ -74,9 +72,9 @@ contract Setup { Fork l2Fork = LATEST_FORK; // L1 contracts - DisputeGameFactory disputeGameFactory; - AnchorStateRegistry anchorStateRegistry; - DelayedWETH delayedWeth; + IDisputeGameFactory disputeGameFactory; + IAnchorStateRegistry anchorStateRegistry; + IDelayedWETH delayedWeth; IOptimismPortal optimismPortal; IOptimismPortal2 optimismPortal2; IL2OutputOracle l2OutputOracle; @@ -147,8 +145,8 @@ contract Setup { optimismPortal = IOptimismPortal(deploy.mustGetAddress("OptimismPortalProxy")); optimismPortal2 = IOptimismPortal2(deploy.mustGetAddress("OptimismPortalProxy")); - disputeGameFactory = DisputeGameFactory(deploy.mustGetAddress("DisputeGameFactoryProxy")); - delayedWeth = DelayedWETH(deploy.mustGetAddress("DelayedWETHProxy")); + disputeGameFactory = IDisputeGameFactory(deploy.mustGetAddress("DisputeGameFactoryProxy")); + delayedWeth = IDelayedWETH(deploy.mustGetAddress("DelayedWETHProxy")); l2OutputOracle = IL2OutputOracle(deploy.mustGetAddress("L2OutputOracleProxy")); systemConfig = ISystemConfig(deploy.mustGetAddress("SystemConfigProxy")); l1StandardBridge = IL1StandardBridge(deploy.mustGetAddress("L1StandardBridgeProxy")); @@ -159,7 +157,7 @@ contract Setup { IOptimismMintableERC20Factory(deploy.mustGetAddress("OptimismMintableERC20FactoryProxy")); protocolVersions = IProtocolVersions(deploy.mustGetAddress("ProtocolVersionsProxy")); superchainConfig = ISuperchainConfig(deploy.mustGetAddress("SuperchainConfigProxy")); - anchorStateRegistry = AnchorStateRegistry(deploy.mustGetAddress("AnchorStateRegistryProxy")); + anchorStateRegistry = IAnchorStateRegistry(deploy.mustGetAddress("AnchorStateRegistryProxy")); vm.label(address(l2OutputOracle), "L2OutputOracle"); vm.label(deploy.mustGetAddress("L2OutputOracleProxy"), "L2OutputOracleProxy"); diff --git a/packages/contracts-bedrock/test/vendor/Initializable.t.sol b/packages/contracts-bedrock/test/vendor/Initializable.t.sol index c5c8487e2428..d5c1a9e5e4c3 100644 --- a/packages/contracts-bedrock/test/vendor/Initializable.t.sol +++ b/packages/contracts-bedrock/test/vendor/Initializable.t.sol @@ -9,11 +9,6 @@ import { Executables } from "scripts/libraries/Executables.sol"; import { ForgeArtifacts, StorageSlot } from "scripts/libraries/ForgeArtifacts.sol"; import { Process } from "scripts/libraries/Process.sol"; -// Contracts -import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; -import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; -import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; - // Libraries import { LibString } from "@solady/utils/LibString.sol"; import { Constants } from "src/libraries/Constants.sol"; @@ -26,6 +21,7 @@ import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { ProtocolVersion } from "src/L1/interfaces/IProtocolVersions.sol"; +import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; /// @title Initializer_Test /// @dev Ensures that the `initialize()` function on contracts cannot be called more than @@ -372,7 +368,7 @@ contract Initializer_Test is Bridge_Initializer { target: address(anchorStateRegistry), initCalldata: abi.encodeCall( anchorStateRegistry.initialize, - (new AnchorStateRegistry.StartingAnchorRoot[](1), ISuperchainConfig(address(0))) + (new IAnchorStateRegistry.StartingAnchorRoot[](1), ISuperchainConfig(address(0))) ) }) ); @@ -383,7 +379,7 @@ contract Initializer_Test is Bridge_Initializer { target: address(anchorStateRegistry), initCalldata: abi.encodeCall( anchorStateRegistry.initialize, - (new AnchorStateRegistry.StartingAnchorRoot[](1), ISuperchainConfig(address(0))) + (new IAnchorStateRegistry.StartingAnchorRoot[](1), ISuperchainConfig(address(0))) ) }) ); From 3c3a3113aa568a8a0d96283b1a62445d7ed4b367 Mon Sep 17 00:00:00 2001 From: Adrian Sutton <adrian@oplabs.co> Date: Fri, 20 Sep 2024 13:09:34 +1000 Subject: [PATCH 214/264] op-challenger: Use a wrapper to specify the vm type for metrics (#12020) * op-challenger: Use a wrapper to specify the vm type for metrics Decouples the vm type from the trace type to give the run-trace subcommand more flexibility, allowing it to report separate metrics for cannon and mt-cannon. Also adjust the run-trace loggers to consistently use `mt-cannon` as the type. * Use constant. Co-authored-by: Inphi <mlaw2501@gmail.com> --------- Co-authored-by: Inphi <mlaw2501@gmail.com> --- .../fault/trace/outputs/output_asterisc.go | 2 +- .../game/fault/trace/outputs/output_cannon.go | 2 +- op-challenger/game/fault/trace/vm/executor.go | 8 +++--- .../game/fault/trace/vm/executor_test.go | 7 +++-- op-challenger/metrics/metrics.go | 10 +++++-- op-challenger/metrics/noop.go | 4 +++ op-challenger/metrics/vm.go | 28 +++++++++++++++++++ op-challenger/runner/runner.go | 23 ++++++++------- .../disputegame/output_cannon_helper.go | 2 +- op-e2e/faultproofs/precompile_test.go | 2 +- 10 files changed, 65 insertions(+), 23 deletions(-) create mode 100644 op-challenger/metrics/vm.go diff --git a/op-challenger/game/fault/trace/outputs/output_asterisc.go b/op-challenger/game/fault/trace/outputs/output_asterisc.go index 726b57e551d7..82dac14f8453 100644 --- a/op-challenger/game/fault/trace/outputs/output_asterisc.go +++ b/op-challenger/game/fault/trace/outputs/output_asterisc.go @@ -41,7 +41,7 @@ func NewOutputAsteriscTraceAccessor( if err != nil { return nil, fmt.Errorf("failed to fetch asterisc local inputs: %w", err) } - provider := asterisc.NewTraceProvider(logger, m, cfg, vmCfg, prestateProvider, asteriscPrestate, localInputs, subdir, depth) + provider := asterisc.NewTraceProvider(logger, m.VmMetrics(cfg.VmType.String()), cfg, vmCfg, prestateProvider, asteriscPrestate, localInputs, subdir, depth) return provider, nil } diff --git a/op-challenger/game/fault/trace/outputs/output_cannon.go b/op-challenger/game/fault/trace/outputs/output_cannon.go index 1f9c4285a354..49b6631b5a7f 100644 --- a/op-challenger/game/fault/trace/outputs/output_cannon.go +++ b/op-challenger/game/fault/trace/outputs/output_cannon.go @@ -41,7 +41,7 @@ func NewOutputCannonTraceAccessor( if err != nil { return nil, fmt.Errorf("failed to fetch cannon local inputs: %w", err) } - provider := cannon.NewTraceProvider(logger, m, cfg, serverExecutor, prestateProvider, cannonPrestate, localInputs, subdir, depth) + provider := cannon.NewTraceProvider(logger, m.VmMetrics(cfg.VmType.String()), cfg, serverExecutor, prestateProvider, cannonPrestate, localInputs, subdir, depth) return provider, nil } diff --git a/op-challenger/game/fault/trace/vm/executor.go b/op-challenger/game/fault/trace/vm/executor.go index d2f80899b3e1..9e2cd0d29e93 100644 --- a/op-challenger/game/fault/trace/vm/executor.go +++ b/op-challenger/game/fault/trace/vm/executor.go @@ -22,8 +22,8 @@ const ( ) type Metricer interface { - RecordVmExecutionTime(vmType string, t time.Duration) - RecordVmMemoryUsed(vmType string, memoryUsed uint64) + RecordExecutionTime(t time.Duration) + RecordMemoryUsed(memoryUsed uint64) } type Config struct { @@ -133,12 +133,12 @@ func (e *Executor) DoGenerateProof(ctx context.Context, dir string, begin uint64 err = e.cmdExecutor(ctx, e.logger.New("proof", end), e.cfg.VmBin, args...) execTime := time.Since(execStart) memoryUsed := "unknown" - e.metrics.RecordVmExecutionTime(e.cfg.VmType.String(), execTime) + e.metrics.RecordExecutionTime(execTime) if e.cfg.DebugInfo && err == nil { if info, err := jsonutil.LoadJSON[debugInfo](filepath.Join(dataDir, debugFilename)); err != nil { e.logger.Warn("Failed to load debug metrics", "err", err) } else { - e.metrics.RecordVmMemoryUsed(e.cfg.VmType.String(), uint64(info.MemoryUsed)) + e.metrics.RecordMemoryUsed(uint64(info.MemoryUsed)) memoryUsed = fmt.Sprintf("%d", uint64(info.MemoryUsed)) } } diff --git a/op-challenger/game/fault/trace/vm/executor_test.go b/op-challenger/game/fault/trace/vm/executor_test.go index f7738036e774..ff4a8ba7e1ab 100644 --- a/op-challenger/game/fault/trace/vm/executor_test.go +++ b/op-challenger/game/fault/trace/vm/executor_test.go @@ -9,7 +9,6 @@ import ( "time" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" - "github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" @@ -145,10 +144,12 @@ func TestGenerateProof(t *testing.T) { } type stubVmMetrics struct { - metrics.NoopMetricsImpl executionTimeRecordCount int } -func (c *stubVmMetrics) RecordVmExecutionTime(_ string, _ time.Duration) { +func (c *stubVmMetrics) RecordExecutionTime(_ time.Duration) { c.executionTimeRecordCount++ } + +func (c *stubVmMetrics) RecordMemoryUsed(_ uint64) { +} diff --git a/op-challenger/metrics/metrics.go b/op-challenger/metrics/metrics.go index fdea90841a04..c6acc2b2f7bb 100644 --- a/op-challenger/metrics/metrics.go +++ b/op-challenger/metrics/metrics.go @@ -38,8 +38,6 @@ type Metricer interface { RecordGameStep() RecordGameMove() RecordGameL2Challenge() - RecordVmExecutionTime(vmType string, t time.Duration) - RecordVmMemoryUsed(vmType string, memoryUsed uint64) RecordClaimResolutionTime(t float64) RecordGameActTime(t float64) @@ -60,6 +58,10 @@ type Metricer interface { DecActiveExecutors() IncIdleExecutors() DecIdleExecutors() + + // Record vm execution metrics + VmMetricer + VmMetrics(vmType string) *VmMetrics } // Metrics implementation must implement RegistryMetricer to allow the metrics server to work. @@ -339,3 +341,7 @@ func (m *Metrics) RecordGameUpdateScheduled() { func (m *Metrics) RecordGameUpdateCompleted() { m.inflightGames.Sub(1) } + +func (m *Metrics) VmMetrics(vmType string) *VmMetrics { + return NewVmMetrics(m, vmType) +} diff --git a/op-challenger/metrics/noop.go b/op-challenger/metrics/noop.go index 99a89965aa21..84b5923a33d9 100644 --- a/op-challenger/metrics/noop.go +++ b/op-challenger/metrics/noop.go @@ -56,3 +56,7 @@ func (*NoopMetricsImpl) DecIdleExecutors() {} func (*NoopMetricsImpl) CacheAdd(_ string, _ int, _ bool) {} func (*NoopMetricsImpl) CacheGet(_ string, _ bool) {} + +func (m *NoopMetricsImpl) VmMetrics(vmType string) *VmMetrics { + return NewVmMetrics(m, vmType) +} diff --git a/op-challenger/metrics/vm.go b/op-challenger/metrics/vm.go new file mode 100644 index 000000000000..70e9a363cb36 --- /dev/null +++ b/op-challenger/metrics/vm.go @@ -0,0 +1,28 @@ +package metrics + +import "time" + +type VmMetricer interface { + RecordVmExecutionTime(vmType string, t time.Duration) + RecordVmMemoryUsed(vmType string, memoryUsed uint64) +} + +type VmMetrics struct { + m VmMetricer + vmType string +} + +func NewVmMetrics(m VmMetricer, vmType string) *VmMetrics { + return &VmMetrics{ + m: m, + vmType: vmType, + } +} + +func (m *VmMetrics) RecordExecutionTime(dur time.Duration) { + m.m.RecordVmExecutionTime(m.vmType, dur) +} + +func (m *VmMetrics) RecordMemoryUsed(memoryUsed uint64) { + m.m.RecordVmMemoryUsed(m.vmType, memoryUsed) +} diff --git a/op-challenger/runner/runner.go b/op-challenger/runner/runner.go index f5c95439357e..e787f35343eb 100644 --- a/op-challenger/runner/runner.go +++ b/op-challenger/runner/runner.go @@ -17,8 +17,8 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" contractMetrics "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-service/cliapp" "github.com/ethereum-optimism/optimism/op-service/dial" "github.com/ethereum-optimism/optimism/op-service/httputil" @@ -29,14 +29,17 @@ import ( "github.com/ethereum/go-ethereum/log" ) +const mtCannonType = "mt-cannon" + var ( ErrUnexpectedStatusCode = errors.New("unexpected status code") ) type Metricer interface { - vm.Metricer contractMetrics.ContractMetricer + RecordVmExecutionTime(vmType string, t time.Duration) + RecordVmMemoryUsed(vmType string, memoryUsed uint64) RecordFailure(vmType string) RecordInvalid(vmType string) RecordSuccess(vmType string) @@ -155,21 +158,21 @@ func (r *Runner) runAndRecordOnce(ctx context.Context, traceType types.TraceType wg.Add(1) go func() { defer wg.Done() - dir, err := r.prepDatadir("mt-cannon") + dir, err := r.prepDatadir(mtCannonType) if err != nil { - recordError(err, "mt-cannon", r.m, r.log) + recordError(err, mtCannonType, r.m, r.log) return } - logger := inputsLogger.With("type", "mt-cannon") - err = r.runMTOnce(ctx, logger, traceType, prestateHash, localInputs, dir) - recordError(err, traceType.String(), r.m, r.log.With("mt-cannon", true)) + logger := inputsLogger.With("type", mtCannonType) + err = r.runMTOnce(ctx, logger, localInputs, dir) + recordError(err, mtCannonType, r.m, r.log.With(mtCannonType, true)) }() } wg.Wait() } func (r *Runner) runOnce(ctx context.Context, logger log.Logger, traceType types.TraceType, prestateHash common.Hash, localInputs utils.LocalGameInputs, dir string) error { - provider, err := createTraceProvider(logger, r.m, r.cfg, prestateHash, traceType, localInputs, dir) + provider, err := createTraceProvider(logger, metrics.NewVmMetrics(r.m, traceType.String()), r.cfg, prestateHash, traceType, localInputs, dir) if err != nil { return fmt.Errorf("failed to create trace provider: %w", err) } @@ -183,8 +186,8 @@ func (r *Runner) runOnce(ctx context.Context, logger log.Logger, traceType types return nil } -func (r *Runner) runMTOnce(ctx context.Context, logger log.Logger, traceType types.TraceType, prestateHash common.Hash, localInputs utils.LocalGameInputs, dir string) error { - provider, err := createMTTraceProvider(logger, r.m, r.cfg.Cannon, r.addMTCannonPrestate, r.addMTCannonPrestateURL, types.TraceTypeCannon, localInputs, dir) +func (r *Runner) runMTOnce(ctx context.Context, logger log.Logger, localInputs utils.LocalGameInputs, dir string) error { + provider, err := createMTTraceProvider(logger, metrics.NewVmMetrics(r.m, mtCannonType), r.cfg.Cannon, r.addMTCannonPrestate, r.addMTCannonPrestateURL, types.TraceTypeCannon, localInputs, dir) if err != nil { return fmt.Errorf("failed to create trace provider: %w", err) } diff --git a/op-e2e/e2eutils/disputegame/output_cannon_helper.go b/op-e2e/e2eutils/disputegame/output_cannon_helper.go index fdb8fd6b3195..a4e017f9c980 100644 --- a/op-e2e/e2eutils/disputegame/output_cannon_helper.go +++ b/op-e2e/e2eutils/disputegame/output_cannon_helper.go @@ -316,7 +316,7 @@ func (g *OutputCannonGameHelper) createCannonTraceProvider(ctx context.Context, localContext = outputs.CreateLocalContext(pre, post) dir := filepath.Join(cfg.Datadir, "cannon-trace") subdir := filepath.Join(dir, localContext.Hex()) - return cannon.NewTraceProviderForTest(logger, metrics.NoopMetrics, cfg, localInputs, subdir, g.MaxDepth(ctx)-splitDepth-1), nil + return cannon.NewTraceProviderForTest(logger, metrics.NoopMetrics.VmMetrics(types.TraceTypeCannon.String()), cfg, localInputs, subdir, g.MaxDepth(ctx)-splitDepth-1), nil }) claims, err := g.Game.GetAllClaims(ctx, rpcblock.Latest) diff --git a/op-e2e/faultproofs/precompile_test.go b/op-e2e/faultproofs/precompile_test.go index 82a8c2e397c6..aebe6a8fd1a9 100644 --- a/op-e2e/faultproofs/precompile_test.go +++ b/op-e2e/faultproofs/precompile_test.go @@ -257,7 +257,7 @@ func runCannon(t *testing.T, ctx context.Context, sys *e2esys.System, inputs uti cannonOpts(&cfg) logger := testlog.Logger(t, log.LevelInfo).New("role", "cannon") - executor := vm.NewExecutor(logger, metrics.NoopMetrics, cfg.Cannon, vm.NewOpProgramServerExecutor(), cfg.CannonAbsolutePreState, inputs) + executor := vm.NewExecutor(logger, metrics.NoopMetrics.VmMetrics("cannon"), cfg.Cannon, vm.NewOpProgramServerExecutor(), cfg.CannonAbsolutePreState, inputs) t.Log("Running cannon") err := executor.DoGenerateProof(ctx, proofsDir, math.MaxUint, math.MaxUint, extraVmArgs...) From 2fcbe4bab16a682bd51c2f0e6bd9be7f8d81c7a1 Mon Sep 17 00:00:00 2001 From: Axel Kingsley <axel.kingsley@gmail.com> Date: Thu, 19 Sep 2024 22:23:03 -0500 Subject: [PATCH 215/264] SuperSystem: Add Emitter Contract - Basic Message Passing (#11956) * Add Emitter Contract * Emitter Contract and Bindings * AddL2RPC without Stopping * Rename testdata folder to contracts * update generate.sh * update solidity and gen script --- op-e2e/interop/contracts/emit.go | 368 ++++++++++++++++++ op-e2e/interop/contracts/foundry.toml | 31 ++ op-e2e/interop/contracts/generate.sh | 12 + op-e2e/interop/contracts/src/emit.sol | 12 + .../test-artifacts/emit.sol/EmitEvent.abi | 28 ++ .../test-artifacts/emit.sol/EmitEvent.bin | 1 + .../test-artifacts/emit.sol/EmitEvent.json | 1 + op-e2e/interop/interop_test.go | 17 +- op-e2e/interop/supersystem.go | 60 ++- op-supervisor/supervisor/backend/backend.go | 27 +- op-supervisor/supervisor/backend/db/db.go | 12 +- .../supervisor/backend/db/entrydb/entry_db.go | 2 +- 12 files changed, 547 insertions(+), 24 deletions(-) create mode 100644 op-e2e/interop/contracts/emit.go create mode 100644 op-e2e/interop/contracts/foundry.toml create mode 100755 op-e2e/interop/contracts/generate.sh create mode 100644 op-e2e/interop/contracts/src/emit.sol create mode 100644 op-e2e/interop/contracts/test-artifacts/emit.sol/EmitEvent.abi create mode 100644 op-e2e/interop/contracts/test-artifacts/emit.sol/EmitEvent.bin create mode 100644 op-e2e/interop/contracts/test-artifacts/emit.sol/EmitEvent.json diff --git a/op-e2e/interop/contracts/emit.go b/op-e2e/interop/contracts/emit.go new file mode 100644 index 000000000000..ceae2412659b --- /dev/null +++ b/op-e2e/interop/contracts/emit.go @@ -0,0 +1,368 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package emit + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// EmitMetaData contains all meta data concerning the Emit contract. +var EmitMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"function\",\"name\":\"emitData\",\"inputs\":[{\"name\":\"_data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"DataEmitted\",\"inputs\":[{\"name\":\"_data\",\"type\":\"bytes\",\"indexed\":true,\"internalType\":\"bytes\"}],\"anonymous\":false}]", + Bin: "0x6080604052348015600e575f80fd5b5060ff8061001b5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c8063d836083e14602a575b5f80fd5b60396035366004607c565b603b565b005b8181604051604992919060e3565b604051908190038120907fe00bbfe6f6f8f1bbed2da38e3f5a139c6f9da594ab248a3cf8b44fc73627772c905f90a25050565b5f8060208385031215608c575f80fd5b823567ffffffffffffffff8082111560a2575f80fd5b818501915085601f83011260b4575f80fd5b81358181111560c1575f80fd5b86602082850101111560d1575f80fd5b60209290920196919550909350505050565b818382375f910190815291905056fea164736f6c6343000819000a", +} + +// EmitABI is the input ABI used to generate the binding from. +// Deprecated: Use EmitMetaData.ABI instead. +var EmitABI = EmitMetaData.ABI + +// EmitBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use EmitMetaData.Bin instead. +var EmitBin = EmitMetaData.Bin + +// DeployEmit deploys a new Ethereum contract, binding an instance of Emit to it. +func DeployEmit(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Emit, error) { + parsed, err := EmitMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EmitBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Emit{EmitCaller: EmitCaller{contract: contract}, EmitTransactor: EmitTransactor{contract: contract}, EmitFilterer: EmitFilterer{contract: contract}}, nil +} + +// Emit is an auto generated Go binding around an Ethereum contract. +type Emit struct { + EmitCaller // Read-only binding to the contract + EmitTransactor // Write-only binding to the contract + EmitFilterer // Log filterer for contract events +} + +// EmitCaller is an auto generated read-only Go binding around an Ethereum contract. +type EmitCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// EmitTransactor is an auto generated write-only Go binding around an Ethereum contract. +type EmitTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// EmitFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type EmitFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// EmitSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type EmitSession struct { + Contract *Emit // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// EmitCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type EmitCallerSession struct { + Contract *EmitCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// EmitTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type EmitTransactorSession struct { + Contract *EmitTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// EmitRaw is an auto generated low-level Go binding around an Ethereum contract. +type EmitRaw struct { + Contract *Emit // Generic contract binding to access the raw methods on +} + +// EmitCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type EmitCallerRaw struct { + Contract *EmitCaller // Generic read-only contract binding to access the raw methods on +} + +// EmitTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type EmitTransactorRaw struct { + Contract *EmitTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewEmit creates a new instance of Emit, bound to a specific deployed contract. +func NewEmit(address common.Address, backend bind.ContractBackend) (*Emit, error) { + contract, err := bindEmit(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Emit{EmitCaller: EmitCaller{contract: contract}, EmitTransactor: EmitTransactor{contract: contract}, EmitFilterer: EmitFilterer{contract: contract}}, nil +} + +// NewEmitCaller creates a new read-only instance of Emit, bound to a specific deployed contract. +func NewEmitCaller(address common.Address, caller bind.ContractCaller) (*EmitCaller, error) { + contract, err := bindEmit(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &EmitCaller{contract: contract}, nil +} + +// NewEmitTransactor creates a new write-only instance of Emit, bound to a specific deployed contract. +func NewEmitTransactor(address common.Address, transactor bind.ContractTransactor) (*EmitTransactor, error) { + contract, err := bindEmit(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &EmitTransactor{contract: contract}, nil +} + +// NewEmitFilterer creates a new log filterer instance of Emit, bound to a specific deployed contract. +func NewEmitFilterer(address common.Address, filterer bind.ContractFilterer) (*EmitFilterer, error) { + contract, err := bindEmit(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &EmitFilterer{contract: contract}, nil +} + +// bindEmit binds a generic wrapper to an already deployed contract. +func bindEmit(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := EmitMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Emit *EmitRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Emit.Contract.EmitCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Emit *EmitRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Emit.Contract.EmitTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Emit *EmitRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Emit.Contract.EmitTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Emit *EmitCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Emit.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Emit *EmitTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Emit.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Emit *EmitTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Emit.Contract.contract.Transact(opts, method, params...) +} + +// EmitData is a paid mutator transaction binding the contract method 0xd836083e. +// +// Solidity: function emitData(bytes _data) returns() +func (_Emit *EmitTransactor) EmitData(opts *bind.TransactOpts, _data []byte) (*types.Transaction, error) { + return _Emit.contract.Transact(opts, "emitData", _data) +} + +// EmitData is a paid mutator transaction binding the contract method 0xd836083e. +// +// Solidity: function emitData(bytes _data) returns() +func (_Emit *EmitSession) EmitData(_data []byte) (*types.Transaction, error) { + return _Emit.Contract.EmitData(&_Emit.TransactOpts, _data) +} + +// EmitData is a paid mutator transaction binding the contract method 0xd836083e. +// +// Solidity: function emitData(bytes _data) returns() +func (_Emit *EmitTransactorSession) EmitData(_data []byte) (*types.Transaction, error) { + return _Emit.Contract.EmitData(&_Emit.TransactOpts, _data) +} + +// EmitDataEmittedIterator is returned from FilterDataEmitted and is used to iterate over the raw logs and unpacked data for DataEmitted events raised by the Emit contract. +type EmitDataEmittedIterator struct { + Event *EmitDataEmitted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EmitDataEmittedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EmitDataEmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EmitDataEmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EmitDataEmittedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EmitDataEmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EmitDataEmitted represents a DataEmitted event raised by the Emit contract. +type EmitDataEmitted struct { + Data common.Hash + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDataEmitted is a free log retrieval operation binding the contract event 0xe00bbfe6f6f8f1bbed2da38e3f5a139c6f9da594ab248a3cf8b44fc73627772c. +// +// Solidity: event DataEmitted(bytes indexed _data) +func (_Emit *EmitFilterer) FilterDataEmitted(opts *bind.FilterOpts, _data [][]byte) (*EmitDataEmittedIterator, error) { + + var _dataRule []interface{} + for _, _dataItem := range _data { + _dataRule = append(_dataRule, _dataItem) + } + + logs, sub, err := _Emit.contract.FilterLogs(opts, "DataEmitted", _dataRule) + if err != nil { + return nil, err + } + return &EmitDataEmittedIterator{contract: _Emit.contract, event: "DataEmitted", logs: logs, sub: sub}, nil +} + +// WatchDataEmitted is a free log subscription operation binding the contract event 0xe00bbfe6f6f8f1bbed2da38e3f5a139c6f9da594ab248a3cf8b44fc73627772c. +// +// Solidity: event DataEmitted(bytes indexed _data) +func (_Emit *EmitFilterer) WatchDataEmitted(opts *bind.WatchOpts, sink chan<- *EmitDataEmitted, _data [][]byte) (event.Subscription, error) { + + var _dataRule []interface{} + for _, _dataItem := range _data { + _dataRule = append(_dataRule, _dataItem) + } + + logs, sub, err := _Emit.contract.WatchLogs(opts, "DataEmitted", _dataRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EmitDataEmitted) + if err := _Emit.contract.UnpackLog(event, "DataEmitted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDataEmitted is a log parse operation binding the contract event 0xe00bbfe6f6f8f1bbed2da38e3f5a139c6f9da594ab248a3cf8b44fc73627772c. +// +// Solidity: event DataEmitted(bytes indexed _data) +func (_Emit *EmitFilterer) ParseDataEmitted(log types.Log) (*EmitDataEmitted, error) { + event := new(EmitDataEmitted) + if err := _Emit.contract.UnpackLog(event, "DataEmitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/op-e2e/interop/contracts/foundry.toml b/op-e2e/interop/contracts/foundry.toml new file mode 100644 index 000000000000..587dba436380 --- /dev/null +++ b/op-e2e/interop/contracts/foundry.toml @@ -0,0 +1,31 @@ +################################################################ +# PROFILE: DEFAULT (Local) # +################################################################ + +[profile.default] + +# Compilation settings +src = 'src' +out = 'build' +script = 'scripts' +optimizer = true +optimizer_runs = 999999 +remappings = [] +extra_output = ['devdoc', 'userdoc', 'metadata', 'storageLayout'] +bytecode_hash = 'none' +build_info_path = 'artifacts/build-info' +ast = true +evm_version = "cancun" +# 5159 error code is selfdestruct error code +ignored_error_codes = ["transient-storage", "code-size", "init-code-size", 5159] + +# We set the gas limit to max int64 to avoid running out of gas during testing, since the default +# gas limit is 1B and some of our tests require more gas than that, such as `test_callWithMinGas_noLeakageLow_succeeds`. +# We use this gas limit since it was the default gas limit prior to https://github.com/foundry-rs/foundry/pull/8274. +# Due to toml-rs limitations, if you increase the gas limit above this value it must be a string. +gas_limit = 9223372036854775807 + +# Test / Script Runner Settings +ffi = false +fs_permissions = [] +libs = ["node_modules", "lib"] diff --git a/op-e2e/interop/contracts/generate.sh b/op-e2e/interop/contracts/generate.sh new file mode 100755 index 000000000000..bba960153ec6 --- /dev/null +++ b/op-e2e/interop/contracts/generate.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +set -euo + +forge build + +cd build/emit.sol +cat EmitEvent.json | jq -r '.bytecode.object' > EmitEvent.bin +cat EmitEvent.json | jq '.abi' > EmitEvent.abi +cd ../.. + +abigen --abi ./build/emit.sol/EmitEvent.abi --bin ./build/emit.sol/EmitEvent.bin --pkg emit --out ./emit.go diff --git a/op-e2e/interop/contracts/src/emit.sol b/op-e2e/interop/contracts/src/emit.sol new file mode 100644 index 000000000000..5464bb7bbe6e --- /dev/null +++ b/op-e2e/interop/contracts/src/emit.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.15; + +contract EmitEvent { + // Define an event that logs the emitted data + event DataEmitted(bytes indexed _data); + + // Function that takes calldata and emits the data as an event + function emitData(bytes calldata _data) external { + emit DataEmitted(_data); + } +} diff --git a/op-e2e/interop/contracts/test-artifacts/emit.sol/EmitEvent.abi b/op-e2e/interop/contracts/test-artifacts/emit.sol/EmitEvent.abi new file mode 100644 index 000000000000..79170e79f968 --- /dev/null +++ b/op-e2e/interop/contracts/test-artifacts/emit.sol/EmitEvent.abi @@ -0,0 +1,28 @@ +[ + { + "type": "function", + "name": "emitData", + "inputs": [ + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "DataEmitted", + "inputs": [ + { + "name": "data", + "type": "bytes", + "indexed": true, + "internalType": "bytes" + } + ], + "anonymous": false + } +] diff --git a/op-e2e/interop/contracts/test-artifacts/emit.sol/EmitEvent.bin b/op-e2e/interop/contracts/test-artifacts/emit.sol/EmitEvent.bin new file mode 100644 index 000000000000..f4c15ab05dca --- /dev/null +++ b/op-e2e/interop/contracts/test-artifacts/emit.sol/EmitEvent.bin @@ -0,0 +1 @@ +0x6080604052348015600e575f80fd5b5060ff8061001b5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c8063d836083e14602a575b5f80fd5b60396035366004607c565b603b565b005b8181604051604992919060e3565b604051908190038120907fe00bbfe6f6f8f1bbed2da38e3f5a139c6f9da594ab248a3cf8b44fc73627772c905f90a25050565b5f8060208385031215608c575f80fd5b823567ffffffffffffffff8082111560a2575f80fd5b818501915085601f83011260b4575f80fd5b81358181111560c1575f80fd5b86602082850101111560d1575f80fd5b60209290920196919550909350505050565b818382375f910190815291905056fea164736f6c6343000819000a diff --git a/op-e2e/interop/contracts/test-artifacts/emit.sol/EmitEvent.json b/op-e2e/interop/contracts/test-artifacts/emit.sol/EmitEvent.json new file mode 100644 index 000000000000..422f62ea7324 --- /dev/null +++ b/op-e2e/interop/contracts/test-artifacts/emit.sol/EmitEvent.json @@ -0,0 +1 @@ +{"abi":[{"type":"function","name":"emitData","inputs":[{"name":"data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"DataEmitted","inputs":[{"name":"data","type":"bytes","indexed":true,"internalType":"bytes"}],"anonymous":false}],"bytecode":{"object":"0x6080604052348015600e575f80fd5b5060ff8061001b5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c8063d836083e14602a575b5f80fd5b60396035366004607c565b603b565b005b8181604051604992919060e3565b604051908190038120907fe00bbfe6f6f8f1bbed2da38e3f5a139c6f9da594ab248a3cf8b44fc73627772c905f90a25050565b5f8060208385031215608c575f80fd5b823567ffffffffffffffff8082111560a2575f80fd5b818501915085601f83011260b4575f80fd5b81358181111560c1575f80fd5b86602082850101111560d1575f80fd5b60209290920196919550909350505050565b818382375f910190815291905056fea164736f6c6343000819000a","sourceMap":"58:275:0:-:0;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x6080604052348015600e575f80fd5b50600436106026575f3560e01c8063d836083e14602a575b5f80fd5b60396035366004607c565b603b565b005b8181604051604992919060e3565b604051908190038120907fe00bbfe6f6f8f1bbed2da38e3f5a139c6f9da594ab248a3cf8b44fc73627772c905f90a25050565b5f8060208385031215608c575f80fd5b823567ffffffffffffffff8082111560a2575f80fd5b818501915085601f83011260b4575f80fd5b81358181111560c1575f80fd5b86602082850101111560d1575f80fd5b60209290920196919550909350505050565b818382375f910190815291905056fea164736f6c6343000819000a","sourceMap":"58:275:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;244:87;;;;;;:::i;:::-;;:::i;:::-;;;319:4;;307:17;;;;;;;:::i;:::-;;;;;;;;;;;;;;;244:87;;:::o;14:591:1:-;84:6;92;145:2;133:9;124:7;120:23;116:32;113:52;;;161:1;158;151:12;113:52;201:9;188:23;230:18;271:2;263:6;260:14;257:34;;;287:1;284;277:12;257:34;325:6;314:9;310:22;300:32;;370:7;363:4;359:2;355:13;351:27;341:55;;392:1;389;382:12;341:55;432:2;419:16;458:2;450:6;447:14;444:34;;;474:1;471;464:12;444:34;519:7;514:2;505:6;501:2;497:15;493:24;490:37;487:57;;;540:1;537;530:12;487:57;571:2;563:11;;;;;593:6;;-1:-1:-1;14:591:1;;-1:-1:-1;;;;14:591:1:o;610:271::-;793:6;785;780:3;767:33;749:3;819:16;;844:13;;;819:16;610:271;-1:-1:-1;610:271:1:o","linkReferences":{}},"methodIdentifiers":{"emitData(bytes)":"d836083e"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"DataEmitted\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"emitData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/emit.sol\":\"EmitEvent\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"src/emit.sol\":{\"keccak256\":\"0xdee458d231a8b41e5ba097be7258a6da27501fafb2a6f865705953458aecafbf\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://912d125138604114be66c8d044a39ef83861e6dc2d5fe3be32a1a4e014ea2763\",\"dweb:/ipfs/QmUx5NRsTXzujjwU1SXMSNp5Wjys3v5PDLuhdpoAyCy7nx\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.25+commit.b61c2a91"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"bytes","name":"data","type":"bytes","indexed":true}],"type":"event","name":"DataEmitted","anonymous":false},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"emitData"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":[],"optimizer":{"enabled":true,"runs":999999},"metadata":{"bytecodeHash":"none"},"compilationTarget":{"src/emit.sol":"EmitEvent"},"evmVersion":"cancun","libraries":{}},"sources":{"src/emit.sol":{"keccak256":"0xdee458d231a8b41e5ba097be7258a6da27501fafb2a6f865705953458aecafbf","urls":["bzz-raw://912d125138604114be66c8d044a39ef83861e6dc2d5fe3be32a1a4e014ea2763","dweb:/ipfs/QmUx5NRsTXzujjwU1SXMSNp5Wjys3v5PDLuhdpoAyCy7nx"],"license":"MIT"}},"version":1},"storageLayout":{"storage":[],"types":{}},"userdoc":{"version":1,"kind":"user"},"devdoc":{"version":1,"kind":"dev"},"ast":{"absolutePath":"src/emit.sol","id":17,"exportedSymbols":{"EmitEvent":[16]},"nodeType":"SourceUnit","src":"32:302:0","nodes":[{"id":1,"nodeType":"PragmaDirective","src":"32:24:0","nodes":[],"literals":["solidity","^","0.8",".15"]},{"id":16,"nodeType":"ContractDefinition","src":"58:275:0","nodes":[{"id":5,"nodeType":"EventDefinition","src":"133:38:0","nodes":[],"anonymous":false,"eventSelector":"e00bbfe6f6f8f1bbed2da38e3f5a139c6f9da594ab248a3cf8b44fc73627772c","name":"DataEmitted","nameLocation":"139:11:0","parameters":{"id":4,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3,"indexed":true,"mutability":"mutable","name":"data","nameLocation":"165:4:0","nodeType":"VariableDeclaration","scope":5,"src":"151:18:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":2,"name":"bytes","nodeType":"ElementaryTypeName","src":"151:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"150:20:0"}},{"id":15,"nodeType":"FunctionDefinition","src":"244:87:0","nodes":[],"body":{"id":14,"nodeType":"Block","src":"292:39:0","nodes":[],"statements":[{"eventCall":{"arguments":[{"id":11,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":7,"src":"319:4:0","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}],"id":10,"name":"DataEmitted","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":5,"src":"307:11:0","typeDescriptions":{"typeIdentifier":"t_function_event_nonpayable$_t_bytes_memory_ptr_$returns$__$","typeString":"function (bytes memory)"}},"id":12,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"307:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":13,"nodeType":"EmitStatement","src":"302:22:0"}]},"functionSelector":"d836083e","implemented":true,"kind":"function","modifiers":[],"name":"emitData","nameLocation":"253:8:0","parameters":{"id":8,"nodeType":"ParameterList","parameters":[{"constant":false,"id":7,"mutability":"mutable","name":"data","nameLocation":"277:4:0","nodeType":"VariableDeclaration","scope":15,"src":"262:19:0","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":6,"name":"bytes","nodeType":"ElementaryTypeName","src":"262:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"261:21:0"},"returnParameters":{"id":9,"nodeType":"ParameterList","parameters":[],"src":"292:0:0"},"scope":16,"stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"abstract":false,"baseContracts":[],"canonicalName":"EmitEvent","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[16],"name":"EmitEvent","nameLocation":"67:9:0","scope":17,"usedErrors":[],"usedEvents":[5]}],"license":"MIT"},"id":0} \ No newline at end of file diff --git a/op-e2e/interop/interop_test.go b/op-e2e/interop/interop_test.go index 6ad12cf44d3d..65265c22e7c2 100644 --- a/op-e2e/interop/interop_test.go +++ b/op-e2e/interop/interop_test.go @@ -2,6 +2,7 @@ package interop import ( "context" + "fmt" "math/big" "testing" "time" @@ -54,9 +55,6 @@ func TestInteropTrivial(t *testing.T) { expectedBalance, _ := big.NewInt(0).SetString("10000000000000000000000000", 10) require.Equal(t, expectedBalance, bobBalance) - // sleep for a bit to allow the chain to start - time.Sleep(30 * time.Second) - // send a tx from Alice to Bob s2.SendL2Tx( chainA, @@ -86,4 +84,17 @@ func TestInteropTrivial(t *testing.T) { require.NoError(t, err) expectedBalance, _ = big.NewInt(0).SetString("10000000000000000000000000", 10) require.Equal(t, expectedBalance, bobBalance) + + s2.DeployEmitterContract(chainA, "Alice") + rec := s2.EmitData(chainA, "Alice", "0x1234567890abcdef") + + fmt.Println("Result of emitting event:", rec) + + s2.DeployEmitterContract(chainB, "Alice") + rec = s2.EmitData(chainB, "Alice", "0x1234567890abcdef") + + fmt.Println("Result of emitting event:", rec) + + time.Sleep(10 * time.Second) + } diff --git a/op-e2e/interop/supersystem.go b/op-e2e/interop/supersystem.go index 5f4273da04e7..58c0d4f4370f 100644 --- a/op-e2e/interop/supersystem.go +++ b/op-e2e/interop/supersystem.go @@ -10,11 +10,13 @@ import ( "testing" "time" + emit "github.com/ethereum-optimism/optimism/op-e2e/interop/contracts" "github.com/ethereum-optimism/optimism/op-e2e/system/helpers" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/stretchr/testify/require" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" @@ -86,6 +88,12 @@ type SuperSystem interface { SendL2Tx(network string, username string, applyTxOpts helpers.TxOptsFn) *types.Receipt // get the address for a user on an L2 Address(network string, username string) common.Address + // Deploy the Emitter Contract, which emits Event Logs + DeployEmitterContract(network string, username string) common.Address + // Use the Emitter Contract to emit an Event Log + EmitData(network string, username string, data string) *types.Receipt + // Access a contract on a network by name + Contract(network string, contractName string) interface{} } // NewSuperSystem creates a new SuperSystem from a recipe. It creates an interopE2ESystem. @@ -123,6 +131,7 @@ type l2Set struct { batcher *bss.BatcherService operatorKeys map[devkeys.ChainOperatorRole]ecdsa.PrivateKey userKeys map[string]ecdsa.PrivateKey + contracts map[string]interface{} } // prepareHDWallet creates a new HD wallet to derive keys from @@ -401,6 +410,7 @@ func (s *interopE2ESystem) newL2(id string, l2Out *interopgen.L2Output) l2Set { batcher: batcher, operatorKeys: operatorKeys, userKeys: make(map[string]ecdsa.PrivateKey), + contracts: make(map[string]interface{}), } } @@ -591,12 +601,60 @@ func (s *interopE2ESystem) SendL2Tx( ) *types.Receipt { senderSecret := s.UserKey(id, sender) require.NotNil(s.t, senderSecret, "no secret found for sender %s", sender) + nonce, err := s.L2GethClient(id).PendingNonceAt(context.Background(), crypto.PubkeyToAddress(senderSecret.PublicKey)) + require.NoError(s.t, err, "failed to get nonce") + newApply := func(opts *helpers.TxOpts) { + applyTxOpts(opts) + opts.Nonce = nonce + } return helpers.SendL2TxWithID( s.t, s.l2s[id].chainID, s.L2GethClient(id), &senderSecret, - applyTxOpts) + newApply) +} + +func (s *interopE2ESystem) DeployEmitterContract( + id string, + sender string, +) common.Address { + secret := s.UserKey(id, sender) + auth, err := bind.NewKeyedTransactorWithChainID(&secret, s.l2s[id].chainID) + require.NoError(s.t, err) + auth.GasLimit = uint64(3000000) + auth.GasPrice = big.NewInt(20000000000) + address, _, _, err := emit.DeployEmit(auth, s.L2GethClient(id)) + require.NoError(s.t, err) + contract, err := emit.NewEmit(address, s.L2GethClient(id)) + require.NoError(s.t, err) + s.l2s[id].contracts["emitter"] = contract + return address +} + +func (s *interopE2ESystem) EmitData( + id string, + sender string, + data string, +) *types.Receipt { + secret := s.UserKey(id, sender) + auth, err := bind.NewKeyedTransactorWithChainID(&secret, s.l2s[id].chainID) + + require.NoError(s.t, err) + + auth.GasLimit = uint64(3000000) + auth.GasPrice = big.NewInt(20000000000) + + contract := s.Contract(id, "emitter").(*emit.Emit) + tx, err := contract.EmitTransactor.EmitData(auth, []byte(data)) + require.NoError(s.t, err) + receipt, err := bind.WaitMined(context.Background(), s.L2GethClient(id), tx) + require.NoError(s.t, err) + return receipt +} + +func (s *interopE2ESystem) Contract(id string, name string) interface{} { + return s.l2s[id].contracts[name] } func mustDial(t *testing.T, logger log.Logger) func(v string) *rpc.Client { diff --git a/op-supervisor/supervisor/backend/backend.go b/op-supervisor/supervisor/backend/backend.go index 7cf0d960a958..5be0b6a4c80d 100644 --- a/op-supervisor/supervisor/backend/backend.go +++ b/op-supervisor/supervisor/backend/backend.go @@ -68,8 +68,9 @@ func NewSupervisorBackend(ctx context.Context, logger log.Logger, m Metrics, cfg } // from the RPC strings, have the supervisor backend create a chain monitor + // don't start the monitor yet, as we will start all monitors at once when Start is called for _, rpc := range cfg.L2RPCs { - err := super.addFromRPC(ctx, logger, rpc) + err := super.addFromRPC(ctx, logger, rpc, false) if err != nil { return nil, fmt.Errorf("failed to add chain monitor for rpc %v: %w", rpc, err) } @@ -79,7 +80,8 @@ func NewSupervisorBackend(ctx context.Context, logger log.Logger, m Metrics, cfg // addFromRPC adds a chain monitor to the supervisor backend from an rpc endpoint // it does not expect to be called after the backend has been started -func (su *SupervisorBackend) addFromRPC(ctx context.Context, logger log.Logger, rpc string) error { +// it will start the monitor if shouldStart is true +func (su *SupervisorBackend) addFromRPC(ctx context.Context, logger log.Logger, rpc string, shouldStart bool) error { // create the rpc client, which yields the chain id rpcClient, chainID, err := createRpcClient(ctx, logger, rpc) if err != nil { @@ -96,12 +98,18 @@ func (su *SupervisorBackend) addFromRPC(ctx context.Context, logger log.Logger, if err != nil { return fmt.Errorf("failed to create logdb for chain %v at %v: %w", chainID, path, err) } + if su.chainMonitors[chainID] != nil { + return fmt.Errorf("chain monitor for chain %v already exists", chainID) + } monitor, err := source.NewChainMonitor(ctx, logger, cm, chainID, rpc, rpcClient, su.db) if err != nil { return fmt.Errorf("failed to create monitor for rpc %v: %w", rpc, err) } - if su.chainMonitors[chainID] != nil { - return fmt.Errorf("chain monitor for chain %v already exists", chainID) + // start the monitor if requested + if shouldStart { + if err := monitor.Start(); err != nil { + return fmt.Errorf("failed to start monitor for rpc %v: %w", rpc, err) + } } su.chainMonitors[chainID] = monitor su.db.AddLogDB(chainID, logDB) @@ -172,15 +180,8 @@ func (su *SupervisorBackend) Close() error { // AddL2RPC adds a new L2 chain to the supervisor backend // it stops and restarts the backend to add the new chain func (su *SupervisorBackend) AddL2RPC(ctx context.Context, rpc string) error { - if err := su.Stop(ctx); err != nil { - return fmt.Errorf("failed to stop backend: %w", err) - } - su.logger.Info("temporarily stopped the backend to add a new L2 RPC", "rpc", rpc) - if err := su.addFromRPC(ctx, su.logger, rpc); err != nil { - return fmt.Errorf("failed to add chain monitor: %w", err) - } - su.logger.Info("added the new L2 RPC, starting supervisor again", "rpc", rpc) - return su.Start(ctx) + // start the monitor immediately, as the backend is assumed to already be running + return su.addFromRPC(ctx, su.logger, rpc, true) } func (su *SupervisorBackend) CheckMessage(identifier types.Identifier, payloadHash common.Hash) (types.SafetyLevel, error) { diff --git a/op-supervisor/supervisor/backend/db/db.go b/op-supervisor/supervisor/backend/db/db.go index 7a14870297ab..c05bab400b7b 100644 --- a/op-supervisor/supervisor/backend/db/db.go +++ b/op-supervisor/supervisor/backend/db/db.go @@ -48,9 +48,10 @@ type ChainsDB struct { func NewChainsDB(logDBs map[types.ChainID]LogStorage, heads HeadsStorage, l log.Logger) *ChainsDB { return &ChainsDB{ - logDBs: logDBs, - heads: heads, - logger: l, + logDBs: logDBs, + heads: heads, + logger: l, + maintenanceReady: make(chan struct{}, 1), } } @@ -79,7 +80,7 @@ func (db *ChainsDB) Resume() error { func (db *ChainsDB) StartCrossHeadMaintenance(ctx context.Context) { go func() { db.logger.Info("cross-head maintenance loop started") - // run the maintenance loop every 10 seconds for now + // run the maintenance loop every 1 seconds for now ticker := time.NewTicker(time.Second * 1) for { select { @@ -200,8 +201,7 @@ func (db *ChainsDB) UpdateCrossHeadsForChain(chainID types.ChainID, checker Safe // based on the provided SafetyChecker. The SafetyChecker is used to determine // the safety of each log entry in the database, and the cross-head associated with it. func (db *ChainsDB) UpdateCrossHeads(checker SafetyChecker) error { - currentHeads := db.heads.Current() - for chainID := range currentHeads.Chains { + for chainID := range db.logDBs { err := db.UpdateCrossHeadsForChain(chainID, checker) if err != nil { return err diff --git a/op-supervisor/supervisor/backend/db/entrydb/entry_db.go b/op-supervisor/supervisor/backend/db/entrydb/entry_db.go index 9d0ffc729efd..fb02c5be8151 100644 --- a/op-supervisor/supervisor/backend/db/entrydb/entry_db.go +++ b/op-supervisor/supervisor/backend/db/entrydb/entry_db.go @@ -54,7 +54,7 @@ func NewEntryDB(logger log.Logger, path string) (*EntryDB, error) { lastEntryIdx: EntryIdx(size - 1), } if size*EntrySize != info.Size() { - logger.Warn("File size is nut a multiple of entry size. Truncating to last complete entry", "fileSize", size, "entrySize", EntrySize) + logger.Warn("File size is not a multiple of entry size. Truncating to last complete entry", "fileSize", size, "entrySize", EntrySize) if err := db.recover(); err != nil { return nil, fmt.Errorf("failed to recover database at %v: %w", path, err) } From bdca797cfbe19deba8a7ab608534564db1bc0c43 Mon Sep 17 00:00:00 2001 From: Adrian Sutton <adrian@oplabs.co> Date: Fri, 20 Sep 2024 14:41:36 +1000 Subject: [PATCH 216/264] Update kurtosis library. (#12025) CI is automatically using the latest version which has broken things. Update to match as a temporary fix until we can install a fixed version in CI. --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0c4277621384..4681c720ba8c 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( github.com/ipfs/go-datastore v0.6.0 github.com/ipfs/go-ds-leveldb v0.5.0 github.com/klauspost/compress v1.17.9 - github.com/kurtosis-tech/kurtosis/api/golang v1.2.0 + github.com/kurtosis-tech/kurtosis/api/golang v1.3.0 github.com/libp2p/go-libp2p v0.36.2 github.com/libp2p/go-libp2p-mplex v0.9.0 github.com/libp2p/go-libp2p-pubsub v0.12.0 diff --git a/go.sum b/go.sum index 015c8a072b23..a92b17d143eb 100644 --- a/go.sum +++ b/go.sum @@ -436,8 +436,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kurtosis-tech/kurtosis-portal/api/golang v0.0.0-20230818182330-1a86869414d2 h1:izciXrFyFR+ihJ7nLTOkoIX5GzBPIp8gVKlw94gIc98= github.com/kurtosis-tech/kurtosis-portal/api/golang v0.0.0-20230818182330-1a86869414d2/go.mod h1:bWSMQK3WHVTGHX9CjxPAb/LtzcmfOxID2wdzakSWQxo= -github.com/kurtosis-tech/kurtosis/api/golang v1.2.0 h1:NaNkkAvLiAVgRVTM9yeLCg4FIoIe/BVJKfU93KIFqdc= -github.com/kurtosis-tech/kurtosis/api/golang v1.2.0/go.mod h1:9T22P7Vv3j5g6sbm78DxHQ4s9C4Cj3s9JjFQ7DFyYpM= +github.com/kurtosis-tech/kurtosis/api/golang v1.3.0 h1:6r+ER69AgIyoHM48DLcP6r+f6dKDeU+65U8Uiibj46w= +github.com/kurtosis-tech/kurtosis/api/golang v1.3.0/go.mod h1:9T22P7Vv3j5g6sbm78DxHQ4s9C4Cj3s9JjFQ7DFyYpM= github.com/kurtosis-tech/kurtosis/contexts-config-store v0.0.0-20230818184218-f4e3e773463b h1:hMoIM99QKcYQqsnK4AF7Lovi9ZD9ac6lZLZ5D/jx2x8= github.com/kurtosis-tech/kurtosis/contexts-config-store v0.0.0-20230818184218-f4e3e773463b/go.mod h1:4pFdrRwDz5R+Fov2ZuTaPhAVgjA2jhGh1Izf832sX7A= github.com/kurtosis-tech/kurtosis/grpc-file-transfer/golang v0.0.0-20230803130419-099ee7a4e3dc h1:7IlEpSehmWcNXOFpNP24Cu5HQI3af7GCBQw//m+LnvQ= From 4461d739368278ec6e10fc5cec0f533e50082019 Mon Sep 17 00:00:00 2001 From: Inphi <mlaw2501@gmail.com> Date: Fri, 20 Sep 2024 01:00:12 -0400 Subject: [PATCH 217/264] proof-tools: Bump op-challenger version (#12017) * proof-tools: Bump op-challenger version * optimistic version bump * update op-challenger version --- docker-bake.hcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-bake.hcl b/docker-bake.hcl index cd5d83b7d1b7..b587e5bde6ea 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -203,7 +203,7 @@ target "proofs-tools" { dockerfile = "./ops/docker/proofs-tools/Dockerfile" context = "." args = { - CHALLENGER_VERSION="v1.1.0" + CHALLENGER_VERSION="2fcbe4bab16a682bd51c2f0e6bd9be7f8d81c7a1" KONA_VERSION="kona-client-v0.1.0-alpha.3" ASTERISC_VERSION="v1.0.2" } From fbf69c9bd633cb247def3ca96b153c02baeb103e Mon Sep 17 00:00:00 2001 From: Matthew Slipper <me@matthewslipper.com> Date: Thu, 19 Sep 2024 23:00:28 -0600 Subject: [PATCH 218/264] Pin kurtosis version in CI (#12026) --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 97efd49e8697..43c36cb98124 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -828,7 +828,7 @@ jobs: command: | echo "deb [trusted=yes] https://apt.fury.io/kurtosis-tech/ /" | sudo tee /etc/apt/sources.list.d/kurtosis.list sudo apt update - sudo apt install kurtosis-cli + sudo apt install kurtosis-cli=1.3.0 kurtosis engine start - checkout - when: From af357f17c5b2535374f561c200e83fe6a12850ca Mon Sep 17 00:00:00 2001 From: Blaine Malone <blainemalone01@gmail.com> Date: Fri, 20 Sep 2024 08:37:54 -0400 Subject: [PATCH 219/264] refactor: Remove file I/O from deployment scripts (#12015) * fix: Removing all file I/O features * fix: comments in code. * fix: pr comment --- .../scripts/DeployAuthSystem.s.sol | 22 ------ .../scripts/DeployImplementations.s.sol | 19 ----- .../scripts/DeployOPChain.s.sol | 18 ----- .../scripts/DeploySuperchain.s.sol | 72 +++--------------- .../test/DeployAuthSystem.t.sol | 45 ----------- .../test/DeployImplementations.t.sol | 13 ---- .../test/DeploySuperchain.t.sol | 74 ------------------- 7 files changed, 9 insertions(+), 254 deletions(-) diff --git a/packages/contracts-bedrock/scripts/DeployAuthSystem.s.sol b/packages/contracts-bedrock/scripts/DeployAuthSystem.s.sol index ac2f51ee4be1..0ddcbc1a7aa0 100644 --- a/packages/contracts-bedrock/scripts/DeployAuthSystem.s.sol +++ b/packages/contracts-bedrock/scripts/DeployAuthSystem.s.sol @@ -35,13 +35,6 @@ contract DeployAuthSystemInput is CommonBase { } } - function loadInputFile(string memory _infile) public { - string memory toml = vm.readFile(_infile); - - set(this.threshold.selector, toml.readUint(".safe.threshold")); - set(this.owners.selector, toml.readAddressArray(".safe.owners")); - } - function threshold() public view returns (uint256) { require(_threshold != 0, "DeployAuthSystemInput: threshold not set"); return _threshold; @@ -61,11 +54,6 @@ contract DeployAuthSystemOutput is CommonBase { else revert("DeployAuthSystemOutput: unknown selector"); } - function writeOutputFile(string memory _outfile) public { - string memory out = vm.serializeAddress("outfile", "safe", address(this.safe())); - vm.writeToml(out, _outfile); - } - function checkOutput() public view { address[] memory addrs = Solarray.addresses(address(this.safe())); DeployUtils.assertValidContractAddresses(addrs); @@ -78,16 +66,6 @@ contract DeployAuthSystemOutput is CommonBase { } contract DeployAuthSystem is Script { - function run(string memory _infile, string memory _outfile) public { - (DeployAuthSystemInput dasi, DeployAuthSystemOutput daso) = etchIOContracts(); - - dasi.loadInputFile(_infile); - - run(dasi, daso); - - daso.writeOutputFile(_outfile); - } - function run(DeployAuthSystemInput _dasi, DeployAuthSystemOutput _daso) public { deploySafe(_dasi, _daso); } diff --git a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol index b68b4243c195..636053574331 100644 --- a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol +++ b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol @@ -97,11 +97,6 @@ contract DeployImplementationsInput is BaseDeployIO { else revert("DeployImplementationsInput: unknown selector"); } - function loadInputFile(string memory _infile) public pure { - _infile; - require(false, "DeployImplementationsInput: not implemented"); - } - function salt() public view returns (bytes32) { // TODO check if implementations are deployed based on code+salt and skip deploy if so. return _salt; @@ -192,11 +187,6 @@ contract DeployImplementationsOutput is BaseDeployIO { // forgefmt: disable-end } - function writeOutputFile(string memory _outfile) public pure { - _outfile; - require(false, "DeployImplementationsOutput: not implemented"); - } - function checkOutput(DeployImplementationsInput _dii) public { address[] memory addrs = Solarray.addresses( address(this.opsmProxy()), @@ -441,15 +431,6 @@ contract DeployImplementationsOutput is BaseDeployIO { contract DeployImplementations is Script { // -------- Core Deployment Methods -------- - function run(string memory _infile) public { - (DeployImplementationsInput dii, DeployImplementationsOutput dio) = etchIOContracts(); - dii.loadInputFile(_infile); - run(dii, dio); - string memory outfile = ""; // This will be derived from input file name, e.g. `foo.in.toml` -> `foo.out.toml` - dio.writeOutputFile(outfile); - require(false, "DeployImplementations: run is not implemented"); - } - function run(DeployImplementationsInput _dii, DeployImplementationsOutput _dio) public { // Deploy the implementations. deploySystemConfigImpl(_dii, _dio); diff --git a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol index a13c1e581eac..d2fec4e9e6d2 100644 --- a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol @@ -70,11 +70,6 @@ contract DeployOPChainInput is BaseDeployIO { } } - function loadInputFile(string memory _infile) public pure { - _infile; - require(false, "DeployOPChainInput: not implemented"); - } - function opChainProxyAdminOwner() public view returns (address) { require(_opChainProxyAdminOwner != address(0), "DeployOPChainInput: not set"); return _opChainProxyAdminOwner; @@ -167,11 +162,6 @@ contract DeployOPChainOutput is BaseDeployIO { // forgefmt: disable-end } - function writeOutputFile(string memory _outfile) public pure { - _outfile; - require(false, "DeployOPChainOutput: not implemented"); - } - function checkOutput(DeployOPChainInput _doi) public view { // With 16 addresses, we'd get a stack too deep error if we tried to do this inline as a // single call to `Solarray.addresses`. So we split it into two calls. @@ -406,14 +396,6 @@ contract DeployOPChainOutput is BaseDeployIO { contract DeployOPChain is Script { // -------- Core Deployment Methods -------- - function run(string memory _infile) public { - (DeployOPChainInput doi, DeployOPChainOutput doo) = etchIOContracts(); - doi.loadInputFile(_infile); - run(doi, doo); - string memory outfile = ""; // This will be derived from input file name, e.g. `foo.in.toml` -> `foo.out.toml` - doo.writeOutputFile(outfile); - require(false, "DeployOPChain: run is not implemented"); - } function run(DeployOPChainInput _doi, DeployOPChainOutput _doo) public { OPStackManager opsmProxy = _doi.opsmProxy(); diff --git a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol index f1cfdbcf571d..365b67df7b47 100644 --- a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol +++ b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol @@ -19,14 +19,14 @@ import { BaseDeployIO } from "scripts/utils/BaseDeployIO.sol"; // deployment script. // // There are three categories of users that are expected to interact with the scripts: -// 1. End users that want to run live contract deployments. +// 1. End users that want to run live contract deployments. These users are expected to run these scripts via +// 'op-deployer' which uses a go interface to interact with the scripts. // 2. Solidity developers that want to use or test these scripts in a standard forge test environment. // 3. Go developers that want to run the deploy scripts as part of e2e testing with other aspects of the OP Stack. // // We want each user to interact with the scripts in the way that's simplest for their use case: -// 1. End users: TOML input files that define config, and TOML output files with all output data. -// 2. Solidity developers: Direct calls to the script, with the input and output contracts configured. -// 3. Go developers: The forge scripts can be executed directly in Go. +// 1. Solidity developers: Direct calls to the script, with the input and output contracts configured. +// 2. Go developers: The forge scripts can be executed directly in Go. // // The following architecture is used to meet the requirements of each user. We use this file's // `DeploySuperchain` script as an example, but it applies to other scripts as well. @@ -39,7 +39,7 @@ import { BaseDeployIO } from "scripts/utils/BaseDeployIO.sol"; // // Because the core script performs calls to the input and output contracts, Go developers can // intercept calls to these addresses (analogous to how forge intercepts calls to the `Vm` address -// to execute cheatcodes), to avoid the need for file I/O or hardcoding the input/output values. +// to execute cheatcodes), to avoid the need for hardcoding the input/output values. // // Public getter methods on the input and output contracts allow individual fields to be accessed // in a strong, type-safe manner (as opposed to a single struct getter where the caller may @@ -110,27 +110,6 @@ contract DeploySuperchainInput is BaseDeployIO { else revert("DeploySuperchainInput: unknown selector"); } - // Load the input from a TOML file. - // When setting inputs from a TOML file, we use the setter methods instead of writing directly - // to storage. This allows us to validate each input as it is set. - function loadInputFile(string memory _infile) public { - string memory toml = vm.readFile(_infile); - - // Parse and set role inputs. - set(this.guardian.selector, toml.readAddress(".roles.guardian")); - set(this.protocolVersionsOwner.selector, toml.readAddress(".roles.protocolVersionsOwner")); - set(this.proxyAdminOwner.selector, toml.readAddress(".roles.proxyAdminOwner")); - - // Parse and set other inputs. - set(this.paused.selector, toml.readBool(".paused")); - - uint256 recVersion = toml.readUint(".recommendedProtocolVersion"); - set(this.recommendedProtocolVersion.selector, ProtocolVersion.wrap(recVersion)); - - uint256 reqVersion = toml.readUint(".requiredProtocolVersion"); - set(this.requiredProtocolVersion.selector, ProtocolVersion.wrap(reqVersion)); - } - // Each input field is exposed via it's own getter method. Using public storage variables here // would be less verbose, but would also be more error-prone, as it would require the caller to // validate that each input is set before accessing it. With getter methods, we can automatically @@ -195,21 +174,8 @@ contract DeploySuperchainOutput is BaseDeployIO { else revert("DeploySuperchainOutput: unknown selector"); } - // Save the output to a TOML file. - // We fetch the output values using external calls to the getters to verify that all outputs are - // set correctly before writing them to the file. - function writeOutputFile(string memory _outfile) public { - string memory key = "dso-outfile"; - vm.serializeAddress(key, "superchainProxyAdmin", address(this.superchainProxyAdmin())); - vm.serializeAddress(key, "superchainConfigImpl", address(this.superchainConfigImpl())); - vm.serializeAddress(key, "superchainConfigProxy", address(this.superchainConfigProxy())); - vm.serializeAddress(key, "protocolVersionsImpl", address(this.protocolVersionsImpl())); - string memory out = vm.serializeAddress(key, "protocolVersionsProxy", address(this.protocolVersionsProxy())); - vm.writeToml(out, _outfile); - } - - // This function can be called to ensure all outputs are correct. Similar to `writeOutputFile`, - // it fetches the output values using external calls to the getter methods for safety. + // This function can be called to ensure all outputs are correct. + // It fetches the output values using external calls to the getter methods for safety. function checkOutput(DeploySuperchainInput _dsi) public { address[] memory addrs = Solarray.addresses( address(this.superchainProxyAdmin()), @@ -322,24 +288,6 @@ contract DeploySuperchainOutput is BaseDeployIO { contract DeploySuperchain is Script { // -------- Core Deployment Methods -------- - // This entrypoint is for end-users to deploy from an input file and write to an output file. - // In this usage, we don't need the input and output contract functionality, so we deploy them - // here and abstract that architectural detail away from the end user. - function run(string memory _infile, string memory _outfile) public { - // End-user without file IO, so etch the IO helper contracts. - (DeploySuperchainInput dsi, DeploySuperchainOutput dso) = etchIOContracts(); - - // Load the input file into the input contract. - dsi.loadInputFile(_infile); - - // Run the deployment script and write outputs to the DeploySuperchainOutput contract. - run(dsi, dso); - - // Write the output data to a file. - dso.writeOutputFile(_outfile); - } - - // This entrypoint is useful for testing purposes, as it doesn't use any file I/O. function run(DeploySuperchainInput _dsi, DeploySuperchainOutput _dso) public { // Notice that we do not do any explicit verification here that inputs are set. This is because // the verification happens elsewhere: @@ -449,10 +397,8 @@ contract DeploySuperchain is Script { // -------- Utilities -------- - // This etches the IO contracts into memory so that we can use them in tests. When using file IO - // we don't need to call this directly, as the `DeploySuperchain.run(file, file)` entrypoint - // handles it. But when interacting with the script programmatically (e.g. in a Solidity test), - // this must be called. + // This etches the IO contracts into memory so that we can use them in tests. + // When interacting with the script programmatically (e.g. in a Solidity test), this must be called. function etchIOContracts() public returns (DeploySuperchainInput dsi_, DeploySuperchainOutput dso_) { (dsi_, dso_) = getIOContracts(); vm.etch(address(dsi_), type(DeploySuperchainInput).runtimeCode); diff --git a/packages/contracts-bedrock/test/DeployAuthSystem.t.sol b/packages/contracts-bedrock/test/DeployAuthSystem.t.sol index f06e9237cb86..19985ef490b9 100644 --- a/packages/contracts-bedrock/test/DeployAuthSystem.t.sol +++ b/packages/contracts-bedrock/test/DeployAuthSystem.t.sol @@ -30,16 +30,6 @@ contract DeployAuthSystemInput_Test is Test { } } - function test_loadInputFile_succeeds() public { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/test-deploy-auth-system-in.toml"); - - dasi.loadInputFile(path); - - assertEq(threshold, dasi.threshold(), "100"); - assertEq(owners.length, dasi.owners().length, "200"); - } - function test_getters_whenNotSet_revert() public { vm.expectRevert("DeployAuthSystemInput: threshold not set"); dasi.threshold(); @@ -88,27 +78,6 @@ contract DeployAuthSystemOutput_Test is Test { vm.expectRevert(expectedErr); daso.safe(); } - - function test_writeOutputFile_succeeds() public { - string memory root = vm.projectRoot(); - - string memory expOutPath = string.concat(root, "/test/fixtures/test-deploy-auth-system-out.toml"); - string memory expOutToml = vm.readFile(expOutPath); - - address expSafe = expOutToml.readAddress(".safe"); - - vm.etch(expSafe, hex"01"); - - daso.set(daso.safe.selector, expSafe); - - string memory actOutPath = string.concat(root, "/.testdata/test-deploy-auth-system-output.toml"); - daso.writeOutputFile(actOutPath); - string memory actOutToml = vm.readFile(actOutPath); - - vm.removeFile(actOutPath); - - assertEq(expOutToml, actOutToml); - } } contract DeployAuthSystem_Test is Test { @@ -166,20 +135,6 @@ contract DeployAuthSystem_Test is Test { daso.checkOutput(); } - function test_run_io_succeeds() public { - string memory root = vm.projectRoot(); - string memory inpath = string.concat(root, "/test/fixtures/test-deploy-auth-system-in.toml"); - string memory outpath = string.concat(root, "/.testdata/test-deploy-auth-system-out.toml"); - - deployAuthSystem.run(inpath, outpath); - - string memory actOutToml = vm.readFile(outpath); - string memory expOutToml = vm.readFile(string.concat(root, "/test/fixtures/test-deploy-auth-system-out.toml")); - - vm.removeFile(outpath); - assertEq(expOutToml, actOutToml); - } - function test_run_NullInput_reverts() public { dasi.set(dasi.owners.selector, defaultOwners); dasi.set(dasi.threshold.selector, defaultThreshold); diff --git a/packages/contracts-bedrock/test/DeployImplementations.t.sol b/packages/contracts-bedrock/test/DeployImplementations.t.sol index bb28b2fecd67..957eb2830435 100644 --- a/packages/contracts-bedrock/test/DeployImplementations.t.sol +++ b/packages/contracts-bedrock/test/DeployImplementations.t.sol @@ -43,19 +43,6 @@ contract DeployImplementationsInput_Test is Test { dii = new DeployImplementationsInput(); } - function test_loadInputFile_succeeds() public { - // See `test_loadInputFile_succeeds` in `DeploySuperchain.t.sol` for a reference implementation. - // This test is currently skipped because loadInputFile is not implemented. - vm.skip(true); - - // Compare the test inputs to the getter methods. - // assertEq(withdrawalDelaySeconds, dii.withdrawalDelaySeconds(), "100"); - // assertEq(minProposalSizeBytes, dii.minProposalSizeBytes(), "200"); - // assertEq(challengePeriodSeconds, dii.challengePeriodSeconds(), "300"); - // assertEq(proofMaturityDelaySeconds, dii.proofMaturityDelaySeconds(), "400"); - // assertEq(disputeGameFinalityDelaySeconds, dii.disputeGameFinalityDelaySeconds(), "500"); - } - function test_getters_whenNotSet_revert() public { vm.expectRevert("DeployImplementationsInput: not set"); dii.withdrawalDelaySeconds(); diff --git a/packages/contracts-bedrock/test/DeploySuperchain.t.sol b/packages/contracts-bedrock/test/DeploySuperchain.t.sol index 1d6650b1cce1..4b51aae0f3d6 100644 --- a/packages/contracts-bedrock/test/DeploySuperchain.t.sol +++ b/packages/contracts-bedrock/test/DeploySuperchain.t.sol @@ -24,28 +24,6 @@ contract DeploySuperchainInput_Test is Test { dsi = new DeploySuperchainInput(); } - function test_loadInputFile_succeeds() public { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/test-deploy-superchain-in.toml"); - - dsi.loadInputFile(path); - - assertEq(proxyAdminOwner, dsi.proxyAdminOwner(), "100"); - assertEq(protocolVersionsOwner, dsi.protocolVersionsOwner(), "200"); - assertEq(guardian, dsi.guardian(), "300"); - assertEq(paused, dsi.paused(), "400"); - assertEq( - ProtocolVersion.unwrap(requiredProtocolVersion), - ProtocolVersion.unwrap(dsi.requiredProtocolVersion()), - "500" - ); - assertEq( - ProtocolVersion.unwrap(recommendedProtocolVersion), - ProtocolVersion.unwrap(dsi.recommendedProtocolVersion()), - "600" - ); - } - function test_getters_whenNotSet_revert() public { vm.expectRevert("DeploySuperchainInput: proxyAdminOwner not set"); dsi.proxyAdminOwner(); @@ -139,43 +117,6 @@ contract DeploySuperchainOutput_Test is Test { vm.expectRevert(expectedErr); dso.protocolVersionsProxy(); } - - function test_writeOutputFile_succeeds() public { - string memory root = vm.projectRoot(); - - // Use the expected data from the test fixture. - string memory expOutPath = string.concat(root, "/test/fixtures/test-deploy-superchain-out.toml"); - string memory expOutToml = vm.readFile(expOutPath); - - // Parse each field of expOutToml individually. - ProxyAdmin expSuperchainProxyAdmin = ProxyAdmin(expOutToml.readAddress(".superchainProxyAdmin")); - SuperchainConfig expSuperchainConfigImpl = SuperchainConfig(expOutToml.readAddress(".superchainConfigImpl")); - SuperchainConfig expSuperchainConfigProxy = SuperchainConfig(expOutToml.readAddress(".superchainConfigProxy")); - ProtocolVersions expProtocolVersionsImpl = ProtocolVersions(expOutToml.readAddress(".protocolVersionsImpl")); - ProtocolVersions expProtocolVersionsProxy = ProtocolVersions(expOutToml.readAddress(".protocolVersionsProxy")); - - // Etch code at each address so the code checks pass when settings values. - vm.etch(address(expSuperchainConfigImpl), hex"01"); - vm.etch(address(expSuperchainConfigProxy), hex"01"); - vm.etch(address(expProtocolVersionsImpl), hex"01"); - vm.etch(address(expProtocolVersionsProxy), hex"01"); - - dso.set(dso.superchainProxyAdmin.selector, address(expSuperchainProxyAdmin)); - dso.set(dso.superchainProxyAdmin.selector, address(expSuperchainProxyAdmin)); - dso.set(dso.superchainConfigImpl.selector, address(expSuperchainConfigImpl)); - dso.set(dso.superchainConfigProxy.selector, address(expSuperchainConfigProxy)); - dso.set(dso.protocolVersionsImpl.selector, address(expProtocolVersionsImpl)); - dso.set(dso.protocolVersionsProxy.selector, address(expProtocolVersionsProxy)); - - string memory actOutPath = string.concat(root, "/.testdata/test-deploy-superchain-output.toml"); - dso.writeOutputFile(actOutPath); - string memory actOutToml = vm.readFile(actOutPath); - - // Clean up before asserting so that we don't leave any files behind. - vm.removeFile(actOutPath); - - assertEq(expOutToml, actOutToml); - } } contract DeploySuperchain_Test is Test { @@ -253,21 +194,6 @@ contract DeploySuperchain_Test is Test { dso.checkOutput(dsi); } - function test_run_io_succeeds() public { - string memory root = vm.projectRoot(); - string memory inpath = string.concat(root, "/test/fixtures/test-deploy-superchain-in.toml"); - string memory outpath = string.concat(root, "/.testdata/test-deploy-superchain-out.toml"); - - deploySuperchain.run(inpath, outpath); - - string memory actOutToml = vm.readFile(outpath); - string memory expOutToml = vm.readFile(string.concat(root, "/test/fixtures/test-deploy-superchain-out.toml")); - - // Clean up before asserting so that we don't leave any files behind. - vm.removeFile(outpath); - assertEq(expOutToml, actOutToml); - } - function test_run_NullInput_reverts() public { // Set default values for all inputs. dsi.set(dsi.proxyAdminOwner.selector, defaultProxyAdminOwner); From bd50ac6909245e6a283e824995940fc055a90f14 Mon Sep 17 00:00:00 2001 From: zhiqiangxu <652732310@qq.com> Date: Fri, 20 Sep 2024 23:08:39 +0800 Subject: [PATCH 220/264] show block number when "L2 safe head ahead of L2 unsafe head" happens (#12030) --- op-batcher/batcher/driver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op-batcher/batcher/driver.go b/op-batcher/batcher/driver.go index fd56a1cebc6b..b9b57cb654d9 100644 --- a/op-batcher/batcher/driver.go +++ b/op-batcher/batcher/driver.go @@ -286,7 +286,7 @@ func (l *BatchSubmitter) calculateL2BlockRangeToStore(ctx context.Context) (eth. // Check if we should even attempt to load any blocks. TODO: May not need this check if syncStatus.SafeL2.Number >= syncStatus.UnsafeL2.Number { - return eth.BlockID{}, eth.BlockID{}, errors.New("L2 safe head ahead of L2 unsafe head") + return eth.BlockID{}, eth.BlockID{}, fmt.Errorf("L2 safe head(%d) ahead of L2 unsafe head(%d)", syncStatus.SafeL2.Number, syncStatus.UnsafeL2.Number) } return l.lastStoredBlock, syncStatus.UnsafeL2.ID(), nil From 9936803afdc2848836eb1d69ecb68cef769b4288 Mon Sep 17 00:00:00 2001 From: smartcontracts <kelvin@optimism.io> Date: Fri, 20 Sep 2024 09:41:36 -0600 Subject: [PATCH 221/264] maint(ct): clean up justfile (#12024) That was one ugly file. --- packages/contracts-bedrock/justfile | 137 ++++++++++++++++++++-------- 1 file changed, 97 insertions(+), 40 deletions(-) diff --git a/packages/contracts-bedrock/justfile b/packages/contracts-bedrock/justfile index e59dd8b03b99..e660d7a1c7ba 100644 --- a/packages/contracts-bedrock/justfile +++ b/packages/contracts-bedrock/justfile @@ -1,21 +1,51 @@ -prebuild: - ./scripts/checks/check-foundry-install.sh +######################################################## +# INSTALL # +######################################################## + +# Installs dependencies. +install: + forge install +# Shows the status of the git submodules. dep-status: git submodule status -install: - forge install +######################################################## +# BUILD # +######################################################## + +# Checks that the correct version of Foundry is installed. +prebuild: + ./scripts/checks/check-foundry-install.sh + +# Builds the contracts. build: prebuild forge build +# Builds the go-ffi tool for contract tests. build-go-ffi: cd scripts/go-ffi && go build +# Cleans build artifacts and deployments. +# Removes everything inside of .testdata (except the .gitkeep file). +clean: + rm -rf ./artifacts ./forge-artifacts ./cache ./scripts/go-ffi/go-ffi ./deployments/hardhat/* + find ./.testdata -mindepth 1 -not -name '.gitkeep' -delete + + +######################################################## +# TEST # +######################################################## + +# Runs standard contract tests. test: build-go-ffi forge test +# Runs standard contract tests with rerun flag. +test-rerun: build-go-ffi + forge test --rerun -vvv + # Run Kontrol tests and build all dependencies. test-kontrol: build-go-ffi build kontrol-summary-full test-kontrol-no-build @@ -23,35 +53,42 @@ test-kontrol: build-go-ffi build kontrol-summary-full test-kontrol-no-build test-kontrol-no-build: ./test/kontrol/scripts/run-kontrol.sh script -test-rerun: build-go-ffi - forge test --rerun -vvv - -genesis: - forge script scripts/L2Genesis.s.sol:L2Genesis --sig 'runWithStateDump()' - +# Runs contract coverage. coverage: build-go-ffi forge coverage || (bash -c "forge coverage 2>&1 | grep -q 'Stack too deep' && echo -e '\\033[1;33mWARNING\\033[0m: Coverage failed with stack too deep, so overriding and exiting successfully' && exit 0 || exit 1") +# Runs contract coverage with lcov. coverage-lcov: build-go-ffi forge coverage --report lcov || (bash -c "forge coverage --report lcov 2>&1 | grep -q 'Stack too deep' && echo -e '\\033[1;33mWARNING\\033[0m: Coverage failed with stack too deep, so overriding and exiting successfully' && exit 0 || exit 1") + +######################################################## +# DEPLOY # +######################################################## + +# Generates the L2 genesis state. +genesis: + forge script scripts/L2Genesis.s.sol:L2Genesis --sig 'runWithStateDump()' + +# Deploys the contracts. deploy: ./scripts/deploy/deploy.sh + +######################################################## +# SNAPSHOTS # +######################################################## + +# Generates a gas snapshot without building. gas-snapshot-no-build: forge snapshot --match-contract GasBenchMark -statediff: - ./scripts/utils/statediff.sh && git diff --exit-code - +# Generates a gas snapshot. gas-snapshot: build-go-ffi gas-snapshot-no-build -gas-snapshot-check: build-go-ffi - forge snapshot --match-contract GasBenchMark --check - -# Check that the Kontrol deployment script has not changed. -kontrol-deployment-check: - ./scripts/checks/check-kontrol-deployment.sh +# Checks that the state diff is up to date. +statediff: + ./scripts/utils/statediff.sh && git diff --exit-code # Generates default Kontrol summary. kontrol-summary: @@ -68,6 +105,10 @@ kontrol-summary-full: kontrol-summary kontrol-summary-fp snapshots-abi-storage: go run ./scripts/autogen/generate-snapshots . +# Updates the semver-lock.json file. +semver-lock: + forge script scripts/autogen/SemverLock.s.sol + # Generates core snapshots without building contracts. Currently just an alias for # snapshots-abi-storage because we no longer run Kontrol snapshots here. Run # kontrol-summary-full to build the Kontrol summaries if necessary. @@ -76,6 +117,22 @@ snapshots-no-build: snapshots-abi-storage # Builds contracts and then generates core snapshots. snapshots: build snapshots-no-build + +######################################################## +# CHECKS # +######################################################## + +# Checks that the gas snapshot is up to date without building. +gas-snapshot-check-no-build: + forge snapshot --match-contract GasBenchMark --check + +# Checks that the gas snapshot is up to date. +gas-snapshot-check: build-go-ffi gas-snapshot-check-no-build + +# Checks that the Kontrol deployment script has not changed. +kontrol-deployment-check: + ./scripts/checks/check-kontrol-deployment.sh + # Checks if the snapshots are up to date without building. snapshots-check-no-build: ./scripts/checks/check-snapshots.sh --no-build @@ -113,40 +170,40 @@ semver-natspec-check-no-build: # Checks that semver natspec is equal to the actual semver version. semver-natspec-check: build semver-natspec-check-no-build -semver-lock: - forge script scripts/autogen/SemverLock.s.sol +# Checks that forge test names are correctly formatted. +lint-forge-tests-check: + go run ./scripts/checks/names +# Checks that contracts are properly linted. +lint-check: + forge fmt --check + +# Checks that the deploy configs are valid. validate-deploy-configs: ./scripts/checks/check-deploy-configs.sh +# Checks that spacer variables are correctly inserted without building. validate-spacers-no-build: go run ./scripts/checks/spacers +# Checks that spacer variables are correctly inserted. validate-spacers: build validate-spacers-no-build -# Cleans build artifacts and deployments. -# Removes everything inside of .testdata (except the .gitkeep file). -clean: - rm -rf ./artifacts ./forge-artifacts ./cache ./scripts/go-ffi/go-ffi ./deployments/hardhat/* - find ./.testdata -mindepth 1 -not -name '.gitkeep' -delete - -pre-pr-no-build: gas-snapshot-no-build snapshots-no-build semver-lock lint +# TODO: Also run lint-forge-tests-check but we need to fix the test names first. +# Runs all checks. +check: gas-snapshot-check-no-build kontrol-deployment-check snapshots-check-no-build lint-check semver-diff-check-no-build semver-natspec-check-no-build validate-deploy-configs validate-spacers-no-build interfaces-check-no-build -pre-pr: clean build-go-ffi build pre-pr-no-build -pre-pr-full: test validate-deploy-configs validate-spacers pre-pr +######################################################## +# DEV TOOLS # +######################################################## -lint-forge-tests-check: - go run ./scripts/checks/names +# Cleans, builds, lints, and runs all checks. +pre-pr: clean build-go-ffi build lint gas-snapshot-no-build snapshots-no-build semver-lock check -lint-contracts-check: - forge fmt --check - -lint-check: lint-contracts-check - -lint-contracts-fix: +# Fixes linting errors. +lint-fix: forge fmt -lint-fix: lint-contracts-fix - +# Fixes linting errors and checks that the code is correctly formatted. lint: lint-fix lint-check From 53d95228a496519298555c44950fe117867af4cd Mon Sep 17 00:00:00 2001 From: smartcontracts <kelvin@optimism.io> Date: Fri, 20 Sep 2024 16:34:57 -0600 Subject: [PATCH 222/264] feat(ct): add constructors to interfaces (#12028) * feat(ct): add constructors to interfaces Adds a pseudo-constructor function called __constructor__ that will be verified as part of the interface. This pseudo-function is useful when we want to be able to maintain type safety in the deploy script where we use vm.getCode. * add a pseudo-constructor for all remaining contracts with constructors * fix warning * update check-interface.sh comment --------- Co-authored-by: Michael Amadi <amadimichaeld@gmail.com> --- .../scripts/checks/check-interfaces.sh | 18 ++- .../interfaces/IDataAvailabilityChallenge.sol | 2 + .../src/L1/interfaces/IDelayedVetoable.sol | 2 + .../src/L1/interfaces/IL2OutputOracle.sol | 2 + .../src/L1/interfaces/IOptimismPortal2.sol | 2 + .../L1/interfaces/IOptimismPortalInterop.sol | 2 + .../src/L1/interfaces/IProtocolVersions.sol | 2 + .../src/L1/interfaces/ISuperchainConfig.sol | 2 + .../src/L1/interfaces/ISystemConfig.sol | 2 + .../L1/interfaces/ISystemConfigInterop.sol | 64 ++++++++- .../src/L2/interfaces/IBaseFeeVault.sol | 7 + .../src/L2/interfaces/IL1FeeVault.sol | 7 + .../L2/interfaces/IL2CrossDomainMessenger.sol | 2 + .../src/L2/interfaces/IL2ERC721Bridge.sol | 2 + .../src/L2/interfaces/IL2StandardBridge.sol | 2 + .../interfaces/IL2StandardBridgeInterop.sol | 79 ++++++++++- .../src/L2/interfaces/ISequencerFeeVault.sol | 7 + .../src/cannon/interfaces/IMIPS.sol | 2 + .../src/cannon/interfaces/IMIPS2.sol | 2 + .../interfaces/IAnchorStateRegistry.sol | 2 + .../interfaces/IDisputeGameFactory.sol | 2 + .../dispute/interfaces/IFaultDisputeGame.sol | 14 ++ .../interfaces/IPermissionedDisputeGame.sol | 130 +++++++++++++++++- .../interfaces/IGovernanceToken.sol | 2 + .../governance/interfaces/IMintManager.sol | 2 + .../legacy/interfaces/IL1ChugSplashProxy.sol | 2 + .../IOptimismMintableERC20Factory.sol | 2 + 27 files changed, 352 insertions(+), 12 deletions(-) diff --git a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh index 628ecbbe2a4b..ed2c8e798eb1 100755 --- a/packages/contracts-bedrock/scripts/checks/check-interfaces.sh +++ b/packages/contracts-bedrock/scripts/checks/check-interfaces.sh @@ -3,8 +3,9 @@ set -euo pipefail # This script checks for ABI consistency between interfaces and their corresponding contracts. # It compares the ABIs of interfaces (files starting with 'I') with their implementation contracts, -# excluding constructors and certain predefined files. The script reports any differences found -# and exits with an error if inconsistencies are detected. +# excluding certain predefined files. Constructors are expected to be represented in interfaces by a +# pseudo-constructor function `__constructor__(...)` with arguments the same as the contract's constructor. +# The script reports any differences found and exits with an error if inconsistencies are detected. # NOTE: Script is fast enough but could be parallelized if necessary. # Parse flags @@ -59,6 +60,7 @@ EXCLUDE_CONTRACTS=( "MintableAndBurnable" "IWETH" "IDelayedWETH" + "IResolvedDelegateProxy" # TODO: Kontrol interfaces that need to be removed "IL1ERC721Bridge" @@ -175,8 +177,8 @@ for interface_file in $JSON_FILES; do fi # Extract and compare ABIs excluding constructors - interface_abi=$(jq '[.abi[] | select(.type != "constructor")]' < "$interface_file") - contract_abi=$(jq '[.abi[] | select(.type != "constructor")]' < "$corresponding_contract_file") + interface_abi=$(jq '[.abi[]]' < "$interface_file") + contract_abi=$(jq '[.abi[]]' < "$corresponding_contract_file") # Function to normalize ABI by replacing interface name with contract name. # Base contracts aren't allowed to inherit from their interfaces in order @@ -190,9 +192,15 @@ for interface_file in $JSON_FILES; do # the contract type instead of the interface type but that's unlikely # to happen in practice and should be an easy fix if it does. local abi="$1" + + # Remove the leading "I" from types. abi="${abi//\"internalType\": \"contract I/\"internalType\": \"contract }" abi="${abi//\"internalType\": \"enum I/\"internalType\": \"enum }" abi="${abi//\"internalType\": \"struct I/\"internalType\": \"struct }" + + # Handle translating pseudo-constructors. + abi=$(echo "$abi" | jq 'map(if .type == "function" and .name == "__constructor__" then .type = "constructor" | del(.name) | del(.outputs) else . end)') + echo "$abi" } @@ -201,7 +209,7 @@ for interface_file in $JSON_FILES; do normalized_contract_abi=$(normalize_abi "$contract_abi") # Use jq to compare the ABIs - if ! diff_result=$(diff -u <(echo "$normalized_interface_abi" | jq -S .) <(echo "$normalized_contract_abi" | jq -S .)); then + if ! diff_result=$(diff -u <(echo "$normalized_interface_abi" | jq 'sort') <(echo "$normalized_contract_abi" | jq 'sort')); then if ! grep -q "^$contract_name$" "$REPORTED_INTERFACES_FILE"; then echo "$contract_name" >> "$REPORTED_INTERFACES_FILE" if ! is_excluded "$contract_name"; then diff --git a/packages/contracts-bedrock/src/L1/interfaces/IDataAvailabilityChallenge.sol b/packages/contracts-bedrock/src/L1/interfaces/IDataAvailabilityChallenge.sol index 5d89c2dac19c..db3c1680e6c5 100644 --- a/packages/contracts-bedrock/src/L1/interfaces/IDataAvailabilityChallenge.sol +++ b/packages/contracts-bedrock/src/L1/interfaces/IDataAvailabilityChallenge.sol @@ -89,4 +89,6 @@ interface IDataAvailabilityChallenge { function variableResolutionCostPrecision() external view returns (uint256); function version() external view returns (string memory); function withdraw() external; + + function __constructor__() external; } diff --git a/packages/contracts-bedrock/src/L1/interfaces/IDelayedVetoable.sol b/packages/contracts-bedrock/src/L1/interfaces/IDelayedVetoable.sol index 08e7b30ca6a1..0bea81fed34b 100644 --- a/packages/contracts-bedrock/src/L1/interfaces/IDelayedVetoable.sol +++ b/packages/contracts-bedrock/src/L1/interfaces/IDelayedVetoable.sol @@ -18,4 +18,6 @@ interface IDelayedVetoable { function target() external returns (address target_); function version() external view returns (string memory); function vetoer() external returns (address vetoer_); + + function __constructor__(address vetoer_, address initiator_, address target_, uint256 operatingDelay_) external; } diff --git a/packages/contracts-bedrock/src/L1/interfaces/IL2OutputOracle.sol b/packages/contracts-bedrock/src/L1/interfaces/IL2OutputOracle.sol index 22b66ee22264..408c53c85156 100644 --- a/packages/contracts-bedrock/src/L1/interfaces/IL2OutputOracle.sol +++ b/packages/contracts-bedrock/src/L1/interfaces/IL2OutputOracle.sol @@ -50,4 +50,6 @@ interface IL2OutputOracle { function startingTimestamp() external view returns (uint256); function submissionInterval() external view returns (uint256); function version() external view returns (string memory); + + function __constructor__() external; } diff --git a/packages/contracts-bedrock/src/L1/interfaces/IOptimismPortal2.sol b/packages/contracts-bedrock/src/L1/interfaces/IOptimismPortal2.sol index 2060b2088247..551bd2832b05 100644 --- a/packages/contracts-bedrock/src/L1/interfaces/IOptimismPortal2.sol +++ b/packages/contracts-bedrock/src/L1/interfaces/IOptimismPortal2.sol @@ -113,4 +113,6 @@ interface IOptimismPortal2 { function superchainConfig() external view returns (ISuperchainConfig); function systemConfig() external view returns (ISystemConfig); function version() external pure returns (string memory); + + function __constructor__(uint256 _proofMaturityDelaySeconds, uint256 _disputeGameFinalityDelaySeconds) external; } diff --git a/packages/contracts-bedrock/src/L1/interfaces/IOptimismPortalInterop.sol b/packages/contracts-bedrock/src/L1/interfaces/IOptimismPortalInterop.sol index 0102b3462ed1..682518897362 100644 --- a/packages/contracts-bedrock/src/L1/interfaces/IOptimismPortalInterop.sol +++ b/packages/contracts-bedrock/src/L1/interfaces/IOptimismPortalInterop.sol @@ -115,4 +115,6 @@ interface IOptimismPortalInterop { function superchainConfig() external view returns (ISuperchainConfig); function systemConfig() external view returns (ISystemConfig); function version() external pure returns (string memory); + + function __constructor__(uint256 _proofMaturityDelaySeconds, uint256 _disputeGameFinalityDelaySeconds) external; } diff --git a/packages/contracts-bedrock/src/L1/interfaces/IProtocolVersions.sol b/packages/contracts-bedrock/src/L1/interfaces/IProtocolVersions.sol index 0fbd8d1f2de6..aa2de51d4846 100644 --- a/packages/contracts-bedrock/src/L1/interfaces/IProtocolVersions.sol +++ b/packages/contracts-bedrock/src/L1/interfaces/IProtocolVersions.sol @@ -25,4 +25,6 @@ interface IProtocolVersions { function setRequired(ProtocolVersion _required) external; function transferOwnership(address newOwner) external; function version() external view returns (string memory); + + function __constructor__() external; } diff --git a/packages/contracts-bedrock/src/L1/interfaces/ISuperchainConfig.sol b/packages/contracts-bedrock/src/L1/interfaces/ISuperchainConfig.sol index d30c0e074f59..dc83893958b0 100644 --- a/packages/contracts-bedrock/src/L1/interfaces/ISuperchainConfig.sol +++ b/packages/contracts-bedrock/src/L1/interfaces/ISuperchainConfig.sol @@ -19,4 +19,6 @@ interface ISuperchainConfig { function paused() external view returns (bool paused_); function unpause() external; function version() external view returns (string memory); + + function __constructor__() external; } diff --git a/packages/contracts-bedrock/src/L1/interfaces/ISystemConfig.sol b/packages/contracts-bedrock/src/L1/interfaces/ISystemConfig.sol index fa4a597df307..59ae98668cf0 100644 --- a/packages/contracts-bedrock/src/L1/interfaces/ISystemConfig.sol +++ b/packages/contracts-bedrock/src/L1/interfaces/ISystemConfig.sol @@ -78,4 +78,6 @@ interface ISystemConfig { function transferOwnership(address newOwner) external; function unsafeBlockSigner() external view returns (address addr_); function version() external pure returns (string memory); + + function __constructor__() external; } diff --git a/packages/contracts-bedrock/src/L1/interfaces/ISystemConfigInterop.sol b/packages/contracts-bedrock/src/L1/interfaces/ISystemConfigInterop.sol index 3f6e6f723650..cffa30dd3efc 100644 --- a/packages/contracts-bedrock/src/L1/interfaces/ISystemConfigInterop.sol +++ b/packages/contracts-bedrock/src/L1/interfaces/ISystemConfigInterop.sol @@ -4,8 +4,66 @@ pragma solidity ^0.8.0; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; -interface ISystemConfigInterop is ISystemConfig { +interface ISystemConfigInterop { + event ConfigUpdate(uint256 indexed version, ISystemConfig.UpdateType indexed updateType, bytes data); + event Initialized(uint8 version); + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + function BATCH_INBOX_SLOT() external view returns (bytes32); + function DISPUTE_GAME_FACTORY_SLOT() external view returns (bytes32); + function L1_CROSS_DOMAIN_MESSENGER_SLOT() external view returns (bytes32); + function L1_ERC_721_BRIDGE_SLOT() external view returns (bytes32); + function L1_STANDARD_BRIDGE_SLOT() external view returns (bytes32); + function OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT() external view returns (bytes32); + function OPTIMISM_PORTAL_SLOT() external view returns (bytes32); + function START_BLOCK_SLOT() external view returns (bytes32); + function UNSAFE_BLOCK_SIGNER_SLOT() external view returns (bytes32); + function VERSION() external view returns (uint256); + function basefeeScalar() external view returns (uint32); + function batchInbox() external view returns (address addr_); + function batcherHash() external view returns (bytes32); + function blobbasefeeScalar() external view returns (uint32); + function disputeGameFactory() external view returns (address addr_); + function gasLimit() external view returns (uint64); + function gasPayingToken() external view returns (address addr_, uint8 decimals_); + function gasPayingTokenName() external view returns (string memory name_); + function gasPayingTokenSymbol() external view returns (string memory symbol_); + function initialize( + address _owner, + uint32 _basefeeScalar, + uint32 _blobbasefeeScalar, + bytes32 _batcherHash, + uint64 _gasLimit, + address _unsafeBlockSigner, + IResourceMetering.ResourceConfig memory _config, + address _batchInbox, + ISystemConfig.Addresses memory _addresses + ) + external; + function isCustomGasToken() external view returns (bool); + function l1CrossDomainMessenger() external view returns (address addr_); + function l1ERC721Bridge() external view returns (address addr_); + function l1StandardBridge() external view returns (address addr_); + function maximumGasLimit() external pure returns (uint64); + function minimumGasLimit() external view returns (uint64); + function optimismMintableERC20Factory() external view returns (address addr_); + function optimismPortal() external view returns (address addr_); + function overhead() external view returns (uint256); + function owner() external view returns (address); + function renounceOwnership() external; + function resourceConfig() external view returns (IResourceMetering.ResourceConfig memory); + function scalar() external view returns (uint256); + function setBatcherHash(bytes32 _batcherHash) external; + function setGasConfig(uint256 _overhead, uint256 _scalar) external; + function setGasConfigEcotone(uint32 _basefeeScalar, uint32 _blobbasefeeScalar) external; + function setGasLimit(uint64 _gasLimit) external; + function setUnsafeBlockSigner(address _unsafeBlockSigner) external; + function startBlock() external view returns (uint256 startBlock_); + function transferOwnership(address newOwner) external; + function unsafeBlockSigner() external view returns (address addr_); + function addDependency(uint256 _chainId) external; + function removeDependency(uint256 _chainId) external; function dependencyManager() external view returns (address); function initialize( address _owner, @@ -16,9 +74,9 @@ interface ISystemConfigInterop is ISystemConfig { address _unsafeBlockSigner, IResourceMetering.ResourceConfig memory _config, address _batchInbox, - Addresses memory _addresses, + ISystemConfig.Addresses memory _addresses, address _dependencyManager ) external; - function removeDependency(uint256 _chainId) external; + function version() external pure returns (string memory); } diff --git a/packages/contracts-bedrock/src/L2/interfaces/IBaseFeeVault.sol b/packages/contracts-bedrock/src/L2/interfaces/IBaseFeeVault.sol index 2c21ac00964a..9843189bdb14 100644 --- a/packages/contracts-bedrock/src/L2/interfaces/IBaseFeeVault.sol +++ b/packages/contracts-bedrock/src/L2/interfaces/IBaseFeeVault.sol @@ -5,4 +5,11 @@ import { IFeeVault } from "src/universal/interfaces/IFeeVault.sol"; interface IBaseFeeVault is IFeeVault { function version() external view returns (string memory); + + function __constructor__( + address _recipient, + uint256 _minWithdrawalAmount, + WithdrawalNetwork _withdrawalNetwork + ) + external; } diff --git a/packages/contracts-bedrock/src/L2/interfaces/IL1FeeVault.sol b/packages/contracts-bedrock/src/L2/interfaces/IL1FeeVault.sol index 539933762046..89ac3b782fca 100644 --- a/packages/contracts-bedrock/src/L2/interfaces/IL1FeeVault.sol +++ b/packages/contracts-bedrock/src/L2/interfaces/IL1FeeVault.sol @@ -5,4 +5,11 @@ import { IFeeVault } from "src/universal/interfaces/IFeeVault.sol"; interface IL1FeeVault is IFeeVault { function version() external view returns (string memory); + + function __constructor__( + address _recipient, + uint256 _minWithdrawalAmount, + WithdrawalNetwork _withdrawalNetwork + ) + external; } diff --git a/packages/contracts-bedrock/src/L2/interfaces/IL2CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L2/interfaces/IL2CrossDomainMessenger.sol index 9c6df21ef1d6..1cb49f674ec0 100644 --- a/packages/contracts-bedrock/src/L2/interfaces/IL2CrossDomainMessenger.sol +++ b/packages/contracts-bedrock/src/L2/interfaces/IL2CrossDomainMessenger.sol @@ -8,4 +8,6 @@ interface IL2CrossDomainMessenger is ICrossDomainMessenger { function initialize(ICrossDomainMessenger _l1CrossDomainMessenger) external; function l1CrossDomainMessenger() external view returns (ICrossDomainMessenger); function version() external view returns (string memory); + + function __constructor__() external; } diff --git a/packages/contracts-bedrock/src/L2/interfaces/IL2ERC721Bridge.sol b/packages/contracts-bedrock/src/L2/interfaces/IL2ERC721Bridge.sol index 1bfde1540015..a760ce1d803c 100644 --- a/packages/contracts-bedrock/src/L2/interfaces/IL2ERC721Bridge.sol +++ b/packages/contracts-bedrock/src/L2/interfaces/IL2ERC721Bridge.sol @@ -15,4 +15,6 @@ interface IL2ERC721Bridge is IERC721Bridge { external; function initialize(address payable _l1ERC721Bridge) external; function version() external view returns (string memory); + + function __constructor__() external; } diff --git a/packages/contracts-bedrock/src/L2/interfaces/IL2StandardBridge.sol b/packages/contracts-bedrock/src/L2/interfaces/IL2StandardBridge.sol index 559aa846c53c..9f9ce1a85621 100644 --- a/packages/contracts-bedrock/src/L2/interfaces/IL2StandardBridge.sol +++ b/packages/contracts-bedrock/src/L2/interfaces/IL2StandardBridge.sol @@ -43,4 +43,6 @@ interface IL2StandardBridge is IStandardBridge { ) external payable; + + function __constructor__() external; } diff --git a/packages/contracts-bedrock/src/L2/interfaces/IL2StandardBridgeInterop.sol b/packages/contracts-bedrock/src/L2/interfaces/IL2StandardBridgeInterop.sol index 1c0327baf3b3..227b48881fa6 100644 --- a/packages/contracts-bedrock/src/L2/interfaces/IL2StandardBridgeInterop.sol +++ b/packages/contracts-bedrock/src/L2/interfaces/IL2StandardBridgeInterop.sol @@ -2,14 +2,15 @@ pragma solidity ^0.8.0; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { IL2StandardBridge } from "src/L2/interfaces/IL2StandardBridge.sol"; +import { IStandardBridge } from "src/universal/interfaces/IStandardBridge.sol"; +import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; interface IMintableAndBurnable is IERC20 { function mint(address, uint256) external; function burn(address, uint256) external; } -interface IL2StandardBridgeInterop is IL2StandardBridge { +interface IL2StandardBridgeInterop is IStandardBridge { error InvalidDecimals(); error InvalidLegacyERC20Address(); error InvalidSuperchainERC20Address(); @@ -19,5 +20,79 @@ interface IL2StandardBridgeInterop is IL2StandardBridge { receive() external payable; + event DepositFinalized( + address indexed l1Token, + address indexed l2Token, + address indexed from, + address to, + uint256 amount, + bytes extraData + ); + event WithdrawalInitiated( + address indexed l1Token, + address indexed l2Token, + address indexed from, + address to, + uint256 amount, + bytes extraData + ); + + function MESSENGER() external view returns (ICrossDomainMessenger); + function OTHER_BRIDGE() external view returns (IStandardBridge); + function bridgeERC20( + address _localToken, + address _remoteToken, + uint256 _amount, + uint32 _minGasLimit, + bytes memory _extraData + ) + external; + function bridgeERC20To( + address _localToken, + address _remoteToken, + address _to, + uint256 _amount, + uint32 _minGasLimit, + bytes memory _extraData + ) + external; + function bridgeETH(uint32 _minGasLimit, bytes memory _extraData) external payable; + function bridgeETHTo(address _to, uint32 _minGasLimit, bytes memory _extraData) external payable; + function deposits(address, address) external view returns (uint256); + function finalizeBridgeERC20( + address _localToken, + address _remoteToken, + address _from, + address _to, + uint256 _amount, + bytes memory _extraData + ) + external; + function finalizeBridgeETH(address _from, address _to, uint256 _amount, bytes memory _extraData) external payable; + function messenger() external view returns (ICrossDomainMessenger); + function otherBridge() external view returns (IStandardBridge); + function paused() external view returns (bool); + + function initialize(IStandardBridge _otherBridge) external; + function l1TokenBridge() external view returns (address); + function withdraw( + address _l2Token, + uint256 _amount, + uint32 _minGasLimit, + bytes memory _extraData + ) + external + payable; + function withdrawTo( + address _l2Token, + address _to, + uint256 _amount, + uint32 _minGasLimit, + bytes memory _extraData + ) + external + payable; + function convert(address _from, address _to, uint256 _amount) external; + function version() external pure returns (string memory); } diff --git a/packages/contracts-bedrock/src/L2/interfaces/ISequencerFeeVault.sol b/packages/contracts-bedrock/src/L2/interfaces/ISequencerFeeVault.sol index d6643b6054be..1987d07bb7f7 100644 --- a/packages/contracts-bedrock/src/L2/interfaces/ISequencerFeeVault.sol +++ b/packages/contracts-bedrock/src/L2/interfaces/ISequencerFeeVault.sol @@ -6,4 +6,11 @@ import { IFeeVault } from "src/universal/interfaces/IFeeVault.sol"; interface ISequencerFeeVault is IFeeVault { function version() external view returns (string memory); function l1FeeWallet() external view returns (address); + + function __constructor__( + address _recipient, + uint256 _minWithdrawalAmount, + WithdrawalNetwork _withdrawalNetwork + ) + external; } diff --git a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS.sol b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS.sol index 8e42ccf6dfa0..75f4e50f3ba3 100644 --- a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS.sol +++ b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS.sol @@ -12,4 +12,6 @@ interface IMIPS is ISemver { function oracle() external view returns (IPreimageOracle oracle_); function step(bytes memory _stateData, bytes memory _proof, bytes32 _localContext) external returns (bytes32); + + function __constructor__(IPreimageOracle _oracle) external; } diff --git a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol index 39653f031e3f..8f57c0f63695 100644 --- a/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol +++ b/packages/contracts-bedrock/src/cannon/interfaces/IMIPS2.sol @@ -14,4 +14,6 @@ interface IMIPS2 is ISemver { function oracle() external view returns (IPreimageOracle oracle_); function step(bytes memory _stateData, bytes memory _proof, bytes32 _localContext) external returns (bytes32); + + function __constructor__(IPreimageOracle _oracle) external; } diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IAnchorStateRegistry.sol b/packages/contracts-bedrock/src/dispute/interfaces/IAnchorStateRegistry.sol index e0bc9ef53e8b..28c544c0d408 100644 --- a/packages/contracts-bedrock/src/dispute/interfaces/IAnchorStateRegistry.sol +++ b/packages/contracts-bedrock/src/dispute/interfaces/IAnchorStateRegistry.sol @@ -29,4 +29,6 @@ interface IAnchorStateRegistry { function superchainConfig() external view returns (ISuperchainConfig); function tryUpdateAnchorState() external; function version() external view returns (string memory); + + function __constructor__(IDisputeGameFactory _disputeGameFactory) external; } diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGameFactory.sol b/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGameFactory.sol index 68bee806843a..1e70cbbb05bf 100644 --- a/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGameFactory.sol +++ b/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGameFactory.sol @@ -69,4 +69,6 @@ interface IDisputeGameFactory { function setInitBond(GameType _gameType, uint256 _initBond) external; function transferOwnership(address newOwner) external; function version() external view returns (string memory); + + function __constructor__() external; } diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IFaultDisputeGame.sol b/packages/contracts-bedrock/src/dispute/interfaces/IFaultDisputeGame.sol index 3d9621c54ed2..379c4fcb6a48 100644 --- a/packages/contracts-bedrock/src/dispute/interfaces/IFaultDisputeGame.sol +++ b/packages/contracts-bedrock/src/dispute/interfaces/IFaultDisputeGame.sol @@ -112,4 +112,18 @@ interface IFaultDisputeGame is IDisputeGame { function version() external view returns (string memory); function vm() external view returns (IBigStepper vm_); function weth() external view returns (IDelayedWETH weth_); + + function __constructor__( + GameType _gameType, + Claim _absolutePrestate, + uint256 _maxGameDepth, + uint256 _splitDepth, + Duration _clockExtension, + Duration _maxClockDuration, + IBigStepper _vm, + IDelayedWETH _weth, + IAnchorStateRegistry _anchorStateRegistry, + uint256 _l2ChainId + ) + external; } diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IPermissionedDisputeGame.sol b/packages/contracts-bedrock/src/dispute/interfaces/IPermissionedDisputeGame.sol index 3872a769f892..5fda4e9163b2 100644 --- a/packages/contracts-bedrock/src/dispute/interfaces/IPermissionedDisputeGame.sol +++ b/packages/contracts-bedrock/src/dispute/interfaces/IPermissionedDisputeGame.sol @@ -1,11 +1,137 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; +import { Types } from "src/libraries/Types.sol"; +import "src/dispute/lib/Types.sol"; + +import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; +import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; +import { IBigStepper } from "src/dispute/interfaces/IBigStepper.sol"; +import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; + +interface IPermissionedDisputeGame is IDisputeGame { + struct ClaimData { + uint32 parentIndex; + address counteredBy; + address claimant; + uint128 bond; + Claim claim; + Position position; + Clock clock; + } + + struct ResolutionCheckpoint { + bool initialCheckpointComplete; + uint32 subgameIndex; + Position leftmostPosition; + address counteredBy; + } + + error AlreadyInitialized(); + error AnchorRootNotFound(); + error BlockNumberMatches(); + error BondTransferFailed(); + error CannotDefendRootClaim(); + error ClaimAboveSplit(); + error ClaimAlreadyExists(); + error ClaimAlreadyResolved(); + error ClockNotExpired(); + error ClockTimeExceeded(); + error ContentLengthMismatch(); + error DuplicateStep(); + error EmptyItem(); + error GameDepthExceeded(); + error GameNotInProgress(); + error IncorrectBondAmount(); + error InvalidChallengePeriod(); + error InvalidClockExtension(); + error InvalidDataRemainder(); + error InvalidDisputedClaimIndex(); + error InvalidHeader(); + error InvalidHeaderRLP(); + error InvalidLocalIdent(); + error InvalidOutputRootProof(); + error InvalidParent(); + error InvalidPrestate(); + error InvalidSplitDepth(); + error L2BlockNumberChallenged(); + error MaxDepthTooLarge(); + error NoCreditToClaim(); + error OutOfOrderResolution(); + error UnexpectedList(); + error UnexpectedRootClaim(Claim rootClaim); + error UnexpectedString(); + error ValidStep(); + + event Move(uint256 indexed parentIndex, Claim indexed claim, address indexed claimant); + + function absolutePrestate() external view returns (Claim absolutePrestate_); + function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) external; + function anchorStateRegistry() external view returns (IAnchorStateRegistry registry_); + function attack(Claim _disputed, uint256 _parentIndex, Claim _claim) external payable; + function challengeRootL2Block(Types.OutputRootProof memory _outputRootProof, bytes memory _headerRLP) external; + function claimCredit(address _recipient) external; + function claimData(uint256) + external + view + returns ( + uint32 parentIndex, + address counteredBy, + address claimant, + uint128 bond, + Claim claim, + Position position, + Clock clock + ); + function claimDataLen() external view returns (uint256 len_); + function claims(Hash) external view returns (bool); + function clockExtension() external view returns (Duration clockExtension_); + function credit(address) external view returns (uint256); + function defend(Claim _disputed, uint256 _parentIndex, Claim _claim) external payable; + function getChallengerDuration(uint256 _claimIndex) external view returns (Duration duration_); + function getNumToResolve(uint256 _claimIndex) external view returns (uint256 numRemainingChildren_); + function getRequiredBond(Position _position) external view returns (uint256 requiredBond_); + function l2BlockNumber() external pure returns (uint256 l2BlockNumber_); + function l2BlockNumberChallenged() external view returns (bool); + function l2BlockNumberChallenger() external view returns (address); + function l2ChainId() external view returns (uint256 l2ChainId_); + function maxClockDuration() external view returns (Duration maxClockDuration_); + function maxGameDepth() external view returns (uint256 maxGameDepth_); + function move(Claim _disputed, uint256 _challengeIndex, Claim _claim, bool _isAttack) external payable; + function resolutionCheckpoints(uint256) + external + view + returns (bool initialCheckpointComplete, uint32 subgameIndex, Position leftmostPosition, address counteredBy); + function resolveClaim(uint256 _claimIndex, uint256 _numToResolve) external; + function resolvedSubgames(uint256) external view returns (bool); + function splitDepth() external view returns (uint256 splitDepth_); + function startingBlockNumber() external view returns (uint256 startingBlockNumber_); + function startingOutputRoot() external view returns (Hash root, uint256 l2BlockNumber); + function startingRootHash() external view returns (Hash startingRootHash_); + function step(uint256 _claimIndex, bool _isAttack, bytes memory _stateData, bytes memory _proof) external; + function subgames(uint256, uint256) external view returns (uint256); + function version() external view returns (string memory); + function vm() external view returns (IBigStepper vm_); + function weth() external view returns (IDelayedWETH weth_); -interface IPermissionedDisputeGame is IFaultDisputeGame { error BadAuth(); function proposer() external view returns (address proposer_); function challenger() external view returns (address challenger_); + + function __constructor__( + GameType _gameType, + Claim _absolutePrestate, + uint256 _maxGameDepth, + uint256 _splitDepth, + Duration _clockExtension, + Duration _maxClockDuration, + IBigStepper _vm, + IDelayedWETH _weth, + IAnchorStateRegistry _anchorStateRegistry, + uint256 _l2ChainId, + address _proposer, + address _challenger + ) + external; } diff --git a/packages/contracts-bedrock/src/governance/interfaces/IGovernanceToken.sol b/packages/contracts-bedrock/src/governance/interfaces/IGovernanceToken.sol index dbef37042f63..04a0490adc9b 100644 --- a/packages/contracts-bedrock/src/governance/interfaces/IGovernanceToken.sol +++ b/packages/contracts-bedrock/src/governance/interfaces/IGovernanceToken.sol @@ -47,4 +47,6 @@ interface IGovernanceToken { function transfer(address to, uint256 amount) external returns (bool); function transferFrom(address from, address to, uint256 amount) external returns (bool); function transferOwnership(address newOwner) external; + + function __constructor__() external; } diff --git a/packages/contracts-bedrock/src/governance/interfaces/IMintManager.sol b/packages/contracts-bedrock/src/governance/interfaces/IMintManager.sol index 2bd9da196d62..e769f3042e53 100644 --- a/packages/contracts-bedrock/src/governance/interfaces/IMintManager.sol +++ b/packages/contracts-bedrock/src/governance/interfaces/IMintManager.sol @@ -16,4 +16,6 @@ interface IMintManager { function renounceOwnership() external; function transferOwnership(address newOwner) external; function upgrade(address _newMintManager) external; + + function __constructor__(address _upgrader, address _governanceToken) external; } diff --git a/packages/contracts-bedrock/src/legacy/interfaces/IL1ChugSplashProxy.sol b/packages/contracts-bedrock/src/legacy/interfaces/IL1ChugSplashProxy.sol index f4ca59fb5511..863c89906751 100644 --- a/packages/contracts-bedrock/src/legacy/interfaces/IL1ChugSplashProxy.sol +++ b/packages/contracts-bedrock/src/legacy/interfaces/IL1ChugSplashProxy.sol @@ -13,6 +13,8 @@ interface IL1ChugSplashProxy { function setCode(bytes memory _code) external; function setOwner(address _owner) external; function setStorage(bytes32 _key, bytes32 _value) external; + + function __constructor__(address _owner) external; } /// @title IStaticL1ChugSplashProxy diff --git a/packages/contracts-bedrock/src/universal/interfaces/IOptimismMintableERC20Factory.sol b/packages/contracts-bedrock/src/universal/interfaces/IOptimismMintableERC20Factory.sol index ecb52c94cada..91f6eba6c175 100644 --- a/packages/contracts-bedrock/src/universal/interfaces/IOptimismMintableERC20Factory.sol +++ b/packages/contracts-bedrock/src/universal/interfaces/IOptimismMintableERC20Factory.sol @@ -33,4 +33,6 @@ interface IOptimismMintableERC20Factory { function deployments(address) external view returns (address); function initialize(address _bridge) external; function version() external view returns (string memory); + + function __constructor__() external; } From 0543bf7a4a1cb732ec9a13581116db943d0627e4 Mon Sep 17 00:00:00 2001 From: protolambda <proto@protolambda.com> Date: Fri, 20 Sep 2024 17:30:16 -0600 Subject: [PATCH 223/264] op-supervisor: store block-checkpoints per block, implement block iteration (#11989) * op-supervisor: register each L2 block, refactor Signed-off-by: protolambda <proto@protolambda.com> * op-supervisor: fix lint and tests * op-supervisor: minor fixes, logging * op-supervisor: fix semgrep --------- Signed-off-by: protolambda <proto@protolambda.com> --- op-e2e/interop/supersystem.go | 3 +- op-supervisor/supervisor/backend/backend.go | 47 +- op-supervisor/supervisor/backend/db/db.go | 135 +-- .../supervisor/backend/db/db_test.go | 373 +++--- .../supervisor/backend/db/entrydb/entry_db.go | 59 + op-supervisor/supervisor/backend/db/init.go | 34 - .../supervisor/backend/db/init_test.go | 91 -- .../supervisor/backend/db/logs/db.go | 671 +++++------ .../backend/db/logs/db_invariants_test.go | 96 +- .../supervisor/backend/db/logs/db_test.go | 1024 ++++++++++------- .../supervisor/backend/db/logs/entries.go | 154 +-- .../supervisor/backend/db/logs/iterator.go | 190 +-- .../supervisor/backend/db/logs/state.go | 407 +++++++ .../supervisor/backend/db/safety_checkers.go | 13 +- .../backend/db/safety_checkers_test.go | 25 +- .../supervisor/backend/source/chain.go | 9 +- .../backend/source/chain_processor.go | 2 +- .../backend/source/log_processor.go | 16 +- .../backend/source/log_processor_test.go | 96 +- 19 files changed, 1908 insertions(+), 1537 deletions(-) delete mode 100644 op-supervisor/supervisor/backend/db/init.go delete mode 100644 op-supervisor/supervisor/backend/db/init_test.go create mode 100644 op-supervisor/supervisor/backend/db/logs/state.go diff --git a/op-e2e/interop/supersystem.go b/op-e2e/interop/supersystem.go index 58c0d4f4370f..ffa91bef97f3 100644 --- a/op-e2e/interop/supersystem.go +++ b/op-e2e/interop/supersystem.go @@ -416,7 +416,8 @@ func (s *interopE2ESystem) newL2(id string, l2Out *interopgen.L2Output) l2Set { // prepareSupervisor creates a new supervisor for the system func (s *interopE2ESystem) prepareSupervisor() *supervisor.SupervisorService { - logger := s.logger.New("role", "supervisor") + // Be verbose with op-supervisor, it's in early test phase + logger := testlog.Logger(s.t, log.LevelDebug).New("role", "supervisor") cfg := supervisorConfig.Config{ MetricsConfig: metrics.CLIConfig{ Enabled: false, diff --git a/op-supervisor/supervisor/backend/backend.go b/op-supervisor/supervisor/backend/backend.go index 5be0b6a4c80d..57b17e591059 100644 --- a/op-supervisor/supervisor/backend/backend.go +++ b/op-supervisor/supervisor/backend/backend.go @@ -9,8 +9,13 @@ import ( "sync/atomic" "time" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/op-service/client" "github.com/ethereum-optimism/optimism/op-service/dial" + "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-supervisor/config" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads" @@ -19,9 +24,6 @@ import ( backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/frontend" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/log" ) type SupervisorBackend struct { @@ -94,7 +96,7 @@ func (su *SupervisorBackend) addFromRPC(ctx context.Context, logger log.Logger, if err != nil { return fmt.Errorf("failed to create datadir for chain %v: %w", chainID, err) } - logDB, err := logs.NewFromFile(logger, cm, path) + logDB, err := logs.NewFromFile(logger, cm, path, true) if err != nil { return fmt.Errorf("failed to create logdb for chain %v at %v: %w", chainID, path, err) } @@ -133,8 +135,9 @@ func (su *SupervisorBackend) Start(ctx context.Context) error { if !su.started.CompareAndSwap(false, true) { return errors.New("already started") } - // initiate "Resume" on the chains db, which rewinds the database to the last block that is guaranteed to have been fully recorded - if err := su.db.Resume(); err != nil { + // initiate "ResumeFromLastSealedBlock" on the chains db, + // which rewinds the database to the last block that is guaranteed to have been fully recorded + if err := su.db.ResumeFromLastSealedBlock(); err != nil { return fmt.Errorf("failed to resume chains db: %w", err) } // start chain monitors @@ -144,8 +147,8 @@ func (su *SupervisorBackend) Start(ctx context.Context) error { } } // start db maintenance loop - maintinenceCtx, cancel := context.WithCancel(context.Background()) - su.db.StartCrossHeadMaintenance(maintinenceCtx) + maintenanceCtx, cancel := context.WithCancel(context.Background()) + su.db.StartCrossHeadMaintenance(maintenanceCtx) su.maintenanceCancel = cancel return nil } @@ -188,13 +191,16 @@ func (su *SupervisorBackend) CheckMessage(identifier types.Identifier, payloadHa chainID := identifier.ChainID blockNum := identifier.BlockNumber logIdx := identifier.LogIndex - ok, i, err := su.db.Check(chainID, blockNum, uint32(logIdx), backendTypes.TruncateHash(payloadHash)) - if err != nil { - return types.Invalid, fmt.Errorf("failed to check log: %w", err) + i, err := su.db.Check(chainID, blockNum, uint32(logIdx), backendTypes.TruncateHash(payloadHash)) + if errors.Is(err, logs.ErrFuture) { + return types.Unsafe, nil } - if !ok { + if errors.Is(err, logs.ErrConflict) { return types.Invalid, nil } + if err != nil { + return types.Invalid, fmt.Errorf("failed to check log: %w", err) + } safest := types.CrossUnsafe // at this point we have the log entry, and we can check if it is safe by various criteria for _, checker := range []db.SafetyChecker{ @@ -231,16 +237,19 @@ func (su *SupervisorBackend) CheckMessages( // The block is considered safe if all logs in the block are safe // this is decided by finding the last log in the block and func (su *SupervisorBackend) CheckBlock(chainID *hexutil.U256, blockHash common.Hash, blockNumber hexutil.Uint64) (types.SafetyLevel, error) { - // TODO(#11612): this function ignores blockHash and assumes that the block in the db is the one we are looking for - // In order to check block hash, the database must *always* insert a block hash checkpoint, which is not currently done safest := types.CrossUnsafe // find the last log index in the block - i, err := su.db.LastLogInBlock(types.ChainID(*chainID), uint64(blockNumber)) - // TODO(#11836) checking for EOF as a non-error case is a bit of a code smell - // and could potentially be incorrect if the given block number is intentionally far in the future - if err != nil && !errors.Is(err, io.EOF) { + id := eth.BlockID{Hash: blockHash, Number: uint64(blockNumber)} + i, err := su.db.FindSealedBlock(types.ChainID(*chainID), id) + if errors.Is(err, logs.ErrFuture) { + return types.Unsafe, nil + } + if errors.Is(err, logs.ErrConflict) { + return types.Invalid, nil + } + if err != nil { su.logger.Error("failed to scan block", "err", err) - return types.Invalid, fmt.Errorf("failed to scan block: %w", err) + return "", err } // at this point we have the extent of the block, and we can check if it is safe by various criteria for _, checker := range []db.SafetyChecker{ diff --git a/op-supervisor/supervisor/backend/db/db.go b/op-supervisor/supervisor/backend/db/db.go index c05bab400b7b..ac8c5f506ca5 100644 --- a/op-supervisor/supervisor/backend/db/db.go +++ b/op-supervisor/supervisor/backend/db/db.go @@ -7,13 +7,15 @@ import ( "io" "time" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs" backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" - "github.com/ethereum/go-ethereum/log" ) var ( @@ -22,16 +24,32 @@ var ( type LogStorage interface { io.Closer - AddLog(logHash backendTypes.TruncatedHash, block eth.BlockID, timestamp uint64, logIdx uint32, execMsg *backendTypes.ExecutingMessage) error + + AddLog(logHash backendTypes.TruncatedHash, parentBlock eth.BlockID, + logIdx uint32, execMsg *backendTypes.ExecutingMessage) error + + SealBlock(parentHash common.Hash, block eth.BlockID, timestamp uint64) error + Rewind(newHeadBlockNum uint64) error - LatestBlockNum() uint64 - ClosestBlockInfo(blockNum uint64) (uint64, backendTypes.TruncatedHash, error) - ClosestBlockIterator(blockNum uint64) (logs.Iterator, error) - Contains(blockNum uint64, logIdx uint32, loghash backendTypes.TruncatedHash) (bool, entrydb.EntryIdx, error) - LastCheckpointBehind(entrydb.EntryIdx) (logs.Iterator, error) - NextExecutingMessage(logs.Iterator) (backendTypes.ExecutingMessage, error) + + LatestSealedBlockNum() (n uint64, ok bool) + + // FindSealedBlock finds the requested block, to check if it exists, + // returning the next index after it where things continue from. + // returns ErrFuture if the block is too new to be able to tell + // returns ErrDifferent if the known block does not match + FindSealedBlock(block eth.BlockID) (nextEntry entrydb.EntryIdx, err error) + + IteratorStartingAt(i entrydb.EntryIdx) (logs.Iterator, error) + + // returns ErrConflict if the log does not match the canonical chain. + // returns ErrFuture if the log is out of reach. + // returns nil if the log is known and matches the canonical chain. + Contains(blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) (nextIndex entrydb.EntryIdx, err error) } +var _ LogStorage = (*logs.DB)(nil) + type HeadsStorage interface { Current() *heads.Heads Apply(op heads.Operation) error @@ -62,14 +80,20 @@ func (db *ChainsDB) AddLogDB(chain types.ChainID, logDB LogStorage) { db.logDBs[chain] = logDB } -// Resume prepares the chains db to resume recording events after a restart. -// It rewinds the database to the last block that is guaranteed to have been fully recorded to the database +// ResumeFromLastSealedBlock prepares the chains db to resume recording events after a restart. +// It rewinds the database to the last block that is guaranteed to have been fully recorded to the database, // to ensure it can resume recording from the first log of the next block. -// TODO(#11793): we can rename this to something more descriptive like "PrepareWithRollback" -func (db *ChainsDB) Resume() error { +func (db *ChainsDB) ResumeFromLastSealedBlock() error { for chain, logStore := range db.logDBs { - if err := Resume(logStore); err != nil { - return fmt.Errorf("failed to resume chain %v: %w", chain, err) + headNum, ok := logStore.LatestSealedBlockNum() + if ok { + // db must be empty, nothing to rewind to + db.logger.Info("Resuming, but found no DB contents", "chain", chain) + continue + } + db.logger.Info("Resuming, starting from last sealed block", "head", headNum) + if err := logStore.Rewind(headNum); err != nil { + return fmt.Errorf("failed to rewind chain %s to sealed block %d", chain, headNum) } } return nil @@ -101,10 +125,10 @@ func (db *ChainsDB) StartCrossHeadMaintenance(ctx context.Context) { } // Check calls the underlying logDB to determine if the given log entry is safe with respect to the checker's criteria. -func (db *ChainsDB) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) (bool, entrydb.EntryIdx, error) { +func (db *ChainsDB) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) (entrydb.EntryIdx, error) { logDB, ok := db.logDBs[chain] if !ok { - return false, 0, fmt.Errorf("%w: %v", ErrUnknownChain, chain) + return 0, fmt.Errorf("%w: %v", ErrUnknownChain, chain) } return logDB.Contains(blockNum, logIdx, logHash) } @@ -146,7 +170,7 @@ func (db *ChainsDB) UpdateCrossHeadsForChain(chainID types.ChainID, checker Safe // advance as far as the local head localHead := checker.LocalHeadForChain(chainID) // get an iterator for the last checkpoint behind the x-head - i, err := db.logDBs[chainID].LastCheckpointBehind(xHead) + iter, err := db.logDBs[chainID].IteratorStartingAt(xHead) if err != nil { return fmt.Errorf("failed to rewind cross-safe head for chain %v: %w", chainID, err) } @@ -158,16 +182,21 @@ func (db *ChainsDB) UpdateCrossHeadsForChain(chainID types.ChainID, checker Safe // - when we reach a message that is not safe // - if an error occurs for { - exec, err := db.logDBs[chainID].NextExecutingMessage(i) - if err == io.EOF { + if err := iter.NextExecMsg(); err == io.EOF { break } else if err != nil { return fmt.Errorf("failed to read next executing message for chain %v: %w", chainID, err) } - // if we are now beyond the local head, stop - if i.Index() > localHead { + // if we would exceed the local head, then abort + if iter.NextIndex() > localHead { + xHead = localHead // clip to local head + updated = localHead != xHead break } + exec := iter.ExecMessage() + if exec == nil { + panic("expected executing message after traversing to one without error") + } // use the checker to determine if this message is safe safe := checker.Check( types.ChainIDFromUInt64(uint64(exec.Chain)), @@ -178,10 +207,9 @@ func (db *ChainsDB) UpdateCrossHeadsForChain(chainID types.ChainID, checker Safe break } // if all is well, prepare the x-head update to this point - xHead = i.Index() + xHead = iter.NextIndex() updated = true } - // have the checker create an update to the x-head in question, and apply that update err = db.heads.Apply(checker.Update(chainID, xHead)) if err != nil { @@ -191,8 +219,10 @@ func (db *ChainsDB) UpdateCrossHeadsForChain(chainID types.ChainID, checker Safe // this allows for the maintenance loop to handle cascading updates // instead of waiting for the next scheduled update if updated { - db.logger.Debug("heads were updated, requesting maintenance") + db.logger.Info("Promoting cross-head", "head", xHead, "safety-level", checker.SafetyLevel()) db.RequestMaintenance() + } else { + db.logger.Info("No cross-head update", "head", xHead, "safety-level", checker.SafetyLevel()) } return nil } @@ -210,62 +240,39 @@ func (db *ChainsDB) UpdateCrossHeads(checker SafetyChecker) error { return nil } -// LastLogInBlock scans through the logs of the given chain starting from the given block number, -// and returns the index of the last log entry in that block. -func (db *ChainsDB) LastLogInBlock(chain types.ChainID, blockNum uint64) (entrydb.EntryIdx, error) { +func (db *ChainsDB) FindSealedBlock(chain types.ChainID, block eth.BlockID) (nextEntry entrydb.EntryIdx, err error) { logDB, ok := db.logDBs[chain] if !ok { return 0, fmt.Errorf("%w: %v", ErrUnknownChain, chain) } - iter, err := logDB.ClosestBlockIterator(blockNum) - if err != nil { - return 0, fmt.Errorf("failed to get block iterator for chain %v: %w", chain, err) - } - ret := entrydb.EntryIdx(0) - // scan through using the iterator until the block number exceeds the target - for { - bn, index, _, err := iter.NextLog() - // if we have reached the end of the database, stop - if err == io.EOF { - break - } - // all other errors are fatal - if err != nil { - return 0, fmt.Errorf("failed to read next log entry for chain %v: %w", chain, err) - } - // if we are now beyond the target block, stop withour updating the return value - if bn > blockNum { - break - } - // only update the return value if the block number is the same - // it is possible the iterator started before the target block, or that the target block is not in the db - if bn == blockNum { - ret = entrydb.EntryIdx(index) - } - } - // if we never found the block, return an error - if ret == 0 { - return 0, fmt.Errorf("block %v not found in chain %v", blockNum, chain) - } - return ret, nil + return logDB.FindSealedBlock(block) } -// LatestBlockNum returns the latest block number that has been recorded to the logs db +// LatestBlockNum returns the latest fully-sealed block number that has been recorded to the logs db // for the given chain. It does not contain safety guarantees. -func (db *ChainsDB) LatestBlockNum(chain types.ChainID) uint64 { +// The block number might not be available (empty database, or non-existent chain). +func (db *ChainsDB) LatestBlockNum(chain types.ChainID) (num uint64, ok bool) { + logDB, knownChain := db.logDBs[chain] + if !knownChain { + return 0, false + } + return logDB.LatestSealedBlockNum() +} + +func (db *ChainsDB) SealBlock(chain types.ChainID, parentHash common.Hash, block eth.BlockID, timestamp uint64) error { logDB, ok := db.logDBs[chain] if !ok { - return 0 + return fmt.Errorf("%w: %v", ErrUnknownChain, chain) } - return logDB.LatestBlockNum() + return logDB.SealBlock(parentHash, block, timestamp) } -func (db *ChainsDB) AddLog(chain types.ChainID, logHash backendTypes.TruncatedHash, block eth.BlockID, timestamp uint64, logIdx uint32, execMsg *backendTypes.ExecutingMessage) error { +func (db *ChainsDB) AddLog(chain types.ChainID, logHash backendTypes.TruncatedHash, parentBlock eth.BlockID, logIdx uint32, execMsg *backendTypes.ExecutingMessage) error { logDB, ok := db.logDBs[chain] if !ok { return fmt.Errorf("%w: %v", ErrUnknownChain, chain) } - return logDB.AddLog(logHash, block, timestamp, logIdx, execMsg) + return logDB.AddLog(logHash, parentBlock, logIdx, execMsg) } func (db *ChainsDB) Rewind(chain types.ChainID, headBlockNum uint64) error { diff --git a/op-supervisor/supervisor/backend/db/db_test.go b/op-supervisor/supervisor/backend/db/db_test.go index 71a4c50cf239..eb10afd7f641 100644 --- a/op-supervisor/supervisor/backend/db/db_test.go +++ b/op-supervisor/supervisor/backend/db/db_test.go @@ -1,10 +1,16 @@ package db import ( - "fmt" + "errors" "io" + "math/rand" // nosemgrep "testing" + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" @@ -12,14 +18,12 @@ import ( "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs" backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" - "github.com/ethereum/go-ethereum/log" - "github.com/stretchr/testify/require" ) func TestChainsDB_AddLog(t *testing.T) { t.Run("UnknownChain", func(t *testing.T) { db := NewChainsDB(nil, &stubHeadStorage{}, testlog.Logger(t, log.LevelDebug)) - err := db.AddLog(types.ChainIDFromUInt64(2), backendTypes.TruncatedHash{}, eth.BlockID{}, 1234, 33, nil) + err := db.AddLog(types.ChainIDFromUInt64(2), backendTypes.TruncatedHash{}, eth.BlockID{}, 33, nil) require.ErrorIs(t, err, ErrUnknownChain) }) @@ -28,11 +32,14 @@ func TestChainsDB_AddLog(t *testing.T) { logDB := &stubLogDB{} db := NewChainsDB(map[types.ChainID]LogStorage{ chainID: logDB, - }, &stubHeadStorage{}, - testlog.Logger(t, log.LevelDebug)) - err := db.AddLog(chainID, backendTypes.TruncatedHash{}, eth.BlockID{}, 1234, 33, nil) + }, &stubHeadStorage{}, testlog.Logger(t, log.LevelDebug)) + bl10 := eth.BlockID{Hash: common.Hash{0x10}, Number: 10} + err := db.SealBlock(chainID, common.Hash{0x9}, bl10, 1234) + require.NoError(t, err, err) + err = db.AddLog(chainID, backendTypes.TruncatedHash{}, bl10, 0, nil) require.NoError(t, err, err) require.Equal(t, 1, logDB.addLogCalls) + require.Equal(t, 1, logDB.sealBlockCalls) }) } @@ -56,128 +63,15 @@ func TestChainsDB_Rewind(t *testing.T) { }) } -func TestChainsDB_LastLogInBlock(t *testing.T) { - // using a chainID of 1 for simplicity - chainID := types.ChainIDFromUInt64(1) - // get default stubbed components - logDB, _, h := setupStubbedForUpdateHeads(chainID) - logDB.nextLogs = []nextLogResponse{ - {10, 1, backendTypes.TruncatedHash{}, nil}, - {10, 2, backendTypes.TruncatedHash{}, nil}, - {10, 3, backendTypes.TruncatedHash{}, nil}, - {10, 4, backendTypes.TruncatedHash{}, nil}, - {11, 5, backendTypes.TruncatedHash{}, nil}, - } - - // The ChainsDB is real, but uses only stubbed components - db := NewChainsDB( - map[types.ChainID]LogStorage{ - chainID: logDB}, - &stubHeadStorage{h}, - testlog.Logger(t, log.LevelDebug)) - - // LastLogInBlock is expected to: - // 1. get a block iterator for block 10 (stubbed) - // 2. scan through the iterator until the block number exceeds the target (10) - // 3. return the index of the last log in the block (4) - index, err := db.LastLogInBlock(chainID, 10) - require.NoError(t, err) - require.Equal(t, entrydb.EntryIdx(4), index) -} - -func TestChainsDB_LastLogInBlockEOF(t *testing.T) { - // using a chainID of 1 for simplicity - chainID := types.ChainIDFromUInt64(1) - // get default stubbed components - logDB, _, h := setupStubbedForUpdateHeads(chainID) - logDB.nextLogs = []nextLogResponse{ - {10, 5, backendTypes.TruncatedHash{}, nil}, - {10, 6, backendTypes.TruncatedHash{}, nil}, - {10, 7, backendTypes.TruncatedHash{}, nil}, - {10, 8, backendTypes.TruncatedHash{}, nil}, - {10, 9, backendTypes.TruncatedHash{}, nil}, - {10, 10, backendTypes.TruncatedHash{}, nil}, - } - - // The ChainsDB is real, but uses only stubbed components - db := NewChainsDB( - map[types.ChainID]LogStorage{ - chainID: logDB}, - &stubHeadStorage{h}, - testlog.Logger(t, log.LevelDebug)) - - // LastLogInBlock is expected to: - // 1. get a block iterator for block 10 (stubbed) - // 2. scan through the iterator and never find the target block - // return an error - index, err := db.LastLogInBlock(chainID, 10) - require.NoError(t, err) - require.Equal(t, entrydb.EntryIdx(10), index) -} - -func TestChainsDB_LastLogInBlockNotFound(t *testing.T) { - // using a chainID of 1 for simplicity - chainID := types.ChainIDFromUInt64(1) - // get default stubbed components - logDB, _, h := setupStubbedForUpdateHeads(chainID) - logDB.nextLogs = []nextLogResponse{ - {100, 5, backendTypes.TruncatedHash{}, nil}, - {100, 6, backendTypes.TruncatedHash{}, nil}, - {100, 7, backendTypes.TruncatedHash{}, nil}, - {101, 8, backendTypes.TruncatedHash{}, nil}, - {101, 9, backendTypes.TruncatedHash{}, nil}, - {101, 10, backendTypes.TruncatedHash{}, nil}, - } - - // The ChainsDB is real, but uses only stubbed components - db := NewChainsDB( - map[types.ChainID]LogStorage{ - chainID: logDB}, - &stubHeadStorage{h}, - testlog.Logger(t, log.LevelDebug)) - - // LastLogInBlock is expected to: - // 1. get a block iterator for block 10 (stubbed) - // 2. scan through the iterator and never find the target block - // return an error - _, err := db.LastLogInBlock(chainID, 10) - require.ErrorContains(t, err, "block 10 not found") -} - -func TestChainsDB_LastLogInBlockError(t *testing.T) { - // using a chainID of 1 for simplicity - chainID := types.ChainIDFromUInt64(1) - // get default stubbed components - logDB, _, h := setupStubbedForUpdateHeads(chainID) - logDB.nextLogs = []nextLogResponse{ - {10, 1, backendTypes.TruncatedHash{}, nil}, - {10, 2, backendTypes.TruncatedHash{}, nil}, - {10, 3, backendTypes.TruncatedHash{}, nil}, - {0, 0, backendTypes.TruncatedHash{}, fmt.Errorf("some error")}, - {11, 5, backendTypes.TruncatedHash{}, nil}, - } - - // The ChainsDB is real, but uses only stubbed components - db := NewChainsDB( - map[types.ChainID]LogStorage{ - chainID: logDB}, - &stubHeadStorage{h}, - testlog.Logger(t, log.LevelDebug)) - - // LastLogInBlock is expected to: - // 1. get a block iterator for block 10 (stubbed) - // 2. scan through the iterator and encounter an error - // return an error - _, err := db.LastLogInBlock(chainID, 10) - require.ErrorContains(t, err, "some error") -} - func TestChainsDB_UpdateCrossHeads(t *testing.T) { // using a chainID of 1 for simplicity chainID := types.ChainIDFromUInt64(1) // get default stubbed components logDB, checker, h := setupStubbedForUpdateHeads(chainID) + checker.numSafe = 1 + xSafe := checker.crossHeadForChain + // The ChainsDB is real, but uses only stubbed components db := NewChainsDB( map[types.ChainID]LogStorage{ @@ -185,14 +79,10 @@ func TestChainsDB_UpdateCrossHeads(t *testing.T) { &stubHeadStorage{h}, testlog.Logger(t, log.LevelDebug)) - // Update cross-heads is expected to: - // 1. get a last checkpoint iterator from the logDB (stubbed to be at 15) - // 2. progress the iterator to the next log (16) because the first safety check will pass - // 3. fail the second safety check - // 4. update the cross-heads to the last successful safety check (16) err := db.UpdateCrossHeads(checker) require.NoError(t, err) - require.Equal(t, entrydb.EntryIdx(16), checker.updated) + // found a safe executing message, and no new initiating messages + require.Equal(t, xSafe+1, checker.updated) } func TestChainsDB_UpdateCrossHeadsBeyondLocal(t *testing.T) { @@ -200,9 +90,11 @@ func TestChainsDB_UpdateCrossHeadsBeyondLocal(t *testing.T) { chainID := types.ChainIDFromUInt64(1) // get default stubbed components logDB, checker, h := setupStubbedForUpdateHeads(chainID) - // set the safety checker to pass 99 times, effeciively allowing all messages to be safe + // set the safety checker to pass 99 times, effectively allowing all messages to be safe checker.numSafe = 99 + startLocalSafe := checker.localHeadForChain + // The ChainsDB is real, but uses only stubbed components db := NewChainsDB( map[types.ChainID]LogStorage{ @@ -216,7 +108,7 @@ func TestChainsDB_UpdateCrossHeadsBeyondLocal(t *testing.T) { // 3. exceed the local head, and update the cross-head to the local head (40) err := db.UpdateCrossHeads(checker) require.NoError(t, err) - require.Equal(t, entrydb.EntryIdx(40), checker.updated) + require.Equal(t, startLocalSafe, checker.updated) } func TestChainsDB_UpdateCrossHeadsEOF(t *testing.T) { @@ -225,9 +117,10 @@ func TestChainsDB_UpdateCrossHeadsEOF(t *testing.T) { // get default stubbed components logDB, checker, h := setupStubbedForUpdateHeads(chainID) // set the log DB to return an EOF error when trying to get the next executing message - // after processing 10 messages as safe (with more messages available to be safe) - logDB.errOverload = io.EOF - logDB.errAfter = 10 + // after processing 10 message (with more messages available to be safe) + logDB.nextLogs = logDB.nextLogs[:checker.crossHeadForChain+11] + // This is a legacy test, the local head is further than the DB content... + checker.numSafe = 99 // The ChainsDB is real, but uses only stubbed components @@ -238,12 +131,11 @@ func TestChainsDB_UpdateCrossHeadsEOF(t *testing.T) { testlog.Logger(t, log.LevelDebug)) // Update cross-heads is expected to: - // 1. get a last checkpoint iterator from the logDB (stubbed to be at 15) - // 2. after processing 10 messages as safe, fail to find any executing messages (EOF) - // 3. update to the last successful safety check (25) without returning an error + // - process 10 logs as safe, 5 of which execute something + // - update cross-safe to what was there err := db.UpdateCrossHeads(checker) require.NoError(t, err) - require.Equal(t, entrydb.EntryIdx(25), checker.updated) + require.Equal(t, checker.crossHeadForChain+11, checker.updated) } func TestChainsDB_UpdateCrossHeadsError(t *testing.T) { @@ -253,8 +145,18 @@ func TestChainsDB_UpdateCrossHeadsError(t *testing.T) { logDB, checker, h := setupStubbedForUpdateHeads(chainID) // set the log DB to return an error when trying to get the next executing message // after processing 3 messages as safe (with more messages available to be safe) - logDB.errOverload = fmt.Errorf("some error") - logDB.errAfter = 3 + + executed := 0 + for i, e := range logDB.nextLogs { + if executed == 3 { + logDB.nextLogs[i].err = errors.New("some error") + } + if entrydb.EntryIdx(i) > checker.crossHeadForChain && e.execIdx >= 0 { + executed++ + } + } + + // everything is safe until error checker.numSafe = 99 // The ChainsDB is real, but uses only stubbed components @@ -280,8 +182,6 @@ func TestChainsDB_UpdateCrossHeadsError(t *testing.T) { // this isn't an issue for now, as all tests can modify the stubbed components directly after calling this function. // but readability and maintainability would be improved by making this function more configurable. func setupStubbedForUpdateHeads(chainID types.ChainID) (*stubLogDB, *stubChecker, *heads.Heads) { - // the checkpoint starts somewhere behind the last known cross-safe head - checkpoint := entrydb.EntryIdx(15) // the last known cross-safe head is at 20 cross := entrydb.EntryIdx(20) // the local head (the limit of the update) is at 40 @@ -290,15 +190,10 @@ func setupStubbedForUpdateHeads(chainID types.ChainID) (*stubLogDB, *stubChecker numExecutingMessages := 30 // number of safety checks that will pass before returning false numSafe := 1 - // number of calls to nextExecutingMessage before potentially returning an error - errAfter := 4 // set up stubbed logDB logDB := &stubLogDB{} - // the log DB will start the iterator at the checkpoint index - logDB.lastCheckpointBehind = &stubIterator{checkpoint, 0, nil} - // rig the log DB to return an error after a certain number of calls to NextExecutingMessage - logDB.errAfter = errAfter + // set up stubbed executing messages that the ChainsDB can pass to the checker logDB.executingMessages = []*backendTypes.ExecutingMessage{} for i := 0; i < numExecutingMessages; i++ { @@ -310,6 +205,31 @@ func setupStubbedForUpdateHeads(chainID types.ChainID) (*stubLogDB, *stubChecker }) } + rng := rand.New(rand.NewSource(123)) + blockNum := uint64(100) + logIndex := uint32(0) + executedCount := 0 + for i := entrydb.EntryIdx(0); i <= local; i++ { + var logHash backendTypes.TruncatedHash + rng.Read(logHash[:]) + + execIndex := -1 + // All the even messages have an executing message + if i%2 == 0 { + execIndex = rng.Intn(len(logDB.executingMessages)) + executedCount += 1 + } + var msgErr error + + logDB.nextLogs = append(logDB.nextLogs, nextLogResponse{ + blockNum: blockNum, + logIdx: logIndex, + evtHash: logHash, + err: msgErr, + execIdx: execIndex, + }) + } + // set up stubbed checker checker := &stubChecker{ localHeadForChain: local, @@ -382,89 +302,138 @@ func (s *stubHeadStorage) Current() *heads.Heads { type nextLogResponse struct { blockNum uint64 - logIdx uint32 - evtHash backendTypes.TruncatedHash - err error + + logIdx uint32 + + evtHash backendTypes.TruncatedHash + + err error + + // -1 if not executing + execIdx int } + type stubIterator struct { - index entrydb.EntryIdx - nextLogIndex int - nextLogs []nextLogResponse + index entrydb.EntryIdx + + db *stubLogDB } -func (s *stubIterator) NextLog() (uint64, uint32, backendTypes.TruncatedHash, error) { - if s.nextLogIndex >= len(s.nextLogs) { - return 0, 0, backendTypes.TruncatedHash{}, io.EOF - } - r := s.nextLogs[s.nextLogIndex] - s.nextLogIndex++ - return r.blockNum, r.logIdx, r.evtHash, r.err +func (s *stubIterator) End() error { + return nil // only used for DB-loading. The stub is already loaded } -func (s *stubIterator) Index() entrydb.EntryIdx { - return s.index +func (s *stubIterator) NextInitMsg() error { + s.index += 1 + if s.index >= entrydb.EntryIdx(len(s.db.nextLogs)) { + return io.EOF + } + e := s.db.nextLogs[s.index] + return e.err +} + +func (s *stubIterator) NextExecMsg() error { + for { + s.index += 1 + if s.index >= entrydb.EntryIdx(len(s.db.nextLogs)) { + return io.EOF + } + e := s.db.nextLogs[s.index] + if e.err != nil { + return e.err + } + if e.execIdx >= 0 { + return nil + } + } } -func (s *stubIterator) ExecMessage() (backendTypes.ExecutingMessage, error) { - panic("not implemented") + +func (s *stubIterator) NextBlock() error { + panic("not yet supported") } -type stubLogDB struct { - addLogCalls int - headBlockNum uint64 - emIndex int - executingMessages []*backendTypes.ExecutingMessage - nextLogs []nextLogResponse - lastCheckpointBehind *stubIterator - errOverload error - errAfter int - containsResponse containsResponse +func (s *stubIterator) NextIndex() entrydb.EntryIdx { + return s.index + 1 } -// stubbed LastCheckpointBehind returns a stubbed iterator which was passed in to the struct -func (s *stubLogDB) LastCheckpointBehind(entrydb.EntryIdx) (logs.Iterator, error) { - return s.lastCheckpointBehind, nil +func (s *stubIterator) SealedBlock() (hash backendTypes.TruncatedHash, num uint64, ok bool) { + panic("not yet supported") } -func (s *stubLogDB) ClosestBlockIterator(blockNum uint64) (logs.Iterator, error) { - return &stubIterator{ - index: entrydb.EntryIdx(99), - nextLogs: s.nextLogs, - }, nil +func (s *stubIterator) InitMessage() (hash backendTypes.TruncatedHash, logIndex uint32, ok bool) { + if s.index < 0 { + return backendTypes.TruncatedHash{}, 0, false + } + if s.index >= entrydb.EntryIdx(len(s.db.nextLogs)) { + return backendTypes.TruncatedHash{}, 0, false + } + e := s.db.nextLogs[s.index] + return e.evtHash, e.logIdx, true } -func (s *stubLogDB) NextExecutingMessage(i logs.Iterator) (backendTypes.ExecutingMessage, error) { - // if error overload is set, return it to simulate a failure condition - if s.errOverload != nil && s.emIndex >= s.errAfter { - return backendTypes.ExecutingMessage{}, s.errOverload +func (s *stubIterator) ExecMessage() *backendTypes.ExecutingMessage { + if s.index < 0 { + return nil } - // increment the iterator to mark advancement - i.(*stubIterator).index += 1 - // return the next executing message - m := *s.executingMessages[s.emIndex] - // and increment to the next message for the next call - s.emIndex++ - return m, nil + if s.index >= entrydb.EntryIdx(len(s.db.nextLogs)) { + return nil + } + e := s.db.nextLogs[s.index] + if e.execIdx < 0 { + return nil + } + return s.db.executingMessages[e.execIdx] } -func (s *stubLogDB) ClosestBlockInfo(_ uint64) (uint64, backendTypes.TruncatedHash, error) { - panic("not implemented") +var _ logs.Iterator = (*stubIterator)(nil) + +type stubLogDB struct { + addLogCalls int + sealBlockCalls int + headBlockNum uint64 + + executingMessages []*backendTypes.ExecutingMessage + nextLogs []nextLogResponse + + containsResponse containsResponse } -func (s *stubLogDB) AddLog(logHash backendTypes.TruncatedHash, block eth.BlockID, timestamp uint64, logIdx uint32, execMsg *backendTypes.ExecutingMessage) error { +func (s *stubLogDB) AddLog(logHash backendTypes.TruncatedHash, parentBlock eth.BlockID, logIdx uint32, execMsg *backendTypes.ExecutingMessage) error { s.addLogCalls++ return nil } +func (s *stubLogDB) SealBlock(parentHash common.Hash, block eth.BlockID, timestamp uint64) error { + s.sealBlockCalls++ + return nil +} + +func (s *stubLogDB) LatestSealedBlockNum() (n uint64, ok bool) { + return s.headBlockNum, true +} + +func (s *stubLogDB) FindSealedBlock(block eth.BlockID) (nextEntry entrydb.EntryIdx, err error) { + panic("not implemented") +} + +func (s *stubLogDB) IteratorStartingAt(i entrydb.EntryIdx) (logs.Iterator, error) { + return &stubIterator{ + index: i - 1, + db: s, + }, nil +} + +var _ LogStorage = (*stubLogDB)(nil) + type containsResponse struct { - contains bool - index entrydb.EntryIdx - err error + index entrydb.EntryIdx + err error } // stubbed Contains records the arguments passed to it // it returns the response set in the struct, or an empty response -func (s *stubLogDB) Contains(blockNum uint64, logIdx uint32, loghash backendTypes.TruncatedHash) (bool, entrydb.EntryIdx, error) { - return s.containsResponse.contains, s.containsResponse.index, s.containsResponse.err +func (s *stubLogDB) Contains(blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) (nextIndex entrydb.EntryIdx, err error) { + return s.containsResponse.index, s.containsResponse.err } func (s *stubLogDB) Rewind(newHeadBlockNum uint64) error { diff --git a/op-supervisor/supervisor/backend/db/entrydb/entry_db.go b/op-supervisor/supervisor/backend/db/entrydb/entry_db.go index fb02c5be8151..446051821ce3 100644 --- a/op-supervisor/supervisor/backend/db/entrydb/entry_db.go +++ b/op-supervisor/supervisor/backend/db/entrydb/entry_db.go @@ -17,6 +17,65 @@ type EntryIdx int64 type Entry [EntrySize]byte +func (entry Entry) Type() EntryType { + return EntryType(entry[0]) +} + +type EntryTypeFlag uint8 + +const ( + FlagSearchCheckpoint EntryTypeFlag = 1 << TypeSearchCheckpoint + FlagCanonicalHash EntryTypeFlag = 1 << TypeCanonicalHash + FlagInitiatingEvent EntryTypeFlag = 1 << TypeInitiatingEvent + FlagExecutingLink EntryTypeFlag = 1 << TypeExecutingLink + FlagExecutingCheck EntryTypeFlag = 1 << TypeExecutingCheck + FlagPadding EntryTypeFlag = 1 << TypePadding + // for additional padding + FlagPadding2 EntryTypeFlag = FlagPadding << 1 +) + +func (ex EntryTypeFlag) Any(v EntryTypeFlag) bool { + return ex&v != 0 +} + +func (ex *EntryTypeFlag) Add(v EntryTypeFlag) { + *ex = *ex | v +} + +func (ex *EntryTypeFlag) Remove(v EntryTypeFlag) { + *ex = *ex &^ v +} + +type EntryType uint8 + +const ( + TypeSearchCheckpoint EntryType = iota + TypeCanonicalHash + TypeInitiatingEvent + TypeExecutingLink + TypeExecutingCheck + TypePadding +) + +func (d EntryType) String() string { + switch d { + case TypeSearchCheckpoint: + return "searchCheckpoint" + case TypeCanonicalHash: + return "canonicalHash" + case TypeInitiatingEvent: + return "initiatingEvent" + case TypeExecutingLink: + return "executingLink" + case TypeExecutingCheck: + return "executingCheck" + case TypePadding: + return "padding" + default: + return fmt.Sprintf("unknown-%d", uint8(d)) + } +} + // dataAccess defines a minimal API required to manipulate the actual stored data. // It is a subset of the os.File API but could (theoretically) be satisfied by an in-memory implementation for testing. type dataAccess interface { diff --git a/op-supervisor/supervisor/backend/db/init.go b/op-supervisor/supervisor/backend/db/init.go deleted file mode 100644 index fe6b51e5c21f..000000000000 --- a/op-supervisor/supervisor/backend/db/init.go +++ /dev/null @@ -1,34 +0,0 @@ -package db - -import ( - "errors" - "fmt" - "io" - "math" -) - -// Resume prepares the given LogStore to resume recording events. -// It returns the block number of the last block that is guaranteed to have been fully recorded to the database -// and rewinds the database to ensure it can resume recording from the first log of the next block. -func Resume(logDB LogStorage) error { - // Get the last checkpoint that was written then Rewind the db - // to the block prior to that block and start from there. - // Guarantees we will always roll back at least one block - // so we know we're always starting from a fully written block. - checkPointBlock, _, err := logDB.ClosestBlockInfo(math.MaxUint64) - if errors.Is(err, io.EOF) { - // No blocks recorded in the database, start from genesis - return nil - } else if err != nil { - return fmt.Errorf("failed to get block from checkpoint: %w", err) - } - if checkPointBlock == 0 { - return nil - } - block := checkPointBlock - 1 - err = logDB.Rewind(block) - if err != nil { - return fmt.Errorf("failed to rewind the database: %w", err) - } - return nil -} diff --git a/op-supervisor/supervisor/backend/db/init_test.go b/op-supervisor/supervisor/backend/db/init_test.go deleted file mode 100644 index 5ff44c524e5b..000000000000 --- a/op-supervisor/supervisor/backend/db/init_test.go +++ /dev/null @@ -1,91 +0,0 @@ -package db - -import ( - "fmt" - "io" - "testing" - - "github.com/ethereum-optimism/optimism/op-service/eth" - "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" - "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs" - "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" - "github.com/stretchr/testify/require" -) - -func TestRecover(t *testing.T) { - tests := []struct { - name string - stubDB *stubLogStore - expectRewoundTo uint64 - }{ - { - name: "emptydb", - stubDB: &stubLogStore{closestBlockErr: fmt.Errorf("no entries: %w", io.EOF)}, - expectRewoundTo: 0, - }, - { - name: "genesis", - stubDB: &stubLogStore{}, - expectRewoundTo: 0, - }, - { - name: "with_blocks", - stubDB: &stubLogStore{closestBlockNumber: 15}, - expectRewoundTo: 14, - }, - } - for _, test := range tests { - test := test - t.Run(test.name, func(t *testing.T) { - err := Resume(test.stubDB) - require.NoError(t, err) - require.Equal(t, test.expectRewoundTo, test.stubDB.rewoundTo) - }) - } -} - -type stubLogStore struct { - closestBlockNumber uint64 - closestBlockErr error - rewoundTo uint64 -} - -func (s *stubLogStore) Contains(blockNum uint64, logIdx uint32, loghash types.TruncatedHash) (bool, entrydb.EntryIdx, error) { - panic("not supported") -} - -func (s *stubLogStore) ClosestBlockIterator(blockNum uint64) (logs.Iterator, error) { - panic("not supported") -} - -func (s *stubLogStore) LastCheckpointBehind(entrydb.EntryIdx) (logs.Iterator, error) { - panic("not supported") -} - -func (s *stubLogStore) ClosestBlockInfo(blockNum uint64) (uint64, types.TruncatedHash, error) { - if s.closestBlockErr != nil { - return 0, types.TruncatedHash{}, s.closestBlockErr - } - return s.closestBlockNumber, types.TruncatedHash{}, nil -} - -func (s *stubLogStore) NextExecutingMessage(logs.Iterator) (types.ExecutingMessage, error) { - panic("not supported") -} - -func (s *stubLogStore) Rewind(headBlockNum uint64) error { - s.rewoundTo = headBlockNum - return nil -} - -func (s *stubLogStore) AddLog(logHash types.TruncatedHash, block eth.BlockID, timestamp uint64, logIdx uint32, execMsg *types.ExecutingMessage) error { - panic("not supported") -} - -func (s *stubLogStore) LatestBlockNum() uint64 { - panic("not supported") -} - -func (s *stubLogStore) Close() error { - return nil -} diff --git a/op-supervisor/supervisor/backend/db/logs/db.go b/op-supervisor/supervisor/backend/db/logs/db.go index 0f757f5254cd..1a2d8c8adfea 100644 --- a/op-supervisor/supervisor/backend/db/logs/db.go +++ b/op-supervisor/supervisor/backend/db/logs/db.go @@ -4,34 +4,35 @@ import ( "errors" "fmt" "io" - "math" "sync" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" - "github.com/ethereum/go-ethereum/log" -) - -const ( - searchCheckpointFrequency = 256 - - eventFlagIncrementLogIdx = byte(1) - eventFlagHasExecutingMessage = byte(1) << 1 ) const ( - typeSearchCheckpoint byte = iota - typeCanonicalHash - typeInitiatingEvent - typeExecutingLink - typeExecutingCheck + searchCheckpointFrequency = 256 + eventFlagHasExecutingMessage = byte(1) ) var ( - ErrLogOutOfOrder = errors.New("log out of order") + // ErrLogOutOfOrder happens when you try to add a log to the DB, + // but it does not actually fit onto the latest data (by being too old or new). + ErrLogOutOfOrder = errors.New("log out of order") + // ErrDataCorruption happens when the underlying DB has some I/O issue ErrDataCorruption = errors.New("data corruption") - ErrNotFound = errors.New("not found") + // ErrSkipped happens when we try to retrieve data that is not available (pruned) + // It may also happen if we erroneously skip data, that was not considered a conflict, if the DB is corrupted. + ErrSkipped = errors.New("skipped data") + // ErrFuture happens when data is just not yet available + ErrFuture = errors.New("future data") + // ErrConflict happens when we know for sure that there is different canonical data + ErrConflict = errors.New("conflicting data") ) type Metrics interface { @@ -39,11 +40,6 @@ type Metrics interface { RecordDBSearchEntriesRead(count int64) } -type logContext struct { - blockNum uint64 - logIdx uint32 -} - type EntryStore interface { Size() int64 LastEntryIdx() entrydb.EntryIdx @@ -60,28 +56,6 @@ type EntryStore interface { // Use a fixed 24 bytes per entry. // // Data is an append-only log, that can be binary searched for any necessary event data. -// -// Rules: -// if entry_index % 256 == 0: must be type 0. For easy binary search. -// type 1 always adjacent to type 0 -// type 2 "diff" values are offsets from type 0 values (always within 256 entries range) -// type 3 always after type 2 -// type 4 always after type 3 -// -// Types (<type> = 1 byte): -// type 0: "search checkpoint" <type><uint64 block number: 8 bytes><uint32 event index offset: 4 bytes><uint64 timestamp: 8 bytes> = 20 bytes -// type 1: "canonical hash" <type><parent blockhash truncated: 20 bytes> = 21 bytes -// type 2: "initiating event" <type><blocknum diff: 1 byte><event flags: 1 byte><event-hash: 20 bytes> = 23 bytes -// type 3: "executing link" <type><chain: 4 bytes><blocknum: 8 bytes><event index: 3 bytes><uint64 timestamp: 8 bytes> = 24 bytes -// type 4: "executing check" <type><event-hash: 20 bytes> = 21 bytes -// other types: future compat. E.g. for linking to L1, registering block-headers as a kind of initiating-event, tracking safe-head progression, etc. -// -// Right-pad each entry that is not 24 bytes. -// -// event-flags: each bit represents a boolean value, currently only two are defined -// * event-flags & 0x01 - true if the log index should increment. Should only be false when the event is immediately after a search checkpoint and canonical hash -// * event-flags & 0x02 - true if the initiating event has an executing link that should follow. Allows detecting when the executing link failed to write. -// event-hash: H(origin, timestamp, payloadhash); enough to check identifier matches & payload matches. type DB struct { log log.Logger m Metrics @@ -91,21 +65,21 @@ type DB struct { lastEntryContext logContext } -func NewFromFile(logger log.Logger, m Metrics, path string) (*DB, error) { +func NewFromFile(logger log.Logger, m Metrics, path string, trimToLastSealed bool) (*DB, error) { store, err := entrydb.NewEntryDB(logger, path) if err != nil { return nil, fmt.Errorf("failed to open DB: %w", err) } - return NewFromEntryStore(logger, m, store) + return NewFromEntryStore(logger, m, store, trimToLastSealed) } -func NewFromEntryStore(logger log.Logger, m Metrics, store EntryStore) (*DB, error) { +func NewFromEntryStore(logger log.Logger, m Metrics, store EntryStore, trimToLastSealed bool) (*DB, error) { db := &DB{ log: logger, m: m, store: store, } - if err := db.init(); err != nil { + if err := db.init(trimToLastSealed); err != nil { return nil, fmt.Errorf("failed to init database: %w", err) } return db, nil @@ -115,59 +89,57 @@ func (db *DB) lastEntryIdx() entrydb.EntryIdx { return db.store.LastEntryIdx() } -func (db *DB) init() error { +func (db *DB) init(trimToLastSealed bool) error { defer db.updateEntryCountMetric() // Always update the entry count metric after init completes - if err := db.trimInvalidTrailingEntries(); err != nil { - return fmt.Errorf("failed to trim invalid trailing entries: %w", err) + if trimToLastSealed { + if err := db.trimToLastSealed(); err != nil { + return fmt.Errorf("failed to trim invalid trailing entries: %w", err) + } } if db.lastEntryIdx() < 0 { - // Database is empty so no context to load + // Database is empty. + // Make a state that is ready to apply the genesis block on top of as first entry. + // This will infer into a checkpoint (half of the block seal here) + // and is then followed up with canonical-hash entry of genesis. + db.lastEntryContext = logContext{ + nextEntryIndex: 0, + blockHash: types.TruncatedHash{}, + blockNum: 0, + timestamp: 0, + logsSince: 0, + logHash: types.TruncatedHash{}, + execMsg: nil, + out: nil, + } return nil } - + // start at the last checkpoint, + // and then apply any remaining changes on top, to hydrate the state. lastCheckpoint := (db.lastEntryIdx() / searchCheckpointFrequency) * searchCheckpointFrequency - i, err := db.newIterator(lastCheckpoint) - if err != nil { - return fmt.Errorf("failed to create iterator at last search checkpoint: %w", err) - } - // Read all entries until the end of the file - for { - _, _, _, err := i.NextLog() - if errors.Is(err, io.EOF) { - break - } else if err != nil { - return fmt.Errorf("failed to init from existing entries: %w", err) - } + i := db.newIterator(lastCheckpoint) + i.current.need.Add(entrydb.FlagCanonicalHash) + if err := i.End(); err != nil { + return fmt.Errorf("failed to init from remaining trailing data: %w", err) } db.lastEntryContext = i.current return nil } -func (db *DB) trimInvalidTrailingEntries() error { +func (db *DB) trimToLastSealed() error { i := db.lastEntryIdx() for ; i >= 0; i-- { entry, err := db.store.Read(i) if err != nil { return fmt.Errorf("failed to read %v to check for trailing entries: %w", i, err) } - if entry[0] == typeExecutingCheck { - // executing check is a valid final entry + if entry.Type() == entrydb.TypeCanonicalHash { + // only an executing hash, indicating a sealed block, is a valid point for restart break } - if entry[0] == typeInitiatingEvent { - evt, err := newInitiatingEventFromEntry(entry) - if err != nil { - // Entry is invalid, keep walking backwards - continue - } - if !evt.hasExecMsg { - // init event with no exec msg is a valid final entry - break - } - } } if i < db.lastEntryIdx() { db.log.Warn("Truncating unexpected trailing entries", "prev", db.lastEntryIdx(), "new", i) + // trim such that the last entry is the canonical-hash we identified return db.store.Truncate(i) } return nil @@ -177,383 +149,350 @@ func (db *DB) updateEntryCountMetric() { db.m.RecordDBEntryCount(db.store.Size()) } -func (db *DB) LatestBlockNum() uint64 { - return db.lastEntryContext.blockNum +func (db *DB) IteratorStartingAt(i entrydb.EntryIdx) (Iterator, error) { + db.rwLock.RLock() + defer db.rwLock.RUnlock() + if i > db.lastEntryContext.nextEntryIndex { + return nil, ErrFuture + } + // TODO(#12031): Workaround while we not have IteratorStartingAt(heads.HeadPointer): + // scroll back from the index, to find block info. + idx := i + for ; idx >= 0; i-- { + entry, err := db.store.Read(idx) + if err != nil { + if errors.Is(err, io.EOF) { + continue // traverse to when we did have blocks + } + return nil, err + } + if entry.Type() == entrydb.TypeSearchCheckpoint { + break + } + if idx == 0 { + return nil, fmt.Errorf("empty DB, no block entry, cannot start at %d", i) + } + } + iter := db.newIterator(idx) + for iter.NextIndex() < i { + if _, err := iter.next(); err != nil { + return nil, errors.New("failed to process back up to the head pointer") + } + } + return iter, nil } -// ClosestBlockInfo returns the block number and hash of the highest recorded block at or before blockNum. -// Since block data is only recorded in search checkpoints, this may return an earlier block even if log data is -// recorded for the requested block. -func (db *DB) ClosestBlockInfo(blockNum uint64) (uint64, types.TruncatedHash, error) { +// FindSealedBlock finds the requested block, to check if it exists, +// returning the next index after it where things continue from. +// returns ErrFuture if the block is too new to be able to tell +// returns ErrDifferent if the known block does not match +func (db *DB) FindSealedBlock(block eth.BlockID) (nextEntry entrydb.EntryIdx, err error) { db.rwLock.RLock() defer db.rwLock.RUnlock() - checkpointIdx, err := db.searchCheckpoint(blockNum, math.MaxUint32) - if err != nil { - return 0, types.TruncatedHash{}, fmt.Errorf("no checkpoint at or before block %v found: %w", blockNum, err) + iter, err := db.newIteratorAt(block.Number, 0) + if errors.Is(err, ErrFuture) { + return 0, fmt.Errorf("block %d is not known yet: %w", block.Number, ErrFuture) + } else if err != nil { + return 0, fmt.Errorf("failed to find sealed block %d: %w", block.Number, err) } - checkpoint, err := db.readSearchCheckpoint(checkpointIdx) - if err != nil { - return 0, types.TruncatedHash{}, fmt.Errorf("failed to reach checkpoint: %w", err) + h, _, ok := iter.SealedBlock() + if !ok { + panic("expected block") } - entry, err := db.readCanonicalHash(checkpointIdx + 1) - if err != nil { - return 0, types.TruncatedHash{}, fmt.Errorf("failed to read canonical hash: %w", err) + if types.TruncateHash(block.Hash) != h { + return 0, fmt.Errorf("queried %s but got %s at number %d: %w", block.Hash, h, block.Number, ErrConflict) } - return checkpoint.blockNum, entry.hash, nil + return iter.NextIndex(), nil } -// ClosestBlockIterator returns an iterator for the block closest to the specified blockNum. -// The iterator will start at the search checkpoint for the block, or the first checkpoint before it. -func (db *DB) ClosestBlockIterator(blockNum uint64) (Iterator, error) { +// LatestSealedBlockNum returns the block number of the block that was last sealed, +// or ok=false if there is no sealed block (i.e. empty DB) +func (db *DB) LatestSealedBlockNum() (n uint64, ok bool) { db.rwLock.RLock() defer db.rwLock.RUnlock() - checkpointIdx, err := db.searchCheckpoint(blockNum, math.MaxUint32) - if err != nil { - return nil, fmt.Errorf("no checkpoint at or before block %v found: %w", blockNum, err) + if !db.lastEntryContext.hasCompleteBlock() { + if db.lastEntryContext.blockNum == 0 { + db.log.Debug("No DB contents yet") + } else { + db.log.Debug("New block is already in progress", "num", db.lastEntryContext.blockNum) + } } - return db.newIterator(checkpointIdx) + return db.lastEntryContext.blockNum, true } -// Get returns the truncated hash of the log at the specified blockNum and logIdx, -// or an error if the log is not found. -func (db *DB) Get(blockNum uint64, logiIdx uint32) (types.TruncatedHash, error) { +// Get returns the truncated hash of the log at the specified blockNum (of the sealed block) +// and logIdx (of the log after the block), or an error if the log is not found. +func (db *DB) Get(blockNum uint64, logIdx uint32) (types.TruncatedHash, error) { db.rwLock.RLock() defer db.rwLock.RUnlock() - hash, _, err := db.findLogInfo(blockNum, logiIdx) + hash, _, err := db.findLogInfo(blockNum, logIdx) return hash, err } -// Contains return true iff the specified logHash is recorded in the specified blockNum and logIdx. -// If the log is found, the entry index of the log is returned, too. +// Contains returns no error iff the specified logHash is recorded in the specified blockNum and logIdx. +// If the log is out of reach, then ErrFuture is returned. +// If the log is determined to conflict with the canonical chain, then ErrConflict is returned. // logIdx is the index of the log in the array of all logs in the block. // This can be used to check the validity of cross-chain interop events. -func (db *DB) Contains(blockNum uint64, logIdx uint32, logHash types.TruncatedHash) (bool, entrydb.EntryIdx, error) { +func (db *DB) Contains(blockNum uint64, logIdx uint32, logHash types.TruncatedHash) (entrydb.EntryIdx, error) { db.rwLock.RLock() defer db.rwLock.RUnlock() db.log.Trace("Checking for log", "blockNum", blockNum, "logIdx", logIdx, "hash", logHash) evtHash, iter, err := db.findLogInfo(blockNum, logIdx) - if errors.Is(err, ErrNotFound) { - // Did not find a log at blockNum and logIdx - return false, 0, nil - } else if err != nil { - return false, 0, err + if err != nil { + return 0, err // may be ErrConflict if the block does not have as many logs } db.log.Trace("Found initiatingEvent", "blockNum", blockNum, "logIdx", logIdx, "hash", evtHash) // Found the requested block and log index, check if the hash matches - if evtHash == logHash { - return true, iter.Index(), nil + if evtHash != logHash { + return 0, fmt.Errorf("payload hash mismatch: expected %s, got %s", logHash, evtHash) } - return false, 0, nil + return iter.NextIndex(), nil } -// Executes checks if the log identified by the specific block number and log index, has an ExecutingMessage associated -// with it that needs to be checked as part of interop validation. -// logIdx is the index of the log in the array of all logs in the block. -// Returns the ExecutingMessage if it exists, or ExecutingMessage{} if the log is found but has no ExecutingMessage. -// Returns ErrNotFound if the specified log does not exist in the database. -func (db *DB) Executes(blockNum uint64, logIdx uint32) (types.ExecutingMessage, error) { - db.rwLock.RLock() - defer db.rwLock.RUnlock() - _, iter, err := db.findLogInfo(blockNum, logIdx) - if err != nil { - return types.ExecutingMessage{}, err +func (db *DB) findLogInfo(blockNum uint64, logIdx uint32) (types.TruncatedHash, Iterator, error) { + if blockNum == 0 { + return types.TruncatedHash{}, nil, ErrConflict // no logs in block 0 + } + // blockNum-1, such that we find a log that came after the parent num-1 was sealed. + // logIdx, such that all entries before logIdx can be skipped, but logIdx itself is still readable. + iter, err := db.newIteratorAt(blockNum-1, logIdx) + if errors.Is(err, ErrFuture) { + db.log.Trace("Could not find log yet", "blockNum", blockNum, "logIdx", logIdx) + return types.TruncatedHash{}, nil, err + } else if err != nil { + db.log.Error("Failed searching for log", "blockNum", blockNum, "logIdx", logIdx) + return types.TruncatedHash{}, nil, err } - execMsg, err := iter.ExecMessage() - if err != nil { - return types.ExecutingMessage{}, fmt.Errorf("failed to read executing message: %w", err) + if err := iter.NextInitMsg(); err != nil { + return types.TruncatedHash{}, nil, fmt.Errorf("failed to read initiating message %d, on top of block %d: %w", logIdx, blockNum, err) + } + if _, x, ok := iter.SealedBlock(); !ok { + panic("expected block") + } else if x < blockNum-1 { + panic(fmt.Errorf("bug in newIteratorAt, expected to have found parent block %d but got %d", blockNum-1, x)) + } else if x > blockNum-1 { + return types.TruncatedHash{}, nil, fmt.Errorf("log does not exist, found next block already: %w", ErrConflict) } - return execMsg, nil + logHash, x, ok := iter.InitMessage() + if !ok { + panic("expected init message") + } else if x != logIdx { + panic(fmt.Errorf("bug in newIteratorAt, expected to have found log %d but got %d", logIdx, x)) + } + return logHash, iter, nil } -func (db *DB) findLogInfo(blockNum uint64, logIdx uint32) (types.TruncatedHash, Iterator, error) { - entryIdx, err := db.searchCheckpoint(blockNum, logIdx) +// newIteratorAt returns an iterator ready after the given sealed block number, +// and positioned such that the next log-read on the iterator return the log with logIndex, if any. +// It may return an ErrNotFound if the block number is unknown, +// or if there are just not that many seen log events after the block as requested. +func (db *DB) newIteratorAt(blockNum uint64, logIndex uint32) (*iterator, error) { + // find a checkpoint before or exactly when blockNum was sealed, + // and have processed up to but not including [logIndex] number of logs (i.e. all prior logs, if any). + searchCheckpointIndex, err := db.searchCheckpoint(blockNum, logIndex) if errors.Is(err, io.EOF) { // Did not find a checkpoint to start reading from so the log cannot be present. - return types.TruncatedHash{}, nil, ErrNotFound + return nil, ErrFuture } else if err != nil { - return types.TruncatedHash{}, nil, err + return nil, err } - - i, err := db.newIterator(entryIdx) + // The iterator did not consume the checkpoint yet, it's positioned right at it. + // So we can call NextBlock() and get the checkpoint itself as first entry. + iter := db.newIterator(searchCheckpointIndex) if err != nil { - return types.TruncatedHash{}, nil, fmt.Errorf("failed to create iterator: %w", err) + return nil, err } - db.log.Trace("Starting search", "entry", entryIdx, "blockNum", i.current.blockNum, "logIdx", i.current.logIdx) + iter.current.need.Add(entrydb.FlagCanonicalHash) defer func() { - db.m.RecordDBSearchEntriesRead(i.entriesRead) + db.m.RecordDBSearchEntriesRead(iter.entriesRead) }() + // First walk up to the block that we are sealed up to (incl.) for { - evtBlockNum, evtLogIdx, evtHash, err := i.NextLog() - if errors.Is(err, io.EOF) { - // Reached end of log without finding the event - return types.TruncatedHash{}, nil, ErrNotFound + if _, n, _ := iter.SealedBlock(); n == blockNum { // we may already have it exactly + break + } + if err := iter.NextBlock(); errors.Is(err, ErrFuture) { + db.log.Trace("ran out of data, could not find block", "nextIndex", iter.NextIndex(), "target", blockNum) + return nil, ErrFuture } else if err != nil { - return types.TruncatedHash{}, nil, fmt.Errorf("failed to read next log: %w", err) + db.log.Error("failed to read next block", "nextIndex", iter.NextIndex(), "target", blockNum, "err", err) + return nil, err } - if evtBlockNum == blockNum && evtLogIdx == logIdx { - db.log.Trace("Found initiatingEvent", "blockNum", evtBlockNum, "logIdx", evtLogIdx, "hash", evtHash) - return evtHash, i, nil + h, num, ok := iter.SealedBlock() + if !ok { + panic("expected sealed block") } - if evtBlockNum > blockNum || (evtBlockNum == blockNum && evtLogIdx > logIdx) { - // Progressed past the requested log without finding it. - return types.TruncatedHash{}, nil, ErrNotFound + db.log.Trace("found sealed block", "num", num, "hash", h) + if num < blockNum { + continue } - } -} - -func (db *DB) newIterator(startCheckpointEntry entrydb.EntryIdx) (*iterator, error) { - checkpoint, err := db.readSearchCheckpoint(startCheckpointEntry) - if err != nil { - return nil, fmt.Errorf("failed to read search checkpoint entry %v: %w", startCheckpointEntry, err) - } - startIdx := startCheckpointEntry + 2 - firstEntry, err := db.store.Read(startIdx) - if errors.Is(err, io.EOF) { - // There should always be an entry after a checkpoint and canonical hash so an EOF here is data corruption - return nil, fmt.Errorf("%w: no entry after checkpoint and canonical hash at %v", ErrDataCorruption, startCheckpointEntry) - } else if err != nil { - return nil, fmt.Errorf("failed to read first entry to iterate %v: %w", startCheckpointEntry+2, err) - } - startLogCtx := logContext{ - blockNum: checkpoint.blockNum, - logIdx: checkpoint.logIdx, - } - // Handle starting from a checkpoint after initiating-event but before its executing-link or executing-check - if firstEntry[0] == typeExecutingLink || firstEntry[0] == typeExecutingCheck { - if firstEntry[0] == typeExecutingLink { - // The start checkpoint was between the initiating event and the executing link - // Step back to read the initiating event. The checkpoint block data will be for the initiating event - startIdx = startCheckpointEntry - 1 - } else { - // The start checkpoint was between the executing link and the executing check - // Step back to read the initiating event. The checkpoint block data will be for the initiating event - startIdx = startCheckpointEntry - 2 + if num != blockNum { // block does not contain + return nil, fmt.Errorf("looking for %d, but already at %d: %w", blockNum, num, ErrConflict) } - initEntry, err := db.store.Read(startIdx) - if err != nil { - return nil, fmt.Errorf("failed to read prior initiating event: %w", err) + break + } + // Now walk up to the number of seen logs that we want to have processed. + // E.g. logIndex == 2, need to have processed index 0 and 1, + // so two logs before quiting (and not 3 to then quit after). + for iter.current.logsSince < logIndex { + if err := iter.NextInitMsg(); err == io.EOF { + return nil, ErrFuture + } else if err != nil { + return nil, err } - initEvt, err := newInitiatingEventFromEntry(initEntry) - if err != nil { - return nil, fmt.Errorf("invalid initiating event at idx %v: %w", startIdx, err) + _, num, ok := iter.SealedBlock() + if !ok { + panic("expected sealed block") } - startLogCtx = initEvt.preContext(startLogCtx) + if num > blockNum { + // we overshot, the block did not contain as many seen log events as requested + return nil, ErrConflict + } + _, idx, ok := iter.InitMessage() + if !ok { + panic("expected initializing message") + } + if idx+1 < logIndex { + continue + } + if idx+1 == logIndex { + break // the NextInitMsg call will position the iterator at the re + } + return nil, fmt.Errorf("unexpected log-skip at block %d log %d", blockNum, idx) } - i := &iterator{ + return iter, nil +} + +// newIterator creates an iterator at the given index. +// None of the iterator attributes will be ready for reads, +// but the entry at the given index will be first read when using the iterator. +func (db *DB) newIterator(index entrydb.EntryIdx) *iterator { + return &iterator{ db: db, - // +2 to skip the initial search checkpoint and the canonical hash event after it - nextEntryIdx: startIdx, - current: startLogCtx, + current: logContext{ + nextEntryIndex: index, + }, } - return i, nil } -// searchCheckpoint performs a binary search of the searchCheckpoint entries to find the closest one at or before -// the requested log. -// Returns the index of the searchCheckpoint to begin reading from or an error -func (db *DB) searchCheckpoint(blockNum uint64, logIdx uint32) (entrydb.EntryIdx, error) { +// searchCheckpoint performs a binary search of the searchCheckpoint entries +// to find the closest one with an equal or lower block number and equal or lower amount of seen logs. +// Returns the index of the searchCheckpoint to begin reading from or an error. +func (db *DB) searchCheckpoint(sealedBlockNum uint64, logsSince uint32) (entrydb.EntryIdx, error) { n := (db.lastEntryIdx() / searchCheckpointFrequency) + 1 - // Define x[-1] < target and x[n] >= target. - // Invariant: x[i-1] < target, x[j] >= target. + // Define: x is the array of known checkpoints + // Invariant: x[i] <= target, x[j] > target. i, j := entrydb.EntryIdx(0), n - for i < j { - h := entrydb.EntryIdx(uint64(i+j) >> 1) // avoid overflow when computing h + for i+1 < j { // i is inclusive, j is exclusive. + // Get the checkpoint exactly in-between, + // bias towards a higher value if an even number of checkpoints. + // E.g. i=3 and j=4 would not run, since i + 1 < j + // E.g. i=3 and j=5 leaves checkpoints 3, 4, and we pick 4 as pivot + // E.g. i=3 and j=6 leaves checkpoints 3, 4, 5, and we pick 4 as pivot + // + // The following holds: i ≤ h < j + h := entrydb.EntryIdx((uint64(i) + uint64(j)) >> 1) checkpoint, err := db.readSearchCheckpoint(h * searchCheckpointFrequency) if err != nil { return 0, fmt.Errorf("failed to read entry %v: %w", h, err) } - // i ≤ h < j - if checkpoint.blockNum < blockNum || (checkpoint.blockNum == blockNum && checkpoint.logIdx < logIdx) { - i = h + 1 // preserves x[i-1] < target + if checkpoint.blockNum < sealedBlockNum || + (checkpoint.blockNum == sealedBlockNum && checkpoint.logsSince < logsSince) { + i = h } else { - j = h // preserves x[j] >= target + j = h } } - if i < n { - checkpoint, err := db.readSearchCheckpoint(i * searchCheckpointFrequency) - if err != nil { - return 0, fmt.Errorf("failed to read entry %v: %w", i, err) - } - if checkpoint.blockNum == blockNum && checkpoint.logIdx == logIdx { - // Found entry at requested block number and log index - return i * searchCheckpointFrequency, nil - } + if i+1 != j { + panic("expected to have 1 checkpoint left") } - if i == 0 { - // There are no checkpoints before the requested blocks - return 0, io.EOF + result := i * searchCheckpointFrequency + checkpoint, err := db.readSearchCheckpoint(result) + if err != nil { + return 0, fmt.Errorf("failed to read final search checkpoint result: %w", err) } - // Not found, need to start reading from the entry prior - return (i - 1) * searchCheckpointFrequency, nil + if checkpoint.blockNum > sealedBlockNum || + (checkpoint.blockNum == sealedBlockNum && checkpoint.logsSince > logsSince) { + return 0, fmt.Errorf("missing data, earliest search checkpoint is %d with %d logs, cannot find something before or at %d with %d logs: %w", + checkpoint.blockNum, checkpoint.logsSince, sealedBlockNum, logsSince, ErrSkipped) + } + return result, nil } -func (db *DB) AddLog(logHash types.TruncatedHash, block eth.BlockID, timestamp uint64, logIdx uint32, execMsg *types.ExecutingMessage) error { - db.rwLock.Lock() - defer db.rwLock.Unlock() - postState := logContext{ - blockNum: block.Number, - logIdx: logIdx, - } - if block.Number == 0 { - return fmt.Errorf("%w: should not have logs in block 0", ErrLogOutOfOrder) - } - if db.lastEntryContext.blockNum > block.Number { - return fmt.Errorf("%w: adding block %v, head block: %v", ErrLogOutOfOrder, block.Number, db.lastEntryContext.blockNum) - } - if db.lastEntryContext.blockNum == block.Number && db.lastEntryContext.logIdx+1 != logIdx { - return fmt.Errorf("%w: adding log %v in block %v, but currently at log %v", ErrLogOutOfOrder, logIdx, block.Number, db.lastEntryContext.logIdx) - } - if db.lastEntryContext.blockNum < block.Number && logIdx != 0 { - return fmt.Errorf("%w: adding log %v as first log in block %v", ErrLogOutOfOrder, logIdx, block.Number) +// debug util to log the last 10 entries of the chain +func (db *DB) debugTip() { + for x := 0; x < 10; x++ { + index := db.lastEntryIdx() - entrydb.EntryIdx(x) + if index < 0 { + continue + } + e, err := db.store.Read(index) + if err == nil { + db.log.Debug("tip", "index", index, "type", e.Type()) + } } - var entriesToAdd []entrydb.Entry - newContext := db.lastEntryContext - lastEntryIdx := db.lastEntryIdx() +} - addEntry := func(entry entrydb.Entry) { - entriesToAdd = append(entriesToAdd, entry) - lastEntryIdx++ +func (db *DB) flush() error { + for i, e := range db.lastEntryContext.out { + db.log.Trace("appending entry", "type", e.Type(), "entry", hexutil.Bytes(e[:]), + "next", int(db.lastEntryContext.nextEntryIndex)-len(db.lastEntryContext.out)+i) } - maybeAddCheckpoint := func() { - if (lastEntryIdx+1)%searchCheckpointFrequency == 0 { - addEntry(newSearchCheckpoint(block.Number, logIdx, timestamp).encode()) - addEntry(newCanonicalHash(types.TruncateHash(block.Hash)).encode()) - newContext = postState - } + if err := db.store.Append(db.lastEntryContext.out...); err != nil { + return fmt.Errorf("failed to append entries: %w", err) } - maybeAddCheckpoint() + db.lastEntryContext.out = db.lastEntryContext.out[:0] + db.updateEntryCountMetric() + return nil +} - evt, err := newInitiatingEvent(newContext, postState.blockNum, postState.logIdx, logHash, execMsg != nil) - if err != nil { - return fmt.Errorf("failed to create initiating event: %w", err) +func (db *DB) SealBlock(parentHash common.Hash, block eth.BlockID, timestamp uint64) error { + db.rwLock.Lock() + defer db.rwLock.Unlock() + + if err := db.lastEntryContext.SealBlock(parentHash, block, timestamp); err != nil { + return fmt.Errorf("failed to seal block: %w", err) } - addEntry(evt.encode()) + db.log.Trace("Sealed block", "parent", parentHash, "block", block, "timestamp", timestamp) + return db.flush() +} - if execMsg != nil { - maybeAddCheckpoint() - link, err := newExecutingLink(*execMsg) - if err != nil { - return fmt.Errorf("failed to create executing link: %w", err) - } - addEntry(link.encode()) +func (db *DB) AddLog(logHash types.TruncatedHash, parentBlock eth.BlockID, logIdx uint32, execMsg *types.ExecutingMessage) error { + db.rwLock.Lock() + defer db.rwLock.Unlock() - maybeAddCheckpoint() - addEntry(newExecutingCheck(execMsg.Hash).encode()) - } - if err := db.store.Append(entriesToAdd...); err != nil { - return fmt.Errorf("failed to append entries: %w", err) + if err := db.lastEntryContext.ApplyLog(parentBlock, logIdx, logHash, execMsg); err != nil { + return fmt.Errorf("failed to apply log: %w", err) } - db.lastEntryContext = postState - db.updateEntryCountMetric() - return nil + db.log.Trace("Applied log", "parentBlock", parentBlock, "logIndex", logIdx, "logHash", logHash, "executing", execMsg != nil) + return db.flush() } // Rewind the database to remove any blocks after headBlockNum // The block at headBlockNum itself is not removed. -func (db *DB) Rewind(headBlockNum uint64) error { +func (db *DB) Rewind(newHeadBlockNum uint64) error { db.rwLock.Lock() defer db.rwLock.Unlock() - if headBlockNum >= db.lastEntryContext.blockNum { - // Nothing to do - return nil - } - // Find the last checkpoint before the block to remove - idx, err := db.searchCheckpoint(headBlockNum+1, 0) - if errors.Is(err, io.EOF) { - // Requested a block prior to the first checkpoint - // Delete everything without scanning forward - idx = -1 - } else if err != nil { - return fmt.Errorf("failed to find checkpoint prior to block %v: %w", headBlockNum, err) - } else { - // Scan forward from the checkpoint to find the first entry about a block after headBlockNum - i, err := db.newIterator(idx) - if err != nil { - return fmt.Errorf("failed to create iterator when searching for rewind point: %w", err) - } - // If we don't find any useful logs after the checkpoint, we should delete the checkpoint itself - // So move our delete marker back to include it as a starting point - idx-- - for { - blockNum, _, _, err := i.NextLog() - if errors.Is(err, io.EOF) { - // Reached end of file, we need to keep everything - return nil - } else if err != nil { - return fmt.Errorf("failed to find rewind point: %w", err) - } - if blockNum > headBlockNum { - // Found the first entry we don't need, so stop searching and delete everything after idx - break - } - // Otherwise we need all of the entries the iterator just read - idx = i.nextEntryIdx - 1 - } + // Even if the last fully-processed block matches headBlockNum, + // we might still have trailing log events to get rid of. + iter, err := db.newIteratorAt(newHeadBlockNum, 0) + if err != nil { + return err } - // Truncate to contain idx+1 entries, since indices are 0 based, this deletes everything after idx - if err := db.store.Truncate(idx); err != nil { - return fmt.Errorf("failed to truncate to block %v: %w", headBlockNum, err) + // Truncate to contain idx+1 entries, since indices are 0 based, + // this deletes everything after idx + if err := db.store.Truncate(iter.NextIndex()); err != nil { + return fmt.Errorf("failed to truncate to block %v: %w", newHeadBlockNum, err) } // Use db.init() to find the log context for the new latest log entry - if err := db.init(); err != nil { + if err := db.init(true); err != nil { return fmt.Errorf("failed to find new last entry context: %w", err) } return nil } -// NextExecutingMessage returns the next executing message in the log database. -// it skips over any non-executing messages, and will return an error if encountered. -// the iterator is modified in the process. -func (db *DB) NextExecutingMessage(iter Iterator) (types.ExecutingMessage, error) { - db.rwLock.RLock() - defer db.rwLock.RUnlock() - // this for-loop will break: - // - when the iterator reaches the end of the log - // - when the iterator reaches an executing message - // - if an error occurs - for { - _, _, _, err := iter.NextLog() - if err != nil { - return types.ExecutingMessage{}, err - } - // if the log is not an executing message, both exec and err are empty - exec, err := iter.ExecMessage() - if err != nil { - return types.ExecutingMessage{}, fmt.Errorf("failed to get executing message: %w", err) - } - if exec != (types.ExecutingMessage{}) { - return exec, nil - } - } -} - -// LastCheckpointBehind returns an iterator for the last checkpoint behind the specified entry index. -// If the entry index is a search checkpoint, the iterator will start at that checkpoint. -// After searching back long enough (the searchCheckpointFrequency), an error is returned, -// as checkpoints are expected to be found within the frequency. -func (db *DB) LastCheckpointBehind(entryIdx entrydb.EntryIdx) (Iterator, error) { - for attempts := 0; attempts < searchCheckpointFrequency; attempts++ { - // attempt to read the index entry as a search checkpoint - _, err := db.readSearchCheckpoint(entryIdx) - if err == nil { - return db.newIterator(entryIdx) - } - // ErrDataCorruption is the return value if the entry is not a search checkpoint - // if it's not that type of error, we should return it instead of continuing - if !errors.Is(err, ErrDataCorruption) { - return nil, err - } - // don't attempt to read behind the start of the data - if entryIdx == 0 { - break - } - // reverse if we haven't found it yet - entryIdx -= 1 - } - return nil, fmt.Errorf("failed to find a search checkpoint in the last %v entries", searchCheckpointFrequency) -} - func (db *DB) readSearchCheckpoint(entryIdx entrydb.EntryIdx) (searchCheckpoint, error) { data, err := db.store.Read(entryIdx) if err != nil { @@ -562,14 +501,6 @@ func (db *DB) readSearchCheckpoint(entryIdx entrydb.EntryIdx) (searchCheckpoint, return newSearchCheckpointFromEntry(data) } -func (db *DB) readCanonicalHash(entryIdx entrydb.EntryIdx) (canonicalHash, error) { - data, err := db.store.Read(entryIdx) - if err != nil { - return canonicalHash{}, fmt.Errorf("failed to read entry %v: %w", entryIdx, err) - } - return newCanonicalHashFromEntry(data) -} - func (db *DB) Close() error { return db.store.Close() } diff --git a/op-supervisor/supervisor/backend/db/logs/db_invariants_test.go b/op-supervisor/supervisor/backend/db/logs/db_invariants_test.go index e0837e8c57bf..04c004f3d096 100644 --- a/op-supervisor/supervisor/backend/db/logs/db_invariants_test.go +++ b/op-supervisor/supervisor/backend/db/logs/db_invariants_test.go @@ -38,16 +38,13 @@ func checkDBInvariants(t *testing.T, dbPath string, m *stubMetrics) { } entryInvariants := []entryInvariant{ - invariantSearchCheckpointOnlyAtFrequency, invariantSearchCheckpointAtEverySearchCheckpointFrequency, - invariantCanonicalHashAfterEverySearchCheckpoint, + invariantCanonicalHashOrCheckpointAfterEverySearchCheckpoint, invariantSearchCheckpointBeforeEveryCanonicalHash, - invariantIncrementLogIdxIfNotImmediatelyAfterCanonicalHash, invariantExecLinkAfterInitEventWithFlagSet, invariantExecLinkOnlyAfterInitiatingEventWithFlagSet, invariantExecCheckAfterExecLink, invariantExecCheckOnlyAfterExecLink, - invariantValidLastEntry, } for i, entry := range entries { for _, invariant := range entryInvariants { @@ -83,81 +80,47 @@ func invariantFileSizeMatchesEntryCountMetric(stat os.FileInfo, m *stubMetrics) return nil } -func invariantSearchCheckpointOnlyAtFrequency(entryIdx int, entry entrydb.Entry, entries []entrydb.Entry, m *stubMetrics) error { - if entry[0] != typeSearchCheckpoint { - return nil - } - if entryIdx%searchCheckpointFrequency != 0 { - return fmt.Errorf("should only have search checkpoints every %v entries but found at entry %v", searchCheckpointFrequency, entryIdx) - } - return nil -} - func invariantSearchCheckpointAtEverySearchCheckpointFrequency(entryIdx int, entry entrydb.Entry, entries []entrydb.Entry, m *stubMetrics) error { - if entryIdx%searchCheckpointFrequency == 0 && entry[0] != typeSearchCheckpoint { + if entryIdx%searchCheckpointFrequency == 0 && entry.Type() != entrydb.TypeSearchCheckpoint { return fmt.Errorf("should have search checkpoints every %v entries but entry %v was %x", searchCheckpointFrequency, entryIdx, entry) } return nil } -func invariantCanonicalHashAfterEverySearchCheckpoint(entryIdx int, entry entrydb.Entry, entries []entrydb.Entry, m *stubMetrics) error { - if entry[0] != typeSearchCheckpoint { +func invariantCanonicalHashOrCheckpointAfterEverySearchCheckpoint(entryIdx int, entry entrydb.Entry, entries []entrydb.Entry, m *stubMetrics) error { + if entry.Type() != entrydb.TypeSearchCheckpoint { return nil } if entryIdx+1 >= len(entries) { - return fmt.Errorf("expected canonical hash after search checkpoint at entry %v but no further entries found", entryIdx) + return fmt.Errorf("expected canonical hash or checkpoint after search checkpoint at entry %v but no further entries found", entryIdx) } nextEntry := entries[entryIdx+1] - if nextEntry[0] != typeCanonicalHash { - return fmt.Errorf("expected canonical hash after search checkpoint at entry %v but got %x", entryIdx, nextEntry) + if nextEntry.Type() != entrydb.TypeCanonicalHash && nextEntry.Type() != entrydb.TypeSearchCheckpoint { + return fmt.Errorf("expected canonical hash or checkpoint after search checkpoint at entry %v but got %x", entryIdx, nextEntry) } return nil } // invariantSearchCheckpointBeforeEveryCanonicalHash ensures we don't have extra canonical-hash entries func invariantSearchCheckpointBeforeEveryCanonicalHash(entryIdx int, entry entrydb.Entry, entries []entrydb.Entry, m *stubMetrics) error { - if entry[0] != typeCanonicalHash { + if entry.Type() != entrydb.TypeCanonicalHash { return nil } if entryIdx == 0 { return fmt.Errorf("expected search checkpoint before canonical hash at entry %v but no previous entries present", entryIdx) } prevEntry := entries[entryIdx-1] - if prevEntry[0] != typeSearchCheckpoint { + if prevEntry.Type() != entrydb.TypeSearchCheckpoint { return fmt.Errorf("expected search checkpoint before canonical hash at entry %v but got %x", entryIdx, prevEntry) } return nil } -func invariantIncrementLogIdxIfNotImmediatelyAfterCanonicalHash(entryIdx int, entry entrydb.Entry, entries []entrydb.Entry, m *stubMetrics) error { - if entry[0] != typeInitiatingEvent { - return nil - } - if entryIdx == 0 { - return fmt.Errorf("found initiating event at index %v before any search checkpoint", entryIdx) - } - blockDiff := entry[1] - flags := entry[2] - incrementsLogIdx := flags&eventFlagIncrementLogIdx != 0 - prevEntry := entries[entryIdx-1] - prevEntryIsCanonicalHash := prevEntry[0] == typeCanonicalHash - if incrementsLogIdx && prevEntryIsCanonicalHash { - return fmt.Errorf("initiating event at index %v increments logIdx despite being immediately after canonical hash (prev entry %x)", entryIdx, prevEntry) - } - if incrementsLogIdx && blockDiff > 0 { - return fmt.Errorf("initiating event at index %v increments logIdx despite starting a new block", entryIdx) - } - if !incrementsLogIdx && !prevEntryIsCanonicalHash && blockDiff == 0 { - return fmt.Errorf("initiating event at index %v does not increment logIdx when block unchanged and not after canonical hash (prev entry %x)", entryIdx, prevEntry) - } - return nil -} - func invariantExecLinkAfterInitEventWithFlagSet(entryIdx int, entry entrydb.Entry, entries []entrydb.Entry, m *stubMetrics) error { - if entry[0] != typeInitiatingEvent { + if entry.Type() != entrydb.TypeInitiatingEvent { return nil } - hasExecMessage := entry[2]&eventFlagHasExecutingMessage != 0 + hasExecMessage := entry[1]&eventFlagHasExecutingMessage != 0 if !hasExecMessage { return nil } @@ -168,14 +131,14 @@ func invariantExecLinkAfterInitEventWithFlagSet(entryIdx int, entry entrydb.Entr if len(entries) <= linkIdx { return fmt.Errorf("expected executing link after initiating event with exec msg flag set at entry %v but there were no more events", entryIdx) } - if entries[linkIdx][0] != typeExecutingLink { + if entries[linkIdx].Type() != entrydb.TypeExecutingLink { return fmt.Errorf("expected executing link at idx %v after initiating event with exec msg flag set at entry %v but got type %v", linkIdx, entryIdx, entries[linkIdx][0]) } return nil } func invariantExecLinkOnlyAfterInitiatingEventWithFlagSet(entryIdx int, entry entrydb.Entry, entries []entrydb.Entry, m *stubMetrics) error { - if entry[0] != typeExecutingLink { + if entry.Type() != entrydb.TypeExecutingLink { return nil } if entryIdx == 0 { @@ -189,10 +152,10 @@ func invariantExecLinkOnlyAfterInitiatingEventWithFlagSet(entryIdx int, entry en return fmt.Errorf("found executing link without a preceding initiating event at entry %v", entryIdx) } initEntry := entries[initIdx] - if initEntry[0] != typeInitiatingEvent { + if initEntry.Type() != entrydb.TypeInitiatingEvent { return fmt.Errorf("expected initiating event at entry %v prior to executing link at %v but got %x", initIdx, entryIdx, initEntry[0]) } - flags := initEntry[2] + flags := initEntry[1] if flags&eventFlagHasExecutingMessage == 0 { return fmt.Errorf("initiating event at %v prior to executing link at %v does not have flag set to indicate needing a executing event: %x", initIdx, entryIdx, initEntry) } @@ -200,7 +163,7 @@ func invariantExecLinkOnlyAfterInitiatingEventWithFlagSet(entryIdx int, entry en } func invariantExecCheckAfterExecLink(entryIdx int, entry entrydb.Entry, entries []entrydb.Entry, m *stubMetrics) error { - if entry[0] != typeExecutingLink { + if entry.Type() != entrydb.TypeExecutingLink { return nil } checkIdx := entryIdx + 1 @@ -211,14 +174,14 @@ func invariantExecCheckAfterExecLink(entryIdx int, entry entrydb.Entry, entries return fmt.Errorf("expected executing link at %v to be followed by executing check at %v but ran out of entries", entryIdx, checkIdx) } checkEntry := entries[checkIdx] - if checkEntry[0] != typeExecutingCheck { + if checkEntry.Type() != entrydb.TypeExecutingCheck { return fmt.Errorf("expected executing link at %v to be followed by executing check at %v but got type %v", entryIdx, checkIdx, checkEntry[0]) } return nil } func invariantExecCheckOnlyAfterExecLink(entryIdx int, entry entrydb.Entry, entries []entrydb.Entry, m *stubMetrics) error { - if entry[0] != typeExecutingCheck { + if entry.Type() != entrydb.TypeExecutingCheck { return nil } if entryIdx == 0 { @@ -232,29 +195,8 @@ func invariantExecCheckOnlyAfterExecLink(entryIdx int, entry entrydb.Entry, entr return fmt.Errorf("found executing link without a preceding initiating event at entry %v", entryIdx) } linkEntry := entries[linkIdx] - if linkEntry[0] != typeExecutingLink { + if linkEntry.Type() != entrydb.TypeExecutingLink { return fmt.Errorf("expected executing link at entry %v prior to executing check at %v but got %x", linkIdx, entryIdx, linkEntry[0]) } return nil } - -// invariantValidLastEntry checks that the last entry is either a executing check or initiating event with no exec message -func invariantValidLastEntry(entryIdx int, entry entrydb.Entry, entries []entrydb.Entry, m *stubMetrics) error { - if entryIdx+1 < len(entries) { - return nil - } - if entry[0] == typeExecutingCheck { - return nil - } - if entry[0] != typeInitiatingEvent { - return fmt.Errorf("invalid final event type: %v", entry[0]) - } - evt, err := newInitiatingEventFromEntry(entry) - if err != nil { - return fmt.Errorf("final event was invalid: %w", err) - } - if evt.hasExecMsg { - return errors.New("ends with init event that should have exec msg but no exec msg follows") - } - return nil -} diff --git a/op-supervisor/supervisor/backend/db/logs/db_test.go b/op-supervisor/supervisor/backend/db/logs/db_test.go index 91caa2fe3e5d..d2dbced9f393 100644 --- a/op-supervisor/supervisor/backend/db/logs/db_test.go +++ b/op-supervisor/supervisor/backend/db/logs/db_test.go @@ -1,21 +1,23 @@ package logs import ( - "bytes" - "fmt" + "encoding/binary" "io" "io/fs" "os" "path/filepath" "testing" + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" - "github.com/stretchr/testify/require" ) func createTruncatedHash(i int) types.TruncatedHash { @@ -23,22 +25,27 @@ func createTruncatedHash(i int) types.TruncatedHash { } func createHash(i int) common.Hash { - data := bytes.Repeat([]byte{byte(i)}, common.HashLength) - return common.BytesToHash(data) + if i == -1 { // parent-hash of genesis is zero + return common.Hash{} + } + var data [9]byte + data[0] = 0xff + binary.BigEndian.PutUint64(data[1:], uint64(i)) + return crypto.Keccak256Hash(data[:]) } func TestErrorOpeningDatabase(t *testing.T) { dir := t.TempDir() - _, err := NewFromFile(testlog.Logger(t, log.LvlInfo), &stubMetrics{}, filepath.Join(dir, "missing-dir", "file.db")) + _, err := NewFromFile(testlog.Logger(t, log.LvlInfo), &stubMetrics{}, filepath.Join(dir, "missing-dir", "file.db"), false) require.ErrorIs(t, err, os.ErrNotExist) } func runDBTest(t *testing.T, setup func(t *testing.T, db *DB, m *stubMetrics), assert func(t *testing.T, db *DB, m *stubMetrics)) { createDb := func(t *testing.T, dir string) (*DB, *stubMetrics, string) { - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LvlTrace) path := filepath.Join(dir, "test.db") m := &stubMetrics{} - db, err := NewFromFile(logger, m, path) + db, err := NewFromFile(logger, m, path, false) require.NoError(t, err, "Failed to create database") t.Cleanup(func() { err := db.Close() @@ -73,8 +80,8 @@ func TestEmptyDbDoesNotFindEntry(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) {}, func(t *testing.T, db *DB, m *stubMetrics) { - requireNotContains(t, db, 0, 0, createHash(1)) - requireNotContains(t, db, 0, 0, common.Hash{}) + requireFuture(t, db, 1, 0, createHash(1)) + requireFuture(t, db, 1, 0, common.Hash{}) }) } @@ -84,111 +91,146 @@ func TestAddLog(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) {}, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 0}, 5000, 0, nil) + genesis := eth.BlockID{Hash: createHash(15), Number: 0} + err := db.AddLog(createTruncatedHash(1), genesis, 0, nil) require.ErrorIs(t, err, ErrLogOutOfOrder) }) }) - t.Run("FirstEntry", func(t *testing.T) { + t.Run("FirstEntries", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 0, nil) - require.NoError(t, err) + genesis := eth.BlockID{Hash: createHash(15), Number: 15} + require.NoError(t, db.SealBlock(common.Hash{}, genesis, 5000), "seal genesis") + err := db.AddLog(createTruncatedHash(1), genesis, 0, nil) + require.NoError(t, err, "first log after genesis") + require.NoError(t, db.SealBlock(genesis.Hash, eth.BlockID{Hash: createHash(16), Number: 16}, 5001)) }, func(t *testing.T, db *DB, m *stubMetrics) { - requireContains(t, db, 15, 0, createHash(1)) + requireContains(t, db, 16, 0, createHash(1)) }) }) t.Run("MultipleEntriesFromSameBlock", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 0, nil) + // create 15 empty blocks + for i := 0; i <= 15; i++ { + bl := eth.BlockID{Hash: createHash(i), Number: uint64(i)} + require.NoError(t, db.SealBlock(createHash(i-1), bl, 5000+uint64(i)), "seal blocks") + } + // Now apply 3 logs on top of that, contents for block 16 + bl15 := eth.BlockID{Hash: createHash(15), Number: 15} + err := db.AddLog(createTruncatedHash(1), bl15, 0, nil) + require.NoError(t, err) + err = db.AddLog(createTruncatedHash(2), bl15, 1, nil) require.NoError(t, err) - err = db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 1, nil) + err = db.AddLog(createTruncatedHash(3), bl15, 2, nil) require.NoError(t, err) - err = db.AddLog(createTruncatedHash(3), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 2, nil) + // Now seal block 16 + bl16 := eth.BlockID{Hash: createHash(16), Number: 16} + err = db.SealBlock(bl15.Hash, bl16, 5016) require.NoError(t, err) }, func(t *testing.T, db *DB, m *stubMetrics) { - require.EqualValues(t, 5, m.entryCount, "should not output new searchCheckpoint for every log") - requireContains(t, db, 15, 0, createHash(1)) - requireContains(t, db, 15, 1, createHash(2)) - requireContains(t, db, 15, 2, createHash(3)) + require.EqualValues(t, 16*2+3+2, m.entryCount, "empty blocks have logs") + requireContains(t, db, 16, 0, createHash(1)) + requireContains(t, db, 16, 1, createHash(2)) + requireContains(t, db, 16, 2, createHash(3)) }) }) t.Run("MultipleEntriesFromMultipleBlocks", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 0, nil) + bl14 := eth.BlockID{Hash: createHash(14), Number: 14} + err := db.SealBlock(createHash(13), bl14, 5000) require.NoError(t, err) - err = db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 1, nil) + bl15 := eth.BlockID{Hash: createHash(15), Number: 15} + err = db.SealBlock(createHash(14), bl15, 5001) require.NoError(t, err) - err = db.AddLog(createTruncatedHash(3), eth.BlockID{Hash: createHash(16), Number: 16}, 5002, 0, nil) + err = db.AddLog(createTruncatedHash(1), bl15, 0, nil) require.NoError(t, err) - err = db.AddLog(createTruncatedHash(4), eth.BlockID{Hash: createHash(16), Number: 16}, 5002, 1, nil) + err = db.AddLog(createTruncatedHash(2), bl15, 1, nil) + require.NoError(t, err) + bl16 := eth.BlockID{Hash: createHash(16), Number: 16} + err = db.SealBlock(bl15.Hash, bl16, 5003) + require.NoError(t, err) + err = db.AddLog(createTruncatedHash(3), bl16, 0, nil) + require.NoError(t, err) + err = db.AddLog(createTruncatedHash(4), bl16, 1, nil) + require.NoError(t, err) + bl17 := eth.BlockID{Hash: createHash(17), Number: 17} + err = db.SealBlock(bl16.Hash, bl17, 5003) require.NoError(t, err) }, func(t *testing.T, db *DB, m *stubMetrics) { - require.EqualValues(t, 6, m.entryCount, "should not output new searchCheckpoint for every block") - requireContains(t, db, 15, 0, createHash(1)) - requireContains(t, db, 15, 1, createHash(2)) - requireContains(t, db, 16, 0, createHash(3)) - requireContains(t, db, 16, 1, createHash(4)) + require.EqualValues(t, 2+2+1+1+2+1+1+2, m.entryCount, "should not output new searchCheckpoint for every block") + requireContains(t, db, 16, 0, createHash(1)) + requireContains(t, db, 16, 1, createHash(2)) + requireContains(t, db, 17, 0, createHash(3)) + requireContains(t, db, 17, 1, createHash(4)) }) }) t.Run("ErrorWhenBeforeCurrentBlock", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 0, nil) + bl15 := eth.BlockID{Hash: createHash(15), Number: 15} + err := db.SealBlock(common.Hash{}, bl15, 5001) require.NoError(t, err) }, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(14), Number: 14}, 4998, 0, nil) - require.ErrorIs(t, err, ErrLogOutOfOrder) + bl14 := eth.BlockID{Hash: createHash(14), Number: 14} + err := db.SealBlock(createHash(13), bl14, 5000) + require.ErrorIs(t, err, ErrConflict) }) }) t.Run("ErrorWhenBeforeCurrentBlockButAfterLastCheckpoint", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(13), Number: 13}, 5000, 0, nil) + err := db.lastEntryContext.forceBlock(eth.BlockID{Hash: createHash(13), Number: 13}, 5000) require.NoError(t, err) - err = db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 0, nil) + err = db.SealBlock(createHash(13), eth.BlockID{Hash: createHash(14), Number: 14}, 5001) + require.NoError(t, err) + err = db.SealBlock(createHash(14), eth.BlockID{Hash: createHash(15), Number: 15}, 5002) require.NoError(t, err) }, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(14), Number: 14}, 4998, 0, nil) - require.ErrorIs(t, err, ErrLogOutOfOrder) + onto := eth.BlockID{Hash: createHash(14), Number: 14} + err := db.AddLog(createTruncatedHash(1), onto, 0, nil) + require.ErrorIs(t, err, ErrLogOutOfOrder, "cannot build logs on 14 when 15 is already sealed") }) }) t.Run("ErrorWhenBeforeCurrentLogEvent", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 1, nil)) + bl15 := eth.BlockID{Hash: createHash(15), Number: 15} + err := db.lastEntryContext.forceBlock(bl15, 5000) + require.NoError(t, err) + require.NoError(t, db.AddLog(createTruncatedHash(1), bl15, 0, nil)) + require.NoError(t, db.AddLog(createTruncatedHash(1), bl15, 1, nil)) }, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(14), Number: 15}, 4998, 0, nil) - require.ErrorIs(t, err, ErrLogOutOfOrder) + bl15 := eth.BlockID{Hash: createHash(15), Number: 15} + err := db.AddLog(createTruncatedHash(1), bl15, 0, nil) + require.ErrorIs(t, err, ErrLogOutOfOrder, "already at log index 2") }) }) - t.Run("ErrorWhenBeforeCurrentLogEventButAfterLastCheckpoint", func(t *testing.T) { + t.Run("ErrorWhenBeforeBlockSeal", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 0, nil) - require.NoError(t, err) - err = db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 1, nil) - require.NoError(t, err) - err = db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 2, nil) + bl15 := eth.BlockID{Hash: createHash(15), Number: 15} + err := db.lastEntryContext.forceBlock(bl15, 5000) require.NoError(t, err) + require.NoError(t, db.AddLog(createTruncatedHash(1), bl15, 0, nil)) + require.NoError(t, db.AddLog(createTruncatedHash(1), bl15, 1, nil)) }, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(14), Number: 15}, 4998, 1, nil) + err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(16), Number: 16}, 0, nil) require.ErrorIs(t, err, ErrLogOutOfOrder) }) }) @@ -196,24 +238,31 @@ func TestAddLog(t *testing.T) { t.Run("ErrorWhenAtCurrentLogEvent", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 1, nil)) + bl15 := eth.BlockID{Hash: createHash(15), Number: 15} + err := db.lastEntryContext.forceBlock(bl15, 5000) + require.NoError(t, err) + require.NoError(t, db.AddLog(createTruncatedHash(1), bl15, 0, nil)) + require.NoError(t, db.AddLog(createTruncatedHash(1), bl15, 1, nil)) }, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 4998, 1, nil) - require.ErrorIs(t, err, ErrLogOutOfOrder) + bl15 := eth.BlockID{Hash: createHash(15), Number: 15} + err := db.AddLog(createTruncatedHash(1), bl15, 1, nil) + require.ErrorIs(t, err, ErrLogOutOfOrder, "already at log index 2") }) }) t.Run("ErrorWhenAtCurrentLogEventButAfterLastCheckpoint", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 1, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 2, nil)) + bl15 := eth.BlockID{Hash: createHash(15), Number: 15} + err := db.lastEntryContext.forceBlock(bl15, 5000) + require.NoError(t, err) + require.NoError(t, db.AddLog(createTruncatedHash(1), bl15, 0, nil)) + require.NoError(t, db.AddLog(createTruncatedHash(1), bl15, 1, nil)) }, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(14), Number: 15}, 4998, 2, nil) + bl15 := eth.BlockID{Hash: createHash(16), Number: 16} + err := db.AddLog(createTruncatedHash(1), bl15, 2, nil) require.ErrorIs(t, err, ErrLogOutOfOrder) }) }) @@ -221,19 +270,27 @@ func TestAddLog(t *testing.T) { t.Run("ErrorWhenSkippingLogEvent", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 0, nil) + bl15 := eth.BlockID{Hash: createHash(15), Number: 15} + err := db.lastEntryContext.forceBlock(bl15, 5000) require.NoError(t, err) + require.NoError(t, db.AddLog(createTruncatedHash(1), bl15, 0, nil)) }, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 4998, 2, nil) + bl15 := eth.BlockID{Hash: createHash(15), Number: 15} + err := db.AddLog(createTruncatedHash(1), bl15, 2, nil) require.ErrorIs(t, err, ErrLogOutOfOrder) }) }) t.Run("ErrorWhenFirstLogIsNotLogIdxZero", func(t *testing.T) { - runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) {}, + runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { + bl15 := eth.BlockID{Hash: createHash(15), Number: 15} + err := db.lastEntryContext.forceBlock(bl15, 5000) + require.NoError(t, err) + }, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 4998, 5, nil) + bl15 := eth.BlockID{Hash: createHash(15), Number: 15} + err := db.AddLog(createTruncatedHash(1), bl15, 5, nil) require.ErrorIs(t, err, ErrLogOutOfOrder) }) }) @@ -241,54 +298,102 @@ func TestAddLog(t *testing.T) { t.Run("ErrorWhenFirstLogOfNewBlockIsNotLogIdxZero", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(14), Number: 14}, 4996, 0, nil)) + bl15 := eth.BlockID{Hash: createHash(15), Number: 15} + err := db.lastEntryContext.forceBlock(bl15, 5000) + require.NoError(t, err) + err = db.AddLog(createTruncatedHash(1), bl15, 0, nil) + require.NoError(t, err) }, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 4998, 1, nil) + bl15 := eth.BlockID{Hash: createHash(15), Number: 15} + err := db.AddLog(createTruncatedHash(1), bl15, 1, nil) + require.NoError(t, err) + bl16 := eth.BlockID{Hash: createHash(16), Number: 16} + err = db.SealBlock(bl15.Hash, bl16, 5001) + require.NoError(t, err) + err = db.AddLog(createTruncatedHash(1), bl16, 1, nil) require.ErrorIs(t, err, ErrLogOutOfOrder) }) }) t.Run("MultipleSearchCheckpoints", func(t *testing.T) { + block0 := eth.BlockID{Hash: createHash(10), Number: 10} block1 := eth.BlockID{Hash: createHash(11), Number: 11} block2 := eth.BlockID{Hash: createHash(12), Number: 12} - block3 := eth.BlockID{Hash: createHash(15), Number: 15} - block4 := eth.BlockID{Hash: createHash(16), Number: 16} - // First checkpoint is at entry idx 0 - // Block 1 logs don't reach the second checkpoint + block3 := eth.BlockID{Hash: createHash(13), Number: 13} + block4 := eth.BlockID{Hash: createHash(14), Number: 14} + // Ignoring seal-checkpoints in checkpoint counting comments here; + // First search-checkpoint is at entry idx 0 + // Block 1 logs don't reach the second search-checkpoint block1LogCount := searchCheckpointFrequency - 10 - // Block 2 logs extend to just after the third checkpoint - block2LogCount := searchCheckpointFrequency + 20 - // Block 3 logs extend to immediately before the fourth checkpoint - block3LogCount := searchCheckpointFrequency - 16 + // Block 2 logs extend to just after the third search-checkpoint + block2LogCount := searchCheckpointFrequency + 16 + // Block 3 logs extend to immediately before the fourth search-checkpoint + block3LogCount := searchCheckpointFrequency - 19 block4LogCount := 2 runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - for i := 0; i < block1LogCount; i++ { - err := db.AddLog(createTruncatedHash(i), block1, 3000, uint32(i), nil) - require.NoErrorf(t, err, "failed to add log %v of block 1", i) + // force in block 0 + require.NoError(t, db.lastEntryContext.forceBlock(block0, 3000)) + expectedIndex := entrydb.EntryIdx(2) + t.Logf("block 0 complete, at entry %d", db.lastEntryContext.NextIndex()) + require.Equal(t, expectedIndex, db.lastEntryContext.NextIndex()) + { // create block 1 + for i := 0; i < block1LogCount; i++ { + err := db.AddLog(createTruncatedHash(i), block0, uint32(i), nil) + require.NoError(t, err) + } + err := db.SealBlock(block0.Hash, block1, 3001) // second seal-checkpoint + require.NoError(t, err) } - for i := 0; i < block2LogCount; i++ { - err := db.AddLog(createTruncatedHash(i), block2, 3002, uint32(i), nil) - require.NoErrorf(t, err, "failed to add log %v of block 2", i) + expectedIndex += entrydb.EntryIdx(block1LogCount) + 2 + t.Logf("block 1 complete, at entry %d", db.lastEntryContext.NextIndex()) + require.Equal(t, expectedIndex, db.lastEntryContext.NextIndex(), "added logs and a seal checkpoint") + { // create block 2 + for i := 0; i < block2LogCount; i++ { + // two of these imply a search checkpoint, the second and third search-checkpoint + err := db.AddLog(createTruncatedHash(i), block1, uint32(i), nil) + require.NoError(t, err) + } + err := db.SealBlock(block1.Hash, block2, 3002) // third seal-checkpoint + require.NoError(t, err) } - for i := 0; i < block3LogCount; i++ { - err := db.AddLog(createTruncatedHash(i), block3, 3004, uint32(i), nil) - require.NoErrorf(t, err, "failed to add log %v of block 3", i) + expectedIndex += entrydb.EntryIdx(block2LogCount) + 2 + 2 + 2 + t.Logf("block 2 complete, at entry %d", db.lastEntryContext.NextIndex()) + require.Equal(t, expectedIndex, db.lastEntryContext.NextIndex(), "added logs, two search checkpoints, and a seal checkpoint") + { // create block 3 + for i := 0; i < block3LogCount; i++ { + err := db.AddLog(createTruncatedHash(i), block2, uint32(i), nil) + require.NoError(t, err) + } + err := db.SealBlock(block2.Hash, block3, 3003) + require.NoError(t, err) } - // Verify that we're right before the fourth checkpoint will be written. + expectedIndex += entrydb.EntryIdx(block3LogCount) + 2 + t.Logf("block 3 complete, at entry %d", db.lastEntryContext.NextIndex()) + require.Equal(t, expectedIndex, db.lastEntryContext.NextIndex(), "added logs, and a seal checkpoint") + + // Verify that we're right before the fourth search-checkpoint will be written. // entryCount is the number of entries, so given 0 based indexing is the index of the next entry // the first checkpoint is at entry 0, the second at entry searchCheckpointFrequency etc - // so the fourth is at entry 3*searchCheckpointFrequency - require.EqualValues(t, 3*searchCheckpointFrequency, m.entryCount) - for i := 0; i < block4LogCount; i++ { - err := db.AddLog(createTruncatedHash(i), block4, 3006, uint32(i), nil) - require.NoErrorf(t, err, "failed to add log %v of block 4", i) + // so the fourth is at entry 3*searchCheckpointFrequency. + require.EqualValues(t, 3*searchCheckpointFrequency-1, m.entryCount) + { // create block 4 + for i := 0; i < block4LogCount; i++ { + // includes a fourth search checkpoint + err := db.AddLog(createTruncatedHash(i), block3, uint32(i), nil) + require.NoError(t, err) + } + err := db.SealBlock(block3.Hash, block4, 3003) // fourth seal checkpoint + require.NoError(t, err) } + expectedIndex += entrydb.EntryIdx(block4LogCount) + 2 + 2 + require.Equal(t, expectedIndex, db.lastEntryContext.NextIndex(), "added logs, a search checkpoint, and a seal checkpoint") + t.Logf("block 4 complete, at entry %d", db.lastEntryContext.NextIndex()) }, func(t *testing.T, db *DB, m *stubMetrics) { - // Check that we wrote additional search checkpoints - expectedCheckpointCount := 4 + // Check that we wrote additional search checkpoints and seal checkpoints + expectedCheckpointCount := 4 + 4 expectedEntryCount := block1LogCount + block2LogCount + block3LogCount + block4LogCount + (2 * expectedCheckpointCount) require.EqualValues(t, expectedEntryCount, m.entryCount) // Check we can find all the logs. @@ -322,68 +427,93 @@ func TestAddDependentLog(t *testing.T) { t.Run("FirstEntry", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 0, &execMsg) - require.NoError(t, err) - }, - func(t *testing.T, db *DB, m *stubMetrics) { - requireContains(t, db, 15, 0, createHash(1), execMsg) - }) - }) - - t.Run("CheckpointBetweenInitEventAndExecLink", func(t *testing.T) { - runDBTest(t, - func(t *testing.T, db *DB, m *stubMetrics) { - for i := uint32(0); m.entryCount < searchCheckpointFrequency-1; i++ { - require.NoError(t, db.AddLog(createTruncatedHash(9), eth.BlockID{Hash: createHash(9), Number: 1}, 500, i, nil)) - } - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 0, &execMsg) + bl15 := eth.BlockID{Hash: createHash(15), Number: 15} + require.NoError(t, db.lastEntryContext.forceBlock(bl15, 5000)) + err := db.AddLog(createTruncatedHash(1), bl15, 0, &execMsg) require.NoError(t, err) }, func(t *testing.T, db *DB, m *stubMetrics) { - requireContains(t, db, 15, 0, createHash(1), execMsg) + requireContains(t, db, 16, 0, createHash(1), execMsg) }) }) - t.Run("CheckpointBetweenInitEventAndExecLinkNotIncrementingBlock", func(t *testing.T) { + t.Run("BlockSealSearchCheckpointOverlap", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - + bl15 := eth.BlockID{Hash: createHash(15), Number: 15} + require.NoError(t, db.lastEntryContext.forceBlock(bl15, 5000)) for i := uint32(0); m.entryCount < searchCheckpointFrequency-1; i++ { - require.NoError(t, db.AddLog(createTruncatedHash(9), eth.BlockID{Hash: createHash(9), Number: 1}, 500, i, nil)) + require.NoError(t, db.AddLog(createTruncatedHash(9), bl15, i, nil)) } - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 1}, 5000, 253, &execMsg) + bl16 := eth.BlockID{Hash: createHash(16), Number: 16} + require.NoError(t, db.SealBlock(bl15.Hash, bl16, 5001)) + // added 3 entries: seal-checkpoint, then a search-checkpoint, then the canonical hash + require.Equal(t, m.entryCount, int64(searchCheckpointFrequency+2)) + err := db.AddLog(createTruncatedHash(1), bl16, 0, &execMsg) require.NoError(t, err) }, func(t *testing.T, db *DB, m *stubMetrics) { - requireContains(t, db, 1, 253, createHash(1), execMsg) + requireContains(t, db, 16, 0, createHash(9)) + requireContains(t, db, 17, 0, createHash(1), execMsg) }) }) - t.Run("CheckpointBetweenExecLinkAndExecCheck", func(t *testing.T) { + t.Run("AvoidCheckpointOverlapWithExecutingCheck", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - for i := uint32(0); m.entryCount < searchCheckpointFrequency-2; i++ { - require.NoError(t, db.AddLog(createTruncatedHash(9), eth.BlockID{Hash: createHash(9), Number: 1}, 500, i, nil)) + bl15 := eth.BlockID{Hash: createHash(15), Number: 15} + require.NoError(t, db.lastEntryContext.forceBlock(bl15, 5000)) + // we add 256 - 2 (start) - 2 (init msg, exec link) = 252 entries + for i := uint32(0); i < 252; i++ { + require.NoError(t, db.AddLog(createTruncatedHash(9), bl15, i, nil)) } - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 15}, 5000, 0, &execMsg) + // add an executing message + err := db.AddLog(createTruncatedHash(1), bl15, 252, &execMsg) require.NoError(t, err) + // 0,1: start + // 2..252+2: initiating logs without exec message + // 254 = inferred padding - 3 entries for exec msg would overlap with checkpoint + // 255 = inferred padding + // 256 = search checkpoint - what would be the exec check without padding + // 257 = canonical hash + // 258 = initiating message + // 259 = executing message link + // 260 = executing message check + require.Equal(t, int64(261), m.entryCount) + db.debugTip() }, func(t *testing.T, db *DB, m *stubMetrics) { - requireContains(t, db, 15, 0, createHash(1), execMsg) + requireContains(t, db, 16, 251, createHash(9)) + requireContains(t, db, 16, 252, createHash(1), execMsg) }) }) - t.Run("CheckpointBetweenExecLinkAndExecCheckNotIncrementingBlock", func(t *testing.T) { + t.Run("AvoidCheckpointOverlapWithExecutingLink", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - for i := uint32(0); m.entryCount < searchCheckpointFrequency-2; i++ { - require.NoError(t, db.AddLog(createTruncatedHash(9), eth.BlockID{Hash: createHash(9), Number: 1}, 500, i, nil)) + bl15 := eth.BlockID{Hash: createHash(15), Number: 15} + require.NoError(t, db.lastEntryContext.forceBlock(bl15, 5000)) + // we add 256 - 2 (start) - 1 (init msg) = 253 entries + for i := uint32(0); i < 253; i++ { + require.NoError(t, db.AddLog(createTruncatedHash(9), bl15, i, nil)) } - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(15), Number: 1}, 5000, 252, &execMsg) + // add an executing message + err := db.AddLog(createTruncatedHash(1), bl15, 253, &execMsg) require.NoError(t, err) + // 0,1: start + // 2..253+2: initiating logs without exec message + // 255 = inferred padding - 3 entries for exec msg would overlap with checkpoint + // 256 = search checkpoint - what would be the exec link without padding + // 257 = canonical hash + // 258 = initiating message + // 259 = executing message link + // 260 = executing message check + db.debugTip() + require.Equal(t, int64(261), m.entryCount) }, func(t *testing.T, db *DB, m *stubMetrics) { - requireContains(t, db, 1, 252, createHash(1), execMsg) + requireContains(t, db, 16, 252, createHash(9)) + requireContains(t, db, 16, 253, createHash(1), execMsg) }) }) } @@ -391,35 +521,36 @@ func TestAddDependentLog(t *testing.T) { func TestContains(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(50), Number: 50}, 500, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(3), eth.BlockID{Hash: createHash(50), Number: 50}, 500, 1, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(50), Number: 50}, 500, 2, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(52), Number: 52}, 500, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(3), eth.BlockID{Hash: createHash(52), Number: 52}, 500, 1, nil)) + bl50 := eth.BlockID{Hash: createHash(50), Number: 50} + require.NoError(t, db.lastEntryContext.forceBlock(bl50, 5000)) + require.NoError(t, db.AddLog(createTruncatedHash(1), bl50, 0, nil)) + require.NoError(t, db.AddLog(createTruncatedHash(3), bl50, 1, nil)) + require.NoError(t, db.AddLog(createTruncatedHash(2), bl50, 2, nil)) + bl51 := eth.BlockID{Hash: createHash(51), Number: 51} + require.NoError(t, db.SealBlock(bl50.Hash, bl51, 5001)) + bl52 := eth.BlockID{Hash: createHash(52), Number: 52} + require.NoError(t, db.SealBlock(bl51.Hash, bl52, 5001)) + require.NoError(t, db.AddLog(createTruncatedHash(1), bl52, 0, nil)) + require.NoError(t, db.AddLog(createTruncatedHash(3), bl52, 1, nil)) }, func(t *testing.T, db *DB, m *stubMetrics) { // Should find added logs - requireContains(t, db, 50, 0, createHash(1)) - requireContains(t, db, 50, 1, createHash(3)) - requireContains(t, db, 50, 2, createHash(2)) - requireContains(t, db, 52, 0, createHash(1)) - requireContains(t, db, 52, 1, createHash(3)) - - // Should not find log when block number too low - requireNotContains(t, db, 49, 0, createHash(1)) - - // Should not find log when block number too high - requireNotContains(t, db, 51, 0, createHash(1)) - - // Should not find log when requested log after end of database - requireNotContains(t, db, 52, 2, createHash(3)) - requireNotContains(t, db, 53, 0, createHash(3)) - - // Should not find log when log index too high - requireNotContains(t, db, 50, 3, createHash(2)) - - // Should not find log when hash doesn't match log at block number and index - requireWrongHash(t, db, 50, 0, createHash(5), types.ExecutingMessage{}) + requireContains(t, db, 51, 0, createHash(1)) + requireContains(t, db, 51, 1, createHash(3)) + requireContains(t, db, 51, 2, createHash(2)) + requireContains(t, db, 53, 0, createHash(1)) + requireContains(t, db, 53, 1, createHash(3)) + + // 52 was sealed as empty + requireConflicts(t, db, 52, 0, createHash(1)) + + // 53 only contained 2 logs, not 3, and is not sealed yet + requireFuture(t, db, 53, 2, createHash(3)) + // 54 doesn't exist yet + requireFuture(t, db, 54, 0, createHash(3)) + + // 51 only contained 3 logs, not 4 + requireConflicts(t, db, 51, 3, createHash(2)) }) } @@ -447,54 +578,63 @@ func TestExecutes(t *testing.T) { } runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(50), Number: 50}, 500, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(3), eth.BlockID{Hash: createHash(50), Number: 50}, 500, 1, &execMsg1)) - require.NoError(t, db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(50), Number: 50}, 500, 2, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(52), Number: 52}, 500, 0, &execMsg2)) - require.NoError(t, db.AddLog(createTruncatedHash(3), eth.BlockID{Hash: createHash(52), Number: 52}, 500, 1, &execMsg3)) + bl50 := eth.BlockID{Hash: createHash(50), Number: 50} + require.NoError(t, db.lastEntryContext.forceBlock(bl50, 500)) + require.NoError(t, db.AddLog(createTruncatedHash(1), bl50, 0, nil)) + require.NoError(t, db.AddLog(createTruncatedHash(3), bl50, 1, &execMsg1)) + require.NoError(t, db.AddLog(createTruncatedHash(2), bl50, 2, nil)) + bl51 := eth.BlockID{Hash: createHash(51), Number: 51} + require.NoError(t, db.SealBlock(bl50.Hash, bl51, 5001)) + bl52 := eth.BlockID{Hash: createHash(52), Number: 52} + require.NoError(t, db.SealBlock(bl51.Hash, bl52, 5001)) + require.NoError(t, db.AddLog(createTruncatedHash(1), bl52, 0, &execMsg2)) + require.NoError(t, db.AddLog(createTruncatedHash(3), bl52, 1, &execMsg3)) }, func(t *testing.T, db *DB, m *stubMetrics) { // Should find added logs - requireExecutingMessage(t, db, 50, 0, types.ExecutingMessage{}) - requireExecutingMessage(t, db, 50, 1, execMsg1) - requireExecutingMessage(t, db, 50, 2, types.ExecutingMessage{}) - requireExecutingMessage(t, db, 52, 0, execMsg2) - requireExecutingMessage(t, db, 52, 1, execMsg3) - - // Should not find log when block number too low - requireNotContains(t, db, 49, 0, createHash(1)) - - // Should not find log when block number too high - requireNotContains(t, db, 51, 0, createHash(1)) - - // Should not find log when requested log after end of database - requireNotContains(t, db, 52, 2, createHash(3)) - requireNotContains(t, db, 53, 0, createHash(3)) - - // Should not find log when log index too high - requireNotContains(t, db, 50, 3, createHash(2)) + requireExecutingMessage(t, db, 51, 0, types.ExecutingMessage{}) + requireExecutingMessage(t, db, 51, 1, execMsg1) + requireExecutingMessage(t, db, 51, 2, types.ExecutingMessage{}) + requireExecutingMessage(t, db, 53, 0, execMsg2) + requireExecutingMessage(t, db, 53, 1, execMsg3) + + // 52 was sealed without logs + requireConflicts(t, db, 52, 0, createHash(1)) + + // 53 only contained 2 logs, not 3, and is not sealed yet + requireFuture(t, db, 53, 2, createHash(3)) + // 54 doesn't exist yet + requireFuture(t, db, 54, 0, createHash(3)) + + // 51 only contained 3 logs, not 4 + requireConflicts(t, db, 51, 3, createHash(2)) }) } func TestGetBlockInfo(t *testing.T) { - t.Run("ReturnsEOFWhenEmpty", func(t *testing.T) { + t.Run("ReturnsErrFutureWhenEmpty", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) {}, func(t *testing.T, db *DB, m *stubMetrics) { - _, _, err := db.ClosestBlockInfo(10) - require.ErrorIs(t, err, io.EOF) + bl10 := eth.BlockID{Hash: createHash(10), Number: 10} + _, err := db.FindSealedBlock(bl10) + require.ErrorIs(t, err, ErrFuture) }) }) - t.Run("ReturnsEOFWhenRequestedBlockBeforeFirstSearchCheckpoint", func(t *testing.T) { + t.Run("ReturnsErrFutureWhenRequestedBlockBeforeFirstSearchCheckpoint", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(11), Number: 11}, 500, 0, nil) + bl11 := eth.BlockID{Hash: createHash(11), Number: 11} + require.NoError(t, db.lastEntryContext.forceBlock(bl11, 500)) + err := db.AddLog(createTruncatedHash(1), bl11, 0, nil) require.NoError(t, err) }, func(t *testing.T, db *DB, m *stubMetrics) { - _, _, err := db.ClosestBlockInfo(10) - require.ErrorIs(t, err, io.EOF) + // if the DB starts at 11, then shouldn't find 10 + bl10 := eth.BlockID{Hash: createHash(10), Number: 10} + _, err := db.FindSealedBlock(bl10) + require.ErrorIs(t, err, ErrSkipped) }) }) @@ -502,56 +642,24 @@ func TestGetBlockInfo(t *testing.T) { block := eth.BlockID{Hash: createHash(11), Number: 11} runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), block, 500, 0, nil) - require.NoError(t, err) + require.NoError(t, db.SealBlock(common.Hash{}, block, 500)) }, func(t *testing.T, db *DB, m *stubMetrics) { - requireClosestBlockInfo(t, db, 11, block.Number, block.Hash) - requireClosestBlockInfo(t, db, 12, block.Number, block.Hash) - requireClosestBlockInfo(t, db, 200, block.Number, block.Hash) - }) - }) - - t.Run("ReturnClosestCheckpointBlockInfo", func(t *testing.T) { - runDBTest(t, - func(t *testing.T, db *DB, m *stubMetrics) { - for i := 1; i < searchCheckpointFrequency+3; i++ { - block := eth.BlockID{Hash: createHash(i), Number: uint64(i)} - err := db.AddLog(createTruncatedHash(i), block, uint64(i)*2, 0, nil) - require.NoError(t, err) - } - }, - func(t *testing.T, db *DB, m *stubMetrics) { - // Expect block from the first checkpoint - requireClosestBlockInfo(t, db, 1, 1, createHash(1)) - requireClosestBlockInfo(t, db, 10, 1, createHash(1)) - requireClosestBlockInfo(t, db, searchCheckpointFrequency-3, 1, createHash(1)) - - // Expect block from the second checkpoint - // 2 entries used for initial checkpoint but we start at block 1 - secondCheckpointBlockNum := searchCheckpointFrequency - 1 - requireClosestBlockInfo(t, db, uint64(secondCheckpointBlockNum), uint64(secondCheckpointBlockNum), createHash(secondCheckpointBlockNum)) - requireClosestBlockInfo(t, db, uint64(secondCheckpointBlockNum)+1, uint64(secondCheckpointBlockNum), createHash(secondCheckpointBlockNum)) - requireClosestBlockInfo(t, db, uint64(secondCheckpointBlockNum)+2, uint64(secondCheckpointBlockNum), createHash(secondCheckpointBlockNum)) + index, err := db.FindSealedBlock(block) + require.NoError(t, err) + require.Equal(t, entrydb.EntryIdx(2), index, + "expecting to continue after search checkpoint that declared the block") }) }) } -func requireClosestBlockInfo(t *testing.T, db *DB, searchFor uint64, expectedBlockNum uint64, expectedHash common.Hash) { - blockNum, hash, err := db.ClosestBlockInfo(searchFor) - require.NoError(t, err) - require.Equal(t, expectedBlockNum, blockNum) - require.Equal(t, types.TruncateHash(expectedHash), hash) -} - func requireContains(t *testing.T, db *DB, blockNum uint64, logIdx uint32, logHash common.Hash, execMsg ...types.ExecutingMessage) { require.LessOrEqual(t, len(execMsg), 1, "cannot have multiple executing messages for a single log") m, ok := db.m.(*stubMetrics) require.True(t, ok, "Did not get the expected metrics type") - result, _, err := db.Contains(blockNum, logIdx, types.TruncateHash(logHash)) + _, err := db.Contains(blockNum, logIdx, types.TruncateHash(logHash)) require.NoErrorf(t, err, "Error searching for log %v in block %v", logIdx, blockNum) - require.Truef(t, result, "Did not find log %v in block %v with hash %v", logIdx, blockNum, logHash) - require.LessOrEqual(t, m.entriesReadForSearch, int64(searchCheckpointFrequency), "Should not need to read more than between two checkpoints") + require.LessOrEqual(t, m.entriesReadForSearch, int64(searchCheckpointFrequency*2), "Should not need to read more than between two checkpoints") require.NotZero(t, m.entriesReadForSearch, "Must read at least some entries to find the log") var expectedExecMsg types.ExecutingMessage @@ -561,318 +669,354 @@ func requireContains(t *testing.T, db *DB, blockNum uint64, logIdx uint32, logHa requireExecutingMessage(t, db, blockNum, logIdx, expectedExecMsg) } -func requireNotContains(t *testing.T, db *DB, blockNum uint64, logIdx uint32, logHash common.Hash) { +func requireConflicts(t *testing.T, db *DB, blockNum uint64, logIdx uint32, logHash common.Hash) { m, ok := db.m.(*stubMetrics) require.True(t, ok, "Did not get the expected metrics type") - result, _, err := db.Contains(blockNum, logIdx, types.TruncateHash(logHash)) - require.NoErrorf(t, err, "Error searching for log %v in block %v", logIdx, blockNum) - require.Falsef(t, result, "Found unexpected log %v in block %v with hash %v", logIdx, blockNum, logHash) - require.LessOrEqual(t, m.entriesReadForSearch, int64(searchCheckpointFrequency), "Should not need to read more than between two checkpoints") - - _, err = db.Executes(blockNum, logIdx) - require.ErrorIs(t, err, ErrNotFound, "Found unexpected log when getting executing message") - require.LessOrEqual(t, m.entriesReadForSearch, int64(searchCheckpointFrequency), "Should not need to read more than between two checkpoints") + _, err := db.Contains(blockNum, logIdx, types.TruncateHash(logHash)) + require.ErrorIs(t, err, ErrConflict, "canonical chain must not include this log") + require.LessOrEqual(t, m.entriesReadForSearch, int64(searchCheckpointFrequency*2), "Should not need to read more than between two checkpoints") } -func requireExecutingMessage(t *testing.T, db *DB, blockNum uint64, logIdx uint32, execMsg types.ExecutingMessage) { +func requireFuture(t *testing.T, db *DB, blockNum uint64, logIdx uint32, logHash common.Hash) { m, ok := db.m.(*stubMetrics) require.True(t, ok, "Did not get the expected metrics type") - actualExecMsg, err := db.Executes(blockNum, logIdx) - require.NoError(t, err, "Error when searching for executing message") - require.Equal(t, execMsg, actualExecMsg, "Should return matching executing message") - require.LessOrEqual(t, m.entriesReadForSearch, int64(searchCheckpointFrequency), "Should not need to read more than between two checkpoints") - require.NotZero(t, m.entriesReadForSearch, "Must read at least some entries to find the log") + _, err := db.Contains(blockNum, logIdx, types.TruncateHash(logHash)) + require.ErrorIs(t, err, ErrFuture, "canonical chain does not yet include this log") + require.LessOrEqual(t, m.entriesReadForSearch, int64(searchCheckpointFrequency*2), "Should not need to read more than between two checkpoints") } -func requireWrongHash(t *testing.T, db *DB, blockNum uint64, logIdx uint32, logHash common.Hash, _ types.ExecutingMessage) { +func requireExecutingMessage(t *testing.T, db *DB, blockNum uint64, logIdx uint32, execMsg types.ExecutingMessage) { m, ok := db.m.(*stubMetrics) require.True(t, ok, "Did not get the expected metrics type") - result, _, err := db.Contains(blockNum, logIdx, types.TruncateHash(logHash)) - require.NoErrorf(t, err, "Error searching for log %v in block %v", logIdx, blockNum) - require.Falsef(t, result, "Found unexpected log %v in block %v with hash %v", logIdx, blockNum, logHash) - - _, err = db.Executes(blockNum, logIdx) + _, iter, err := db.findLogInfo(blockNum, logIdx) require.NoError(t, err, "Error when searching for executing message") - require.LessOrEqual(t, m.entriesReadForSearch, int64(searchCheckpointFrequency), "Should not need to read more than between two checkpoints") + actualExecMsg := iter.ExecMessage() // non-nil if not just an initiating message, but also an executing message + if execMsg == (types.ExecutingMessage{}) { + require.Nil(t, actualExecMsg) + } else { + require.NotNil(t, actualExecMsg) + require.Equal(t, execMsg, *actualExecMsg, "Should return matching executing message") + } + require.LessOrEqual(t, m.entriesReadForSearch, int64(searchCheckpointFrequency*2), "Should not need to read more than between two checkpoints") + require.NotZero(t, m.entriesReadForSearch, "Must read at least some entries to find the log") } func TestRecoverOnCreate(t *testing.T) { createDb := func(t *testing.T, store *stubEntryStore) (*DB, *stubMetrics, error) { logger := testlog.Logger(t, log.LvlInfo) m := &stubMetrics{} - db, err := NewFromEntryStore(logger, m, store) + db, err := NewFromEntryStore(logger, m, store, true) return db, m, err } - validInitEvent, err := newInitiatingEvent(logContext{blockNum: 1, logIdx: 0}, 1, 0, createTruncatedHash(1), false) - require.NoError(t, err) - validEventSequence := []entrydb.Entry{ - newSearchCheckpoint(1, 0, 100).encode(), - newCanonicalHash(createTruncatedHash(344)).encode(), - validInitEvent.encode(), + storeWithEvents := func(evts ...entrydb.Entry) *stubEntryStore { + store := &stubEntryStore{} + store.entries = append(store.entries, evts...) + return store } - var emptyEventSequence []entrydb.Entry - - for _, prefixEvents := range [][]entrydb.Entry{emptyEventSequence, validEventSequence} { - prefixEvents := prefixEvents - storeWithEvents := func(evts ...entrydb.Entry) *stubEntryStore { - store := &stubEntryStore{} - store.entries = append(store.entries, prefixEvents...) - store.entries = append(store.entries, evts...) - return store + t.Run("NoTruncateWhenLastEntryIsLogWithNoExecMessageSealed", func(t *testing.T) { + store := storeWithEvents( + // seal 0, 1, 2, 3 + newSearchCheckpoint(0, 0, 100).encode(), + newCanonicalHash(createTruncatedHash(300)).encode(), + newSearchCheckpoint(1, 0, 101).encode(), + newCanonicalHash(createTruncatedHash(301)).encode(), + newSearchCheckpoint(2, 0, 102).encode(), + newCanonicalHash(createTruncatedHash(302)).encode(), + newSearchCheckpoint(3, 0, 103).encode(), + newCanonicalHash(createTruncatedHash(303)).encode(), + // open and seal 4 + newInitiatingEvent(createTruncatedHash(1), false).encode(), + newSearchCheckpoint(4, 0, 104).encode(), + newCanonicalHash(createTruncatedHash(304)).encode(), + ) + db, m, err := createDb(t, store) + require.NoError(t, err) + require.EqualValues(t, int64(4*2+3), m.entryCount) + requireContains(t, db, 4, 0, createHash(1)) + }) + + t.Run("NoTruncateWhenLastEntryIsExecutingCheckSealed", func(t *testing.T) { + execMsg := types.ExecutingMessage{ + Chain: 4, + BlockNum: 10, + LogIdx: 4, + Timestamp: 1288, + Hash: createTruncatedHash(4), } - t.Run(fmt.Sprintf("PrefixEvents-%v", len(prefixEvents)), func(t *testing.T) { - t.Run("NoTruncateWhenLastEntryIsLogWithNoExecMessage", func(t *testing.T) { - initEvent, err := newInitiatingEvent(logContext{blockNum: 3, logIdx: 0}, 3, 0, createTruncatedHash(1), false) - require.NoError(t, err) - store := storeWithEvents( - newSearchCheckpoint(3, 0, 100).encode(), - newCanonicalHash(createTruncatedHash(344)).encode(), - initEvent.encode(), - ) - db, m, err := createDb(t, store) - require.NoError(t, err) - require.EqualValues(t, len(prefixEvents)+3, m.entryCount) - requireContains(t, db, 3, 0, createHash(1)) - }) + linkEvt, err := newExecutingLink(execMsg) + require.NoError(t, err) + store := storeWithEvents( + newSearchCheckpoint(0, 0, 100).encode(), + newCanonicalHash(createTruncatedHash(300)).encode(), + newSearchCheckpoint(1, 0, 101).encode(), + newCanonicalHash(createTruncatedHash(301)).encode(), + newSearchCheckpoint(2, 0, 102).encode(), + newCanonicalHash(createTruncatedHash(302)).encode(), + newInitiatingEvent(createTruncatedHash(1111), true).encode(), + linkEvt.encode(), + newExecutingCheck(execMsg.Hash).encode(), + newSearchCheckpoint(3, 0, 103).encode(), + newCanonicalHash(createTruncatedHash(303)).encode(), + ) + db, m, err := createDb(t, store) + require.NoError(t, err) + require.EqualValues(t, int64(3*2+5), m.entryCount) + requireContains(t, db, 3, 0, createHash(1111), execMsg) + }) - t.Run("NoTruncateWhenLastEntryIsExecutingCheck", func(t *testing.T) { - initEvent, err := newInitiatingEvent(logContext{blockNum: 3, logIdx: 0}, 3, 0, createTruncatedHash(1), true) - execMsg := types.ExecutingMessage{ - Chain: 4, - BlockNum: 10, - LogIdx: 4, - Timestamp: 1288, - Hash: createTruncatedHash(4), - } - require.NoError(t, err) - linkEvt, err := newExecutingLink(execMsg) - require.NoError(t, err) - store := storeWithEvents( - newSearchCheckpoint(3, 0, 100).encode(), - newCanonicalHash(createTruncatedHash(344)).encode(), - initEvent.encode(), - linkEvt.encode(), - newExecutingCheck(execMsg.Hash).encode(), - ) - db, m, err := createDb(t, store) - require.NoError(t, err) - require.EqualValues(t, len(prefixEvents)+5, m.entryCount) - requireContains(t, db, 3, 0, createHash(1), execMsg) - }) + t.Run("TruncateWhenLastEntrySearchCheckpoint", func(t *testing.T) { + // A checkpoint, without a canonical blockhash, is useless, and thus truncated. + store := storeWithEvents( + newSearchCheckpoint(0, 0, 100).encode()) + _, m, err := createDb(t, store) + require.NoError(t, err) + require.EqualValues(t, int64(0), m.entryCount) + }) - t.Run("TruncateWhenLastEntrySearchCheckpoint", func(t *testing.T) { - store := storeWithEvents(newSearchCheckpoint(3, 0, 100).encode()) - _, m, err := createDb(t, store) - require.NoError(t, err) - require.EqualValues(t, len(prefixEvents), m.entryCount) - }) + t.Run("NoTruncateWhenLastEntryCanonicalHash", func(t *testing.T) { + // A completed seal is fine to have as last entry. + store := storeWithEvents( + newSearchCheckpoint(0, 0, 100).encode(), + newCanonicalHash(createTruncatedHash(344)).encode(), + ) + _, m, err := createDb(t, store) + require.NoError(t, err) + require.EqualValues(t, int64(2), m.entryCount) + }) - t.Run("TruncateWhenLastEntryCanonicalHash", func(t *testing.T) { - store := storeWithEvents( - newSearchCheckpoint(3, 0, 100).encode(), - newCanonicalHash(createTruncatedHash(344)).encode(), - ) - _, m, err := createDb(t, store) - require.NoError(t, err) - require.EqualValues(t, len(prefixEvents), m.entryCount) - }) + t.Run("TruncateWhenLastEntryInitEventWithExecMsg", func(t *testing.T) { + // An initiating event that claims an executing message, + // without said executing message, is dropped. + store := storeWithEvents( + newSearchCheckpoint(0, 0, 100).encode(), + newCanonicalHash(createTruncatedHash(344)).encode(), + // both pruned because we go back to a seal + newInitiatingEvent(createTruncatedHash(0), false).encode(), + newInitiatingEvent(createTruncatedHash(1), true).encode(), + ) + _, m, err := createDb(t, store) + require.NoError(t, err) + require.EqualValues(t, int64(2), m.entryCount) + }) - t.Run("TruncateWhenLastEntryInitEventWithExecMsg", func(t *testing.T) { - initEvent, err := newInitiatingEvent(logContext{blockNum: 3, logIdx: 0}, 3, 0, createTruncatedHash(1), true) - require.NoError(t, err) - store := storeWithEvents( - newSearchCheckpoint(3, 0, 100).encode(), - newCanonicalHash(createTruncatedHash(344)).encode(), - initEvent.encode(), - ) - _, m, err := createDb(t, store) - require.NoError(t, err) - require.EqualValues(t, len(prefixEvents), m.entryCount) - }) + t.Run("NoTruncateWhenLastEntrySealed", func(t *testing.T) { + // An initiating event that claims an executing message, + // without said executing message, is dropped. + store := storeWithEvents( + newSearchCheckpoint(0, 0, 100).encode(), + newCanonicalHash(createTruncatedHash(300)).encode(), + // pruned because we go back to a seal + newInitiatingEvent(createTruncatedHash(0), false).encode(), + newSearchCheckpoint(1, 0, 100).encode(), + newCanonicalHash(createTruncatedHash(301)).encode(), + ) + _, m, err := createDb(t, store) + require.NoError(t, err) + require.EqualValues(t, int64(5), m.entryCount) + }) - t.Run("TruncateWhenLastEntryInitEventWithExecLink", func(t *testing.T) { - initEvent, err := newInitiatingEvent(logContext{blockNum: 3, logIdx: 0}, 3, 0, createTruncatedHash(1), true) - require.NoError(t, err) - execMsg := types.ExecutingMessage{ - Chain: 4, - BlockNum: 10, - LogIdx: 4, - Timestamp: 1288, - Hash: createTruncatedHash(4), - } - require.NoError(t, err) - linkEvt, err := newExecutingLink(execMsg) - require.NoError(t, err) - store := storeWithEvents( - newSearchCheckpoint(3, 0, 100).encode(), - newCanonicalHash(createTruncatedHash(344)).encode(), - initEvent.encode(), - linkEvt.encode(), - ) - _, m, err := createDb(t, store) - require.NoError(t, err) - require.EqualValues(t, len(prefixEvents), m.entryCount) - }) - }) - } + t.Run("TruncateWhenLastEntryInitEventWithExecLink", func(t *testing.T) { + execMsg := types.ExecutingMessage{ + Chain: 4, + BlockNum: 10, + LogIdx: 4, + Timestamp: 1288, + Hash: createTruncatedHash(4), + } + linkEvt, err := newExecutingLink(execMsg) + require.NoError(t, err) + store := storeWithEvents( + newSearchCheckpoint(3, 0, 100).encode(), + newCanonicalHash(createTruncatedHash(344)).encode(), + newInitiatingEvent(createTruncatedHash(1), true).encode(), + linkEvt.encode(), + ) + _, m, err := createDb(t, store) + require.NoError(t, err) + require.EqualValues(t, int64(2), m.entryCount) + }) } func TestRewind(t *testing.T) { t.Run("WhenEmpty", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) {}, func(t *testing.T, db *DB, m *stubMetrics) { - require.NoError(t, db.Rewind(100)) - require.NoError(t, db.Rewind(0)) + require.ErrorIs(t, db.Rewind(100), ErrFuture) + // Genesis is a block to, not present in an empty DB + require.ErrorIs(t, db.Rewind(0), ErrFuture) }) }) t.Run("AfterLastBlock", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(50), Number: 50}, 500, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(50), Number: 50}, 500, 1, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(3), eth.BlockID{Hash: createHash(51), Number: 51}, 502, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(4), eth.BlockID{Hash: createHash(74), Number: 74}, 700, 0, nil)) - require.NoError(t, db.Rewind(75)) + bl50 := eth.BlockID{Hash: createHash(50), Number: 50} + require.NoError(t, db.SealBlock(createHash(49), bl50, 500)) + require.NoError(t, db.AddLog(createTruncatedHash(1), bl50, 0, nil)) + require.NoError(t, db.AddLog(createTruncatedHash(2), bl50, 1, nil)) + bl51 := eth.BlockID{Hash: createHash(51), Number: 51} + require.NoError(t, db.SealBlock(bl50.Hash, bl51, 502)) + require.NoError(t, db.AddLog(createTruncatedHash(3), bl51, 0, nil)) + bl52 := eth.BlockID{Hash: createHash(52), Number: 52} + require.NoError(t, db.SealBlock(bl51.Hash, bl52, 504)) + require.NoError(t, db.AddLog(createTruncatedHash(4), bl52, 0, nil)) + // cannot rewind to a block that is not sealed yet + require.ErrorIs(t, db.Rewind(53), ErrFuture) }, func(t *testing.T, db *DB, m *stubMetrics) { - requireContains(t, db, 50, 0, createHash(1)) - requireContains(t, db, 50, 1, createHash(2)) - requireContains(t, db, 51, 0, createHash(3)) - requireContains(t, db, 74, 0, createHash(4)) + requireContains(t, db, 51, 0, createHash(1)) + requireContains(t, db, 51, 1, createHash(2)) + requireContains(t, db, 52, 0, createHash(3)) + // Still have the pending log of unsealed block if the rewind to unknown sealed block fails + requireContains(t, db, 53, 0, createHash(4)) }) }) t.Run("BeforeFirstBlock", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(50), Number: 50}, 500, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(50), Number: 50}, 500, 1, nil)) - require.NoError(t, db.Rewind(25)) + bl50 := eth.BlockID{Hash: createHash(50), Number: 50} + require.NoError(t, db.SealBlock(createHash(49), bl50, 500)) + require.NoError(t, db.AddLog(createTruncatedHash(1), bl50, 0, nil)) + require.NoError(t, db.AddLog(createTruncatedHash(2), bl50, 1, nil)) + // cannot go back to an unknown block + require.ErrorIs(t, db.Rewind(25), ErrSkipped) }, func(t *testing.T, db *DB, m *stubMetrics) { - requireNotContains(t, db, 50, 0, createHash(1)) - requireNotContains(t, db, 50, 0, createHash(1)) - require.Zero(t, m.entryCount) + requireContains(t, db, 51, 0, createHash(1)) + requireContains(t, db, 51, 0, createHash(1)) }) }) t.Run("AtFirstBlock", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(50), Number: 50}, 500, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(50), Number: 50}, 500, 1, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(51), Number: 51}, 502, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(51), Number: 51}, 502, 1, nil)) - require.NoError(t, db.Rewind(50)) + bl50 := eth.BlockID{Hash: createHash(50), Number: 50} + require.NoError(t, db.SealBlock(createHash(49), bl50, 500)) + require.NoError(t, db.AddLog(createTruncatedHash(1), bl50, 0, nil)) + require.NoError(t, db.AddLog(createTruncatedHash(2), bl50, 1, nil)) + bl51 := eth.BlockID{Hash: createHash(51), Number: 51} + require.NoError(t, db.SealBlock(bl50.Hash, bl51, 502)) + require.NoError(t, db.AddLog(createTruncatedHash(1), bl51, 0, nil)) + require.NoError(t, db.AddLog(createTruncatedHash(2), bl51, 1, nil)) + bl52 := eth.BlockID{Hash: createHash(52), Number: 52} + require.NoError(t, db.SealBlock(bl51.Hash, bl52, 504)) + require.NoError(t, db.Rewind(51)) }, func(t *testing.T, db *DB, m *stubMetrics) { - requireContains(t, db, 50, 0, createHash(1)) - requireContains(t, db, 50, 1, createHash(2)) - requireNotContains(t, db, 51, 0, createHash(1)) - requireNotContains(t, db, 51, 1, createHash(2)) + requireContains(t, db, 51, 0, createHash(1)) + requireContains(t, db, 51, 1, createHash(2)) + requireFuture(t, db, 52, 0, createHash(1)) + requireFuture(t, db, 52, 1, createHash(2)) }) }) - t.Run("AtSecondCheckpoint", func(t *testing.T) { + t.Run("AfterSecondCheckpoint", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { + bl50 := eth.BlockID{Hash: createHash(50), Number: 50} + require.NoError(t, db.SealBlock(createHash(49), bl50, 500)) for i := uint32(0); m.entryCount < searchCheckpointFrequency; i++ { - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(50), Number: 50}, 500, i, nil)) + require.NoError(t, db.AddLog(createTruncatedHash(1), bl50, i, nil)) } - require.EqualValues(t, searchCheckpointFrequency, m.entryCount) - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(51), Number: 51}, 502, 0, nil)) - require.EqualValues(t, searchCheckpointFrequency+3, m.entryCount, "Should have inserted new checkpoint and extra log") - require.NoError(t, db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(51), Number: 51}, 502, 1, nil)) - require.NoError(t, db.Rewind(50)) - }, - func(t *testing.T, db *DB, m *stubMetrics) { - require.EqualValues(t, searchCheckpointFrequency, m.entryCount, "Should have deleted second checkpoint") - requireContains(t, db, 50, 0, createHash(1)) - requireContains(t, db, 50, 1, createHash(1)) - requireNotContains(t, db, 51, 0, createHash(1)) - requireNotContains(t, db, 51, 1, createHash(2)) - }) - }) - - t.Run("BetweenLogEntries", func(t *testing.T) { - runDBTest(t, - func(t *testing.T, db *DB, m *stubMetrics) { - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(50), Number: 50}, 500, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(50), Number: 50}, 500, 1, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(60), Number: 60}, 502, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(60), Number: 60}, 502, 1, nil)) - require.NoError(t, db.Rewind(55)) + // The checkpoint is added automatically, + // it will be there as soon as it reaches 255 with log events. + // Thus add 2 for the checkpoint. + require.EqualValues(t, searchCheckpointFrequency+2, m.entryCount) + bl51 := eth.BlockID{Hash: createHash(51), Number: 51} + require.NoError(t, db.SealBlock(bl50.Hash, bl51, 502)) + require.NoError(t, db.AddLog(createTruncatedHash(1), bl51, 0, nil)) + require.EqualValues(t, searchCheckpointFrequency+2+3, m.entryCount, "Should have inserted new checkpoint and extra log") + require.NoError(t, db.AddLog(createTruncatedHash(2), bl51, 1, nil)) + bl52 := eth.BlockID{Hash: createHash(52), Number: 52} + require.NoError(t, db.SealBlock(bl51.Hash, bl52, 504)) + require.NoError(t, db.Rewind(51)) }, func(t *testing.T, db *DB, m *stubMetrics) { - requireContains(t, db, 50, 0, createHash(1)) - requireContains(t, db, 50, 1, createHash(2)) - requireNotContains(t, db, 60, 0, createHash(1)) - requireNotContains(t, db, 60, 1, createHash(2)) + require.EqualValues(t, searchCheckpointFrequency+2+2, m.entryCount, "Should have deleted second checkpoint") + requireContains(t, db, 51, 0, createHash(1)) + requireContains(t, db, 51, 1, createHash(1)) + requireFuture(t, db, 52, 0, createHash(1)) + requireFuture(t, db, 52, 1, createHash(2)) }) }) - t.Run("AtExistingLogEntry", func(t *testing.T) { + t.Run("BetweenBlockEntries", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(59), Number: 59}, 500, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(59), Number: 59}, 500, 1, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(60), Number: 60}, 502, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(60), Number: 60}, 502, 1, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(61), Number: 61}, 502, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(61), Number: 61}, 502, 1, nil)) - require.NoError(t, db.Rewind(60)) + // create many blocks, and all the odd blocks get 2 logs + for i := uint32(0); i < 30; i++ { + bl := eth.BlockID{Hash: createHash(int(i)), Number: uint64(i)} + require.NoError(t, db.SealBlock(createHash(int(i)-1), bl, 500+uint64(i))) + if i%2 == 0 { + require.NoError(t, db.AddLog(createTruncatedHash(1), bl, 0, nil)) + require.NoError(t, db.AddLog(createTruncatedHash(2), bl, 1, nil)) + } + } + require.NoError(t, db.Rewind(15)) }, func(t *testing.T, db *DB, m *stubMetrics) { - requireContains(t, db, 59, 0, createHash(1)) - requireContains(t, db, 59, 1, createHash(2)) - requireContains(t, db, 60, 0, createHash(1)) - requireContains(t, db, 60, 1, createHash(2)) - requireNotContains(t, db, 61, 0, createHash(1)) - requireNotContains(t, db, 61, 1, createHash(2)) + requireContains(t, db, 15, 0, createHash(1)) + requireContains(t, db, 15, 1, createHash(2)) + requireFuture(t, db, 16, 0, createHash(1)) + requireFuture(t, db, 16, 1, createHash(2)) }) }) t.Run("AtLastEntry", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(50), Number: 50}, 500, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(50), Number: 50}, 500, 1, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(60), Number: 60}, 502, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(60), Number: 60}, 502, 1, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(70), Number: 70}, 502, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(70), Number: 70}, 502, 1, nil)) - require.NoError(t, db.Rewind(70)) + // create many blocks, and all the even blocks get 2 logs + for i := uint32(0); i <= 30; i++ { + bl := eth.BlockID{Hash: createHash(int(i)), Number: uint64(i)} + require.NoError(t, db.SealBlock(createHash(int(i)-1), bl, 500+uint64(i))) + if i%2 == 1 { + require.NoError(t, db.AddLog(createTruncatedHash(1), bl, 0, nil)) + require.NoError(t, db.AddLog(createTruncatedHash(2), bl, 1, nil)) + } + } + // We ended at 30, and sealed it, nothing left to prune + require.NoError(t, db.Rewind(30)) }, func(t *testing.T, db *DB, m *stubMetrics) { - requireContains(t, db, 50, 0, createHash(1)) - requireContains(t, db, 50, 1, createHash(2)) - requireContains(t, db, 60, 0, createHash(1)) - requireContains(t, db, 60, 1, createHash(2)) - requireContains(t, db, 70, 0, createHash(1)) - requireContains(t, db, 70, 1, createHash(2)) + requireContains(t, db, 20, 0, createHash(1)) + requireContains(t, db, 20, 1, createHash(2)) + // built on top of 29, these are in sealed block 30, still around + requireContains(t, db, 30, 0, createHash(1)) + requireContains(t, db, 30, 1, createHash(2)) }) }) - t.Run("ReaddDeletedBlocks", func(t *testing.T) { + t.Run("ReadDeletedBlocks", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(59), Number: 59}, 500, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(59), Number: 59}, 500, 1, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(60), Number: 60}, 502, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(60), Number: 60}, 502, 1, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(61), Number: 61}, 502, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(61), Number: 61}, 502, 1, nil)) - require.NoError(t, db.Rewind(60)) + // create many blocks, and all the odd blocks get 2 logs + for i := uint32(0); i < 30; i++ { + bl := eth.BlockID{Hash: createHash(int(i)), Number: uint64(i)} + require.NoError(t, db.SealBlock(createHash(int(i)-1), bl, 500+uint64(i))) + if i%2 == 0 { + require.NoError(t, db.AddLog(createTruncatedHash(1), bl, 0, nil)) + require.NoError(t, db.AddLog(createTruncatedHash(2), bl, 1, nil)) + } + } + require.NoError(t, db.Rewind(16)) }, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(59), Number: 59}, 500, 1, nil) - require.ErrorIs(t, err, ErrLogOutOfOrder, "Cannot add block before rewound head") - err = db.AddLog(createTruncatedHash(2), eth.BlockID{Hash: createHash(60), Number: 60}, 502, 1, nil) - require.ErrorIs(t, err, ErrLogOutOfOrder, "Cannot add block that was rewound to") - err = db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(60), Number: 61}, 502, 0, nil) - require.NoError(t, err, "Can re-add deleted block") + bl29 := eth.BlockID{Hash: createHash(29), Number: 29} + // 29 was deleted + err := db.AddLog(createTruncatedHash(2), bl29, 1, nil) + require.ErrorIs(t, err, ErrLogOutOfOrder, "Cannot add log on removed block") + // 15 is older, we have up to 16 + bl15 := eth.BlockID{Hash: createHash(15), Number: 15} + // try to add a third log to 15 + err = db.AddLog(createTruncatedHash(10), bl15, 2, nil) + require.ErrorIs(t, err, ErrLogOutOfOrder) + bl16 := eth.BlockID{Hash: createHash(16), Number: 16} + // try to add a log to 17, on top of 16 + err = db.AddLog(createTruncatedHash(42), bl16, 0, nil) + require.NoError(t, err) + requireContains(t, db, 17, 0, createHash(42)) }) }) } diff --git a/op-supervisor/supervisor/backend/db/logs/entries.go b/op-supervisor/supervisor/backend/db/logs/entries.go index 8816474cdd2f..5dbc1e3b4816 100644 --- a/op-supervisor/supervisor/backend/db/logs/entries.go +++ b/op-supervisor/supervisor/backend/db/logs/entries.go @@ -3,44 +3,46 @@ package logs import ( "encoding/binary" "fmt" - "math" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" ) +// searchCheckpoint is both a checkpoint for searching, as well as a checkpoint for sealing blocks. type searchCheckpoint struct { - blockNum uint64 - logIdx uint32 + blockNum uint64 + // seen logs *after* the seal of the mentioned block, i.e. not part of this block, but building on top of it. + // There is at least one checkpoint per L2 block with logsSince == 0, i.e. the exact block boundary. + logsSince uint32 timestamp uint64 } -func newSearchCheckpoint(blockNum uint64, logIdx uint32, timestamp uint64) searchCheckpoint { +func newSearchCheckpoint(blockNum uint64, logsSince uint32, timestamp uint64) searchCheckpoint { return searchCheckpoint{ blockNum: blockNum, - logIdx: logIdx, + logsSince: logsSince, timestamp: timestamp, } } func newSearchCheckpointFromEntry(data entrydb.Entry) (searchCheckpoint, error) { - if data[0] != typeSearchCheckpoint { - return searchCheckpoint{}, fmt.Errorf("%w: attempting to decode search checkpoint but was type %v", ErrDataCorruption, data[0]) + if data.Type() != entrydb.TypeSearchCheckpoint { + return searchCheckpoint{}, fmt.Errorf("%w: attempting to decode search checkpoint but was type %s", ErrDataCorruption, data.Type()) } return searchCheckpoint{ blockNum: binary.LittleEndian.Uint64(data[1:9]), - logIdx: binary.LittleEndian.Uint32(data[9:13]), + logsSince: binary.LittleEndian.Uint32(data[9:13]), timestamp: binary.LittleEndian.Uint64(data[13:21]), }, nil } -// encode creates a search checkpoint entry -// type 0: "search checkpoint" <type><uint64 block number: 8 bytes><uint32 event index offset: 4 bytes><uint64 timestamp: 8 bytes> = 20 bytes +// encode creates a checkpoint entry +// type 0: "search checkpoint" <type><uint64 block number: 8 bytes><uint32 logsSince count: 4 bytes><uint64 timestamp: 8 bytes> = 21 bytes func (s searchCheckpoint) encode() entrydb.Entry { var data entrydb.Entry - data[0] = typeSearchCheckpoint + data[0] = uint8(entrydb.TypeSearchCheckpoint) binary.LittleEndian.PutUint64(data[1:9], s.blockNum) - binary.LittleEndian.PutUint32(data[9:13], s.logIdx) + binary.LittleEndian.PutUint32(data[9:13], s.logsSince) binary.LittleEndian.PutUint64(data[13:21], s.timestamp) return data } @@ -54,8 +56,8 @@ func newCanonicalHash(hash types.TruncatedHash) canonicalHash { } func newCanonicalHashFromEntry(data entrydb.Entry) (canonicalHash, error) { - if data[0] != typeCanonicalHash { - return canonicalHash{}, fmt.Errorf("%w: attempting to decode canonical hash but was type %v", ErrDataCorruption, data[0]) + if data.Type() != entrydb.TypeCanonicalHash { + return canonicalHash{}, fmt.Errorf("%w: attempting to decode canonical hash but was type %s", ErrDataCorruption, data.Type()) } var truncated types.TruncatedHash copy(truncated[:], data[1:21]) @@ -64,100 +66,48 @@ func newCanonicalHashFromEntry(data entrydb.Entry) (canonicalHash, error) { func (c canonicalHash) encode() entrydb.Entry { var entry entrydb.Entry - entry[0] = typeCanonicalHash + entry[0] = uint8(entrydb.TypeCanonicalHash) copy(entry[1:21], c.hash[:]) return entry } type initiatingEvent struct { - blockDiff uint8 - incrementLogIdx bool - hasExecMsg bool - logHash types.TruncatedHash + hasExecMsg bool + logHash types.TruncatedHash } func newInitiatingEventFromEntry(data entrydb.Entry) (initiatingEvent, error) { - if data[0] != typeInitiatingEvent { - return initiatingEvent{}, fmt.Errorf("%w: attempting to decode initiating event but was type %v", ErrDataCorruption, data[0]) + if data.Type() != entrydb.TypeInitiatingEvent { + return initiatingEvent{}, fmt.Errorf("%w: attempting to decode initiating event but was type %s", ErrDataCorruption, data.Type()) } - blockNumDiff := data[1] - flags := data[2] + flags := data[1] return initiatingEvent{ - blockDiff: blockNumDiff, - incrementLogIdx: flags&eventFlagIncrementLogIdx != 0, - hasExecMsg: flags&eventFlagHasExecutingMessage != 0, - logHash: types.TruncatedHash(data[3:23]), + hasExecMsg: flags&eventFlagHasExecutingMessage != 0, + logHash: types.TruncatedHash(data[2:22]), }, nil } -func newInitiatingEvent(pre logContext, blockNum uint64, logIdx uint32, logHash types.TruncatedHash, hasExecMsg bool) (initiatingEvent, error) { - blockDiff := blockNum - pre.blockNum - if blockDiff > math.MaxUint8 { - // TODO(optimism#11091): Need to find a way to support this. - return initiatingEvent{}, fmt.Errorf("too many block skipped between %v and %v", pre.blockNum, blockNum) - } - - currLogIdx := pre.logIdx - if blockDiff > 0 { - currLogIdx = 0 - } - logDiff := logIdx - currLogIdx - if logDiff > 1 { - return initiatingEvent{}, fmt.Errorf("skipped logs between %v and %v", currLogIdx, logIdx) - } - +func newInitiatingEvent(logHash types.TruncatedHash, hasExecMsg bool) initiatingEvent { return initiatingEvent{ - blockDiff: uint8(blockDiff), - incrementLogIdx: logDiff > 0, - hasExecMsg: hasExecMsg, - logHash: logHash, - }, nil + hasExecMsg: hasExecMsg, + logHash: logHash, + } } // encode creates an initiating event entry -// type 2: "initiating event" <type><blocknum diff: 1 byte><event flags: 1 byte><event-hash: 20 bytes> = 23 bytes +// type 2: "initiating event" <type><flags><event-hash: 20 bytes> = 22 bytes func (i initiatingEvent) encode() entrydb.Entry { var data entrydb.Entry - data[0] = typeInitiatingEvent - data[1] = i.blockDiff + data[0] = uint8(entrydb.TypeInitiatingEvent) flags := byte(0) - if i.incrementLogIdx { - // Set flag to indicate log idx needs to be incremented (ie we're not directly after a checkpoint) - flags = flags | eventFlagIncrementLogIdx - } if i.hasExecMsg { flags = flags | eventFlagHasExecutingMessage } - data[2] = flags - copy(data[3:23], i.logHash[:]) + data[1] = flags + copy(data[2:22], i.logHash[:]) return data } -func (i initiatingEvent) postContext(pre logContext) logContext { - post := logContext{ - blockNum: pre.blockNum + uint64(i.blockDiff), - logIdx: pre.logIdx, - } - if i.blockDiff > 0 { - post.logIdx = 0 - } - if i.incrementLogIdx { - post.logIdx++ - } - return post -} - -// preContext is the reverse of postContext and calculates the logContext required as input to get the specified post -// context after applying this init event. -func (i initiatingEvent) preContext(post logContext) logContext { - pre := post - pre.blockNum = post.blockNum - uint64(i.blockDiff) - if i.incrementLogIdx { - pre.logIdx-- - } - return pre -} - type executingLink struct { chain uint32 blockNum uint64 @@ -178,8 +128,8 @@ func newExecutingLink(msg types.ExecutingMessage) (executingLink, error) { } func newExecutingLinkFromEntry(data entrydb.Entry) (executingLink, error) { - if data[0] != typeExecutingLink { - return executingLink{}, fmt.Errorf("%w: attempting to decode executing link but was type %v", ErrDataCorruption, data[0]) + if data.Type() != entrydb.TypeExecutingLink { + return executingLink{}, fmt.Errorf("%w: attempting to decode executing link but was type %s", ErrDataCorruption, data.Type()) } timestamp := binary.LittleEndian.Uint64(data[16:24]) return executingLink{ @@ -194,7 +144,7 @@ func newExecutingLinkFromEntry(data entrydb.Entry) (executingLink, error) { // type 3: "executing link" <type><chain: 4 bytes><blocknum: 8 bytes><event index: 3 bytes><uint64 timestamp: 8 bytes> = 24 bytes func (e executingLink) encode() entrydb.Entry { var entry entrydb.Entry - entry[0] = typeExecutingLink + entry[0] = uint8(entrydb.TypeExecutingLink) binary.LittleEndian.PutUint32(entry[1:5], e.chain) binary.LittleEndian.PutUint64(entry[5:13], e.blockNum) @@ -214,12 +164,12 @@ func newExecutingCheck(hash types.TruncatedHash) executingCheck { return executingCheck{hash: hash} } -func newExecutingCheckFromEntry(entry entrydb.Entry) (executingCheck, error) { - if entry[0] != typeExecutingCheck { - return executingCheck{}, fmt.Errorf("%w: attempting to decode executing check but was type %v", ErrDataCorruption, entry[0]) +func newExecutingCheckFromEntry(data entrydb.Entry) (executingCheck, error) { + if data.Type() != entrydb.TypeExecutingCheck { + return executingCheck{}, fmt.Errorf("%w: attempting to decode executing check but was type %s", ErrDataCorruption, data.Type()) } var hash types.TruncatedHash - copy(hash[:], entry[1:21]) + copy(hash[:], data[1:21]) return newExecutingCheck(hash), nil } @@ -227,25 +177,17 @@ func newExecutingCheckFromEntry(entry entrydb.Entry) (executingCheck, error) { // type 4: "executing check" <type><event-hash: 20 bytes> = 21 bytes func (e executingCheck) encode() entrydb.Entry { var entry entrydb.Entry - entry[0] = typeExecutingCheck + entry[0] = uint8(entrydb.TypeExecutingCheck) copy(entry[1:21], e.hash[:]) return entry } -func newExecutingMessageFromEntries(linkEntry entrydb.Entry, checkEntry entrydb.Entry) (types.ExecutingMessage, error) { - link, err := newExecutingLinkFromEntry(linkEntry) - if err != nil { - return types.ExecutingMessage{}, fmt.Errorf("invalid executing link: %w", err) - } - check, err := newExecutingCheckFromEntry(checkEntry) - if err != nil { - return types.ExecutingMessage{}, fmt.Errorf("invalid executing check: %w", err) - } - return types.ExecutingMessage{ - Chain: link.chain, - BlockNum: link.blockNum, - LogIdx: link.logIdx, - Timestamp: link.timestamp, - Hash: check.hash, - }, nil +type paddingEntry struct{} + +// encoding of the padding entry +// type 5: "padding" <type><padding: 23 bytes> = 24 bytes +func (e paddingEntry) encode() entrydb.Entry { + var entry entrydb.Entry + entry[0] = uint8(entrydb.TypePadding) + return entry } diff --git a/op-supervisor/supervisor/backend/db/logs/iterator.go b/op-supervisor/supervisor/backend/db/logs/iterator.go index 7312966b2455..29b47245e71c 100644 --- a/op-supervisor/supervisor/backend/db/logs/iterator.go +++ b/op-supervisor/supervisor/backend/db/logs/iterator.go @@ -9,106 +9,134 @@ import ( "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" ) +type IteratorState interface { + NextIndex() entrydb.EntryIdx + SealedBlock() (hash types.TruncatedHash, num uint64, ok bool) + InitMessage() (hash types.TruncatedHash, logIndex uint32, ok bool) + ExecMessage() *types.ExecutingMessage +} + type Iterator interface { - NextLog() (blockNum uint64, logIdx uint32, evtHash types.TruncatedHash, outErr error) - Index() entrydb.EntryIdx - ExecMessage() (types.ExecutingMessage, error) + End() error + NextInitMsg() error + NextExecMsg() error + NextBlock() error + IteratorState } type iterator struct { - db *DB - nextEntryIdx entrydb.EntryIdx - - current logContext - hasExecMsg bool - + db *DB + current logContext entriesRead int64 } -// NextLog returns the next log in the iterator. -// It scans forward until it finds an initiating event, returning the block number, log index, and event hash. -func (i *iterator) NextLog() (blockNum uint64, logIdx uint32, evtHash types.TruncatedHash, outErr error) { - for i.nextEntryIdx <= i.db.lastEntryIdx() { - entryIdx := i.nextEntryIdx - entry, err := i.db.store.Read(entryIdx) +// End traverses the iterator to the end of the DB. +// It does not return io.EOF or ErrFuture. +func (i *iterator) End() error { + for { + _, err := i.next() + if errors.Is(err, ErrFuture) { + return nil + } else if err != nil { + return err + } + } +} + +// NextInitMsg returns the next initiating message in the iterator. +// It scans forward until it finds and fully reads an initiating event, skipping any blocks. +func (i *iterator) NextInitMsg() error { + seenLog := false + for { + typ, err := i.next() if err != nil { - outErr = fmt.Errorf("failed to read entry %v: %w", i, err) - return + return err + } + if typ == entrydb.TypeInitiatingEvent { + seenLog = true } - i.nextEntryIdx++ - i.entriesRead++ - i.hasExecMsg = false - switch entry[0] { - case typeSearchCheckpoint: - current, err := newSearchCheckpointFromEntry(entry) - if err != nil { - outErr = fmt.Errorf("failed to parse search checkpoint at idx %v: %w", entryIdx, err) - return - } - i.current.blockNum = current.blockNum - i.current.logIdx = current.logIdx - case typeInitiatingEvent: - evt, err := newInitiatingEventFromEntry(entry) - if err != nil { - outErr = fmt.Errorf("failed to parse initiating event at idx %v: %w", entryIdx, err) - return - } - i.current = evt.postContext(i.current) - blockNum = i.current.blockNum - logIdx = i.current.logIdx - evtHash = evt.logHash - i.hasExecMsg = evt.hasExecMsg - return - case typeCanonicalHash: // Skip - case typeExecutingCheck: // Skip - case typeExecutingLink: // Skip - default: - outErr = fmt.Errorf("unknown entry type at idx %v %v", entryIdx, entry[0]) - return + if !i.current.hasCompleteBlock() { + continue // must know the block we're building on top of + } + if i.current.hasIncompleteLog() { + continue // didn't finish processing the log yet + } + if seenLog { + return nil } } - outErr = io.EOF - return } -func (i *iterator) Index() entrydb.EntryIdx { - return i.nextEntryIdx - 1 +// NextExecMsg returns the next executing message in the iterator. +// It scans forward until it finds and fully reads an initiating event, skipping any blocks. +// This does not stay at the executing message of the current initiating message, if there is any. +func (i *iterator) NextExecMsg() error { + for { + err := i.NextInitMsg() + if err != nil { + return err + } + if i.current.execMsg != nil { + return nil // found a new executing message! + } + } } -func (i *iterator) ExecMessage() (types.ExecutingMessage, error) { - if !i.hasExecMsg { - return types.ExecutingMessage{}, nil - } - // Look ahead to find the exec message info - logEntryIdx := i.nextEntryIdx - 1 - execMsg, err := i.readExecMessage(logEntryIdx) - if err != nil { - return types.ExecutingMessage{}, fmt.Errorf("failed to read exec message for initiating event at %v: %w", logEntryIdx, err) +// NextBlock returns the next block in the iterator. +// It scans forward until it finds and fully reads a block, skipping any events. +func (i *iterator) NextBlock() error { + seenBlock := false + for { + typ, err := i.next() + if err != nil { + return err + } + if typ == entrydb.TypeSearchCheckpoint { + seenBlock = true + } + if !i.current.hasCompleteBlock() { + continue // need the full block content + } + if seenBlock { + return nil + } } - return execMsg, nil } -func (i *iterator) readExecMessage(initEntryIdx entrydb.EntryIdx) (types.ExecutingMessage, error) { - linkIdx := initEntryIdx + 1 - if linkIdx%searchCheckpointFrequency == 0 { - linkIdx += 2 // skip the search checkpoint and canonical hash entries +// Read and apply the next entry. +func (i *iterator) next() (entrydb.EntryType, error) { + index := i.current.nextEntryIndex + entry, err := i.db.store.Read(index) + if err != nil { + if errors.Is(err, io.EOF) { + return 0, ErrFuture + } + return 0, fmt.Errorf("failed to read entry %d: %w", index, err) } - linkEntry, err := i.db.store.Read(linkIdx) - if errors.Is(err, io.EOF) { - return types.ExecutingMessage{}, fmt.Errorf("%w: missing expected executing link event at idx %v", ErrDataCorruption, linkIdx) - } else if err != nil { - return types.ExecutingMessage{}, fmt.Errorf("failed to read executing link event at idx %v: %w", linkIdx, err) + if err := i.current.ApplyEntry(entry); err != nil { + return entry.Type(), fmt.Errorf("failed to apply entry %d to iterator state: %w", index, err) } - checkIdx := linkIdx + 1 - if checkIdx%searchCheckpointFrequency == 0 { - checkIdx += 2 // skip the search checkpoint and canonical hash entries - } - checkEntry, err := i.db.store.Read(checkIdx) - if errors.Is(err, io.EOF) { - return types.ExecutingMessage{}, fmt.Errorf("%w: missing expected executing check event at idx %v", ErrDataCorruption, checkIdx) - } else if err != nil { - return types.ExecutingMessage{}, fmt.Errorf("failed to read executing check event at idx %v: %w", checkIdx, err) - } - return newExecutingMessageFromEntries(linkEntry, checkEntry) + i.entriesRead++ + return entry.Type(), nil +} + +func (i *iterator) NextIndex() entrydb.EntryIdx { + return i.current.NextIndex() +} + +// SealedBlock returns the sealed block that we are appending logs after, if any is available. +// I.e. the block is the parent block of the block containing the logs that are currently appending to it. +func (i *iterator) SealedBlock() (hash types.TruncatedHash, num uint64, ok bool) { + return i.current.SealedBlock() +} + +// InitMessage returns the current initiating message, if any is available. +func (i *iterator) InitMessage() (hash types.TruncatedHash, logIndex uint32, ok bool) { + return i.current.InitMessage() +} + +// ExecMessage returns the current executing message, if any is available. +func (i *iterator) ExecMessage() *types.ExecutingMessage { + return i.current.ExecMessage() } diff --git a/op-supervisor/supervisor/backend/db/logs/state.go b/op-supervisor/supervisor/backend/db/logs/state.go new file mode 100644 index 000000000000..083e07f97083 --- /dev/null +++ b/op-supervisor/supervisor/backend/db/logs/state.go @@ -0,0 +1,407 @@ +package logs + +import ( + "errors" + "fmt" + "io" + + "github.com/ethereum/go-ethereum/common" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" +) + +// logContext is a buffer on top of the DB, +// where blocks and logs can be applied to. +// +// Rules: +// +// if entry_index % 256 == 0: must be type 0. For easy binary search. +// else if end_of_block: also type 0. +// else: +// after type 0: type 1 +// after type 1: type 2 iff any event and space, otherwise type 0 +// after type 2: type 3 iff executing, otherwise type 2 or 0 +// after type 3: type 4 +// after type 4: type 2 iff any event and space, otherwise type 0 +// after type 5: any +// +// Type 0 can repeat: seal the block, then start a search checkpoint, then a single canonical hash. +// Type 0 may also be used as padding: type 2 only starts when it will not be interrupted by a search checkpoint. +// +// Types (<type> = 1 byte): +// type 0: "checkpoint" <type><uint64 block number: 8 bytes><uint32 logsSince count: 4 bytes><uint64 timestamp: 8 bytes> = 21 bytes +// type 1: "canonical hash" <type><parent blockhash truncated: 20 bytes> = 21 bytes +// type 2: "initiating event" <type><event flags: 1 byte><event-hash: 20 bytes> = 22 bytes +// type 3: "executing link" <type><chain: 4 bytes><blocknum: 8 bytes><event index: 3 bytes><uint64 timestamp: 8 bytes> = 24 bytes +// type 4: "executing check" <type><event-hash: 20 bytes> = 21 bytes +// type 5: "padding" <type><padding: 23 bytes> = 24 bytes +// other types: future compat. E.g. for linking to L1, registering block-headers as a kind of initiating-event, tracking safe-head progression, etc. +// +// Right-pad each entry that is not 24 bytes. +// +// We insert a checkpoint for every search interval and block sealing event, +// and these may overlap as the same thing. +// Such seal has logsSince == 0, i.e. wrapping up the last block and starting a fresh list of logs. +// +// event-flags: each bit represents a boolean value, currently only two are defined +// * event-flags & 0x01 - true if the initiating event has an executing link that should follow. Allows detecting when the executing link failed to write. +// event-hash: H(origin, timestamp, payloadhash); enough to check identifier matches & payload matches. +type logContext struct { + // next entry index, including the contents of `out` + nextEntryIndex entrydb.EntryIdx + + // blockHash of the last sealed block. + // A block is not considered sealed until we know its block hash. + // While we process logs we keep the parent-block of said logs around as sealed block. + blockHash types.TruncatedHash + // blockNum of the last sealed block + blockNum uint64 + // timestamp of the last sealed block + timestamp uint64 + + // number of logs since the last sealed block + logsSince uint32 + + // payload-hash of the log-event that was last processed. (may not be fully processed, see doneLog) + logHash types.TruncatedHash + + // executing message that might exist for the current log event. + // Might be incomplete; if !logDone while we already processed the initiating event, + // then we know an executing message is still coming. + execMsg *types.ExecutingMessage + + need entrydb.EntryTypeFlag + + // buffer of entries not yet in the DB. + // This is generated as objects are applied. + // E.g. you can build multiple hypothetical blocks with log events on top of the state, + // before flushing the entries to a DB. + // However, no entries can be read from the DB while objects are being applied. + out []entrydb.Entry +} + +type EntryObj interface { + encode() entrydb.Entry +} + +func (l *logContext) NextIndex() entrydb.EntryIdx { + return l.nextEntryIndex +} + +// SealedBlock returns the block that we are building on top of, and if it is sealed. +func (l *logContext) SealedBlock() (hash types.TruncatedHash, num uint64, ok bool) { + if !l.hasCompleteBlock() { + return types.TruncatedHash{}, 0, false + } + return l.blockHash, l.blockNum, true +} + +func (l *logContext) hasCompleteBlock() bool { + return !l.need.Any(entrydb.FlagCanonicalHash) +} + +func (l *logContext) hasIncompleteLog() bool { + return l.need.Any(entrydb.FlagInitiatingEvent | entrydb.FlagExecutingLink | entrydb.FlagExecutingCheck) +} + +func (l *logContext) hasReadableLog() bool { + return l.logsSince > 0 && !l.hasIncompleteLog() +} + +// InitMessage returns the current initiating message, if any is available. +func (l *logContext) InitMessage() (hash types.TruncatedHash, logIndex uint32, ok bool) { + if !l.hasReadableLog() { + return types.TruncatedHash{}, 0, false + } + return l.logHash, l.logsSince - 1, true +} + +// ExecMessage returns the current executing message, if any is available. +func (l *logContext) ExecMessage() *types.ExecutingMessage { + if l.hasCompleteBlock() && l.hasReadableLog() && l.execMsg != nil { + return l.execMsg + } + return nil +} + +// ApplyEntry applies an entry on top of the current state. +func (l *logContext) ApplyEntry(entry entrydb.Entry) error { + // Wrap processEntry to add common useful error message info + err := l.processEntry(entry) + if err != nil { + return fmt.Errorf("failed to process type %s entry at idx %d (%x): %w", entry.Type().String(), l.nextEntryIndex, entry[:], err) + } + return nil +} + +// processEntry decodes and applies an entry to the state. +// Entries may not be applied if we are in the process of generating entries from objects. +// These outputs need to be flushed before inputs can be accepted. +func (l *logContext) processEntry(entry entrydb.Entry) error { + if len(l.out) != 0 { + panic("can only apply without appending if the state is still empty") + } + switch entry.Type() { + case entrydb.TypeSearchCheckpoint: + current, err := newSearchCheckpointFromEntry(entry) + if err != nil { + return err + } + l.blockNum = current.blockNum + l.blockHash = types.TruncatedHash{} + l.logsSince = current.logsSince // TODO this is bumping the logsSince? + l.timestamp = current.timestamp + l.need.Add(entrydb.FlagCanonicalHash) + // Log data after the block we are sealing remains to be seen + if l.logsSince == 0 { + l.logHash = types.TruncatedHash{} + l.execMsg = nil + } + case entrydb.TypeCanonicalHash: + if !l.need.Any(entrydb.FlagCanonicalHash) { + return errors.New("not ready for canonical hash entry, already sealed the last block") + } + canonHash, err := newCanonicalHashFromEntry(entry) + if err != nil { + return err + } + l.blockHash = canonHash.hash + l.need.Remove(entrydb.FlagCanonicalHash) + case entrydb.TypeInitiatingEvent: + if !l.hasCompleteBlock() { + return errors.New("did not complete block seal, cannot add log") + } + if l.hasIncompleteLog() { + return errors.New("cannot process log before last log completes") + } + evt, err := newInitiatingEventFromEntry(entry) + if err != nil { + return err + } + l.execMsg = nil // clear the old state + l.logHash = evt.logHash + if evt.hasExecMsg { + l.need.Add(entrydb.FlagExecutingLink | entrydb.FlagExecutingCheck) + } else { + l.logsSince += 1 + } + l.need.Remove(entrydb.FlagInitiatingEvent) + case entrydb.TypeExecutingLink: + if !l.need.Any(entrydb.FlagExecutingLink) { + return errors.New("unexpected executing-link") + } + link, err := newExecutingLinkFromEntry(entry) + if err != nil { + return err + } + l.execMsg = &types.ExecutingMessage{ + Chain: link.chain, + BlockNum: link.blockNum, + LogIdx: link.logIdx, + Timestamp: link.timestamp, + Hash: types.TruncatedHash{}, // not known yet + } + l.need.Remove(entrydb.FlagExecutingLink) + l.need.Add(entrydb.FlagExecutingCheck) + case entrydb.TypeExecutingCheck: + if l.need.Any(entrydb.FlagExecutingLink) { + return errors.New("need executing link to be applied before the check part") + } + if !l.need.Any(entrydb.FlagExecutingCheck) { + return errors.New("unexpected executing check") + } + link, err := newExecutingCheckFromEntry(entry) + if err != nil { + return err + } + l.execMsg.Hash = link.hash + l.need.Remove(entrydb.FlagExecutingCheck) + l.logsSince += 1 + case entrydb.TypePadding: + if l.need.Any(entrydb.FlagPadding) { + l.need.Remove(entrydb.FlagPadding) + } else { + l.need.Remove(entrydb.FlagPadding2) + } + default: + return fmt.Errorf("unknown entry type: %s", entry.Type()) + } + l.nextEntryIndex += 1 + return nil +} + +// appendEntry add the entry to the output-buffer, +// and registers it as last processed entry type, and increments the next entry-index. +func (l *logContext) appendEntry(obj EntryObj) { + entry := obj.encode() + l.out = append(l.out, entry) + l.nextEntryIndex += 1 +} + +// infer advances the logContext in cases where multiple entries are to be appended implicitly +// depending on the last type of entry, a new entry is appended, +// or when the searchCheckpoint should be inserted. +// This can be done repeatedly until there is no more implied data to extend. +func (l *logContext) infer() error { + // We force-insert a checkpoint whenever we hit the known fixed interval. + if l.nextEntryIndex%searchCheckpointFrequency == 0 { + l.need.Add(entrydb.FlagSearchCheckpoint) + } + if l.need.Any(entrydb.FlagSearchCheckpoint) { + l.appendEntry(newSearchCheckpoint(l.blockNum, l.logsSince, l.timestamp)) + l.need.Add(entrydb.FlagCanonicalHash) // always follow with a canonical hash + l.need.Remove(entrydb.FlagSearchCheckpoint) + return nil + } + if l.need.Any(entrydb.FlagCanonicalHash) { + l.appendEntry(newCanonicalHash(l.blockHash)) + l.need.Remove(entrydb.FlagCanonicalHash) + return nil + } + if l.need.Any(entrydb.FlagPadding) { + l.appendEntry(paddingEntry{}) + l.need.Remove(entrydb.FlagPadding) + return nil + } + if l.need.Any(entrydb.FlagPadding2) { + l.appendEntry(paddingEntry{}) + l.need.Remove(entrydb.FlagPadding2) + return nil + } + if l.need.Any(entrydb.FlagInitiatingEvent) { + // If we are running out of space for log-event data, + // write some checkpoints as padding, to pass the checkpoint. + if l.execMsg != nil { // takes 3 total. Need to avoid the checkpoint. + switch l.nextEntryIndex % searchCheckpointFrequency { + case searchCheckpointFrequency - 1: + l.need.Add(entrydb.FlagPadding) + return nil + case searchCheckpointFrequency - 2: + l.need.Add(entrydb.FlagPadding | entrydb.FlagPadding2) + return nil + } + } + evt := newInitiatingEvent(l.logHash, l.execMsg != nil) + l.appendEntry(evt) + l.need.Remove(entrydb.FlagInitiatingEvent) + if l.execMsg == nil { + l.logsSince += 1 + } + return nil + } + if l.need.Any(entrydb.FlagExecutingLink) { + link, err := newExecutingLink(*l.execMsg) + if err != nil { + return fmt.Errorf("failed to create executing link: %w", err) + } + l.appendEntry(link) + l.need.Remove(entrydb.FlagExecutingLink) + return nil + } + if l.need.Any(entrydb.FlagExecutingCheck) { + l.appendEntry(newExecutingCheck(l.execMsg.Hash)) + l.need.Remove(entrydb.FlagExecutingCheck) + l.logsSince += 1 + return nil + } + return io.EOF +} + +// inferFull advances the queued entries held by the log context repeatedly +// until no more implied entries can be added +func (l *logContext) inferFull() error { + for i := 0; i < 10; i++ { + err := l.infer() + if err == nil { + continue + } + if err == io.EOF { // wrapped io.EOF does not count. + return nil + } else { + return err + } + } + panic("hit sanity limit") +} + +// forceBlock force-overwrites the state, to match the given sealed block as starting point (excl) +func (l *logContext) forceBlock(upd eth.BlockID, timestamp uint64) error { + if l.nextEntryIndex != 0 { + return errors.New("can only bootstrap on top of an empty state") + } + l.blockHash = types.TruncateHash(upd.Hash) + l.blockNum = upd.Number + l.timestamp = timestamp + l.logsSince = 0 + l.execMsg = nil + l.logHash = types.TruncatedHash{} + l.need = 0 + l.out = nil + return l.inferFull() // apply to the state as much as possible +} + +// SealBlock applies a block header on top of the current state. +// This seals the state; no further logs of this block may be added with ApplyLog. +func (l *logContext) SealBlock(parent common.Hash, upd eth.BlockID, timestamp uint64) error { + // If we don't have any entries yet, allow any block to start things off + if l.nextEntryIndex != 0 { + if err := l.inferFull(); err != nil { // ensure we can start applying + return err + } + if l.blockHash != types.TruncateHash(parent) { + return fmt.Errorf("%w: cannot apply block %s (parent %s) on top of %s", ErrConflict, upd, parent, l.blockHash) + } + if l.blockHash != (types.TruncatedHash{}) && l.blockNum+1 != upd.Number { + return fmt.Errorf("%w: cannot apply block %d on top of %d", ErrConflict, upd.Number, l.blockNum) + } + if l.timestamp > timestamp { + return fmt.Errorf("%w: block timestamp %d must be equal or larger than current timestamp %d", ErrConflict, timestamp, l.timestamp) + } + } + l.blockHash = types.TruncateHash(upd.Hash) + l.blockNum = upd.Number + l.timestamp = timestamp + l.logsSince = 0 + l.execMsg = nil + l.logHash = types.TruncatedHash{} + l.need.Add(entrydb.FlagSearchCheckpoint) + return l.inferFull() // apply to the state as much as possible +} + +// ApplyLog applies a log on top of the current state. +// The parent-block that the log comes after must be applied with ApplyBlock first. +func (l *logContext) ApplyLog(parentBlock eth.BlockID, logIdx uint32, logHash types.TruncatedHash, execMsg *types.ExecutingMessage) error { + if parentBlock == (eth.BlockID{}) { + return fmt.Errorf("genesis does not have logs: %w", ErrLogOutOfOrder) + } + if err := l.inferFull(); err != nil { // ensure we can start applying + return err + } + if !l.hasCompleteBlock() { + if l.blockNum == 0 { + return fmt.Errorf("%w: should not have logs in block 0", ErrLogOutOfOrder) + } else { + return errors.New("cannot append log before last known block is sealed") + } + } + // check parent block + if l.blockHash != types.TruncateHash(parentBlock.Hash) { + return fmt.Errorf("%w: log builds on top of block %s, but have block %s", ErrLogOutOfOrder, parentBlock, l.blockHash) + } + if l.blockNum != parentBlock.Number { + return fmt.Errorf("%w: log builds on top of block %d, but have block %d", ErrLogOutOfOrder, parentBlock.Number, l.blockNum) + } + // check if log fits on top. The length so far == the index of the next log. + if logIdx != l.logsSince { + return fmt.Errorf("%w: expected event index %d, cannot append %d", ErrLogOutOfOrder, l.logsSince, logIdx) + } + l.logHash = logHash + l.execMsg = execMsg + l.need.Add(entrydb.FlagInitiatingEvent) + if execMsg != nil { + l.need.Add(entrydb.FlagExecutingLink | entrydb.FlagExecutingCheck) + } + return l.inferFull() // apply to the state as much as possible +} diff --git a/op-supervisor/supervisor/backend/db/safety_checkers.go b/op-supervisor/supervisor/backend/db/safety_checkers.go index 3c92c1e808df..3ed297a60c3e 100644 --- a/op-supervisor/supervisor/backend/db/safety_checkers.go +++ b/op-supervisor/supervisor/backend/db/safety_checkers.go @@ -1,8 +1,11 @@ package db import ( + "errors" + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads" + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs" backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" ) @@ -132,11 +135,17 @@ func check( // exist at the blockNum and logIdx // have a hash that matches the provided hash (implicit in the Contains call), and // be less than or equal to the local head for the chain - exists, index, err := chainsDB.logDBs[chain].Contains(blockNum, logIdx, logHash) + index, err := chainsDB.logDBs[chain].Contains(blockNum, logIdx, logHash) if err != nil { + if errors.Is(err, logs.ErrFuture) { + return false // TODO(#12031) + } + if errors.Is(err, logs.ErrConflict) { + return false // TODO(#12031) + } return false } - return exists && index <= localHead + return index <= localHead } // Check checks if the log entry is safe, provided a local head for the chain diff --git a/op-supervisor/supervisor/backend/db/safety_checkers_test.go b/op-supervisor/supervisor/backend/db/safety_checkers_test.go index 0e815bdaccb5..667cd8d46607 100644 --- a/op-supervisor/supervisor/backend/db/safety_checkers_test.go +++ b/op-supervisor/supervisor/backend/db/safety_checkers_test.go @@ -1,16 +1,19 @@ package db import ( - "fmt" + "errors" "testing" + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads" + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs" backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" - "github.com/ethereum/go-ethereum/log" - "github.com/stretchr/testify/require" ) // TestHeadsForChain tests the heads for a chain, @@ -115,7 +118,7 @@ func TestCheck(t *testing.T) { 1, 1, backendTypes.TruncatedHash{1, 2, 3}, - containsResponse{true, entrydb.EntryIdx(6), nil}, + containsResponse{entrydb.EntryIdx(6), nil}, true, }, { @@ -126,7 +129,7 @@ func TestCheck(t *testing.T) { 1, 1, backendTypes.TruncatedHash{1, 2, 3}, - containsResponse{true, entrydb.EntryIdx(3), nil}, + containsResponse{entrydb.EntryIdx(3), nil}, true, }, { @@ -137,7 +140,7 @@ func TestCheck(t *testing.T) { 1, 1, backendTypes.TruncatedHash{1, 2, 3}, - containsResponse{true, entrydb.EntryIdx(1), nil}, + containsResponse{entrydb.EntryIdx(1), nil}, true, }, { @@ -148,7 +151,7 @@ func TestCheck(t *testing.T) { 1, 1, backendTypes.TruncatedHash{1, 2, 3}, - containsResponse{false, entrydb.EntryIdx(1), nil}, + containsResponse{entrydb.EntryIdx(1), logs.ErrConflict}, false, }, { @@ -159,7 +162,7 @@ func TestCheck(t *testing.T) { 1, 1, backendTypes.TruncatedHash{1, 2, 3}, - containsResponse{true, entrydb.EntryIdx(100), nil}, + containsResponse{entrydb.EntryIdx(100), nil}, false, }, { @@ -170,7 +173,7 @@ func TestCheck(t *testing.T) { 1, 1, backendTypes.TruncatedHash{1, 2, 3}, - containsResponse{true, entrydb.EntryIdx(5), nil}, + containsResponse{entrydb.EntryIdx(5), nil}, false, }, { @@ -181,7 +184,7 @@ func TestCheck(t *testing.T) { 1, 1, backendTypes.TruncatedHash{1, 2, 3}, - containsResponse{true, entrydb.EntryIdx(3), nil}, + containsResponse{entrydb.EntryIdx(3), nil}, false, }, { @@ -192,7 +195,7 @@ func TestCheck(t *testing.T) { 1, 1, backendTypes.TruncatedHash{1, 2, 3}, - containsResponse{false, entrydb.EntryIdx(0), fmt.Errorf("error")}, + containsResponse{entrydb.EntryIdx(0), errors.New("error")}, false, }, } diff --git a/op-supervisor/supervisor/backend/source/chain.go b/op-supervisor/supervisor/backend/source/chain.go index f7fd31b202dc..c8fef89f8b83 100644 --- a/op-supervisor/supervisor/backend/source/chain.go +++ b/op-supervisor/supervisor/backend/source/chain.go @@ -26,7 +26,7 @@ type Metrics interface { type Storage interface { LogStorage DatabaseRewinder - LatestBlockNum(chainID types.ChainID) uint64 + LatestBlockNum(chainID types.ChainID) (num uint64, ok bool) } // ChainMonitor monitors a source L2 chain, retrieving the data required to populate the database and perform @@ -43,8 +43,13 @@ func NewChainMonitor(ctx context.Context, logger log.Logger, m Metrics, chainID return nil, err } + latest, ok := store.LatestBlockNum(chainID) + if !ok { + logger.Warn("") + } + startingHead := eth.L1BlockRef{ - Number: store.LatestBlockNum(chainID), + Number: latest, } processLogs := newLogProcessor(chainID, store) diff --git a/op-supervisor/supervisor/backend/source/chain_processor.go b/op-supervisor/supervisor/backend/source/chain_processor.go index 714d9f2e4a6d..0a42da1556a0 100644 --- a/op-supervisor/supervisor/backend/source/chain_processor.go +++ b/op-supervisor/supervisor/backend/source/chain_processor.go @@ -49,7 +49,7 @@ func NewChainProcessor(log log.Logger, client BlockByNumberSource, chain types.C } func (s *ChainProcessor) OnNewHead(ctx context.Context, head eth.L1BlockRef) { - s.log.Debug("Processing chain", "chain", s.chain, "head", head) + s.log.Debug("Processing chain", "chain", s.chain, "head", head, "last", s.lastBlock) if head.Number <= s.lastBlock.Number { s.log.Info("head is not newer than last processed block", "head", head, "lastBlock", s.lastBlock) return diff --git a/op-supervisor/supervisor/backend/source/log_processor.go b/op-supervisor/supervisor/backend/source/log_processor.go index 3fd96476d41f..1a23d149216a 100644 --- a/op-supervisor/supervisor/backend/source/log_processor.go +++ b/op-supervisor/supervisor/backend/source/log_processor.go @@ -5,17 +5,19 @@ import ( "errors" "fmt" + "github.com/ethereum/go-ethereum/common" + ethTypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/source/contracts" backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" supTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" - "github.com/ethereum/go-ethereum/common" - ethTypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" ) type LogStorage interface { - AddLog(chain supTypes.ChainID, logHash backendTypes.TruncatedHash, block eth.BlockID, timestamp uint64, logIdx uint32, execMsg *backendTypes.ExecutingMessage) error + SealBlock(chain supTypes.ChainID, parentHash common.Hash, block eth.BlockID, timestamp uint64) error + AddLog(chain supTypes.ChainID, logHash backendTypes.TruncatedHash, parentBlock eth.BlockID, logIdx uint32, execMsg *backendTypes.ExecutingMessage) error } type EventDecoder interface { @@ -53,13 +55,15 @@ func (p *logProcessor) ProcessLogs(_ context.Context, block eth.L1BlockRef, rcpt } // executing messages have multiple entries in the database // they should start with the initiating message and then include the execution - fmt.Println("p.chain", p.chain) - err = p.logStore.AddLog(p.chain, logHash, block.ID(), block.Time, uint32(l.Index), execMsg) + err = p.logStore.AddLog(p.chain, logHash, block.ParentID(), uint32(l.Index), execMsg) if err != nil { return fmt.Errorf("failed to add log %d from block %v: %w", l.Index, block.ID(), err) } } } + if err := p.logStore.SealBlock(p.chain, block.ParentHash, block.ID(), block.Time); err != nil { + return fmt.Errorf("failed to seal block %s: %w", block.ID(), err) + } return nil } diff --git a/op-supervisor/supervisor/backend/source/log_processor_test.go b/op-supervisor/supervisor/backend/source/log_processor_test.go index 5c65973ab4e4..01d274aa57ee 100644 --- a/op-supervisor/supervisor/backend/source/log_processor_test.go +++ b/op-supervisor/supervisor/backend/source/log_processor_test.go @@ -18,7 +18,12 @@ var logProcessorChainID = supTypes.ChainIDFromUInt64(4) func TestLogProcessor(t *testing.T) { ctx := context.Background() - block1 := eth.L1BlockRef{Number: 100, Hash: common.Hash{0x11}, Time: 1111} + block1 := eth.L1BlockRef{ + ParentHash: common.Hash{0x42}, + Number: 100, + Hash: common.Hash{0x11}, + Time: 1111, + } t.Run("NoOutputWhenLogsAreEmpty", func(t *testing.T) { store := &stubLogStorage{} processor := newLogProcessor(logProcessorChainID, store) @@ -59,30 +64,36 @@ func TestLogProcessor(t *testing.T) { err := processor.ProcessLogs(ctx, block1, rcpts) require.NoError(t, err) - expected := []storedLog{ + expectedLogs := []storedLog{ { - block: block1.ID(), - timestamp: block1.Time, - logIdx: 0, - logHash: logToLogHash(rcpts[0].Logs[0]), - execMsg: nil, + parent: block1.ParentID(), + logIdx: 0, + logHash: logToLogHash(rcpts[0].Logs[0]), + execMsg: nil, }, { - block: block1.ID(), - timestamp: block1.Time, - logIdx: 0, - logHash: logToLogHash(rcpts[0].Logs[1]), - execMsg: nil, + parent: block1.ParentID(), + logIdx: 0, + logHash: logToLogHash(rcpts[0].Logs[1]), + execMsg: nil, }, { + parent: block1.ParentID(), + logIdx: 0, + logHash: logToLogHash(rcpts[1].Logs[0]), + execMsg: nil, + }, + } + require.Equal(t, expectedLogs, store.logs) + + expectedBlocks := []storedSeal{ + { + parent: block1.ParentHash, block: block1.ID(), timestamp: block1.Time, - logIdx: 0, - logHash: logToLogHash(rcpts[1].Logs[0]), - execMsg: nil, }, } - require.Equal(t, expected, store.logs) + require.Equal(t, expectedBlocks, store.seals) }) t.Run("IncludeExecutingMessage", func(t *testing.T) { @@ -115,14 +126,22 @@ func TestLogProcessor(t *testing.T) { require.NoError(t, err) expected := []storedLog{ { + parent: block1.ParentID(), + logIdx: 0, + logHash: logToLogHash(rcpts[0].Logs[0]), + execMsg: &execMsg, + }, + } + require.Equal(t, expected, store.logs) + + expectedBlocks := []storedSeal{ + { + parent: block1.ParentHash, block: block1.ID(), timestamp: block1.Time, - logIdx: 0, - logHash: logToLogHash(rcpts[0].Logs[0]), - execMsg: &execMsg, }, } - require.Equal(t, expected, store.logs) + require.Equal(t, expectedBlocks, store.seals) }) } @@ -183,29 +202,46 @@ func TestToLogHash(t *testing.T) { } type stubLogStorage struct { - logs []storedLog + logs []storedLog + seals []storedSeal } -func (s *stubLogStorage) AddLog(chainID supTypes.ChainID, logHash backendTypes.TruncatedHash, block eth.BlockID, timestamp uint64, logIdx uint32, execMsg *backendTypes.ExecutingMessage) error { +func (s *stubLogStorage) SealBlock(chainID supTypes.ChainID, parentHash common.Hash, block eth.BlockID, timestamp uint64) error { if logProcessorChainID != chainID { return fmt.Errorf("chain id mismatch, expected %v but got %v", logProcessorChainID, chainID) } - s.logs = append(s.logs, storedLog{ + s.seals = append(s.seals, storedSeal{ + parent: parentHash, block: block, timestamp: timestamp, - logIdx: logIdx, - logHash: logHash, - execMsg: execMsg, }) return nil } -type storedLog struct { +func (s *stubLogStorage) AddLog(chainID supTypes.ChainID, logHash backendTypes.TruncatedHash, parentBlock eth.BlockID, logIdx uint32, execMsg *backendTypes.ExecutingMessage) error { + if logProcessorChainID != chainID { + return fmt.Errorf("chain id mismatch, expected %v but got %v", logProcessorChainID, chainID) + } + s.logs = append(s.logs, storedLog{ + parent: parentBlock, + logIdx: logIdx, + logHash: logHash, + execMsg: execMsg, + }) + return nil +} + +type storedSeal struct { + parent common.Hash block eth.BlockID timestamp uint64 - logIdx uint32 - logHash backendTypes.TruncatedHash - execMsg *backendTypes.ExecutingMessage +} + +type storedLog struct { + parent eth.BlockID + logIdx uint32 + logHash backendTypes.TruncatedHash + execMsg *backendTypes.ExecutingMessage } type EventDecoderFn func(*ethTypes.Log) (backendTypes.ExecutingMessage, error) From c5007bb4be66e08b9e4db51c72096912d69eeb0c Mon Sep 17 00:00:00 2001 From: Matthew Slipper <me@matthewslipper.com> Date: Fri, 20 Sep 2024 22:25:22 -0600 Subject: [PATCH 224/264] Add builds for op-deployer, bugfixes, artifacts downloads (#12033) * Add builds for op-deployer, bugfixes, artifacts downloads Adds Docker builds for op-deployer, makes some bugfixes, and adds support for downloading remote artifacts. * Apply code scanning fix for arbitrary file access during archive extraction ("zip slip") Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * fix compile error * lint * fix test * Update from code review, add docker build * fix versioning * remove errant dispatch * update target --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- .circleci/config.yml | 4 + docker-bake.hcl | 16 ++ op-chain-ops/Makefile | 25 +++- op-chain-ops/cmd/op-deployer/main.go | 12 ++ op-chain-ops/deployer/apply.go | 35 +++-- op-chain-ops/deployer/flags.go | 15 +- op-chain-ops/deployer/init.go | 81 ++++++---- op-chain-ops/deployer/inspect/flags.go | 40 +---- op-chain-ops/deployer/inspect/genesis.go | 89 +++++++---- op-chain-ops/deployer/inspect/rollup.go | 58 +------- .../deployer/integration_test/apply_test.go | 2 +- op-chain-ops/deployer/pipeline/downloader.go | 138 ++++++++++++++++++ .../deployer/pipeline/downloader_test.go | 42 ++++++ op-chain-ops/deployer/pipeline/env.go | 4 +- .../deployer/pipeline/implementations.go | 14 +- op-chain-ops/deployer/pipeline/init.go | 6 +- op-chain-ops/deployer/pipeline/l2genesis.go | 14 +- op-chain-ops/deployer/pipeline/opchain.go | 12 +- op-chain-ops/deployer/pipeline/superchain.go | 13 +- .../pipeline/testdata/artifacts.tar.gz | Bin 0 -> 12116 bytes op-chain-ops/deployer/state/intent.go | 4 - op-chain-ops/deployer/state/state.go | 8 +- op-chain-ops/deployer/version/version.go | 6 + op-e2e/e2eutils/challenger/helper.go | 4 +- op-e2e/e2eutils/secrets.go | 13 -- op-e2e/e2eutils/setuputils/utils.go | 5 +- op-service/crypto/secrets.go | 19 +++ op-service/util.go | 31 ++++ op-service/util_test.go | 56 +++++++ ops/docker/deployment-utils/Dockerfile | 35 +++++ ops/docker/deployment-utils/README.md | 16 ++ ops/docker/op-stack-go/Dockerfile | 9 ++ 32 files changed, 588 insertions(+), 238 deletions(-) create mode 100644 op-chain-ops/deployer/pipeline/downloader.go create mode 100644 op-chain-ops/deployer/pipeline/downloader_test.go create mode 100644 op-chain-ops/deployer/pipeline/testdata/artifacts.tar.gz create mode 100644 op-chain-ops/deployer/version/version.go create mode 100644 op-service/crypto/secrets.go create mode 100644 ops/docker/deployment-utils/Dockerfile create mode 100644 ops/docker/deployment-utils/README.md diff --git a/.circleci/config.yml b/.circleci/config.yml index 43c36cb98124..f4975442dd87 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1683,6 +1683,7 @@ workflows: - op-conductor - da-server - op-supervisor + - op-deployer - cannon-prestate: requires: - go-mod-download @@ -1742,6 +1743,7 @@ workflows: - da-server - op-ufm - op-supervisor + - op-deployer name: <<matrix.docker_name>>-docker-release docker_tags: <<pipeline.git.revision>> platforms: "linux/amd64,linux/arm64" @@ -1770,6 +1772,7 @@ workflows: - da-server - op-ufm - op-supervisor + - op-deployer name: <<matrix.op_component>>-cross-platform requires: - op-node-docker-release @@ -1781,6 +1784,7 @@ workflows: - da-server-docker-release - op-ufm-docker-release - op-supervisor-docker-release + - op-deployer-docker-release # Standard (xlarge) AMD-only docker images go here - docker-build: matrix: diff --git a/docker-bake.hcl b/docker-bake.hcl index b587e5bde6ea..788b9a651745 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -69,6 +69,9 @@ variable "OP_CONDUCTOR_VERSION" { default = "${GIT_VERSION}" } +variable "OP_DEPLOYER_VERSION" { + default = "${GIT_VERSION}" +} target "op-node" { dockerfile = "ops/docker/op-stack-go/Dockerfile" @@ -236,3 +239,16 @@ target "contracts-bedrock" { platforms = ["linux/amd64"] tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/contracts-bedrock:${tag}"] } + +target "op-deployer" { + dockerfile = "ops/docker/op-stack-go/Dockerfile" + context = "." + args = { + GIT_COMMIT = "${GIT_COMMIT}" + GIT_DATE = "${GIT_DATE}" + OP_DEPLOYER_VERSION = "${OP_DEPLOYER_VERSION}" + } + target = "op-deployer-target" + platforms = split(",", PLATFORMS) + tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/op-deployer:${tag}"] +} diff --git a/op-chain-ops/Makefile b/op-chain-ops/Makefile index a18f76961599..630167f7b60e 100644 --- a/op-chain-ops/Makefile +++ b/op-chain-ops/Makefile @@ -1,3 +1,26 @@ +GITCOMMIT ?= $(shell git rev-parse HEAD) +GITDATE ?= $(shell git show -s --format='%ct') + +# Find the github tag that points to this commit. If none are found, set the version string to "untagged" +# Prioritizes release tag, if one exists, over tags suffixed with "-rc" +VERSION ?= $(shell tags=$$(git tag --points-at $(GITCOMMIT) | grep '^op-deployer/' | sed 's/op-deployer\///' | sort -V); \ + preferred_tag=$$(echo "$$tags" | grep -v -- '-rc' | tail -n 1); \ + if [ -z "$$preferred_tag" ]; then \ + if [ -z "$$tags" ]; then \ + echo "untagged"; \ + else \ + echo "$$tags" | tail -n 1; \ + fi \ + else \ + echo $$preferred_tag; \ + fi) + +LDFLAGSSTRING +=-X main.GitCommit=$(GITCOMMIT) +LDFLAGSSTRING +=-X main.GitDate=$(GITDATE) +LDFLAGSSTRING +=-X github.com/ethereum-optimism/optimism/op-chain-ops/deployer/version.Version=$(VERSION) +LDFLAGSSTRING +=-X github.com/ethereum-optimism/optimism/op-chain-ops/deployer/version.Meta=$(VERSION_META) +LDFLAGS := -ldflags "$(LDFLAGSSTRING)" + # Use the old Apple linker to workaround broken xcode - https://github.com/golang/go/issues/65169 ifeq ($(shell uname),Darwin) FUZZLDFLAGS := -ldflags=-extldflags=-Wl,-ld_classic @@ -13,7 +36,7 @@ test: go test ./... op-deployer: - go build -o ./bin/op-deployer ./cmd/op-deployer/main.go + GOOS=$(TARGETOS) GOARCH=$(TARGETARCH) CGO_ENABLED=0 go build -v $(LDFLAGS) -o ./bin/op-deployer ./cmd/op-deployer/main.go fuzz: go test $(FUZZLDFLAGS) -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzEncodeDecodeWithdrawal ./crossdomain diff --git a/op-chain-ops/cmd/op-deployer/main.go b/op-chain-ops/cmd/op-deployer/main.go index cb5dae586acf..023d8adca39d 100644 --- a/op-chain-ops/cmd/op-deployer/main.go +++ b/op-chain-ops/cmd/op-deployer/main.go @@ -4,6 +4,9 @@ import ( "fmt" "os" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/version" + opservice "github.com/ethereum-optimism/optimism/op-service" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/inspect" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer" @@ -11,8 +14,17 @@ import ( "github.com/urfave/cli/v2" ) +var ( + GitCommit = "" + GitDate = "" +) + +// VersionWithMeta holds the textual version string including the metadata. +var VersionWithMeta = opservice.FormatVersion(version.Version, GitCommit, GitDate, version.Meta) + func main() { app := cli.NewApp() + app.Version = VersionWithMeta app.Name = "op-deployer" app.Usage = "Tool to configure and deploy OP Chains." app.Flags = cliapp.ProtectFlags(deployer.GlobalFlags) diff --git a/op-chain-ops/deployer/apply.go b/op-chain-ops/deployer/apply.go index 27de5af4b2ff..ca34d4266df7 100644 --- a/op-chain-ops/deployer/apply.go +++ b/op-chain-ops/deployer/apply.go @@ -6,6 +6,8 @@ import ( "fmt" "strings" + "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/pipeline" @@ -128,7 +130,7 @@ func Apply(ctx context.Context, cfg ApplyConfig) error { type pipelineStage struct { name string - stage pipeline.Stage + apply pipeline.Stage } func ApplyPipeline( @@ -137,6 +139,20 @@ func ApplyPipeline( intent *state.Intent, st *state.State, ) error { + progressor := func(curr, total int64) { + env.Logger.Info("artifacts download progress", "current", curr, "total", total) + } + + artifactsFS, cleanup, err := pipeline.DownloadArtifacts(ctx, intent.ContractArtifactsURL, progressor) + if err != nil { + return fmt.Errorf("failed to download artifacts: %w", err) + } + defer func() { + if err := cleanup(); err != nil { + env.Logger.Warn("failed to clean up artifacts", "err", err) + } + }() + pline := []pipelineStage{ {"init", pipeline.Init}, {"deploy-superchain", pipeline.DeploySuperchain}, @@ -144,22 +160,23 @@ func ApplyPipeline( } for _, chain := range intent.Chains { + chainID := chain.ID pline = append(pline, pipelineStage{ - fmt.Sprintf("deploy-opchain-%s", chain.ID.Hex()), - func(ctx context.Context, env *pipeline.Env, intent *state.Intent, st *state.State) error { - return pipeline.DeployOPChain(ctx, env, intent, st, chain.ID) + fmt.Sprintf("deploy-opchain-%s", chainID.Hex()), + func(ctx context.Context, env *pipeline.Env, artifactsFS foundry.StatDirFs, intent *state.Intent, st *state.State) error { + return pipeline.DeployOPChain(ctx, env, artifactsFS, intent, st, chainID) }, }, pipelineStage{ - fmt.Sprintf("generate-l2-genesis-%s", chain.ID.Hex()), - func(ctx context.Context, env *pipeline.Env, intent *state.Intent, st *state.State) error { - return pipeline.GenerateL2Genesis(ctx, env, intent, st, chain.ID) + fmt.Sprintf("generate-l2-genesis-%s", chainID.Hex()), + func(ctx context.Context, env *pipeline.Env, artifactsFS foundry.StatDirFs, intent *state.Intent, st *state.State) error { + return pipeline.GenerateL2Genesis(ctx, env, artifactsFS, intent, st, chainID) }, }) } for _, stage := range pline { - if err := stage.stage(ctx, env, intent, st); err != nil { - return fmt.Errorf("error in pipeline stage: %w", err) + if err := stage.apply(ctx, env, artifactsFS, intent, st); err != nil { + return fmt.Errorf("error in pipeline stage apply: %w", err) } } diff --git a/op-chain-ops/deployer/flags.go b/op-chain-ops/deployer/flags.go index d2bfd0eff5b4..e0ab864bdada 100644 --- a/op-chain-ops/deployer/flags.go +++ b/op-chain-ops/deployer/flags.go @@ -12,9 +12,9 @@ const ( EnvVarPrefix = "DEPLOYER" L1RPCURLFlagName = "l1-rpc-url" L1ChainIDFlagName = "l1-chain-id" + L2ChainIDsFlagName = "l2-chain-ids" WorkdirFlagName = "workdir" OutdirFlagName = "outdir" - DevFlagName = "dev" PrivateKeyFlagName = "private-key" ) @@ -33,6 +33,11 @@ var ( EnvVars: prefixEnvVar("L1_CHAIN_ID"), Value: 900, } + L2ChainIDsFlag = &cli.StringFlag{ + Name: L2ChainIDsFlagName, + Usage: "Comma-separated list of L2 chain IDs to deploy.", + EnvVars: prefixEnvVar("L2_CHAIN_IDS"), + } WorkdirFlag = &cli.StringFlag{ Name: WorkdirFlagName, Usage: "Directory storing intent and stage. Defaults to the current directory.", @@ -42,12 +47,6 @@ var ( OutdirFlagName, }, } - DevFlag = &cli.BoolFlag{ - Name: DevFlagName, - Usage: "Use development mode. This will use the development mnemonic to own the chain" + - " and fund dev accounts.", - EnvVars: prefixEnvVar("DEV"), - } PrivateKeyFlag = &cli.StringFlag{ Name: PrivateKeyFlagName, @@ -60,8 +59,8 @@ var GlobalFlags = append([]cli.Flag{}, oplog.CLIFlags(EnvVarPrefix)...) var InitFlags = []cli.Flag{ L1ChainIDFlag, + L2ChainIDsFlag, WorkdirFlag, - DevFlag, } var ApplyFlags = []cli.Flag{ diff --git a/op-chain-ops/deployer/init.go b/op-chain-ops/deployer/init.go index f3f181c2186f..0cc288b40ffb 100644 --- a/op-chain-ops/deployer/init.go +++ b/op-chain-ops/deployer/init.go @@ -3,6 +3,9 @@ package deployer import ( "fmt" "path" + "strings" + + op_service "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" "github.com/ethereum-optimism/optimism/op-chain-ops/devkeys" @@ -10,12 +13,10 @@ import ( "github.com/urfave/cli/v2" ) -const devMnemonic = "test test test test test test test test test test test junk" - type InitConfig struct { - L1ChainID uint64 - Outdir string - Dev bool + L1ChainID uint64 + Outdir string + L2ChainIDs []common.Hash } func (c *InitConfig) Check() error { @@ -27,6 +28,10 @@ func (c *InitConfig) Check() error { return fmt.Errorf("outdir must be specified") } + if len(c.L2ChainIDs) == 0 { + return fmt.Errorf("must specify at least one L2 chain ID") + } + return nil } @@ -34,12 +39,22 @@ func InitCLI() func(ctx *cli.Context) error { return func(ctx *cli.Context) error { l1ChainID := ctx.Uint64(L1ChainIDFlagName) outdir := ctx.String(OutdirFlagName) - dev := ctx.Bool(DevFlagName) + + l2ChainIDsRaw := ctx.String(L2ChainIDsFlagName) + l2ChainIDsStr := strings.Split(l2ChainIDsRaw, ",") + l2ChainIDs := make([]common.Hash, 0, len(l2ChainIDsStr)) + for _, idStr := range l2ChainIDsStr { + id, err := op_service.Parse256BitChainID(idStr) + if err != nil { + return fmt.Errorf("invalid chain ID: %w", err) + } + l2ChainIDs = append(l2ChainIDs, id) + } return Init(InitConfig{ - L1ChainID: l1ChainID, - Outdir: outdir, - Dev: dev, + L1ChainID: l1ChainID, + Outdir: outdir, + L2ChainIDs: l2ChainIDs, }) } } @@ -52,30 +67,44 @@ func Init(cfg InitConfig) error { intent := &state.Intent{ L1ChainID: cfg.L1ChainID, UseFaultProofs: true, - FundDevAccounts: cfg.Dev, + FundDevAccounts: true, } l1ChainIDBig := intent.L1ChainIDBig() - if cfg.Dev { - dk, err := devkeys.NewMnemonicDevKeys(devMnemonic) + dk, err := devkeys.NewMnemonicDevKeys(devkeys.TestMnemonic) + if err != nil { + return fmt.Errorf("failed to create dev keys: %w", err) + } + + addrFor := func(key devkeys.Key) common.Address { + // The error below should never happen, so panic if it does. + addr, err := dk.Address(key) if err != nil { - return fmt.Errorf("failed to create dev keys: %w", err) + panic(err) } + return addr + } + intent.SuperchainRoles = state.SuperchainRoles{ + ProxyAdminOwner: addrFor(devkeys.L1ProxyAdminOwnerRole.Key(l1ChainIDBig)), + ProtocolVersionsOwner: addrFor(devkeys.SuperchainProtocolVersionsOwner.Key(l1ChainIDBig)), + Guardian: addrFor(devkeys.SuperchainConfigGuardianKey.Key(l1ChainIDBig)), + } - addrFor := func(key devkeys.Key) common.Address { - // The error below should never happen, so panic if it does. - addr, err := dk.Address(key) - if err != nil { - panic(err) - } - return addr - } - intent.SuperchainRoles = state.SuperchainRoles{ - ProxyAdminOwner: addrFor(devkeys.L1ProxyAdminOwnerRole.Key(l1ChainIDBig)), - ProtocolVersionsOwner: addrFor(devkeys.SuperchainDeployerKey.Key(l1ChainIDBig)), - Guardian: addrFor(devkeys.SuperchainConfigGuardianKey.Key(l1ChainIDBig)), - } + for _, l2ChainID := range cfg.L2ChainIDs { + l2ChainIDBig := l2ChainID.Big() + intent.Chains = append(intent.Chains, &state.ChainIntent{ + ID: l2ChainID, + Roles: state.ChainRoles{ + ProxyAdminOwner: addrFor(devkeys.L2ProxyAdminOwnerRole.Key(l2ChainIDBig)), + SystemConfigOwner: addrFor(devkeys.SystemConfigOwner.Key(l2ChainIDBig)), + GovernanceTokenOwner: addrFor(devkeys.L2ProxyAdminOwnerRole.Key(l2ChainIDBig)), + UnsafeBlockSigner: addrFor(devkeys.SequencerP2PRole.Key(l2ChainIDBig)), + Batcher: addrFor(devkeys.BatcherRole.Key(l2ChainIDBig)), + Proposer: addrFor(devkeys.ProposerRole.Key(l2ChainIDBig)), + Challenger: addrFor(devkeys.ChallengerRole.Key(l2ChainIDBig)), + }, + }) } st := &state.State{ diff --git a/op-chain-ops/deployer/inspect/flags.go b/op-chain-ops/deployer/inspect/flags.go index ad3ea679b824..601e28ba85a5 100644 --- a/op-chain-ops/deployer/inspect/flags.go +++ b/op-chain-ops/deployer/inspect/flags.go @@ -3,9 +3,9 @@ package inspect import ( "fmt" + op_service "github.com/ethereum-optimism/optimism/op-service" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer" - "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/pipeline" - "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" "github.com/ethereum/go-ethereum/common" "github.com/urfave/cli/v2" ) @@ -70,7 +70,7 @@ func readConfig(cliCtx *cli.Context) (cliConfig, error) { return cfg, fmt.Errorf("chain-id argument is required") } - chainID, err := chainIDStrToHash(chainIDStr) + chainID, err := op_service.Parse256BitChainID(chainIDStr) if err != nil { return cfg, fmt.Errorf("failed to parse chain ID: %w", err) } @@ -81,37 +81,3 @@ func readConfig(cliCtx *cli.Context) (cliConfig, error) { ChainID: chainID, }, nil } - -type inspectState struct { - GlobalState *state.State - ChainIntent *state.ChainIntent - ChainState *state.ChainState -} - -func bootstrapState(cfg cliConfig) (*inspectState, error) { - env := &pipeline.Env{Workdir: cfg.Workdir} - globalState, err := env.ReadState() - if err != nil { - return nil, fmt.Errorf("failed to read intent: %w", err) - } - - if globalState.AppliedIntent == nil { - return nil, fmt.Errorf("chain state is not applied - run op-deployer apply") - } - - chainIntent, err := globalState.AppliedIntent.Chain(cfg.ChainID) - if err != nil { - return nil, fmt.Errorf("failed to get applied chain intent: %w", err) - } - - chainState, err := globalState.Chain(cfg.ChainID) - if err != nil { - return nil, fmt.Errorf("failed to get chain ID %s: %w", cfg.ChainID.String(), err) - } - - return &inspectState{ - GlobalState: globalState, - ChainIntent: chainIntent, - ChainState: chainState, - }, nil -} diff --git a/op-chain-ops/deployer/inspect/genesis.go b/op-chain-ops/deployer/inspect/genesis.go index 7e2f13b6d672..4c2fbad01092 100644 --- a/op-chain-ops/deployer/inspect/genesis.go +++ b/op-chain-ops/deployer/inspect/genesis.go @@ -2,9 +2,12 @@ package inspect import ( "fmt" - "math/big" - "strconv" - "strings" + + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/pipeline" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" + "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum/go-ethereum/core" "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/ethereum-optimism/optimism/op-service/jsonutil" @@ -18,40 +21,72 @@ func GenesisCLI(cliCtx *cli.Context) error { return err } - st, err := bootstrapState(cfg) + env := &pipeline.Env{Workdir: cfg.Workdir} + globalState, err := env.ReadState() if err != nil { - return err + return fmt.Errorf("failed to read intent: %w", err) } - genesis, err := st.ChainState.UnmarshalGenesis() + l2Genesis, _, err := GenesisAndRollup(globalState, cfg.ChainID) if err != nil { - return fmt.Errorf("failed to unmarshal genesis: %w", err) + return fmt.Errorf("failed to generate genesis block: %w", err) } - if err := jsonutil.WriteJSON(genesis, ioutil.ToStdOutOrFileOrNoop(cfg.Outfile, 0o666)); err != nil { + if err := jsonutil.WriteJSON(l2Genesis, ioutil.ToStdOutOrFileOrNoop(cfg.Outfile, 0o666)); err != nil { return fmt.Errorf("failed to write genesis: %w", err) } return nil } -func chainIDStrToHash(in string) (common.Hash, error) { - var chainIDBig *big.Int - if strings.HasPrefix(in, "0x") { - in = strings.TrimPrefix(in, "0x") - var ok bool - chainIDBig, ok = new(big.Int).SetString(in, 16) - if !ok { - return common.Hash{}, fmt.Errorf("failed to parse chain ID %s", in) - } - } else { - inUint, err := strconv.ParseUint(in, 10, 64) - if err != nil { - return common.Hash{}, fmt.Errorf("failed to parse chain ID %s: %w", in, err) - } - - chainIDBig = new(big.Int).SetUint64(inUint) - } - - return common.BigToHash(chainIDBig), nil +func GenesisAndRollup(globalState *state.State, chainID common.Hash) (*core.Genesis, *rollup.Config, error) { + if globalState.AppliedIntent == nil { + return nil, nil, fmt.Errorf("chain state is not applied - run op-deployer apply") + } + + chainIntent, err := globalState.AppliedIntent.Chain(chainID) + if err != nil { + return nil, nil, fmt.Errorf("failed to get applied chain intent: %w", err) + } + + chainState, err := globalState.Chain(chainID) + if err != nil { + return nil, nil, fmt.Errorf("failed to get chain ID %s: %w", chainID.String(), err) + } + + l2Allocs, err := chainState.UnmarshalAllocs() + if err != nil { + return nil, nil, fmt.Errorf("failed to unmarshal genesis: %w", err) + } + + config, err := state.CombineDeployConfig( + globalState.AppliedIntent, + chainIntent, + globalState, + chainState, + ) + if err != nil { + return nil, nil, fmt.Errorf("failed to combine L2 init config: %w", err) + } + + l2GenesisBuilt, err := genesis.BuildL2Genesis(&config, l2Allocs, chainState.StartBlock) + if err != nil { + return nil, nil, fmt.Errorf("failed to build L2 genesis: %w", err) + } + l2GenesisBlock := l2GenesisBuilt.ToBlock() + + rollupConfig, err := config.RollupConfig( + chainState.StartBlock, + l2GenesisBlock.Hash(), + l2GenesisBlock.Number().Uint64(), + ) + if err != nil { + return nil, nil, fmt.Errorf("failed to build rollup config: %w", err) + } + + if err := rollupConfig.Check(); err != nil { + return nil, nil, fmt.Errorf("generated rollup config does not pass validation: %w", err) + } + + return l2GenesisBuilt, rollupConfig, nil } diff --git a/op-chain-ops/deployer/inspect/rollup.go b/op-chain-ops/deployer/inspect/rollup.go index 8d9d39e1c49c..60cbf4f5c46c 100644 --- a/op-chain-ops/deployer/inspect/rollup.go +++ b/op-chain-ops/deployer/inspect/rollup.go @@ -4,12 +4,8 @@ import ( "fmt" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/pipeline" - "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" - "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" - "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/ethereum-optimism/optimism/op-service/jsonutil" - "github.com/ethereum/go-ethereum/common" "github.com/urfave/cli/v2" ) @@ -25,7 +21,7 @@ func RollupCLI(cliCtx *cli.Context) error { return fmt.Errorf("failed to read intent: %w", err) } - rollupConfig, err := Rollup(globalState, cfg.ChainID) + _, rollupConfig, err := GenesisAndRollup(globalState, cfg.ChainID) if err != nil { return fmt.Errorf("failed to generate rollup config: %w", err) } @@ -36,55 +32,3 @@ func RollupCLI(cliCtx *cli.Context) error { return nil } - -func Rollup(globalState *state.State, chainID common.Hash) (*rollup.Config, error) { - if globalState.AppliedIntent == nil { - return nil, fmt.Errorf("chain state is not applied - run op-deployer apply") - } - - chainIntent, err := globalState.AppliedIntent.Chain(chainID) - if err != nil { - return nil, fmt.Errorf("failed to get applied chain intent: %w", err) - } - - chainState, err := globalState.Chain(chainID) - if err != nil { - return nil, fmt.Errorf("failed to get chain ID %s: %w", chainID.String(), err) - } - - l2Allocs, err := chainState.UnmarshalGenesis() - if err != nil { - return nil, fmt.Errorf("failed to unmarshal genesis: %w", err) - } - - config, err := state.CombineDeployConfig( - globalState.AppliedIntent, - chainIntent, - globalState, - chainState, - ) - if err != nil { - return nil, fmt.Errorf("failed to combine L2 init config: %w", err) - } - - l2GenesisBuilt, err := genesis.BuildL2Genesis(&config, l2Allocs, chainState.StartBlock) - if err != nil { - return nil, fmt.Errorf("failed to build L2 genesis: %w", err) - } - l2GenesisBlock := l2GenesisBuilt.ToBlock() - - rollupConfig, err := config.RollupConfig( - chainState.StartBlock, - l2GenesisBlock.Hash(), - l2GenesisBlock.Number().Uint64(), - ) - if err != nil { - return nil, fmt.Errorf("failed to build rollup config: %w", err) - } - - if err := rollupConfig.Check(); err != nil { - return nil, fmt.Errorf("generated rollup config does not pass validation: %w", err) - } - - return rollupConfig, nil -} diff --git a/op-chain-ops/deployer/integration_test/apply_test.go b/op-chain-ops/deployer/integration_test/apply_test.go index 624367ad3677..6d673ed03791 100644 --- a/op-chain-ops/deployer/integration_test/apply_test.go +++ b/op-chain-ops/deployer/integration_test/apply_test.go @@ -197,7 +197,7 @@ func TestEndToEndApply(t *testing.T) { } t.Run("l2 genesis", func(t *testing.T) { - require.Greater(t, len(chainState.Genesis), 0) + require.Greater(t, len(chainState.Allocs), 0) }) } } diff --git a/op-chain-ops/deployer/pipeline/downloader.go b/op-chain-ops/deployer/pipeline/downloader.go new file mode 100644 index 000000000000..8932792f822f --- /dev/null +++ b/op-chain-ops/deployer/pipeline/downloader.go @@ -0,0 +1,138 @@ +package pipeline + +import ( + "archive/tar" + "bufio" + "compress/gzip" + "context" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "os" + "path" + "strings" + "time" + + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" + "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" +) + +var ErrUnsupportedArtifactsScheme = errors.New("unsupported artifacts URL scheme") + +type DownloadProgressor func(current, total int64) + +type CleanupFunc func() error + +var noopCleanup = func() error { return nil } + +func DownloadArtifacts(ctx context.Context, artifactsURL *state.ArtifactsURL, progress DownloadProgressor) (foundry.StatDirFs, CleanupFunc, error) { + switch artifactsURL.Scheme { + case "http", "https": + req, err := http.NewRequestWithContext(ctx, http.MethodGet, (*url.URL)(artifactsURL).String(), nil) + if err != nil { + return nil, nil, fmt.Errorf("failed to create request: %w", err) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, nil, fmt.Errorf("failed to download artifacts: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, nil, fmt.Errorf("failed to download artifacts: invalid status code %s", resp.Status) + } + + tmpDir, err := os.MkdirTemp("", "op-deployer-artifacts-*") + if err != nil { + return nil, nil, fmt.Errorf("failed to create temp dir: %w", err) + } + + pr := &progressReader{ + r: resp.Body, + progress: progress, + total: resp.ContentLength, + } + + gr, err := gzip.NewReader(pr) + if err != nil { + return nil, nil, fmt.Errorf("failed to create gzip reader: %w", err) + } + defer gr.Close() + + tr := tar.NewReader(gr) + if err := untar(tmpDir, tr); err != nil { + return nil, nil, fmt.Errorf("failed to untar: %w", err) + } + + fs := os.DirFS(path.Join(tmpDir, "forge-artifacts")) + cleanup := func() error { + return os.RemoveAll(tmpDir) + } + return fs.(foundry.StatDirFs), cleanup, nil + case "file": + fs := os.DirFS(artifactsURL.Path) + return fs.(foundry.StatDirFs), noopCleanup, nil + default: + return nil, nil, ErrUnsupportedArtifactsScheme + } +} + +type progressReader struct { + r io.Reader + progress DownloadProgressor + curr int64 + total int64 + lastPrint time.Time +} + +func (pr *progressReader) Read(p []byte) (int, error) { + + n, err := pr.r.Read(p) + pr.curr += int64(n) + if pr.progress != nil && time.Since(pr.lastPrint) > 1*time.Second { + pr.progress(pr.curr, pr.total) + pr.lastPrint = time.Now() + } + return n, err +} + +func untar(dir string, tr *tar.Reader) error { + for { + hdr, err := tr.Next() + if err == io.EOF { + return nil + } + if err != nil { + return fmt.Errorf("failed to read tar header: %w", err) + } + + cleanedName := path.Clean(hdr.Name) + if strings.Contains(cleanedName, "..") { + return fmt.Errorf("invalid file path: %s", hdr.Name) + } + dst := path.Join(dir, cleanedName) + if hdr.FileInfo().IsDir() { + if err := os.MkdirAll(dst, 0o755); err != nil { + return fmt.Errorf("failed to create directory: %w", err) + } + continue + } + + f, err := os.Create(dst) + buf := bufio.NewWriter(f) + if err != nil { + return fmt.Errorf("failed to create file: %w", err) + } + if _, err := io.Copy(buf, tr); err != nil { + _ = f.Close() + return fmt.Errorf("failed to write file: %w", err) + } + if err := buf.Flush(); err != nil { + return fmt.Errorf("failed to flush buffer: %w", err) + } + _ = f.Close() + } +} diff --git a/op-chain-ops/deployer/pipeline/downloader_test.go b/op-chain-ops/deployer/pipeline/downloader_test.go new file mode 100644 index 000000000000..277409461a41 --- /dev/null +++ b/op-chain-ops/deployer/pipeline/downloader_test.go @@ -0,0 +1,42 @@ +package pipeline + +import ( + "context" + "io" + "net/http" + "net/http/httptest" + "net/url" + "os" + "testing" + + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" + "github.com/stretchr/testify/require" +) + +func TestDownloadArtifacts(t *testing.T) { + f, err := os.OpenFile("testdata/artifacts.tar.gz", os.O_RDONLY, 0o644) + require.NoError(t, err) + defer f.Close() + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + _, err := io.Copy(w, f) + require.NoError(t, err) + })) + defer ts.Close() + + ctx := context.Background() + artifactsURL, err := url.Parse(ts.URL) + require.NoError(t, err) + + fs, cleanup, err := DownloadArtifacts(ctx, (*state.ArtifactsURL)(artifactsURL), nil) + require.NoError(t, err) + require.NotNil(t, fs) + defer func() { + require.NoError(t, cleanup()) + }() + + info, err := fs.Stat("WETH98.sol/WETH98.json") + require.NoError(t, err) + require.Greater(t, info.Size(), int64(0)) +} diff --git a/op-chain-ops/deployer/pipeline/env.go b/op-chain-ops/deployer/pipeline/env.go index 9ee28e3843f6..d0778122d27a 100644 --- a/op-chain-ops/deployer/pipeline/env.go +++ b/op-chain-ops/deployer/pipeline/env.go @@ -5,6 +5,8 @@ import ( "fmt" "path" + "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" opcrypto "github.com/ethereum-optimism/optimism/op-service/crypto" "github.com/ethereum-optimism/optimism/op-service/jsonutil" @@ -44,4 +46,4 @@ func (e *Env) WriteState(st *state.State) error { return st.WriteToFile(statePath) } -type Stage func(ctx context.Context, env *Env, intent *state.Intent, state2 *state.State) error +type Stage func(ctx context.Context, env *Env, artifactsFS foundry.StatDirFs, intent *state.Intent, state2 *state.State) error diff --git a/op-chain-ops/deployer/pipeline/implementations.go b/op-chain-ops/deployer/pipeline/implementations.go index f7e2acd1130c..f9e125e4150b 100644 --- a/op-chain-ops/deployer/pipeline/implementations.go +++ b/op-chain-ops/deployer/pipeline/implementations.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "math/big" - "os" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opsm" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" @@ -12,7 +11,7 @@ import ( "github.com/ethereum-optimism/optimism/op-chain-ops/script" ) -func DeployImplementations(ctx context.Context, env *Env, intent *state.Intent, st *state.State) error { +func DeployImplementations(ctx context.Context, env *Env, artifactsFS foundry.StatDirFs, intent *state.Intent, st *state.State) error { lgr := env.Logger.New("stage", "deploy-implementations") if !shouldDeployImplementations(intent, st) { @@ -22,17 +21,9 @@ func DeployImplementations(ctx context.Context, env *Env, intent *state.Intent, lgr.Info("deploying implementations") - var artifactsFS foundry.StatDirFs - var err error - if intent.ContractArtifactsURL.Scheme == "file" { - fs := os.DirFS(intent.ContractArtifactsURL.Path) - artifactsFS = fs.(foundry.StatDirFs) - } else { - return fmt.Errorf("only file:// artifacts URLs are supported") - } - var dump *foundry.ForgeAllocs var dio opsm.DeployImplementationsOutput + var err error err = CallScriptBroadcast( ctx, CallScriptBroadcastOpts{ @@ -49,6 +40,7 @@ func DeployImplementations(ctx context.Context, env *Env, intent *state.Intent, dio, err = opsm.DeployImplementations( host, opsm.DeployImplementationsInput{ + Salt: st.Create2Salt, WithdrawalDelaySeconds: big.NewInt(604800), MinProposalSizeBytes: big.NewInt(126000), ChallengePeriodSeconds: big.NewInt(86400), diff --git a/op-chain-ops/deployer/pipeline/init.go b/op-chain-ops/deployer/pipeline/init.go index 26fbb7c2667c..094e103aa940 100644 --- a/op-chain-ops/deployer/pipeline/init.go +++ b/op-chain-ops/deployer/pipeline/init.go @@ -5,6 +5,8 @@ import ( "crypto/rand" "fmt" + "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" + "github.com/ethereum-optimism/optimism/op-chain-ops/script" "github.com/ethereum/go-ethereum/common" @@ -16,7 +18,7 @@ func IsSupportedStateVersion(version int) bool { return version == 1 } -func Init(ctx context.Context, env *Env, intent *state.Intent, st *state.State) error { +func Init(ctx context.Context, env *Env, artifactsFS foundry.StatDirFs, intent *state.Intent, st *state.State) error { lgr := env.Logger.New("stage", "init") lgr.Info("initializing pipeline") @@ -73,7 +75,7 @@ func Init(ctx context.Context, env *Env, intent *state.Intent, st *state.State) return fmt.Errorf("deterministic deployer is not deployed on this chain - please deploy it first") } - // TODO: validate individual L2s + // TODO: validate individual return nil } diff --git a/op-chain-ops/deployer/pipeline/l2genesis.go b/op-chain-ops/deployer/pipeline/l2genesis.go index 95613fada912..f74c6e833620 100644 --- a/op-chain-ops/deployer/pipeline/l2genesis.go +++ b/op-chain-ops/deployer/pipeline/l2genesis.go @@ -7,7 +7,6 @@ import ( "encoding/json" "fmt" "math/big" - "os" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opsm" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" @@ -16,20 +15,11 @@ import ( "github.com/ethereum/go-ethereum/common" ) -func GenerateL2Genesis(ctx context.Context, env *Env, intent *state.Intent, st *state.State, chainID common.Hash) error { +func GenerateL2Genesis(ctx context.Context, env *Env, artifactsFS foundry.StatDirFs, intent *state.Intent, st *state.State, chainID common.Hash) error { lgr := env.Logger.New("stage", "generate-l2-genesis") lgr.Info("generating L2 genesis", "id", chainID.Hex()) - var artifactsFS foundry.StatDirFs - var err error - if intent.ContractArtifactsURL.Scheme == "file" { - fs := os.DirFS(intent.ContractArtifactsURL.Path) - artifactsFS = fs.(foundry.StatDirFs) - } else { - return fmt.Errorf("only file:// artifacts URLs are supported") - } - thisIntent, err := intent.Chain(chainID) if err != nil { return fmt.Errorf("failed to get chain intent: %w", err) @@ -92,7 +82,7 @@ func GenerateL2Genesis(ctx context.Context, env *Env, intent *state.Intent, st * if err := gw.Close(); err != nil { return fmt.Errorf("failed to close gzip writer: %w", err) } - thisChainState.Genesis = buf.Bytes() + thisChainState.Allocs = buf.Bytes() startHeader, err := env.L1Client.HeaderByNumber(ctx, nil) if err != nil { return fmt.Errorf("failed to get start block: %w", err) diff --git a/op-chain-ops/deployer/pipeline/opchain.go b/op-chain-ops/deployer/pipeline/opchain.go index c6d64255c650..90d03b028142 100644 --- a/op-chain-ops/deployer/pipeline/opchain.go +++ b/op-chain-ops/deployer/pipeline/opchain.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "math/big" - "os" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opsm" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" @@ -13,7 +12,7 @@ import ( "github.com/ethereum/go-ethereum/common" ) -func DeployOPChain(ctx context.Context, env *Env, intent *state.Intent, st *state.State, chainID common.Hash) error { +func DeployOPChain(ctx context.Context, env *Env, artifactsFS foundry.StatDirFs, intent *state.Intent, st *state.State, chainID common.Hash) error { lgr := env.Logger.New("stage", "deploy-opchain") if !shouldDeployOPChain(intent, st, chainID) { @@ -23,15 +22,6 @@ func DeployOPChain(ctx context.Context, env *Env, intent *state.Intent, st *stat lgr.Info("deploying OP chain", "id", chainID.Hex()) - var artifactsFS foundry.StatDirFs - var err error - if intent.ContractArtifactsURL.Scheme == "file" { - fs := os.DirFS(intent.ContractArtifactsURL.Path) - artifactsFS = fs.(foundry.StatDirFs) - } else { - return fmt.Errorf("only file:// artifacts URLs are supported") - } - thisIntent, err := intent.Chain(chainID) if err != nil { return fmt.Errorf("failed to get chain intent: %w", err) diff --git a/op-chain-ops/deployer/pipeline/superchain.go b/op-chain-ops/deployer/pipeline/superchain.go index a3c1dc2827a3..21aeda0e23dc 100644 --- a/op-chain-ops/deployer/pipeline/superchain.go +++ b/op-chain-ops/deployer/pipeline/superchain.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "math/big" - "os" "github.com/ethereum-optimism/optimism/op-chain-ops/script" @@ -14,7 +13,7 @@ import ( "github.com/ethereum-optimism/optimism/op-node/rollup" ) -func DeploySuperchain(ctx context.Context, env *Env, intent *state.Intent, st *state.State) error { +func DeploySuperchain(ctx context.Context, env *Env, artifactsFS foundry.StatDirFs, intent *state.Intent, st *state.State) error { lgr := env.Logger.New("stage", "deploy-superchain") if !shouldDeploySuperchain(intent, st) { @@ -24,17 +23,9 @@ func DeploySuperchain(ctx context.Context, env *Env, intent *state.Intent, st *s lgr.Info("deploying superchain") - var artifactsFS foundry.StatDirFs - var err error - if intent.ContractArtifactsURL.Scheme == "file" { - fs := os.DirFS(intent.ContractArtifactsURL.Path) - artifactsFS = fs.(foundry.StatDirFs) - } else { - return fmt.Errorf("only file:// artifacts URLs are supported") - } - var dump *foundry.ForgeAllocs var dso opsm.DeploySuperchainOutput + var err error err = CallScriptBroadcast( ctx, CallScriptBroadcastOpts{ diff --git a/op-chain-ops/deployer/pipeline/testdata/artifacts.tar.gz b/op-chain-ops/deployer/pipeline/testdata/artifacts.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..58f034254f46aa79a18fcfaa10429b447e08c78d GIT binary patch literal 12116 zcmV-aFRRcWiwFR$T<T^31MPhaliRqFaDIwTwRN?r_(8luxpI~4BbU8zH`&C#<Z|b& zDL!pwHPS@V*gNa;fB(7xkOV1`A~ljmPDaUEBNC79Mx)UWpb@RN^E^tno9Dkc*(V4B zCB(#hOZy#AZol1ULbz0v3rPby35cMQ{9+<b2U7L9-E5;ZfN~vew{Nreo5lR*CR^{8 zgJOB!(~iTV{Qg8fQ91tc?R=3woiFp%u~}jG_!CK>KtL2D;&J@X@o61@PB<fyrix`W z&r->S4rrbRVH}Gz%;>YfZ&u6UeE>Zq=Y8W(%lS`~oWM&Fs9#Ki)1h5`{>8`t!^ek) z;PLa2pVs-Gt2mP+r!o$tPQoPAQIO?<h!x2-kAsuWe~$BC3idev&+&Pj|Nq*b*7;8o zt+fbQs`8AdG!R54p@7*NXPHi9a?1G+iXyK6^l|>5<?}fI|Fu6!l)TMOX#3-5y#2?S z2p;XfbA0UhZ&r(WI^W(s&F713^VB>XDdc-TqvStRApZ$vkM`eLK9BPMU;C4<)^D<> z(Mi3)!{tBDe**GfGD#oh|2aO*@&D`BuYMouXRsg~j}^wP|7iaQggmbQXZiGuzx(t4 zYC!M$PlcpJHO8MP)c+pW|I>dyOrv-{o&Dd3>Gtj>o6e?rv{=MZ^5gW$6j0t~-`#GZ z!~&E<czF}uMe!n=etc4vUuQ`+f0qp{p5HE$?R>R_^2_KNpFn@B_t7%JCg#hV+wI1H z<KDtUS2Ie}b+*}<Qrm33j25rzFR+&bYW?tJy1LzV_j?N!fk}5;C|+O-ySTrbXYcnQ zesi;4y=zDN&F$S`n7@zGk)Zb?AFo!6-RkCPJKD?Da?q&9(E`W(kNLev{lUgB&64?b zwAlC<3;{;BgQD*N$jxdq-*&>$+U%fFGG8Om+ichK<(pmn-19>b+}vHqjt?IeknL(4 zEneQ<+$`?Kj`~ShaJ!C{n><^$PNH<P{pXe;1@^yNudZ7uuvsUEQQ)7RbnoZex9K{1 z-%7UoATa`}>|M6pRv`V>EQirz+(@R`Pgy#hZP&Nikn!nUS4XzfNg~${Xi=NphJ2Dm zK$N@d)$PU=?k3DvyW)L6qh2sRulj`6u?G56B+Oskq&)E)H~~uVEWX=j$ts1SAEvAL z?^&{iO2JPu(18qiASmNHAVQKLAc0U4j3gc8sfa}Y&oosUzrpm!H!Q?|bCzdSeR#qd z6v0x7Yk>(FWC2N_3}b{PnUIPQETOo-7FiSqB241gKIK{CDTk+km3^8984J=lFi(Rd zcTZDEvy^4FEEurLy_F)a^^5OGoY-0_hyW=@?9+_dr=du77<2oS8amY4BAUn`O;ZbP zBy6qnscB0%xG0OYqQz6?`lT6(RLb4cFlqJ>$UIH6fLR<<WoreY$RZWnr-bHyEhY<U znC}!Jk1~7{1R`!et40}du8lH`q7DSnKo@{42#FcfRKvG|))kdR1uBq2avH$!ajAjW zG#K=ez&Y5ipa2u{3o)3;5PCwU5e%WTZ#47`EC&4L!An@Y!<B^R=HCct0L+8!WQHd2 z7t*Y3F@!dV&;}y_*!5kb2a%2TxvFaS*VMWTvQU+fDH0ZtX<Dxz?bf$rMq;nN5U#!m z!+QOsrT-LIl2CxVq=5|b97mPNer&RQw>6pJzj;<cBQx8w8(E-{paq?H5W+LTZSQ5v zlq7>Vju#xqh2T*6z)!_-2s^3Mj7r)uW>k?DZjvmo*Vire4V7qE)mPf_AiM);3i<>= zNHw#R0^B*iLEPaz#eY58F;lwaKTBs*k5Hr?XFQ~42GJyia@_o_vKVWdR)q*Gr3GPz zvJ7UH$}^JZd6GbF5UV^EBFuS8!$`+@B9k-%Q5=H=Nm;@r@E%Dhhb{#CFM-J!CSl+> zs5WCGT0yOe!?uRI!I;rNv3%f1E8y5b3!n^8$JW*Y=pbNb62v|vD%XjKGm?oc&JqP9 z0s=M%kxx}hGR<>XB~Yd&L9Sv7LzIaappO!rsD#DPu%R1MIM==T0ln-<rHCOt1MHa~ zZL!1%Y#5P!V+tcr2{AmzV(#<Uh(0*MWzX=c!Hd&KC^3fSybfji7&4~0pat(D>}qHS zogc!1Wn+Usk716T9_EtXTqcLpdtA@O?A68W<xx`3ULCOd?7a^xZ8D?kHB;Ta9*?JM zeF{o;<P^pJOdaSMRL#LXgJj@iN-I#Va*!fXO5%(rpzFynp}31SPngna6orDuk%FQi z_##*<sm_Inc$$OYj9CWsEwvY+RY(TP3TAP%(xO|c7qZ`RBrGgGNA6z@G%Ki_^6rs! zs{zCH#`FW&2e|sMFeoH9{7-23<N&*a9Hfa`{UqpXilr7Zmf63mHC+%Z`|V1ja?ni~ zO+YaYA_?kyoJ!E-K@EyQrzI(<^e{m{Xoot9S)7BOsbLu699bfkqI0DQN(}@c;t9?# z%`5$?PV-Vz32^0w|BTk5Mc`Is(7pj?;_w4nD!?CgJBF$w{7o$cSl;{%r6f06J1NIY zhE6LmW5Towh}C$JE+hvlU?{70e885HX2mO^sbh&lJ!0M(U65E!C-ONBwepH?y1+-k z8frO41vUN0Jc+e2{}Q85hTO<N7^x5_$VACSUYkfKuphaWRl786whQx;d+k!AYk_WP zMpM|4aPNrIDY@wpdc)H0Kc5FElqh?Ys;<dF%^LQ*HFVH`5x7s&3XU$Cg-H{)NYrRX zEN)=ZVV}H)TZv5po632{wTcxvTtg0w`~WrpebvYmUd&_zCy45Dbp(~sSeWo_U`!AO z;mJKL52fu4g6VHcYg@N0&9HQyMMQ$!mN_8DII|>ye<O@iu5Q;!_FZ%{olQeQW;Bp$ zMnf@sItyOxexSx;zWnjeS)Q%4Ws+^CvkxCXKEasFVs)3LU+i;xJi09&-4=aQ<k4;M z=(c!tTRgfg9^Dp?Zj0{Equb)qZSm-~cywDlx-Hs1k8X=cx5cB|;&dMvDLD&Y%+!ln zIGfF1%x1HvFA6B&H6wxl8n{f)Kxkm8^7E9;%>Q2y&cYd`2>fnGuBQ7rD?4)^pgf%s zO<S5RUX|^7mHl=I&~--mj0=W{g$!VUZzX1&-~$N{;EMwsy51-O=-`JkRdJun3|Op= zh6fFUO2oV^iel$5yfZ3n=PyviU}v05)0y8S)K@d2TxUWez_hEg=IbWvAk+n*$vOt4 zc-vJSxP1nw`;`HB;AjBezAFYNoLRzBBok5Qp$unC;vWJS7QQ%Av}n`P2T|3wCRl9n z2k*eN`F4jv3g83|a=_Y}0NFAlteySJYGBsEm{8e9ZTG61+8~B!Fe2^5b}#o~-~lC( z?U;r?LZDLs-#}cLZj@AoW{g8gMJT*51$Lj{gIaGTOi+x;8FRc$l)%YeV^yMn=%g%Q zN*DZVht2VDt)&|Hv)QVeP5=O<Dnx836>P@g3;4uf)Ie?K55kP$)Tf|WBLJ?dt1GJ) zScZmr#u`}E=UX|)ih4dzRKv|cBG~crrO(XZQ%pR>M@qnxW7m=s#Hf5wp+dZN@pT~~ zKyP$#Lv>Ih+}u%tB~kh0#Y}1+HU+bm_>%>RSM>=dgSHLe?3UGIpc}Mj9&_cogqDGh zDE71|6Y{F1Mzgwr3(8c@&KUDSgLlkMGpe+laavSH0npX3FdS~mlnrCM@JNBcsH*Qi zga;k$U7%%w(V?_m*88@@^MZyzPt#;53r?&(g9lyRgvd_CXmqsBg=q<khAq#UtsAO@ z3R#(kC^k$%;A!tS{H5y;hO)h_(8~6(N{WK*9hbi-`QBeoK++p#AQ~oNLn^^9?XNR9 zP3<Va-(<#=Ek(dyG);i5wIkRlLL4$guqx1e1`oPK8))1GAHolTVyt}XdRM|WR6cW$ zisF9h#-~Cq#JQkcKec6^A}LGZY0I?>PrnTdn<KOnH^s_>;)Y9&LWYL~1v{v~22?6g zlED`x_8p<P5|p$7y@sQrQ?73nrD_Ws4l=A$uo3`(ILh#t!}^FzJ}lKJ=W&gYW<H>H zDB)jNJF)8!e*ooRvFBKdg1(394QNCNDF8r_>0x#Rz-AgsGb9lFOHBjr)r%KkTi7YY zK(Ro^W}vNsm}J05MjSGn)9_QEut3#O!WW9f;Dz4|2x$3&bEx#fP@2IP0ERdVP(;ZK zK~Oaj1{NOT%;Z)t<QkM0s0B+F$S+r`B$)uQW=BxKqE5sMFp&@hp@JC*Q6X^HjR=rt z1`5!aL5Y0fNbA$yBlhYAm|imynqgMZB?TnFf<*`vEI<NUQ~;0!CQ%^<C_Y6L|sV zIQ(bE+`Vuu74udr09Y8!B!mTBf({SEiR=lAT!>>8!ssaYH$ZxaP#hLq6gOt}W2|C^ zDh%=}m`B)=dkJ`=uy}zX0b~sKvznBkRe=nJH-rYrLj;Fh8y*Ma&8+JlISN26JwPpk zVF1a2?I6)5e1*V-V41-`mMJB-9LW#?_%av}Nev3{UEm;<!9hw?sHDN6cnb=aMM4qV zR@g*BYJ&voLjW_XI|wLz0SjV1Y)_YOy^0E$pQF^$IKN+DXcQ}GLT!aGG+-*=H(V$S zjD3-7^k!pIVcZUB5SmE_(g}4uBM$*{u!IffU=^DtL*Q_Wc?fKYf=Xg3G&QQXz8GV; zB-n++_34Xn2ZbFNiZdTXxzpzaPJA3EYBegH`hl9EeidM=sFWEz;agguDC0&PFqBCQ z#*S2PLGwac2;bVaWq%r~f~<lcGO#ku_RKX(ABF=0@{eN`0XB-lFJihEPzk$7VQIS; z0_Q)l8Wu*}s<%`qVY&xaGi}+Q)u5vD#Bc*e{$bjxaTN7G1Fy7}PVv^OD1pC_8wxC{ zVWv`1V+&z11xP5PrXkBx1wsPE3VIVz@@rf)@r$770kJB~Q*IE_sC45~!{JZ~Sq5b* zGp|F6q7EZR_Lmd9BsBP7F=PIEFjtCQ2(m7;3{o_2AjidvP-7-Coa`LFBsFqfg!qq~ zY5ZcwGQpRss}Bb9qwJ$>ch$8Q<2u{EU8Uco*>XG2=h+&cSI5dfcSm5JxbI)$=^(c` z0$OyZu**{JoC}sJwiiID^0@NnUMt0BiRqK_Eb!;}yx3Y{o}05<=5eu4!yWiB&x(Bw z=;1MkT+P#BzXcxCsZN}lSH-3ZeC5tjwSivj6!D7TDaj@+{3^x945(6^4*cAI?RIEP zf#C4!yKEb!(KdoNA6`$B)%DGMk*!|?<zG+V!4S+>OZf468a&g_i1-y0xSnsHWrXL* z$FHH4*Ha+ro7?D3W(vM^DX3mg;f*~{Xj_Zo`D;7|^}0HC^tw2t^x7Shas}KGrq}K) z)a%+ACew?<+jN41U><JPiFvTyDfRKm;jO;8y&KkQg-WAYNBw%U@1wNdY+35#4}Q7g zIAy)CIdSG7I2Ae5&GsP?cgH2qkN0WV=z*zO9M-&Ga-Ih9>M&+E>W!1m=Dj=UT(49l zRViVwk!J`s`blx07HU|RtEMN0I{|H_Zy#~n=!HoR8pLv^)ek4uUeS9@MsW(n5Q5>s z{XS~h_noAwj?o{RV1sz0)PXLMH)@a;+SpJ)^*%85Nr0@@DG$c3ZpMv#ttb1(ep1-v zD1EdjN*tXSR{6bfAU$3D5~sl6*}hk$IHq{q`U=FSDj)aiA{R?`wE8|3(%%c=!e$*R zPX|IgSQNWFcn+*IdzY?&XV8HC5mZ$t@!y#`)?cx)Z@c^t_U%oyj;>uvqt&2F{x+Mq z(v$7mXgis2Ca#rqvRzGzp@)~*1d}*EGrbx@7S%ytUv7JAKeIOaI@{i^mkxrfz_tKt z{A8Y+_9JIzPTohG$>ugm0IK|Ufwe!n;rZO*(%KX>fn_Eu+uU~bW40_R7ao!R>b6vC z12yMKe=DXaAb@4DEk`%oOqZi&cZ|#&Z;nyRkif&vQE|N=Fc@Vw?SnDM6LbWejI<n5 zAqPOtPlg@u)-KBJ;5cZC`lh{)g?RZ(w4S3>D5iB~NHrT@y<ZwnS<6g@SDVJP-P~kg z>2{PKF!L*dbrKj`!WyotNfIrqrdG>IoV|?}c`?Hb_!hRV$#k3!3~fE5V;~(@lYiW1 z>pRnws|_u;Q=)orioXE?zARemM{!S01AAqLRFbEXdbigxVxLcnVwL=w+-|Zx{ST>b zxpO<;E}TolB=j}SRxVnCWuU^kT(69W!}VBr5%-9T<!U=mY$sn|&$nA($M<iMAj@ij z0A9V0(##En^U`&Q)Xw%M&T4A3_NpnN$2MDXW4+zV2{ane_hnVTO>DH(2axJ53PES! zVyDYLTjsC}@p0zdlYJVA*S%$qY_mH9+Qt1&uL<B<cDoy5>BV>71oY<L=lv}Wno3Vz zSFxO3Lg0{X%H=A~3N{6Hi0>vF7y+<ICosxLj+MoIwFC+!Ti3X+D0RWvrYG&FNgb6t zw4`<=siTc99cjOc<TY4K)f(6AuJ|28IzojR*C(nX9emsYN{1TZbz4Y}jgf=C8d0jp zUST7g&5Ay8(zyUGoZQ~LS%U;gC;4hUDI#SPjII6jY)76Op2)UaU^ypJY<Mn0v*uN_ zev`S#8t7@yZ<lkd8!f!d@3qAOTg%>E|HX^xEmq4E|AaS-dAtV2$7($vttc~bLEA%- z6!7=a=51khWwy=L&31l0|G9`6W=m9_ydc5))~tG=`PilV8YGiL>i^)s-$3V2f6S63 z`tkX%;qT|(?_zds@Zoa<>g+cw5QRTyH#ga0zN|_-b;QN~Z99Isr|spc_WRp@CwiNN z*8^MXYi73%9FwO>bTfwui<kRcgMw;XD1Nwt@H0y9o^G?vc87+pIJ|#u-q)&>t>NFu zNcL@XyIobCmA{$*rW>zIdj-K}o0=YrS5=$YI^mK^^SGA|NKSlPuV5RgI%)J-_46i! zDYDuF`P*on!qVC(wFDl&x?ZKXp#MKFir5N2Vgswi)8uUyZE-F*6k48FpbX+{TXX=k z4rS`z2KRGvU-e%0wH0sHvBwl8Y4Jz-s-h4)dj529=}nYpO<)?&n&7msdHG^@I@zv% zFrwF-)Y<G6vFI5xLu#B^ARB|9WE!Lqk&4FV+T|>XQkq7gOi7w64*yds%F<Bf8N=fj zJf%v=AP>_tl7wZ66Uj-o+}K6sKfnL>DSH-}=eO&HlbrF-KR<<KY4-eim_|C|GRidN zspd%*vw$g<Yf5;;1J0u`<(wosPlXPGlycnWg=e9lFi&hGD1D#Bv*+`heDnNI*V+I6 z;j6!0uhyHd{`BtVPpdD0yMO*G{YUcM=I`t-`^P&*UVS0H|Nig)^CkUTL9iN)j8`y^ zfP&AzF$zW}wU`z<mr0OhfVv8mj!6~~rErgHLPZ1*6P<7k1)`j2%0fIunWw4QbVKqT zYJK<3t4>PAiY7UW6Gj;2JP4uLEQ~S<6w9cDp@?*v=PZfyFsFpcn1p$TC+$NPGbQCN zrC$A&{nz|=|Gm;Te|!5?ynXxq@Adz_yb(EBUZ-y&{^iS`SNw13*FWFfEWblaeQYfA z(<kL(i~F65EjakMD~9`vTDRZe9-d<J4HPOAifNI^+w7lm*MfL?h&xgXS84hOBq+u_ z#QWMAlBBz(ohp^_m_)~zyLfLx^0pk#BM37j8TA<usuGFc6Q5%Z^o7vHOGy4OggG`s zwM62*DD_?qQZ`@S2{e)%yR;a>6)m;8ug9oh?7djXzhz+`@pmcz@rRL!w@R>s2Y&BW z4}C-^FB$3~fxBj+{rZW~$RBI`{40WvI(`R1<K6bN2N>N2iXH^WfI%%T{JB3??t-5l zjLMsIy6)IH264*^ejXZ-`UO8{mKv?g;e$vG?_Qy^iH+8^^I$FFLCNMWBsvx8PLD`= zJ<tK-s<;pk`?uR5(44@ahml<Grp18`drYJA_{9eo?8CosJ)Ip8{=~BkQCd_Tu<5~^ zZm=$I?Dr}#>f!$F4(QG;Pj!6QZKBnEZz@&CKH96bIqprx#>tTO+N~~oTfO`Ah);Q( zT(d!;|2A5;#qjr$xGQ>JgL=<lmV+@sAvB<{*|=~Pgj<f{_{g;Z(A=hA;=q+pfWQwI z@AW1oK55L%o&!`LT;u{O9y<n!)anxoWyi;gK4OP$$GbXk?2S84Kh}?eb+oZR;%FNx z&yM+M-zU~Mtx2hN*jmI?T}ri9YZp^3QmVCfhnU(UrOKubjVVsYNR%<Xjfo~syJmUW zVNV=!+L+onR4(*qmxLl_2Fv$!c)$!K!D*spJq?cum322WFiwUI><^M*sWB0<s{BrP z3>`81Vq;KdU|<YN-ZLr&E%b)O;QgL>7?c<h41>}mBVkiK?K^;9QPDnL46M7g{ruTk zx0flQ*3i(GEjlRfg}Tg`pcj_k<y`x;J=`_Ldq0aHJ_;Kb!Y?i&!~lL3zpuqA{A~f& zCc%qAceg2E*{%p0%0=@7YgQW+;IZAFVA;oRPH^YMU1YAm)elviX*xSXOb+0{coNFr z<Hg-jQXCp}!*O#_FF?>m2+bP5Hx9Q;o%_b%TB&p2SX+}iV<K&J>U{UjtL6%eHt=d4 zy~)0f?p8Kb<{lVRJ=$!)fhj<kB8($T+X-g<8?7uib8L(uxj0)i9iMr=!HEz+zl)W* zT%t0yw^wd?|9pE@s4Uy7Qinj}-Ghe*2f|Zxr0>8(_QBH!<1eR06vIr*vWS%@AS2MR zH$xZ1A~OA#FjZb4qfGxX$D25y-jo_<J_M9{pROz}T-lvLuIjUZqG+#B@P7Rtla@zS z54+GZ3J>2!i`zltxv#`gFeqEw3vKCYdgA@qH*%i$YPWS`s(RLGHSwN2TB?th>Z7Il zX<MrHXaQE)d$6F^?%qQM2wK;Xf}WOkjuT)zdk+)zHMnz-09))iM$p$*%Mk+WXD-Qo z=$>IaY2S4V*+)P9qo4lKPyY~pdUIT>X52;_w;>Od^V@CqeYAbsqrL;SbF1)!DFhPt zr<>IpWXem!o(2|U&VjK)m?nyX`t7>HCs0ZJU_?xsxoG1{V>SQx(rg^FbO)PvMkzN5 z$EUWi3sgE&gVI_P--CH{9ep)lXUTSMHluj$utqD!00Y}IvS#6?+MEco3;umZ#MA~z zi_Unhvu~~u<K515KxZP{?W~ustyb`pX+B?ML(8H(`F52Uw+7THlH4I&$qFGZhH6t0 zdS=Fk6;kK7i+QwhBnD}o&EG6>AWH(UGH`3hwoZ>SFCLn20PA9f%feS#vH<o(s2m~I zMP5DsodboIR3v0391+oM`zqTc>-mjq=0hP~+Ym-e52&>@*kIJ#8$@8c8qi-lJ@Bh6 zpF<TJoVF17w;!}J9}8+t6$f*Dq{_C+EcA7rh=JU{b5Ze)n<|0$!Pw86ZM57LPOc(! z{xVwtyRFvKTK2zdKTuv)ZQD}Rpc&rzIMWU;pH0M*`f1|=j>0EVHIZg{bi3HL50iQ3 zF-Bp`X;=KE-BD9+Te468V8HhHPM4^Z`<^Pgf4#`Ap@V3B_o}Gtlf8$D#zOb8v`Ifq z-)2Ak#o4DY5W13vgog0<=F4&bZQ3w+^sTE<KKTB2T@u#mL)H#LE7lbLbM}whY_l!5 zV%8A<)=IAuTYFQ&ICL$aMvE(=uj0Ea(!?APzcLIpA!c|Ao80}HZ|2nojoWxJPyESd zJW~T_h<D?{{wYFOZHhS3w9FANb7pOhm>*^{Ny{F<ojC&1JUs6lao&>8u1Z(R75?qk z{HxEJ!_?<p>6lcE8F!5x8t*ZwwscmmuR*ho1dPtqIR2~psNqxYuBxjD-<6Igk7?-0 zE{{xGGb47WNNW<yxuFJ9k+ZQ>toqmyTgGknall;V!&fu!Zjt?Sl@6V&Uas8!x$3)# zn{ySU?}g0OeQY*}(R!V{T@yQOpV;Ca6I-8sVgrZq<4o+c3`DyW(Cs534<89w<Ig=3 zn5g{{MXWkp#DbVOzK9(nV|5M0LR7XGAB3oICR$9^c$MDyWZ<gS<QI!o@?+Hs*e^4C z(MG)$BMYysj}$B#Fy4{wMgV@8M(a1X#k(J#bi90JLupu`1cmP$95}Lps7NR)+=v`I zh{dXNRcv&=s<tVAc6Ifc^UC0#&4DhePCoyonKC8PVw|?`emZr(X!T22)B2QtpsJ%y z3;Vdr9$AVNaJ#-UFN<~tl4*N;W9iW(f_c#-fUHlul3QLDJk|yqZatr-tHkh<8()v9 zN!>F9Yjpx61N=~{QB4+(R$hU0_7ghzeq+7Ylkev@neo~=o;2>a`Spzz57jmjHzLKZ za!^86X_4jM5Wd_(-|c8Iez<JwZU!i^X*j8hLf_8KfdaphnVSwLbLoqrRpBoDzP)*N zNb@Kef};60O{rt^{k!>kdmB|ORTFtYc{8nQLQlxSLXRrEc4oiO6QWP(;l+z*6MBN4 zRp{Xjm=7=X1iLVyXD$XkqtFw4xX`O$+avVCaYBzWeJr6@p1VDw)Dyu$VhL}A8Y1-s zIiz_M4d;=1a=6qhZn51f_GGWv;}mbz87cNWH>OaEN}>W4NFg~5xKLbbDHQdbn{wpL zud!Kqvhon;rnymVq%+rc=%PGVL6D>@<uc7V&uJ3Jp$L*(^DL%WNTZ0RX-XLhMNFa~ z2#I1@B*G|=j0u&ctSK0Zc5N?{*VDhQ!H&t&$=A5k<n`3|m)2h4i$Vzgd56ahnW;ze zx~#DkJi3&(99#L);)4Mb?uQ=1Bh)y-!^$g%J;5_y0%G$mbTYBAp^vRj9`7Ea9&uEi z6Koep?lf`J`GXgC71{$Xwd;AB)rCe~#QxEhd3lp1{u1r#`EnzaE==;VQ{L%=1d<}d z<eeO$M1I)yx0TJ1ecrWRQNQ0oSjto*0Sg`_++Bq{-SNXY0Cyd6*V*-IeK&TpU)gF` zH`{e{z81%~+udd|s7?r%C%}if6A(Rlh-A8QSocBObSo5EoIQ720Kf{_IAmROhttbN z%}&1kYnmFqrnw8Q_pfQHcTE#`18vL7IDAdxLU8Vf=hTC(U?L0-W0P_L%XLITmgih@ z&Hyc$1ZkA3G^UXbh1Q%&k<vKPJdU`Eq|RY|3lkC(9*cM<thu{@f#7beTMbd(zFaA9 zxl;YhRdp+R&vF&^Emv~na>W%tc)9W}$h*gKRc4)NE?9W`rtDj=<e>|e;K9BHOCGdf zi898#XTeg(S+Lak7A#dQSOQh@3tzC*;R_a`_n-@w!28!vzhH&K7c7YvnKHe9!3uj9 zEUDBi9P4{3n%43lw@TMqw8--9@1te<5~PDU4F{t3>-LT-R;q1;IIbHDcY_pU(yH>; zJU~pzbLD8}@}1R5(=kHT?uhHno8yw`DG?QYLN#M!>GNiufH2u?@Q7HG7@IeBr0G#P z4MbR+t^eSJkvZ8?r_Fb!z;De~)@cpP((iG+Xl5^BR&?yc%a-y77dd1He&FItvp7;5 zvDWQxfdk(xoj(zTB=CySOMdlh_`ROLd0U&{9X!j=!?TLe)AH<Lk+wlRYt`KWEQ?5v z6kG#F+~X(4kKTGoz`Ekx>$LVj!3EWvr?Fo3dZ?t6>B2KH9p@)yx-hr|L5Wx%Ur=_9 zU3jKNP6>J1u{+@+H(X!{d31rXH$Hg~Lp(VM7%vp6t8Lm}ohB5j1JqOt%Cf`ve;9dI zi-UG(m4kw#JLipRTzF}*QlwkyQ#(hnG;9P*ujkvA6-O~r9Fgd93=yjO97AfPV@L+! z!H%Ic$XJlZ!TlUV-j0EWXGns?FPOXCeWMO?-$*eq-k`#Rng{duUh&ly%YJts9c`Q| z=(Fo}06f)p_N!snQ^xx2dJS|Vs(BV@%%&2PIsbaKwCx`xYs)D`1ATN)LEZfA^cB#6 zo!M8QWq2XJ0vgESz5*JY$?noBJf#{%gA>|a!&P9!@-lq|yOEz(X92SDX`KaM%$L#n z?vKVxU}d1^G5C+tW6&|JtL@Y_%kQ!Gu!R*R!qGO{a2wi?S&wVoB}uL|Z4)FPsA_jN z_=7jEs-1&t;HLRHJA~>_iGBkA^@$4Y5oh%2fl_65FkaojWI$nx_zcvKvFI-+Sg|fx zMjn(rxn_*yVd{LEF(vgqa=jiI54cX#ostKNAW%ZitQCZTz7(y1@DW-8q36*GLZVNq z6_CTs+9PWPh~;H!1;Zi;$i)v6L3r94K`2L8oJ|`D89SXeVCXwi8yN0Ur(}dj-2-J; ze%B4fqIt^CHwsD|eH0GUod!4@`)JoLb!l)WsVhzzj-ZrWgwz!$2uGa8sqN|8<e<D9 z1I)eMoi?5#P!WyG*+@x*k9=*#`O8{#OZZW$DXvu4`EW`qH~r}2$37DKu4viG*yHo@ zVWAnP`eW-*w@4><9OWNTBlkQ*)EKA^t}I5VKC@4#PkFa2?VsB~hOsMVX(JXLH6knH zqA9I9HodfCwn!(&&S)#r5$9|@;0}r2Q!nAtDVIwc1f#W%am(dl9){yCmj=sIMDNSU zMQ|=Pkp^V+zO+v?noVit5UpKvdhCF<s%C9CUafk7h&E-1DWNBn#i5@C>I|}&)%Uh{ zM6^R4&RGA+Ji>ZU=7l38+DaWB(WV)RRLax)MYPKc{dPmznpCL<TSM9)D35Yv0OeKx zkpU+rn*ibt1TVttz}R<gfcmjY%4UT43i5z+0|#YL?2i+-=>5QsCH|um<{)0jPM9;` zn1H6VJS^0^T>%!RL$)hmRDbw(h1!*tBX=w`()9G~SfGK#qjUR@gVRRlmHLhaN{E>8 zmXxEt8y1FmrFiAR-oBkTjK_Oxhg4S>@L)D_H*AsC|FbKbYxwFjJDg1}EXqxa?8gUc zAqV&8DH?p_a(Z091SR8>Ha7hdz5a+!KLoGT*0FwweL&ZI4g6jk@J``tFyNDW8jnN5 z7zG9R>C7M(?HghTky_q>qpc#nM^h<gLoDe~Kf2X8no0>3rH8&#U+X)XN|_j?uhD=V zel!*IDH){cJ@vKvJ>(6I2$rI-QfJzAHYN{Pcxf;&&5Ien`>TW$Gclg$6scM13x*1+ z9m<!b4AOgKPpqMJK4lQP6-6GU1CERiP259=Cpn-b1Tn6gw-dBzYQ0GgC>1!%#;R&X z+w!==egBq^?oA+~Vyaq>-s8HXcu-O9Xj?<ikR;YykTDC(;2k64OwL$(;(eszBAl`G z6W>Q_cz&!Fb*i0DCQa2YAD6Ey4IeLTI<_RB!jl9c8OyvEv=7J*>d1@?$JqzeyA4QI zd;L!lS)hV?12}rW+Td+KhP-U#%@`xL0X6dS^@ZkqP!0;sNp+spfYH;2=HzitupGD= zAeN^L&B^d=5|FXcp}8@bsM7`+eNn*p=tKe+6=XblXi`=e2o%>_9zQTCc{Lzp^wy=p zamo9~D0^d->cV1`hL-0%eM{AlSS5f}oxa`Ko$4jjQyi^XiNKc~+$W))J1KKOIz7rH z8yg<zK9}R&HVxqI&3H#Ksd-6&-i&vY30XMNI^BxA*R9yNHe#<^kw|%Xg4R%Ek&5q` zpw-=_+Tv2A-UTM@9z`)CpM8(Z50}P%m!Dgan*e%ST*mnQs_b!qV|a!r@ZM#nJ?c_v zB%`A)h*!;@*&QA|o(<OF7ktt;^z@(&0F;7YzVFau#QHKf08mk#(HiaZMZ6xs=S%U> zgd7qm5F_FceXJwS7AWw!MpR4L$(W{Z@oQz5>hy`LI+Rz$5f|n`Tq5X94vq}8Z{rvo z9|#BMo}fH{mA~yKl4g7$?8`ktF@ddU$xJyS^+dZbL7&N&AcE7LiqRM0OF%47=}YiZ zs->Ib-!em0war(M(V4l%U=p6#mw;J13ry%}zwp17FF{wngyQtZ@7Am9qYnyGl|O-p z1mxm@4u#fRjK=sBiqr+;Jqr`phRbMBlR@F7IU112RWixL91Xq8a=(FWvUL`;sk<PW z1~S)t#`hS=qSrtknfZ${+<tPPfgFW_2$MLzpMmTj$!b_3oQOU9r1eo!s~dseuj{&X zrU@XU2boEsCjltGSPNMlem>IR^(k1$dT&<!b_<zvaqppL>S8TqFAw@?3mNfx01KI8 zZo5GivKB{?8kkP{Oct`wHBw)mg{-|)c%v+2ADgpS$Xu$kS;$Ncw~&Q|rC;pdLB~|D zg)F(6F*)|`yHjOnWaPM68b)MiWL_G#v*cl-Qi==7!^BKJvCiE{EU4CXg#GANXIO3g zmE*IiT+|*j98_}rMD$0>RmjL`{Rb?l{0CB>E<2GS^VqF?50a~p1(lcJOt}iF6r=U2 z)8#5;<X#C&PGH_6dCs|yfRXwN+`Gxm1J0Qt>AbMn_pY;jT37)LJMOg%yDRKoDEHfz zCE?VGVJ$o2XItP@FnWvDfCX;o`tWZZ>qBdlgL%2^P8#J<!AbYevm@vBJTS_ESe{`2 zyvJ8$q}1=VjE1t*zyEtXOC8ZFIC3(YAyz@Ro!}<{JIhfWMcJo#REJ^az#gN5gy)mF z;}d0Glu>~kFxIFzm8nQaT>8i8dG14k0X}KUUUp#8y<;yR>{3(qj^N|dp4B;m^3$5S zgVB*H#F0}?D4`EcHPJca@rRc(u+>q^Xr%&<_UrEf`s1N?_gKt4Yuw8VjD?OYk*K%i zjNi#s+Thn2*oE-k8Q}xX?-tXWj<laz1F=W6ypbsPP2N$+?QLZE;HpzXG?>6A%g9Yn z{d2h{%&()L21#-x#PLI3o|xswGzB~pLmuyfkZM3gJu3fA-sTtyVe!*t?=U1^Gy)x> zp2(^Z=uir`7uNz|XOC{MOR{4aJ+~bb@=wx^VeOYxl&{&@>=-?MH|S;Qf0(B8LhKk! z<1*NeVP|rL=@UD`*hM(P^l2Pn=jG!Ev}5)K`B>$lI(3jw)6-o@X2{G&w*D|dK34fT z&K2ZS`tUn^k00dYheef6Xlej?I6Y&KkJq)&-XNa`T<3*kj2~ZFJTN;I<L6ctHBjeM zR26yqEvMz{GpdT>6k*2mEwRV}m!c~2F{&az&)u~!z@w9vj8YZ(CEQ(Wu)IuFaaeXL zWaEd)PStx$9ph(I5!LZ?($wfXRz)11o{EX#w~YFreEi{K_qr~Qzo})=MWald`TB9H zLwPA1T=8&v&%!LuxBn*$PH;f<i~<eD^tAh14-;rYo=u>I<b*aa()R?JzDqLc5dy6O zrCXZG<6gctLYjqVmS!PUmm<wNlHiuFt4-b~IqvS=Y89R$b>8`;8II}0NV8w{N;65% zC(Zcrudl7q_k_|+^5N3V17%P4(6V)TKBYjNV1t^6i8`M^P@{KZjl$%7c1w7I^DF;M z`7fBPf?}^)uSq>dE=@eWSPY2dpJ*;kCJ*!Fp3Xgvw4`UegO#a<CEcD&GZbO>P4B(A zG}+j6rANx8$?%HOhsveN0^t#$KUGMG`)Br~3Q?plRY*AUiXOrA;a4iMSSxz(D|#Af zc^WAh1gyGcGM(0ZAuKpfz7SmM`%nHm4WkKR$PY;x;b#mIT3&3vkg(FQM&}C=T7DAw zLiS&&*`6v!1_vcmtqpy6xye++d!&j%ygq@UH_GH8sbVBOD4D81^pad`GF2AbBUKFI z^#G}2ga#wIyg{ocRg77Y@4sNM;B2X4YFxv~#ifd2!J(;Qd~EIw+Ym01JUB_JnBr1g z=qZXf<~G!_AgXa+x+_vGPvMgW4GFClTB~(+*lFKK+qcs`dyJ^^vWZXyvm)(%)log2 z+&5O+L+|X%n=C18!JP&Gvm^q7%#�V#Myc*C*u#uwP|27&cxe^TNt0-uyqS4i-PB zJ=cQMaXPG)Y*y_#cPi|5zFlPQI@;IE$#0gc?K~+SOy-+OG;w#HPFA^nJh{Djvqsx@ zlCRd2m#f7*g`u4U&-AmOo>>)mvAFwYSJPe0ml@2#pR@Ff#y~s9vSU)Iyd~Kh!XcCe zZ`N587~^)6rC+btE2})?SOB+W%MCX7pWlD`lsyZIA%^-NfARQv{5*ahKaZdDeEvTk KJ+klsegOcQ)RBn* literal 0 HcmV?d00001 diff --git a/op-chain-ops/deployer/state/intent.go b/op-chain-ops/deployer/state/intent.go index 5b91dbbf7c13..c737dab37dd0 100644 --- a/op-chain-ops/deployer/state/intent.go +++ b/op-chain-ops/deployer/state/intent.go @@ -58,10 +58,6 @@ func (c *Intent) Check() error { return fmt.Errorf("contractArtifactsURL must be set") } - if c.ContractArtifactsURL.Scheme != "file" { - return fmt.Errorf("contractArtifactsURL must be a file URL") - } - return nil } diff --git a/op-chain-ops/deployer/state/state.go b/op-chain-ops/deployer/state/state.go index 6fdc4f7dbae6..098fa7a731d7 100644 --- a/op-chain-ops/deployer/state/state.go +++ b/op-chain-ops/deployer/state/state.go @@ -98,13 +98,13 @@ type ChainState struct { DelayedWETHPermissionedGameProxyAddress common.Address `json:"delayedWETHPermissionedGameProxyAddress"` DelayedWETHPermissionlessGameProxyAddress common.Address `json:"delayedWETHPermissionlessGameProxyAddress"` - Genesis Base64Bytes `json:"genesis"` + Allocs Base64Bytes `json:"allocs"` StartBlock *types.Header `json:"startBlock"` } -func (c *ChainState) UnmarshalGenesis() (*foundry.ForgeAllocs, error) { - gr, err := gzip.NewReader(bytes.NewReader(c.Genesis)) +func (c *ChainState) UnmarshalAllocs() (*foundry.ForgeAllocs, error) { + gr, err := gzip.NewReader(bytes.NewReader(c.Allocs)) if err != nil { return nil, fmt.Errorf("failed to create gzip reader: %w", err) } @@ -112,7 +112,7 @@ func (c *ChainState) UnmarshalGenesis() (*foundry.ForgeAllocs, error) { var allocs foundry.ForgeAllocs if err := json.NewDecoder(gr).Decode(&allocs); err != nil { - return nil, fmt.Errorf("failed to decode genesis: %w", err) + return nil, fmt.Errorf("failed to decode allocs: %w", err) } return &allocs, nil diff --git a/op-chain-ops/deployer/version/version.go b/op-chain-ops/deployer/version/version.go new file mode 100644 index 000000000000..2456f656d45c --- /dev/null +++ b/op-chain-ops/deployer/version/version.go @@ -0,0 +1,6 @@ +package version + +var ( + Version = "v0.0.0" + Meta = "dev" +) diff --git a/op-e2e/e2eutils/challenger/helper.go b/op-e2e/e2eutils/challenger/helper.go index 3b037ef71c6d..87a51d96a5f0 100644 --- a/op-e2e/e2eutils/challenger/helper.go +++ b/op-e2e/e2eutils/challenger/helper.go @@ -11,6 +11,8 @@ import ( "testing" "time" + "github.com/ethereum-optimism/optimism/op-service/crypto" + "github.com/ethereum/go-ethereum/ethclient" "github.com/stretchr/testify/require" @@ -72,7 +74,7 @@ func WithGameAddress(addr common.Address) Option { func WithPrivKey(key *ecdsa.PrivateKey) Option { return func(c *config.Config) { - c.TxMgrConfig.PrivateKey = e2eutils.EncodePrivKeyToString(key) + c.TxMgrConfig.PrivateKey = crypto.EncodePrivKeyToString(key) } } diff --git a/op-e2e/e2eutils/secrets.go b/op-e2e/e2eutils/secrets.go index 7c934cc65f5a..cd4c91e1e09e 100644 --- a/op-e2e/e2eutils/secrets.go +++ b/op-e2e/e2eutils/secrets.go @@ -8,7 +8,6 @@ import ( hdwallet "github.com/ethereum-optimism/go-ethereum-hdwallet" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" ) @@ -134,18 +133,6 @@ type Secrets struct { Wallet *hdwallet.Wallet } -// EncodePrivKey encodes the given private key in 32 bytes -func EncodePrivKey(priv *ecdsa.PrivateKey) hexutil.Bytes { - privkey := make([]byte, 32) - blob := priv.D.Bytes() - copy(privkey[32-len(blob):], blob) - return privkey -} - -func EncodePrivKeyToString(priv *ecdsa.PrivateKey) string { - return hexutil.Encode(EncodePrivKey(priv)) -} - // Addresses computes the ethereum address of each account, // which can then be kept around for fast precomputed address access. func (s *Secrets) Addresses() *Addresses { diff --git a/op-e2e/e2eutils/setuputils/utils.go b/op-e2e/e2eutils/setuputils/utils.go index 9c82f3a5602d..12f6bca83f42 100644 --- a/op-e2e/e2eutils/setuputils/utils.go +++ b/op-e2e/e2eutils/setuputils/utils.go @@ -4,15 +4,16 @@ import ( "crypto/ecdsa" "time" + "github.com/ethereum-optimism/optimism/op-service/crypto" + "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-service/endpoint" "github.com/ethereum-optimism/optimism/op-service/txmgr" ) func hexPriv(in *ecdsa.PrivateKey) string { - b := e2eutils.EncodePrivKey(in) + b := crypto.EncodePrivKey(in) return hexutil.Encode(b) } diff --git a/op-service/crypto/secrets.go b/op-service/crypto/secrets.go new file mode 100644 index 000000000000..410de63cb3ca --- /dev/null +++ b/op-service/crypto/secrets.go @@ -0,0 +1,19 @@ +package crypto + +import ( + "crypto/ecdsa" + + "github.com/ethereum/go-ethereum/common/hexutil" +) + +// EncodePrivKey encodes the given private key in 32 bytes +func EncodePrivKey(priv *ecdsa.PrivateKey) hexutil.Bytes { + privkey := make([]byte, 32) + blob := priv.D.Bytes() + copy(privkey[32-len(blob):], blob) + return privkey +} + +func EncodePrivKeyToString(priv *ecdsa.PrivateKey) string { + return hexutil.Encode(EncodePrivKey(priv)) +} diff --git a/op-service/util.go b/op-service/util.go index 26960a911c6b..5c42d3de5dde 100644 --- a/op-service/util.go +++ b/op-service/util.go @@ -4,9 +4,11 @@ import ( "context" "errors" "fmt" + "math/big" "os" "path/filepath" "reflect" + "strconv" "strings" "time" @@ -132,3 +134,32 @@ func FindMonorepoRoot(startDir string) (string, error) { } return "", errors.New("monorepo root not found") } + +// Parse256BitChainID parses a 256-bit chain ID from a string. Chain IDs +// can be defined as either an integer or a hex string. If the string +// starts with "0x", it is treated as a hex string, otherwise it is +// treated as an integer string. +func Parse256BitChainID(in string) (common.Hash, error) { + var chainIDBig *big.Int + if strings.HasPrefix(in, "0x") { + in = strings.TrimPrefix(in, "0x") + var ok bool + chainIDBig, ok = new(big.Int).SetString(in, 16) + if !ok { + return common.Hash{}, fmt.Errorf("failed to parse chain ID %s", in) + } + } else { + inUint, err := strconv.ParseUint(in, 10, 64) + if err != nil { + return common.Hash{}, fmt.Errorf("failed to parse chain ID %s: %w", in, err) + } + + chainIDBig = new(big.Int).SetUint64(inUint) + } + + if chainIDBig.BitLen() > 256 { + return common.Hash{}, fmt.Errorf("chain ID %s is too large", in) + } + + return common.BigToHash(chainIDBig), nil +} diff --git a/op-service/util_test.go b/op-service/util_test.go index 12d28f3b3414..940bb7001fc8 100644 --- a/op-service/util_test.go +++ b/op-service/util_test.go @@ -3,6 +3,8 @@ package op_service import ( "testing" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" "github.com/urfave/cli/v2" ) @@ -30,3 +32,57 @@ func TestValidateEnvVars(t *testing.T) { invalids := validateEnvVars("OP_BATCHER", provided, defined) require.ElementsMatch(t, invalids, []string{"OP_BATCHER_FAKE=false"}) } + +func TestParse256BitChainID(t *testing.T) { + tests := []struct { + name string + input string + expected common.Hash + err bool + }{ + { + name: "valid int", + input: "12345", + expected: common.Hash{30: 0x30, 31: 0x39}, + err: false, + }, + { + name: "invalid hash", + input: common.Hash{0x00: 0xff}.String(), + expected: common.Hash{0x00: 0xff}, + err: false, + }, + { + name: "hash overflow", + input: "0xff0000000000000000000000000000000000000000000000000000000000000000", + err: true, + }, + { + name: "number overflow", + // (2^256 - 1) + 1 + input: "115792089237316195423570985008687907853269984665640564039457584007913129639936", + err: true, + }, + { + name: "invalid hex", + input: "0xnope", + err: true, + }, + { + name: "invalid number", + input: "nope", + err: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + res, err := Parse256BitChainID(tt.input) + if tt.err { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tt.expected, res) + } + }) + } +} diff --git a/ops/docker/deployment-utils/Dockerfile b/ops/docker/deployment-utils/Dockerfile new file mode 100644 index 000000000000..c0f82e5a3405 --- /dev/null +++ b/ops/docker/deployment-utils/Dockerfile @@ -0,0 +1,35 @@ +FROM golang:1.23.1-bookworm AS go-base + +RUN go install github.com/tomwright/dasel/v2/cmd/dasel@master + +FROM debian:12.7-slim AS base + +SHELL ["/bin/bash", "-c"] + +ENV PATH=/root/.cargo/bin:/root/.foundry/bin:$PATH +ENV DEBIAN_FRONTEND=noninteractive +ENV SHELL=/bin/bash + +RUN apt-get update && apt-get install -y curl git jq build-essential + +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > rustup.sh && \ + chmod +x ./rustup.sh && \ + sh rustup.sh -y + +RUN source $HOME/.profile && rustup update nightly +RUN curl -L https://foundry.paradigm.xyz | bash +RUN foundryup + +FROM debian:12.7-slim + +ENV PATH=/root/.cargo/bin:/root/.foundry/bin:$PATH +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y bash curl jq + +SHELL ["/bin/bash", "-c"] + +COPY --from=base /root/.foundry/bin/forge /usr/local/bin/forge +COPY --from=base /root/.foundry/bin/cast /usr/local/bin/cast +COPY --from=base /root/.foundry/bin/anvil /usr/local/bin/anvil +COPY --from=go-base /go/bin/dasel /usr/local/bin/dasel \ No newline at end of file diff --git a/ops/docker/deployment-utils/README.md b/ops/docker/deployment-utils/README.md new file mode 100644 index 000000000000..450af3423b11 --- /dev/null +++ b/ops/docker/deployment-utils/README.md @@ -0,0 +1,16 @@ +# deployment-utils + +This image provides a minimal set of Foundry and Bash tools for use with builder images like Kurtosis. It contains the +following packages: + +- The Foundry suite (`forge`, `cast`, `anvil`) +- [`Dasel`](https://github.com/TomWright/dasel), for TOML/YAML manipulation. +- `jq` for JSON manipulation. +- `curl`, for when you need to cURLs. +- A default `bash` shell. + +## Image Size + +According to `dive`, this image is 255MB in size including the base Debian image. Most of the additional size comes from +the tools themselves. I'd like to keep it this way. This image should not contain toolchains, libraries, etc. - it is +designed to run prebuilt software and manipulate configuration files. Use the CI builder for everything else. \ No newline at end of file diff --git a/ops/docker/op-stack-go/Dockerfile b/ops/docker/op-stack-go/Dockerfile index 18163a86c3cc..a395968fd07a 100644 --- a/ops/docker/op-stack-go/Dockerfile +++ b/ops/docker/op-stack-go/Dockerfile @@ -101,6 +101,11 @@ ARG OP_SUPERVISOR_VERSION=v0.0.0 RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build cd op-supervisor && make op-supervisor \ GOOS=$TARGETOS GOARCH=$TARGETARCH GITCOMMIT=$GIT_COMMIT GITDATE=$GIT_DATE VERSION="$OP_SUPERVISOR_VERSION" +FROM --platform=$BUILDPLATFORM builder AS op-deployer-builder +ARG OP_NODE_VERSION=v0.0.0 +RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build cd op-chain-ops && make op-deployer \ + GOOS=$TARGETOS GOARCH=$TARGETARCH GITCOMMIT=$GIT_COMMIT GITDATE=$GIT_DATE VERSION="$OP_DEPLOYER_VERSION" + FROM --platform=$TARGETPLATFORM $TARGET_BASE_IMAGE AS cannon-target COPY --from=cannon-builder /app/cannon/bin/cannon /usr/local/bin/ CMD ["cannon"] @@ -150,3 +155,7 @@ CMD ["da-server"] FROM --platform=$TARGETPLATFORM $TARGET_BASE_IMAGE AS op-supervisor-target COPY --from=op-supervisor-builder /app/op-supervisor/bin/op-supervisor /usr/local/bin/ CMD ["op-supervisor"] + +FROM --platform=$TARGETPLATFORM $TARGET_BASE_IMAGE AS op-deployer-target +COPY --from=op-deployer-builder /app/op-chain-ops/bin/op-deployer /usr/local/bin/ +CMD ["op-deployer"] \ No newline at end of file From dd7f5dbbb2dc10e6bdf4923a406e93fd7214f566 Mon Sep 17 00:00:00 2001 From: clabby <ben@clab.by> Date: Sat, 21 Sep 2024 13:26:25 -0400 Subject: [PATCH 225/264] chore(op-e2e): assert that the channel actually timed out (#11998) * assert that the channel actually timed out * fmt --- op-e2e/actions/helpers/l2_verifier.go | 13 ++++++++++--- op-e2e/actions/proofs/channel_timeout_test.go | 16 ++++++++++++++++ op-service/testutils/metrics.go | 4 ++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/op-e2e/actions/helpers/l2_verifier.go b/op-e2e/actions/helpers/l2_verifier.go index 4d201a88fb0c..1594e1eb368c 100644 --- a/op-e2e/actions/helpers/l2_verifier.go +++ b/op-e2e/actions/helpers/l2_verifier.go @@ -49,8 +49,9 @@ type L2Verifier struct { drainer event.Drainer // L2 rollup - engine *engine.EngineController - derivation *derive.DerivationPipeline + engine *engine.EngineController + derivationMetrics *testutils.TestDerivationMetrics + derivation *derive.DerivationPipeline safeHeadListener rollup.SafeHeadListener syncCfg *sync.Config @@ -88,7 +89,8 @@ type safeDB interface { func NewL2Verifier(t Testing, log log.Logger, l1 derive.L1Fetcher, blobsSrc derive.L1BlobsFetcher, altDASrc driver.AltDAIface, eng L2API, cfg *rollup.Config, syncCfg *sync.Config, safeHeadListener safeDB, - interopBackend interop.InteropBackend) *L2Verifier { + interopBackend interop.InteropBackend, +) *L2Verifier { ctx, cancel := context.WithCancel(context.Background()) t.Cleanup(cancel) @@ -162,6 +164,7 @@ func NewL2Verifier(t Testing, log log.Logger, l1 derive.L1Fetcher, log: log, Eng: eng, engine: ec, + derivationMetrics: metrics, derivation: pipeline, safeHeadListener: safeHeadListener, syncCfg: syncCfg, @@ -238,6 +241,10 @@ func (s *l2VerifierBackend) OnUnsafeL2Payload(ctx context.Context, envelope *eth return nil } +func (s *L2Verifier) DerivationMetricsTracer() *testutils.TestDerivationMetrics { + return s.derivationMetrics +} + func (s *L2Verifier) L2Finalized() eth.L2BlockRef { return s.engine.Finalized() } diff --git a/op-e2e/actions/proofs/channel_timeout_test.go b/op-e2e/actions/proofs/channel_timeout_test.go index 1e97a5e38d3a..09ff333922ab 100644 --- a/op-e2e/actions/proofs/channel_timeout_test.go +++ b/op-e2e/actions/proofs/channel_timeout_test.go @@ -17,6 +17,11 @@ func runChannelTimeoutTest(gt *testing.T, testCfg *helpers.TestCfg[any]) { env := helpers.NewL2FaultProofEnv(t, testCfg, tp, helpers.NewBatcherCfg()) channelTimeout := env.Sd.ChainSpec.ChannelTimeout(0) + var timedOutChannels uint + env.Sequencer.DerivationMetricsTracer().FnRecordChannelTimedOut = func() { + timedOutChannels++ + } + const NumL2Blocks = 10 // Build NumL2Blocks empty blocks on L2 @@ -62,6 +67,9 @@ func runChannelTimeoutTest(gt *testing.T, testCfg *helpers.TestCfg[any]) { l2SafeHead = env.Engine.L2Chain().CurrentSafeBlock() require.Equal(t, uint64(0), l2SafeHead.Number.Uint64()) + // Ensure that the channel was timed out. + require.EqualValues(t, 1, timedOutChannels) + // Instruct the batcher to submit the blocks to L1 in a new channel, // submitted across 2 transactions. for i := 0; i < 2; i++ { @@ -103,6 +111,11 @@ func runChannelTimeoutTest_CloseChannelLate(gt *testing.T, testCfg *helpers.Test env := helpers.NewL2FaultProofEnv(t, testCfg, tp, helpers.NewBatcherCfg()) channelTimeout := env.Sd.ChainSpec.ChannelTimeout(0) + var timedOutChannels uint + env.Sequencer.DerivationMetricsTracer().FnRecordChannelTimedOut = func() { + timedOutChannels++ + } + const NumL2Blocks = 10 // Build NumL2Blocks empty blocks on L2 @@ -148,6 +161,9 @@ func runChannelTimeoutTest_CloseChannelLate(gt *testing.T, testCfg *helpers.Test l2SafeHead = env.Engine.L2Chain().CurrentSafeBlock() require.Equal(t, uint64(0), l2SafeHead.Number.Uint64()) + // Ensure that the channel was timed out. + require.EqualValues(t, 1, timedOutChannels) + // Cache the second and final frame of the channel from the batcher, but do not submit it yet. for i := 0; i < NumL2Blocks/2; i++ { env.Batcher.ActL2BatchBuffer(t) diff --git a/op-service/testutils/metrics.go b/op-service/testutils/metrics.go index 617d2ded3c03..421d32f2109c 100644 --- a/op-service/testutils/metrics.go +++ b/op-service/testutils/metrics.go @@ -14,6 +14,7 @@ type TestDerivationMetrics struct { FnRecordL2Ref func(name string, ref eth.L2BlockRef) FnRecordUnsafePayloads func(length uint64, memSize uint64, next eth.BlockID) FnRecordChannelInputBytes func(inputCompressedBytes int) + FnRecordChannelTimedOut func() } func (t *TestDerivationMetrics) CountSequencedTxs(count int) { @@ -59,6 +60,9 @@ func (t *TestDerivationMetrics) RecordHeadChannelOpened() { } func (t *TestDerivationMetrics) RecordChannelTimedOut() { + if t.FnRecordChannelTimedOut != nil { + t.FnRecordChannelTimedOut() + } } func (t *TestDerivationMetrics) RecordFrame() { From 53080c9ff58d2da0c056eba9e2708bde92c61415 Mon Sep 17 00:00:00 2001 From: clabby <ben@clab.by> Date: Sat, 21 Sep 2024 21:58:04 -0400 Subject: [PATCH 226/264] feat(op-e2e): Recover from bad transactions in batch test (#12039) * feat(op-e2e): Recover from bad transactions in batch test * fix * clean * naming nit --- op-e2e/actions/helpers/l2_batcher.go | 21 +++ op-e2e/actions/helpers/user.go | 4 + op-e2e/actions/proofs/bad_tx_in_batch_test.go | 174 ++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 op-e2e/actions/proofs/bad_tx_in_batch_test.go diff --git a/op-e2e/actions/helpers/l2_batcher.go b/op-e2e/actions/helpers/l2_batcher.go index d39c324ef9f0..f1f10b362b88 100644 --- a/op-e2e/actions/helpers/l2_batcher.go +++ b/op-e2e/actions/helpers/l2_batcher.go @@ -136,6 +136,14 @@ func (s *L2Batcher) SubmittingData() bool { return s.l2Submitting } +// Reset the batcher state, clearing any buffered data. +func (s *L2Batcher) Reset() { + s.L2ChannelOut = nil + s.l2Submitting = false + s.L2BufferedBlock = eth.L2BlockRef{} + s.l2SubmittedBlock = eth.L2BlockRef{} +} + // ActL2BatchBuffer adds the next L2 block to the batch buffer. // If the buffer is being submitted, the buffer is wiped. func (s *L2Batcher) ActL2BatchBuffer(t Testing) { @@ -143,6 +151,12 @@ func (s *L2Batcher) ActL2BatchBuffer(t Testing) { } func (s *L2Batcher) Buffer(t Testing) error { + return s.BufferWithOpts(t) +} + +type BlockModifier = func(block *types.Block) + +func (s *L2Batcher) BufferWithOpts(t Testing, opts ...BlockModifier) error { if s.l2Submitting { // break ongoing submitting work if necessary s.L2ChannelOut = nil s.l2Submitting = false @@ -175,6 +189,7 @@ func (s *L2Batcher) Buffer(t Testing) error { return nil } } + block, err := s.l2.BlockByNumber(t.Ctx(), big.NewInt(int64(s.L2BufferedBlock.Number+1))) require.NoError(t, err, "need l2 block %d from sync status", s.l2SubmittedBlock.Number+1) if block.ParentHash() != s.L2BufferedBlock.Hash { @@ -183,6 +198,12 @@ func (s *L2Batcher) Buffer(t Testing) error { s.L2BufferedBlock = syncStatus.SafeL2 s.L2ChannelOut = nil } + + // Apply modifications to the block + for _, f := range opts { + f(block) + } + // Create channel if we don't have one yet if s.L2ChannelOut == nil { var ch ChannelOutIface diff --git a/op-e2e/actions/helpers/user.go b/op-e2e/actions/helpers/user.go index 4df96e67cb6a..65a39ce6aa4a 100644 --- a/op-e2e/actions/helpers/user.go +++ b/op-e2e/actions/helpers/user.go @@ -130,6 +130,10 @@ func (s *BasicUser[B]) SetUserEnv(env *BasicUserEnv[B]) { s.env = env } +func (s *BasicUser[B]) Signer() types.Signer { + return s.env.Signer +} + func (s *BasicUser[B]) signerFn(address common.Address, tx *types.Transaction) (*types.Transaction, error) { if address != s.address { return nil, bind.ErrNotAuthorized diff --git a/op-e2e/actions/proofs/bad_tx_in_batch_test.go b/op-e2e/actions/proofs/bad_tx_in_batch_test.go new file mode 100644 index 000000000000..c3259211c300 --- /dev/null +++ b/op-e2e/actions/proofs/bad_tx_in_batch_test.go @@ -0,0 +1,174 @@ +package proofs + +import ( + "testing" + + actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" + "github.com/ethereum-optimism/optimism/op-e2e/actions/proofs/helpers" + "github.com/ethereum-optimism/optimism/op-program/client/claim" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" +) + +func runBadTxInBatchTest(gt *testing.T, testCfg *helpers.TestCfg[any]) { + t := actionsHelpers.NewDefaultTesting(gt) + env := helpers.NewL2FaultProofEnv(t, testCfg, helpers.NewTestParams(), helpers.NewBatcherCfg()) + + // Build a block on L2 with 1 tx. + env.Alice.L2.ActResetTxOpts(t) + env.Alice.L2.ActSetTxToAddr(&env.Dp.Addresses.Bob) + env.Alice.L2.ActMakeTx(t) + + env.Sequencer.ActL2StartBlock(t) + env.Engine.ActL2IncludeTx(env.Alice.Address())(t) + env.Sequencer.ActL2EndBlock(t) + env.Alice.L2.ActCheckReceiptStatusOfLastTx(true)(t) + + // Instruct the batcher to submit a faulty channel, with an invalid tx. + err := env.Batcher.BufferWithOpts(t, func(block *types.Block) { + // Replace the tx with one that has a bad signature. + txs := block.Transactions() + newTx, err := txs[1].WithSignature(env.Alice.L2.Signer(), make([]byte, 65)) + txs[1] = newTx + require.NoError(t, err) + }) + require.NoError(t, err) + env.Batcher.ActL2ChannelClose(t) + env.Batcher.ActL2BatchSubmit(t) + + // Include the batcher transaction. + env.Miner.ActL1StartBlock(12)(t) + env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t) + env.Miner.ActL1EndBlock(t) + env.Miner.ActL1SafeNext(t) + + // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. + env.Sequencer.ActL1HeadSignal(t) + env.Sequencer.ActL2PipelineFull(t) + + // Ensure the safe head has not advanced - the batch is invalid. + l2SafeHead := env.Engine.L2Chain().CurrentSafeBlock() + require.Equal(t, uint64(0), l2SafeHead.Number.Uint64()) + + // Reset the batcher and submit a valid batch. + env.Batcher.Reset() + env.Batcher.ActSubmitAll(t) + env.Miner.ActL1StartBlock(12)(t) + env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t) + env.Miner.ActL1EndBlock(t) + env.Miner.ActL1SafeNext(t) + + // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. + env.Sequencer.ActL1HeadSignal(t) + env.Sequencer.ActL2PipelineFull(t) + + // Ensure the safe head has advanced. + l1Head := env.Miner.L1Chain().CurrentBlock() + l2SafeHead = env.Engine.L2Chain().CurrentSafeBlock() + require.Equal(t, uint64(2), l1Head.Number.Uint64()) + require.Equal(t, uint64(1), l2SafeHead.Number.Uint64()) + + env.RunFaultProofProgram(t, l2SafeHead.Number.Uint64(), testCfg.CheckResult, testCfg.InputParams...) +} + +func runBadTxInBatch_ResubmitBadFirstFrame_Test(gt *testing.T, testCfg *helpers.TestCfg[any]) { + t := actionsHelpers.NewDefaultTesting(gt) + env := helpers.NewL2FaultProofEnv(t, testCfg, helpers.NewTestParams(), helpers.NewBatcherCfg()) + + // Build 2 blocks on L2 with 1 tx each. + for i := 0; i < 2; i++ { + env.Alice.L2.ActResetTxOpts(t) + env.Alice.L2.ActSetTxToAddr(&env.Dp.Addresses.Bob) + env.Alice.L2.ActMakeTx(t) + + env.Sequencer.ActL2StartBlock(t) + env.Engine.ActL2IncludeTx(env.Alice.Address())(t) + env.Sequencer.ActL2EndBlock(t) + env.Alice.L2.ActCheckReceiptStatusOfLastTx(true)(t) + } + + // Instruct the batcher to submit a faulty channel, with an invalid tx in the second block + // within the span batch. + env.Batcher.ActL2BatchBuffer(t) + err := env.Batcher.BufferWithOpts(t, func(block *types.Block) { + // Replace the tx with one that has a bad signature. + txs := block.Transactions() + newTx, err := txs[1].WithSignature(env.Alice.L2.Signer(), make([]byte, 65)) + txs[1] = newTx + require.NoError(t, err) + }) + require.NoError(t, err) + env.Batcher.ActL2ChannelClose(t) + env.Batcher.ActL2BatchSubmit(t) + + // Include the batcher transaction. + env.Miner.ActL1StartBlock(12)(t) + env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t) + env.Miner.ActL1EndBlock(t) + env.Miner.ActL1SafeNext(t) + + // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. + env.Sequencer.ActL1HeadSignal(t) + env.Sequencer.ActL2PipelineFull(t) + + // Ensure the safe head has not advanced - the batch is invalid. + l2SafeHead := env.Engine.L2Chain().CurrentSafeBlock() + require.Equal(t, uint64(0), l2SafeHead.Number.Uint64()) + + // Reset the batcher and submit a valid batch. + env.Batcher.Reset() + env.Batcher.ActSubmitAll(t) + env.Miner.ActL1StartBlock(12)(t) + env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t) + env.Miner.ActL1EndBlock(t) + env.Miner.ActL1SafeNext(t) + + // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. + env.Sequencer.ActL1HeadSignal(t) + env.Sequencer.ActL2PipelineFull(t) + + // Ensure the safe head has advanced. + l1Head := env.Miner.L1Chain().CurrentBlock() + l2SafeHead = env.Engine.L2Chain().CurrentSafeBlock() + require.Equal(t, uint64(2), l1Head.Number.Uint64()) + require.Equal(t, uint64(2), l2SafeHead.Number.Uint64()) + + env.RunFaultProofProgram(t, l2SafeHead.Number.Uint64()-1, testCfg.CheckResult, testCfg.InputParams...) +} + +func Test_ProgramAction_BadTxInBatch(gt *testing.T) { + matrix := helpers.NewMatrix[any]() + defer matrix.Run(gt) + + matrix.AddTestCase( + "HonestClaim", + nil, + helpers.LatestForkOnly, + runBadTxInBatchTest, + helpers.ExpectNoError(), + ) + matrix.AddTestCase( + "JunkClaim", + nil, + helpers.LatestForkOnly, + runBadTxInBatchTest, + helpers.ExpectError(claim.ErrClaimNotValid), + helpers.WithL2Claim(common.HexToHash("0xdeadbeef")), + ) + matrix.AddTestCase( + "ResubmitBadFirstFrame-HonestClaim", + nil, + helpers.LatestForkOnly, + runBadTxInBatch_ResubmitBadFirstFrame_Test, + helpers.ExpectNoError(), + ) + matrix.AddTestCase( + "ResubmitBadFirstFrame-JunkClaim", + nil, + helpers.LatestForkOnly, + runBadTxInBatch_ResubmitBadFirstFrame_Test, + helpers.ExpectError(claim.ErrClaimNotValid), + helpers.WithL2Claim(common.HexToHash("0xdeadbeef")), + ) +} From 4c6bc7e5fec12427ecb50346ebfdbcf6fcbe5f46 Mon Sep 17 00:00:00 2001 From: Siciliabird <136583351+QianlongCry@users.noreply.github.com> Date: Sun, 22 Sep 2024 22:56:21 +0200 Subject: [PATCH 227/264] docs: remove fault proof alpha from readme (#12036) --- docs/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index da82e0a7f6aa..cabb2506b084 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,4 +6,3 @@ The directory layout is divided into the following sub-directories. - [`postmortems/`](./postmortems/): Timestamped post-mortem documents. - [`security-reviews`](./security-reviews/): Audit summaries and other security review documents. -- [`fault-proof-alpha`](./fault-proof-alpha): Information on the alpha version of the fault proof system. From de7f8d9bb3481be7863f151d1b14f9258433d4e8 Mon Sep 17 00:00:00 2001 From: Michael de Hoog <michael.dehoog@coinbase.com> Date: Sun, 22 Sep 2024 11:04:48 -1000 Subject: [PATCH 228/264] Use TxManager interface in DriverSetup and BatcherService (#12040) --- op-batcher/batcher/driver.go | 2 +- op-batcher/batcher/service.go | 2 +- op-batcher/batcher/test_batch_submitter.go | 6 ++- op-challenger/sender/sender_test.go | 5 +++ op-e2e/actions/helpers/l2_proposer.go | 4 ++ op-service/txmgr/mocks/TxManager.go | 45 ++++++++++++++++++++++ op-service/txmgr/txmgr.go | 6 ++- 7 files changed, 66 insertions(+), 4 deletions(-) diff --git a/op-batcher/batcher/driver.go b/op-batcher/batcher/driver.go index b9b57cb654d9..0b7d36d960dd 100644 --- a/op-batcher/batcher/driver.go +++ b/op-batcher/batcher/driver.go @@ -80,7 +80,7 @@ type DriverSetup struct { Metr metrics.Metricer RollupConfig *rollup.Config Config BatcherConfig - Txmgr *txmgr.SimpleTxManager + Txmgr txmgr.TxManager L1Client L1Client EndpointProvider dial.L2EndpointProvider ChannelConfig ChannelConfigProvider diff --git a/op-batcher/batcher/service.go b/op-batcher/batcher/service.go index edd31f465d16..6ed906af15aa 100644 --- a/op-batcher/batcher/service.go +++ b/op-batcher/batcher/service.go @@ -53,7 +53,7 @@ type BatcherService struct { Metrics metrics.Metricer L1Client *ethclient.Client EndpointProvider dial.L2EndpointProvider - TxManager *txmgr.SimpleTxManager + TxManager txmgr.TxManager AltDA *altda.DAClient BatcherConfig diff --git a/op-batcher/batcher/test_batch_submitter.go b/op-batcher/batcher/test_batch_submitter.go index 8814400f06ca..9ff5ca69796f 100644 --- a/op-batcher/batcher/test_batch_submitter.go +++ b/op-batcher/batcher/test_batch_submitter.go @@ -37,8 +37,12 @@ func (l *TestBatchSubmitter) JamTxPool(ctx context.Context) error { return err } + simpleTxMgr, ok := l.Txmgr.(*txmgr.SimpleTxManager) + if !ok { + return errors.New("txmgr is not a SimpleTxManager") + } l.ttm = &txmgr.TestTxManager{ - SimpleTxManager: l.Txmgr, + SimpleTxManager: simpleTxMgr, } l.Log.Info("sending txpool blocking test tx") if err := l.ttm.JamTxPool(ctx, *candidate); err != nil { diff --git a/op-challenger/sender/sender_test.go b/op-challenger/sender/sender_test.go index c8fcae07a07b..5169ae67192a 100644 --- a/op-challenger/sender/sender_test.go +++ b/op-challenger/sender/sender_test.go @@ -3,6 +3,7 @@ package sender import ( "context" "fmt" + "math/big" "sync" "testing" "time" @@ -181,3 +182,7 @@ func (s *stubTxMgr) API() rpc.API { func (s *stubTxMgr) Close() { } + +func (s *stubTxMgr) SuggestGasPriceCaps(context.Context) (*big.Int, *big.Int, *big.Int, error) { + panic("unimplemented") +} diff --git a/op-e2e/actions/helpers/l2_proposer.go b/op-e2e/actions/helpers/l2_proposer.go index e97a66a1f5bc..f1a0c4d0d634 100644 --- a/op-e2e/actions/helpers/l2_proposer.go +++ b/op-e2e/actions/helpers/l2_proposer.go @@ -84,6 +84,10 @@ func (f fakeTxMgr) API() rpc.API { panic("unimplemented") } +func (f fakeTxMgr) SuggestGasPriceCaps(context.Context) (*big.Int, *big.Int, *big.Int, error) { + panic("unimplemented") +} + func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Client, rollupCl *sources.RollupClient) *L2Proposer { proposerConfig := proposer.ProposerConfig{ PollInterval: time.Second, diff --git a/op-service/txmgr/mocks/TxManager.go b/op-service/txmgr/mocks/TxManager.go index e0791c7bfbe2..ec805b74d004 100644 --- a/op-service/txmgr/mocks/TxManager.go +++ b/op-service/txmgr/mocks/TxManager.go @@ -4,6 +4,7 @@ package mocks import ( context "context" + big "math/big" common "github.com/ethereum/go-ethereum/common" @@ -125,6 +126,50 @@ func (_m *TxManager) SendAsync(ctx context.Context, candidate txmgr.TxCandidate, _m.Called(ctx, candidate, ch) } +// SuggestGasPriceCaps provides a mock function with given fields: ctx +func (_m *TxManager) SuggestGasPriceCaps(ctx context.Context) (*big.Int, *big.Int, *big.Int, error) { + ret := _m.Called(ctx) + + var r0 *big.Int + var r1 *big.Int + var r2 *big.Int + var r3 error + if rf, ok := ret.Get(0).(func(context.Context) (*big.Int, *big.Int, *big.Int, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *big.Int); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) *big.Int); ok { + r1 = rf(ctx) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*big.Int) + } + } + + if rf, ok := ret.Get(2).(func(context.Context) *big.Int); ok { + r2 = rf(ctx) + } else { + if ret.Get(2) != nil { + r2 = ret.Get(2).(*big.Int) + } + } + + if rf, ok := ret.Get(3).(func(context.Context) error); ok { + r3 = rf(ctx) + } else { + r3 = ret.Error(3) + } + + return r0, r1, r2, r3 +} + type mockConstructorTestingTNewTxManager interface { mock.TestingT Cleanup(func()) diff --git a/op-service/txmgr/txmgr.go b/op-service/txmgr/txmgr.go index a0e944f8a5be..6fa0ea5dc15a 100644 --- a/op-service/txmgr/txmgr.go +++ b/op-service/txmgr/txmgr.go @@ -90,6 +90,10 @@ type TxManager interface { // Close the underlying connection Close() IsClosed() bool + + // SuggestGasPriceCaps suggests what the new tip, base fee, and blob base fee should be based on + // the current L1 conditions. `blobBaseFee` will be nil if 4844 is not yet active. + SuggestGasPriceCaps(ctx context.Context) (tipCap *big.Int, baseFee *big.Int, blobBaseFee *big.Int, err error) } // ETHBackend is the set of methods that the transaction manager uses to resubmit gas & determine @@ -857,7 +861,7 @@ func (m *SimpleTxManager) increaseGasPrice(ctx context.Context, tx *types.Transa } // SuggestGasPriceCaps suggests what the new tip, base fee, and blob base fee should be based on -// the current L1 conditions. blobfee will be nil if 4844 is not yet active. +// the current L1 conditions. `blobBaseFee` will be nil if 4844 is not yet active. func (m *SimpleTxManager) SuggestGasPriceCaps(ctx context.Context) (*big.Int, *big.Int, *big.Int, error) { cCtx, cancel := context.WithTimeout(ctx, m.cfg.NetworkTimeout) defer cancel() From 6c98946155465de9438f8885f7d5cda2d2df8db7 Mon Sep 17 00:00:00 2001 From: clabby <ben@clab.by> Date: Sun, 22 Sep 2024 22:08:54 -0400 Subject: [PATCH 229/264] feat(op-e2e): L1 lookback action tests (#12043) * feat(op-e2e): L1 lookback action tests * review * adrian review --- op-e2e/actions/helpers/l2_batcher.go | 6 +- op-e2e/actions/helpers/user.go | 14 +- op-e2e/actions/proofs/bad_tx_in_batch_test.go | 4 +- op-e2e/actions/proofs/helpers/env.go | 5 + op-e2e/actions/proofs/l1_lookback_test.go | 161 ++++++++++++++++++ 5 files changed, 178 insertions(+), 12 deletions(-) create mode 100644 op-e2e/actions/proofs/l1_lookback_test.go diff --git a/op-e2e/actions/helpers/l2_batcher.go b/op-e2e/actions/helpers/l2_batcher.go index f1f10b362b88..2502aec39f38 100644 --- a/op-e2e/actions/helpers/l2_batcher.go +++ b/op-e2e/actions/helpers/l2_batcher.go @@ -150,13 +150,9 @@ func (s *L2Batcher) ActL2BatchBuffer(t Testing) { require.NoError(t, s.Buffer(t), "failed to add block to channel") } -func (s *L2Batcher) Buffer(t Testing) error { - return s.BufferWithOpts(t) -} - type BlockModifier = func(block *types.Block) -func (s *L2Batcher) BufferWithOpts(t Testing, opts ...BlockModifier) error { +func (s *L2Batcher) Buffer(t Testing, opts ...BlockModifier) error { if s.l2Submitting { // break ongoing submitting work if necessary s.L2ChannelOut = nil s.l2Submitting = false diff --git a/op-e2e/actions/helpers/user.go b/op-e2e/actions/helpers/user.go index 65a39ce6aa4a..2acd6ccaf8e7 100644 --- a/op-e2e/actions/helpers/user.go +++ b/op-e2e/actions/helpers/user.go @@ -235,9 +235,7 @@ func (s *BasicUser[B]) LastTxReceipt(t Testing) *types.Receipt { return receipt } -// ActMakeTx makes a tx with the predetermined contents (see randomization and other actions) -// and sends it to the tx pool -func (s *BasicUser[B]) ActMakeTx(t Testing) { +func (s *BasicUser[B]) MakeTransaction(t Testing) *types.Transaction { gas, err := s.env.EthCl.EstimateGas(t.Ctx(), ethereum.CallMsg{ From: s.address, To: s.txToAddr, @@ -247,7 +245,7 @@ func (s *BasicUser[B]) ActMakeTx(t Testing) { Data: s.txCallData, }) require.NoError(t, err, "gas estimation should pass") - tx := types.MustSignNewTx(s.account, s.env.Signer, &types.DynamicFeeTx{ + return types.MustSignNewTx(s.account, s.env.Signer, &types.DynamicFeeTx{ To: s.txToAddr, GasFeeCap: s.txOpts.GasFeeCap, GasTipCap: s.txOpts.GasTipCap, @@ -257,7 +255,13 @@ func (s *BasicUser[B]) ActMakeTx(t Testing) { Gas: gas, Data: s.txCallData, }) - err = s.env.EthCl.SendTransaction(t.Ctx(), tx) +} + +// ActMakeTx makes a tx with the predetermined contents (see randomization and other actions) +// and sends it to the tx pool +func (s *BasicUser[B]) ActMakeTx(t Testing) { + tx := s.MakeTransaction(t) + err := s.env.EthCl.SendTransaction(t.Ctx(), tx) require.NoError(t, err, "must send tx") s.lastTxHash = tx.Hash() // reset the calldata diff --git a/op-e2e/actions/proofs/bad_tx_in_batch_test.go b/op-e2e/actions/proofs/bad_tx_in_batch_test.go index c3259211c300..f67e216f76cb 100644 --- a/op-e2e/actions/proofs/bad_tx_in_batch_test.go +++ b/op-e2e/actions/proofs/bad_tx_in_batch_test.go @@ -26,7 +26,7 @@ func runBadTxInBatchTest(gt *testing.T, testCfg *helpers.TestCfg[any]) { env.Alice.L2.ActCheckReceiptStatusOfLastTx(true)(t) // Instruct the batcher to submit a faulty channel, with an invalid tx. - err := env.Batcher.BufferWithOpts(t, func(block *types.Block) { + err := env.Batcher.Buffer(t, func(block *types.Block) { // Replace the tx with one that has a bad signature. txs := block.Transactions() newTx, err := txs[1].WithSignature(env.Alice.L2.Signer(), make([]byte, 65)) @@ -91,7 +91,7 @@ func runBadTxInBatch_ResubmitBadFirstFrame_Test(gt *testing.T, testCfg *helpers. // Instruct the batcher to submit a faulty channel, with an invalid tx in the second block // within the span batch. env.Batcher.ActL2BatchBuffer(t) - err := env.Batcher.BufferWithOpts(t, func(block *types.Block) { + err := env.Batcher.Buffer(t, func(block *types.Block) { // Replace the tx with one that has a bad signature. txs := block.Transactions() newTx, err := txs[1].WithSignature(env.Alice.L2.Signer(), make([]byte, 65)) diff --git a/op-e2e/actions/proofs/helpers/env.go b/op-e2e/actions/proofs/helpers/env.go index 6d970cfbe0d6..ca670acb228d 100644 --- a/op-e2e/actions/proofs/helpers/env.go +++ b/op-e2e/actions/proofs/helpers/env.go @@ -34,6 +34,7 @@ type L2FaultProofEnv struct { Dp *e2eutils.DeployParams Miner *helpers.L1Miner Alice *helpers.CrossLayerUser + Bob *helpers.CrossLayerUser } func NewL2FaultProofEnv[c any](t helpers.Testing, testCfg *TestCfg[c], tp *e2eutils.TestParams, batcherCfg *helpers.BatcherCfg) *L2FaultProofEnv { @@ -100,6 +101,9 @@ func NewL2FaultProofEnv[c any](t helpers.Testing, testCfg *TestCfg[c], tp *e2eut alice := helpers.NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b))) alice.L1.SetUserEnv(l1UserEnv) alice.L2.SetUserEnv(l2UserEnv) + bob := helpers.NewCrossLayerUser(log, dp.Secrets.Bob, rand.New(rand.NewSource(0xbeef))) + bob.L1.SetUserEnv(l1UserEnv) + bob.L2.SetUserEnv(l2UserEnv) return &L2FaultProofEnv{ log: log, @@ -111,6 +115,7 @@ func NewL2FaultProofEnv[c any](t helpers.Testing, testCfg *TestCfg[c], tp *e2eut Dp: dp, Miner: miner, Alice: alice, + Bob: bob, } } diff --git a/op-e2e/actions/proofs/l1_lookback_test.go b/op-e2e/actions/proofs/l1_lookback_test.go new file mode 100644 index 000000000000..b40635ac5509 --- /dev/null +++ b/op-e2e/actions/proofs/l1_lookback_test.go @@ -0,0 +1,161 @@ +package proofs + +import ( + "testing" + + actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers" + "github.com/ethereum-optimism/optimism/op-e2e/actions/proofs/helpers" + "github.com/ethereum-optimism/optimism/op-program/client/claim" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" +) + +func runL1LookbackTest(gt *testing.T, testCfg *helpers.TestCfg[any]) { + t := actionsHelpers.NewDefaultTesting(gt) + tp := helpers.NewTestParams() + env := helpers.NewL2FaultProofEnv(t, testCfg, tp, helpers.NewBatcherCfg()) + + const numL2Blocks = 8 + for i := 0; i < numL2Blocks; i++ { + // Create an empty L2 block. + env.Sequencer.ActL2StartBlock(t) + env.Sequencer.ActL2EndBlock(t) + + // Buffer the L2 block in the batcher. + env.Batcher.ActBufferAll(t) + if i == numL2Blocks-1 { + env.Batcher.ActL2ChannelClose(t) + } + env.Batcher.ActL2BatchSubmit(t) + + // Include the frame on L1. + env.Miner.ActL1StartBlock(12)(t) + env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t) + env.Miner.ActL1EndBlock(t) + env.Miner.ActL1SafeNext(t) + } + + // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. + env.Sequencer.ActL1HeadSignal(t) + env.Sequencer.ActL2PipelineFull(t) + + // Ensure that the safe head has advanced to `NumL2Blocks`. + l2SafeHead := env.Engine.L2Chain().CurrentSafeBlock() + require.EqualValues(t, numL2Blocks, l2SafeHead.Number.Uint64()) + + // Run the FPP on the configured L2 block. + env.RunFaultProofProgram(t, numL2Blocks/2, testCfg.CheckResult, testCfg.InputParams...) +} + +func runL1LookbackTest_ReopenChannel(gt *testing.T, testCfg *helpers.TestCfg[any]) { + t := actionsHelpers.NewDefaultTesting(gt) + tp := helpers.NewTestParams() + env := helpers.NewL2FaultProofEnv(t, testCfg, tp, helpers.NewBatcherCfg()) + + // Create an L2 block with 1 transaction. + env.Sequencer.ActL2StartBlock(t) + env.Alice.L2.ActResetTxOpts(t) + env.Alice.L2.ActSetTxToAddr(&env.Dp.Addresses.Bob) + env.Alice.L2.ActMakeTx(t) + env.Engine.ActL2IncludeTx(env.Alice.Address())(t) + env.Sequencer.ActL2EndBlock(t) + l2BlockBeforeDerive := env.Engine.L2Chain().CurrentBlock() + + // Buffer the L2 block in the batcher. + env.Batcher.ActL2BatchBuffer(t) + env.Batcher.ActL2BatchSubmit(t) + + // Include the frame on L1. + env.Miner.ActL1StartBlock(12)(t) + env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t) + env.Miner.ActL1EndBlock(t) + env.Miner.ActL1SafeNext(t) + + // Re-submit the first L2 block frame w/ different transaction data. + err := env.Batcher.Buffer(t, func(block *types.Block) { + env.Bob.L2.ActResetTxOpts(t) + env.Bob.L2.ActSetTxToAddr(&env.Dp.Addresses.Mallory) + tx := env.Bob.L2.MakeTransaction(t) + block.Transactions()[1] = tx + }) + require.NoError(t, err) + env.Batcher.ActL2BatchSubmit(t) + + // Include the duplicate frame on L1. + env.Miner.ActL1StartBlock(12)(t) + env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t) + env.Miner.ActL1EndBlock(t) + env.Miner.ActL1SafeNext(t) + + const numL2Blocks = 8 + for i := 1; i < numL2Blocks; i++ { + // Create an empty L2 block. + env.Sequencer.ActL2StartBlock(t) + env.Sequencer.ActL2EndBlock(t) + + // Buffer the L2 block in the batcher. + env.Batcher.ActBufferAll(t) + if i == numL2Blocks-1 { + env.Batcher.ActL2ChannelClose(t) + } + env.Batcher.ActL2BatchSubmit(t) + + // Include the frame on L1. + env.Miner.ActL1StartBlock(12)(t) + env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t) + env.Miner.ActL1EndBlock(t) + env.Miner.ActL1SafeNext(t) + } + + // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. + env.Sequencer.ActL1HeadSignal(t) + env.Sequencer.ActL2PipelineFull(t) + + // Ensure that the correct block was derived. + l2BlockAfterDerive := env.Engine.L2Chain().GetBlockByNumber(1) + require.EqualValues(t, l2BlockAfterDerive.Hash(), l2BlockBeforeDerive.Hash()) + + // Ensure that the safe head has advanced to `NumL2Blocks`. + l2SafeHead := env.Engine.L2Chain().CurrentSafeBlock() + require.EqualValues(t, numL2Blocks, l2SafeHead.Number.Uint64()) + + // Run the FPP on the configured L2 block. + env.RunFaultProofProgram(t, numL2Blocks/2, testCfg.CheckResult, testCfg.InputParams...) +} + +func Test_ProgramAction_L1Lookback(gt *testing.T) { + matrix := helpers.NewMatrix[any]() + defer matrix.Run(gt) + + matrix.AddTestCase( + "HonestClaim", + nil, + helpers.LatestForkOnly, + runL1LookbackTest, + helpers.ExpectNoError(), + ) + matrix.AddTestCase( + "JunkClaim", + nil, + helpers.LatestForkOnly, + runL1LookbackTest, + helpers.ExpectError(claim.ErrClaimNotValid), + helpers.WithL2Claim(common.HexToHash("0xdeadbeef")), + ) + matrix.AddTestCase( + "HonestClaim-ReopenChannel", + nil, + helpers.LatestForkOnly, + runL1LookbackTest_ReopenChannel, + helpers.ExpectNoError(), + ) + matrix.AddTestCase( + "JunkClaim-ReopenChannel", + nil, + helpers.LatestForkOnly, + runL1LookbackTest_ReopenChannel, + helpers.ExpectError(claim.ErrClaimNotValid), + helpers.WithL2Claim(common.HexToHash("0xdeadbeef")), + ) +} From d348c69ebeee46d68e2766aae117e4721b276b67 Mon Sep 17 00:00:00 2001 From: Adrian Sutton <adrian@oplabs.co> Date: Mon, 23 Sep 2024 14:14:17 +1000 Subject: [PATCH 230/264] codeowners: Set proofs team as owners of faultproofs e2e tests (#12053) --- .github/CODEOWNERS | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 1e1823fce0ac..46196699f646 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -19,12 +19,13 @@ /op-conductor @ethereum-optimism/op-conductor @ethereum-optimism/go-reviewers -/cannon @ethereum-optimism/proofs @ethereum-optimism/go-reviewers -/op-challenger @ethereum-optimism/proofs @ethereum-optimism/go-reviewers -/op-dispute-mon @ethereum-optimism/proofs @ethereum-optimism/go-reviewers -/op-preimage @ethereum-optimism/proofs @ethereum-optimism/go-reviewers -/op-program @ethereum-optimism/proofs @ethereum-optimism/go-reviewers +/cannon @ethereum-optimism/proofs @ethereum-optimism/go-reviewers +/op-challenger @ethereum-optimism/proofs @ethereum-optimism/go-reviewers +/op-dispute-mon @ethereum-optimism/proofs @ethereum-optimism/go-reviewers +/op-preimage @ethereum-optimism/proofs @ethereum-optimism/go-reviewers +/op-program @ethereum-optimism/proofs @ethereum-optimism/go-reviewers /op-e2e/actions/proofs @ethereum-optimism/proofs @ethereum-optimism/go-reviewers +/op-e2e/faultproofs @ethereum-optimism/proofs @ethereum-optimism/go-reviewers # Ops /.circleci @ethereum-optimism/monorepo-ops-reviewers From 05c0421d8a5414d54c2a0fc96f9428b552e48e1b Mon Sep 17 00:00:00 2001 From: Adrian Sutton <adrian@oplabs.co> Date: Mon, 23 Sep 2024 14:21:23 +1000 Subject: [PATCH 231/264] cannon, op-program: Avoid logging errors during normal shutdown. (#12051) Previously op-program host and cannon both logged an error message that the pre-image server couldn't be stopped after it stopped successfully. --- cannon/cmd/run.go | 3 ++- op-program/host/host.go | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/cannon/cmd/run.go b/cannon/cmd/run.go index 49c248f6f9d2..03836d087d98 100644 --- a/cannon/cmd/run.go +++ b/cannon/cmd/run.go @@ -248,7 +248,8 @@ func (p *ProcessPreimageOracle) Close() error { func (p *ProcessPreimageOracle) wait() { err := p.cmd.Wait() var waitErr error - if err, ok := err.(*exec.ExitError); !ok || !err.Success() { + var exitErr *exec.ExitError + if errors.As(err, &exitErr) && !exitErr.Success() { waitErr = err } p.cancelIO(fmt.Errorf("%w: pre-image server has exited", waitErr)) diff --git a/op-program/host/host.go b/op-program/host/host.go index 9a7990c9491e..a60e451b972d 100644 --- a/op-program/host/host.go +++ b/op-program/host/host.go @@ -217,6 +217,10 @@ func PreimageServer(ctx context.Context, logger log.Logger, cfg *config.Config, return err case <-ctx.Done(): logger.Info("Shutting down") + if errors.Is(ctx.Err(), context.Canceled) { + // We were asked to shutdown by the context being cancelled so don't treat it as an error condition. + return nil + } return ctx.Err() } } From 7ee6dcca4b92d0acf2cee308b5efa76915232165 Mon Sep 17 00:00:00 2001 From: Adrian Sutton <adrian@oplabs.co> Date: Mon, 23 Sep 2024 14:28:42 +1000 Subject: [PATCH 232/264] op-challenger: Fix run-trace to only run mt-cannon in parallel with cannon traces. (#12052) Previously it was also running it in parallel with kona-asterisc traces, resulting in errors because there were two mt-cannon traces sharing a preimages directory. --- op-challenger/runner/runner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op-challenger/runner/runner.go b/op-challenger/runner/runner.go index e787f35343eb..61fc8180905f 100644 --- a/op-challenger/runner/runner.go +++ b/op-challenger/runner/runner.go @@ -154,7 +154,7 @@ func (r *Runner) runAndRecordOnce(ctx context.Context, traceType types.TraceType recordError(err, traceType.String(), r.m, r.log) }() - if r.addMTCannonPrestate != (common.Hash{}) && r.addMTCannonPrestateURL != nil { + if traceType == types.TraceTypeCannon && r.addMTCannonPrestate != (common.Hash{}) && r.addMTCannonPrestateURL != nil { wg.Add(1) go func() { defer wg.Done() From 90700b9bb37080961747420882b14578577d47cc Mon Sep 17 00:00:00 2001 From: rickck11 <rick32377@gmail.com> Date: Mon, 23 Sep 2024 01:29:39 -0300 Subject: [PATCH 233/264] contract-test: delete outdated structure explanation (#12054) * delete outdated structure * small fix --- packages/contracts-bedrock/test/kontrol/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/contracts-bedrock/test/kontrol/README.md b/packages/contracts-bedrock/test/kontrol/README.md index 489a9017e3c7..0a6dcec7c79b 100644 --- a/packages/contracts-bedrock/test/kontrol/README.md +++ b/packages/contracts-bedrock/test/kontrol/README.md @@ -37,8 +37,6 @@ The directory is structured as follows ├── <a href="./pausability-lemmas.md">pausability-lemmas.md</a>: File containing the necessary lemmas for this project ├── <a href="./deployment">deployment</a>: Custom deploy sequence for Kontrol proofs and tests for its <a href="https://github.com/runtimeverification/kontrol/pull/271">fast summarization</a> │ ├── <a href="./deployment/KontrolDeployment.sol">KontrolDeployment.sol</a>: Deployment sequence for Kontrol proofs -│ ├── <a href="./deployment/DeploymentSummary.t.sol">DeploymentSummary.t.sol</a>: Tests for the summarization of classic deployment -│ └── <a href="./deployment/DeploymentSummaryFaultProofs.t.sol">DeploymentSummaryFaultProofs.t.sol</a>: Tests for the summarization of fault proofs deployment ├── <a href="./proofs">proofs</a>: Where the proofs (tests) themselves live │ ├── *.k.sol</a>: Symbolic property tests for contracts │ ├── <a href="./proofs/interfaces">interfaces</a>: Interface files for src contracts, to avoid unnecessary compilation of contracts From 6933bfea679bb332878608c42a60299da8d1a8a6 Mon Sep 17 00:00:00 2001 From: Michael de Hoog <michael.dehoog@coinbase.com> Date: Mon, 23 Sep 2024 02:11:17 -1000 Subject: [PATCH 234/264] Simplify ChannelOut initialization (#12045) --- op-batcher/batcher/channel.go | 2 +- op-batcher/batcher/channel_builder.go | 37 +++++++++++----------- op-batcher/batcher/channel_builder_test.go | 18 +++++------ op-batcher/batcher/channel_manager_test.go | 16 +++++----- op-batcher/batcher/driver_test.go | 2 +- op-e2e/actions/helpers/l2_batcher.go | 2 +- op-e2e/actions/sync/sync_test.go | 2 +- op-node/benchmarks/batchbuilding_test.go | 7 ++-- op-node/rollup/chain_spec.go | 12 +++++++ op-node/rollup/derive/channel_out_test.go | 7 ++-- op-node/rollup/derive/span_channel_out.go | 5 ++- 11 files changed, 61 insertions(+), 49 deletions(-) diff --git a/op-batcher/batcher/channel.go b/op-batcher/batcher/channel.go index 9a5e6b4c6a2e..e35124d8525a 100644 --- a/op-batcher/batcher/channel.go +++ b/op-batcher/batcher/channel.go @@ -35,7 +35,7 @@ type channel struct { } func newChannel(log log.Logger, metr metrics.Metricer, cfg ChannelConfig, rollupCfg *rollup.Config, latestL1OriginBlockNum uint64) (*channel, error) { - cb, err := NewChannelBuilder(cfg, *rollupCfg, latestL1OriginBlockNum) + cb, err := NewChannelBuilder(cfg, rollupCfg, latestL1OriginBlockNum) if err != nil { return nil, fmt.Errorf("creating new channel: %w", err) } diff --git a/op-batcher/batcher/channel_builder.go b/op-batcher/batcher/channel_builder.go index 4cdcba8325c2..cb4345e419d4 100644 --- a/op-batcher/batcher/channel_builder.go +++ b/op-batcher/batcher/channel_builder.go @@ -48,7 +48,7 @@ type frameData struct { // size approximation. type ChannelBuilder struct { cfg ChannelConfig - rollupCfg rollup.Config + rollupCfg *rollup.Config // L1 block number timeout of combined // - channel duration timeout, @@ -85,22 +85,8 @@ type ChannelBuilder struct { // NewChannelBuilder creates a new channel builder or returns an error if the // channel out could not be created. // it acts as a factory for either a span or singular channel out -func NewChannelBuilder(cfg ChannelConfig, rollupCfg rollup.Config, latestL1OriginBlockNum uint64) (*ChannelBuilder, error) { - c, err := cfg.CompressorConfig.NewCompressor() - if err != nil { - return nil, err - } - - chainSpec := rollup.NewChainSpec(&rollupCfg) - var co derive.ChannelOut - if cfg.BatchType == derive.SpanBatchType { - co, err = derive.NewSpanChannelOut( - rollupCfg.Genesis.L2Time, rollupCfg.L2ChainID, - cfg.CompressorConfig.TargetOutputSize, cfg.CompressorConfig.CompressionAlgo, - chainSpec, derive.WithMaxBlocksPerSpanBatch(cfg.MaxBlocksPerSpanBatch)) - } else { - co, err = derive.NewSingularChannelOut(c, chainSpec) - } +func NewChannelBuilder(cfg ChannelConfig, rollupCfg *rollup.Config, latestL1OriginBlockNum uint64) (*ChannelBuilder, error) { + co, err := newChannelOut(cfg, rollupCfg) if err != nil { return nil, fmt.Errorf("creating channel out: %w", err) } @@ -116,6 +102,21 @@ func NewChannelBuilder(cfg ChannelConfig, rollupCfg rollup.Config, latestL1Origi return cb, nil } +// newChannelOut creates a new channel out based on the given configuration. +func newChannelOut(cfg ChannelConfig, rollupCfg *rollup.Config) (derive.ChannelOut, error) { + spec := rollup.NewChainSpec(rollupCfg) + if cfg.BatchType == derive.SpanBatchType { + return derive.NewSpanChannelOut( + cfg.CompressorConfig.TargetOutputSize, cfg.CompressorConfig.CompressionAlgo, + spec, derive.WithMaxBlocksPerSpanBatch(cfg.MaxBlocksPerSpanBatch)) + } + comp, err := cfg.CompressorConfig.NewCompressor() + if err != nil { + return nil, err + } + return derive.NewSingularChannelOut(comp, spec) +} + func (c *ChannelBuilder) ID() derive.ChannelID { return c.co.ID() } @@ -177,7 +178,7 @@ func (c *ChannelBuilder) AddBlock(block *types.Block) (*derive.L1BlockInfo, erro return nil, c.FullErr() } - batch, l1info, err := derive.BlockToSingularBatch(&c.rollupCfg, block) + batch, l1info, err := derive.BlockToSingularBatch(c.rollupCfg, block) if err != nil { return l1info, fmt.Errorf("converting block to batch: %w", err) } diff --git a/op-batcher/batcher/channel_builder_test.go b/op-batcher/batcher/channel_builder_test.go index 85edbef5def5..1c25f06d81c0 100644 --- a/op-batcher/batcher/channel_builder_test.go +++ b/op-batcher/batcher/channel_builder_test.go @@ -22,7 +22,7 @@ import ( const latestL1BlockOrigin = 10 -var defaultTestRollupConfig = rollup.Config{ +var defaultTestRollupConfig = &rollup.Config{ Genesis: rollup.Genesis{L2: eth.BlockID{Number: 0}}, L2ChainID: big.NewInt(1234), } @@ -63,7 +63,7 @@ func newMiniL2BlockWithNumberParentAndL1Information(numTx int, l2Number *big.Int Number: big.NewInt(l1Number), Time: blockTime, }, nil, nil, trie.NewStackTrie(nil)) - l1InfoTx, err := derive.L1InfoDeposit(&defaultTestRollupConfig, eth.SystemConfig{}, 0, eth.BlockToInfo(l1Block), blockTime) + l1InfoTx, err := derive.L1InfoDeposit(defaultTestRollupConfig, eth.SystemConfig{}, 0, eth.BlockToInfo(l1Block), blockTime) if err != nil { panic(err) } @@ -369,7 +369,7 @@ func ChannelBuilder_OutputWrongFramePanic(t *testing.T, batchType uint) { // the type of batch does not matter here because we are using it to construct a broken frame c, err := channelConfig.CompressorConfig.NewCompressor() require.NoError(t, err) - co, err := derive.NewSingularChannelOut(c, rollup.NewChainSpec(&defaultTestRollupConfig)) + co, err := derive.NewSingularChannelOut(c, rollup.NewChainSpec(defaultTestRollupConfig)) require.NoError(t, err) var buf bytes.Buffer fn, err := co.OutputFrame(&buf, channelConfig.MaxFrameSize) @@ -503,7 +503,7 @@ func ChannelBuilder_OutputFrames_SpanBatch(t *testing.T, algo derive.Compression func ChannelBuilder_MaxRLPBytesPerChannel(t *testing.T, batchType uint) { t.Parallel() channelConfig := defaultTestChannelConfig() - chainSpec := rollup.NewChainSpec(&defaultTestRollupConfig) + chainSpec := rollup.NewChainSpec(defaultTestRollupConfig) channelConfig.MaxFrameSize = chainSpec.MaxRLPBytesPerChannel(latestL1BlockOrigin) * 2 channelConfig.InitNoneCompressor() channelConfig.BatchType = batchType @@ -525,7 +525,7 @@ func ChannelBuilder_MaxRLPBytesPerChannel(t *testing.T, batchType uint) { func ChannelBuilder_MaxRLPBytesPerChannelFjord(t *testing.T, batchType uint) { t.Parallel() channelConfig := defaultTestChannelConfig() - chainSpec := rollup.NewChainSpec(&defaultTestRollupConfig) + chainSpec := rollup.NewChainSpec(defaultTestRollupConfig) channelConfig.MaxFrameSize = chainSpec.MaxRLPBytesPerChannel(latestL1BlockOrigin) * 2 channelConfig.InitNoneCompressor() channelConfig.BatchType = batchType @@ -541,13 +541,13 @@ func ChannelBuilder_MaxRLPBytesPerChannelFjord(t *testing.T, batchType uint) { // Create a new channel builder with fjord fork now := time.Now() fjordTime := uint64(now.Add(-1 * time.Second).Unix()) - rollupConfig := rollup.Config{ + rollupConfig := &rollup.Config{ Genesis: rollup.Genesis{L2: eth.BlockID{Number: 0}}, L2ChainID: big.NewInt(1234), FjordTime: &fjordTime, } - chainSpec = rollup.NewChainSpec(&rollupConfig) + chainSpec = rollup.NewChainSpec(rollupConfig) channelConfig.MaxFrameSize = chainSpec.MaxRLPBytesPerChannel(uint64(now.Unix())) * 2 channelConfig.InitNoneCompressor() channelConfig.BatchType = batchType @@ -887,7 +887,7 @@ func ChannelBuilder_InputBytes(t *testing.T, batchType uint) { if batchType == derive.SingularBatchType { l += blockBatchRlpSize(t, block) } else { - singularBatch, l1Info, err := derive.BlockToSingularBatch(&defaultTestRollupConfig, block) + singularBatch, l1Info, err := derive.BlockToSingularBatch(defaultTestRollupConfig, block) require.NoError(err) err = spanBatch.AppendSingularBatch(singularBatch, l1Info.SequenceNumber) require.NoError(err) @@ -942,7 +942,7 @@ func ChannelBuilder_OutputBytes(t *testing.T, batchType uint) { func blockBatchRlpSize(t *testing.T, b *types.Block) int { t.Helper() - singularBatch, _, err := derive.BlockToSingularBatch(&defaultTestRollupConfig, b) + singularBatch, _, err := derive.BlockToSingularBatch(defaultTestRollupConfig, b) batch := derive.NewBatchData(singularBatch) require.NoError(t, err) var buf bytes.Buffer diff --git a/op-batcher/batcher/channel_manager_test.go b/op-batcher/batcher/channel_manager_test.go index 474942ce5e87..a6271df9a535 100644 --- a/op-batcher/batcher/channel_manager_test.go +++ b/op-batcher/batcher/channel_manager_test.go @@ -124,7 +124,7 @@ func ChannelManager_Clear(t *testing.T, batchType uint) { // clearing confirmed transactions, and resetting the pendingChannels map cfg.ChannelTimeout = 10 cfg.InitRatioCompressor(1, derive.Zlib) - m := NewChannelManager(log, metrics.NoopMetrics, cfg, &defaultTestRollupConfig) + m := NewChannelManager(log, metrics.NoopMetrics, cfg, defaultTestRollupConfig) // Channel Manager state should be empty by default require.Empty(m.blocks) @@ -195,7 +195,7 @@ func ChannelManager_TxResend(t *testing.T, batchType uint) { log := testlog.Logger(t, log.LevelError) cfg := channelManagerTestConfig(120_000, batchType) cfg.CompressorConfig.TargetOutputSize = 1 // full on first block - m := NewChannelManager(log, metrics.NoopMetrics, cfg, &defaultTestRollupConfig) + m := NewChannelManager(log, metrics.NoopMetrics, cfg, defaultTestRollupConfig) m.Clear(eth.BlockID{}) a := derivetest.RandomL2BlockWithChainId(rng, 4, defaultTestRollupConfig.L2ChainID) @@ -234,7 +234,7 @@ func ChannelManagerCloseBeforeFirstUse(t *testing.T, batchType uint) { log := testlog.Logger(t, log.LevelCrit) m := NewChannelManager(log, metrics.NoopMetrics, channelManagerTestConfig(10000, batchType), - &defaultTestRollupConfig, + defaultTestRollupConfig, ) m.Clear(eth.BlockID{}) @@ -258,7 +258,7 @@ func ChannelManagerCloseNoPendingChannel(t *testing.T, batchType uint) { cfg := channelManagerTestConfig(10000, batchType) cfg.CompressorConfig.TargetOutputSize = 1 // full on first block cfg.ChannelTimeout = 1000 - m := NewChannelManager(log, metrics.NoopMetrics, cfg, &defaultTestRollupConfig) + m := NewChannelManager(log, metrics.NoopMetrics, cfg, defaultTestRollupConfig) m.Clear(eth.BlockID{}) a := newMiniL2Block(0) b := newMiniL2BlockWithNumberParent(0, big.NewInt(1), a.Hash()) @@ -294,7 +294,7 @@ func ChannelManagerClosePendingChannel(t *testing.T, batchType uint) { log := testlog.Logger(t, log.LevelError) cfg := channelManagerTestConfig(10_000, batchType) cfg.ChannelTimeout = 1000 - m := NewChannelManager(log, metrics.NoopMetrics, cfg, &defaultTestRollupConfig) + m := NewChannelManager(log, metrics.NoopMetrics, cfg, defaultTestRollupConfig) m.Clear(eth.BlockID{}) numTx := 20 // Adjust number of txs to make 2 frames @@ -346,7 +346,7 @@ func TestChannelManager_Close_PartiallyPendingChannel(t *testing.T) { TargetNumFrames: 100, } cfg.InitNoneCompressor() - m := NewChannelManager(log, metrics.NoopMetrics, cfg, &defaultTestRollupConfig) + m := NewChannelManager(log, metrics.NoopMetrics, cfg, defaultTestRollupConfig) m.Clear(eth.BlockID{}) numTx := 3 // Adjust number of txs to make 2 frames @@ -398,7 +398,7 @@ func ChannelManagerCloseAllTxsFailed(t *testing.T, batchType uint) { cfg := channelManagerTestConfig(100, batchType) cfg.TargetNumFrames = 1000 cfg.InitNoneCompressor() - m := NewChannelManager(log, metrics.NoopMetrics, cfg, &defaultTestRollupConfig) + m := NewChannelManager(log, metrics.NoopMetrics, cfg, defaultTestRollupConfig) m.Clear(eth.BlockID{}) a := derivetest.RandomL2BlockWithChainId(rng, 1000, defaultTestRollupConfig.L2ChainID) @@ -471,7 +471,7 @@ func TestChannelManager_ChannelCreation(t *testing.T) { } { test := tt t.Run(test.name, func(t *testing.T) { - m := NewChannelManager(l, metrics.NoopMetrics, cfg, &defaultTestRollupConfig) + m := NewChannelManager(l, metrics.NoopMetrics, cfg, defaultTestRollupConfig) m.l1OriginLastClosedChannel = test.safeL1Block require.Nil(t, m.currentChannel) diff --git a/op-batcher/batcher/driver_test.go b/op-batcher/batcher/driver_test.go index df72fa28d49a..1c5ace753771 100644 --- a/op-batcher/batcher/driver_test.go +++ b/op-batcher/batcher/driver_test.go @@ -49,7 +49,7 @@ func setup(t *testing.T) (*BatchSubmitter, *mockL2EndpointProvider) { return NewBatchSubmitter(DriverSetup{ Log: testlog.Logger(t, log.LevelDebug), Metr: metrics.NoopMetrics, - RollupConfig: &cfg, + RollupConfig: cfg, EndpointProvider: ep, }), ep } diff --git a/op-e2e/actions/helpers/l2_batcher.go b/op-e2e/actions/helpers/l2_batcher.go index 2502aec39f38..d9e6fe3dbec5 100644 --- a/op-e2e/actions/helpers/l2_batcher.go +++ b/op-e2e/actions/helpers/l2_batcher.go @@ -219,7 +219,7 @@ func (s *L2Batcher) Buffer(t Testing, opts ...BlockModifier) error { chainSpec := rollup.NewChainSpec(s.rollupCfg) // use span batch if we're forcing it or if we're at/beyond delta if s.l2BatcherCfg.ForceSubmitSpanBatch || s.rollupCfg.IsDelta(block.Time()) { - ch, err = derive.NewSpanChannelOut(s.rollupCfg.Genesis.L2Time, s.rollupCfg.L2ChainID, target, derive.Zlib, chainSpec) + ch, err = derive.NewSpanChannelOut(target, derive.Zlib, chainSpec) // use singular batches in all other cases } else { ch, err = derive.NewSingularChannelOut(c, chainSpec) diff --git a/op-e2e/actions/sync/sync_test.go b/op-e2e/actions/sync/sync_test.go index cd6bf4b29b9d..523b68517afb 100644 --- a/op-e2e/actions/sync/sync_test.go +++ b/op-e2e/actions/sync/sync_test.go @@ -35,7 +35,7 @@ import ( ) func newSpanChannelOut(t actionsHelpers.StatefulTesting, e e2eutils.SetupData) derive.ChannelOut { - channelOut, err := derive.NewSpanChannelOut(e.RollupCfg.Genesis.L2Time, e.RollupCfg.L2ChainID, 128_000, derive.Zlib, rollup.NewChainSpec(e.RollupCfg)) + channelOut, err := derive.NewSpanChannelOut(128_000, derive.Zlib, rollup.NewChainSpec(e.RollupCfg)) require.NoError(t, err) return channelOut } diff --git a/op-node/benchmarks/batchbuilding_test.go b/op-node/benchmarks/batchbuilding_test.go index 54690eabb152..57a5382d749b 100644 --- a/op-node/benchmarks/batchbuilding_test.go +++ b/op-node/benchmarks/batchbuilding_test.go @@ -87,15 +87,16 @@ var ( // channelOutByType returns a channel out of the given type as a helper for the benchmarks func channelOutByType(b *testing.B, batchType uint, cd compressorDetails) (derive.ChannelOut, error) { - chainID := big.NewInt(333) - rollupConfig := new(rollup.Config) + rollupConfig := &rollup.Config{ + L2ChainID: big.NewInt(333), + } if batchType == derive.SingularBatchType { compressor, err := cd.Compressor() require.NoError(b, err) return derive.NewSingularChannelOut(compressor, rollup.NewChainSpec(rollupConfig)) } if batchType == derive.SpanBatchType { - return derive.NewSpanChannelOut(0, chainID, cd.config.TargetOutputSize, cd.config.CompressionAlgo, rollup.NewChainSpec(rollupConfig)) + return derive.NewSpanChannelOut(cd.config.TargetOutputSize, cd.config.CompressionAlgo, rollup.NewChainSpec(rollupConfig)) } return nil, fmt.Errorf("unsupported batch type: %d", batchType) } diff --git a/op-node/rollup/chain_spec.go b/op-node/rollup/chain_spec.go index 95d9c3b19798..66d2e526d0d1 100644 --- a/op-node/rollup/chain_spec.go +++ b/op-node/rollup/chain_spec.go @@ -1,6 +1,8 @@ package rollup import ( + "math/big" + "github.com/ethereum-optimism/optimism/op-node/params" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/log" @@ -63,6 +65,16 @@ func NewChainSpec(config *Config) *ChainSpec { return &ChainSpec{config: config} } +// L2ChainID returns the chain ID of the L2 chain. +func (s *ChainSpec) L2ChainID() *big.Int { + return s.config.L2ChainID +} + +// L2GenesisTime returns the genesis time of the L2 chain. +func (s *ChainSpec) L2GenesisTime() uint64 { + return s.config.Genesis.L2Time +} + // IsCanyon returns true if t >= canyon_time func (s *ChainSpec) IsCanyon(t uint64) bool { return s.config.IsCanyon(t) diff --git a/op-node/rollup/derive/channel_out_test.go b/op-node/rollup/derive/channel_out_test.go index 53fedef03e64..34aa58400fdd 100644 --- a/op-node/rollup/derive/channel_out_test.go +++ b/op-node/rollup/derive/channel_out_test.go @@ -61,7 +61,7 @@ var channelTypes = []struct { { Name: "Span", ChannelOut: func(t *testing.T, rcfg *rollup.Config) ChannelOut { - cout, err := NewSpanChannelOut(0, big.NewInt(0), 128_000, Zlib, rollup.NewChainSpec(rcfg)) + cout, err := NewSpanChannelOut(128_000, Zlib, rollup.NewChainSpec(rcfg)) require.NoError(t, err) return cout }, @@ -111,9 +111,8 @@ func TestOutputFrameNoEmptyLastFrame(t *testing.T) { cout := tcase.ChannelOut(t, &rollupCfg) rng := rand.New(rand.NewSource(0x543331)) - chainID := big.NewInt(0) txCount := 1 - singularBatch := RandomSingularBatch(rng, txCount, chainID) + singularBatch := RandomSingularBatch(rng, txCount, rollupCfg.L2ChainID) err := cout.AddSingularBatch(singularBatch, 0) var written uint64 @@ -236,7 +235,7 @@ func SpanChannelAndBatches(t *testing.T, targetOutputSize uint64, numBatches int chainID := rollupCfg.L2ChainID txCount := 1 genesisTime := rollupCfg.Genesis.L2Time - cout, err := NewSpanChannelOut(genesisTime, chainID, targetOutputSize, algo, rollup.NewChainSpec(&rollupCfg), opts...) + cout, err := NewSpanChannelOut(targetOutputSize, algo, rollup.NewChainSpec(&rollupCfg), opts...) require.NoError(t, err) batches := make([]*SingularBatch, 0, numBatches) // adding the first batch should not cause an error diff --git a/op-node/rollup/derive/span_channel_out.go b/op-node/rollup/derive/span_channel_out.go index aa2eae04b2d1..9950fe29c413 100644 --- a/op-node/rollup/derive/span_channel_out.go +++ b/op-node/rollup/derive/span_channel_out.go @@ -5,7 +5,6 @@ import ( "crypto/rand" "fmt" "io" - "math/big" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rlp" @@ -65,11 +64,11 @@ func WithMaxBlocksPerSpanBatch(maxBlock int) SpanChannelOutOption { } } -func NewSpanChannelOut(genesisTimestamp uint64, chainID *big.Int, targetOutputSize uint64, compressionAlgo CompressionAlgo, chainSpec *rollup.ChainSpec, opts ...SpanChannelOutOption) (*SpanChannelOut, error) { +func NewSpanChannelOut(targetOutputSize uint64, compressionAlgo CompressionAlgo, chainSpec *rollup.ChainSpec, opts ...SpanChannelOutOption) (*SpanChannelOut, error) { c := &SpanChannelOut{ id: ChannelID{}, frame: 0, - spanBatch: NewSpanBatch(genesisTimestamp, chainID), + spanBatch: NewSpanBatch(chainSpec.L2GenesisTime(), chainSpec.L2ChainID()), rlp: [2]*bytes.Buffer{{}, {}}, target: targetOutputSize, chainSpec: chainSpec, From 2f2554af50f88840d5ff6f38ba967737878cd933 Mon Sep 17 00:00:00 2001 From: Maurelian <john@oplabs.co> Date: Mon, 23 Sep 2024 09:43:49 -0400 Subject: [PATCH 235/264] Add AnchorStateRegistry Implementation to OPSM (#11955) * feat: Add ASR proxy to OPStackManager * feat: Add AnchorStateRegistry blueprint * feat: Add AnchorStateRegistry Implementation * feat: Return startingAnchorInputs as bytes The op-deployer tooling does not support structs, therefore we need to return a more generic type for compatibility. * rebuild snapshots * fix: ASR initializer encoding * handoff commit with op-deployer debugging debugging op-deployer test wip: literal anchor roots * test and golang fixes * hardcode permissioned state * hardcode 0xdead as the starting anchor root * chore: fix semver lock * fix: no permissionless root, remove hash from 0xdead * fix: use 0xdead root properly * fix: set the override in the input contract * Fix tests and accidental mutation of `Implementation` struct * lint * semver * Update op-chain-ops/deployer/opsm/opchain.go Co-authored-by: Maurelian <john@oplabs.co> * Update packages/contracts-bedrock/scripts/DeployOPChain.s.sol --------- Co-authored-by: Matthew Slipper <me@matthewslipper.com> Co-authored-by: Matt Solomon <matt@mattsolomon.dev> --- op-chain-ops/deployer/opsm/opchain.go | 12 ++++ .../scripts/DeployImplementations.s.sol | 16 +++--- .../scripts/DeployOPChain.s.sol | 57 ++++++++++++++++++- packages/contracts-bedrock/semver-lock.json | 4 +- .../snapshots/abi/OPStackManager.json | 5 ++ .../snapshots/abi/OPStackManagerInterop.json | 5 ++ .../src/L1/OPStackManager.sol | 40 ++++++++++--- .../test/DeployOPChain.t.sol | 45 ++++++++++++++- .../test/L1/OPStackManager.t.sol | 3 +- 9 files changed, 163 insertions(+), 24 deletions(-) diff --git a/op-chain-ops/deployer/opsm/opchain.go b/op-chain-ops/deployer/opsm/opchain.go index 79ad79569c3f..d600f200dcf1 100644 --- a/op-chain-ops/deployer/opsm/opchain.go +++ b/op-chain-ops/deployer/opsm/opchain.go @@ -9,6 +9,12 @@ import ( "github.com/ethereum-optimism/optimism/op-chain-ops/script" ) +// PermissionedGameStartingAnchorRoots is a root of bytes32(hex"dead") for the permissioned game at block 0, +// and no root for the permissionless game. +var PermissionedGameStartingAnchorRoots = []byte{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xde, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +} + type DeployOPChainInput struct { OpChainProxyAdminOwner common.Address SystemConfigOwner common.Address @@ -27,6 +33,10 @@ func (input *DeployOPChainInput) InputSet() bool { return true } +func (input *DeployOPChainInput) StartingAnchorRoots() []byte { + return PermissionedGameStartingAnchorRoots +} + type DeployOPChainOutput struct { OpChainProxyAdmin common.Address AddressManager common.Address @@ -65,6 +75,7 @@ func DeployOPChain(host *script.Host, input DeployOPChainInput) (DeployOPChainOu return dco, fmt.Errorf("failed to insert DeployOPChainInput precompile: %w", err) } defer cleanupInput() + host.Label(inputAddr, "DeployOPChainInput") cleanupOutput, err := script.WithPrecompileAtAddress[*DeployOPChainOutput](host, outputAddr, &dco, script.WithFieldSetter[*DeployOPChainOutput]) @@ -72,6 +83,7 @@ func DeployOPChain(host *script.Host, input DeployOPChainInput) (DeployOPChainOu return dco, fmt.Errorf("failed to insert DeployOPChainOutput precompile: %w", err) } defer cleanupOutput() + host.Label(outputAddr, "DeployOPChainOutput") deployScript, cleanupDeploy, err := script.WithScript[DeployOPChainScript](host, "DeployOPChain.s.sol", "DeployOPChain") if err != nil { diff --git a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol index 636053574331..433b1573efe4 100644 --- a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol +++ b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol @@ -617,14 +617,14 @@ contract DeployImplementations is Script { // The fault proofs contracts are configured as follows: // | Contract | Proxied | Deployment | MCP Ready | // |-------------------------|---------|-----------------------------------|------------| - // | DisputeGameFactory | Yes | Bespoke | Yes | - // | AnchorStateRegistry | Yes | Bespoke | No | - // | FaultDisputeGame | No | Bespoke | No | - // | PermissionedDisputeGame | No | Bespoke | No | - // | DelayedWETH | Yes | Two bespoke (one per DisputeGame) | No | - // | PreimageOracle | No | Shared | N/A | - // | MIPS | No | Shared | N/A | - // | OptimismPortal2 | Yes | Shared | No | + // | DisputeGameFactory | Yes | Bespoke | Yes | X + // | AnchorStateRegistry | Yes | Bespoke | No | X + // | FaultDisputeGame | No | Bespoke | No | Todo + // | PermissionedDisputeGame | No | Bespoke | No | Todo + // | DelayedWETH | Yes | Two bespoke (one per DisputeGame) | No | Todo: Proxies. + // | PreimageOracle | No | Shared | N/A | X + // | MIPS | No | Shared | N/A | X + // | OptimismPortal2 | Yes | Shared | No | X // // This script only deploys the shared contracts. The bespoke contracts are deployed by // `DeployOPChain.s.sol`. When the shared contracts are proxied, the contracts deployed here are diff --git a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol index d2fec4e9e6d2..50fd9060ae91 100644 --- a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol @@ -15,6 +15,7 @@ import { Constants } from "src/libraries/Constants.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; +import { Proxy } from "src/universal/Proxy.sol"; import { AddressManager } from "src/legacy/AddressManager.sol"; import { DelayedWETH } from "src/dispute/DelayedWETH.sol"; @@ -22,6 +23,7 @@ import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; +import { GameType, GameTypes, Hash, OutputRoot } from "src/dispute/lib/Types.sol"; import { OPStackManager } from "src/L1/OPStackManager.sol"; import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; @@ -116,6 +118,26 @@ contract DeployOPChainInput is BaseDeployIO { return _l2ChainId; } + function startingAnchorRoots() public pure returns (bytes memory) { + // WARNING: For now always hardcode the starting permissioned game anchor root to 0xdead, + // and we do not set anything for the permissioned game. This is because we currently only + // support deploying straight to permissioned games, and the starting root does not + // matter for that, as long as it is non-zero, since no games will be played. We do not + // deploy the permissionless game (and therefore do not set a starting root for it here) + // because to to update to the permissionless game, we will need to update its starting + // anchor root and deploy a new permissioned dispute game contract anyway. + // + // You can `console.logBytes(abi.encode(defaultStartingAnchorRoots))` to get the bytes that + // are hardcoded into `op-chain-ops/deployer/opsm/opchain.go` + AnchorStateRegistry.StartingAnchorRoot[] memory defaultStartingAnchorRoots = + new AnchorStateRegistry.StartingAnchorRoot[](1); + defaultStartingAnchorRoots[0] = AnchorStateRegistry.StartingAnchorRoot({ + gameType: GameTypes.PERMISSIONED_CANNON, + outputRoot: OutputRoot({ root: Hash.wrap(bytes32(hex"dead")), l2BlockNumber: 0 }) + }); + return abi.encode(defaultStartingAnchorRoots); + } + // TODO: Check that opsm is proxied and it has an implementation. function opsmProxy() public view returns (OPStackManager) { require(address(_opsmProxy) != address(0), "DeployOPChainInput: not set"); @@ -162,7 +184,7 @@ contract DeployOPChainOutput is BaseDeployIO { // forgefmt: disable-end } - function checkOutput(DeployOPChainInput _doi) public view { + function checkOutput(DeployOPChainInput _doi) public { // With 16 addresses, we'd get a stack too deep error if we tried to do this inline as a // single call to `Solarray.addresses`. So we split it into two calls. address[] memory addrs1 = Solarray.addresses( @@ -266,7 +288,9 @@ contract DeployOPChainOutput is BaseDeployIO { // -------- Deployment Assertions -------- - function assertValidDeploy(DeployOPChainInput _doi) internal view { + function assertValidDeploy(DeployOPChainInput _doi) internal { + assertValidAnchorStateRegistryProxy(_doi); + assertValidAnchorStateRegistryImpl(_doi); assertValidDelayedWETHs(_doi); assertValidDisputeGameFactory(_doi); assertValidL1CrossDomainMessenger(_doi); @@ -279,6 +303,32 @@ contract DeployOPChainOutput is BaseDeployIO { // TODO add initialization assertions } + function assertValidAnchorStateRegistryProxy(DeployOPChainInput) internal { + // First we check the proxy as itself. + Proxy proxy = Proxy(payable(address(anchorStateRegistryProxy()))); + vm.prank(address(0)); + address admin = proxy.admin(); + require(admin == address(opChainProxyAdmin()), "ANCHORP-10"); + + // Then we check the proxy as ASR. + DeployUtils.assertInitialized({ _contractAddress: address(anchorStateRegistryProxy()), _slot: 0, _offset: 0 }); + + vm.prank(address(0)); + address impl = proxy.implementation(); + require(impl == address(anchorStateRegistryImpl()), "ANCHORP-20"); + require( + address(anchorStateRegistryProxy().disputeGameFactory()) == address(disputeGameFactoryProxy()), "ANCHORP-30" + ); + } + + function assertValidAnchorStateRegistryImpl(DeployOPChainInput) internal view { + AnchorStateRegistry registry = anchorStateRegistryImpl(); + + DeployUtils.assertInitialized({ _contractAddress: address(registry), _slot: 0, _offset: 0 }); + + require(address(registry.disputeGameFactory()) == address(disputeGameFactoryProxy()), "ANCHORI-10"); + } + function assertValidSystemConfig(DeployOPChainInput _doi) internal view { SystemConfig systemConfig = systemConfigProxy(); @@ -412,7 +462,8 @@ contract DeployOPChain is Script { roles: roles, basefeeScalar: _doi.basefeeScalar(), blobBasefeeScalar: _doi.blobBaseFeeScalar(), - l2ChainId: _doi.l2ChainId() + l2ChainId: _doi.l2ChainId(), + startingAnchorRoots: _doi.startingAnchorRoots() }); vm.broadcast(msg.sender); diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 91897e737ccf..db35c5b37429 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -32,8 +32,8 @@ "sourceCodeHash": "0xde4df0f9633dc0cdb1c9f634003ea5b0f7c5c1aebc407bc1b2f44c0ecf938649" }, "src/L1/OPStackManager.sol": { - "initCodeHash": "0x022b3f6a80eb637972dd0d9ce8666a037c4b916889f44f86771d8c3add9d615d", - "sourceCodeHash": "0xb085725e18c1a0cc1826b770e403ecad765fce686bb80555bf0f6c3c67b21cba" + "initCodeHash": "0x4bffecbd95e63f9bd04ab8e3c6a804cc25e0cd151ebeb7f8d6b9330332e6eb20", + "sourceCodeHash": "0x850f1eacc77f1a5c680625196618bc4b4332cb68924d9eddd57c749bedcd7c94" }, "src/L1/OptimismPortal.sol": { "initCodeHash": "0xbe2c0c81b3459014f287d8c89cdc0d27dde5d1f44e5d024fa1e4773ddc47c190", diff --git a/packages/contracts-bedrock/snapshots/abi/OPStackManager.json b/packages/contracts-bedrock/snapshots/abi/OPStackManager.json index 8f8d68515681..2ad0a4d1dc2c 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPStackManager.json +++ b/packages/contracts-bedrock/snapshots/abi/OPStackManager.json @@ -134,6 +134,11 @@ "internalType": "uint256", "name": "l2ChainId", "type": "uint256" + }, + { + "internalType": "bytes", + "name": "startingAnchorRoots", + "type": "bytes" } ], "internalType": "struct OPStackManager.DeployInput", diff --git a/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json b/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json index 8f8d68515681..2ad0a4d1dc2c 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json +++ b/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json @@ -134,6 +134,11 @@ "internalType": "uint256", "name": "l2ChainId", "type": "uint256" + }, + { + "internalType": "bytes", + "name": "startingAnchorRoots", + "type": "bytes" } ], "internalType": "struct OPStackManager.DeployInput", diff --git a/packages/contracts-bedrock/src/L1/OPStackManager.sol b/packages/contracts-bedrock/src/L1/OPStackManager.sol index dad32c5628ea..f7d71233005e 100644 --- a/packages/contracts-bedrock/src/L1/OPStackManager.sol +++ b/packages/contracts-bedrock/src/L1/OPStackManager.sol @@ -55,6 +55,9 @@ contract OPStackManager is ISemver, Initializable { uint32 basefeeScalar; uint32 blobBasefeeScalar; uint256 l2ChainId; + // The correct type is AnchorStateRegistry.StartingAnchorRoot[] memory, + // but OP Deployer does not yet support structs. + bytes startingAnchorRoots; } /// @notice The full set of outputs from deploying a new OP Stack chain. @@ -115,8 +118,8 @@ contract OPStackManager is ISemver, Initializable { // -------- Constants and Variables -------- - /// @custom:semver 1.0.0-beta.3 - string public constant version = "1.0.0-beta.3"; + /// @custom:semver 1.0.0-beta.4 + string public constant version = "1.0.0-beta.4"; /// @notice Address of the SuperchainConfig contract shared by all chains. SuperchainConfig public immutable superchainConfig; @@ -206,8 +209,6 @@ contract OPStackManager is ISemver, Initializable { // -------- TODO: Placeholders -------- // For contracts we don't yet deploy, we set the outputs to dummy proxies so they have code to pass assertions. // We do these first, that way the disputeGameFactoryProxy is set when passed to the SystemConfig input. - output.anchorStateRegistryProxy = AnchorStateRegistry(deployProxy(l2ChainId, output.opChainProxyAdmin, "3")); - output.anchorStateRegistryImpl = AnchorStateRegistry(deployProxy(l2ChainId, output.opChainProxyAdmin, "4")); output.faultDisputeGame = FaultDisputeGame(deployProxy(l2ChainId, output.opChainProxyAdmin, "5")); output.permissionedDisputeGame = PermissionedDisputeGame(deployProxy(l2ChainId, output.opChainProxyAdmin, "6")); output.delayedWETHPermissionedGameProxy = @@ -266,7 +267,7 @@ contract OPStackManager is ISemver, Initializable { ); // -------- Set and Initialize Proxy Implementations -------- - Implementation storage impl; + Implementation memory impl; bytes memory data; impl = getLatestImplementation("L1ERC721Bridge"); @@ -293,10 +294,16 @@ contract OPStackManager is ISemver, Initializable { data = encodeL1StandardBridgeInitializer(impl.initializer, output); upgradeAndCall(output.opChainProxyAdmin, address(output.l1StandardBridgeProxy), impl.logic, data); + // TODO: also call setImplementation() once the dispute games are deployed. impl = getLatestImplementation("DisputeGameFactory"); data = encodeDisputeGameFactoryInitializer(impl.initializer, _input); upgradeAndCall(output.opChainProxyAdmin, address(output.disputeGameFactoryProxy), impl.logic, data); + impl.logic = address(output.anchorStateRegistryImpl); + impl.initializer = AnchorStateRegistry.initialize.selector; + data = encodeAnchorStateRegistryInitializer(impl.initializer, _input); + upgradeAndCall(output.opChainProxyAdmin, address(output.anchorStateRegistryProxy), impl.logic, data); + // -------- Finalize Deployment -------- // Transfer ownership of the ProxyAdmin from this contract to the specified owner. output.opChainProxyAdmin.transferOwnership(_input.roles.opChainProxyAdminOwner); @@ -345,9 +352,11 @@ contract OPStackManager is ISemver, Initializable { return Blueprint.deployFrom(blueprint.proxy, salt, abi.encode(_proxyAdmin)); } - /// @notice Returns the implementation data for a contract name. - function getLatestImplementation(string memory _name) internal view returns (Implementation storage) { - return implementations[latestRelease][_name]; + /// @notice Returns the implementation data for a contract name. Makes a copy of the internal + // Implementation struct in storage to prevent accidental mutation of the internal data. + function getLatestImplementation(string memory _name) internal view returns (Implementation memory) { + Implementation storage impl = implementations[latestRelease][_name]; + return Implementation({ logic: impl.logic, initializer: impl.initializer }); } // -------- Initializer Encoding -------- @@ -464,6 +473,21 @@ contract OPStackManager is ISemver, Initializable { return abi.encodeWithSelector(_selector, _input.roles.opChainProxyAdminOwner); } + function encodeAnchorStateRegistryInitializer( + bytes4 _selector, + DeployInput memory _input + ) + internal + view + virtual + returns (bytes memory) + { + // this line fails in the op-deployer tests because it is not passing in any data + AnchorStateRegistry.StartingAnchorRoot[] memory startingAnchorRoots = + abi.decode(_input.startingAnchorRoots, (AnchorStateRegistry.StartingAnchorRoot[])); + return abi.encodeWithSelector(_selector, startingAnchorRoots, superchainConfig); + } + /// @notice Returns default, standard config arguments for the SystemConfig initializer. /// This is used by subclasses to reduce code duplication. function defaultSystemConfigParams( diff --git a/packages/contracts-bedrock/test/DeployOPChain.t.sol b/packages/contracts-bedrock/test/DeployOPChain.t.sol index b0a4cb15507e..ef8fc06cc626 100644 --- a/packages/contracts-bedrock/test/DeployOPChain.t.sol +++ b/packages/contracts-bedrock/test/DeployOPChain.t.sol @@ -31,6 +31,8 @@ import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; +import { GameType, GameTypes, Hash, OutputRoot } from "src/dispute/lib/Types.sol"; + contract DeployOPChainInput_Test is Test { DeployOPChainInput doi; @@ -336,9 +338,29 @@ contract DeployOPChain_TestBase is Test { uint32 basefeeScalar = 100; uint32 blobBaseFeeScalar = 200; uint256 l2ChainId = 300; + AnchorStateRegistry.StartingAnchorRoot[] startingAnchorRoots; OPStackManager opsm = OPStackManager(address(0)); function setUp() public virtual { + // Set defaults for reference types + uint256 cannonBlock = 400; + uint256 permissionedBlock = 500; + startingAnchorRoots.push( + AnchorStateRegistry.StartingAnchorRoot({ + gameType: GameTypes.CANNON, + outputRoot: OutputRoot({ root: Hash.wrap(keccak256("defaultOutputRootCannon")), l2BlockNumber: cannonBlock }) + }) + ); + startingAnchorRoots.push( + AnchorStateRegistry.StartingAnchorRoot({ + gameType: GameTypes.PERMISSIONED_CANNON, + outputRoot: OutputRoot({ + root: Hash.wrap(keccak256("defaultOutputRootPermissioned")), + l2BlockNumber: permissionedBlock + }) + }) + ); + // Initialize deploy scripts. DeploySuperchain deploySuperchain = new DeploySuperchain(); (DeploySuperchainInput dsi, DeploySuperchainOutput dso) = deploySuperchain.etchIOContracts(); @@ -389,7 +411,7 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { return keccak256(abi.encode(_seed, _i)); } - function testFuzz_run_memory_succeeds(bytes32 _seed) public { + function testFuzz_run_memory_succeed(bytes32 _seed) public { opChainProxyAdminOwner = address(uint160(uint256(hash(_seed, 0)))); systemConfigOwner = address(uint160(uint256(hash(_seed, 1)))); batcher = address(uint160(uint256(hash(_seed, 2)))); @@ -398,7 +420,26 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { challenger = address(uint160(uint256(hash(_seed, 5)))); basefeeScalar = uint32(uint256(hash(_seed, 6))); blobBaseFeeScalar = uint32(uint256(hash(_seed, 7))); - l2ChainId = uint256(uint256(hash(_seed, 8))); + l2ChainId = uint256(hash(_seed, 8)); + + // Set the initial anchor states. The typical usage we expect is to pass in one root per game type. + uint256 cannonBlock = uint256(hash(_seed, 9)); + uint256 permissionedBlock = uint256(hash(_seed, 10)); + startingAnchorRoots.push( + AnchorStateRegistry.StartingAnchorRoot({ + gameType: GameTypes.CANNON, + outputRoot: OutputRoot({ root: Hash.wrap(keccak256(abi.encode(_seed, 11))), l2BlockNumber: cannonBlock }) + }) + ); + startingAnchorRoots.push( + AnchorStateRegistry.StartingAnchorRoot({ + gameType: GameTypes.PERMISSIONED_CANNON, + outputRoot: OutputRoot({ + root: Hash.wrap(keccak256(abi.encode(_seed, 12))), + l2BlockNumber: permissionedBlock + }) + }) + ); doi.set(doi.opChainProxyAdminOwner.selector, opChainProxyAdminOwner); doi.set(doi.systemConfigOwner.selector, systemConfigOwner); diff --git a/packages/contracts-bedrock/test/L1/OPStackManager.t.sol b/packages/contracts-bedrock/test/L1/OPStackManager.t.sol index 0443c9f0c46d..6d9d7d134c33 100644 --- a/packages/contracts-bedrock/test/L1/OPStackManager.t.sol +++ b/packages/contracts-bedrock/test/L1/OPStackManager.t.sol @@ -62,7 +62,8 @@ contract OPStackManager_Deploy_Test is DeployOPChain_TestBase { }), basefeeScalar: _doi.basefeeScalar(), blobBasefeeScalar: _doi.blobBaseFeeScalar(), - l2ChainId: _doi.l2ChainId() + l2ChainId: _doi.l2ChainId(), + startingAnchorRoots: _doi.startingAnchorRoots() }); } From d204c1f1d28e045f1c2c4442a1395879c44e3257 Mon Sep 17 00:00:00 2001 From: Adrian Sutton <adrian@oplabs.co> Date: Tue, 24 Sep 2024 02:49:19 +1000 Subject: [PATCH 236/264] proofs-tools: Update op-challenger version in proofs-tools. (#12055) Includes fix to stop running mt-cannon in parallel. --- docker-bake.hcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-bake.hcl b/docker-bake.hcl index 788b9a651745..b09495948745 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -206,7 +206,7 @@ target "proofs-tools" { dockerfile = "./ops/docker/proofs-tools/Dockerfile" context = "." args = { - CHALLENGER_VERSION="2fcbe4bab16a682bd51c2f0e6bd9be7f8d81c7a1" + CHALLENGER_VERSION="90700b9bb37080961747420882b14578577d47cc" KONA_VERSION="kona-client-v0.1.0-alpha.3" ASTERISC_VERSION="v1.0.2" } From f86ccc833e618605b9155257d8e2090fd249aab6 Mon Sep 17 00:00:00 2001 From: smartcontracts <kelvin@optimism.io> Date: Mon, 23 Sep 2024 16:06:27 -0400 Subject: [PATCH 237/264] fix(ci): do not check closed issues in main job (#12066) Updates the todo-checker to not check for closed issues in the main job. Will still check for closed issues in the scheduled job. Prevents CI from randomly failing when stuff gets closed. --- .circleci/config.yml | 7 ++++++- ops/scripts/todo-checker.sh | 16 ++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f4975442dd87..dccd91867d5b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -714,6 +714,10 @@ jobs: working_directory: packages/contracts-bedrock todo-issues: + parameters: + check_closed: + type: boolean + default: true machine: image: <<pipeline.parameters.base_image>> steps: @@ -723,7 +727,7 @@ jobs: command: sudo apt-get install -y ripgrep - run: name: Check TODO issues - command: ./ops/scripts/todo-checker.sh --verbose + command: ./ops/scripts/todo-checker.sh --verbose <<#parameters.check_closed>> --check-closed <</parameters.check_closed>> - notify-failures-on-develop fuzz-golang: @@ -1709,6 +1713,7 @@ workflows: - cannon-build-test-vectors - todo-issues: name: todo-issues-check + check_closed: false - shellcheck/check: name: shell-check # We don't need the `exclude` key as the orb detects the `.shellcheckrc` diff --git a/ops/scripts/todo-checker.sh b/ops/scripts/todo-checker.sh index 4aebcf1a957d..6b144ec200cf 100755 --- a/ops/scripts/todo-checker.sh +++ b/ops/scripts/todo-checker.sh @@ -5,6 +5,7 @@ set -uo pipefail # Flags FAIL_INVALID_FMT=false VERBOSE=false +CHECK_CLOSED=false # Github API access token (Optional - necessary for private repositories.) GH_API_TOKEN="${CI_TODO_CHECKER_PAT:-""}" @@ -36,6 +37,7 @@ NC='\033[0m' # No Color # # `--strict`: Toggle strict mode; Will fail if any TODOs are found that don't match the expected # `--verbose`: Toggle verbose mode; Will print out details about each TODO +# `--check-closed`: Check for closed issues and error out if found for arg in "$@"; do case $arg in --strict) @@ -46,6 +48,10 @@ for arg in "$@"; do VERBOSE=true shift ;; + --check-closed) + CHECK_CLOSED=true + shift + ;; esac done @@ -104,14 +110,16 @@ for todo in $todos; do # Check issue state STATE=$(echo "$RESPONSE" | jq -r .state) - if [[ "$STATE" == "closed" ]]; then + if [[ "$STATE" == "closed" ]] && $CHECK_CLOSED; then echo -e "${RED}[Error]:${NC} Issue #$ISSUE_NUM is closed. Please remove the TODO in ${GREEN}$FILE:$LINE_NUM${NC} referencing ${YELLOW}$ISSUE_REFERENCE${NC} (${CYAN}https://github.com/$GH_URL_PATH${NC})" exit 1 fi - ((OPEN_COUNT++)) - TITLE=$(echo "$RESPONSE" | jq -r .title) - OPEN_ISSUES+=("$REPO_FULL/issues/$ISSUE_NUM|$TITLE|$FILE:$LINE_NUM") + if [[ "$STATE" == "open" ]]; then + ((OPEN_COUNT++)) + TITLE=$(echo "$RESPONSE" | jq -r .title) + OPEN_ISSUES+=("$REPO_FULL/issues/$ISSUE_NUM|$TITLE|$FILE:$LINE_NUM") + fi done # Print summary From 9178d5fff5a16ab47b6efcd4c03904c188ae9292 Mon Sep 17 00:00:00 2001 From: smartcontracts <kelvin@optimism.io> Date: Mon, 23 Sep 2024 16:06:42 -0400 Subject: [PATCH 238/264] feat: deploy utils cleanup (#12027) Updates DeployUtils to include new utils for using create and create2. --- .../scripts/libraries/DeployUtils.sol | 207 +++++++++++++++++- 1 file changed, 197 insertions(+), 10 deletions(-) diff --git a/packages/contracts-bedrock/scripts/libraries/DeployUtils.sol b/packages/contracts-bedrock/scripts/libraries/DeployUtils.sol index cf8eaf7cb69f..92870309657e 100644 --- a/packages/contracts-bedrock/scripts/libraries/DeployUtils.sol +++ b/packages/contracts-bedrock/scripts/libraries/DeployUtils.sol @@ -1,27 +1,212 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Proxy } from "src/universal/Proxy.sol"; -import { LibString } from "@solady/utils/LibString.sol"; +// Scripts import { Vm } from "forge-std/Vm.sol"; +import { console2 as console } from "forge-std/console2.sol"; +import { Artifacts } from "scripts/Artifacts.s.sol"; + +// Libraries +import { LibString } from "@solady/utils/LibString.sol"; + +// Contracts +import { Proxy } from "src/universal/Proxy.sol"; library DeployUtils { Vm internal constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - // This takes a sender and an identifier and returns a deterministic address based on the two. - // The result is used to etch the input and output contracts to a deterministic address based on - // those two values, where the identifier represents the input or output contract, such as - // `optimism.DeploySuperchainInput` or `optimism.DeployOPChainOutput`. - // Example: `toIOAddress(msg.sender, "optimism.DeploySuperchainInput")` + /// @notice Deploys a contract with the given name and arguments via CREATE. + /// @param _name Name of the contract to deploy. + /// @param _args ABI-encoded constructor arguments. + /// @return addr_ Address of the deployed contract. + function create1(string memory _name, bytes memory _args) internal returns (address payable addr_) { + bytes memory bytecode = abi.encodePacked(vm.getCode(_name), _args); + assembly { + addr_ := create(0, add(bytecode, 0x20), mload(bytecode)) + } + assertValidContractAddress(addr_); + } + + /// @notice Deploys a contract with the given name via CREATE. + /// @param _name Name of the contract to deploy. + /// @return Address of the deployed contract. + function create1(string memory _name) internal returns (address payable) { + return create1(_name, hex""); + } + + /// @notice Deploys a contract with the given name and arguments via CREATE and saves the result. + /// @param _save Artifacts contract. + /// @param _name Name of the contract to deploy. + /// @param _nick Nickname to save the address to. + /// @param _args ABI-encoded constructor arguments. + /// @return addr_ Address of the deployed contract. + function create1AndSave( + Artifacts _save, + string memory _name, + string memory _nick, + bytes memory _args + ) + internal + returns (address payable addr_) + { + console.log("Deploying %s", _nick); + addr_ = create1(_name, _args); + _save.save(_nick, addr_); + console.log("%s deployed at %s", _nick, addr_); + } + + /// @notice Deploys a contract with the given name via CREATE and saves the result. + /// @param _save Artifacts contract. + /// @param _name Name of the contract to deploy. + /// @param _nickname Nickname to save the address to. + /// @return addr_ Address of the deployed contract. + function create1AndSave( + Artifacts _save, + string memory _name, + string memory _nickname + ) + internal + returns (address payable addr_) + { + return create1AndSave(_save, _name, _nickname, hex""); + } + + /// @notice Deploys a contract with the given name and arguments via CREATE and saves the result. + /// @param _save Artifacts contract. + /// @param _name Name of the contract to deploy. + /// @param _args ABI-encoded constructor arguments. + /// @return addr_ Address of the deployed contract. + function create1AndSave( + Artifacts _save, + string memory _name, + bytes memory _args + ) + internal + returns (address payable addr_) + { + return create1AndSave(_save, _name, _name, _args); + } + + /// @notice Deploys a contract with the given name and arguments via CREATE2. + /// @param _name Name of the contract to deploy. + /// @param _args ABI-encoded constructor arguments. + /// @param _salt Salt for the CREATE2 operation. + /// @return addr_ Address of the deployed contract. + function create2(string memory _name, bytes memory _args, bytes32 _salt) internal returns (address payable addr_) { + bytes memory initCode = abi.encodePacked(vm.getCode(_name), _args); + address preComputedAddress = vm.computeCreate2Address(_salt, keccak256(initCode)); + require(preComputedAddress.code.length == 0, "DeployUtils: contract already deployed"); + assembly { + addr_ := create2(0, add(initCode, 0x20), mload(initCode), _salt) + } + assertValidContractAddress(addr_); + } + + /// @notice Deploys a contract with the given name via CREATE2. + /// @param _name Name of the contract to deploy. + /// @param _salt Salt for the CREATE2 operation. + /// @return Address of the deployed contract. + function create2(string memory _name, bytes32 _salt) internal returns (address payable) { + return create2(_name, hex"", _salt); + } + + /// @notice Deploys a contract with the given name and arguments via CREATE2 and saves the result. + /// @param _save Artifacts contract. + /// @param _name Name of the contract to deploy. + /// @param _nick Nickname to save the address to. + /// @param _args ABI-encoded constructor arguments. + /// @param _salt Salt for the CREATE2 operation. + /// @return addr_ Address of the deployed contract. + function create2AndSave( + Artifacts _save, + string memory _name, + string memory _nick, + bytes memory _args, + bytes32 _salt + ) + internal + returns (address payable addr_) + { + console.log("Deploying %s", _nick); + addr_ = create2(_name, _args, _salt); + _save.save(_nick, addr_); + console.log("%s deployed at %s", _nick, addr_); + } + + /// @notice Deploys a contract with the given name via CREATE2 and saves the result. + /// @param _save Artifacts contract. + /// @param _name Name of the contract to deploy. + /// @param _nick Nickname to save the address to. + /// @param _salt Salt for the CREATE2 operation. + /// @return addr_ Address of the deployed contract. + function create2AndSave( + Artifacts _save, + string memory _name, + string memory _nick, + bytes32 _salt + ) + internal + returns (address payable addr_) + { + return create2AndSave(_save, _name, _nick, hex"", _salt); + } + + /// @notice Deploys a contract with the given name and arguments via CREATE2 and saves the result. + /// @param _save Artifacts contract. + /// @param _name Name of the contract to deploy. + /// @param _args ABI-encoded constructor arguments. + /// @param _salt Salt for the CREATE2 operation. + /// @return addr_ Address of the deployed contract. + function create2AndSave( + Artifacts _save, + string memory _name, + bytes memory _args, + bytes32 _salt + ) + internal + returns (address payable addr_) + { + return create2AndSave(_save, _name, _name, _args, _salt); + } + + /// @notice Deploys a contract with the given name via CREATE2 and saves the result. + /// @param _save Artifacts contract. + /// @param _name Name of the contract to deploy. + /// @param _salt Salt for the CREATE2 operation. + /// @return addr_ Address of the deployed contract. + function create2AndSave( + Artifacts _save, + string memory _name, + bytes32 _salt + ) + internal + returns (address payable addr_) + { + return create2AndSave(_save, _name, _name, hex"", _salt); + } + + /// @notice Takes a sender and an identifier and returns a deterministic address based on the + /// two. The result is used to etch the input and output contracts to a deterministic + /// address based on those two values, where the identifier represents the input or + /// output contract, such as `optimism.DeploySuperchainInput` or + /// `optimism.DeployOPChainOutput`. + /// Example: `toIOAddress(msg.sender, "optimism.DeploySuperchainInput")` + /// @param _sender Address of the sender. + /// @param _identifier Additional identifier. + /// @return Deterministic address. function toIOAddress(address _sender, string memory _identifier) internal pure returns (address) { return address(uint160(uint256(keccak256(abi.encode(_sender, _identifier))))); } + /// @notice Asserts that the given address is a valid contract address. + /// @param _who Address to check. function assertValidContractAddress(address _who) internal view { require(_who != address(0), "DeployUtils: zero address"); require(_who.code.length > 0, string.concat("DeployUtils: no code at ", LibString.toHexStringChecksummed(_who))); } + /// @notice Asserts that the given proxy has an implementation set. + /// @param _proxy Proxy to check. function assertImplementationSet(address _proxy) internal { // We prank as the zero address due to the Proxy's `proxyCallIfNotAdmin` modifier. // Pranking inside this function also means it can no longer be considered `view`. @@ -30,6 +215,8 @@ library DeployUtils { assertValidContractAddress(implementation); } + /// @notice Asserts that the given addresses are valid contract addresses. + /// @param _addrs Addresses to check. function assertValidContractAddresses(address[] memory _addrs) internal view { // Assert that all addresses are non-zero and have code. // We use LibString to avoid the need for adding cheatcodes to this contract. @@ -48,9 +235,9 @@ library DeployUtils { } } - // Asserts that for a given contract the value of a storage slot at an offset is 1 or - // `type(uint8).max`. The value is set to 1 when a contract is initialized, and set to - // `type(uint8).max` when `_disableInitializers` is called. + /// @notice Asserts that for a given contract the value of a storage slot at an offset is 1 or + /// `type(uint8).max`. The value is set to 1 when a contract is initialized, and set to + /// `type(uint8).max` when `_disableInitializers` is called. function assertInitialized(address _contractAddress, uint256 _slot, uint256 _offset) internal view { bytes32 slotVal = vm.load(_contractAddress, bytes32(_slot)); uint8 value = uint8((uint256(slotVal) >> (_offset * 8)) & 0xFF); From 9a12768ca95fff8c32f513705e4124646a95a2c7 Mon Sep 17 00:00:00 2001 From: tre <tremarkley@gmail.com> Date: Mon, 23 Sep 2024 14:17:54 -0700 Subject: [PATCH 239/264] feat(L2ToL2CrossDomainMessenger): add successfulMessages and messageNonce to IL2ToL2CrossDomainMessenger (#12068) * feat(L2ToL2CrossDomainMessenger): add successfulMessages and messageNonce to interface * lint --- .../L2/interfaces/IL2ToL2CrossDomainMessenger.sol | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/contracts-bedrock/src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol index 8b6b9d617cf1..cb8d1952de65 100644 --- a/packages/contracts-bedrock/src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol +++ b/packages/contracts-bedrock/src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol @@ -4,6 +4,19 @@ pragma solidity ^0.8.0; /// @title IL2ToL2CrossDomainMessenger /// @notice Interface for the L2ToL2CrossDomainMessenger contract. interface IL2ToL2CrossDomainMessenger { + /// @notice Mapping of message hashes to boolean receipt values. Note that a message will only + /// be present in this mapping if it has successfully been relayed on this chain, and + /// can therefore not be relayed again. + /// @param _msgHash message hash to check. + /// @return Returns true if the message corresponding to the `_msgHash` was successfully relayed. + function successfulMessages(bytes32 _msgHash) external view returns (bool); + + /// @notice Retrieves the next message nonce. Message version will be added to the upper two + /// bytes of the message nonce. Message version allows us to treat messages as having + /// different structures. + /// @return Nonce of the next message to be sent, with added message version. + function messageNonce() external view returns (uint256); + /// @notice Retrieves the sender of the current cross domain message. /// @return _sender Address of the sender of the current cross domain message. function crossDomainMessageSender() external view returns (address _sender); From 718b9b018dd821b0bd205df5c6d02ac7dbbba77d Mon Sep 17 00:00:00 2001 From: protolambda <proto@protolambda.com> Date: Mon, 23 Sep 2024 16:08:26 -0600 Subject: [PATCH 240/264] op-supervisor: encode full hashes (#12071) --- op-supervisor/supervisor/backend/backend.go | 3 +- op-supervisor/supervisor/backend/db/db.go | 11 +- .../supervisor/backend/db/db_test.go | 33 ++- .../supervisor/backend/db/entrydb/entry_db.go | 2 +- .../supervisor/backend/db/logs/db.go | 28 +-- .../supervisor/backend/db/logs/db_test.go | 208 +++++++++--------- .../supervisor/backend/db/logs/entries.go | 36 ++- .../supervisor/backend/db/logs/iterator.go | 12 +- .../supervisor/backend/db/logs/state.go | 46 ++-- .../supervisor/backend/db/safety_checkers.go | 13 +- .../backend/db/safety_checkers_test.go | 20 +- .../backend/source/contracts/l2inbox.go | 21 +- .../backend/source/contracts/l2inbox_test.go | 4 +- .../backend/source/log_processor.go | 21 +- .../backend/source/log_processor_test.go | 27 ++- .../supervisor/backend/types/types.go | 27 --- op-supervisor/supervisor/types/types.go | 8 + 17 files changed, 246 insertions(+), 274 deletions(-) delete mode 100644 op-supervisor/supervisor/backend/types/types.go diff --git a/op-supervisor/supervisor/backend/backend.go b/op-supervisor/supervisor/backend/backend.go index 57b17e591059..54b2f2eae20a 100644 --- a/op-supervisor/supervisor/backend/backend.go +++ b/op-supervisor/supervisor/backend/backend.go @@ -21,7 +21,6 @@ import ( "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/source" - backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/frontend" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" ) @@ -191,7 +190,7 @@ func (su *SupervisorBackend) CheckMessage(identifier types.Identifier, payloadHa chainID := identifier.ChainID blockNum := identifier.BlockNumber logIdx := identifier.LogIndex - i, err := su.db.Check(chainID, blockNum, uint32(logIdx), backendTypes.TruncateHash(payloadHash)) + i, err := su.db.Check(chainID, blockNum, uint32(logIdx), payloadHash) if errors.Is(err, logs.ErrFuture) { return types.Unsafe, nil } diff --git a/op-supervisor/supervisor/backend/db/db.go b/op-supervisor/supervisor/backend/db/db.go index ac8c5f506ca5..184be4df76c1 100644 --- a/op-supervisor/supervisor/backend/db/db.go +++ b/op-supervisor/supervisor/backend/db/db.go @@ -14,7 +14,6 @@ import ( "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs" - backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" ) @@ -25,8 +24,8 @@ var ( type LogStorage interface { io.Closer - AddLog(logHash backendTypes.TruncatedHash, parentBlock eth.BlockID, - logIdx uint32, execMsg *backendTypes.ExecutingMessage) error + AddLog(logHash common.Hash, parentBlock eth.BlockID, + logIdx uint32, execMsg *types.ExecutingMessage) error SealBlock(parentHash common.Hash, block eth.BlockID, timestamp uint64) error @@ -45,7 +44,7 @@ type LogStorage interface { // returns ErrConflict if the log does not match the canonical chain. // returns ErrFuture if the log is out of reach. // returns nil if the log is known and matches the canonical chain. - Contains(blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) (nextIndex entrydb.EntryIdx, err error) + Contains(blockNum uint64, logIdx uint32, logHash common.Hash) (nextIndex entrydb.EntryIdx, err error) } var _ LogStorage = (*logs.DB)(nil) @@ -125,7 +124,7 @@ func (db *ChainsDB) StartCrossHeadMaintenance(ctx context.Context) { } // Check calls the underlying logDB to determine if the given log entry is safe with respect to the checker's criteria. -func (db *ChainsDB) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) (entrydb.EntryIdx, error) { +func (db *ChainsDB) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash common.Hash) (entrydb.EntryIdx, error) { logDB, ok := db.logDBs[chain] if !ok { return 0, fmt.Errorf("%w: %v", ErrUnknownChain, chain) @@ -267,7 +266,7 @@ func (db *ChainsDB) SealBlock(chain types.ChainID, parentHash common.Hash, block return logDB.SealBlock(parentHash, block, timestamp) } -func (db *ChainsDB) AddLog(chain types.ChainID, logHash backendTypes.TruncatedHash, parentBlock eth.BlockID, logIdx uint32, execMsg *backendTypes.ExecutingMessage) error { +func (db *ChainsDB) AddLog(chain types.ChainID, logHash common.Hash, parentBlock eth.BlockID, logIdx uint32, execMsg *types.ExecutingMessage) error { logDB, ok := db.logDBs[chain] if !ok { return fmt.Errorf("%w: %v", ErrUnknownChain, chain) diff --git a/op-supervisor/supervisor/backend/db/db_test.go b/op-supervisor/supervisor/backend/db/db_test.go index eb10afd7f641..e1da3c177b10 100644 --- a/op-supervisor/supervisor/backend/db/db_test.go +++ b/op-supervisor/supervisor/backend/db/db_test.go @@ -16,14 +16,13 @@ import ( "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs" - backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" ) func TestChainsDB_AddLog(t *testing.T) { t.Run("UnknownChain", func(t *testing.T) { db := NewChainsDB(nil, &stubHeadStorage{}, testlog.Logger(t, log.LevelDebug)) - err := db.AddLog(types.ChainIDFromUInt64(2), backendTypes.TruncatedHash{}, eth.BlockID{}, 33, nil) + err := db.AddLog(types.ChainIDFromUInt64(2), common.Hash{}, eth.BlockID{}, 33, nil) require.ErrorIs(t, err, ErrUnknownChain) }) @@ -36,7 +35,7 @@ func TestChainsDB_AddLog(t *testing.T) { bl10 := eth.BlockID{Hash: common.Hash{0x10}, Number: 10} err := db.SealBlock(chainID, common.Hash{0x9}, bl10, 1234) require.NoError(t, err, err) - err = db.AddLog(chainID, backendTypes.TruncatedHash{}, bl10, 0, nil) + err = db.AddLog(chainID, common.Hash{}, bl10, 0, nil) require.NoError(t, err, err) require.Equal(t, 1, logDB.addLogCalls) require.Equal(t, 1, logDB.sealBlockCalls) @@ -195,13 +194,13 @@ func setupStubbedForUpdateHeads(chainID types.ChainID) (*stubLogDB, *stubChecker logDB := &stubLogDB{} // set up stubbed executing messages that the ChainsDB can pass to the checker - logDB.executingMessages = []*backendTypes.ExecutingMessage{} + logDB.executingMessages = []*types.ExecutingMessage{} for i := 0; i < numExecutingMessages; i++ { // executing messages are packed in groups of 3, with block numbers increasing by 1 - logDB.executingMessages = append(logDB.executingMessages, &backendTypes.ExecutingMessage{ + logDB.executingMessages = append(logDB.executingMessages, &types.ExecutingMessage{ BlockNum: uint64(100 + int(i/3)), LogIdx: uint32(i), - Hash: backendTypes.TruncatedHash{}, + Hash: common.Hash{}, }) } @@ -210,7 +209,7 @@ func setupStubbedForUpdateHeads(chainID types.ChainID) (*stubLogDB, *stubChecker logIndex := uint32(0) executedCount := 0 for i := entrydb.EntryIdx(0); i <= local; i++ { - var logHash backendTypes.TruncatedHash + var logHash common.Hash rng.Read(logHash[:]) execIndex := -1 @@ -266,7 +265,7 @@ func (s *stubChecker) CrossHeadForChain(chainID types.ChainID) entrydb.EntryIdx } // stubbed Check returns true for the first numSafe calls, and false thereafter -func (s *stubChecker) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) bool { +func (s *stubChecker) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash common.Hash) bool { if s.checkCalls >= s.numSafe { return false } @@ -305,7 +304,7 @@ type nextLogResponse struct { logIdx uint32 - evtHash backendTypes.TruncatedHash + evtHash common.Hash err error @@ -356,22 +355,22 @@ func (s *stubIterator) NextIndex() entrydb.EntryIdx { return s.index + 1 } -func (s *stubIterator) SealedBlock() (hash backendTypes.TruncatedHash, num uint64, ok bool) { +func (s *stubIterator) SealedBlock() (hash common.Hash, num uint64, ok bool) { panic("not yet supported") } -func (s *stubIterator) InitMessage() (hash backendTypes.TruncatedHash, logIndex uint32, ok bool) { +func (s *stubIterator) InitMessage() (hash common.Hash, logIndex uint32, ok bool) { if s.index < 0 { - return backendTypes.TruncatedHash{}, 0, false + return common.Hash{}, 0, false } if s.index >= entrydb.EntryIdx(len(s.db.nextLogs)) { - return backendTypes.TruncatedHash{}, 0, false + return common.Hash{}, 0, false } e := s.db.nextLogs[s.index] return e.evtHash, e.logIdx, true } -func (s *stubIterator) ExecMessage() *backendTypes.ExecutingMessage { +func (s *stubIterator) ExecMessage() *types.ExecutingMessage { if s.index < 0 { return nil } @@ -392,13 +391,13 @@ type stubLogDB struct { sealBlockCalls int headBlockNum uint64 - executingMessages []*backendTypes.ExecutingMessage + executingMessages []*types.ExecutingMessage nextLogs []nextLogResponse containsResponse containsResponse } -func (s *stubLogDB) AddLog(logHash backendTypes.TruncatedHash, parentBlock eth.BlockID, logIdx uint32, execMsg *backendTypes.ExecutingMessage) error { +func (s *stubLogDB) AddLog(logHash common.Hash, parentBlock eth.BlockID, logIdx uint32, execMsg *types.ExecutingMessage) error { s.addLogCalls++ return nil } @@ -432,7 +431,7 @@ type containsResponse struct { // stubbed Contains records the arguments passed to it // it returns the response set in the struct, or an empty response -func (s *stubLogDB) Contains(blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) (nextIndex entrydb.EntryIdx, err error) { +func (s *stubLogDB) Contains(blockNum uint64, logIdx uint32, logHash common.Hash) (nextIndex entrydb.EntryIdx, err error) { return s.containsResponse.index, s.containsResponse.err } diff --git a/op-supervisor/supervisor/backend/db/entrydb/entry_db.go b/op-supervisor/supervisor/backend/db/entrydb/entry_db.go index 446051821ce3..a260d143ddb5 100644 --- a/op-supervisor/supervisor/backend/db/entrydb/entry_db.go +++ b/op-supervisor/supervisor/backend/db/entrydb/entry_db.go @@ -10,7 +10,7 @@ import ( ) const ( - EntrySize = 24 + EntrySize = 34 ) type EntryIdx int64 diff --git a/op-supervisor/supervisor/backend/db/logs/db.go b/op-supervisor/supervisor/backend/db/logs/db.go index 1a2d8c8adfea..61184318ece9 100644 --- a/op-supervisor/supervisor/backend/db/logs/db.go +++ b/op-supervisor/supervisor/backend/db/logs/db.go @@ -12,7 +12,7 @@ import ( "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" - "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" ) const ( @@ -103,11 +103,11 @@ func (db *DB) init(trimToLastSealed bool) error { // and is then followed up with canonical-hash entry of genesis. db.lastEntryContext = logContext{ nextEntryIndex: 0, - blockHash: types.TruncatedHash{}, + blockHash: common.Hash{}, blockNum: 0, timestamp: 0, logsSince: 0, - logHash: types.TruncatedHash{}, + logHash: common.Hash{}, execMsg: nil, out: nil, } @@ -199,7 +199,7 @@ func (db *DB) FindSealedBlock(block eth.BlockID) (nextEntry entrydb.EntryIdx, er if !ok { panic("expected block") } - if types.TruncateHash(block.Hash) != h { + if block.Hash != h { return 0, fmt.Errorf("queried %s but got %s at number %d: %w", block.Hash, h, block.Number, ErrConflict) } return iter.NextIndex(), nil @@ -220,9 +220,9 @@ func (db *DB) LatestSealedBlockNum() (n uint64, ok bool) { return db.lastEntryContext.blockNum, true } -// Get returns the truncated hash of the log at the specified blockNum (of the sealed block) +// Get returns the hash of the log at the specified blockNum (of the sealed block) // and logIdx (of the log after the block), or an error if the log is not found. -func (db *DB) Get(blockNum uint64, logIdx uint32) (types.TruncatedHash, error) { +func (db *DB) Get(blockNum uint64, logIdx uint32) (common.Hash, error) { db.rwLock.RLock() defer db.rwLock.RUnlock() hash, _, err := db.findLogInfo(blockNum, logIdx) @@ -234,7 +234,7 @@ func (db *DB) Get(blockNum uint64, logIdx uint32) (types.TruncatedHash, error) { // If the log is determined to conflict with the canonical chain, then ErrConflict is returned. // logIdx is the index of the log in the array of all logs in the block. // This can be used to check the validity of cross-chain interop events. -func (db *DB) Contains(blockNum uint64, logIdx uint32, logHash types.TruncatedHash) (entrydb.EntryIdx, error) { +func (db *DB) Contains(blockNum uint64, logIdx uint32, logHash common.Hash) (entrydb.EntryIdx, error) { db.rwLock.RLock() defer db.rwLock.RUnlock() db.log.Trace("Checking for log", "blockNum", blockNum, "logIdx", logIdx, "hash", logHash) @@ -251,29 +251,29 @@ func (db *DB) Contains(blockNum uint64, logIdx uint32, logHash types.TruncatedHa return iter.NextIndex(), nil } -func (db *DB) findLogInfo(blockNum uint64, logIdx uint32) (types.TruncatedHash, Iterator, error) { +func (db *DB) findLogInfo(blockNum uint64, logIdx uint32) (common.Hash, Iterator, error) { if blockNum == 0 { - return types.TruncatedHash{}, nil, ErrConflict // no logs in block 0 + return common.Hash{}, nil, ErrConflict // no logs in block 0 } // blockNum-1, such that we find a log that came after the parent num-1 was sealed. // logIdx, such that all entries before logIdx can be skipped, but logIdx itself is still readable. iter, err := db.newIteratorAt(blockNum-1, logIdx) if errors.Is(err, ErrFuture) { db.log.Trace("Could not find log yet", "blockNum", blockNum, "logIdx", logIdx) - return types.TruncatedHash{}, nil, err + return common.Hash{}, nil, err } else if err != nil { db.log.Error("Failed searching for log", "blockNum", blockNum, "logIdx", logIdx) - return types.TruncatedHash{}, nil, err + return common.Hash{}, nil, err } if err := iter.NextInitMsg(); err != nil { - return types.TruncatedHash{}, nil, fmt.Errorf("failed to read initiating message %d, on top of block %d: %w", logIdx, blockNum, err) + return common.Hash{}, nil, fmt.Errorf("failed to read initiating message %d, on top of block %d: %w", logIdx, blockNum, err) } if _, x, ok := iter.SealedBlock(); !ok { panic("expected block") } else if x < blockNum-1 { panic(fmt.Errorf("bug in newIteratorAt, expected to have found parent block %d but got %d", blockNum-1, x)) } else if x > blockNum-1 { - return types.TruncatedHash{}, nil, fmt.Errorf("log does not exist, found next block already: %w", ErrConflict) + return common.Hash{}, nil, fmt.Errorf("log does not exist, found next block already: %w", ErrConflict) } logHash, x, ok := iter.InitMessage() if !ok { @@ -459,7 +459,7 @@ func (db *DB) SealBlock(parentHash common.Hash, block eth.BlockID, timestamp uin return db.flush() } -func (db *DB) AddLog(logHash types.TruncatedHash, parentBlock eth.BlockID, logIdx uint32, execMsg *types.ExecutingMessage) error { +func (db *DB) AddLog(logHash common.Hash, parentBlock eth.BlockID, logIdx uint32, execMsg *types.ExecutingMessage) error { db.rwLock.Lock() defer db.rwLock.Unlock() diff --git a/op-supervisor/supervisor/backend/db/logs/db_test.go b/op-supervisor/supervisor/backend/db/logs/db_test.go index d2dbced9f393..c89433c7b4fe 100644 --- a/op-supervisor/supervisor/backend/db/logs/db_test.go +++ b/op-supervisor/supervisor/backend/db/logs/db_test.go @@ -17,13 +17,9 @@ import ( "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" - "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" ) -func createTruncatedHash(i int) types.TruncatedHash { - return types.TruncateHash(createHash(i)) -} - func createHash(i int) common.Hash { if i == -1 { // parent-hash of genesis is zero return common.Hash{} @@ -92,7 +88,7 @@ func TestAddLog(t *testing.T) { func(t *testing.T, db *DB, m *stubMetrics) {}, func(t *testing.T, db *DB, m *stubMetrics) { genesis := eth.BlockID{Hash: createHash(15), Number: 0} - err := db.AddLog(createTruncatedHash(1), genesis, 0, nil) + err := db.AddLog(createHash(1), genesis, 0, nil) require.ErrorIs(t, err, ErrLogOutOfOrder) }) }) @@ -102,7 +98,7 @@ func TestAddLog(t *testing.T) { func(t *testing.T, db *DB, m *stubMetrics) { genesis := eth.BlockID{Hash: createHash(15), Number: 15} require.NoError(t, db.SealBlock(common.Hash{}, genesis, 5000), "seal genesis") - err := db.AddLog(createTruncatedHash(1), genesis, 0, nil) + err := db.AddLog(createHash(1), genesis, 0, nil) require.NoError(t, err, "first log after genesis") require.NoError(t, db.SealBlock(genesis.Hash, eth.BlockID{Hash: createHash(16), Number: 16}, 5001)) }, @@ -121,11 +117,11 @@ func TestAddLog(t *testing.T) { } // Now apply 3 logs on top of that, contents for block 16 bl15 := eth.BlockID{Hash: createHash(15), Number: 15} - err := db.AddLog(createTruncatedHash(1), bl15, 0, nil) + err := db.AddLog(createHash(1), bl15, 0, nil) require.NoError(t, err) - err = db.AddLog(createTruncatedHash(2), bl15, 1, nil) + err = db.AddLog(createHash(2), bl15, 1, nil) require.NoError(t, err) - err = db.AddLog(createTruncatedHash(3), bl15, 2, nil) + err = db.AddLog(createHash(3), bl15, 2, nil) require.NoError(t, err) // Now seal block 16 bl16 := eth.BlockID{Hash: createHash(16), Number: 16} @@ -149,16 +145,16 @@ func TestAddLog(t *testing.T) { bl15 := eth.BlockID{Hash: createHash(15), Number: 15} err = db.SealBlock(createHash(14), bl15, 5001) require.NoError(t, err) - err = db.AddLog(createTruncatedHash(1), bl15, 0, nil) + err = db.AddLog(createHash(1), bl15, 0, nil) require.NoError(t, err) - err = db.AddLog(createTruncatedHash(2), bl15, 1, nil) + err = db.AddLog(createHash(2), bl15, 1, nil) require.NoError(t, err) bl16 := eth.BlockID{Hash: createHash(16), Number: 16} err = db.SealBlock(bl15.Hash, bl16, 5003) require.NoError(t, err) - err = db.AddLog(createTruncatedHash(3), bl16, 0, nil) + err = db.AddLog(createHash(3), bl16, 0, nil) require.NoError(t, err) - err = db.AddLog(createTruncatedHash(4), bl16, 1, nil) + err = db.AddLog(createHash(4), bl16, 1, nil) require.NoError(t, err) bl17 := eth.BlockID{Hash: createHash(17), Number: 17} err = db.SealBlock(bl16.Hash, bl17, 5003) @@ -199,7 +195,7 @@ func TestAddLog(t *testing.T) { }, func(t *testing.T, db *DB, m *stubMetrics) { onto := eth.BlockID{Hash: createHash(14), Number: 14} - err := db.AddLog(createTruncatedHash(1), onto, 0, nil) + err := db.AddLog(createHash(1), onto, 0, nil) require.ErrorIs(t, err, ErrLogOutOfOrder, "cannot build logs on 14 when 15 is already sealed") }) }) @@ -210,12 +206,12 @@ func TestAddLog(t *testing.T) { bl15 := eth.BlockID{Hash: createHash(15), Number: 15} err := db.lastEntryContext.forceBlock(bl15, 5000) require.NoError(t, err) - require.NoError(t, db.AddLog(createTruncatedHash(1), bl15, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(1), bl15, 1, nil)) + require.NoError(t, db.AddLog(createHash(1), bl15, 0, nil)) + require.NoError(t, db.AddLog(createHash(1), bl15, 1, nil)) }, func(t *testing.T, db *DB, m *stubMetrics) { bl15 := eth.BlockID{Hash: createHash(15), Number: 15} - err := db.AddLog(createTruncatedHash(1), bl15, 0, nil) + err := db.AddLog(createHash(1), bl15, 0, nil) require.ErrorIs(t, err, ErrLogOutOfOrder, "already at log index 2") }) }) @@ -226,11 +222,11 @@ func TestAddLog(t *testing.T) { bl15 := eth.BlockID{Hash: createHash(15), Number: 15} err := db.lastEntryContext.forceBlock(bl15, 5000) require.NoError(t, err) - require.NoError(t, db.AddLog(createTruncatedHash(1), bl15, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(1), bl15, 1, nil)) + require.NoError(t, db.AddLog(createHash(1), bl15, 0, nil)) + require.NoError(t, db.AddLog(createHash(1), bl15, 1, nil)) }, func(t *testing.T, db *DB, m *stubMetrics) { - err := db.AddLog(createTruncatedHash(1), eth.BlockID{Hash: createHash(16), Number: 16}, 0, nil) + err := db.AddLog(createHash(1), eth.BlockID{Hash: createHash(16), Number: 16}, 0, nil) require.ErrorIs(t, err, ErrLogOutOfOrder) }) }) @@ -241,12 +237,12 @@ func TestAddLog(t *testing.T) { bl15 := eth.BlockID{Hash: createHash(15), Number: 15} err := db.lastEntryContext.forceBlock(bl15, 5000) require.NoError(t, err) - require.NoError(t, db.AddLog(createTruncatedHash(1), bl15, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(1), bl15, 1, nil)) + require.NoError(t, db.AddLog(createHash(1), bl15, 0, nil)) + require.NoError(t, db.AddLog(createHash(1), bl15, 1, nil)) }, func(t *testing.T, db *DB, m *stubMetrics) { bl15 := eth.BlockID{Hash: createHash(15), Number: 15} - err := db.AddLog(createTruncatedHash(1), bl15, 1, nil) + err := db.AddLog(createHash(1), bl15, 1, nil) require.ErrorIs(t, err, ErrLogOutOfOrder, "already at log index 2") }) }) @@ -257,12 +253,12 @@ func TestAddLog(t *testing.T) { bl15 := eth.BlockID{Hash: createHash(15), Number: 15} err := db.lastEntryContext.forceBlock(bl15, 5000) require.NoError(t, err) - require.NoError(t, db.AddLog(createTruncatedHash(1), bl15, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(1), bl15, 1, nil)) + require.NoError(t, db.AddLog(createHash(1), bl15, 0, nil)) + require.NoError(t, db.AddLog(createHash(1), bl15, 1, nil)) }, func(t *testing.T, db *DB, m *stubMetrics) { bl15 := eth.BlockID{Hash: createHash(16), Number: 16} - err := db.AddLog(createTruncatedHash(1), bl15, 2, nil) + err := db.AddLog(createHash(1), bl15, 2, nil) require.ErrorIs(t, err, ErrLogOutOfOrder) }) }) @@ -273,11 +269,11 @@ func TestAddLog(t *testing.T) { bl15 := eth.BlockID{Hash: createHash(15), Number: 15} err := db.lastEntryContext.forceBlock(bl15, 5000) require.NoError(t, err) - require.NoError(t, db.AddLog(createTruncatedHash(1), bl15, 0, nil)) + require.NoError(t, db.AddLog(createHash(1), bl15, 0, nil)) }, func(t *testing.T, db *DB, m *stubMetrics) { bl15 := eth.BlockID{Hash: createHash(15), Number: 15} - err := db.AddLog(createTruncatedHash(1), bl15, 2, nil) + err := db.AddLog(createHash(1), bl15, 2, nil) require.ErrorIs(t, err, ErrLogOutOfOrder) }) }) @@ -290,7 +286,7 @@ func TestAddLog(t *testing.T) { }, func(t *testing.T, db *DB, m *stubMetrics) { bl15 := eth.BlockID{Hash: createHash(15), Number: 15} - err := db.AddLog(createTruncatedHash(1), bl15, 5, nil) + err := db.AddLog(createHash(1), bl15, 5, nil) require.ErrorIs(t, err, ErrLogOutOfOrder) }) }) @@ -301,17 +297,17 @@ func TestAddLog(t *testing.T) { bl15 := eth.BlockID{Hash: createHash(15), Number: 15} err := db.lastEntryContext.forceBlock(bl15, 5000) require.NoError(t, err) - err = db.AddLog(createTruncatedHash(1), bl15, 0, nil) + err = db.AddLog(createHash(1), bl15, 0, nil) require.NoError(t, err) }, func(t *testing.T, db *DB, m *stubMetrics) { bl15 := eth.BlockID{Hash: createHash(15), Number: 15} - err := db.AddLog(createTruncatedHash(1), bl15, 1, nil) + err := db.AddLog(createHash(1), bl15, 1, nil) require.NoError(t, err) bl16 := eth.BlockID{Hash: createHash(16), Number: 16} err = db.SealBlock(bl15.Hash, bl16, 5001) require.NoError(t, err) - err = db.AddLog(createTruncatedHash(1), bl16, 1, nil) + err = db.AddLog(createHash(1), bl16, 1, nil) require.ErrorIs(t, err, ErrLogOutOfOrder) }) }) @@ -340,7 +336,7 @@ func TestAddLog(t *testing.T) { require.Equal(t, expectedIndex, db.lastEntryContext.NextIndex()) { // create block 1 for i := 0; i < block1LogCount; i++ { - err := db.AddLog(createTruncatedHash(i), block0, uint32(i), nil) + err := db.AddLog(createHash(i), block0, uint32(i), nil) require.NoError(t, err) } err := db.SealBlock(block0.Hash, block1, 3001) // second seal-checkpoint @@ -352,7 +348,7 @@ func TestAddLog(t *testing.T) { { // create block 2 for i := 0; i < block2LogCount; i++ { // two of these imply a search checkpoint, the second and third search-checkpoint - err := db.AddLog(createTruncatedHash(i), block1, uint32(i), nil) + err := db.AddLog(createHash(i), block1, uint32(i), nil) require.NoError(t, err) } err := db.SealBlock(block1.Hash, block2, 3002) // third seal-checkpoint @@ -363,7 +359,7 @@ func TestAddLog(t *testing.T) { require.Equal(t, expectedIndex, db.lastEntryContext.NextIndex(), "added logs, two search checkpoints, and a seal checkpoint") { // create block 3 for i := 0; i < block3LogCount; i++ { - err := db.AddLog(createTruncatedHash(i), block2, uint32(i), nil) + err := db.AddLog(createHash(i), block2, uint32(i), nil) require.NoError(t, err) } err := db.SealBlock(block2.Hash, block3, 3003) @@ -381,7 +377,7 @@ func TestAddLog(t *testing.T) { { // create block 4 for i := 0; i < block4LogCount; i++ { // includes a fourth search checkpoint - err := db.AddLog(createTruncatedHash(i), block3, uint32(i), nil) + err := db.AddLog(createHash(i), block3, uint32(i), nil) require.NoError(t, err) } err := db.SealBlock(block3.Hash, block4, 3003) // fourth seal checkpoint @@ -422,14 +418,14 @@ func TestAddDependentLog(t *testing.T) { BlockNum: 42894, LogIdx: 42, Timestamp: 8742482, - Hash: types.TruncateHash(createHash(8844)), + Hash: createHash(8844), } t.Run("FirstEntry", func(t *testing.T) { runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { bl15 := eth.BlockID{Hash: createHash(15), Number: 15} require.NoError(t, db.lastEntryContext.forceBlock(bl15, 5000)) - err := db.AddLog(createTruncatedHash(1), bl15, 0, &execMsg) + err := db.AddLog(createHash(1), bl15, 0, &execMsg) require.NoError(t, err) }, func(t *testing.T, db *DB, m *stubMetrics) { @@ -443,13 +439,13 @@ func TestAddDependentLog(t *testing.T) { bl15 := eth.BlockID{Hash: createHash(15), Number: 15} require.NoError(t, db.lastEntryContext.forceBlock(bl15, 5000)) for i := uint32(0); m.entryCount < searchCheckpointFrequency-1; i++ { - require.NoError(t, db.AddLog(createTruncatedHash(9), bl15, i, nil)) + require.NoError(t, db.AddLog(createHash(9), bl15, i, nil)) } bl16 := eth.BlockID{Hash: createHash(16), Number: 16} require.NoError(t, db.SealBlock(bl15.Hash, bl16, 5001)) // added 3 entries: seal-checkpoint, then a search-checkpoint, then the canonical hash require.Equal(t, m.entryCount, int64(searchCheckpointFrequency+2)) - err := db.AddLog(createTruncatedHash(1), bl16, 0, &execMsg) + err := db.AddLog(createHash(1), bl16, 0, &execMsg) require.NoError(t, err) }, func(t *testing.T, db *DB, m *stubMetrics) { @@ -465,10 +461,10 @@ func TestAddDependentLog(t *testing.T) { require.NoError(t, db.lastEntryContext.forceBlock(bl15, 5000)) // we add 256 - 2 (start) - 2 (init msg, exec link) = 252 entries for i := uint32(0); i < 252; i++ { - require.NoError(t, db.AddLog(createTruncatedHash(9), bl15, i, nil)) + require.NoError(t, db.AddLog(createHash(9), bl15, i, nil)) } // add an executing message - err := db.AddLog(createTruncatedHash(1), bl15, 252, &execMsg) + err := db.AddLog(createHash(1), bl15, 252, &execMsg) require.NoError(t, err) // 0,1: start // 2..252+2: initiating logs without exec message @@ -495,10 +491,10 @@ func TestAddDependentLog(t *testing.T) { require.NoError(t, db.lastEntryContext.forceBlock(bl15, 5000)) // we add 256 - 2 (start) - 1 (init msg) = 253 entries for i := uint32(0); i < 253; i++ { - require.NoError(t, db.AddLog(createTruncatedHash(9), bl15, i, nil)) + require.NoError(t, db.AddLog(createHash(9), bl15, i, nil)) } // add an executing message - err := db.AddLog(createTruncatedHash(1), bl15, 253, &execMsg) + err := db.AddLog(createHash(1), bl15, 253, &execMsg) require.NoError(t, err) // 0,1: start // 2..253+2: initiating logs without exec message @@ -523,15 +519,15 @@ func TestContains(t *testing.T) { func(t *testing.T, db *DB, m *stubMetrics) { bl50 := eth.BlockID{Hash: createHash(50), Number: 50} require.NoError(t, db.lastEntryContext.forceBlock(bl50, 5000)) - require.NoError(t, db.AddLog(createTruncatedHash(1), bl50, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(3), bl50, 1, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), bl50, 2, nil)) + require.NoError(t, db.AddLog(createHash(1), bl50, 0, nil)) + require.NoError(t, db.AddLog(createHash(3), bl50, 1, nil)) + require.NoError(t, db.AddLog(createHash(2), bl50, 2, nil)) bl51 := eth.BlockID{Hash: createHash(51), Number: 51} require.NoError(t, db.SealBlock(bl50.Hash, bl51, 5001)) bl52 := eth.BlockID{Hash: createHash(52), Number: 52} require.NoError(t, db.SealBlock(bl51.Hash, bl52, 5001)) - require.NoError(t, db.AddLog(createTruncatedHash(1), bl52, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(3), bl52, 1, nil)) + require.NoError(t, db.AddLog(createHash(1), bl52, 0, nil)) + require.NoError(t, db.AddLog(createHash(3), bl52, 1, nil)) }, func(t *testing.T, db *DB, m *stubMetrics) { // Should find added logs @@ -560,35 +556,35 @@ func TestExecutes(t *testing.T) { BlockNum: 22, LogIdx: 99, Timestamp: 948294, - Hash: createTruncatedHash(332299), + Hash: createHash(332299), } execMsg2 := types.ExecutingMessage{ Chain: 44, BlockNum: 55, LogIdx: 66, Timestamp: 77777, - Hash: createTruncatedHash(445566), + Hash: createHash(445566), } execMsg3 := types.ExecutingMessage{ Chain: 77, BlockNum: 88, LogIdx: 89, Timestamp: 6578567, - Hash: createTruncatedHash(778889), + Hash: createHash(778889), } runDBTest(t, func(t *testing.T, db *DB, m *stubMetrics) { bl50 := eth.BlockID{Hash: createHash(50), Number: 50} require.NoError(t, db.lastEntryContext.forceBlock(bl50, 500)) - require.NoError(t, db.AddLog(createTruncatedHash(1), bl50, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(3), bl50, 1, &execMsg1)) - require.NoError(t, db.AddLog(createTruncatedHash(2), bl50, 2, nil)) + require.NoError(t, db.AddLog(createHash(1), bl50, 0, nil)) + require.NoError(t, db.AddLog(createHash(3), bl50, 1, &execMsg1)) + require.NoError(t, db.AddLog(createHash(2), bl50, 2, nil)) bl51 := eth.BlockID{Hash: createHash(51), Number: 51} require.NoError(t, db.SealBlock(bl50.Hash, bl51, 5001)) bl52 := eth.BlockID{Hash: createHash(52), Number: 52} require.NoError(t, db.SealBlock(bl51.Hash, bl52, 5001)) - require.NoError(t, db.AddLog(createTruncatedHash(1), bl52, 0, &execMsg2)) - require.NoError(t, db.AddLog(createTruncatedHash(3), bl52, 1, &execMsg3)) + require.NoError(t, db.AddLog(createHash(1), bl52, 0, &execMsg2)) + require.NoError(t, db.AddLog(createHash(3), bl52, 1, &execMsg3)) }, func(t *testing.T, db *DB, m *stubMetrics) { // Should find added logs @@ -627,7 +623,7 @@ func TestGetBlockInfo(t *testing.T) { func(t *testing.T, db *DB, m *stubMetrics) { bl11 := eth.BlockID{Hash: createHash(11), Number: 11} require.NoError(t, db.lastEntryContext.forceBlock(bl11, 500)) - err := db.AddLog(createTruncatedHash(1), bl11, 0, nil) + err := db.AddLog(createHash(1), bl11, 0, nil) require.NoError(t, err) }, func(t *testing.T, db *DB, m *stubMetrics) { @@ -657,7 +653,7 @@ func requireContains(t *testing.T, db *DB, blockNum uint64, logIdx uint32, logHa require.LessOrEqual(t, len(execMsg), 1, "cannot have multiple executing messages for a single log") m, ok := db.m.(*stubMetrics) require.True(t, ok, "Did not get the expected metrics type") - _, err := db.Contains(blockNum, logIdx, types.TruncateHash(logHash)) + _, err := db.Contains(blockNum, logIdx, logHash) require.NoErrorf(t, err, "Error searching for log %v in block %v", logIdx, blockNum) require.LessOrEqual(t, m.entriesReadForSearch, int64(searchCheckpointFrequency*2), "Should not need to read more than between two checkpoints") require.NotZero(t, m.entriesReadForSearch, "Must read at least some entries to find the log") @@ -672,7 +668,7 @@ func requireContains(t *testing.T, db *DB, blockNum uint64, logIdx uint32, logHa func requireConflicts(t *testing.T, db *DB, blockNum uint64, logIdx uint32, logHash common.Hash) { m, ok := db.m.(*stubMetrics) require.True(t, ok, "Did not get the expected metrics type") - _, err := db.Contains(blockNum, logIdx, types.TruncateHash(logHash)) + _, err := db.Contains(blockNum, logIdx, logHash) require.ErrorIs(t, err, ErrConflict, "canonical chain must not include this log") require.LessOrEqual(t, m.entriesReadForSearch, int64(searchCheckpointFrequency*2), "Should not need to read more than between two checkpoints") } @@ -680,7 +676,7 @@ func requireConflicts(t *testing.T, db *DB, blockNum uint64, logIdx uint32, logH func requireFuture(t *testing.T, db *DB, blockNum uint64, logIdx uint32, logHash common.Hash) { m, ok := db.m.(*stubMetrics) require.True(t, ok, "Did not get the expected metrics type") - _, err := db.Contains(blockNum, logIdx, types.TruncateHash(logHash)) + _, err := db.Contains(blockNum, logIdx, logHash) require.ErrorIs(t, err, ErrFuture, "canonical chain does not yet include this log") require.LessOrEqual(t, m.entriesReadForSearch, int64(searchCheckpointFrequency*2), "Should not need to read more than between two checkpoints") } @@ -718,17 +714,17 @@ func TestRecoverOnCreate(t *testing.T) { store := storeWithEvents( // seal 0, 1, 2, 3 newSearchCheckpoint(0, 0, 100).encode(), - newCanonicalHash(createTruncatedHash(300)).encode(), + newCanonicalHash(createHash(300)).encode(), newSearchCheckpoint(1, 0, 101).encode(), - newCanonicalHash(createTruncatedHash(301)).encode(), + newCanonicalHash(createHash(301)).encode(), newSearchCheckpoint(2, 0, 102).encode(), - newCanonicalHash(createTruncatedHash(302)).encode(), + newCanonicalHash(createHash(302)).encode(), newSearchCheckpoint(3, 0, 103).encode(), - newCanonicalHash(createTruncatedHash(303)).encode(), + newCanonicalHash(createHash(303)).encode(), // open and seal 4 - newInitiatingEvent(createTruncatedHash(1), false).encode(), + newInitiatingEvent(createHash(1), false).encode(), newSearchCheckpoint(4, 0, 104).encode(), - newCanonicalHash(createTruncatedHash(304)).encode(), + newCanonicalHash(createHash(304)).encode(), ) db, m, err := createDb(t, store) require.NoError(t, err) @@ -742,22 +738,22 @@ func TestRecoverOnCreate(t *testing.T) { BlockNum: 10, LogIdx: 4, Timestamp: 1288, - Hash: createTruncatedHash(4), + Hash: createHash(4), } linkEvt, err := newExecutingLink(execMsg) require.NoError(t, err) store := storeWithEvents( newSearchCheckpoint(0, 0, 100).encode(), - newCanonicalHash(createTruncatedHash(300)).encode(), + newCanonicalHash(createHash(300)).encode(), newSearchCheckpoint(1, 0, 101).encode(), - newCanonicalHash(createTruncatedHash(301)).encode(), + newCanonicalHash(createHash(301)).encode(), newSearchCheckpoint(2, 0, 102).encode(), - newCanonicalHash(createTruncatedHash(302)).encode(), - newInitiatingEvent(createTruncatedHash(1111), true).encode(), + newCanonicalHash(createHash(302)).encode(), + newInitiatingEvent(createHash(1111), true).encode(), linkEvt.encode(), newExecutingCheck(execMsg.Hash).encode(), newSearchCheckpoint(3, 0, 103).encode(), - newCanonicalHash(createTruncatedHash(303)).encode(), + newCanonicalHash(createHash(303)).encode(), ) db, m, err := createDb(t, store) require.NoError(t, err) @@ -778,7 +774,7 @@ func TestRecoverOnCreate(t *testing.T) { // A completed seal is fine to have as last entry. store := storeWithEvents( newSearchCheckpoint(0, 0, 100).encode(), - newCanonicalHash(createTruncatedHash(344)).encode(), + newCanonicalHash(createHash(344)).encode(), ) _, m, err := createDb(t, store) require.NoError(t, err) @@ -790,10 +786,10 @@ func TestRecoverOnCreate(t *testing.T) { // without said executing message, is dropped. store := storeWithEvents( newSearchCheckpoint(0, 0, 100).encode(), - newCanonicalHash(createTruncatedHash(344)).encode(), + newCanonicalHash(createHash(344)).encode(), // both pruned because we go back to a seal - newInitiatingEvent(createTruncatedHash(0), false).encode(), - newInitiatingEvent(createTruncatedHash(1), true).encode(), + newInitiatingEvent(createHash(0), false).encode(), + newInitiatingEvent(createHash(1), true).encode(), ) _, m, err := createDb(t, store) require.NoError(t, err) @@ -805,11 +801,11 @@ func TestRecoverOnCreate(t *testing.T) { // without said executing message, is dropped. store := storeWithEvents( newSearchCheckpoint(0, 0, 100).encode(), - newCanonicalHash(createTruncatedHash(300)).encode(), + newCanonicalHash(createHash(300)).encode(), // pruned because we go back to a seal - newInitiatingEvent(createTruncatedHash(0), false).encode(), + newInitiatingEvent(createHash(0), false).encode(), newSearchCheckpoint(1, 0, 100).encode(), - newCanonicalHash(createTruncatedHash(301)).encode(), + newCanonicalHash(createHash(301)).encode(), ) _, m, err := createDb(t, store) require.NoError(t, err) @@ -822,14 +818,14 @@ func TestRecoverOnCreate(t *testing.T) { BlockNum: 10, LogIdx: 4, Timestamp: 1288, - Hash: createTruncatedHash(4), + Hash: createHash(4), } linkEvt, err := newExecutingLink(execMsg) require.NoError(t, err) store := storeWithEvents( newSearchCheckpoint(3, 0, 100).encode(), - newCanonicalHash(createTruncatedHash(344)).encode(), - newInitiatingEvent(createTruncatedHash(1), true).encode(), + newCanonicalHash(createHash(344)).encode(), + newInitiatingEvent(createHash(1), true).encode(), linkEvt.encode(), ) _, m, err := createDb(t, store) @@ -853,14 +849,14 @@ func TestRewind(t *testing.T) { func(t *testing.T, db *DB, m *stubMetrics) { bl50 := eth.BlockID{Hash: createHash(50), Number: 50} require.NoError(t, db.SealBlock(createHash(49), bl50, 500)) - require.NoError(t, db.AddLog(createTruncatedHash(1), bl50, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), bl50, 1, nil)) + require.NoError(t, db.AddLog(createHash(1), bl50, 0, nil)) + require.NoError(t, db.AddLog(createHash(2), bl50, 1, nil)) bl51 := eth.BlockID{Hash: createHash(51), Number: 51} require.NoError(t, db.SealBlock(bl50.Hash, bl51, 502)) - require.NoError(t, db.AddLog(createTruncatedHash(3), bl51, 0, nil)) + require.NoError(t, db.AddLog(createHash(3), bl51, 0, nil)) bl52 := eth.BlockID{Hash: createHash(52), Number: 52} require.NoError(t, db.SealBlock(bl51.Hash, bl52, 504)) - require.NoError(t, db.AddLog(createTruncatedHash(4), bl52, 0, nil)) + require.NoError(t, db.AddLog(createHash(4), bl52, 0, nil)) // cannot rewind to a block that is not sealed yet require.ErrorIs(t, db.Rewind(53), ErrFuture) }, @@ -878,8 +874,8 @@ func TestRewind(t *testing.T) { func(t *testing.T, db *DB, m *stubMetrics) { bl50 := eth.BlockID{Hash: createHash(50), Number: 50} require.NoError(t, db.SealBlock(createHash(49), bl50, 500)) - require.NoError(t, db.AddLog(createTruncatedHash(1), bl50, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), bl50, 1, nil)) + require.NoError(t, db.AddLog(createHash(1), bl50, 0, nil)) + require.NoError(t, db.AddLog(createHash(2), bl50, 1, nil)) // cannot go back to an unknown block require.ErrorIs(t, db.Rewind(25), ErrSkipped) }, @@ -894,12 +890,12 @@ func TestRewind(t *testing.T) { func(t *testing.T, db *DB, m *stubMetrics) { bl50 := eth.BlockID{Hash: createHash(50), Number: 50} require.NoError(t, db.SealBlock(createHash(49), bl50, 500)) - require.NoError(t, db.AddLog(createTruncatedHash(1), bl50, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), bl50, 1, nil)) + require.NoError(t, db.AddLog(createHash(1), bl50, 0, nil)) + require.NoError(t, db.AddLog(createHash(2), bl50, 1, nil)) bl51 := eth.BlockID{Hash: createHash(51), Number: 51} require.NoError(t, db.SealBlock(bl50.Hash, bl51, 502)) - require.NoError(t, db.AddLog(createTruncatedHash(1), bl51, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), bl51, 1, nil)) + require.NoError(t, db.AddLog(createHash(1), bl51, 0, nil)) + require.NoError(t, db.AddLog(createHash(2), bl51, 1, nil)) bl52 := eth.BlockID{Hash: createHash(52), Number: 52} require.NoError(t, db.SealBlock(bl51.Hash, bl52, 504)) require.NoError(t, db.Rewind(51)) @@ -918,7 +914,7 @@ func TestRewind(t *testing.T) { bl50 := eth.BlockID{Hash: createHash(50), Number: 50} require.NoError(t, db.SealBlock(createHash(49), bl50, 500)) for i := uint32(0); m.entryCount < searchCheckpointFrequency; i++ { - require.NoError(t, db.AddLog(createTruncatedHash(1), bl50, i, nil)) + require.NoError(t, db.AddLog(createHash(1), bl50, i, nil)) } // The checkpoint is added automatically, // it will be there as soon as it reaches 255 with log events. @@ -926,9 +922,9 @@ func TestRewind(t *testing.T) { require.EqualValues(t, searchCheckpointFrequency+2, m.entryCount) bl51 := eth.BlockID{Hash: createHash(51), Number: 51} require.NoError(t, db.SealBlock(bl50.Hash, bl51, 502)) - require.NoError(t, db.AddLog(createTruncatedHash(1), bl51, 0, nil)) + require.NoError(t, db.AddLog(createHash(1), bl51, 0, nil)) require.EqualValues(t, searchCheckpointFrequency+2+3, m.entryCount, "Should have inserted new checkpoint and extra log") - require.NoError(t, db.AddLog(createTruncatedHash(2), bl51, 1, nil)) + require.NoError(t, db.AddLog(createHash(2), bl51, 1, nil)) bl52 := eth.BlockID{Hash: createHash(52), Number: 52} require.NoError(t, db.SealBlock(bl51.Hash, bl52, 504)) require.NoError(t, db.Rewind(51)) @@ -950,8 +946,8 @@ func TestRewind(t *testing.T) { bl := eth.BlockID{Hash: createHash(int(i)), Number: uint64(i)} require.NoError(t, db.SealBlock(createHash(int(i)-1), bl, 500+uint64(i))) if i%2 == 0 { - require.NoError(t, db.AddLog(createTruncatedHash(1), bl, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), bl, 1, nil)) + require.NoError(t, db.AddLog(createHash(1), bl, 0, nil)) + require.NoError(t, db.AddLog(createHash(2), bl, 1, nil)) } } require.NoError(t, db.Rewind(15)) @@ -972,8 +968,8 @@ func TestRewind(t *testing.T) { bl := eth.BlockID{Hash: createHash(int(i)), Number: uint64(i)} require.NoError(t, db.SealBlock(createHash(int(i)-1), bl, 500+uint64(i))) if i%2 == 1 { - require.NoError(t, db.AddLog(createTruncatedHash(1), bl, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), bl, 1, nil)) + require.NoError(t, db.AddLog(createHash(1), bl, 0, nil)) + require.NoError(t, db.AddLog(createHash(2), bl, 1, nil)) } } // We ended at 30, and sealed it, nothing left to prune @@ -996,8 +992,8 @@ func TestRewind(t *testing.T) { bl := eth.BlockID{Hash: createHash(int(i)), Number: uint64(i)} require.NoError(t, db.SealBlock(createHash(int(i)-1), bl, 500+uint64(i))) if i%2 == 0 { - require.NoError(t, db.AddLog(createTruncatedHash(1), bl, 0, nil)) - require.NoError(t, db.AddLog(createTruncatedHash(2), bl, 1, nil)) + require.NoError(t, db.AddLog(createHash(1), bl, 0, nil)) + require.NoError(t, db.AddLog(createHash(2), bl, 1, nil)) } } require.NoError(t, db.Rewind(16)) @@ -1005,16 +1001,16 @@ func TestRewind(t *testing.T) { func(t *testing.T, db *DB, m *stubMetrics) { bl29 := eth.BlockID{Hash: createHash(29), Number: 29} // 29 was deleted - err := db.AddLog(createTruncatedHash(2), bl29, 1, nil) + err := db.AddLog(createHash(2), bl29, 1, nil) require.ErrorIs(t, err, ErrLogOutOfOrder, "Cannot add log on removed block") // 15 is older, we have up to 16 bl15 := eth.BlockID{Hash: createHash(15), Number: 15} // try to add a third log to 15 - err = db.AddLog(createTruncatedHash(10), bl15, 2, nil) + err = db.AddLog(createHash(10), bl15, 2, nil) require.ErrorIs(t, err, ErrLogOutOfOrder) bl16 := eth.BlockID{Hash: createHash(16), Number: 16} // try to add a log to 17, on top of 16 - err = db.AddLog(createTruncatedHash(42), bl16, 0, nil) + err = db.AddLog(createHash(42), bl16, 0, nil) require.NoError(t, err) requireContains(t, db, 17, 0, createHash(42)) }) diff --git a/op-supervisor/supervisor/backend/db/logs/entries.go b/op-supervisor/supervisor/backend/db/logs/entries.go index 5dbc1e3b4816..431adc99f465 100644 --- a/op-supervisor/supervisor/backend/db/logs/entries.go +++ b/op-supervisor/supervisor/backend/db/logs/entries.go @@ -4,8 +4,10 @@ import ( "encoding/binary" "fmt" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" - "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" ) // searchCheckpoint is both a checkpoint for searching, as well as a checkpoint for sealing blocks. @@ -48,10 +50,10 @@ func (s searchCheckpoint) encode() entrydb.Entry { } type canonicalHash struct { - hash types.TruncatedHash + hash common.Hash } -func newCanonicalHash(hash types.TruncatedHash) canonicalHash { +func newCanonicalHash(hash common.Hash) canonicalHash { return canonicalHash{hash: hash} } @@ -59,21 +61,19 @@ func newCanonicalHashFromEntry(data entrydb.Entry) (canonicalHash, error) { if data.Type() != entrydb.TypeCanonicalHash { return canonicalHash{}, fmt.Errorf("%w: attempting to decode canonical hash but was type %s", ErrDataCorruption, data.Type()) } - var truncated types.TruncatedHash - copy(truncated[:], data[1:21]) - return newCanonicalHash(truncated), nil + return newCanonicalHash(common.Hash(data[1:33])), nil } func (c canonicalHash) encode() entrydb.Entry { var entry entrydb.Entry entry[0] = uint8(entrydb.TypeCanonicalHash) - copy(entry[1:21], c.hash[:]) + copy(entry[1:33], c.hash[:]) return entry } type initiatingEvent struct { hasExecMsg bool - logHash types.TruncatedHash + logHash common.Hash } func newInitiatingEventFromEntry(data entrydb.Entry) (initiatingEvent, error) { @@ -83,11 +83,11 @@ func newInitiatingEventFromEntry(data entrydb.Entry) (initiatingEvent, error) { flags := data[1] return initiatingEvent{ hasExecMsg: flags&eventFlagHasExecutingMessage != 0, - logHash: types.TruncatedHash(data[2:22]), + logHash: common.Hash(data[2:34]), }, nil } -func newInitiatingEvent(logHash types.TruncatedHash, hasExecMsg bool) initiatingEvent { +func newInitiatingEvent(logHash common.Hash, hasExecMsg bool) initiatingEvent { return initiatingEvent{ hasExecMsg: hasExecMsg, logHash: logHash, @@ -104,7 +104,7 @@ func (i initiatingEvent) encode() entrydb.Entry { flags = flags | eventFlagHasExecutingMessage } data[1] = flags - copy(data[2:22], i.logHash[:]) + copy(data[2:34], i.logHash[:]) return data } @@ -157,10 +157,10 @@ func (e executingLink) encode() entrydb.Entry { } type executingCheck struct { - hash types.TruncatedHash + hash common.Hash } -func newExecutingCheck(hash types.TruncatedHash) executingCheck { +func newExecutingCheck(hash common.Hash) executingCheck { return executingCheck{hash: hash} } @@ -168,24 +168,22 @@ func newExecutingCheckFromEntry(data entrydb.Entry) (executingCheck, error) { if data.Type() != entrydb.TypeExecutingCheck { return executingCheck{}, fmt.Errorf("%w: attempting to decode executing check but was type %s", ErrDataCorruption, data.Type()) } - var hash types.TruncatedHash - copy(hash[:], data[1:21]) - return newExecutingCheck(hash), nil + return newExecutingCheck(common.Hash(data[1:33])), nil } // encode creates an executing check entry -// type 4: "executing check" <type><event-hash: 20 bytes> = 21 bytes +// type 4: "executing check" <type><event-hash: 32 bytes> = 33 bytes func (e executingCheck) encode() entrydb.Entry { var entry entrydb.Entry entry[0] = uint8(entrydb.TypeExecutingCheck) - copy(entry[1:21], e.hash[:]) + copy(entry[1:33], e.hash[:]) return entry } type paddingEntry struct{} // encoding of the padding entry -// type 5: "padding" <type><padding: 23 bytes> = 24 bytes +// type 5: "padding" <type><padding: 33 bytes> = 34 bytes func (e paddingEntry) encode() entrydb.Entry { var entry entrydb.Entry entry[0] = uint8(entrydb.TypePadding) diff --git a/op-supervisor/supervisor/backend/db/logs/iterator.go b/op-supervisor/supervisor/backend/db/logs/iterator.go index 29b47245e71c..4b3bd1b65908 100644 --- a/op-supervisor/supervisor/backend/db/logs/iterator.go +++ b/op-supervisor/supervisor/backend/db/logs/iterator.go @@ -5,14 +5,16 @@ import ( "fmt" "io" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" - "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" ) type IteratorState interface { NextIndex() entrydb.EntryIdx - SealedBlock() (hash types.TruncatedHash, num uint64, ok bool) - InitMessage() (hash types.TruncatedHash, logIndex uint32, ok bool) + SealedBlock() (hash common.Hash, num uint64, ok bool) + InitMessage() (hash common.Hash, logIndex uint32, ok bool) ExecMessage() *types.ExecutingMessage } @@ -127,12 +129,12 @@ func (i *iterator) NextIndex() entrydb.EntryIdx { // SealedBlock returns the sealed block that we are appending logs after, if any is available. // I.e. the block is the parent block of the block containing the logs that are currently appending to it. -func (i *iterator) SealedBlock() (hash types.TruncatedHash, num uint64, ok bool) { +func (i *iterator) SealedBlock() (hash common.Hash, num uint64, ok bool) { return i.current.SealedBlock() } // InitMessage returns the current initiating message, if any is available. -func (i *iterator) InitMessage() (hash types.TruncatedHash, logIndex uint32, ok bool) { +func (i *iterator) InitMessage() (hash common.Hash, logIndex uint32, ok bool) { return i.current.InitMessage() } diff --git a/op-supervisor/supervisor/backend/db/logs/state.go b/op-supervisor/supervisor/backend/db/logs/state.go index 083e07f97083..bb00762acc2e 100644 --- a/op-supervisor/supervisor/backend/db/logs/state.go +++ b/op-supervisor/supervisor/backend/db/logs/state.go @@ -9,7 +9,7 @@ import ( "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" - "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" ) // logContext is a buffer on top of the DB, @@ -32,14 +32,14 @@ import ( // // Types (<type> = 1 byte): // type 0: "checkpoint" <type><uint64 block number: 8 bytes><uint32 logsSince count: 4 bytes><uint64 timestamp: 8 bytes> = 21 bytes -// type 1: "canonical hash" <type><parent blockhash truncated: 20 bytes> = 21 bytes -// type 2: "initiating event" <type><event flags: 1 byte><event-hash: 20 bytes> = 22 bytes +// type 1: "canonical hash" <type><parent blockhash: 32 bytes> = 33 bytes +// type 2: "initiating event" <type><event flags: 1 byte><event-hash: 32 bytes> = 34 bytes // type 3: "executing link" <type><chain: 4 bytes><blocknum: 8 bytes><event index: 3 bytes><uint64 timestamp: 8 bytes> = 24 bytes -// type 4: "executing check" <type><event-hash: 20 bytes> = 21 bytes -// type 5: "padding" <type><padding: 23 bytes> = 24 bytes +// type 4: "executing check" <type><event-hash: 32 bytes> = 33 bytes +// type 5: "padding" <type><padding: 33 bytes> = 34 bytes // other types: future compat. E.g. for linking to L1, registering block-headers as a kind of initiating-event, tracking safe-head progression, etc. // -// Right-pad each entry that is not 24 bytes. +// Right-pad each entry that is not 34 bytes. // // We insert a checkpoint for every search interval and block sealing event, // and these may overlap as the same thing. @@ -55,7 +55,7 @@ type logContext struct { // blockHash of the last sealed block. // A block is not considered sealed until we know its block hash. // While we process logs we keep the parent-block of said logs around as sealed block. - blockHash types.TruncatedHash + blockHash common.Hash // blockNum of the last sealed block blockNum uint64 // timestamp of the last sealed block @@ -65,7 +65,7 @@ type logContext struct { logsSince uint32 // payload-hash of the log-event that was last processed. (may not be fully processed, see doneLog) - logHash types.TruncatedHash + logHash common.Hash // executing message that might exist for the current log event. // Might be incomplete; if !logDone while we already processed the initiating event, @@ -91,9 +91,9 @@ func (l *logContext) NextIndex() entrydb.EntryIdx { } // SealedBlock returns the block that we are building on top of, and if it is sealed. -func (l *logContext) SealedBlock() (hash types.TruncatedHash, num uint64, ok bool) { +func (l *logContext) SealedBlock() (hash common.Hash, num uint64, ok bool) { if !l.hasCompleteBlock() { - return types.TruncatedHash{}, 0, false + return common.Hash{}, 0, false } return l.blockHash, l.blockNum, true } @@ -111,9 +111,9 @@ func (l *logContext) hasReadableLog() bool { } // InitMessage returns the current initiating message, if any is available. -func (l *logContext) InitMessage() (hash types.TruncatedHash, logIndex uint32, ok bool) { +func (l *logContext) InitMessage() (hash common.Hash, logIndex uint32, ok bool) { if !l.hasReadableLog() { - return types.TruncatedHash{}, 0, false + return common.Hash{}, 0, false } return l.logHash, l.logsSince - 1, true } @@ -150,13 +150,13 @@ func (l *logContext) processEntry(entry entrydb.Entry) error { return err } l.blockNum = current.blockNum - l.blockHash = types.TruncatedHash{} + l.blockHash = common.Hash{} l.logsSince = current.logsSince // TODO this is bumping the logsSince? l.timestamp = current.timestamp l.need.Add(entrydb.FlagCanonicalHash) // Log data after the block we are sealing remains to be seen if l.logsSince == 0 { - l.logHash = types.TruncatedHash{} + l.logHash = common.Hash{} l.execMsg = nil } case entrydb.TypeCanonicalHash: @@ -201,7 +201,7 @@ func (l *logContext) processEntry(entry entrydb.Entry) error { BlockNum: link.blockNum, LogIdx: link.logIdx, Timestamp: link.timestamp, - Hash: types.TruncatedHash{}, // not known yet + Hash: common.Hash{}, // not known yet } l.need.Remove(entrydb.FlagExecutingLink) l.need.Add(entrydb.FlagExecutingCheck) @@ -331,12 +331,12 @@ func (l *logContext) forceBlock(upd eth.BlockID, timestamp uint64) error { if l.nextEntryIndex != 0 { return errors.New("can only bootstrap on top of an empty state") } - l.blockHash = types.TruncateHash(upd.Hash) + l.blockHash = upd.Hash l.blockNum = upd.Number l.timestamp = timestamp l.logsSince = 0 l.execMsg = nil - l.logHash = types.TruncatedHash{} + l.logHash = common.Hash{} l.need = 0 l.out = nil return l.inferFull() // apply to the state as much as possible @@ -350,29 +350,29 @@ func (l *logContext) SealBlock(parent common.Hash, upd eth.BlockID, timestamp ui if err := l.inferFull(); err != nil { // ensure we can start applying return err } - if l.blockHash != types.TruncateHash(parent) { + if l.blockHash != parent { return fmt.Errorf("%w: cannot apply block %s (parent %s) on top of %s", ErrConflict, upd, parent, l.blockHash) } - if l.blockHash != (types.TruncatedHash{}) && l.blockNum+1 != upd.Number { + if l.blockHash != (common.Hash{}) && l.blockNum+1 != upd.Number { return fmt.Errorf("%w: cannot apply block %d on top of %d", ErrConflict, upd.Number, l.blockNum) } if l.timestamp > timestamp { return fmt.Errorf("%w: block timestamp %d must be equal or larger than current timestamp %d", ErrConflict, timestamp, l.timestamp) } } - l.blockHash = types.TruncateHash(upd.Hash) + l.blockHash = upd.Hash l.blockNum = upd.Number l.timestamp = timestamp l.logsSince = 0 l.execMsg = nil - l.logHash = types.TruncatedHash{} + l.logHash = common.Hash{} l.need.Add(entrydb.FlagSearchCheckpoint) return l.inferFull() // apply to the state as much as possible } // ApplyLog applies a log on top of the current state. // The parent-block that the log comes after must be applied with ApplyBlock first. -func (l *logContext) ApplyLog(parentBlock eth.BlockID, logIdx uint32, logHash types.TruncatedHash, execMsg *types.ExecutingMessage) error { +func (l *logContext) ApplyLog(parentBlock eth.BlockID, logIdx uint32, logHash common.Hash, execMsg *types.ExecutingMessage) error { if parentBlock == (eth.BlockID{}) { return fmt.Errorf("genesis does not have logs: %w", ErrLogOutOfOrder) } @@ -387,7 +387,7 @@ func (l *logContext) ApplyLog(parentBlock eth.BlockID, logIdx uint32, logHash ty } } // check parent block - if l.blockHash != types.TruncateHash(parentBlock.Hash) { + if l.blockHash != parentBlock.Hash { return fmt.Errorf("%w: log builds on top of block %s, but have block %s", ErrLogOutOfOrder, parentBlock, l.blockHash) } if l.blockNum != parentBlock.Number { diff --git a/op-supervisor/supervisor/backend/db/safety_checkers.go b/op-supervisor/supervisor/backend/db/safety_checkers.go index 3ed297a60c3e..916f26f6dead 100644 --- a/op-supervisor/supervisor/backend/db/safety_checkers.go +++ b/op-supervisor/supervisor/backend/db/safety_checkers.go @@ -3,10 +3,11 @@ package db import ( "errors" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs" - backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" ) @@ -21,7 +22,7 @@ const ( type SafetyChecker interface { LocalHeadForChain(chainID types.ChainID) entrydb.EntryIdx CrossHeadForChain(chainID types.ChainID) entrydb.EntryIdx - Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) bool + Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash common.Hash) bool Update(chain types.ChainID, index entrydb.EntryIdx) heads.OperationFn Name() string SafetyLevel() types.SafetyLevel @@ -129,7 +130,7 @@ func check( chain types.ChainID, blockNum uint64, logIdx uint32, - logHash backendTypes.TruncatedHash) bool { + logHash common.Hash) bool { // for the Check to be valid, the log must: // exist at the blockNum and logIdx @@ -150,13 +151,13 @@ func check( // Check checks if the log entry is safe, provided a local head for the chain // it passes on the local head this checker is concerned with, along with its view of the database -func (c *unsafeChecker) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) bool { +func (c *unsafeChecker) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash common.Hash) bool { return check(c.chainsDB, c.LocalHeadForChain(chain), chain, blockNum, logIdx, logHash) } -func (c *safeChecker) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) bool { +func (c *safeChecker) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash common.Hash) bool { return check(c.chainsDB, c.LocalHeadForChain(chain), chain, blockNum, logIdx, logHash) } -func (c *finalizedChecker) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) bool { +func (c *finalizedChecker) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash common.Hash) bool { return check(c.chainsDB, c.LocalHeadForChain(chain), chain, blockNum, logIdx, logHash) } diff --git a/op-supervisor/supervisor/backend/db/safety_checkers_test.go b/op-supervisor/supervisor/backend/db/safety_checkers_test.go index 667cd8d46607..c8fb4e34a757 100644 --- a/op-supervisor/supervisor/backend/db/safety_checkers_test.go +++ b/op-supervisor/supervisor/backend/db/safety_checkers_test.go @@ -6,13 +6,13 @@ import ( "github.com/stretchr/testify/require" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs" - backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" ) @@ -105,7 +105,7 @@ func TestCheck(t *testing.T) { chainID types.ChainID blockNum uint64 logIdx uint32 - loghash backendTypes.TruncatedHash + loghash common.Hash containsResponse containsResponse expected bool }{ @@ -117,7 +117,7 @@ func TestCheck(t *testing.T) { types.ChainIDFromUInt64(1), 1, 1, - backendTypes.TruncatedHash{1, 2, 3}, + common.Hash{1, 2, 3}, containsResponse{entrydb.EntryIdx(6), nil}, true, }, @@ -128,7 +128,7 @@ func TestCheck(t *testing.T) { types.ChainIDFromUInt64(1), 1, 1, - backendTypes.TruncatedHash{1, 2, 3}, + common.Hash{1, 2, 3}, containsResponse{entrydb.EntryIdx(3), nil}, true, }, @@ -139,7 +139,7 @@ func TestCheck(t *testing.T) { types.ChainIDFromUInt64(1), 1, 1, - backendTypes.TruncatedHash{1, 2, 3}, + common.Hash{1, 2, 3}, containsResponse{entrydb.EntryIdx(1), nil}, true, }, @@ -150,7 +150,7 @@ func TestCheck(t *testing.T) { types.ChainIDFromUInt64(1), 1, 1, - backendTypes.TruncatedHash{1, 2, 3}, + common.Hash{1, 2, 3}, containsResponse{entrydb.EntryIdx(1), logs.ErrConflict}, false, }, @@ -161,7 +161,7 @@ func TestCheck(t *testing.T) { types.ChainIDFromUInt64(1), 1, 1, - backendTypes.TruncatedHash{1, 2, 3}, + common.Hash{1, 2, 3}, containsResponse{entrydb.EntryIdx(100), nil}, false, }, @@ -172,7 +172,7 @@ func TestCheck(t *testing.T) { types.ChainIDFromUInt64(1), 1, 1, - backendTypes.TruncatedHash{1, 2, 3}, + common.Hash{1, 2, 3}, containsResponse{entrydb.EntryIdx(5), nil}, false, }, @@ -183,7 +183,7 @@ func TestCheck(t *testing.T) { types.ChainIDFromUInt64(1), 1, 1, - backendTypes.TruncatedHash{1, 2, 3}, + common.Hash{1, 2, 3}, containsResponse{entrydb.EntryIdx(3), nil}, false, }, @@ -194,7 +194,7 @@ func TestCheck(t *testing.T) { types.ChainIDFromUInt64(1), 1, 1, - backendTypes.TruncatedHash{1, 2, 3}, + common.Hash{1, 2, 3}, containsResponse{entrydb.EntryIdx(0), errors.New("error")}, false, }, diff --git a/op-supervisor/supervisor/backend/source/contracts/l2inbox.go b/op-supervisor/supervisor/backend/source/contracts/l2inbox.go index b490b612e6c6..741c6ae3d865 100644 --- a/op-supervisor/supervisor/backend/source/contracts/l2inbox.go +++ b/op-supervisor/supervisor/backend/source/contracts/l2inbox.go @@ -10,7 +10,6 @@ import ( "github.com/ethereum-optimism/optimism/op-service/predeploys" "github.com/ethereum-optimism/optimism/op-service/solabi" "github.com/ethereum-optimism/optimism/op-service/sources/batching" - backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" "github.com/ethereum-optimism/optimism/packages/contracts-bedrock/snapshots" "github.com/ethereum/go-ethereum/common" @@ -48,20 +47,20 @@ func NewCrossL2Inbox() *CrossL2Inbox { } } -func (i *CrossL2Inbox) DecodeExecutingMessageLog(l *ethTypes.Log) (backendTypes.ExecutingMessage, error) { +func (i *CrossL2Inbox) DecodeExecutingMessageLog(l *ethTypes.Log) (types.ExecutingMessage, error) { if l.Address != i.contract.Addr() { - return backendTypes.ExecutingMessage{}, fmt.Errorf("%w: log not from CrossL2Inbox", ErrEventNotFound) + return types.ExecutingMessage{}, fmt.Errorf("%w: log not from CrossL2Inbox", ErrEventNotFound) } // use DecodeEvent to check the name of the event // but the actual decoding is done manually to extract the contract identifier name, _, err := i.contract.DecodeEvent(l) if errors.Is(err, batching.ErrUnknownEvent) { - return backendTypes.ExecutingMessage{}, fmt.Errorf("%w: %v", ErrEventNotFound, err.Error()) + return types.ExecutingMessage{}, fmt.Errorf("%w: %v", ErrEventNotFound, err.Error()) } else if err != nil { - return backendTypes.ExecutingMessage{}, fmt.Errorf("failed to decode event: %w", err) + return types.ExecutingMessage{}, fmt.Errorf("failed to decode event: %w", err) } if name != eventExecutingMessage { - return backendTypes.ExecutingMessage{}, fmt.Errorf("%w: event %v not an ExecutingMessage event", ErrEventNotFound, name) + return types.ExecutingMessage{}, fmt.Errorf("%w: event %v not an ExecutingMessage event", ErrEventNotFound, name) } // the second topic is the hash of the payload (the first is the event ID) msgHash := l.Topics[1] @@ -69,14 +68,14 @@ func (i *CrossL2Inbox) DecodeExecutingMessageLog(l *ethTypes.Log) (backendTypes. identifierBytes := bytes.NewReader(l.Data[32:]) identifier, err := identifierFromBytes(identifierBytes) if err != nil { - return backendTypes.ExecutingMessage{}, fmt.Errorf("failed to read contract identifier: %w", err) + return types.ExecutingMessage{}, fmt.Errorf("failed to read contract identifier: %w", err) } chainID, err := types.ChainIDFromBig(identifier.ChainId).ToUInt32() if err != nil { - return backendTypes.ExecutingMessage{}, fmt.Errorf("failed to convert chain ID %v to uint32: %w", identifier.ChainId, err) + return types.ExecutingMessage{}, fmt.Errorf("failed to convert chain ID %v to uint32: %w", identifier.ChainId, err) } hash := payloadHashToLogHash(msgHash, identifier.Origin) - return backendTypes.ExecutingMessage{ + return types.ExecutingMessage{ Chain: chainID, Hash: hash, BlockNum: identifier.BlockNumber.Uint64(), @@ -126,9 +125,9 @@ func identifierFromBytes(identifierBytes io.Reader) (contractIdentifier, error) // to the log the referenced initiating message. // TODO: this function is duplicated between contracts and backend/source/log_processor.go // to avoid a circular dependency. It should be reorganized to avoid this duplication. -func payloadHashToLogHash(payloadHash common.Hash, addr common.Address) backendTypes.TruncatedHash { +func payloadHashToLogHash(payloadHash common.Hash, addr common.Address) common.Hash { msg := make([]byte, 0, 2*common.HashLength) msg = append(msg, addr.Bytes()...) msg = append(msg, payloadHash.Bytes()...) - return backendTypes.TruncateHash(crypto.Keccak256Hash(msg)) + return crypto.Keccak256Hash(msg) } diff --git a/op-supervisor/supervisor/backend/source/contracts/l2inbox_test.go b/op-supervisor/supervisor/backend/source/contracts/l2inbox_test.go index b343519a48fc..302b188e5cdf 100644 --- a/op-supervisor/supervisor/backend/source/contracts/l2inbox_test.go +++ b/op-supervisor/supervisor/backend/source/contracts/l2inbox_test.go @@ -7,7 +7,7 @@ import ( "github.com/ethereum-optimism/optimism/op-service/predeploys" "github.com/ethereum-optimism/optimism/op-service/sources/batching" - backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" "github.com/ethereum-optimism/optimism/packages/contracts-bedrock/snapshots" "github.com/ethereum/go-ethereum/common" ethTypes "github.com/ethereum/go-ethereum/core/types" @@ -19,7 +19,7 @@ func TestDecodeExecutingMessageEvent(t *testing.T) { inbox := NewCrossL2Inbox() payload := bytes.Repeat([]byte{0xaa, 0xbb}, 50) payloadHash := crypto.Keccak256Hash(payload) - expected := backendTypes.ExecutingMessage{ + expected := types.ExecutingMessage{ Chain: 42424, BlockNum: 12345, LogIdx: 98, diff --git a/op-supervisor/supervisor/backend/source/log_processor.go b/op-supervisor/supervisor/backend/source/log_processor.go index 1a23d149216a..1c20f8c4530a 100644 --- a/op-supervisor/supervisor/backend/source/log_processor.go +++ b/op-supervisor/supervisor/backend/source/log_processor.go @@ -11,26 +11,25 @@ import ( "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/source/contracts" - backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" - supTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" ) type LogStorage interface { - SealBlock(chain supTypes.ChainID, parentHash common.Hash, block eth.BlockID, timestamp uint64) error - AddLog(chain supTypes.ChainID, logHash backendTypes.TruncatedHash, parentBlock eth.BlockID, logIdx uint32, execMsg *backendTypes.ExecutingMessage) error + SealBlock(chain types.ChainID, parentHash common.Hash, block eth.BlockID, timestamp uint64) error + AddLog(chain types.ChainID, logHash common.Hash, parentBlock eth.BlockID, logIdx uint32, execMsg *types.ExecutingMessage) error } type EventDecoder interface { - DecodeExecutingMessageLog(log *ethTypes.Log) (backendTypes.ExecutingMessage, error) + DecodeExecutingMessageLog(log *ethTypes.Log) (types.ExecutingMessage, error) } type logProcessor struct { - chain supTypes.ChainID + chain types.ChainID logStore LogStorage eventDecoder EventDecoder } -func newLogProcessor(chain supTypes.ChainID, logStore LogStorage) *logProcessor { +func newLogProcessor(chain types.ChainID, logStore LogStorage) *logProcessor { return &logProcessor{ chain: chain, logStore: logStore, @@ -45,7 +44,7 @@ func (p *logProcessor) ProcessLogs(_ context.Context, block eth.L1BlockRef, rcpt for _, l := range rcpt.Logs { // log hash represents the hash of *this* log as a potentially initiating message logHash := logToLogHash(l) - var execMsg *backendTypes.ExecutingMessage + var execMsg *types.ExecutingMessage msg, err := p.eventDecoder.DecodeExecutingMessageLog(l) if err != nil && !errors.Is(err, contracts.ErrEventNotFound) { return fmt.Errorf("failed to decode executing message log: %w", err) @@ -72,7 +71,7 @@ func (p *logProcessor) ProcessLogs(_ context.Context, block eth.L1BlockRef, rcpt // which is then hashed again. This is the hash that is stored in the log storage. // The address is hashed into the payload hash to save space in the log storage, // and because they represent paired data. -func logToLogHash(l *ethTypes.Log) backendTypes.TruncatedHash { +func logToLogHash(l *ethTypes.Log) common.Hash { payloadHash := crypto.Keccak256(logToMessagePayload(l)) return payloadHashToLogHash(common.Hash(payloadHash), l.Address) } @@ -94,9 +93,9 @@ func logToMessagePayload(l *ethTypes.Log) []byte { // which is then hashed. This is the hash that is stored in the log storage. // The logHash can then be used to traverse from the executing message // to the log the referenced initiating message. -func payloadHashToLogHash(payloadHash common.Hash, addr common.Address) backendTypes.TruncatedHash { +func payloadHashToLogHash(payloadHash common.Hash, addr common.Address) common.Hash { msg := make([]byte, 0, 2*common.HashLength) msg = append(msg, addr.Bytes()...) msg = append(msg, payloadHash.Bytes()...) - return backendTypes.TruncateHash(crypto.Keccak256Hash(msg)) + return crypto.Keccak256Hash(msg) } diff --git a/op-supervisor/supervisor/backend/source/log_processor_test.go b/op-supervisor/supervisor/backend/source/log_processor_test.go index 01d274aa57ee..bd7aa7abc3d1 100644 --- a/op-supervisor/supervisor/backend/source/log_processor_test.go +++ b/op-supervisor/supervisor/backend/source/log_processor_test.go @@ -7,14 +7,13 @@ import ( "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/predeploys" - backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" - supTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" + "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" "github.com/ethereum/go-ethereum/common" ethTypes "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/require" ) -var logProcessorChainID = supTypes.ChainIDFromUInt64(4) +var logProcessorChainID = types.ChainIDFromUInt64(4) func TestLogProcessor(t *testing.T) { ctx := context.Background() @@ -108,16 +107,16 @@ func TestLogProcessor(t *testing.T) { }, }, } - execMsg := backendTypes.ExecutingMessage{ + execMsg := types.ExecutingMessage{ Chain: 4, BlockNum: 6, LogIdx: 8, Timestamp: 10, - Hash: backendTypes.TruncatedHash{0xaa}, + Hash: common.Hash{0xaa}, } store := &stubLogStorage{} - processor := newLogProcessor(supTypes.ChainID{4}, store) - processor.eventDecoder = EventDecoderFn(func(l *ethTypes.Log) (backendTypes.ExecutingMessage, error) { + processor := newLogProcessor(types.ChainID{4}, store) + processor.eventDecoder = EventDecoderFn(func(l *ethTypes.Log) (types.ExecutingMessage, error) { require.Equal(t, rcpts[0].Logs[0], l) return execMsg, nil }) @@ -182,7 +181,7 @@ func TestToLogHash(t *testing.T) { refHash := logToLogHash(mkLog()) // The log hash is stored in the database so test that it matches the actual value. // If this changes, compatibility with existing databases may be affected - expectedRefHash := backendTypes.TruncateHash(common.HexToHash("0x4e1dc08fddeb273275f787762cdfe945cf47bb4e80a1fabbc7a825801e81b73f")) + expectedRefHash := common.HexToHash("0x4e1dc08fddeb273275f787762cdfe945cf47bb4e80a1fabbc7a825801e81b73f") require.Equal(t, expectedRefHash, refHash, "reference hash changed, check that database compatibility is not broken") // Check that the hash is changed when any data it should include changes @@ -206,7 +205,7 @@ type stubLogStorage struct { seals []storedSeal } -func (s *stubLogStorage) SealBlock(chainID supTypes.ChainID, parentHash common.Hash, block eth.BlockID, timestamp uint64) error { +func (s *stubLogStorage) SealBlock(chainID types.ChainID, parentHash common.Hash, block eth.BlockID, timestamp uint64) error { if logProcessorChainID != chainID { return fmt.Errorf("chain id mismatch, expected %v but got %v", logProcessorChainID, chainID) } @@ -218,7 +217,7 @@ func (s *stubLogStorage) SealBlock(chainID supTypes.ChainID, parentHash common.H return nil } -func (s *stubLogStorage) AddLog(chainID supTypes.ChainID, logHash backendTypes.TruncatedHash, parentBlock eth.BlockID, logIdx uint32, execMsg *backendTypes.ExecutingMessage) error { +func (s *stubLogStorage) AddLog(chainID types.ChainID, logHash common.Hash, parentBlock eth.BlockID, logIdx uint32, execMsg *types.ExecutingMessage) error { if logProcessorChainID != chainID { return fmt.Errorf("chain id mismatch, expected %v but got %v", logProcessorChainID, chainID) } @@ -240,12 +239,12 @@ type storedSeal struct { type storedLog struct { parent eth.BlockID logIdx uint32 - logHash backendTypes.TruncatedHash - execMsg *backendTypes.ExecutingMessage + logHash common.Hash + execMsg *types.ExecutingMessage } -type EventDecoderFn func(*ethTypes.Log) (backendTypes.ExecutingMessage, error) +type EventDecoderFn func(*ethTypes.Log) (types.ExecutingMessage, error) -func (f EventDecoderFn) DecodeExecutingMessageLog(log *ethTypes.Log) (backendTypes.ExecutingMessage, error) { +func (f EventDecoderFn) DecodeExecutingMessageLog(log *ethTypes.Log) (types.ExecutingMessage, error) { return f(log) } diff --git a/op-supervisor/supervisor/backend/types/types.go b/op-supervisor/supervisor/backend/types/types.go deleted file mode 100644 index cf28120a34ee..000000000000 --- a/op-supervisor/supervisor/backend/types/types.go +++ /dev/null @@ -1,27 +0,0 @@ -package types - -import ( - "encoding/hex" - - "github.com/ethereum/go-ethereum/common" -) - -type TruncatedHash [20]byte - -func TruncateHash(hash common.Hash) TruncatedHash { - var truncated TruncatedHash - copy(truncated[:], hash[0:20]) - return truncated -} - -func (h TruncatedHash) String() string { - return hex.EncodeToString(h[:]) -} - -type ExecutingMessage struct { - Chain uint32 - BlockNum uint64 - LogIdx uint32 - Timestamp uint64 - Hash TruncatedHash -} diff --git a/op-supervisor/supervisor/types/types.go b/op-supervisor/supervisor/types/types.go index 54b1a8a0c92c..b035e26abcef 100644 --- a/op-supervisor/supervisor/types/types.go +++ b/op-supervisor/supervisor/types/types.go @@ -13,6 +13,14 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" ) +type ExecutingMessage struct { + Chain uint32 // same as ChainID for now, but will be indirect, i.e. translated to full ID, later + BlockNum uint64 + LogIdx uint32 + Timestamp uint64 + Hash common.Hash +} + type Message struct { Identifier Identifier `json:"identifier"` PayloadHash common.Hash `json:"payloadHash"` From 0fee34b645ca9dff91eb2d992bb62ec458408538 Mon Sep 17 00:00:00 2001 From: Sam Stokes <35908605+bitwiseguy@users.noreply.github.com> Date: Tue, 24 Sep 2024 08:50:57 -0400 Subject: [PATCH 241/264] op-service: add configurable client timeout (#12074) * op-service: add configurable timeouts * op-service: fix lazy_dial --- op-service/client/lazy_dial.go | 3 ++- op-service/client/rpc.go | 34 ++++++++++++++++++++++++----- op-service/sources/engine_client.go | 27 ++++++++++++++++------- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/op-service/client/lazy_dial.go b/op-service/client/lazy_dial.go index f5872778da9e..9a4e7cf6d872 100644 --- a/op-service/client/lazy_dial.go +++ b/op-service/client/lazy_dial.go @@ -49,7 +49,7 @@ func (l *LazyRPC) dial(ctx context.Context) error { if err != nil { return fmt.Errorf("failed to dial: %w", err) } - l.inner = &BaseRPCClient{c: underlying} + l.inner = NewBaseRPCClient(underlying) return nil } @@ -66,6 +66,7 @@ func (l *LazyRPC) CallContext(ctx context.Context, result any, method string, ar if err := l.dial(ctx); err != nil { return err } + fmt.Println("checkpoin 1") return l.inner.CallContext(ctx, result, method, args...) } diff --git a/op-service/client/rpc.go b/op-service/client/rpc.go index f1452c57f0db..8fb2d4d37b88 100644 --- a/op-service/client/rpc.go +++ b/op-service/client/rpc.go @@ -36,10 +36,26 @@ type rpcConfig struct { limit float64 burst int lazy bool + callTimeout time.Duration + batchCallTimeout time.Duration } type RPCOption func(cfg *rpcConfig) error +func WithCallTimeout(d time.Duration) RPCOption { + return func(cfg *rpcConfig) error { + cfg.callTimeout = d + return nil + } +} + +func WithBatchCallTimeout(d time.Duration) RPCOption { + return func(cfg *rpcConfig) error { + cfg.batchCallTimeout = d + return nil + } +} + // WithDialBackoff configures the number of attempts for the initial dial to the RPC, // attempts are executed with an exponential backoff strategy. func WithDialBackoff(attempts int) RPCOption { @@ -98,6 +114,12 @@ func NewRPC(ctx context.Context, lgr log.Logger, addr string, opts ...RPCOption) if cfg.backoffAttempts < 1 { // default to at least 1 attempt, or it always fails to dial. cfg.backoffAttempts = 1 } + if cfg.callTimeout == 0 { + cfg.callTimeout = 10 * time.Second + } + if cfg.batchCallTimeout == 0 { + cfg.batchCallTimeout = 20 * time.Second + } var wrapped RPC if cfg.lazy { @@ -107,7 +129,7 @@ func NewRPC(ctx context.Context, lgr log.Logger, addr string, opts ...RPCOption) if err != nil { return nil, err } - wrapped = &BaseRPCClient{c: underlying} + wrapped = &BaseRPCClient{c: underlying, callTimeout: cfg.callTimeout, batchCallTimeout: cfg.batchCallTimeout} } if cfg.limit != 0 { @@ -171,11 +193,13 @@ func IsURLAvailable(ctx context.Context, address string) bool { // with the client.RPC interface. // It sets a timeout of 10s on CallContext & 20s on BatchCallContext made through it. type BaseRPCClient struct { - c *rpc.Client + c *rpc.Client + batchCallTimeout time.Duration + callTimeout time.Duration } func NewBaseRPCClient(c *rpc.Client) *BaseRPCClient { - return &BaseRPCClient{c: c} + return &BaseRPCClient{c: c, callTimeout: 10 * time.Second, batchCallTimeout: 20 * time.Second} } func (b *BaseRPCClient) Close() { @@ -183,13 +207,13 @@ func (b *BaseRPCClient) Close() { } func (b *BaseRPCClient) CallContext(ctx context.Context, result any, method string, args ...any) error { - cCtx, cancel := context.WithTimeout(ctx, 10*time.Second) + cCtx, cancel := context.WithTimeout(ctx, b.callTimeout) defer cancel() return b.c.CallContext(cCtx, result, method, args...) } func (b *BaseRPCClient) BatchCallContext(ctx context.Context, batch []rpc.BatchElem) error { - cCtx, cancel := context.WithTimeout(ctx, 20*time.Second) + cCtx, cancel := context.WithTimeout(ctx, b.batchCallTimeout) defer cancel() return b.c.BatchCallContext(cCtx, batch) } diff --git a/op-service/sources/engine_client.go b/op-service/sources/engine_client.go index 07d7ecb9d271..79921192f9e7 100644 --- a/op-service/sources/engine_client.go +++ b/op-service/sources/engine_client.go @@ -50,9 +50,10 @@ func NewEngineClient(client client.RPC, log log.Logger, metrics caching.Metrics, // EngineAPIClient is an RPC client for the Engine API functions. type EngineAPIClient struct { - RPC client.RPC - log log.Logger - evp EngineVersionProvider + RPC client.RPC + log log.Logger + evp EngineVersionProvider + timeout time.Duration } type EngineVersionProvider interface { @@ -63,9 +64,19 @@ type EngineVersionProvider interface { func NewEngineAPIClient(rpc client.RPC, l log.Logger, evp EngineVersionProvider) *EngineAPIClient { return &EngineAPIClient{ - RPC: rpc, - log: l, - evp: evp, + RPC: rpc, + log: l, + evp: evp, + timeout: time.Second * 5, + } +} + +func NewEngineAPIClientWithTimeout(rpc client.RPC, l log.Logger, evp EngineVersionProvider, timeout time.Duration) *EngineAPIClient { + return &EngineAPIClient{ + RPC: rpc, + log: l, + evp: evp, + timeout: timeout, } } @@ -84,7 +95,7 @@ func (s *EngineAPIClient) ForkchoiceUpdate(ctx context.Context, fc *eth.Forkchoi llog := s.log.New("state", fc) // local logger tlog := llog.New("attr", attributes) // trace logger tlog.Trace("Sharing forkchoice-updated signal") - fcCtx, cancel := context.WithTimeout(ctx, time.Second*5) + fcCtx, cancel := context.WithTimeout(ctx, s.timeout) defer cancel() var result eth.ForkchoiceUpdatedResult method := s.evp.ForkchoiceUpdatedVersion(attributes) @@ -120,7 +131,7 @@ func (s *EngineAPIClient) NewPayload(ctx context.Context, payload *eth.Execution e := s.log.New("block_hash", payload.BlockHash) e.Trace("sending payload for execution") - execCtx, cancel := context.WithTimeout(ctx, time.Second*5) + execCtx, cancel := context.WithTimeout(ctx, s.timeout) defer cancel() var result eth.PayloadStatusV1 From ec3f63440e6e4f8d39966446c37e71ff6db4be75 Mon Sep 17 00:00:00 2001 From: Inphi <mlaw2501@gmail.com> Date: Tue, 24 Sep 2024 10:33:25 -0400 Subject: [PATCH 242/264] ci: Sanitize op-program for unsupported instructions (#12007) --- .circleci/config.yml | 3 +++ cannon/Makefile | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index dccd91867d5b..6cab0308e927 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1048,6 +1048,9 @@ jobs: - restore_cache: name: Restore cannon prestate cache key: cannon-prestate-{{ checksum "./cannon/bin/cannon" }}-{{ checksum "op-program/bin/op-program-client.elf" }} + - run: + name: Sanitize op-program guest + command: make -f cannon/Makefile sanitize-program GUEST_PROGRAM=op-program/bin/op-program-client.elf - run: name: generate cannon prestate command: make cannon-prestate diff --git a/cannon/Makefile b/cannon/Makefile index 0f3836fb62fb..d6a1d85eff89 100644 --- a/cannon/Makefile +++ b/cannon/Makefile @@ -22,6 +22,14 @@ clean: elf: make -C ./testdata/example elf +sanitize-program: + @if ! { mips-linux-gnu-objdump -d -j .text $$GUEST_PROGRAM | awk '{print $3}' | grep -Ew -m1 '(bgezal|bltzal)'; }; then \ + echo "guest program is sanitized for unsupported instructions"; \ + else \ + echo "found unsupported instructions in the guest program"; \ + exit 1; \ + fi + contract: cd ../packages/contracts-bedrock && forge build From 308ce74c7ab82a7a4a4fb5dd709224af316d2921 Mon Sep 17 00:00:00 2001 From: Maurelian <john@oplabs.co> Date: Tue, 24 Sep 2024 10:45:42 -0400 Subject: [PATCH 243/264] OPSM: Deploy Permissioned Game (#12064) * chore: fix semver lock * fix: no permissionless root, remove hash from 0xdead * fix: use 0xdead root properly * feat: add remaining fault proof support * chore: Update semver-lock * fix: Remove extra anchor root definition and restore aritfactsFs argument * feat: Add wip big blueprint code * Don't wrap input to deployBigBytecode with preamble * fix: off by one in deployBigBytecode * feat: more gas efficient blueprint deployment for permissioned game * Get the big deployments working * perf: more efficient preamble parsing * chore: snapshots + fix revert * test: skip FaultDisputeGameAddress since we don't deploy it yet * chore: cleanup --------- Co-authored-by: Matt Solomon <matt@mattsolomon.dev> Co-authored-by: Matthew Slipper <me@matthewslipper.com> --- .../deployer/integration_test/apply_test.go | 9 +- .../scripts/DeployImplementations.s.sol | 52 ++++++-- .../scripts/DeployOPChain.s.sol | 38 ++++-- packages/contracts-bedrock/semver-lock.json | 4 +- .../snapshots/abi/OPStackManager.json | 25 ++++ .../snapshots/abi/OPStackManagerInterop.json | 25 ++++ .../storageLayout/OPStackManager.json | 27 ++-- .../storageLayout/OPStackManagerInterop.json | 27 ++-- .../src/L1/OPStackManager.sol | 115 ++++++++++++++---- .../src/libraries/Blueprint.sol | 55 ++++++++- .../test/libraries/Blueprint.t.sol | 2 +- 11 files changed, 309 insertions(+), 70 deletions(-) diff --git a/op-chain-ops/deployer/integration_test/apply_test.go b/op-chain-ops/deployer/integration_test/apply_test.go index 6d673ed03791..b69595b67761 100644 --- a/op-chain-ops/deployer/integration_test/apply_test.go +++ b/op-chain-ops/deployer/integration_test/apply_test.go @@ -27,6 +27,8 @@ import ( const TestParams = ` participants: - el_type: geth + el_extra_params: + - "--gcmode=archive" cl_type: lighthouse network_params: prefunded_accounts: '{ "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266": { "balance": "1000000ETH" } }' @@ -41,6 +43,7 @@ network_params: }' network_id: "77799777" seconds_per_slot: 3 + genesis_delay: 0 ` type deployerKey struct{} @@ -56,7 +59,7 @@ func (d *deployerKey) String() string { func TestEndToEndApply(t *testing.T) { kurtosisutil.Test(t) - lgr := testlog.Logger(t, slog.LevelInfo) + lgr := testlog.Logger(t, slog.LevelDebug) ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -189,6 +192,10 @@ func TestEndToEndApply(t *testing.T) { {"DelayedWETHPermissionlessGameProxyAddress", chainState.DelayedWETHPermissionlessGameProxyAddress}, } for _, addr := range chainAddrs { + // TODO Delete this `if`` block once FaultDisputeGameAddress is deployed. + if addr.name == "FaultDisputeGameAddress" { + continue + } t.Run(fmt.Sprintf("chain %s - %s", chainState.ID, addr.name), func(t *testing.T) { code, err := l1Client.CodeAt(ctx, addr.addr, nil) require.NoError(t, err) diff --git a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol index 433b1573efe4..81cafa89c272 100644 --- a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol +++ b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol @@ -10,6 +10,7 @@ import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { Constants } from "src/libraries/Constants.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; +import { Bytes } from "src/libraries/Bytes.sol"; import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { Proxy } from "src/universal/Proxy.sol"; @@ -23,6 +24,7 @@ import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol"; import { MIPS } from "src/cannon/MIPS.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; +import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; @@ -514,10 +516,11 @@ contract DeployImplementations is Script { blueprints.l1ChugSplashProxy = deployBytecode(Blueprint.blueprintDeployerBytecode(type(L1ChugSplashProxy).creationCode), salt); blueprints.resolvedDelegateProxy = deployBytecode(Blueprint.blueprintDeployerBytecode(type(ResolvedDelegateProxy).creationCode), salt); blueprints.anchorStateRegistry = deployBytecode(Blueprint.blueprintDeployerBytecode(type(AnchorStateRegistry).creationCode), salt); + (blueprints.permissionedDisputeGame1, blueprints.permissionedDisputeGame2) = deployBigBytecode(type(PermissionedDisputeGame).creationCode, salt); vm.stopBroadcast(); // forgefmt: disable-end - OPStackManager.ImplementationSetter[] memory setters = new OPStackManager.ImplementationSetter[](7); + OPStackManager.ImplementationSetter[] memory setters = new OPStackManager.ImplementationSetter[](9); setters[0] = OPStackManager.ImplementationSetter({ name: "L1ERC721Bridge", info: OPStackManager.Implementation(address(_dio.l1ERC721BridgeImpl()), L1ERC721Bridge.initialize.selector) @@ -543,13 +546,22 @@ contract DeployImplementations is Script { name: "L1StandardBridge", info: OPStackManager.Implementation(address(_dio.l1StandardBridgeImpl()), L1StandardBridge.initialize.selector) }); - setters[6] = OPStackManager.ImplementationSetter({ name: "DisputeGameFactory", info: OPStackManager.Implementation( address(_dio.disputeGameFactoryImpl()), DisputeGameFactory.initialize.selector ) }); + setters[7] = OPStackManager.ImplementationSetter({ + name: "DelayedWETH", + info: OPStackManager.Implementation(address(_dio.delayedWETHImpl()), DelayedWETH.initialize.selector) + }); + setters[8] = OPStackManager.ImplementationSetter({ + name: "MIPS", + // MIPS is a singleton for all chains, so it doesn't need to be initialized, so the + // selector is just `bytes4(0)`. + info: OPStackManager.Implementation(address(_dio.mipsSingleton()), bytes4(0)) + }); // This call contains a broadcast to deploy OPSM which is proxied. OPStackManager opsmProxy = createOPSMContract(_dii, _dio, blueprints, release, setters); @@ -617,14 +629,14 @@ contract DeployImplementations is Script { // The fault proofs contracts are configured as follows: // | Contract | Proxied | Deployment | MCP Ready | // |-------------------------|---------|-----------------------------------|------------| - // | DisputeGameFactory | Yes | Bespoke | Yes | X - // | AnchorStateRegistry | Yes | Bespoke | No | X - // | FaultDisputeGame | No | Bespoke | No | Todo - // | PermissionedDisputeGame | No | Bespoke | No | Todo - // | DelayedWETH | Yes | Two bespoke (one per DisputeGame) | No | Todo: Proxies. - // | PreimageOracle | No | Shared | N/A | X - // | MIPS | No | Shared | N/A | X - // | OptimismPortal2 | Yes | Shared | No | X + // | DisputeGameFactory | Yes | Bespoke | Yes | + // | AnchorStateRegistry | Yes | Bespoke | No | + // | FaultDisputeGame | No | Bespoke | No | Not yet supported by OPCM + // | PermissionedDisputeGame | No | Bespoke | No | + // | DelayedWETH | Yes | Two bespoke (one per DisputeGame) | No | + // | PreimageOracle | No | Shared | N/A | + // | MIPS | No | Shared | N/A | + // | OptimismPortal2 | Yes | Shared | No | // // This script only deploys the shared contracts. The bespoke contracts are deployed by // `DeployOPChain.s.sol`. When the shared contracts are proxied, the contracts deployed here are @@ -731,6 +743,26 @@ contract DeployImplementations is Script { } require(newContract_ != address(0), "DeployImplementations: create2 failed"); } + + function deployBigBytecode( + bytes memory _bytecode, + bytes32 _salt + ) + public + returns (address newContract1_, address newContract2_) + { + // Preamble needs 3 bytes. + uint256 maxInitCodeSize = 24576 - 3; + require(_bytecode.length > maxInitCodeSize, "DeployImplementations: Use deployBytecode instead"); + + bytes memory part1Slice = Bytes.slice(_bytecode, 0, maxInitCodeSize); + bytes memory part1 = Blueprint.blueprintDeployerBytecode(part1Slice); + bytes memory part2Slice = Bytes.slice(_bytecode, maxInitCodeSize, _bytecode.length - maxInitCodeSize); + bytes memory part2 = Blueprint.blueprintDeployerBytecode(part2Slice); + + newContract1_ = deployBytecode(part1, _salt); + newContract2_ = deployBytecode(part2, _salt); + } } // Similar to how DeploySuperchain.s.sol contains a lot of comments to thoroughly document the script diff --git a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol index 50fd9060ae91..e0df48cc6029 100644 --- a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol @@ -11,6 +11,7 @@ import { BaseDeployIO } from "scripts/utils/BaseDeployIO.sol"; import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; +import { IBigStepper } from "src/dispute/interfaces/IBigStepper.sol"; import { Constants } from "src/libraries/Constants.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; @@ -23,7 +24,7 @@ import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; -import { GameType, GameTypes, Hash, OutputRoot } from "src/dispute/lib/Types.sol"; +import { Claim, GameType, GameTypes, Hash, OutputRoot } from "src/dispute/lib/Types.sol"; import { OPStackManager } from "src/L1/OPStackManager.sol"; import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; @@ -201,7 +202,7 @@ contract DeployOPChainOutput is BaseDeployIO { address(_disputeGameFactoryProxy), address(_anchorStateRegistryProxy), address(_anchorStateRegistryImpl), - address(_faultDisputeGame), + // address(_faultDisputeGame), address(_permissionedDisputeGame), address(_delayedWETHPermissionedGameProxy), address(_delayedWETHPermissionlessGameProxy) @@ -289,8 +290,8 @@ contract DeployOPChainOutput is BaseDeployIO { // -------- Deployment Assertions -------- function assertValidDeploy(DeployOPChainInput _doi) internal { - assertValidAnchorStateRegistryProxy(_doi); assertValidAnchorStateRegistryImpl(_doi); + assertValidAnchorStateRegistryProxy(_doi); assertValidDelayedWETHs(_doi); assertValidDisputeGameFactory(_doi); assertValidL1CrossDomainMessenger(_doi); @@ -298,9 +299,23 @@ contract DeployOPChainOutput is BaseDeployIO { assertValidL1StandardBridge(_doi); assertValidOptimismMintableERC20Factory(_doi); assertValidOptimismPortal(_doi); + assertValidPermissionedDisputeGame(_doi); assertValidSystemConfig(_doi); - // TODO Other FP assertions like the dispute games, anchor state registry, etc. - // TODO add initialization assertions + } + + function assertValidPermissionedDisputeGame(DeployOPChainInput _doi) internal view { + PermissionedDisputeGame game = permissionedDisputeGame(); + + require(GameType.unwrap(game.gameType()) == GameType.unwrap(GameTypes.PERMISSIONED_CANNON), "DPG-10"); + require(Claim.unwrap(game.absolutePrestate()) == bytes32(hex"dead"), "DPG-20"); + + OPStackManager opsm = _doi.opsmProxy(); + (address mips,) = opsm.implementations(opsm.latestRelease(), "MIPS"); + require(game.vm() == IBigStepper(mips), "DPG-30"); + + require(address(game.weth()) == address(delayedWETHPermissionedGameProxy()), "DPG-40"); + require(address(game.anchorStateRegistry()) == address(anchorStateRegistryProxy()), "DPG-50"); + require(game.l2ChainId() == _doi.l2ChainId(), "DPG-60"); } function assertValidAnchorStateRegistryProxy(DeployOPChainInput) internal { @@ -436,7 +451,14 @@ contract DeployOPChainOutput is BaseDeployIO { } function assertValidDisputeGameFactory(DeployOPChainInput) internal view { - // TODO add in once FP support is added. + DisputeGameFactory factory = disputeGameFactoryProxy(); + + DeployUtils.assertInitialized({ _contractAddress: address(factory), _slot: 0, _offset: 0 }); + + require( + address(factory.gameImpls(GameTypes.PERMISSIONED_CANNON)) == address(permissionedDisputeGame()), "DF-10" + ); + require(factory.owner() == address(opChainProxyAdmin()), "DF-20"); } function assertValidDelayedWETHs(DeployOPChainInput) internal view { @@ -480,7 +502,7 @@ contract DeployOPChain is Script { vm.label(address(deployOutput.disputeGameFactoryProxy), "disputeGameFactoryProxy"); vm.label(address(deployOutput.anchorStateRegistryProxy), "anchorStateRegistryProxy"); vm.label(address(deployOutput.anchorStateRegistryImpl), "anchorStateRegistryImpl"); - vm.label(address(deployOutput.faultDisputeGame), "faultDisputeGame"); + // vm.label(address(deployOutput.faultDisputeGame), "faultDisputeGame"); vm.label(address(deployOutput.permissionedDisputeGame), "permissionedDisputeGame"); vm.label(address(deployOutput.delayedWETHPermissionedGameProxy), "delayedWETHPermissionedGameProxy"); vm.label(address(deployOutput.delayedWETHPermissionlessGameProxy), "delayedWETHPermissionlessGameProxy"); @@ -498,7 +520,7 @@ contract DeployOPChain is Script { _doo.set(_doo.disputeGameFactoryProxy.selector, address(deployOutput.disputeGameFactoryProxy)); _doo.set(_doo.anchorStateRegistryProxy.selector, address(deployOutput.anchorStateRegistryProxy)); _doo.set(_doo.anchorStateRegistryImpl.selector, address(deployOutput.anchorStateRegistryImpl)); - _doo.set(_doo.faultDisputeGame.selector, address(deployOutput.faultDisputeGame)); + // _doo.set(_doo.faultDisputeGame.selector, address(deployOutput.faultDisputeGame)); _doo.set(_doo.permissionedDisputeGame.selector, address(deployOutput.permissionedDisputeGame)); _doo.set(_doo.delayedWETHPermissionedGameProxy.selector, address(deployOutput.delayedWETHPermissionedGameProxy)); _doo.set( diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index db35c5b37429..7312208bee3e 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -32,8 +32,8 @@ "sourceCodeHash": "0xde4df0f9633dc0cdb1c9f634003ea5b0f7c5c1aebc407bc1b2f44c0ecf938649" }, "src/L1/OPStackManager.sol": { - "initCodeHash": "0x4bffecbd95e63f9bd04ab8e3c6a804cc25e0cd151ebeb7f8d6b9330332e6eb20", - "sourceCodeHash": "0x850f1eacc77f1a5c680625196618bc4b4332cb68924d9eddd57c749bedcd7c94" + "initCodeHash": "0x5b451782192b8429f6822c88270c4f0dbd10342518c5695ecf4dff7b5ebfb4e4", + "sourceCodeHash": "0x4a9c242ce96471437ec97662d2365a7bda376db765c630a41cbe238811f1df51" }, "src/L1/OptimismPortal.sol": { "initCodeHash": "0xbe2c0c81b3459014f287d8c89cdc0d27dde5d1f44e5d024fa1e4773ddc47c190", diff --git a/packages/contracts-bedrock/snapshots/abi/OPStackManager.json b/packages/contracts-bedrock/snapshots/abi/OPStackManager.json index 2ad0a4d1dc2c..9654f8f084ab 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPStackManager.json +++ b/packages/contracts-bedrock/snapshots/abi/OPStackManager.json @@ -50,6 +50,16 @@ "internalType": "address", "name": "anchorStateRegistry", "type": "address" + }, + { + "internalType": "address", + "name": "permissionedDisputeGame1", + "type": "address" + }, + { + "internalType": "address", + "name": "permissionedDisputeGame2", + "type": "address" } ], "internalType": "struct OPStackManager.Blueprints", @@ -298,6 +308,16 @@ "internalType": "address", "name": "anchorStateRegistry", "type": "address" + }, + { + "internalType": "address", + "name": "permissionedDisputeGame1", + "type": "address" + }, + { + "internalType": "address", + "name": "permissionedDisputeGame2", + "type": "address" } ], "internalType": "struct OPStackManager.Blueprints", @@ -499,6 +519,11 @@ "name": "EmptyInitcode", "type": "error" }, + { + "inputs": [], + "name": "IdentityPrecompileCallFailed", + "type": "error" + }, { "inputs": [], "name": "InvalidChainId", diff --git a/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json b/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json index 2ad0a4d1dc2c..9654f8f084ab 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json +++ b/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json @@ -50,6 +50,16 @@ "internalType": "address", "name": "anchorStateRegistry", "type": "address" + }, + { + "internalType": "address", + "name": "permissionedDisputeGame1", + "type": "address" + }, + { + "internalType": "address", + "name": "permissionedDisputeGame2", + "type": "address" } ], "internalType": "struct OPStackManager.Blueprints", @@ -298,6 +308,16 @@ "internalType": "address", "name": "anchorStateRegistry", "type": "address" + }, + { + "internalType": "address", + "name": "permissionedDisputeGame1", + "type": "address" + }, + { + "internalType": "address", + "name": "permissionedDisputeGame2", + "type": "address" } ], "internalType": "struct OPStackManager.Blueprints", @@ -499,6 +519,11 @@ "name": "EmptyInitcode", "type": "error" }, + { + "inputs": [], + "name": "IdentityPrecompileCallFailed", + "type": "error" + }, { "inputs": [], "name": "InvalidChainId", diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OPStackManager.json b/packages/contracts-bedrock/snapshots/storageLayout/OPStackManager.json index 881871a50dd1..c22ed7c2c8da 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/OPStackManager.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/OPStackManager.json @@ -13,32 +13,39 @@ "slot": "0", "type": "bool" }, - { - "bytes": "192", - "label": "blueprint", - "offset": 0, - "slot": "1", - "type": "struct OPStackManager.Blueprints" - }, { "bytes": "32", "label": "latestRelease", "offset": 0, - "slot": "7", + "slot": "1", "type": "string" }, { "bytes": "32", "label": "implementations", "offset": 0, - "slot": "8", + "slot": "2", "type": "mapping(string => mapping(string => struct OPStackManager.Implementation))" }, { "bytes": "32", "label": "systemConfigs", "offset": 0, - "slot": "9", + "slot": "3", "type": "mapping(uint256 => contract SystemConfig)" + }, + { + "bytes": "256", + "label": "blueprint", + "offset": 0, + "slot": "4", + "type": "struct OPStackManager.Blueprints" + }, + { + "bytes": "1600", + "label": "__gap", + "offset": 0, + "slot": "12", + "type": "uint256[50]" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OPStackManagerInterop.json b/packages/contracts-bedrock/snapshots/storageLayout/OPStackManagerInterop.json index 881871a50dd1..c22ed7c2c8da 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/OPStackManagerInterop.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/OPStackManagerInterop.json @@ -13,32 +13,39 @@ "slot": "0", "type": "bool" }, - { - "bytes": "192", - "label": "blueprint", - "offset": 0, - "slot": "1", - "type": "struct OPStackManager.Blueprints" - }, { "bytes": "32", "label": "latestRelease", "offset": 0, - "slot": "7", + "slot": "1", "type": "string" }, { "bytes": "32", "label": "implementations", "offset": 0, - "slot": "8", + "slot": "2", "type": "mapping(string => mapping(string => struct OPStackManager.Implementation))" }, { "bytes": "32", "label": "systemConfigs", "offset": 0, - "slot": "9", + "slot": "3", "type": "mapping(uint256 => contract SystemConfig)" + }, + { + "bytes": "256", + "label": "blueprint", + "offset": 0, + "slot": "4", + "type": "struct OPStackManager.Blueprints" + }, + { + "bytes": "1600", + "label": "__gap", + "offset": 0, + "slot": "12", + "type": "uint256[50]" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/src/L1/OPStackManager.sol b/packages/contracts-bedrock/src/L1/OPStackManager.sol index f7d71233005e..1a81430ff1e6 100644 --- a/packages/contracts-bedrock/src/L1/OPStackManager.sol +++ b/packages/contracts-bedrock/src/L1/OPStackManager.sol @@ -8,6 +8,10 @@ import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; +import { IBigStepper } from "src/dispute/interfaces/IBigStepper.sol"; +import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; +import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; +import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; import { Proxy } from "src/universal/Proxy.sol"; import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; @@ -23,7 +27,7 @@ import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; -import { GameTypes } from "src/dispute/lib/Types.sol"; +import { Claim, Duration, GameType, GameTypes } from "src/dispute/lib/Types.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; @@ -105,6 +109,8 @@ contract OPStackManager is ISemver, Initializable { address l1ChugSplashProxy; address resolvedDelegateProxy; address anchorStateRegistry; + address permissionedDisputeGame1; + address permissionedDisputeGame2; } /// @notice Inputs required when initializing the OPStackManager. To avoid 'StackTooDeep' errors, @@ -118,8 +124,8 @@ contract OPStackManager is ISemver, Initializable { // -------- Constants and Variables -------- - /// @custom:semver 1.0.0-beta.4 - string public constant version = "1.0.0-beta.4"; + /// @custom:semver 1.0.0-beta.5 + string public constant version = "1.0.0-beta.5"; /// @notice Address of the SuperchainConfig contract shared by all chains. SuperchainConfig public immutable superchainConfig; @@ -127,12 +133,6 @@ contract OPStackManager is ISemver, Initializable { /// @notice Address of the ProtocolVersions contract shared by all chains. ProtocolVersions public immutable protocolVersions; - /// @notice Addresses of the Blueprint contracts. - /// This is internal because if public the autogenerated getter method would return a tuple of - /// addresses, but we want it to return a struct. This is also set via `initialize` because - /// we can't make this an immutable variable as it is a non-value type. - Blueprints internal blueprint; - /// @notice The latest release of the OP Stack Manager, as a string of the format `op-contracts/vX.Y.Z`. string public latestRelease; @@ -142,6 +142,16 @@ contract OPStackManager is ISemver, Initializable { /// @notice Maps an L2 Chain ID to the SystemConfig for that chain. mapping(uint256 => SystemConfig) public systemConfigs; + /// @notice Addresses of the Blueprint contracts. + /// This is internal because if public the autogenerated getter method would return a tuple of + /// addresses, but we want it to return a struct. This is also set via `initialize` because + /// we can't make this an immutable variable as it is a non-value type. + Blueprints internal blueprint; + + /// @notice Storage gap for future modifications, so we can expand the number of blueprints + /// without affecting other storage variables. + uint256[50] private __gap; + // -------- Events -------- /// @notice Emitted when a new OP Stack chain is deployed. @@ -206,16 +216,6 @@ contract OPStackManager is ISemver, Initializable { bytes32 salt = bytes32(_input.l2ChainId); DeployOutput memory output; - // -------- TODO: Placeholders -------- - // For contracts we don't yet deploy, we set the outputs to dummy proxies so they have code to pass assertions. - // We do these first, that way the disputeGameFactoryProxy is set when passed to the SystemConfig input. - output.faultDisputeGame = FaultDisputeGame(deployProxy(l2ChainId, output.opChainProxyAdmin, "5")); - output.permissionedDisputeGame = PermissionedDisputeGame(deployProxy(l2ChainId, output.opChainProxyAdmin, "6")); - output.delayedWETHPermissionedGameProxy = - DelayedWETH(payable(deployProxy(l2ChainId, output.opChainProxyAdmin, "7"))); - output.delayedWETHPermissionlessGameProxy = - DelayedWETH(payable(deployProxy(l2ChainId, output.opChainProxyAdmin, "8"))); - // -------- Deploy Chain Singletons -------- // The ProxyAdmin is the owner of all proxies for the chain. We temporarily set the owner to @@ -266,6 +266,22 @@ contract OPStackManager is ISemver, Initializable { Blueprint.deployFrom(blueprint.anchorStateRegistry, salt, abi.encode(output.disputeGameFactoryProxy)) ); + // We have two delayed WETH contracts per chain, one for each of the permissioned and permissionless games. + output.delayedWETHPermissionlessGameProxy = + DelayedWETH(payable(deployProxy(l2ChainId, output.opChainProxyAdmin, "DelayedWETHPermissionlessGame"))); + output.delayedWETHPermissionedGameProxy = + DelayedWETH(payable(deployProxy(l2ChainId, output.opChainProxyAdmin, "DelayedWETHPermissionedGame"))); + + // While not a proxy, we deploy the PermissionedDisputeGame here as well because it's bespoke per chain. + output.permissionedDisputeGame = PermissionedDisputeGame( + Blueprint.deployFrom( + blueprint.permissionedDisputeGame1, + blueprint.permissionedDisputeGame2, + salt, + encodePermissionedDisputeGameConstructor(_input, output) + ) + ); + // -------- Set and Initialize Proxy Implementations -------- Implementation memory impl; bytes memory data; @@ -294,10 +310,20 @@ contract OPStackManager is ISemver, Initializable { data = encodeL1StandardBridgeInitializer(impl.initializer, output); upgradeAndCall(output.opChainProxyAdmin, address(output.l1StandardBridgeProxy), impl.logic, data); - // TODO: also call setImplementation() once the dispute games are deployed. + impl = getLatestImplementation("DelayedWETH"); + data = encodeDelayedWETHInitializer(impl.initializer, _input); + upgradeAndCall(output.opChainProxyAdmin, address(output.delayedWETHPermissionedGameProxy), impl.logic, data); + upgradeAndCall(output.opChainProxyAdmin, address(output.delayedWETHPermissionlessGameProxy), impl.logic, data); + + // We set the initial owner to this contract, set game implementations, then transfer ownership. impl = getLatestImplementation("DisputeGameFactory"); data = encodeDisputeGameFactoryInitializer(impl.initializer, _input); upgradeAndCall(output.opChainProxyAdmin, address(output.disputeGameFactoryProxy), impl.logic, data); + output.disputeGameFactoryProxy.setImplementation( + GameTypes.PERMISSIONED_CANNON, IDisputeGame(address(output.permissionedDisputeGame)) + ); + output.disputeGameFactoryProxy.setInitBond(GameTypes.PERMISSIONED_CANNON, 0.08 ether); + output.disputeGameFactoryProxy.transferOwnership(address(output.opChainProxyAdmin)); impl.logic = address(output.anchorStateRegistryImpl); impl.initializer = AnchorStateRegistry.initialize.selector; @@ -387,7 +413,11 @@ contract OPStackManager is ISemver, Initializable { _output; // TODO make GameTypes.CANNON an input once FPs are supported return abi.encodeWithSelector( - _selector, _output.disputeGameFactoryProxy, _output.systemConfigProxy, superchainConfig, GameTypes.CANNON + _selector, + _output.disputeGameFactoryProxy, + _output.systemConfigProxy, + superchainConfig, + GameTypes.PERMISSIONED_CANNON ); } @@ -463,14 +493,16 @@ contract OPStackManager is ISemver, Initializable { function encodeDisputeGameFactoryInitializer( bytes4 _selector, - DeployInput memory _input + DeployInput memory ) internal view virtual returns (bytes memory) { - return abi.encodeWithSelector(_selector, _input.roles.opChainProxyAdminOwner); + // This contract must be the initial owner so we can set game implementations, then + // ownership is transferred after. + return abi.encodeWithSelector(_selector, address(this)); } function encodeAnchorStateRegistryInitializer( @@ -488,6 +520,43 @@ contract OPStackManager is ISemver, Initializable { return abi.encodeWithSelector(_selector, startingAnchorRoots, superchainConfig); } + function encodeDelayedWETHInitializer( + bytes4 _selector, + DeployInput memory _input + ) + internal + view + virtual + returns (bytes memory) + { + return abi.encodeWithSelector(_selector, _input.roles.opChainProxyAdminOwner, superchainConfig); + } + + function encodePermissionedDisputeGameConstructor( + DeployInput memory _input, + DeployOutput memory _output + ) + internal + view + virtual + returns (bytes memory) + { + return abi.encode( + GameType.wrap(1), // Permissioned Cannon + Claim.wrap(bytes32(hex"dead")), // absolutePrestate + 73, // maxGameDepth + 30, // splitDepth + Duration.wrap(3 hours), // clockExtension + Duration.wrap(3.5 days), // maxClockDuration + IBigStepper(getLatestImplementation("MIPS").logic), + IDelayedWETH(payable(address(_output.delayedWETHPermissionedGameProxy))), + IAnchorStateRegistry(address(_output.anchorStateRegistryProxy)), + _input.l2ChainId, + _input.roles.proposer, + _input.roles.challenger + ); + } + /// @notice Returns default, standard config arguments for the SystemConfig initializer. /// This is used by subclasses to reduce code duplication. function defaultSystemConfigParams( diff --git a/packages/contracts-bedrock/src/libraries/Blueprint.sol b/packages/contracts-bedrock/src/libraries/Blueprint.sol index 2e0979e1c6bf..a7ddf1f9009b 100644 --- a/packages/contracts-bedrock/src/libraries/Blueprint.sol +++ b/packages/contracts-bedrock/src/libraries/Blueprint.sol @@ -20,6 +20,9 @@ library Blueprint { /// @notice Thrown when parsing a blueprint preamble and the resulting initcode is empty. error EmptyInitcode(); + /// @notice Thrown when call to the identity precompile fails. + error IdentityPrecompileCallFailed(); + /// @notice Thrown when parsing a blueprint preamble and the bytecode does not contain the expected prefix bytes. error NotABlueprint(); @@ -56,7 +59,7 @@ library Blueprint { /// @notice Given bytecode as a sequence of bytes, parse the blueprint preamble and deconstruct /// the bytecode into the ERC version, preamble data and initcode. Reverts if the bytecode is /// not a valid blueprint contract according to ERC-5202. - function parseBlueprintPreamble(bytes memory _bytecode) internal pure returns (Preamble memory) { + function parseBlueprintPreamble(bytes memory _bytecode) internal view returns (Preamble memory) { if (_bytecode.length < 2 || _bytecode[0] != 0xFE || _bytecode[1] != 0x71) { revert NotABlueprint(); } @@ -77,18 +80,34 @@ library Blueprint { bytes memory preambleData = new bytes(dataLength); if (nLengthBytes != 0) { uint256 dataStart = 3 + nLengthBytes; + // This loop is very small, so not worth using the identity precompile like we do with initcode below. for (uint256 i = 0; i < dataLength; i++) { preambleData[i] = _bytecode[dataStart + i]; } } + // Parsing the initcode byte-by-byte is too costly for long initcode, so we perform a staticcall + // to the identity precompile at address(0x04) to copy the initcode. uint256 initcodeStart = 3 + nLengthBytes + dataLength; - bytes memory initcode = new bytes(_bytecode.length - initcodeStart); - for (uint256 i = 0; i < initcode.length; i++) { - initcode[i] = _bytecode[initcodeStart + i]; + uint256 initcodeLength = _bytecode.length - initcodeStart; + if (initcodeLength == 0) revert EmptyInitcode(); + + bytes memory initcode = new bytes(initcodeLength); + bool success; + assembly ("memory-safe") { + // Calculate the memory address of the input data (initcode) within _bytecode. + // - add(_bytecode, 32): Moves past the length field to the start of _bytecode's data. + // - add(..., initcodeStart): Adds the offset to reach the initcode within _bytecode. + let inputData := add(add(_bytecode, 32), initcodeStart) + + // Calculate the memory address for the output data in initcode. + let outputData := add(initcode, 32) + + // Perform the staticcall to the identity precompile. + success := staticcall(gas(), 0x04, inputData, initcodeLength, outputData, initcodeLength) } - if (initcode.length == 0) revert EmptyInitcode(); + if (!success) revert IdentityPrecompileCallFailed(); return Preamble(ercVersion, preambleData, initcode); } @@ -112,6 +131,32 @@ library Blueprint { if (newContract_ == address(0)) revert DeploymentFailed(); } + /// @notice Parses the code at two target addresses as individual blueprints, concatentates them and then deploys + /// the resulting initcode with the given `_data` appended, i.e. `_data` is the ABI-encoded constructor arguments. + function deployFrom( + address _target1, + address _target2, + bytes32 _salt, + bytes memory _data + ) + internal + returns (address newContract_) + { + Preamble memory preamble1 = parseBlueprintPreamble(address(_target1).code); + if (preamble1.ercVersion != 0) revert UnsupportedERCVersion(preamble1.ercVersion); + if (preamble1.preambleData.length != 0) revert UnexpectedPreambleData(preamble1.preambleData); + + Preamble memory preamble2 = parseBlueprintPreamble(address(_target2).code); + if (preamble2.ercVersion != 0) revert UnsupportedERCVersion(preamble2.ercVersion); + if (preamble2.preambleData.length != 0) revert UnexpectedPreambleData(preamble2.preambleData); + + bytes memory initcode = bytes.concat(preamble1.initcode, preamble2.initcode, _data); + assembly ("memory-safe") { + newContract_ := create2(0, add(initcode, 0x20), mload(initcode), _salt) + } + if (newContract_ == address(0)) revert DeploymentFailed(); + } + /// @notice Convert a bytes array to a uint256. function bytesToUint(bytes memory _b) internal pure returns (uint256) { if (_b.length > 32) revert BytesArrayTooLong(); diff --git a/packages/contracts-bedrock/test/libraries/Blueprint.t.sol b/packages/contracts-bedrock/test/libraries/Blueprint.t.sol index 94a30ab99fb0..c94616a88e4f 100644 --- a/packages/contracts-bedrock/test/libraries/Blueprint.t.sol +++ b/packages/contracts-bedrock/test/libraries/Blueprint.t.sol @@ -22,7 +22,7 @@ contract BlueprintHarness { return Blueprint.blueprintDeployerBytecode(_initcode); } - function parseBlueprintPreamble(bytes memory _bytecode) public pure returns (Blueprint.Preamble memory) { + function parseBlueprintPreamble(bytes memory _bytecode) public view returns (Blueprint.Preamble memory) { return Blueprint.parseBlueprintPreamble(_bytecode); } From 43224ed7b8c8ad9d1f2fea3fe3fffd5d83a6943f Mon Sep 17 00:00:00 2001 From: Sam Stokes <35908605+bitwiseguy@users.noreply.github.com> Date: Tue, 24 Sep 2024 12:07:30 -0400 Subject: [PATCH 244/264] op-service: remove test print statement (#12083) --- op-service/client/lazy_dial.go | 1 - 1 file changed, 1 deletion(-) diff --git a/op-service/client/lazy_dial.go b/op-service/client/lazy_dial.go index 9a4e7cf6d872..9064fbe1fe09 100644 --- a/op-service/client/lazy_dial.go +++ b/op-service/client/lazy_dial.go @@ -66,7 +66,6 @@ func (l *LazyRPC) CallContext(ctx context.Context, result any, method string, ar if err := l.dial(ctx); err != nil { return err } - fmt.Println("checkpoin 1") return l.inner.CallContext(ctx, result, method, args...) } From 8b7693137fde7e31a350d6c794ab99d2d9e58910 Mon Sep 17 00:00:00 2001 From: Blaine Malone <blainemalone01@gmail.com> Date: Tue, 24 Sep 2024 13:39:50 -0400 Subject: [PATCH 245/264] feat: Implement release-based contract deployment (#12035) * forge install: superchain-registry v0.1.2 * fix: better clarity around when we're in a broadcast context. --- op-chain-ops/Makefile | 6 +- .../deployer/integration_test/apply_test.go | 1 + op-chain-ops/deployer/opsm/implementations.go | 2 + .../deployer/opsm/standard-versions.toml | 47 ++ op-chain-ops/deployer/opsm/standard.go | 8 + .../deployer/pipeline/implementations.go | 3 +- op-chain-ops/deployer/state/intent.go | 2 + op-chain-ops/interopgen/configs.go | 2 + op-chain-ops/interopgen/deploy.go | 1 + op-chain-ops/interopgen/deployments.go | 1 + op-chain-ops/interopgen/recipe.go | 7 +- op-chain-ops/script/cheatcodes_utilities.go | 75 +++ .../script/cheatcodes_utilities_test.go | 59 +++ packages/contracts-bedrock/.testdata/.gitkeep | 0 .../scripts/DeployImplementations.s.sol | 440 ++++++++++++++---- .../test/DeployImplementations.t.sol | 144 +++++- .../test/DeployOPChain.t.sol | 7 +- .../test/fixtures/standard-versions.toml | 47 ++ .../fixtures/test-deploy-auth-system-in.toml | 11 - .../fixtures/test-deploy-auth-system-out.toml | 1 - .../fixtures/test-deploy-superchain-in.toml | 8 - .../fixtures/test-deploy-superchain-out.toml | 5 - 22 files changed, 748 insertions(+), 129 deletions(-) create mode 100644 op-chain-ops/deployer/opsm/standard-versions.toml create mode 100644 op-chain-ops/deployer/opsm/standard.go create mode 100644 op-chain-ops/script/cheatcodes_utilities_test.go delete mode 100644 packages/contracts-bedrock/.testdata/.gitkeep create mode 100644 packages/contracts-bedrock/test/fixtures/standard-versions.toml delete mode 100644 packages/contracts-bedrock/test/fixtures/test-deploy-auth-system-in.toml delete mode 100644 packages/contracts-bedrock/test/fixtures/test-deploy-auth-system-out.toml delete mode 100644 packages/contracts-bedrock/test/fixtures/test-deploy-superchain-in.toml delete mode 100644 packages/contracts-bedrock/test/fixtures/test-deploy-superchain-out.toml diff --git a/op-chain-ops/Makefile b/op-chain-ops/Makefile index 630167f7b60e..262a989bc465 100644 --- a/op-chain-ops/Makefile +++ b/op-chain-ops/Makefile @@ -44,4 +44,8 @@ fuzz: go test $(FUZZLDFLAGS) -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzAliasing ./crossdomain go test $(FUZZLDFLAGS) -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzVersionedNonce ./crossdomain -.PHONY: test fuzz op-deployer \ No newline at end of file + +sync-standard-version: + curl -Lo ./deployer/opsm/standard-versions.toml https://raw.githubusercontent.com/ethereum-optimism/superchain-registry/refs/heads/main/validation/standard/standard-versions.toml + +.PHONY: test fuzz op-deployer sync-standard-version \ No newline at end of file diff --git a/op-chain-ops/deployer/integration_test/apply_test.go b/op-chain-ops/deployer/integration_test/apply_test.go index b69595b67761..f3bcd5b3e4bd 100644 --- a/op-chain-ops/deployer/integration_test/apply_test.go +++ b/op-chain-ops/deployer/integration_test/apply_test.go @@ -115,6 +115,7 @@ func TestEndToEndApply(t *testing.T) { UseFaultProofs: true, FundDevAccounts: true, ContractArtifactsURL: (*state.ArtifactsURL)(artifactsURL), + ContractsRelease: "dev", Chains: []*state.ChainIntent{ { ID: id.Bytes32(), diff --git a/op-chain-ops/deployer/opsm/implementations.go b/op-chain-ops/deployer/opsm/implementations.go index ed20b55f1522..d60330440abc 100644 --- a/op-chain-ops/deployer/opsm/implementations.go +++ b/op-chain-ops/deployer/opsm/implementations.go @@ -23,6 +23,7 @@ type DeployImplementationsInput struct { UseInterop bool // if true, deploy Interop implementations SuperchainProxyAdmin common.Address + StandardVersionsToml string // contents of 'standard-versions.toml' file } func (input *DeployImplementationsInput) InputSet() bool { @@ -31,6 +32,7 @@ func (input *DeployImplementationsInput) InputSet() bool { type DeployImplementationsOutput struct { OpsmProxy common.Address + OpsmImpl common.Address DelayedWETHImpl common.Address OptimismPortalImpl common.Address PreimageOracleSingleton common.Address diff --git a/op-chain-ops/deployer/opsm/standard-versions.toml b/op-chain-ops/deployer/opsm/standard-versions.toml new file mode 100644 index 000000000000..cb4d336a7336 --- /dev/null +++ b/op-chain-ops/deployer/opsm/standard-versions.toml @@ -0,0 +1,47 @@ +standard_release = "op-contracts/v1.6.0" + +[releases] + +# Contracts which are +# * unproxied singletons: specify a standard "address" +# * proxied : specify a standard "implementation_address" +# * neither : specify neither a standard "address" nor "implementation_address" + +# Fault Proofs https://github.com/ethereum-optimism/optimism/releases/tag/op-contracts%2Fv1.6.0 +[releases."op-contracts/v1.6.0"] +optimism_portal = { version = "3.10.0", implementation_address = "0xe2F826324b2faf99E513D16D266c3F80aE87832B" } +system_config = { version = "2.2.0", implementation_address = "0xF56D96B2535B932656d3c04Ebf51baBff241D886" } +anchor_state_registry = { version = "2.0.0" } +delayed_weth = { version = "1.1.0", implementation_address = "0x71e966Ae981d1ce531a7b6d23DC0f27B38409087" } +dispute_game_factory = { version = "1.0.0", implementation_address = "0xc641A33cab81C559F2bd4b21EA34C290E2440C2B" } +fault_dispute_game = { version = "1.3.0" } +permissioned_dispute_game = { version = "1.3.0" } +mips = { version = "1.1.0", address = "0x16e83cE5Ce29BF90AD9Da06D2fE6a15d5f344ce4" } +preimage_oracle = { version = "1.1.2", address = "0x9c065e11870B891D214Bc2Da7EF1f9DDFA1BE277" } +l1_cross_domain_messenger = { version = "2.3.0", implementation_address = "0xD3494713A5cfaD3F5359379DfA074E2Ac8C6Fd65" } +l1_erc721_bridge = { version = "2.1.0", implementation_address = "0xAE2AF01232a6c4a4d3012C5eC5b1b35059caF10d" } +l1_standard_bridge = { version = "2.1.0", implementation_address = "0x64B5a5Ed26DCb17370Ff4d33a8D503f0fbD06CfF" } +# l2_output_oracle -- This contract not used in fault proofs +optimism_mintable_erc20_factory = { version = "1.9.0", implementation_address = "0xE01efbeb1089D1d1dB9c6c8b135C934C0734c846" } + +# Fault Proofs https://github.com/ethereum-optimism/optimism/releases/tag/op-contracts%2Fv1.4.0 +[releases."op-contracts/v1.4.0"] +optimism_portal = { version = "3.10.0", implementation_address = "0xe2F826324b2faf99E513D16D266c3F80aE87832B" } +system_config = { version = "2.2.0", implementation_address = "0xF56D96B2535B932656d3c04Ebf51baBff241D886" } +anchor_state_registry = { version = "1.0.0" } +delayed_weth = { version = "1.0.0", implementation_address = "0x97988d5624F1ba266E1da305117BCf20713bee08" } +dispute_game_factory = { version = "1.0.0", implementation_address = "0xc641A33cab81C559F2bd4b21EA34C290E2440C2B" } +fault_dispute_game = { version = "1.2.0" } +permissioned_dispute_game = { version = "1.2.0" } +mips = { version = "1.0.1", address = "0x0f8EdFbDdD3c0256A80AD8C0F2560B1807873C9c" } +preimage_oracle = { version = "1.0.0", address = "0xD326E10B8186e90F4E2adc5c13a2d0C137ee8b34" } + +# MCP https://github.com/ethereum-optimism/optimism/releases/tag/op-contracts%2Fv1.3.0 +[releases."op-contracts/v1.3.0"] +l1_cross_domain_messenger = { version = "2.3.0", implementation_address = "0xD3494713A5cfaD3F5359379DfA074E2Ac8C6Fd65" } +l1_erc721_bridge = { version = "2.1.0", implementation_address = "0xAE2AF01232a6c4a4d3012C5eC5b1b35059caF10d" } +l1_standard_bridge = { version = "2.1.0", implementation_address = "0x64B5a5Ed26DCb17370Ff4d33a8D503f0fbD06CfF" } +l2_output_oracle = { version = "1.8.0", implementation_address = "0xF243BEd163251380e78068d317ae10f26042B292" } +optimism_mintable_erc20_factory = { version = "1.9.0", implementation_address = "0xE01efbeb1089D1d1dB9c6c8b135C934C0734c846" } +optimism_portal = { version = "2.5.0", implementation_address = "0x2D778797049FE9259d947D1ED8e5442226dFB589" } +system_config = { version = "1.12.0", implementation_address = "0xba2492e52F45651B60B8B38d4Ea5E2390C64Ffb1" } diff --git a/op-chain-ops/deployer/opsm/standard.go b/op-chain-ops/deployer/opsm/standard.go new file mode 100644 index 000000000000..56f0d7ada37b --- /dev/null +++ b/op-chain-ops/deployer/opsm/standard.go @@ -0,0 +1,8 @@ +package opsm + +import "embed" + +//go:embed standard-versions.toml +var StandardVersionsData string + +var _ embed.FS diff --git a/op-chain-ops/deployer/pipeline/implementations.go b/op-chain-ops/deployer/pipeline/implementations.go index f9e125e4150b..0dcda8feea19 100644 --- a/op-chain-ops/deployer/pipeline/implementations.go +++ b/op-chain-ops/deployer/pipeline/implementations.go @@ -46,10 +46,11 @@ func DeployImplementations(ctx context.Context, env *Env, artifactsFS foundry.St ChallengePeriodSeconds: big.NewInt(86400), ProofMaturityDelaySeconds: big.NewInt(604800), DisputeGameFinalityDelaySeconds: big.NewInt(302400), - Release: "op-contracts/v1.6.0", + Release: intent.ContractsRelease, SuperchainConfigProxy: st.SuperchainDeployment.SuperchainConfigProxyAddress, ProtocolVersionsProxy: st.SuperchainDeployment.ProtocolVersionsProxyAddress, SuperchainProxyAdmin: st.SuperchainDeployment.ProxyAdminAddress, + StandardVersionsToml: opsm.StandardVersionsData, UseInterop: false, }, ) diff --git a/op-chain-ops/deployer/state/intent.go b/op-chain-ops/deployer/state/intent.go index c737dab37dd0..17bedacd77b5 100644 --- a/op-chain-ops/deployer/state/intent.go +++ b/op-chain-ops/deployer/state/intent.go @@ -24,6 +24,8 @@ type Intent struct { ContractArtifactsURL *ArtifactsURL `json:"contractArtifactsURL" toml:"contractArtifactsURL"` + ContractsRelease string `json:"contractsVersion" toml:"contractsVersion"` + Chains []*ChainIntent `json:"chains" toml:"chains"` GlobalDeployOverrides map[string]any `json:"globalDeployOverrides" toml:"globalDeployOverrides"` diff --git a/op-chain-ops/interopgen/configs.go b/op-chain-ops/interopgen/configs.go index 0bc939ec0351..9abe9880fe8b 100644 --- a/op-chain-ops/interopgen/configs.go +++ b/op-chain-ops/interopgen/configs.go @@ -39,6 +39,8 @@ type OPSMImplementationsConfig struct { FaultProof SuperFaultProofConfig UseInterop bool // to deploy Interop implementation contracts, instead of the regular ones. + + StandardVersionsToml string // serialized string of superchain-registry 'standard-versions.toml' file } type SuperchainConfig struct { diff --git a/op-chain-ops/interopgen/deploy.go b/op-chain-ops/interopgen/deploy.go index fde7485e04da..9da41e9894d8 100644 --- a/op-chain-ops/interopgen/deploy.go +++ b/op-chain-ops/interopgen/deploy.go @@ -172,6 +172,7 @@ func deploySuperchainToL1(l1Host *script.Host, superCfg *SuperchainConfig) (*Sup ProtocolVersionsProxy: superDeployment.ProtocolVersionsProxy, SuperchainProxyAdmin: superDeployment.SuperchainProxyAdmin, UseInterop: superCfg.Implementations.UseInterop, + StandardVersionsToml: opsm.StandardVersionsData, }) if err != nil { return nil, fmt.Errorf("failed to deploy Implementations contracts: %w", err) diff --git a/op-chain-ops/interopgen/deployments.go b/op-chain-ops/interopgen/deployments.go index 5b54c2286f9a..b6bb124d8e85 100644 --- a/op-chain-ops/interopgen/deployments.go +++ b/op-chain-ops/interopgen/deployments.go @@ -10,6 +10,7 @@ type L1Deployment struct { type Implementations struct { OpsmProxy common.Address `json:"OPSMProxy"` + OpsmImpl common.Address `json:"OPSMImpl"` DelayedWETHImpl common.Address `json:"DelayedWETHImpl"` OptimismPortalImpl common.Address `json:"OptimismPortalImpl"` PreimageOracleSingleton common.Address `json:"PreimageOracleSingleton"` diff --git a/op-chain-ops/interopgen/recipe.go b/op-chain-ops/interopgen/recipe.go index a1761f9f0dc8..4dbe58e4ca1f 100644 --- a/op-chain-ops/interopgen/recipe.go +++ b/op-chain-ops/interopgen/recipe.go @@ -8,6 +8,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opsm" "github.com/ethereum-optimism/optimism/op-chain-ops/devkeys" "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" ) @@ -61,12 +62,13 @@ func (r *InteropDevRecipe) Build(addrs devkeys.Addresses) (*WorldConfig, error) l1Cfg.Prefund[superchainDeployer] = Ether(10_000_000) l1Cfg.Prefund[superchainProxyAdmin] = Ether(10_000_000) l1Cfg.Prefund[superchainConfigGuardian] = Ether(10_000_000) + superchainCfg := &SuperchainConfig{ ProxyAdminOwner: superchainProxyAdmin, ProtocolVersionsOwner: superchainProtocolVersionsOwner, Deployer: superchainDeployer, Implementations: OPSMImplementationsConfig{ - Release: "op-contracts/0.0.1", + Release: "dev", FaultProof: SuperFaultProofConfig{ WithdrawalDelaySeconds: big.NewInt(604800), MinProposalSizeBytes: big.NewInt(10000), @@ -74,7 +76,8 @@ func (r *InteropDevRecipe) Build(addrs devkeys.Addresses) (*WorldConfig, error) ProofMaturityDelaySeconds: big.NewInt(12), DisputeGameFinalityDelaySeconds: big.NewInt(6), }, - UseInterop: true, + UseInterop: true, + StandardVersionsToml: opsm.StandardVersionsData, }, SuperchainL1DeployConfig: genesis.SuperchainL1DeployConfig{ RequiredProtocolVersion: params.OPStackSupport, diff --git a/op-chain-ops/script/cheatcodes_utilities.go b/op-chain-ops/script/cheatcodes_utilities.go index 2ae53a52e910..022befa60627 100644 --- a/op-chain-ops/script/cheatcodes_utilities.go +++ b/op-chain-ops/script/cheatcodes_utilities.go @@ -3,9 +3,12 @@ package script import ( "fmt" "math/big" + "regexp" "strconv" "strings" + "github.com/BurntSushi/toml" + hdwallet "github.com/ethereum-optimism/go-ethereum-hdwallet" "github.com/ethereum/go-ethereum/accounts" @@ -188,5 +191,77 @@ func (c *CheatCodesPrecompile) Breakpoint_f7d39a8d(name string, v bool) { } } +// ParseTomlAddress_65e7c844 implements https://book.getfoundry.sh/cheatcodes/parse-toml. This +// method is not well optimized or implemented. It's optimized for quickly delivering OPCM. We +// can come back and clean it up more later. +func (c *CheatCodesPrecompile) ParseTomlAddress_65e7c844(tomlStr string, key string) (common.Address, error) { + var data map[string]any + if err := toml.Unmarshal([]byte(tomlStr), &data); err != nil { + return common.Address{}, fmt.Errorf("failed to parse TOML: %w", err) + } + + keys, err := SplitJSONPathKeys(key) + if err != nil { + return common.Address{}, fmt.Errorf("failed to split keys: %w", err) + } + + loc := data + for i, k := range keys { + value, ok := loc[k] + if !ok { + return common.Address{}, fmt.Errorf("key %q not found in TOML", k) + } + + if i == len(keys)-1 { + addrStr, ok := value.(string) + if !ok { + return common.Address{}, fmt.Errorf("key %q is not a string", key) + } + if !common.IsHexAddress(addrStr) { + return common.Address{}, fmt.Errorf("key %q is not a valid address", key) + } + return common.HexToAddress(addrStr), nil + } + + next, ok := value.(map[string]any) + if !ok { + return common.Address{}, fmt.Errorf("key %q is not a nested map", key) + } + loc = next + } + + panic("should never get here") +} + // unsupported //func (c *CheatCodesPrecompile) CreateWallet() {} + +// SplitJSONPathKeys splits a JSON path into keys. It supports bracket notation. There is a much +// better way to implement this, but I'm keeping this simple for now. +func SplitJSONPathKeys(path string) ([]string, error) { + var out []string + bracketSplit := regexp.MustCompile(`[\[\]]`).Split(path, -1) + for _, split := range bracketSplit { + if len(split) == 0 { + continue + } + + split = strings.ReplaceAll(split, "\"", "") + split = strings.ReplaceAll(split, " ", "") + + if !strings.HasPrefix(split, ".") { + out = append(out, split) + continue + } + + keys := strings.Split(split, ".") + for _, key := range keys { + if len(key) == 0 { + continue + } + out = append(out, key) + } + } + + return out, nil +} diff --git a/op-chain-ops/script/cheatcodes_utilities_test.go b/op-chain-ops/script/cheatcodes_utilities_test.go new file mode 100644 index 000000000000..23936a10e344 --- /dev/null +++ b/op-chain-ops/script/cheatcodes_utilities_test.go @@ -0,0 +1,59 @@ +package script + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +const tomlTest = ` +foo = "0x0d4CE7B6a91A35c31D7D62b327D19617c8da6F23" + +[foomap] +[foomap."bar.bump"] +baz = "0xff4ce7b6a91a35c31d7d62b327d19617c8da6f23" +` + +func TestSplitJSONPathKeys(t *testing.T) { + tests := []struct { + name string + path string + expected []string + }{ + { + "simple", + ".foo.bar", + []string{"foo", "bar"}, + }, + { + "bracket keys", + ".foo[\"hey\"].bar", + []string{"foo", "hey", "bar"}, + }, + { + "bracket keys with dots", + ".foo[\"hey.there\"].bar", + []string{"foo", "hey.there", "bar"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := SplitJSONPathKeys(tt.path) + require.NoError(t, err) + require.Equal(t, tt.expected, got) + }) + } +} + +func TestParseTomlAddress(t *testing.T) { + c := &CheatCodesPrecompile{} + + addr, err := c.ParseTomlAddress_65e7c844(tomlTest, "foo") + require.NoError(t, err) + require.Equal(t, common.HexToAddress("0x0d4ce7b6a91a35c31d7d62b327d19617c8da6f23"), addr) + + addr, err = c.ParseTomlAddress_65e7c844(tomlTest, "foomap[\"bar.bump\"].baz") + require.NoError(t, err) + require.Equal(t, common.HexToAddress("0xff4ce7b6a91a35c31d7d62b327d19617c8da6f23"), addr) +} diff --git a/packages/contracts-bedrock/.testdata/.gitkeep b/packages/contracts-bedrock/.testdata/.gitkeep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol index 81cafa89c272..df950fed71f2 100644 --- a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol +++ b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol @@ -62,6 +62,8 @@ contract DeployImplementationsInput is BaseDeployIO { SuperchainConfig internal _superchainConfigProxy; ProtocolVersions internal _protocolVersionsProxy; + string internal _standardVersionsToml; + function set(bytes4 sel, uint256 _value) public { require(_value != 0, "DeployImplementationsInput: cannot set zero value"); @@ -84,6 +86,7 @@ contract DeployImplementationsInput is BaseDeployIO { function set(bytes4 sel, string memory _value) public { require(!LibString.eq(_value, ""), "DeployImplementationsInput: cannot set empty string"); if (sel == this.release.selector) _release = _value; + else if (sel == this.standardVersionsToml.selector) _standardVersionsToml = _value; else revert("DeployImplementationsInput: unknown selector"); } @@ -137,6 +140,11 @@ contract DeployImplementationsInput is BaseDeployIO { return _release; } + function standardVersionsToml() public view returns (string memory) { + require(!LibString.eq(_standardVersionsToml, ""), "DeployImplementationsInput: not set"); + return _standardVersionsToml; + } + function superchainConfigProxy() public view returns (SuperchainConfig) { require(address(_superchainConfigProxy) != address(0), "DeployImplementationsInput: not set"); return _superchainConfigProxy; @@ -159,6 +167,7 @@ contract DeployImplementationsInput is BaseDeployIO { contract DeployImplementationsOutput is BaseDeployIO { OPStackManager internal _opsmProxy; + OPStackManager internal _opsmImpl; DelayedWETH internal _delayedWETHImpl; OptimismPortal2 internal _optimismPortalImpl; PreimageOracle internal _preimageOracleSingleton; @@ -175,6 +184,7 @@ contract DeployImplementationsOutput is BaseDeployIO { // forgefmt: disable-start if (sel == this.opsmProxy.selector) _opsmProxy = OPStackManager(payable(_addr)); + else if (sel == this.opsmImpl.selector) _opsmImpl = OPStackManager(payable(_addr)); else if (sel == this.optimismPortalImpl.selector) _optimismPortalImpl = OptimismPortal2(payable(_addr)); else if (sel == this.delayedWETHImpl.selector) _delayedWETHImpl = DelayedWETH(payable(_addr)); else if (sel == this.preimageOracleSingleton.selector) _preimageOracleSingleton = PreimageOracle(_addr); @@ -190,12 +200,18 @@ contract DeployImplementationsOutput is BaseDeployIO { } function checkOutput(DeployImplementationsInput _dii) public { - address[] memory addrs = Solarray.addresses( + // With 12 addresses, we'd get a stack too deep error if we tried to do this inline as a + // single call to `Solarray.addresses`. So we split it into two calls. + address[] memory addrs1 = Solarray.addresses( address(this.opsmProxy()), + address(this.opsmImpl()), address(this.optimismPortalImpl()), address(this.delayedWETHImpl()), address(this.preimageOracleSingleton()), - address(this.mipsSingleton()), + address(this.mipsSingleton()) + ); + + address[] memory addrs2 = Solarray.addresses( address(this.systemConfigImpl()), address(this.l1CrossDomainMessengerImpl()), address(this.l1ERC721BridgeImpl()), @@ -203,7 +219,8 @@ contract DeployImplementationsOutput is BaseDeployIO { address(this.optimismMintableERC20FactoryImpl()), address(this.disputeGameFactoryImpl()) ); - DeployUtils.assertValidContractAddresses(addrs); + + DeployUtils.assertValidContractAddresses(Solarray.extend(addrs1, addrs2)); assertValidDeploy(_dii); } @@ -214,6 +231,11 @@ contract DeployImplementationsOutput is BaseDeployIO { return _opsmProxy; } + function opsmImpl() public view returns (OPStackManager) { + DeployUtils.assertValidContractAddress(address(_opsmImpl)); + return _opsmImpl; + } + function optimismPortalImpl() public view returns (OptimismPortal2) { DeployUtils.assertValidContractAddress(address(_optimismPortalImpl)); return _optimismPortalImpl; @@ -474,26 +496,30 @@ contract DeployImplementations is Script { // Deploy and initialize a proxied OPStackManager. function createOPSMContract( DeployImplementationsInput _dii, - DeployImplementationsOutput, - OPStackManager.Blueprints memory blueprints, - string memory release, - OPStackManager.ImplementationSetter[] memory setters + DeployImplementationsOutput _dio, + OPStackManager.Blueprints memory _blueprints, + string memory _release, + OPStackManager.ImplementationSetter[] memory _setters ) internal virtual returns (OPStackManager opsmProxy_) { - SuperchainConfig superchainConfigProxy = _dii.superchainConfigProxy(); - ProtocolVersions protocolVersionsProxy = _dii.protocolVersionsProxy(); ProxyAdmin proxyAdmin = _dii.superchainProxyAdmin(); - vm.startBroadcast(msg.sender); + vm.broadcast(msg.sender); Proxy proxy = new Proxy(address(msg.sender)); - OPStackManager opsm = new OPStackManager(superchainConfigProxy, protocolVersionsProxy); + + deployOPContractsManagerImpl(_dii, _dio); + OPStackManager opsmImpl = _dio.opsmImpl(); OPStackManager.InitializerInputs memory initializerInputs = - OPStackManager.InitializerInputs(blueprints, setters, release, true); - proxy.upgradeToAndCall(address(opsm), abi.encodeWithSelector(opsm.initialize.selector, initializerInputs)); + OPStackManager.InitializerInputs(_blueprints, _setters, _release, true); + + vm.startBroadcast(msg.sender); + proxy.upgradeToAndCall( + address(opsmImpl), abi.encodeWithSelector(opsmImpl.initialize.selector, initializerInputs) + ); proxy.changeAdmin(address(proxyAdmin)); // transfer ownership of Proxy contract to the ProxyAdmin contract vm.stopBroadcast(); @@ -572,56 +598,148 @@ contract DeployImplementations is Script { // --- Core Contracts --- - function deploySystemConfigImpl(DeployImplementationsInput, DeployImplementationsOutput _dio) public virtual { - vm.broadcast(msg.sender); - SystemConfig systemConfigImpl = new SystemConfig(); + function deploySystemConfigImpl(DeployImplementationsInput _dii, DeployImplementationsOutput _dio) public virtual { + string memory release = _dii.release(); + string memory stdVerToml = _dii.standardVersionsToml(); + // Using snake case for contract name to match the TOML file in superchain-registry. + string memory contractName = "system_config"; + SystemConfig impl; + + address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); + if (existingImplementation != address(0)) { + impl = SystemConfig(existingImplementation); + } else if (isDevelopRelease(release)) { + // Deploy a new implementation for development builds. + vm.broadcast(msg.sender); + impl = new SystemConfig(); + } else { + revert(string.concat("DeployImplementations: failed to deploy release ", release)); + } - vm.label(address(systemConfigImpl), "SystemConfigImpl"); - _dio.set(_dio.systemConfigImpl.selector, address(systemConfigImpl)); + vm.label(address(impl), "SystemConfigImpl"); + _dio.set(_dio.systemConfigImpl.selector, address(impl)); } function deployL1CrossDomainMessengerImpl( - DeployImplementationsInput, + DeployImplementationsInput _dii, DeployImplementationsOutput _dio ) public virtual { - vm.broadcast(msg.sender); - L1CrossDomainMessenger l1CrossDomainMessengerImpl = new L1CrossDomainMessenger(); + string memory release = _dii.release(); + string memory stdVerToml = _dii.standardVersionsToml(); + string memory contractName = "l1_cross_domain_messenger"; + L1CrossDomainMessenger impl; + + address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); + if (existingImplementation != address(0)) { + impl = L1CrossDomainMessenger(existingImplementation); + } else if (isDevelopRelease(release)) { + vm.broadcast(msg.sender); + impl = new L1CrossDomainMessenger(); + } else { + revert(string.concat("DeployImplementations: failed to deploy release ", release)); + } - vm.label(address(l1CrossDomainMessengerImpl), "L1CrossDomainMessengerImpl"); - _dio.set(_dio.l1CrossDomainMessengerImpl.selector, address(l1CrossDomainMessengerImpl)); + vm.label(address(impl), "L1CrossDomainMessengerImpl"); + _dio.set(_dio.l1CrossDomainMessengerImpl.selector, address(impl)); } - function deployL1ERC721BridgeImpl(DeployImplementationsInput, DeployImplementationsOutput _dio) public virtual { - vm.broadcast(msg.sender); - L1ERC721Bridge l1ERC721BridgeImpl = new L1ERC721Bridge(); + function deployL1ERC721BridgeImpl( + DeployImplementationsInput _dii, + DeployImplementationsOutput _dio + ) + public + virtual + { + string memory release = _dii.release(); + string memory stdVerToml = _dii.standardVersionsToml(); + string memory contractName = "l1_erc721_bridge"; + L1ERC721Bridge impl; + + address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); + if (existingImplementation != address(0)) { + impl = L1ERC721Bridge(existingImplementation); + } else if (isDevelopRelease(release)) { + vm.broadcast(msg.sender); + impl = new L1ERC721Bridge(); + } else { + revert(string.concat("DeployImplementations: failed to deploy release ", release)); + } - vm.label(address(l1ERC721BridgeImpl), "L1ERC721BridgeImpl"); - _dio.set(_dio.l1ERC721BridgeImpl.selector, address(l1ERC721BridgeImpl)); + vm.label(address(impl), "L1ERC721BridgeImpl"); + _dio.set(_dio.l1ERC721BridgeImpl.selector, address(impl)); } - function deployL1StandardBridgeImpl(DeployImplementationsInput, DeployImplementationsOutput _dio) public virtual { - vm.broadcast(msg.sender); - L1StandardBridge l1StandardBridgeImpl = new L1StandardBridge(); + function deployL1StandardBridgeImpl( + DeployImplementationsInput _dii, + DeployImplementationsOutput _dio + ) + public + virtual + { + string memory release = _dii.release(); + string memory stdVerToml = _dii.standardVersionsToml(); + string memory contractName = "l1_standard_bridge"; + L1StandardBridge impl; + + address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); + if (existingImplementation != address(0)) { + impl = L1StandardBridge(payable(existingImplementation)); + } else if (isDevelopRelease(release)) { + vm.broadcast(msg.sender); + impl = new L1StandardBridge(); + } else { + revert(string.concat("DeployImplementations: failed to deploy release ", release)); + } - vm.label(address(l1StandardBridgeImpl), "L1StandardBridgeImpl"); - _dio.set(_dio.l1StandardBridgeImpl.selector, address(l1StandardBridgeImpl)); + vm.label(address(impl), "L1StandardBridgeImpl"); + _dio.set(_dio.l1StandardBridgeImpl.selector, address(impl)); } function deployOptimismMintableERC20FactoryImpl( - DeployImplementationsInput, + DeployImplementationsInput _dii, DeployImplementationsOutput _dio ) public virtual { + string memory release = _dii.release(); + string memory stdVerToml = _dii.standardVersionsToml(); + string memory contractName = "optimism_mintable_erc20_factory"; + OptimismMintableERC20Factory impl; + + address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); + if (existingImplementation != address(0)) { + impl = OptimismMintableERC20Factory(existingImplementation); + } else if (isDevelopRelease(release)) { + vm.broadcast(msg.sender); + impl = new OptimismMintableERC20Factory(); + } else { + revert(string.concat("DeployImplementations: failed to deploy release ", release)); + } + + vm.label(address(impl), "OptimismMintableERC20FactoryImpl"); + _dio.set(_dio.optimismMintableERC20FactoryImpl.selector, address(impl)); + } + + function deployOPContractsManagerImpl( + DeployImplementationsInput _dii, + DeployImplementationsOutput _dio + ) + public + virtual + { + SuperchainConfig superchainConfigProxy = _dii.superchainConfigProxy(); + ProtocolVersions protocolVersionsProxy = _dii.protocolVersionsProxy(); + vm.broadcast(msg.sender); - OptimismMintableERC20Factory optimismMintableERC20FactoryImpl = new OptimismMintableERC20Factory(); + // TODO: Eventually we will want to select the correct implementation based on the release. + OPStackManager impl = new OPStackManager(superchainConfigProxy, protocolVersionsProxy); - vm.label(address(optimismMintableERC20FactoryImpl), "OptimismMintableERC20FactoryImpl"); - _dio.set(_dio.optimismMintableERC20FactoryImpl.selector, address(optimismMintableERC20FactoryImpl)); + vm.label(address(impl), "OPStackManagerImpl"); + _dio.set(_dio.opsmImpl.selector, address(impl)); } // --- Fault Proofs Contracts --- @@ -659,27 +777,46 @@ contract DeployImplementations is Script { public virtual { - uint256 proofMaturityDelaySeconds = _dii.proofMaturityDelaySeconds(); - uint256 disputeGameFinalityDelaySeconds = _dii.disputeGameFinalityDelaySeconds(); - - vm.broadcast(msg.sender); - OptimismPortal2 optimismPortalImpl = new OptimismPortal2({ - _proofMaturityDelaySeconds: proofMaturityDelaySeconds, - _disputeGameFinalityDelaySeconds: disputeGameFinalityDelaySeconds - }); + string memory release = _dii.release(); + string memory stdVerToml = _dii.standardVersionsToml(); + string memory contractName = "optimism_portal"; + OptimismPortal2 impl; + + address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); + if (existingImplementation != address(0)) { + impl = OptimismPortal2(payable(existingImplementation)); + } else if (isDevelopRelease(release)) { + uint256 proofMaturityDelaySeconds = _dii.proofMaturityDelaySeconds(); + uint256 disputeGameFinalityDelaySeconds = _dii.disputeGameFinalityDelaySeconds(); + vm.broadcast(msg.sender); + impl = new OptimismPortal2(proofMaturityDelaySeconds, disputeGameFinalityDelaySeconds); + } else { + revert(string.concat("DeployImplementations: failed to deploy release ", release)); + } - vm.label(address(optimismPortalImpl), "OptimismPortalImpl"); - _dio.set(_dio.optimismPortalImpl.selector, address(optimismPortalImpl)); + vm.label(address(impl), "OptimismPortalImpl"); + _dio.set(_dio.optimismPortalImpl.selector, address(impl)); } function deployDelayedWETHImpl(DeployImplementationsInput _dii, DeployImplementationsOutput _dio) public virtual { - uint256 withdrawalDelaySeconds = _dii.withdrawalDelaySeconds(); - - vm.broadcast(msg.sender); - DelayedWETH delayedWETHImpl = new DelayedWETH({ _delay: withdrawalDelaySeconds }); + string memory release = _dii.release(); + string memory stdVerToml = _dii.standardVersionsToml(); + string memory contractName = "delayed_weth"; + DelayedWETH impl; + + address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); + if (existingImplementation != address(0)) { + impl = DelayedWETH(payable(existingImplementation)); + } else if (isDevelopRelease(release)) { + uint256 withdrawalDelaySeconds = _dii.withdrawalDelaySeconds(); + vm.broadcast(msg.sender); + impl = new DelayedWETH(withdrawalDelaySeconds); + } else { + revert(string.concat("DeployImplementations: failed to deploy release ", release)); + } - vm.label(address(delayedWETHImpl), "DelayedWETHImpl"); - _dio.set(_dio.delayedWETHImpl.selector, address(delayedWETHImpl)); + vm.label(address(impl), "DelayedWETHImpl"); + _dio.set(_dio.delayedWETHImpl.selector, address(impl)); } function deployPreimageOracleSingleton( @@ -689,39 +826,72 @@ contract DeployImplementations is Script { public virtual { - uint256 minProposalSizeBytes = _dii.minProposalSizeBytes(); - uint256 challengePeriodSeconds = _dii.challengePeriodSeconds(); - - vm.broadcast(msg.sender); - PreimageOracle preimageOracleSingleton = - new PreimageOracle({ _minProposalSize: minProposalSizeBytes, _challengePeriod: challengePeriodSeconds }); + string memory release = _dii.release(); + string memory stdVerToml = _dii.standardVersionsToml(); + string memory contractName = "preimage_oracle"; + PreimageOracle singleton; + + address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); + if (existingImplementation != address(0)) { + singleton = PreimageOracle(payable(existingImplementation)); + } else if (isDevelopRelease(release)) { + uint256 minProposalSizeBytes = _dii.minProposalSizeBytes(); + uint256 challengePeriodSeconds = _dii.challengePeriodSeconds(); + vm.broadcast(msg.sender); + singleton = new PreimageOracle(minProposalSizeBytes, challengePeriodSeconds); + } else { + revert(string.concat("DeployImplementations: failed to deploy release ", release)); + } - vm.label(address(preimageOracleSingleton), "PreimageOracleSingleton"); - _dio.set(_dio.preimageOracleSingleton.selector, address(preimageOracleSingleton)); + vm.label(address(singleton), "PreimageOracleSingleton"); + _dio.set(_dio.preimageOracleSingleton.selector, address(singleton)); } - function deployMipsSingleton(DeployImplementationsInput, DeployImplementationsOutput _dio) public virtual { - IPreimageOracle preimageOracle = IPreimageOracle(_dio.preimageOracleSingleton()); - - vm.broadcast(msg.sender); - MIPS mipsSingleton = new MIPS(preimageOracle); + function deployMipsSingleton(DeployImplementationsInput _dii, DeployImplementationsOutput _dio) public virtual { + string memory release = _dii.release(); + string memory stdVerToml = _dii.standardVersionsToml(); + string memory contractName = "mips"; + MIPS singleton; + + address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); + if (existingImplementation != address(0)) { + singleton = MIPS(payable(existingImplementation)); + } else if (isDevelopRelease(release)) { + IPreimageOracle preimageOracle = IPreimageOracle(_dio.preimageOracleSingleton()); + vm.broadcast(msg.sender); + singleton = new MIPS(preimageOracle); + } else { + revert(string.concat("DeployImplementations: failed to deploy release ", release)); + } - vm.label(address(mipsSingleton), "MIPSSingleton"); - _dio.set(_dio.mipsSingleton.selector, address(mipsSingleton)); + vm.label(address(singleton), "MIPSSingleton"); + _dio.set(_dio.mipsSingleton.selector, address(singleton)); } function deployDisputeGameFactoryImpl( - DeployImplementationsInput, + DeployImplementationsInput _dii, DeployImplementationsOutput _dio ) public virtual { - vm.broadcast(msg.sender); - DisputeGameFactory disputeGameFactoryImpl = new DisputeGameFactory(); + string memory release = _dii.release(); + string memory stdVerToml = _dii.standardVersionsToml(); + string memory contractName = "dispute_game_factory"; + DisputeGameFactory impl; + + address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); + if (existingImplementation != address(0)) { + impl = DisputeGameFactory(payable(existingImplementation)); + } else if (isDevelopRelease(release)) { + vm.broadcast(msg.sender); + impl = new DisputeGameFactory(); + } else { + revert(string.concat("DeployImplementations: failed to deploy release ", release)); + } - vm.label(address(disputeGameFactoryImpl), "DisputeGameFactoryImpl"); - _dio.set(_dio.disputeGameFactoryImpl.selector, address(disputeGameFactoryImpl)); + vm.label(address(impl), "DisputeGameFactoryImpl"); + _dio.set(_dio.disputeGameFactoryImpl.selector, address(impl)); } // -------- Utilities -------- @@ -763,6 +933,35 @@ contract DeployImplementations is Script { newContract1_ = deployBytecode(part1, _salt); newContract2_ = deployBytecode(part2, _salt); } + + // Zero address is returned if the address is not found in '_standardVersionsToml'. + function getReleaseAddress( + string memory _version, + string memory _contractName, + string memory _standardVersionsToml + ) + internal + pure + returns (address addr_) + { + string memory baseKey = string.concat('.releases["', _version, '"].', _contractName); + string memory implAddressKey = string.concat(baseKey, ".implementation_address"); + string memory addressKey = string.concat(baseKey, ".address"); + try vm.parseTomlAddress(_standardVersionsToml, implAddressKey) returns (address parsedAddr_) { + addr_ = parsedAddr_; + } catch { + try vm.parseTomlAddress(_standardVersionsToml, addressKey) returns (address parsedAddr_) { + addr_ = parsedAddr_; + } catch { + addr_ = address(0); + } + } + } + + // A release is considered a 'develop' release if it does not start with 'op-contracts'. + function isDevelopRelease(string memory _release) internal pure returns (bool) { + return !LibString.startsWith(_release, "op-contracts"); + } } // Similar to how DeploySuperchain.s.sol contains a lot of comments to thoroughly document the script @@ -800,26 +999,30 @@ contract DeployImplementations is Script { contract DeployImplementationsInterop is DeployImplementations { function createOPSMContract( DeployImplementationsInput _dii, - DeployImplementationsOutput, - OPStackManager.Blueprints memory blueprints, - string memory release, - OPStackManager.ImplementationSetter[] memory setters + DeployImplementationsOutput _dio, + OPStackManager.Blueprints memory _blueprints, + string memory _release, + OPStackManager.ImplementationSetter[] memory _setters ) internal override returns (OPStackManager opsmProxy_) { - SuperchainConfig superchainConfigProxy = _dii.superchainConfigProxy(); - ProtocolVersions protocolVersionsProxy = _dii.protocolVersionsProxy(); ProxyAdmin proxyAdmin = _dii.superchainProxyAdmin(); - vm.startBroadcast(msg.sender); + vm.broadcast(msg.sender); Proxy proxy = new Proxy(address(msg.sender)); - OPStackManager opsm = new OPStackManagerInterop(superchainConfigProxy, protocolVersionsProxy); + + deployOPContractsManagerImpl(_dii, _dio); // overriding function + OPStackManager opsmImpl = _dio.opsmImpl(); OPStackManager.InitializerInputs memory initializerInputs = - OPStackManager.InitializerInputs(blueprints, setters, release, true); - proxy.upgradeToAndCall(address(opsm), abi.encodeWithSelector(opsm.initialize.selector, initializerInputs)); + OPStackManager.InitializerInputs(_blueprints, _setters, _release, true); + + vm.startBroadcast(msg.sender); + proxy.upgradeToAndCall( + address(opsmImpl), abi.encodeWithSelector(opsmImpl.initialize.selector, initializerInputs) + ); proxy.changeAdmin(address(proxyAdmin)); // transfer ownership of Proxy contract to the ProxyAdmin contract vm.stopBroadcast(); @@ -834,25 +1037,70 @@ contract DeployImplementationsInterop is DeployImplementations { public override { - uint256 proofMaturityDelaySeconds = _dii.proofMaturityDelaySeconds(); - uint256 disputeGameFinalityDelaySeconds = _dii.disputeGameFinalityDelaySeconds(); + string memory release = _dii.release(); + string memory stdVerToml = _dii.standardVersionsToml(); + string memory contractName = "optimism_portal"; + OptimismPortal2 impl; + + address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); + if (existingImplementation != address(0)) { + impl = OptimismPortalInterop(payable(existingImplementation)); + } else if (isDevelopRelease(release)) { + uint256 proofMaturityDelaySeconds = _dii.proofMaturityDelaySeconds(); + uint256 disputeGameFinalityDelaySeconds = _dii.disputeGameFinalityDelaySeconds(); + vm.broadcast(msg.sender); + impl = new OptimismPortalInterop(proofMaturityDelaySeconds, disputeGameFinalityDelaySeconds); + } else { + revert(string.concat("DeployImplementations: failed to deploy release ", release)); + } - vm.broadcast(msg.sender); - OptimismPortalInterop optimismPortalImpl = new OptimismPortalInterop({ - _proofMaturityDelaySeconds: proofMaturityDelaySeconds, - _disputeGameFinalityDelaySeconds: disputeGameFinalityDelaySeconds - }); + vm.label(address(impl), "OptimismPortalImpl"); + _dio.set(_dio.optimismPortalImpl.selector, address(impl)); + } - vm.label(address(optimismPortalImpl), "OptimismPortalImpl"); - _dio.set(_dio.optimismPortalImpl.selector, address(optimismPortalImpl)); + function deploySystemConfigImpl( + DeployImplementationsInput _dii, + DeployImplementationsOutput _dio + ) + public + override + { + string memory release = _dii.release(); + string memory stdVerToml = _dii.standardVersionsToml(); + + string memory contractName = "system_config"; + SystemConfig impl; + + address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); + if (existingImplementation != address(0)) { + impl = SystemConfigInterop(existingImplementation); + } else if (isDevelopRelease(release)) { + vm.broadcast(msg.sender); + impl = new SystemConfigInterop(); + } else { + revert(string.concat("DeployImplementations: failed to deploy release ", release)); + } + + vm.label(address(impl), "SystemConfigImpl"); + _dio.set(_dio.systemConfigImpl.selector, address(impl)); } - function deploySystemConfigImpl(DeployImplementationsInput, DeployImplementationsOutput _dio) public override { + function deployOPContractsManagerImpl( + DeployImplementationsInput _dii, + DeployImplementationsOutput _dio + ) + public + override + { + SuperchainConfig superchainConfigProxy = _dii.superchainConfigProxy(); + ProtocolVersions protocolVersionsProxy = _dii.protocolVersionsProxy(); + vm.broadcast(msg.sender); - SystemConfigInterop systemConfigImpl = new SystemConfigInterop(); + // TODO: Eventually we will want to select the correct implementation based on the release. + OPStackManager impl = new OPStackManagerInterop(superchainConfigProxy, protocolVersionsProxy); - vm.label(address(systemConfigImpl), "SystemConfigImpl"); - _dio.set(_dio.systemConfigImpl.selector, address(systemConfigImpl)); + vm.label(address(impl), "OPStackManagerImpl"); + _dio.set(_dio.opsmImpl.selector, address(impl)); } function opsmSystemConfigSetter( diff --git a/packages/contracts-bedrock/test/DeployImplementations.t.sol b/packages/contracts-bedrock/test/DeployImplementations.t.sol index 957eb2830435..1eac67c6fdf3 100644 --- a/packages/contracts-bedrock/test/DeployImplementations.t.sol +++ b/packages/contracts-bedrock/test/DeployImplementations.t.sol @@ -35,7 +35,7 @@ contract DeployImplementationsInput_Test is Test { uint256 challengePeriodSeconds = 300; uint256 proofMaturityDelaySeconds = 400; uint256 disputeGameFinalityDelaySeconds = 500; - string release = "op-contracts/latest"; + string release = "dev-release"; // this means implementation contracts will be deployed SuperchainConfig superchainConfigProxy = SuperchainConfig(makeAddr("superchainConfigProxy")); ProtocolVersions protocolVersionsProxy = ProtocolVersions(makeAddr("protocolVersionsProxy")); @@ -70,6 +70,9 @@ contract DeployImplementationsInput_Test is Test { vm.expectRevert("DeployImplementationsInput: not set"); dii.superchainProxyAdmin(); + + vm.expectRevert("DeployImplementationsInput: not set"); + dii.standardVersionsToml(); } function test_superchainProxyAdmin_whenNotSet_reverts() public { @@ -247,13 +250,18 @@ contract DeployImplementations_Test is Test { uint256 challengePeriodSeconds = 300; uint256 proofMaturityDelaySeconds = 400; uint256 disputeGameFinalityDelaySeconds = 500; - string release = "op-contracts/latest"; SuperchainConfig superchainConfigProxy = SuperchainConfig(makeAddr("superchainConfigProxy")); ProtocolVersions protocolVersionsProxy = ProtocolVersions(makeAddr("protocolVersionsProxy")); function setUp() public virtual { deployImplementations = new DeployImplementations(); (dii, dio) = deployImplementations.etchIOContracts(); + + // End users of the DeployImplementations contract will need to set the `standardVersionsToml`. + string memory standardVersionsTomlPath = + string.concat(vm.projectRoot(), "/test/fixtures/standard-versions.toml"); + string memory standardVersionsToml = vm.readFile(standardVersionsTomlPath); + dii.set(dii.standardVersionsToml.selector, standardVersionsToml); } // By deploying the `DeployImplementations` contract with this virtual function, we provide a @@ -267,13 +275,142 @@ contract DeployImplementations_Test is Test { return keccak256(abi.encode(_seed, _i)); } + function test_deployImplementation_succeeds() public { + string memory deployContractsRelease = "dev-release"; + dii.set(dii.release.selector, deployContractsRelease); + deployImplementations.deploySystemConfigImpl(dii, dio); + assertTrue(address(0) != address(dio.systemConfigImpl())); + } + + function test_reuseImplementation_succeeds() public { + // All hardcoded addresses below are taken from the superchain-registry config: + // https://github.com/ethereum-optimism/superchain-registry/blob/be65d22f8128cf0c4e5b4e1f677daf86843426bf/validation/standard/standard-versions.toml#L11 + string memory testRelease = "op-contracts/v1.6.0"; + dii.set(dii.release.selector, testRelease); + + deployImplementations.deploySystemConfigImpl(dii, dio); + address srSystemConfigImpl = address(0xF56D96B2535B932656d3c04Ebf51baBff241D886); + vm.etch(address(srSystemConfigImpl), hex"01"); + assertEq(srSystemConfigImpl, address(dio.systemConfigImpl())); + + address srL1CrossDomainMessengerImpl = address(0xD3494713A5cfaD3F5359379DfA074E2Ac8C6Fd65); + vm.etch(address(srL1CrossDomainMessengerImpl), hex"01"); + deployImplementations.deployL1CrossDomainMessengerImpl(dii, dio); + assertEq(srL1CrossDomainMessengerImpl, address(dio.l1CrossDomainMessengerImpl())); + + address srL1ERC721BridgeImpl = address(0xAE2AF01232a6c4a4d3012C5eC5b1b35059caF10d); + vm.etch(address(srL1ERC721BridgeImpl), hex"01"); + deployImplementations.deployL1ERC721BridgeImpl(dii, dio); + assertEq(srL1ERC721BridgeImpl, address(dio.l1ERC721BridgeImpl())); + + address srL1StandardBridgeImpl = address(0x64B5a5Ed26DCb17370Ff4d33a8D503f0fbD06CfF); + vm.etch(address(srL1StandardBridgeImpl), hex"01"); + deployImplementations.deployL1StandardBridgeImpl(dii, dio); + assertEq(srL1StandardBridgeImpl, address(dio.l1StandardBridgeImpl())); + + address srOptimismMintableERC20FactoryImpl = address(0xE01efbeb1089D1d1dB9c6c8b135C934C0734c846); + vm.etch(address(srOptimismMintableERC20FactoryImpl), hex"01"); + deployImplementations.deployOptimismMintableERC20FactoryImpl(dii, dio); + assertEq(srOptimismMintableERC20FactoryImpl, address(dio.optimismMintableERC20FactoryImpl())); + + address srOptimismPortalImpl = address(0xe2F826324b2faf99E513D16D266c3F80aE87832B); + vm.etch(address(srOptimismPortalImpl), hex"01"); + deployImplementations.deployOptimismPortalImpl(dii, dio); + assertEq(srOptimismPortalImpl, address(dio.optimismPortalImpl())); + + address srDelayedWETHImpl = address(0x71e966Ae981d1ce531a7b6d23DC0f27B38409087); + vm.etch(address(srDelayedWETHImpl), hex"01"); + deployImplementations.deployDelayedWETHImpl(dii, dio); + assertEq(srDelayedWETHImpl, address(dio.delayedWETHImpl())); + + address srPreimageOracleSingleton = address(0x9c065e11870B891D214Bc2Da7EF1f9DDFA1BE277); + vm.etch(address(srPreimageOracleSingleton), hex"01"); + deployImplementations.deployPreimageOracleSingleton(dii, dio); + assertEq(srPreimageOracleSingleton, address(dio.preimageOracleSingleton())); + + address srMipsSingleton = address(0x16e83cE5Ce29BF90AD9Da06D2fE6a15d5f344ce4); + vm.etch(address(srMipsSingleton), hex"01"); + deployImplementations.deployMipsSingleton(dii, dio); + assertEq(srMipsSingleton, address(dio.mipsSingleton())); + + address srDisputeGameFactoryImpl = address(0xc641A33cab81C559F2bd4b21EA34C290E2440C2B); + vm.etch(address(srDisputeGameFactoryImpl), hex"01"); + deployImplementations.deployDisputeGameFactoryImpl(dii, dio); + assertEq(srDisputeGameFactoryImpl, address(dio.disputeGameFactoryImpl())); + } + + function test_deployAtNonExistentRelease_reverts() public { + string memory unknownRelease = "op-contracts/v0.0.0"; + dii.set(dii.release.selector, unknownRelease); + + bytes memory expectedErr = + bytes(string.concat("DeployImplementations: failed to deploy release ", unknownRelease)); + + vm.expectRevert(expectedErr); + deployImplementations.deploySystemConfigImpl(dii, dio); + + vm.expectRevert(expectedErr); + deployImplementations.deployL1CrossDomainMessengerImpl(dii, dio); + + vm.expectRevert(expectedErr); + deployImplementations.deployL1ERC721BridgeImpl(dii, dio); + + vm.expectRevert(expectedErr); + deployImplementations.deployL1StandardBridgeImpl(dii, dio); + + vm.expectRevert(expectedErr); + deployImplementations.deployOptimismMintableERC20FactoryImpl(dii, dio); + + // TODO: Uncomment the code below when OPContractsManager is deployed based on release. Superchain-registry + // doesn't contain OPContractsManager yet. + // dii.set(dii.superchainConfigProxy.selector, address(superchainConfigProxy)); + // dii.set(dii.protocolVersionsProxy.selector, address(protocolVersionsProxy)); + // vm.etch(address(superchainConfigProxy), hex"01"); + // vm.etch(address(protocolVersionsProxy), hex"01"); + // vm.expectRevert(expectedErr); + // deployImplementations.deployOPContractsManagerImpl(dii, dio); + + dii.set(dii.proofMaturityDelaySeconds.selector, 1); + dii.set(dii.disputeGameFinalityDelaySeconds.selector, 2); + vm.expectRevert(expectedErr); + deployImplementations.deployOptimismPortalImpl(dii, dio); + + dii.set(dii.withdrawalDelaySeconds.selector, 1); + vm.expectRevert(expectedErr); + deployImplementations.deployDelayedWETHImpl(dii, dio); + + dii.set(dii.minProposalSizeBytes.selector, 1); + dii.set(dii.challengePeriodSeconds.selector, 2); + vm.expectRevert(expectedErr); + deployImplementations.deployPreimageOracleSingleton(dii, dio); + + address preImageOracleSingleton = makeAddr("preImageOracleSingleton"); + vm.etch(address(preImageOracleSingleton), hex"01"); + dio.set(dio.preimageOracleSingleton.selector, preImageOracleSingleton); + vm.expectRevert(expectedErr); + deployImplementations.deployMipsSingleton(dii, dio); + + vm.expectRevert(expectedErr); // fault proof contracts don't exist at this release + deployImplementations.deployDisputeGameFactoryImpl(dii, dio); + } + + function test_noContractExistsAtRelease_reverts() public { + string memory unknownRelease = "op-contracts/v1.3.0"; + dii.set(dii.release.selector, unknownRelease); + bytes memory expectedErr = + bytes(string.concat("DeployImplementations: failed to deploy release ", unknownRelease)); + + vm.expectRevert(expectedErr); // fault proof contracts don't exist at this release + deployImplementations.deployDisputeGameFactoryImpl(dii, dio); + } + function testFuzz_run_memory_succeeds(bytes32 _seed) public { withdrawalDelaySeconds = uint256(hash(_seed, 0)); minProposalSizeBytes = uint256(hash(_seed, 1)); challengePeriodSeconds = bound(uint256(hash(_seed, 2)), 0, type(uint64).max); proofMaturityDelaySeconds = uint256(hash(_seed, 3)); disputeGameFinalityDelaySeconds = uint256(hash(_seed, 4)); - release = string(bytes.concat(hash(_seed, 5))); + string memory release = string(bytes.concat(hash(_seed, 5))); protocolVersionsProxy = ProtocolVersions(address(uint160(uint256(hash(_seed, 7))))); // Must configure the ProxyAdmin contract which is used to upgrade the OPSM's proxy contract. @@ -325,6 +462,7 @@ contract DeployImplementations_Test is Test { dii.set(dii.challengePeriodSeconds.selector, challengePeriodSeconds); dii.set(dii.proofMaturityDelaySeconds.selector, proofMaturityDelaySeconds); dii.set(dii.disputeGameFinalityDelaySeconds.selector, disputeGameFinalityDelaySeconds); + string memory release = "dev-release"; dii.set(dii.release.selector, release); dii.set(dii.superchainConfigProxy.selector, address(superchainConfigProxy)); dii.set(dii.protocolVersionsProxy.selector, address(protocolVersionsProxy)); diff --git a/packages/contracts-bedrock/test/DeployOPChain.t.sol b/packages/contracts-bedrock/test/DeployOPChain.t.sol index ef8fc06cc626..5f4525fde158 100644 --- a/packages/contracts-bedrock/test/DeployOPChain.t.sol +++ b/packages/contracts-bedrock/test/DeployOPChain.t.sol @@ -323,7 +323,7 @@ contract DeployOPChain_TestBase is Test { uint256 challengePeriodSeconds = 300; uint256 proofMaturityDelaySeconds = 400; uint256 disputeGameFinalityDelaySeconds = 500; - string release = "op-contracts/latest"; + string release = "dev-release"; // this means implementation contracts will be deployed SuperchainConfig superchainConfigProxy; ProtocolVersions protocolVersionsProxy; @@ -393,6 +393,11 @@ contract DeployOPChain_TestBase is Test { dii.set(dii.release.selector, release); dii.set(dii.superchainConfigProxy.selector, address(superchainConfigProxy)); dii.set(dii.protocolVersionsProxy.selector, address(protocolVersionsProxy)); + // End users of the DeployImplementations contract will need to set the `standardVersionsToml`. + string memory standardVersionsTomlPath = + string.concat(vm.projectRoot(), "/test/fixtures/standard-versions.toml"); + string memory standardVersionsToml = vm.readFile(standardVersionsTomlPath); + dii.set(dii.standardVersionsToml.selector, standardVersionsToml); deployImplementations.run(dii, dio); // Set the OPStackManager input for DeployOPChain. diff --git a/packages/contracts-bedrock/test/fixtures/standard-versions.toml b/packages/contracts-bedrock/test/fixtures/standard-versions.toml new file mode 100644 index 000000000000..cb4d336a7336 --- /dev/null +++ b/packages/contracts-bedrock/test/fixtures/standard-versions.toml @@ -0,0 +1,47 @@ +standard_release = "op-contracts/v1.6.0" + +[releases] + +# Contracts which are +# * unproxied singletons: specify a standard "address" +# * proxied : specify a standard "implementation_address" +# * neither : specify neither a standard "address" nor "implementation_address" + +# Fault Proofs https://github.com/ethereum-optimism/optimism/releases/tag/op-contracts%2Fv1.6.0 +[releases."op-contracts/v1.6.0"] +optimism_portal = { version = "3.10.0", implementation_address = "0xe2F826324b2faf99E513D16D266c3F80aE87832B" } +system_config = { version = "2.2.0", implementation_address = "0xF56D96B2535B932656d3c04Ebf51baBff241D886" } +anchor_state_registry = { version = "2.0.0" } +delayed_weth = { version = "1.1.0", implementation_address = "0x71e966Ae981d1ce531a7b6d23DC0f27B38409087" } +dispute_game_factory = { version = "1.0.0", implementation_address = "0xc641A33cab81C559F2bd4b21EA34C290E2440C2B" } +fault_dispute_game = { version = "1.3.0" } +permissioned_dispute_game = { version = "1.3.0" } +mips = { version = "1.1.0", address = "0x16e83cE5Ce29BF90AD9Da06D2fE6a15d5f344ce4" } +preimage_oracle = { version = "1.1.2", address = "0x9c065e11870B891D214Bc2Da7EF1f9DDFA1BE277" } +l1_cross_domain_messenger = { version = "2.3.0", implementation_address = "0xD3494713A5cfaD3F5359379DfA074E2Ac8C6Fd65" } +l1_erc721_bridge = { version = "2.1.0", implementation_address = "0xAE2AF01232a6c4a4d3012C5eC5b1b35059caF10d" } +l1_standard_bridge = { version = "2.1.0", implementation_address = "0x64B5a5Ed26DCb17370Ff4d33a8D503f0fbD06CfF" } +# l2_output_oracle -- This contract not used in fault proofs +optimism_mintable_erc20_factory = { version = "1.9.0", implementation_address = "0xE01efbeb1089D1d1dB9c6c8b135C934C0734c846" } + +# Fault Proofs https://github.com/ethereum-optimism/optimism/releases/tag/op-contracts%2Fv1.4.0 +[releases."op-contracts/v1.4.0"] +optimism_portal = { version = "3.10.0", implementation_address = "0xe2F826324b2faf99E513D16D266c3F80aE87832B" } +system_config = { version = "2.2.0", implementation_address = "0xF56D96B2535B932656d3c04Ebf51baBff241D886" } +anchor_state_registry = { version = "1.0.0" } +delayed_weth = { version = "1.0.0", implementation_address = "0x97988d5624F1ba266E1da305117BCf20713bee08" } +dispute_game_factory = { version = "1.0.0", implementation_address = "0xc641A33cab81C559F2bd4b21EA34C290E2440C2B" } +fault_dispute_game = { version = "1.2.0" } +permissioned_dispute_game = { version = "1.2.0" } +mips = { version = "1.0.1", address = "0x0f8EdFbDdD3c0256A80AD8C0F2560B1807873C9c" } +preimage_oracle = { version = "1.0.0", address = "0xD326E10B8186e90F4E2adc5c13a2d0C137ee8b34" } + +# MCP https://github.com/ethereum-optimism/optimism/releases/tag/op-contracts%2Fv1.3.0 +[releases."op-contracts/v1.3.0"] +l1_cross_domain_messenger = { version = "2.3.0", implementation_address = "0xD3494713A5cfaD3F5359379DfA074E2Ac8C6Fd65" } +l1_erc721_bridge = { version = "2.1.0", implementation_address = "0xAE2AF01232a6c4a4d3012C5eC5b1b35059caF10d" } +l1_standard_bridge = { version = "2.1.0", implementation_address = "0x64B5a5Ed26DCb17370Ff4d33a8D503f0fbD06CfF" } +l2_output_oracle = { version = "1.8.0", implementation_address = "0xF243BEd163251380e78068d317ae10f26042B292" } +optimism_mintable_erc20_factory = { version = "1.9.0", implementation_address = "0xE01efbeb1089D1d1dB9c6c8b135C934C0734c846" } +optimism_portal = { version = "2.5.0", implementation_address = "0x2D778797049FE9259d947D1ED8e5442226dFB589" } +system_config = { version = "1.12.0", implementation_address = "0xba2492e52F45651B60B8B38d4Ea5E2390C64Ffb1" } diff --git a/packages/contracts-bedrock/test/fixtures/test-deploy-auth-system-in.toml b/packages/contracts-bedrock/test/fixtures/test-deploy-auth-system-in.toml deleted file mode 100644 index 4f0df83e1af2..000000000000 --- a/packages/contracts-bedrock/test/fixtures/test-deploy-auth-system-in.toml +++ /dev/null @@ -1,11 +0,0 @@ -[safe] -threshold = 5 -owners = [ - "0x1111111111111111111111111111111111111111", - "0x2222222222222222222222222222222222222222", - "0x3333333333333333333333333333333333333333", - "0x4444444444444444444444444444444444444444", - "0x5555555555555555555555555555555555555555", - "0x6666666666666666666666666666666666666666", - "0x7777777777777777777777777777777777777777" -] diff --git a/packages/contracts-bedrock/test/fixtures/test-deploy-auth-system-out.toml b/packages/contracts-bedrock/test/fixtures/test-deploy-auth-system-out.toml deleted file mode 100644 index 35465cae1942..000000000000 --- a/packages/contracts-bedrock/test/fixtures/test-deploy-auth-system-out.toml +++ /dev/null @@ -1 +0,0 @@ -safe = "0xDC93f9959c0F9c3849461B6468B4592a19567E09" diff --git a/packages/contracts-bedrock/test/fixtures/test-deploy-superchain-in.toml b/packages/contracts-bedrock/test/fixtures/test-deploy-superchain-in.toml deleted file mode 100644 index 0900e71635d7..000000000000 --- a/packages/contracts-bedrock/test/fixtures/test-deploy-superchain-in.toml +++ /dev/null @@ -1,8 +0,0 @@ -paused = false -requiredProtocolVersion = 1 -recommendedProtocolVersion = 2 - -[roles] -proxyAdminOwner = "0x51f0348a9fA2aAbaB45E82825Fbd13d406e04497" -protocolVersionsOwner = "0xeEB4cc05dC0dE43c465f97cfc703D165418CA93A" -guardian = "0xE5DbA98c65F4B9EB0aeEBb3674fE64f88509a1eC" diff --git a/packages/contracts-bedrock/test/fixtures/test-deploy-superchain-out.toml b/packages/contracts-bedrock/test/fixtures/test-deploy-superchain-out.toml deleted file mode 100644 index ceb558a79d5a..000000000000 --- a/packages/contracts-bedrock/test/fixtures/test-deploy-superchain-out.toml +++ /dev/null @@ -1,5 +0,0 @@ -protocolVersionsImpl = "0x5991A2dF15A8F6A256D3Ec51E99254Cd3fb576A9" -protocolVersionsProxy = "0x1d1499e622D69689cdf9004d05Ec547d650Ff211" -superchainConfigImpl = "0xF62849F9A0B5Bf2913b396098F7c7019b51A820a" -superchainConfigProxy = "0xc7183455a4C133Ae270771860664b6B7ec320bB1" -superchainProxyAdmin = "0x2e234DAe75C793f67A35089C9d99245E1C58470b" From 1ee7ea1feca356347e12dafff53d601270c71ed2 Mon Sep 17 00:00:00 2001 From: Blaine Malone <blainemalone01@gmail.com> Date: Tue, 24 Sep 2024 15:17:50 -0400 Subject: [PATCH 246/264] fix: justfile clean command (#12092) * fix: justfile clean command * fix: removed stale comment --- packages/contracts-bedrock/justfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/contracts-bedrock/justfile b/packages/contracts-bedrock/justfile index e660d7a1c7ba..901ce17daa68 100644 --- a/packages/contracts-bedrock/justfile +++ b/packages/contracts-bedrock/justfile @@ -28,10 +28,8 @@ build-go-ffi: cd scripts/go-ffi && go build # Cleans build artifacts and deployments. -# Removes everything inside of .testdata (except the .gitkeep file). clean: rm -rf ./artifacts ./forge-artifacts ./cache ./scripts/go-ffi/go-ffi ./deployments/hardhat/* - find ./.testdata -mindepth 1 -not -name '.gitkeep' -delete ######################################################## From 5b9b3b8c5bfc67c17123fb8a26ed8f2bc615bc9f Mon Sep 17 00:00:00 2001 From: Maurelian <john@oplabs.co> Date: Tue, 24 Sep 2024 15:24:53 -0400 Subject: [PATCH 247/264] Add permissioned game output assertions (#12093) * test: Add permissioned game output assertions * test: reorder DeployOpChainTest_Base for clarity * Update packages/contracts-bedrock/test/DeployOPChain.t.sol Co-authored-by: Matt Solomon <matt@mattsolomon.dev> --------- Co-authored-by: Matt Solomon <matt@mattsolomon.dev> --- .../test/DeployOPChain.t.sol | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/packages/contracts-bedrock/test/DeployOPChain.t.sol b/packages/contracts-bedrock/test/DeployOPChain.t.sol index 5f4525fde158..732eea8b05bf 100644 --- a/packages/contracts-bedrock/test/DeployOPChain.t.sol +++ b/packages/contracts-bedrock/test/DeployOPChain.t.sol @@ -361,9 +361,10 @@ contract DeployOPChain_TestBase is Test { }) ); - // Initialize deploy scripts. + // Configure and deploy Superchain contracts DeploySuperchain deploySuperchain = new DeploySuperchain(); (DeploySuperchainInput dsi, DeploySuperchainOutput dso) = deploySuperchain.etchIOContracts(); + dsi.set(dsi.proxyAdminOwner.selector, proxyAdminOwner); dsi.set(dsi.protocolVersionsOwner.selector, protocolVersionsOwner); dsi.set(dsi.guardian.selector, guardian); @@ -371,20 +372,16 @@ contract DeployOPChain_TestBase is Test { dsi.set(dsi.requiredProtocolVersion.selector, requiredProtocolVersion); dsi.set(dsi.recommendedProtocolVersion.selector, recommendedProtocolVersion); - DeployImplementations deployImplementations = createDeployImplementationsContract(); - (DeployImplementationsInput dii, DeployImplementationsOutput dio) = deployImplementations.etchIOContracts(); - - deployOPChain = new DeployOPChain(); - (doi, doo) = deployOPChain.etchIOContracts(); - - // Deploy the superchain contracts. deploySuperchain.run(dsi, dso); // Populate the inputs for DeployImplementations based on the output of DeploySuperchain. superchainConfigProxy = dso.superchainConfigProxy(); protocolVersionsProxy = dso.protocolVersionsProxy(); - // Deploy the implementations. + // Configure and deploy Implementation contracts + DeployImplementations deployImplementations = createDeployImplementationsContract(); + (DeployImplementationsInput dii, DeployImplementationsOutput dio) = deployImplementations.etchIOContracts(); + dii.set(dii.withdrawalDelaySeconds.selector, withdrawalDelaySeconds); dii.set(dii.minProposalSizeBytes.selector, minProposalSizeBytes); dii.set(dii.challengePeriodSeconds.selector, challengePeriodSeconds); @@ -400,7 +397,11 @@ contract DeployOPChain_TestBase is Test { dii.set(dii.standardVersionsToml.selector, standardVersionsToml); deployImplementations.run(dii, dio); - // Set the OPStackManager input for DeployOPChain. + // Deploy DeployOpChain, but defer populating the input values to the test suites inheriting this contract. + deployOPChain = new DeployOPChain(); + (doi, doo) = deployOPChain.etchIOContracts(); + + // Set the OPStackManager address as input to DeployOPChain. opsm = dio.opsmProxy(); } @@ -478,8 +479,12 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { address batcherActual = address(uint160(uint256(doo.systemConfigProxy().batcherHash()))); assertEq(batcherActual, batcher, "2300"); assertEq(address(doo.systemConfigProxy().unsafeBlockSigner()), unsafeBlockSigner, "2400"); - // assertEq(address(...proposer()), proposer, "2500"); // TODO once we deploy dispute games. - // assertEq(address(...challenger()), challenger, "2600"); // TODO once we deploy dispute games. + assertEq(address(doo.permissionedDisputeGame().proposer()), proposer, "2500"); + assertEq(address(doo.permissionedDisputeGame().challenger()), challenger, "2600"); + + // TODO once we deploy the Permissionless Dispute Game + // assertEq(address(doo.faultDisputeGame().proposer()), proposer, "2700"); + // assertEq(address(doo.faultDisputeGame().challenger()), challenger, "2800"); // Most architecture assertions are handled within the OP Stack Manager itself and therefore // we only assert on the things that are not visible onchain. From 712b760f7aa266864137cb55d450c2e3a300d799 Mon Sep 17 00:00:00 2001 From: mbaxter <meredith@oplabs.co> Date: Tue, 24 Sep 2024 16:09:21 -0400 Subject: [PATCH 248/264] cannon: Drop unnecessary wakeup field reset (#12095) * cannon: Cut unnecessary wakeup reset * cannon: Cut now-extraneous state argument * cannon: Run semver lock --- cannon/mipsevm/multithreaded/mips.go | 4 +--- packages/contracts-bedrock/semver-lock.json | 4 ++-- .../contracts-bedrock/src/cannon/MIPS2.sol | 19 ++++++------------- 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/cannon/mipsevm/multithreaded/mips.go b/cannon/mipsevm/multithreaded/mips.go index daa36d05c0ff..b06ad3917724 100644 --- a/cannon/mipsevm/multithreaded/mips.go +++ b/cannon/mipsevm/multithreaded/mips.go @@ -363,6 +363,7 @@ func (m *InstrumentedState) handleRMWOps(insn, opcode uint32) error { } func (m *InstrumentedState) onWaitComplete(thread *ThreadState, isTimedOut bool) { + // Note: no need to reset m.state.Wakeup. If we're here, the Wakeup field has already been reset // Clear the futex state thread.FutexAddr = exec.FutexEmptyAddr thread.FutexVal = 0 @@ -376,9 +377,6 @@ func (m *InstrumentedState) onWaitComplete(thread *ThreadState, isTimedOut bool) v1 = exec.MipsETIMEDOUT } exec.HandleSyscallUpdates(&thread.Cpu, &thread.Registers, v0, v1) - - // Clear wakeup signal - m.state.Wakeup = exec.FutexEmptyAddr } func (m *InstrumentedState) preemptThread(thread *ThreadState) bool { diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 7312208bee3e..3a60a92d73e3 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -144,8 +144,8 @@ "sourceCodeHash": "0xba4674e1846afbbc708877332a38dfabd4b8d1e48ce07d8ebf0a45c9f27f16b0" }, "src/cannon/MIPS2.sol": { - "initCodeHash": "0xd9da47f735b7a655a25ae0e867b467620a2cb537eb65d184a361f5ea4174d384", - "sourceCodeHash": "0x3a6d83a7d46eb267f6778f8ae116383fe3c14ad553d90b6c761fafeef22ae29c" + "initCodeHash": "0x67fb4107e25561ffcb3a9b6653f695e125773408d626a92036ea4b0814797021", + "sourceCodeHash": "0x5f4851e04dc9369552c94fb23aee8e8ca4ea9a9602917f0abb3b5f1347460bd5" }, "src/cannon/PreimageOracle.sol": { "initCodeHash": "0x801e52f9c8439fcf7089575fa93272dfb874641dbfc7d82f36d979c987271c0b", diff --git a/packages/contracts-bedrock/src/cannon/MIPS2.sol b/packages/contracts-bedrock/src/cannon/MIPS2.sol index 45811d9b46c8..487ea0aac6df 100644 --- a/packages/contracts-bedrock/src/cannon/MIPS2.sol +++ b/packages/contracts-bedrock/src/cannon/MIPS2.sol @@ -57,8 +57,8 @@ contract MIPS2 is ISemver { } /// @notice The semantic version of the MIPS2 contract. - /// @custom:semver 1.0.0-beta.10 - string public constant version = "1.0.0-beta.10"; + /// @custom:semver 1.0.0-beta.11 + string public constant version = "1.0.0-beta.11"; /// @notice The preimage oracle contract. IPreimageOracle internal immutable ORACLE; @@ -202,7 +202,7 @@ contract MIPS2 is ISemver { // check timeout first if (state.step > thread.futexTimeoutStep) { // timeout! Allow execution - return onWaitComplete(state, thread, true); + return onWaitComplete(thread, true); } else { uint32 mem = MIPSMemory.readMem( state.memRoot, thread.futexAddr & 0xFFffFFfc, MIPSMemory.memoryProofOffset(MEM_PROOF_OFFSET, 1) @@ -214,7 +214,7 @@ contract MIPS2 is ISemver { } else { // wake thread up, the value at its address changed! // Userspace can turn thread back to sleep if it was too sporadic. - return onWaitComplete(state, thread, false); + return onWaitComplete(thread, false); } } } @@ -690,14 +690,8 @@ contract MIPS2 is ISemver { } /// @notice Completes the FUTEX_WAIT syscall. - function onWaitComplete( - State memory _state, - ThreadState memory _thread, - bool _isTimedOut - ) - internal - returns (bytes32 out_) - { + function onWaitComplete(ThreadState memory _thread, bool _isTimedOut) internal returns (bytes32 out_) { + // Note: no need to reset State.wakeup. If we're here, the wakeup field has already been reset // Clear the futex state _thread.futexAddr = sys.FUTEX_EMPTY_ADDR; _thread.futexVal = 0; @@ -711,7 +705,6 @@ contract MIPS2 is ISemver { sys.handleSyscallUpdates(cpu, _thread.registers, v0, v1); setStateCpuScalars(_thread, cpu); - _state.wakeup = sys.FUTEX_EMPTY_ADDR; updateCurrentThreadRoot(); out_ = outputState(); } From 9c02f544ec32cf0a1c437773f444d2cfea65d8fa Mon Sep 17 00:00:00 2001 From: Matt Solomon <matt@mattsolomon.dev> Date: Tue, 24 Sep 2024 15:46:11 -0600 Subject: [PATCH 249/264] chore: emit event on deploy (#12090) --- packages/contracts-bedrock/semver-lock.json | 4 ++-- packages/contracts-bedrock/src/L1/OPStackManager.sol | 5 +++-- packages/contracts-bedrock/test/L1/OPStackManager.t.sol | 5 +++++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 3a60a92d73e3..6d1b97c01f0d 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -32,8 +32,8 @@ "sourceCodeHash": "0xde4df0f9633dc0cdb1c9f634003ea5b0f7c5c1aebc407bc1b2f44c0ecf938649" }, "src/L1/OPStackManager.sol": { - "initCodeHash": "0x5b451782192b8429f6822c88270c4f0dbd10342518c5695ecf4dff7b5ebfb4e4", - "sourceCodeHash": "0x4a9c242ce96471437ec97662d2365a7bda376db765c630a41cbe238811f1df51" + "initCodeHash": "0x92c72b75206e756742df25d67d295e4479e65db1473948b8f53cb4ca642025d5", + "sourceCodeHash": "0x3cbd30c68cad0dd18d49165bd21d94422b7403174f91a733e2398539dadf8656" }, "src/L1/OptimismPortal.sol": { "initCodeHash": "0xbe2c0c81b3459014f287d8c89cdc0d27dde5d1f44e5d024fa1e4773ddc47c190", diff --git a/packages/contracts-bedrock/src/L1/OPStackManager.sol b/packages/contracts-bedrock/src/L1/OPStackManager.sol index 1a81430ff1e6..12e9a6f5cbdb 100644 --- a/packages/contracts-bedrock/src/L1/OPStackManager.sol +++ b/packages/contracts-bedrock/src/L1/OPStackManager.sol @@ -124,8 +124,8 @@ contract OPStackManager is ISemver, Initializable { // -------- Constants and Variables -------- - /// @custom:semver 1.0.0-beta.5 - string public constant version = "1.0.0-beta.5"; + /// @custom:semver 1.0.0-beta.6 + string public constant version = "1.0.0-beta.6"; /// @notice Address of the SuperchainConfig contract shared by all chains. SuperchainConfig public immutable superchainConfig; @@ -334,6 +334,7 @@ contract OPStackManager is ISemver, Initializable { // Transfer ownership of the ProxyAdmin from this contract to the specified owner. output.opChainProxyAdmin.transferOwnership(_input.roles.opChainProxyAdminOwner); + emit Deployed(l2ChainId, output.systemConfigProxy); return output; } diff --git a/packages/contracts-bedrock/test/L1/OPStackManager.t.sol b/packages/contracts-bedrock/test/L1/OPStackManager.t.sol index 6d9d7d134c33..ea26a6dae0b3 100644 --- a/packages/contracts-bedrock/test/L1/OPStackManager.t.sol +++ b/packages/contracts-bedrock/test/L1/OPStackManager.t.sol @@ -9,6 +9,7 @@ import { DeployOPChain_TestBase } from "test/DeployOPChain.t.sol"; import { OPStackManager } from "src/L1/OPStackManager.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; +import { SystemConfig } from "src/L1/SystemConfig.sol"; // Exposes internal functions for testing. contract OPStackManager_Harness is OPStackManager { @@ -33,6 +34,8 @@ contract OPStackManager_Harness is OPStackManager { contract OPStackManager_Deploy_Test is DeployOPChain_TestBase { using stdStorage for StdStorage; + event Deployed(uint256 indexed l2ChainId, SystemConfig indexed systemConfig); + function setUp() public override { DeployOPChain_TestBase.setUp(); @@ -83,6 +86,8 @@ contract OPStackManager_Deploy_Test is DeployOPChain_TestBase { } function test_deploy_succeeds() public { + vm.expectEmit(true, false, true, true); // TODO precompute the system config address. + emit Deployed(doi.l2ChainId(), SystemConfig(address(1))); opsm.deploy(toOPSMDeployInput(doi)); } } From 22094b4dd71921232cb009e7956ff5f0e55973ba Mon Sep 17 00:00:00 2001 From: Hamdi Allam <hamdi.allam97@gmail.com> Date: Tue, 24 Sep 2024 19:28:00 -0400 Subject: [PATCH 250/264] check deposit on validateMessage (#12088) --- packages/contracts-bedrock/semver-lock.json | 4 +- .../contracts-bedrock/src/L2/CrossL2Inbox.sol | 7 ++- .../test/L2/CrossL2Inbox.t.sol | 48 +++++++++++++++++++ 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 6d1b97c01f0d..d88cbdba6bfd 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -68,8 +68,8 @@ "sourceCodeHash": "0x2dc2284cf7c68e743da50e4113e96ffeab435de2390aeba2eab2f1e8ca411ce9" }, "src/L2/CrossL2Inbox.sol": { - "initCodeHash": "0x79c5deb404605b42ef917b5e7308a9015dacfb71225d957a634e6d0a3a5bc621", - "sourceCodeHash": "0xd219408d99f627770dfcdb3243a183dec7429372787f0aec3bdbff5b3c294f2a" + "initCodeHash": "0x0ee27866b4bf864a0b68ab25ea9559d7f2722b0396d02f2e8e089c6a1a5a6a93", + "sourceCodeHash": "0xe6f453049035e0d77e4d7a92904b448bc17e04dd3d99e738b9af20e20986ce64" }, "src/L2/ETHLiquidity.sol": { "initCodeHash": "0x713c18f95a6a746d0703f475f3ae10c106c9b9ecb64d881a2e61b8969b581371", diff --git a/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol b/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol index 6f86717c4e4d..437e0c62a2e3 100644 --- a/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol +++ b/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol @@ -65,8 +65,8 @@ contract CrossL2Inbox is ICrossL2Inbox, ISemver, TransientReentrancyAware { address internal constant DEPOSITOR_ACCOUNT = 0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001; /// @notice Semantic version. - /// @custom:semver 1.0.0-beta.6 - string public constant version = "1.0.0-beta.6"; + /// @custom:semver 1.0.0-beta.7 + string public constant version = "1.0.0-beta.7"; /// @notice Emitted when a cross chain message is being executed. /// @param msgHash Hash of message payload being executed. @@ -164,6 +164,9 @@ contract CrossL2Inbox is ICrossL2Inbox, ISemver, TransientReentrancyAware { /// @param _id Identifier of the message. /// @param _msgHash Hash of the message payload to call target with. function validateMessage(Identifier calldata _id, bytes32 _msgHash) external { + // We need to know if this is being called on a depositTx + if (IL1BlockIsthmus(Predeploys.L1_BLOCK_ATTRIBUTES).isDeposit()) revert NoExecutingDeposits(); + // Check the Identifier. _checkIdentifier(_id); diff --git a/packages/contracts-bedrock/test/L2/CrossL2Inbox.t.sol b/packages/contracts-bedrock/test/L2/CrossL2Inbox.t.sol index 99704860c00d..0d3175d41ed1 100644 --- a/packages/contracts-bedrock/test/L2/CrossL2Inbox.t.sol +++ b/packages/contracts-bedrock/test/L2/CrossL2Inbox.t.sol @@ -461,6 +461,13 @@ contract CrossL2InboxTest is Test { returnData: abi.encode(true) }); + // Ensure is not a deposit transaction + vm.mockCall({ + callee: Predeploys.L1_BLOCK_ATTRIBUTES, + data: abi.encodeWithSelector(IL1BlockIsthmus.isDeposit.selector), + returnData: abi.encode(false) + }); + // Look for the emit ExecutingMessage event vm.expectEmit(Predeploys.CROSS_L2_INBOX); emit CrossL2Inbox.ExecutingMessage(_messageHash, _id); @@ -469,6 +476,26 @@ contract CrossL2InboxTest is Test { crossL2Inbox.validateMessage(_id, _messageHash); } + function testFuzz_validateMessage_isDeposit_reverts( + ICrossL2Inbox.Identifier calldata _id, + bytes32 _messageHash + ) + external + { + // Ensure it is a deposit transaction + vm.mockCall({ + callee: Predeploys.L1_BLOCK_ATTRIBUTES, + data: abi.encodeWithSelector(IL1BlockIsthmus.isDeposit.selector), + returnData: abi.encode(true) + }); + + // Expect a revert with the NoExecutingDeposits selector + vm.expectRevert(NoExecutingDeposits.selector); + + // Call the executeMessage function + crossL2Inbox.validateMessage(_id, _messageHash); + } + /// @dev Tests that the `validateMessage` function reverts when called with an identifier with a timestamp later /// than current block.timestamp. function testFuzz_validateMessage_invalidTimestamp_reverts( @@ -478,6 +505,13 @@ contract CrossL2InboxTest is Test { external setInteropStart { + // Ensure is not a deposit transaction + vm.mockCall({ + callee: Predeploys.L1_BLOCK_ATTRIBUTES, + data: abi.encodeWithSelector(IL1BlockIsthmus.isDeposit.selector), + returnData: abi.encode(false) + }); + // Ensure that the id's timestamp is invalid (greater than the current block timestamp) vm.assume(_id.timestamp > block.timestamp); @@ -500,6 +534,13 @@ contract CrossL2InboxTest is Test { // Ensure that the id's timestamp is invalid (less than or equal to interopStartTime) _id.timestamp = bound(_id.timestamp, 0, crossL2Inbox.interopStart()); + // Ensure is not a deposit transaction + vm.mockCall({ + callee: Predeploys.L1_BLOCK_ATTRIBUTES, + data: abi.encodeWithSelector(IL1BlockIsthmus.isDeposit.selector), + returnData: abi.encode(false) + }); + // Expect a revert with the InvalidTimestamp selector vm.expectRevert(InvalidTimestamp.selector); @@ -527,6 +568,13 @@ contract CrossL2InboxTest is Test { returnData: abi.encode(false) }); + // Ensure is not a deposit transaction + vm.mockCall({ + callee: Predeploys.L1_BLOCK_ATTRIBUTES, + data: abi.encodeWithSelector(IL1BlockIsthmus.isDeposit.selector), + returnData: abi.encode(false) + }); + // Expect a revert with the InvalidChainId selector vm.expectRevert(InvalidChainId.selector); From cbbb45eca2e73eb301d0f37c24e7a2a98c1f1856 Mon Sep 17 00:00:00 2001 From: Paul Lange <palango@users.noreply.github.com> Date: Wed, 25 Sep 2024 02:13:43 +0200 Subject: [PATCH 251/264] op-node: Remove unused field in `ChannelBank` (#12001) --- op-node/rollup/derive/channel_bank.go | 6 ++---- op-node/rollup/derive/channel_bank_test.go | 8 ++++---- op-node/rollup/derive/pipeline.go | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/op-node/rollup/derive/channel_bank.go b/op-node/rollup/derive/channel_bank.go index b2efb0d3ce16..8dd689dfadaa 100644 --- a/op-node/rollup/derive/channel_bank.go +++ b/op-node/rollup/derive/channel_bank.go @@ -37,14 +37,13 @@ type ChannelBank struct { channels map[ChannelID]*Channel // channels by ID channelQueue []ChannelID // channels in FIFO order - prev NextFrameProvider - fetcher L1Fetcher + prev NextFrameProvider } var _ ResettableStage = (*ChannelBank)(nil) // NewChannelBank creates a ChannelBank, which should be Reset(origin) before use. -func NewChannelBank(log log.Logger, cfg *rollup.Config, prev NextFrameProvider, fetcher L1Fetcher, m Metrics) *ChannelBank { +func NewChannelBank(log log.Logger, cfg *rollup.Config, prev NextFrameProvider, m Metrics) *ChannelBank { return &ChannelBank{ log: log, spec: rollup.NewChainSpec(cfg), @@ -52,7 +51,6 @@ func NewChannelBank(log log.Logger, cfg *rollup.Config, prev NextFrameProvider, channels: make(map[ChannelID]*Channel), channelQueue: make([]ChannelID, 0, 10), prev: prev, - fetcher: fetcher, } } diff --git a/op-node/rollup/derive/channel_bank_test.go b/op-node/rollup/derive/channel_bank_test.go index 59c82c308f01..33763c23c5e0 100644 --- a/op-node/rollup/derive/channel_bank_test.go +++ b/op-node/rollup/derive/channel_bank_test.go @@ -102,7 +102,7 @@ func TestChannelBankSimple(t *testing.T) { cfg := &rollup.Config{ChannelTimeoutBedrock: 10} - cb := NewChannelBank(testlog.Logger(t, log.LevelCrit), cfg, input, nil, metrics.NoopMetrics) + cb := NewChannelBank(testlog.Logger(t, log.LevelCrit), cfg, input, metrics.NoopMetrics) // Load the first frame out, err := cb.NextData(context.Background()) @@ -146,7 +146,7 @@ func TestChannelBankInterleavedPreCanyon(t *testing.T) { cfg := &rollup.Config{ChannelTimeoutBedrock: 10, CanyonTime: nil} - cb := NewChannelBank(testlog.Logger(t, log.LevelCrit), cfg, input, nil, metrics.NoopMetrics) + cb := NewChannelBank(testlog.Logger(t, log.LevelCrit), cfg, input, metrics.NoopMetrics) // Load a:0 out, err := cb.NextData(context.Background()) @@ -211,7 +211,7 @@ func TestChannelBankInterleaved(t *testing.T) { ct := uint64(0) cfg := &rollup.Config{ChannelTimeoutBedrock: 10, CanyonTime: &ct} - cb := NewChannelBank(testlog.Logger(t, log.LevelCrit), cfg, input, nil, metrics.NoopMetrics) + cb := NewChannelBank(testlog.Logger(t, log.LevelCrit), cfg, input, metrics.NoopMetrics) // Load a:0 out, err := cb.NextData(context.Background()) @@ -271,7 +271,7 @@ func TestChannelBankDuplicates(t *testing.T) { cfg := &rollup.Config{ChannelTimeoutBedrock: 10} - cb := NewChannelBank(testlog.Logger(t, log.LevelCrit), cfg, input, nil, metrics.NoopMetrics) + cb := NewChannelBank(testlog.Logger(t, log.LevelCrit), cfg, input, metrics.NoopMetrics) // Load the first frame out, err := cb.NextData(context.Background()) diff --git a/op-node/rollup/derive/pipeline.go b/op-node/rollup/derive/pipeline.go index e4eae7e20303..a06640086fde 100644 --- a/op-node/rollup/derive/pipeline.go +++ b/op-node/rollup/derive/pipeline.go @@ -84,7 +84,7 @@ func NewDerivationPipeline(log log.Logger, rollupCfg *rollup.Config, l1Fetcher L dataSrc := NewDataSourceFactory(log, rollupCfg, l1Fetcher, l1Blobs, altDA) // auxiliary stage for L1Retrieval l1Src := NewL1Retrieval(log, dataSrc, l1Traversal) frameQueue := NewFrameQueue(log, l1Src) - bank := NewChannelBank(log, rollupCfg, frameQueue, l1Fetcher, metrics) + bank := NewChannelBank(log, rollupCfg, frameQueue, metrics) chInReader := NewChannelInReader(rollupCfg, log, bank, metrics) batchQueue := NewBatchQueue(log, rollupCfg, chInReader, l2Source) attrBuilder := NewFetchingAttributesBuilder(rollupCfg, l1Fetcher, l2Source) From 30725498eba13839240e793e36eae47c270322a5 Mon Sep 17 00:00:00 2001 From: Chen Kai <281165273grape@gmail.com> Date: Wed, 25 Sep 2024 12:17:14 +0800 Subject: [PATCH 252/264] MTCannon: Add add/addi/addu/addiu opcodes tests (#12085) * feat:add cannon add/addi/addu/addiu opcodes test Signed-off-by: Chen Kai <281165273grape@gmail.com> * feat:add cannon add/addu/addi/addiu opcodes test Signed-off-by: Chen Kai <281165273grape@gmail.com> --------- Signed-off-by: Chen Kai <281165273grape@gmail.com> --- cannon/mipsevm/tests/evm_common_test.go | 65 ++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/cannon/mipsevm/tests/evm_common_test.go b/cannon/mipsevm/tests/evm_common_test.go index ea6c7b2de957..21aea97a7a14 100644 --- a/cannon/mipsevm/tests/evm_common_test.go +++ b/cannon/mipsevm/tests/evm_common_test.go @@ -115,7 +115,7 @@ func TestEVM(t *testing.T) { } } -func TestEVMSingleStep(t *testing.T) { +func TestEVMSingleStep_Jump(t *testing.T) { var tracer *tracing.Hooks versions := GetMipsVersionTestCases(t) @@ -162,6 +162,69 @@ func TestEVMSingleStep(t *testing.T) { } } +func TestEVMSingleStep_Add(t *testing.T) { + var tracer *tracing.Hooks + + versions := GetMipsVersionTestCases(t) + cases := []struct { + name string + insn uint32 + ifImm bool + rs uint32 + rt uint32 + imm uint16 + expectRD uint32 + expectImm uint32 + }{ + {name: "add", insn: 0x02_32_40_20, ifImm: false, rs: uint32(12), rt: uint32(20), expectRD: uint32(32)}, // add t0, s1, s2 + {name: "addu", insn: 0x02_32_40_21, ifImm: false, rs: uint32(12), rt: uint32(20), expectRD: uint32(32)}, // addu t0, s1, s2 + {name: "addi", insn: 0x22_28_00_28, ifImm: true, rs: uint32(4), rt: uint32(1), imm: uint16(40), expectImm: uint32(44)}, // addi t0, s1, 40 + {name: "addi sign", insn: 0x22_28_ff_fe, ifImm: true, rs: uint32(2), rt: uint32(1), imm: uint16(0xfffe), expectImm: uint32(0)}, // addi t0, s1, -2 + {name: "addiu", insn: 0x26_28_00_28, ifImm: true, rs: uint32(4), rt: uint32(1), imm: uint16(40), expectImm: uint32(44)}, // addiu t0, s1, 40 + } + + for _, v := range versions { + for i, tt := range cases { + testName := fmt.Sprintf("%v (%v)", tt.name, v.Name) + t.Run(testName, func(t *testing.T) { + goVm := v.VMFactory(nil, os.Stdout, os.Stderr, testutil.CreateLogger(), testutil.WithRandomization(int64(i)), testutil.WithPC(0), testutil.WithNextPC(4)) + state := goVm.GetState() + if tt.ifImm { + state.GetRegistersRef()[8] = tt.rt + state.GetRegistersRef()[17] = tt.rs + } else { + state.GetRegistersRef()[17] = tt.rs + state.GetRegistersRef()[18] = tt.rt + } + state.GetMemory().SetMemory(0, tt.insn) + step := state.GetStep() + + // Setup expectations + expected := testutil.NewExpectedState(state) + expected.Step += 1 + expected.PC = 4 + expected.NextPC = 8 + + if tt.ifImm { + expected.Registers[8] = tt.expectImm + expected.Registers[17] = tt.rs + } else { + expected.Registers[8] = tt.expectRD + expected.Registers[17] = tt.rs + expected.Registers[18] = tt.rt + } + + stepWitness, err := goVm.Step(true) + require.NoError(t, err) + + // Check expectations + expected.Validate(t, state) + testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, tracer) + }) + } + } +} + func TestEVM_MMap(t *testing.T) { var tracer *tracing.Hooks From 56502ddc8773dc13b057445111e9aeaa5b8d14f0 Mon Sep 17 00:00:00 2001 From: Inphi <mlaw2501@gmail.com> Date: Wed, 25 Sep 2024 00:34:05 -0400 Subject: [PATCH 253/264] cannon: Multi VM executor (#12072) * cannon: Multi VM executor * fix run subcmd arg fwding * fix mt prestate * add list subcmd; multicannon in op-stack-go * remove cannon-latest * safer strconv * lint * include .gitkeep in embed * fix .git copy * add detect.go tests * add nosemgrep * review comments * list filtering * add note to MIPS.sol in version stf ref * use fork-exec * minimal flag parsing * load old cannon binaries from docker images * note * --help flag defaults * remove redundant copy from cannon-builder-0 --- Makefile | 4 +- cannon/.gitignore | 1 + cannon/Makefile | 11 +++- cannon/README.md | 2 +- cannon/cmd/load_elf.go | 64 ++++++++++---------- cannon/cmd/run.go | 48 ++++++++------- cannon/cmd/witness.go | 22 ++++--- cannon/mipsevm/versions/detect.go | 35 +++++++++++ cannon/mipsevm/versions/detect_test.go | 65 ++++++++++++++++++++ cannon/mipsevm/versions/state.go | 25 ++++++++ cannon/multicannon/embeds/.gitkeep | 0 cannon/multicannon/exec.go | 83 ++++++++++++++++++++++++++ cannon/multicannon/list.go | 73 ++++++++++++++++++++++ cannon/multicannon/load_elf.go | 31 ++++++++++ cannon/multicannon/main.go | 35 +++++++++++ cannon/multicannon/run.go | 39 ++++++++++++ cannon/multicannon/util.go | 37 ++++++++++++ cannon/multicannon/util_test.go | 68 +++++++++++++++++++++ cannon/multicannon/witness.go | 32 ++++++++++ op-program/Dockerfile.repro | 4 +- ops/docker/op-stack-go/Dockerfile | 12 +++- 21 files changed, 618 insertions(+), 73 deletions(-) create mode 100644 cannon/mipsevm/versions/detect.go create mode 100644 cannon/mipsevm/versions/detect_test.go create mode 100644 cannon/multicannon/embeds/.gitkeep create mode 100644 cannon/multicannon/exec.go create mode 100644 cannon/multicannon/list.go create mode 100644 cannon/multicannon/load_elf.go create mode 100644 cannon/multicannon/main.go create mode 100644 cannon/multicannon/run.go create mode 100644 cannon/multicannon/util.go create mode 100644 cannon/multicannon/util_test.go create mode 100644 cannon/multicannon/witness.go diff --git a/Makefile b/Makefile index 6b1abdd37f00..4f329a4241e2 100644 --- a/Makefile +++ b/Makefile @@ -142,13 +142,13 @@ $(DEVNET_CANNON_PRESTATE_FILES): make cannon-prestate-mt cannon-prestate: op-program cannon ## Generates prestate using cannon and op-program - ./cannon/bin/cannon load-elf --path op-program/bin/op-program-client.elf --out op-program/bin/prestate.json --meta op-program/bin/meta.json + ./cannon/bin/cannon load-elf --type singlethreaded --path op-program/bin/op-program-client.elf --out op-program/bin/prestate.json --meta op-program/bin/meta.json ./cannon/bin/cannon run --proof-at '=0' --stop-at '=1' --input op-program/bin/prestate.json --meta op-program/bin/meta.json --proof-fmt 'op-program/bin/%d.json' --output "" mv op-program/bin/0.json op-program/bin/prestate-proof.json .PHONY: cannon-prestate cannon-prestate-mt: op-program cannon ## Generates prestate using cannon and op-program in the multithreaded cannon format - ./cannon/bin/cannon load-elf --type cannon-mt --path op-program/bin/op-program-client.elf --out op-program/bin/prestate-mt.bin.gz --meta op-program/bin/meta-mt.json + ./cannon/bin/cannon load-elf --type multithreaded --path op-program/bin/op-program-client.elf --out op-program/bin/prestate-mt.bin.gz --meta op-program/bin/meta-mt.json ./cannon/bin/cannon run --proof-at '=0' --stop-at '=1' --input op-program/bin/prestate-mt.bin.gz --meta op-program/bin/meta-mt.json --proof-fmt 'op-program/bin/%d-mt.json' --output "" mv op-program/bin/0-mt.json op-program/bin/prestate-proof-mt.json .PHONY: cannon-prestate-mt diff --git a/cannon/.gitignore b/cannon/.gitignore index c3e45199f0ed..68424370890f 100644 --- a/cannon/.gitignore +++ b/cannon/.gitignore @@ -13,3 +13,4 @@ state.json *.pprof *.out bin +multicannon/embeds/cannon* diff --git a/cannon/Makefile b/cannon/Makefile index d6a1d85eff89..7540b88e58f2 100644 --- a/cannon/Makefile +++ b/cannon/Makefile @@ -13,8 +13,15 @@ ifeq ($(shell uname),Darwin) FUZZLDFLAGS := -ldflags=-extldflags=-Wl,-ld_classic endif -cannon: - env GO111MODULE=on GOOS=$(TARGETOS) GOARCH=$(TARGETARCH) go build -v $(LDFLAGS) -o ./bin/cannon . +cannon-impl: + env GO111MODULE=on GOOS=$(TARGETOS) GOARCH=$(TARGETARCH) go build -v $(LDFLAGS) -o ./bin/cannon-impl . + +cannon-embeds: cannon-impl + @cp bin/cannon-impl ./multicannon/embeds/cannon-0 + @cp bin/cannon-impl ./multicannon/embeds/cannon-1 + +cannon: cannon-embeds + env GO111MODULE=on GOOS=$(TARGETOS) GOARCH=$(TARGETARCH) go build -v $(LDFLAGS) -o ./bin/cannon ./multicannon/ clean: rm -rf bin diff --git a/cannon/README.md b/cannon/README.md index e9e751ce2ffe..a3b917193901 100644 --- a/cannon/README.md +++ b/cannon/README.md @@ -30,7 +30,7 @@ make cannon # Transform MIPS op-program client binary into first VM state. # This outputs state.json (VM state) and meta.json (for debug symbols). -./bin/cannon load-elf --path=../op-program/bin/op-program-client.elf +./bin/cannon load-elf --type singlethreaded --path=../op-program/bin/op-program-client.elf # Run cannon emulator (with example inputs) # Note that the server-mode op-program command is passed into cannon (after the --), diff --git a/cannon/cmd/load_elf.go b/cannon/cmd/load_elf.go index a6b9e0e5897a..816eb7c02e46 100644 --- a/cannon/cmd/load_elf.go +++ b/cannon/cmd/load_elf.go @@ -12,6 +12,7 @@ import ( "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" "github.com/ethereum-optimism/optimism/cannon/mipsevm/versions" "github.com/ethereum-optimism/optimism/cannon/serialize" + openum "github.com/ethereum-optimism/optimism/op-service/enum" "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/ethereum-optimism/optimism/op-service/jsonutil" ) @@ -19,9 +20,8 @@ import ( var ( LoadELFVMTypeFlag = &cli.StringFlag{ Name: "type", - Usage: "VM type to create state for. Options are 'cannon' (default), 'cannon-mt'", - Value: "cannon", - Required: false, + Usage: "VM type to create state for. Valid options: " + openum.EnumString(stateVersions()), + Required: true, } LoadELFPathFlag = &cli.PathFlag{ Name: "path", @@ -43,21 +43,12 @@ var ( } ) -type VMType string - -var ( - cannonVMType VMType = "cannon" - mtVMType VMType = "cannon-mt" -) - -func vmTypeFromString(ctx *cli.Context) (VMType, error) { - if vmTypeStr := ctx.String(LoadELFVMTypeFlag.Name); vmTypeStr == string(cannonVMType) { - return cannonVMType, nil - } else if vmTypeStr == string(mtVMType) { - return mtVMType, nil - } else { - return "", fmt.Errorf("unknown VM type %q", vmTypeStr) +func stateVersions() []string { + vers := make([]string, len(versions.StateVersionTypes)) + for i, v := range versions.StateVersionTypes { + vers[i] = v.String() } + return vers } func LoadELF(ctx *cli.Context) error { @@ -73,9 +64,12 @@ func LoadELF(ctx *cli.Context) error { var createInitialState func(f *elf.File) (mipsevm.FPVMState, error) var patcher = program.PatchStack - if vmType, err := vmTypeFromString(ctx); err != nil { + ver, err := versions.ParseStateVersion(ctx.String(LoadELFVMTypeFlag.Name)) + if err != nil { return err - } else if vmType == cannonVMType { + } + switch ver { + case versions.VersionSingleThreaded: createInitialState = func(f *elf.File) (mipsevm.FPVMState, error) { return program.LoadELF(f, singlethreaded.CreateInitialState) } @@ -86,12 +80,12 @@ func LoadELF(ctx *cli.Context) error { } return program.PatchStack(state) } - } else if vmType == mtVMType { + case versions.VersionMultiThreaded: createInitialState = func(f *elf.File) (mipsevm.FPVMState, error) { return program.LoadELF(f, multithreaded.CreateInitialState) } - } else { - return fmt.Errorf("invalid VM type: %q", vmType) + default: + return fmt.Errorf("unsupported state version: %d (%s)", ver, ver.String()) } state, err := createInitialState(elfProgram) @@ -118,15 +112,19 @@ func LoadELF(ctx *cli.Context) error { return serialize.Write(ctx.Path(LoadELFOutFlag.Name), versionedState, OutFilePerm) } -var LoadELFCommand = &cli.Command{ - Name: "load-elf", - Usage: "Load ELF file into Cannon state", - Description: "Load ELF file into Cannon state", - Action: LoadELF, - Flags: []cli.Flag{ - LoadELFVMTypeFlag, - LoadELFPathFlag, - LoadELFOutFlag, - LoadELFMetaFlag, - }, +func CreateLoadELFCommand(action cli.ActionFunc) *cli.Command { + return &cli.Command{ + Name: "load-elf", + Usage: "Load ELF file into Cannon state", + Description: "Load ELF file into Cannon state", + Action: action, + Flags: []cli.Flag{ + LoadELFVMTypeFlag, + LoadELFPathFlag, + LoadELFOutFlag, + LoadELFMetaFlag, + }, + } } + +var LoadELFCommand = CreateLoadELFCommand(LoadELF) diff --git a/cannon/cmd/run.go b/cannon/cmd/run.go index 03836d087d98..21f4f7c29825 100644 --- a/cannon/cmd/run.go +++ b/cannon/cmd/run.go @@ -496,26 +496,30 @@ func Run(ctx *cli.Context) error { return nil } -var RunCommand = &cli.Command{ - Name: "run", - Usage: "Run VM step(s) and generate proof data to replicate onchain.", - Description: "Run VM step(s) and generate proof data to replicate onchain. See flags to match when to output a proof, a snapshot, or to stop early.", - Action: Run, - Flags: []cli.Flag{ - RunInputFlag, - RunOutputFlag, - RunProofAtFlag, - RunProofFmtFlag, - RunSnapshotAtFlag, - RunSnapshotFmtFlag, - RunStopAtFlag, - RunStopAtPreimageFlag, - RunStopAtPreimageTypeFlag, - RunStopAtPreimageLargerThanFlag, - RunMetaFlag, - RunInfoAtFlag, - RunPProfCPU, - RunDebugFlag, - RunDebugInfoFlag, - }, +func CreateRunCommand(action cli.ActionFunc) *cli.Command { + return &cli.Command{ + Name: "run", + Usage: "Run VM step(s) and generate proof data to replicate onchain.", + Description: "Run VM step(s) and generate proof data to replicate onchain. See flags to match when to output a proof, a snapshot, or to stop early.", + Action: action, + Flags: []cli.Flag{ + RunInputFlag, + RunOutputFlag, + RunProofAtFlag, + RunProofFmtFlag, + RunSnapshotAtFlag, + RunSnapshotFmtFlag, + RunStopAtFlag, + RunStopAtPreimageFlag, + RunStopAtPreimageTypeFlag, + RunStopAtPreimageLargerThanFlag, + RunMetaFlag, + RunInfoAtFlag, + RunPProfCPU, + RunDebugFlag, + RunDebugInfoFlag, + }, + } } + +var RunCommand = CreateRunCommand(Run) diff --git a/cannon/cmd/witness.go b/cannon/cmd/witness.go index a4f2e60ab6a6..753438493f95 100644 --- a/cannon/cmd/witness.go +++ b/cannon/cmd/witness.go @@ -39,13 +39,17 @@ func Witness(ctx *cli.Context) error { return nil } -var WitnessCommand = &cli.Command{ - Name: "witness", - Usage: "Convert a Cannon JSON state into a binary witness", - Description: "Convert a Cannon JSON state into a binary witness. The hash of the witness is written to stdout", - Action: Witness, - Flags: []cli.Flag{ - WitnessInputFlag, - WitnessOutputFlag, - }, +func CreateWitnessCommand(action cli.ActionFunc) *cli.Command { + return &cli.Command{ + Name: "witness", + Usage: "Convert a Cannon JSON state into a binary witness", + Description: "Convert a Cannon JSON state into a binary witness. The hash of the witness is written to stdout", + Action: action, + Flags: []cli.Flag{ + WitnessInputFlag, + WitnessOutputFlag, + }, + } } + +var WitnessCommand = CreateWitnessCommand(Witness) diff --git a/cannon/mipsevm/versions/detect.go b/cannon/mipsevm/versions/detect.go new file mode 100644 index 000000000000..ca4b9be9c51d --- /dev/null +++ b/cannon/mipsevm/versions/detect.go @@ -0,0 +1,35 @@ +package versions + +import ( + "fmt" + "io" + + "github.com/ethereum-optimism/optimism/cannon/serialize" + "github.com/ethereum-optimism/optimism/op-service/ioutil" +) + +func DetectVersion(path string) (StateVersion, error) { + if !serialize.IsBinaryFile(path) { + return VersionSingleThreaded, nil + } + + var f io.ReadCloser + f, err := ioutil.OpenDecompressed(path) + if err != nil { + return 0, fmt.Errorf("failed to open file %q: %w", path, err) + } + defer f.Close() + + var ver StateVersion + bin := serialize.NewBinaryReader(f) + if err := bin.ReadUInt(&ver); err != nil { + return 0, err + } + + switch ver { + case VersionSingleThreaded, VersionMultiThreaded: + return ver, nil + default: + return 0, fmt.Errorf("%w: %d", ErrUnknownVersion, ver) + } +} diff --git a/cannon/mipsevm/versions/detect_test.go b/cannon/mipsevm/versions/detect_test.go new file mode 100644 index 000000000000..38a90f178694 --- /dev/null +++ b/cannon/mipsevm/versions/detect_test.go @@ -0,0 +1,65 @@ +package versions + +import ( + "os" + "path/filepath" + "testing" + + "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded" + "github.com/ethereum-optimism/optimism/op-service/ioutil" + "github.com/stretchr/testify/require" +) + +func TestDetectVersion(t *testing.T) { + t.Run("SingleThreadedJSON", func(t *testing.T) { + state, err := NewFromState(singlethreaded.CreateEmptyState()) + require.NoError(t, err) + path := writeToFile(t, "state.json", state) + version, err := DetectVersion(path) + require.NoError(t, err) + require.Equal(t, VersionSingleThreaded, version) + }) + + t.Run("SingleThreadedBinary", func(t *testing.T) { + state, err := NewFromState(singlethreaded.CreateEmptyState()) + require.NoError(t, err) + path := writeToFile(t, "state.bin.gz", state) + version, err := DetectVersion(path) + require.NoError(t, err) + require.Equal(t, VersionSingleThreaded, version) + }) + + t.Run("MultiThreadedBinary", func(t *testing.T) { + state, err := NewFromState(multithreaded.CreateEmptyState()) + require.NoError(t, err) + path := writeToFile(t, "state.bin.gz", state) + version, err := DetectVersion(path) + require.NoError(t, err) + require.Equal(t, VersionMultiThreaded, version) + }) +} + +func TestDetectVersionInvalid(t *testing.T) { + t.Run("bad gzip", func(t *testing.T) { + dir := t.TempDir() + filename := "state.bin.gz" + path := filepath.Join(dir, filename) + require.NoError(t, os.WriteFile(path, []byte("ekans"), 0o644)) + + _, err := DetectVersion(path) + require.ErrorContains(t, err, "failed to open file") + }) + + t.Run("unknown version", func(t *testing.T) { + dir := t.TempDir() + filename := "state.bin.gz" + path := filepath.Join(dir, filename) + const badVersion = 0xFF + err := ioutil.WriteCompressedBytes(path, []byte{badVersion}, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o644) + require.NoError(t, err) + + _, err = DetectVersion(path) + require.ErrorIs(t, err, ErrUnknownVersion) + }) +} diff --git a/cannon/mipsevm/versions/state.go b/cannon/mipsevm/versions/state.go index fcf7b1864f38..afd2a94204b3 100644 --- a/cannon/mipsevm/versions/state.go +++ b/cannon/mipsevm/versions/state.go @@ -16,6 +16,7 @@ import ( type StateVersion uint8 const ( + // VersionSingleThreaded is the version of the Cannon STF found in op-contracts/v1.6.0 - https://github.com/ethereum-optimism/optimism/blob/op-contracts/v1.6.0/packages/contracts-bedrock/src/cannon/MIPS.sol VersionSingleThreaded StateVersion = iota VersionMultiThreaded ) @@ -25,6 +26,8 @@ var ( ErrJsonNotSupported = errors.New("json not supported") ) +var StateVersionTypes = []StateVersion{VersionSingleThreaded, VersionMultiThreaded} + func LoadStateFromFile(path string) (*VersionedState, error) { if !serialize.IsBinaryFile(path) { // Always use singlethreaded for JSON states @@ -103,3 +106,25 @@ func (s *VersionedState) MarshalJSON() ([]byte, error) { } return json.Marshal(s.FPVMState) } + +func (s StateVersion) String() string { + switch s { + case VersionSingleThreaded: + return "singlethreaded" + case VersionMultiThreaded: + return "multithreaded" + default: + return "unknown" + } +} + +func ParseStateVersion(ver string) (StateVersion, error) { + switch ver { + case "singlethreaded": + return VersionSingleThreaded, nil + case "multithreaded": + return VersionMultiThreaded, nil + default: + return StateVersion(0), errors.New("unknown state version") + } +} diff --git a/cannon/multicannon/embeds/.gitkeep b/cannon/multicannon/embeds/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/cannon/multicannon/exec.go b/cannon/multicannon/exec.go new file mode 100644 index 000000000000..1372c035f560 --- /dev/null +++ b/cannon/multicannon/exec.go @@ -0,0 +1,83 @@ +package main + +import ( + "context" + "embed" + "errors" + "fmt" + "os" + "os/exec" + "path/filepath" + + "github.com/ethereum-optimism/optimism/cannon/mipsevm/versions" +) + +// use the all directive to ensure the .gitkeep file is retained and avoid compiler errors + +//go:embed all:embeds +var vmFS embed.FS + +const baseDir = "embeds" + +func ExecuteCannon(ctx context.Context, args []string, ver versions.StateVersion) error { + switch ver { + case versions.VersionSingleThreaded, versions.VersionMultiThreaded: + default: + return errors.New("unsupported version") + } + + cannonProgramName := vmFilename(ver) + cannonProgramBin, err := vmFS.ReadFile(cannonProgramName) + if err != nil { + return err + } + cannonProgramPath, err := extractTempFile(filepath.Base(cannonProgramName), cannonProgramBin) + if err != nil { + fmt.Fprintf(os.Stderr, "Error extracting %s: %v\n", cannonProgramName, err) + os.Exit(1) + } + defer os.Remove(cannonProgramPath) + + if err := os.Chmod(cannonProgramPath, 0755); err != nil { + fmt.Fprintf(os.Stderr, "Error setting execute permission for %s: %v\n", cannonProgramName, err) + os.Exit(1) + } + + // nosemgrep: go.lang.security.audit.dangerous-exec-command.dangerous-exec-command + cmd := exec.CommandContext(ctx, cannonProgramPath, args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + err = cmd.Start() + if err != nil { + return fmt.Errorf("unable to launch cannon-impl program: %w", err) + } + if err := cmd.Wait(); err != nil { + var exitErr *exec.ExitError + if errors.As(err, &exitErr) { + // relay exit code to the parent process + os.Exit(exitErr.ExitCode()) + } else { + return fmt.Errorf("failed to wait for cannon-impl program: %w", err) + } + } + return nil +} + +func extractTempFile(name string, data []byte) (string, error) { + tempDir := os.TempDir() + tempFile, err := os.CreateTemp(tempDir, name+"-*") + if err != nil { + return "", err + } + defer tempFile.Close() + + if _, err := tempFile.Write(data); err != nil { + return "", err + } + + return tempFile.Name(), nil +} + +func vmFilename(ver versions.StateVersion) string { + return fmt.Sprintf("%s/cannon-%d", baseDir, ver) +} diff --git a/cannon/multicannon/list.go b/cannon/multicannon/list.go new file mode 100644 index 000000000000..6e9e8a68b65a --- /dev/null +++ b/cannon/multicannon/list.go @@ -0,0 +1,73 @@ +package main + +import ( + "fmt" + "math" + "strconv" + "strings" + + "github.com/urfave/cli/v2" + + "github.com/ethereum-optimism/optimism/cannon/mipsevm/versions" +) + +func List(ctx *cli.Context) error { + return list() +} + +func list() error { + fmt.Println("Available cannon versions:") + artifacts, err := getArtifacts() + if err != nil { + return err + } + for _, art := range artifacts { + if art.isValid() { + fmt.Printf("filename: %s\tversion: %s (%d)\n", art.filename, versions.StateVersion(art.ver), art.ver) + } else { + fmt.Printf("filename: %s\tversion: %s\n", art.filename, "unknown") + } + } + return nil +} + +func getArtifacts() ([]artifact, error) { + var ret []artifact + entries, err := vmFS.ReadDir(baseDir) + if err != nil { + return nil, err + } + for _, entry := range entries { + filename := entry.Name() + toks := strings.Split(filename, "-") + if len(toks) != 2 { + continue + } + if toks[0] != "cannon" { + continue + } + ver, err := strconv.ParseUint(toks[1], 10, 8) + if err != nil { + ret = append(ret, artifact{filename, math.MaxUint64}) + continue + } + ret = append(ret, artifact{filename, ver}) + } + return ret, nil +} + +type artifact struct { + filename string + ver uint64 +} + +func (a artifact) isValid() bool { + return a.ver != math.MaxUint64 +} + +var ListCommand = &cli.Command{ + Name: "list", + Usage: "List embedded Cannon VM implementations", + Description: "List embedded Cannon VM implementations", + Action: List, +} diff --git a/cannon/multicannon/load_elf.go b/cannon/multicannon/load_elf.go new file mode 100644 index 000000000000..cbe1fda46303 --- /dev/null +++ b/cannon/multicannon/load_elf.go @@ -0,0 +1,31 @@ +package main + +import ( + "fmt" + "os" + + "github.com/ethereum-optimism/optimism/cannon/cmd" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/versions" + "github.com/urfave/cli/v2" +) + +func LoadELF(ctx *cli.Context) error { + if len(os.Args) == 2 && os.Args[2] == "--help" { + if err := list(); err != nil { + return err + } + fmt.Println("use `--type <vm type> --help` to get more detailed help") + } + + typ, err := parseFlag(os.Args[1:], "--type") + if err != nil { + return err + } + ver, err := versions.ParseStateVersion(typ) + if err != nil { + return err + } + return ExecuteCannon(ctx.Context, os.Args[1:], ver) +} + +var LoadELFCommand = cmd.CreateLoadELFCommand(LoadELF) diff --git a/cannon/multicannon/main.go b/cannon/multicannon/main.go new file mode 100644 index 000000000000..31dde280d8d0 --- /dev/null +++ b/cannon/multicannon/main.go @@ -0,0 +1,35 @@ +package main + +import ( + "context" + "errors" + "fmt" + "os" + + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" + "github.com/urfave/cli/v2" +) + +func main() { + app := cli.NewApp() + app.Name = "multicannon" + app.Usage = "MIPS Fault Proof tool" + app.Description = "MIPS Fault Proof tool" + app.Commands = []*cli.Command{ + LoadELFCommand, + WitnessCommand, + RunCommand, + ListCommand, + } + ctx := ctxinterrupt.WithCancelOnInterrupt(context.Background()) + err := app.RunContext(ctx, os.Args) + if err != nil { + if errors.Is(err, ctx.Err()) { + _, _ = fmt.Fprintf(os.Stderr, "command interrupted") + os.Exit(130) + } else { + _, _ = fmt.Fprintf(os.Stderr, "error: %v", err) + os.Exit(1) + } + } +} diff --git a/cannon/multicannon/run.go b/cannon/multicannon/run.go new file mode 100644 index 000000000000..532cf317fb21 --- /dev/null +++ b/cannon/multicannon/run.go @@ -0,0 +1,39 @@ +package main + +import ( + "fmt" + "os" + + "github.com/urfave/cli/v2" + + "github.com/ethereum-optimism/optimism/cannon/mipsevm/versions" +) + +func Run(ctx *cli.Context) error { + fmt.Printf("args %v\n", os.Args[:]) + if len(os.Args) == 3 && os.Args[2] == "--help" { + if err := list(); err != nil { + return err + } + fmt.Println("use `--input <valid input file> --help` to get more detailed help") + } + + inputPath, err := parsePathFlag(os.Args[1:], "--input") + if err != nil { + return err + } + version, err := versions.DetectVersion(inputPath) + if err != nil { + return err + } + return ExecuteCannon(ctx.Context, os.Args[1:], version) +} + +// var RunCommand = cmd.CreateRunCommand(Run) +var RunCommand = &cli.Command{ + Name: "run", + Usage: "Run VM step(s) and generate proof data to replicate onchain.", + Description: "Run VM step(s) and generate proof data to replicate onchain. See flags to match when to output a proof, a snapshot, or to stop early.", + Action: Run, + SkipFlagParsing: true, +} diff --git a/cannon/multicannon/util.go b/cannon/multicannon/util.go new file mode 100644 index 000000000000..ea484c6ce2d2 --- /dev/null +++ b/cannon/multicannon/util.go @@ -0,0 +1,37 @@ +package main + +import ( + "errors" + "fmt" + "os" + "strings" +) + +// parseFlag reads a flag argument. It assumes the flag has an argument +func parseFlag(args []string, flag string) (string, error) { + for i := 0; i < len(args); i++ { + arg := args[i] + if strings.HasPrefix(arg, flag) { + toks := strings.Split(arg, "=") + if len(toks) == 2 { + return toks[1], nil + } else if i+1 == len(args) { + return "", fmt.Errorf("flag needs an argument: %s", flag) + } else { + return args[i+1], nil + } + } + } + return "", fmt.Errorf("missing flag: %s", flag) +} + +func parsePathFlag(args []string, flag string) (string, error) { + path, err := parseFlag(args, flag) + if err != nil { + return "", err + } + if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) { + return "", fmt.Errorf("file `%s` does not exist", path) + } + return path, nil +} diff --git a/cannon/multicannon/util_test.go b/cannon/multicannon/util_test.go new file mode 100644 index 000000000000..9997b1315a8f --- /dev/null +++ b/cannon/multicannon/util_test.go @@ -0,0 +1,68 @@ +package main + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestParseFlag(t *testing.T) { + cases := []struct { + name string + args string + flag string + expect string + expectErr string + }{ + { + name: "bar=one", + args: "--foo --bar=one --baz", + flag: "--bar", + expect: "one", + }, + { + name: "bar one", + args: "--foo --bar one --baz", + flag: "--bar", + expect: "one", + }, + { + name: "bar one first flag", + args: "--bar one --foo two --baz three", + flag: "--bar", + expect: "one", + }, + { + name: "bar one last flag", + args: "--foo --baz --bar one", + flag: "--bar", + expect: "one", + }, + { + name: "non-existent flag", + args: "--foo one", + flag: "--bar", + expectErr: "missing flag", + }, + { + name: "empty args", + args: "", + flag: "--foo", + expectErr: "missing flag", + }, + } + for _, tt := range cases { + tt := tt + t.Run(tt.name, func(t *testing.T) { + args := strings.Split(tt.args, " ") + result, err := parseFlag(args, tt.flag) + if tt.expectErr != "" { + require.ErrorContains(t, err, tt.expectErr) + } else { + require.NoError(t, err) + require.Equal(t, tt.expect, result) + } + }) + } +} diff --git a/cannon/multicannon/witness.go b/cannon/multicannon/witness.go new file mode 100644 index 000000000000..077d0d3f1aed --- /dev/null +++ b/cannon/multicannon/witness.go @@ -0,0 +1,32 @@ +package main + +import ( + "fmt" + "os" + + "github.com/urfave/cli/v2" + + "github.com/ethereum-optimism/optimism/cannon/cmd" + "github.com/ethereum-optimism/optimism/cannon/mipsevm/versions" +) + +func Witness(ctx *cli.Context) error { + if len(os.Args) == 3 && os.Args[2] == "--help" { + if err := list(); err != nil { + return err + } + fmt.Println("use `--input <valid input file> --help` to get more detailed help") + } + + inputPath, err := parsePathFlag(os.Args[1:], "--input") + if err != nil { + return err + } + version, err := versions.DetectVersion(inputPath) + if err != nil { + return err + } + return ExecuteCannon(ctx.Context, os.Args[1:], version) +} + +var WitnessCommand = cmd.CreateWitnessCommand(Witness) diff --git a/op-program/Dockerfile.repro b/op-program/Dockerfile.repro index 12e52ec5b5a5..57f65bb72b81 100644 --- a/op-program/Dockerfile.repro +++ b/op-program/Dockerfile.repro @@ -35,8 +35,8 @@ RUN --mount=type=cache,target=/root/.cache/go-build cd op-program && make op-pro GOOS=linux GOARCH=mips GOMIPS=softfloat GITCOMMIT=$GIT_COMMIT GITDATE=$GIT_DATE VERSION="$OP_PROGRAM_VERSION" # Run the op-program-client.elf binary directly through cannon's load-elf subcommand. -RUN /app/cannon/bin/cannon load-elf --path /app/op-program/bin/op-program-client.elf --out /app/op-program/bin/prestate.json --meta "" -RUN /app/cannon/bin/cannon load-elf --type cannon-mt --path /app/op-program/bin/op-program-client.elf --out /app/op-program/bin/prestate-mt.bin.gz --meta "" +RUN /app/cannon/bin/cannon load-elf --type singlethreaded --path /app/op-program/bin/op-program-client.elf --out /app/op-program/bin/prestate.json --meta "" +RUN /app/cannon/bin/cannon load-elf --type multithreaded --path /app/op-program/bin/op-program-client.elf --out /app/op-program/bin/prestate-mt.bin.gz --meta "" # Generate the prestate proof containing the absolute pre-state hash. RUN /app/cannon/bin/cannon run --proof-at '=0' --stop-at '=1' --input /app/op-program/bin/prestate.json --meta "" --proof-fmt '/app/op-program/bin/%d.json' --output "" diff --git a/ops/docker/op-stack-go/Dockerfile b/ops/docker/op-stack-go/Dockerfile index a395968fd07a..540abfeb0466 100644 --- a/ops/docker/op-stack-go/Dockerfile +++ b/ops/docker/op-stack-go/Dockerfile @@ -46,8 +46,16 @@ ARG TARGETARCH # Build the Go services, utilizing caches and share the many common packages. # The "id" defaults to the value of "target", the cache will thus be reused during this build. # "sharing" defaults to "shared", the cache will thus be available to other concurrent docker builds. + +# For now fetch the v1 cannon binary from the op-challenger image +#FROM --platform=$BUILDPLATFORM us-docker.pkg.dev/oplabs-tools-artifacts/images/op-challenger:v1.1.0 AS cannon-builder-0 + FROM --platform=$BUILDPLATFORM builder AS cannon-builder -ARG CANNON_VERSION=v0.0.0 +# note: bump this CANNON_VERSION when the VM behavior changes +ARG CANNON_VERSION=v1.0.0 +# uncomment these lines once there's a new Cannon version available +#COPY --from=cannon-builder-0 /usr/local/bin/cannon ./cannon/multicannon/embeds/cannon-0 +#COPY --from=cannon-builder-0 /usr/local/bin/cannon ./cannon/multicannon/embeds/cannon-1 RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build cd cannon && make cannon \ GOOS=$TARGETOS GOARCH=$TARGETARCH GITCOMMIT=$GIT_COMMIT GITDATE=$GIT_DATE VERSION="$CANNON_VERSION" @@ -158,4 +166,4 @@ CMD ["op-supervisor"] FROM --platform=$TARGETPLATFORM $TARGET_BASE_IMAGE AS op-deployer-target COPY --from=op-deployer-builder /app/op-chain-ops/bin/op-deployer /usr/local/bin/ -CMD ["op-deployer"] \ No newline at end of file +CMD ["op-deployer"] From decf4513ae61b39a2fa6f40afcfe79e2fef619cc Mon Sep 17 00:00:00 2001 From: Adrian Sutton <adrian@oplabs.co> Date: Wed, 25 Sep 2024 14:58:03 +1000 Subject: [PATCH 254/264] cannon: Build the cannon docker image and publish on cannon release tags (#12100) * cannon: Build the cannon docker image and publish on cannon release tags. * ci: Add docker builds as dependencies so they prevent merging if they fail. * cannon: Include specific implementation builds in final docker image. --- .circleci/config.yml | 14 +++++++++++++- ops/docker/op-stack-go/Dockerfile | 1 + ops/scripts/ci-docker-tag-op-stack-release.sh | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6cab0308e927..0dffb662b116 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1673,6 +1673,12 @@ workflows: - op-e2e-fault-proof-tests - op-e2e-action-tests - op-e2e-action-tests-altda + # Not needed for the devnet but we want to make sure they build successfully + - cannon-docker-build + - op-dispute-mon-docker-build + - op-program-docker-build + - op-supervisor-docker-build + - proofs-tools-docker-build - docker-build: name: <<matrix.docker_name>>-docker-build docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>> @@ -1691,6 +1697,7 @@ workflows: - da-server - op-supervisor - op-deployer + - cannon - cannon-prestate: requires: - go-mod-download @@ -1734,7 +1741,7 @@ workflows: type: approval filters: tags: - only: /^(da-server|ci-builder(-rust)?|proofs-tools|ufm-[a-z0-9\-]*|op-[a-z0-9\-]*)\/v.*/ + only: /^(da-server|ci-builder(-rust)?|proofs-tools|cannon|ufm-[a-z0-9\-]*|op-[a-z0-9\-]*)\/v.*/ branches: ignore: /.*/ # Standard (medium) cross-platform docker images go here @@ -1752,6 +1759,7 @@ workflows: - op-ufm - op-supervisor - op-deployer + - cannon name: <<matrix.docker_name>>-docker-release docker_tags: <<pipeline.git.revision>> platforms: "linux/amd64,linux/arm64" @@ -1781,6 +1789,7 @@ workflows: - op-ufm - op-supervisor - op-deployer + - cannon name: <<matrix.op_component>>-cross-platform requires: - op-node-docker-release @@ -1793,6 +1802,7 @@ workflows: - op-ufm-docker-release - op-supervisor-docker-release - op-deployer-docker-release + - cannon-docker-release # Standard (xlarge) AMD-only docker images go here - docker-build: matrix: @@ -1922,6 +1932,7 @@ workflows: - op-dispute-mon - op-conductor - op-supervisor + - cannon name: <<matrix.docker_name>>-docker-publish docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>> platforms: "linux/amd64,linux/arm64" @@ -1941,6 +1952,7 @@ workflows: - op-dispute-mon - op-conductor - op-supervisor + - cannon name: <<matrix.op_component>>-cross-platform requires: - <<matrix.op_component>>-docker-publish diff --git a/ops/docker/op-stack-go/Dockerfile b/ops/docker/op-stack-go/Dockerfile index 540abfeb0466..0266e7010a76 100644 --- a/ops/docker/op-stack-go/Dockerfile +++ b/ops/docker/op-stack-go/Dockerfile @@ -116,6 +116,7 @@ RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache FROM --platform=$TARGETPLATFORM $TARGET_BASE_IMAGE AS cannon-target COPY --from=cannon-builder /app/cannon/bin/cannon /usr/local/bin/ +COPY --from=cannon-builder /app/cannon/multicannon/embeds/* /usr/local/bin/ CMD ["cannon"] FROM --platform=$TARGETPLATFORM $TARGET_BASE_IMAGE AS op-program-target diff --git a/ops/scripts/ci-docker-tag-op-stack-release.sh b/ops/scripts/ci-docker-tag-op-stack-release.sh index 09ae8ad81df3..45dd92094994 100755 --- a/ops/scripts/ci-docker-tag-op-stack-release.sh +++ b/ops/scripts/ci-docker-tag-op-stack-release.sh @@ -6,7 +6,7 @@ DOCKER_REPO=$1 GIT_TAG=$2 GIT_SHA=$3 -IMAGE_NAME=$(echo "$GIT_TAG" | grep -Eow '^(ci-builder(-rust)?|da-server|proofs-tools|ufm-[a-z0-9\-]*|op-[a-z0-9\-]*)' || true) +IMAGE_NAME=$(echo "$GIT_TAG" | grep -Eow '^(ci-builder(-rust)?|da-server|proofs-tools|cannon|ufm-[a-z0-9\-]*|op-[a-z0-9\-]*)' || true) if [ -z "$IMAGE_NAME" ]; then echo "image name could not be parsed from git tag '$GIT_TAG'" exit 1 From 4f1e8a7036e1f85fb1754ca1bb08a461c7c50ac4 Mon Sep 17 00:00:00 2001 From: zhiqiangxu <652732310@qq.com> Date: Wed, 25 Sep 2024 20:54:30 +0800 Subject: [PATCH 255/264] remove unused function (#12087) --- packages/contracts-bedrock/test/Predeploys.t.sol | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/contracts-bedrock/test/Predeploys.t.sol b/packages/contracts-bedrock/test/Predeploys.t.sol index 0d9e4879fd6b..6c9ac3750a03 100644 --- a/packages/contracts-bedrock/test/Predeploys.t.sol +++ b/packages/contracts-bedrock/test/Predeploys.t.sol @@ -12,13 +12,6 @@ contract PredeploysBaseTest is CommonTest { /// Internal helpers ////////////////////////////////////////////////////// - /// @dev Returns true if the address is an interop predeploy. - function _isInterop(address _addr) internal pure returns (bool) { - return _addr == Predeploys.CROSS_L2_INBOX || _addr == Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER - || _addr == Predeploys.SUPERCHAIN_WETH || _addr == Predeploys.ETH_LIQUIDITY - || _addr == Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY || _addr == Predeploys.OPTIMISM_SUPERCHAIN_ERC20_BEACON; - } - /// @dev Returns true if the address is a predeploy that has a different code in the interop mode. function _interopCodeDiffer(address _addr) internal pure returns (bool) { return _addr == Predeploys.L1_BLOCK_ATTRIBUTES || _addr == Predeploys.L2_STANDARD_BRIDGE; From 106993f81203ead1ff060f463f92bfcaa84821f1 Mon Sep 17 00:00:00 2001 From: George Knee <georgeknee@googlemail.com> Date: Wed, 25 Sep 2024 14:28:33 +0100 Subject: [PATCH 256/264] op-batcher: Move decision about data availability type to channel submission time (#12002) * tidy up godoc * move data availability config decision to channel submission time instead of channel creation time Also, cache the ChannelConfig whenever we switch DA type so it is used by default for new channels * fix test * formatting changes * respond to PR comments * add unit test for Requeue method * reduce number of txs in test block * improve test (more blocks in queue) * hoist pending tx management up * wip * tidy up test * wip * fix * refactor to do requeue before calling nextTxData * introduce ErrInsufficientData do not return nextTxData from channel which was discarded by requeue * run test until nonzero data is returned by TxData * break up and improve error logic * fix test to anticipate ErrInsufficientData * after requeuing, call nextTxData again * remove unecessary checks * move err declaration to top of file * add some comments and whitespace * hoist lock back up to TxData * rename variable to blocksToRequeue * remove panic * add comment * use deterministic rng and nonecompressor in test * test: increase block size to fill channel more quickly * remove ErrInsufficientData replace with io.EOF as before * tidy up * typo --- op-batcher/batcher/channel.go | 11 +- op-batcher/batcher/channel_builder.go | 4 +- op-batcher/batcher/channel_config.go | 4 +- op-batcher/batcher/channel_config_provider.go | 4 + op-batcher/batcher/channel_manager.go | 103 +++++++++-- op-batcher/batcher/channel_manager_test.go | 172 ++++++++++++++++++ op-batcher/batcher/channel_test.go | 4 +- op-batcher/batcher/driver.go | 9 +- op-batcher/batcher/driver_test.go | 1 + 9 files changed, 283 insertions(+), 29 deletions(-) diff --git a/op-batcher/batcher/channel.go b/op-batcher/batcher/channel.go index e35124d8525a..de68fa588a0a 100644 --- a/op-batcher/batcher/channel.go +++ b/op-batcher/batcher/channel.go @@ -155,9 +155,9 @@ func (s *channel) ID() derive.ChannelID { return s.channelBuilder.ID() } -// NextTxData returns the next tx data packet. -// If cfg.MultiFrameTxs is false, it returns txData with a single frame. -// If cfg.MultiFrameTxs is true, it will read frames from its channel builder +// NextTxData dequeues the next frames from the channel and returns them encoded in a tx data packet. +// If cfg.UseBlobs is false, it returns txData with a single frame. +// If cfg.UseBlobs is true, it will read frames from its channel builder // until it either doesn't have more frames or the target number of frames is reached. // // NextTxData should only be called after HasTxData returned true. @@ -177,10 +177,11 @@ func (s *channel) NextTxData() txData { } func (s *channel) HasTxData() bool { - if s.IsFull() || !s.cfg.UseBlobs { + if s.IsFull() || // If the channel is full, we should start to submit it + !s.cfg.UseBlobs { // If using calldata, we only send one frame per tx return s.channelBuilder.HasFrame() } - // collect enough frames if channel is not full yet + // Collect enough frames if channel is not full yet return s.channelBuilder.PendingFrames() >= int(s.cfg.MaxFramesPerTx()) } diff --git a/op-batcher/batcher/channel_builder.go b/op-batcher/batcher/channel_builder.go index cb4345e419d4..0c16f3156d9b 100644 --- a/op-batcher/batcher/channel_builder.go +++ b/op-batcher/batcher/channel_builder.go @@ -417,12 +417,12 @@ func (c *ChannelBuilder) HasFrame() bool { } // PendingFrames returns the number of pending frames in the frames queue. -// It is larger zero iff HasFrames() returns true. +// It is larger zero iff HasFrame() returns true. func (c *ChannelBuilder) PendingFrames() int { return len(c.frames) } -// NextFrame returns the next available frame. +// NextFrame dequeues the next available frame. // HasFrame must be called prior to check if there's a next frame available. // Panics if called when there's no next frame. func (c *ChannelBuilder) NextFrame() frameData { diff --git a/op-batcher/batcher/channel_config.go b/op-batcher/batcher/channel_config.go index 63e0d5d5deef..45dc1d4dcfa4 100644 --- a/op-batcher/batcher/channel_config.go +++ b/op-batcher/batcher/channel_config.go @@ -51,8 +51,8 @@ type ChannelConfig struct { UseBlobs bool } -// ChannelConfig returns a copy of itself. This makes a ChannelConfig a static -// ChannelConfigProvider of itself. +// ChannelConfig returns a copy of the receiver. +// This allows the receiver to be a static ChannelConfigProvider of itself. func (cc ChannelConfig) ChannelConfig() ChannelConfig { return cc } diff --git a/op-batcher/batcher/channel_config_provider.go b/op-batcher/batcher/channel_config_provider.go index c65e83b8289f..6cf5b0db6863 100644 --- a/op-batcher/batcher/channel_config_provider.go +++ b/op-batcher/batcher/channel_config_provider.go @@ -48,6 +48,10 @@ func NewDynamicEthChannelConfig(lgr log.Logger, return dec } +// ChannelConfig will perform an estimate of the cost per byte for +// calldata and for blobs, given current market conditions: it will return +// the appropriate ChannelConfig depending on which is cheaper. It makes +// assumptions about the typical makeup of channel data. func (dec *DynamicEthChannelConfig) ChannelConfig() ChannelConfig { ctx, cancel := context.WithTimeout(context.Background(), dec.timeout) defer cancel() diff --git a/op-batcher/batcher/channel_manager.go b/op-batcher/batcher/channel_manager.go index 1f22565c94c5..3bfff303db4b 100644 --- a/op-batcher/batcher/channel_manager.go +++ b/op-batcher/batcher/channel_manager.go @@ -35,6 +35,8 @@ type channelManager struct { blocks []*types.Block // The latest L1 block from all the L2 blocks in the most recently closed channel l1OriginLastClosedChannel eth.BlockID + // The default ChannelConfig to use for the next channel + defaultCfg ChannelConfig // last block hash - for reorg detection tip common.Hash @@ -54,6 +56,7 @@ func NewChannelManager(log log.Logger, metr metrics.Metricer, cfgProvider Channe log: log, metr: metr, cfgProvider: cfgProvider, + defaultCfg: cfgProvider.ChannelConfig(), rollupCfg: rollupCfg, txChannels: make(map[string]*channel), } @@ -133,7 +136,8 @@ func (s *channelManager) removePendingChannel(channel *channel) { s.channelQueue = append(s.channelQueue[:index], s.channelQueue[index+1:]...) } -// nextTxData pops off s.datas & handles updating the internal state +// nextTxData dequeues frames from the channel and returns them encoded in a transaction. +// It also updates the internal tx -> channels mapping func (s *channelManager) nextTxData(channel *channel) (txData, error) { if channel == nil || !channel.HasTxData() { s.log.Trace("no next tx data") @@ -146,12 +150,51 @@ func (s *channelManager) nextTxData(channel *channel) (txData, error) { // TxData returns the next tx data that should be submitted to L1. // -// If the pending channel is +// If the current channel is // full, it only returns the remaining frames of this channel until it got // successfully fully sent to L1. It returns io.EOF if there's no pending tx data. +// +// It will decide whether to switch DA type automatically. +// When switching DA type, the channelManager state will be rebuilt +// with a new ChannelConfig. func (s *channelManager) TxData(l1Head eth.BlockID) (txData, error) { s.mu.Lock() defer s.mu.Unlock() + channel, err := s.getReadyChannel(l1Head) + if err != nil { + return emptyTxData, err + } + // If the channel has already started being submitted, + // return now and ensure no requeueing happens + if !channel.NoneSubmitted() { + return s.nextTxData(channel) + } + + // Call provider method to reassess optimal DA type + newCfg := s.cfgProvider.ChannelConfig() + + // No change: + if newCfg.UseBlobs == s.defaultCfg.UseBlobs { + s.log.Debug("Recomputing optimal ChannelConfig: no need to switch DA type", + "useBlobs", s.defaultCfg.UseBlobs) + return s.nextTxData(channel) + } + + // Change: + s.log.Info("Recomputing optimal ChannelConfig: changing DA type and requeing blocks...", + "useBlobsBefore", s.defaultCfg.UseBlobs, + "useBlobsAfter", newCfg.UseBlobs) + s.Requeue(newCfg) + channel, err = s.getReadyChannel(l1Head) + if err != nil { + return emptyTxData, err + } + return s.nextTxData(channel) +} + +// getReadyChannel returns the next channel ready to submit data, or an error. +// It adds blocks from the block queue to the current channel and generates frames for it. +func (s *channelManager) getReadyChannel(l1Head eth.BlockID) (*channel, error) { var firstWithTxData *channel for _, ch := range s.channelQueue { if ch.HasTxData() { @@ -160,27 +203,31 @@ func (s *channelManager) TxData(l1Head eth.BlockID) (txData, error) { } } - dataPending := firstWithTxData != nil && firstWithTxData.HasTxData() + dataPending := firstWithTxData != nil s.log.Debug("Requested tx data", "l1Head", l1Head, "txdata_pending", dataPending, "blocks_pending", len(s.blocks)) - // Short circuit if there is pending tx data or the channel manager is closed. - if dataPending || s.closed { - return s.nextTxData(firstWithTxData) + // Short circuit if there is pending tx data or the channel manager is closed + if dataPending { + return firstWithTxData, nil + } + + if s.closed { + return nil, io.EOF } // No pending tx data, so we have to add new blocks to the channel // If we have no saved blocks, we will not be able to create valid frames if len(s.blocks) == 0 { - return txData{}, io.EOF + return nil, io.EOF } if err := s.ensureChannelWithSpace(l1Head); err != nil { - return txData{}, err + return nil, err } if err := s.processBlocks(); err != nil { - return txData{}, err + return nil, err } // Register current L1 head only after all pending blocks have been @@ -189,10 +236,10 @@ func (s *channelManager) TxData(l1Head eth.BlockID) (txData, error) { s.registerL1Block(l1Head) if err := s.outputFrames(); err != nil { - return txData{}, err + return nil, err } - return s.nextTxData(s.currentChannel) + return s.currentChannel, nil } // ensureChannelWithSpace ensures currentChannel is populated with a channel that has @@ -203,7 +250,10 @@ func (s *channelManager) ensureChannelWithSpace(l1Head eth.BlockID) error { return nil } - cfg := s.cfgProvider.ChannelConfig() + // We reuse the ChannelConfig from the last channel. + // This will be reassessed at channel submission-time, + // but this is our best guess at the appropriate values for now. + cfg := s.defaultCfg pc, err := newChannel(s.log, s.metr, cfg, s.rollupCfg, s.l1OriginLastClosedChannel.Number) if err != nil { return fmt.Errorf("creating new channel: %w", err) @@ -228,7 +278,7 @@ func (s *channelManager) ensureChannelWithSpace(l1Head eth.BlockID) error { return nil } -// registerL1Block registers the given block at the pending channel. +// registerL1Block registers the given block at the current channel. func (s *channelManager) registerL1Block(l1Head eth.BlockID) { s.currentChannel.CheckTimeout(l1Head.Number) s.log.Debug("new L1-block registered at channel builder", @@ -238,7 +288,7 @@ func (s *channelManager) registerL1Block(l1Head eth.BlockID) { ) } -// processBlocks adds blocks from the blocks queue to the pending channel until +// processBlocks adds blocks from the blocks queue to the current channel until // either the queue got exhausted or the channel is full. func (s *channelManager) processBlocks() error { var ( @@ -288,6 +338,7 @@ func (s *channelManager) processBlocks() error { return nil } +// outputFrames generates frames for the current channel, and computes and logs the compression ratio func (s *channelManager) outputFrames() error { if err := s.currentChannel.OutputFrames(); err != nil { return fmt.Errorf("creating frames with channel builder: %w", err) @@ -339,6 +390,7 @@ func (s *channelManager) outputFrames() error { func (s *channelManager) AddL2Block(block *types.Block) error { s.mu.Lock() defer s.mu.Unlock() + if s.tip != (common.Hash{}) && s.tip != block.ParentHash() { return ErrReorg } @@ -414,3 +466,26 @@ func (s *channelManager) Close() error { } return nil } + +// Requeue rebuilds the channel manager state by +// rewinding blocks back from the channel queue, and setting the defaultCfg. +func (s *channelManager) Requeue(newCfg ChannelConfig) { + newChannelQueue := []*channel{} + blocksToRequeue := []*types.Block{} + for _, channel := range s.channelQueue { + if !channel.NoneSubmitted() { + newChannelQueue = append(newChannelQueue, channel) + continue + } + blocksToRequeue = append(blocksToRequeue, channel.channelBuilder.Blocks()...) + } + + // We put the blocks back at the front of the queue: + s.blocks = append(blocksToRequeue, s.blocks...) + // Channels which where already being submitted are put back + s.channelQueue = newChannelQueue + s.currentChannel = nil + // Setting the defaultCfg will cause new channels + // to pick up the new ChannelConfig + s.defaultCfg = newCfg +} diff --git a/op-batcher/batcher/channel_manager_test.go b/op-batcher/batcher/channel_manager_test.go index a6271df9a535..5df5feacf4bf 100644 --- a/op-batcher/batcher/channel_manager_test.go +++ b/op-batcher/batcher/channel_manager_test.go @@ -1,6 +1,7 @@ package batcher import ( + "errors" "io" "math/big" "math/rand" @@ -483,3 +484,174 @@ func TestChannelManager_ChannelCreation(t *testing.T) { }) } } + +// FakeDynamicEthChannelConfig is a ChannelConfigProvider which always returns +// either a blob- or calldata-based config depending on its internal chooseBlob +// switch. +type FakeDynamicEthChannelConfig struct { + DynamicEthChannelConfig + chooseBlobs bool +} + +func (f *FakeDynamicEthChannelConfig) ChannelConfig() ChannelConfig { + if f.chooseBlobs { + return f.blobConfig + } + return f.calldataConfig +} + +func newFakeDynamicEthChannelConfig(lgr log.Logger, + reqTimeout time.Duration) *FakeDynamicEthChannelConfig { + + calldataCfg := ChannelConfig{ + MaxFrameSize: 120_000 - 1, + TargetNumFrames: 1, + } + blobCfg := ChannelConfig{ + MaxFrameSize: eth.MaxBlobDataSize - 1, + TargetNumFrames: 3, // gets closest to amortized fixed tx costs + UseBlobs: true, + } + calldataCfg.InitNoneCompressor() + blobCfg.InitNoneCompressor() + + return &FakeDynamicEthChannelConfig{ + chooseBlobs: false, + DynamicEthChannelConfig: *NewDynamicEthChannelConfig( + lgr, + reqTimeout, + &mockGasPricer{}, + blobCfg, + calldataCfg), + } +} + +// TestChannelManager_TxData seeds the channel manager with blocks and triggers the +// blocks->channels pipeline multiple times. Values are chosen such that a channel +// is created under one set of market conditions, and then submitted under a different +// set of market conditions. The test asserts that the DA type is changed at channel +// submission time. +func TestChannelManager_TxData(t *testing.T) { + + type TestCase struct { + name string + chooseBlobsWhenChannelCreated bool + chooseBlobsWhenChannelSubmitted bool + } + + tt := []TestCase{ + {"blobs->blobs", true, true}, + {"calldata->calldata", false, false}, + {"blobs->calldata", true, false}, + {"calldata->blobs", false, true}, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + l := testlog.Logger(t, log.LevelCrit) + + cfg := newFakeDynamicEthChannelConfig(l, 1000) + + cfg.chooseBlobs = tc.chooseBlobsWhenChannelCreated + m := NewChannelManager(l, metrics.NoopMetrics, cfg, defaultTestRollupConfig) + require.Equal(t, tc.chooseBlobsWhenChannelCreated, m.defaultCfg.UseBlobs) + + // Seed channel manager with a block + rng := rand.New(rand.NewSource(time.Now().UnixNano())) + blockA := derivetest.RandomL2BlockWithChainId(rng, 200, defaultTestRollupConfig.L2ChainID) + m.blocks = []*types.Block{blockA} + + // Call TxData a first time to trigger blocks->channels pipeline + _, err := m.TxData(eth.BlockID{}) + require.ErrorIs(t, err, io.EOF) + + // The test requires us to have something in the channel queue + // at this point, but not yet ready to send and not full + require.NotEmpty(t, m.channelQueue) + require.False(t, m.channelQueue[0].IsFull()) + + // Simulate updated market conditions + // by possibly flipping the state of the + // fake channel provider + l.Info("updating market conditions", "chooseBlobs", tc.chooseBlobsWhenChannelSubmitted) + cfg.chooseBlobs = tc.chooseBlobsWhenChannelSubmitted + + // Add a block and call TxData until + // we get some data to submit + var data txData + for { + m.blocks = []*types.Block{blockA} + data, err = m.TxData(eth.BlockID{}) + if err == nil && data.Len() > 0 { + break + } + if !errors.Is(err, io.EOF) { + require.NoError(t, err) + } + } + + require.Equal(t, tc.chooseBlobsWhenChannelSubmitted, data.asBlob) + require.Equal(t, tc.chooseBlobsWhenChannelSubmitted, m.defaultCfg.UseBlobs) + }) + } + +} + +// TestChannelManager_Requeue seeds the channel manager with blocks, +// takes a state snapshot, triggers the blocks->channels pipeline, +// and then calls Requeue. Finally, it asserts the channel manager's +// state is equal to the snapshot. It repeats this for a channel +// which has a pending transaction and verifies that Requeue is then +// a noop. +func TestChannelManager_Requeue(t *testing.T) { + l := testlog.Logger(t, log.LevelCrit) + cfg := channelManagerTestConfig(100, derive.SingularBatchType) + m := NewChannelManager(l, metrics.NoopMetrics, cfg, defaultTestRollupConfig) + + // Seed channel manager with blocks + rng := rand.New(rand.NewSource(99)) + blockA := derivetest.RandomL2BlockWithChainId(rng, 10, defaultTestRollupConfig.L2ChainID) + blockB := derivetest.RandomL2BlockWithChainId(rng, 10, defaultTestRollupConfig.L2ChainID) + + // This is the snapshot of channel manager state we want to reinstate + // when we requeue + stateSnapshot := []*types.Block{blockA, blockB} + m.blocks = stateSnapshot + require.Empty(t, m.channelQueue) + + // Trigger the blocks -> channelQueue data pipelining + require.NoError(t, m.ensureChannelWithSpace(eth.BlockID{})) + require.NotEmpty(t, m.channelQueue) + require.NoError(t, m.processBlocks()) + + // Assert that at least one block was processed into the channel + require.NotContains(t, m.blocks, blockA) + + // Call the function we are testing + m.Requeue(m.defaultCfg) + + // Ensure we got back to the state above + require.Equal(t, m.blocks, stateSnapshot) + require.Empty(t, m.channelQueue) + + // Trigger the blocks -> channelQueue data pipelining again + require.NoError(t, m.ensureChannelWithSpace(eth.BlockID{})) + require.NotEmpty(t, m.channelQueue) + require.NoError(t, m.processBlocks()) + + // Assert that at least one block was processed into the channel + require.NotContains(t, m.blocks, blockA) + + // Now mark the 0th channel in the queue as already + // starting to send on chain + channel0 := m.channelQueue[0] + channel0.pendingTransactions["foo"] = txData{} + require.False(t, channel0.NoneSubmitted()) + + // Call the function we are testing + m.Requeue(m.defaultCfg) + + // The requeue shouldn't affect the pending channel + require.Contains(t, m.channelQueue, channel0) + require.NotContains(t, m.blocks, blockA) +} diff --git a/op-batcher/batcher/channel_test.go b/op-batcher/batcher/channel_test.go index 7fa8030e771e..8dec9d9e108b 100644 --- a/op-batcher/batcher/channel_test.go +++ b/op-batcher/batcher/channel_test.go @@ -86,8 +86,8 @@ func TestChannelManager_NextTxData(t *testing.T) { require.Equal(t, txData{}, returnedTxData) // Set the pending channel - // The nextTxData function should still return EOF - // since the pending channel has no frames + // The nextTxData function should still return io.EOF + // since the current channel has no frames require.NoError(t, m.ensureChannelWithSpace(eth.BlockID{})) channel := m.currentChannel require.NotNil(t, channel) diff --git a/op-batcher/batcher/driver.go b/op-batcher/batcher/driver.go index 0b7d36d960dd..968e6de3e71a 100644 --- a/op-batcher/batcher/driver.go +++ b/op-batcher/batcher/driver.go @@ -190,10 +190,11 @@ func (l *BatchSubmitter) StopBatchSubmitting(ctx context.Context) error { // loadBlocksIntoState loads all blocks since the previous stored block // It does the following: -// 1. Fetch the sync status of the sequencer -// 2. Check if the sync status is valid or if we are all the way up to date -// 3. Check if it needs to initialize state OR it is lagging (todo: lagging just means race condition?) -// 4. Load all new blocks into the local state. +// 1. Fetch the sync status of the sequencer +// 2. Check if the sync status is valid or if we are all the way up to date +// 3. Check if it needs to initialize state OR it is lagging (todo: lagging just means race condition?) +// 4. Load all new blocks into the local state. +// // If there is a reorg, it will reset the last stored block but not clear the internal state so // the state can be flushed to L1. func (l *BatchSubmitter) loadBlocksIntoState(ctx context.Context) error { diff --git a/op-batcher/batcher/driver_test.go b/op-batcher/batcher/driver_test.go index 1c5ace753771..5ce0983bfe1a 100644 --- a/op-batcher/batcher/driver_test.go +++ b/op-batcher/batcher/driver_test.go @@ -50,6 +50,7 @@ func setup(t *testing.T) (*BatchSubmitter, *mockL2EndpointProvider) { Log: testlog.Logger(t, log.LevelDebug), Metr: metrics.NoopMetrics, RollupConfig: cfg, + ChannelConfig: defaultTestChannelConfig(), EndpointProvider: ep, }), ep } From b0e6d13737513ca838fccdaf2f1d26e03a68601a Mon Sep 17 00:00:00 2001 From: Adrian Sutton <adrian@oplabs.co> Date: Wed, 25 Sep 2024 23:51:33 +1000 Subject: [PATCH 257/264] cannon: Support the --version argument for multicannon. (#12101) Pick up the version from the release tag automatically. --- cannon/Makefile | 4 ++-- cannon/multicannon/main.go | 11 +++++++++++ cannon/multicannon/version/version.go | 6 ++++++ ops/docker/op-stack-go/Dockerfile | 3 +-- 4 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 cannon/multicannon/version/version.go diff --git a/cannon/Makefile b/cannon/Makefile index 7540b88e58f2..e914ad542eae 100644 --- a/cannon/Makefile +++ b/cannon/Makefile @@ -4,8 +4,8 @@ VERSION ?= v0.0.0 LDFLAGSSTRING +=-X main.GitCommit=$(GITCOMMIT) LDFLAGSSTRING +=-X main.GitDate=$(GITDATE) -LDFLAGSSTRING +=-X github.com/ethereum-optimism/optimism/op-program/version.Version=$(VERSION) -LDFLAGSSTRING +=-X github.com/ethereum-optimism/optimism/op-program/version.Meta=$(VERSION_META) +LDFLAGSSTRING +=-X github.com/ethereum-optimism/optimism/cannon/multicannon/version.Version=$(VERSION) +LDFLAGSSTRING +=-X github.com/ethereum-optimism/optimism/cannon/multicannon/version.Meta=$(VERSION_META) LDFLAGS := -ldflags "$(LDFLAGSSTRING)" # Use the old Apple linker to workaround broken xcode - https://github.com/golang/go/issues/65169 diff --git a/cannon/multicannon/main.go b/cannon/multicannon/main.go index 31dde280d8d0..e496eba880ba 100644 --- a/cannon/multicannon/main.go +++ b/cannon/multicannon/main.go @@ -6,15 +6,26 @@ import ( "fmt" "os" + "github.com/ethereum-optimism/optimism/cannon/multicannon/version" + opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" "github.com/urfave/cli/v2" ) +var ( + GitCommit = "" + GitDate = "" +) + +// VersionWithMeta holds the textual version string including the metadata. +var VersionWithMeta = opservice.FormatVersion(version.Version, GitCommit, GitDate, version.Meta) + func main() { app := cli.NewApp() app.Name = "multicannon" app.Usage = "MIPS Fault Proof tool" app.Description = "MIPS Fault Proof tool" + app.Version = VersionWithMeta app.Commands = []*cli.Command{ LoadELFCommand, WitnessCommand, diff --git a/cannon/multicannon/version/version.go b/cannon/multicannon/version/version.go new file mode 100644 index 000000000000..2456f656d45c --- /dev/null +++ b/cannon/multicannon/version/version.go @@ -0,0 +1,6 @@ +package version + +var ( + Version = "v0.0.0" + Meta = "dev" +) diff --git a/ops/docker/op-stack-go/Dockerfile b/ops/docker/op-stack-go/Dockerfile index 0266e7010a76..35f14d19a439 100644 --- a/ops/docker/op-stack-go/Dockerfile +++ b/ops/docker/op-stack-go/Dockerfile @@ -51,8 +51,7 @@ ARG TARGETARCH #FROM --platform=$BUILDPLATFORM us-docker.pkg.dev/oplabs-tools-artifacts/images/op-challenger:v1.1.0 AS cannon-builder-0 FROM --platform=$BUILDPLATFORM builder AS cannon-builder -# note: bump this CANNON_VERSION when the VM behavior changes -ARG CANNON_VERSION=v1.0.0 +ARG CANNON_VERSION=v0.0.0 # uncomment these lines once there's a new Cannon version available #COPY --from=cannon-builder-0 /usr/local/bin/cannon ./cannon/multicannon/embeds/cannon-0 #COPY --from=cannon-builder-0 /usr/local/bin/cannon ./cannon/multicannon/embeds/cannon-1 From da9bc723d83570f3e8e1a4388228588bba8112d2 Mon Sep 17 00:00:00 2001 From: zhiqiangxu <652732310@qq.com> Date: Wed, 25 Sep 2024 22:36:41 +0800 Subject: [PATCH 258/264] show log for `devnet` (#12102) * show log for devnet * add comment --- bedrock-devnet/devnet/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bedrock-devnet/devnet/__init__.py b/bedrock-devnet/devnet/__init__.py index ccf080c18566..8a3fb0ee4c99 100644 --- a/bedrock-devnet/devnet/__init__.py +++ b/bedrock-devnet/devnet/__init__.py @@ -11,6 +11,8 @@ from multiprocessing import Process, Queue import concurrent.futures from collections import namedtuple +# This import is necessary for devnet logs to be shown. +from . import log_setup pjoin = os.path.join From b55f4d737594ca9d93a977b9221e8fc1c7a5b51f Mon Sep 17 00:00:00 2001 From: Blaine Malone <blainemalone01@gmail.com> Date: Wed, 25 Sep 2024 11:05:22 -0400 Subject: [PATCH 259/264] rename: OPStackManafer -> OPContractsManager (#12091) --- op-chain-ops/Makefile | 2 +- .../deployer/integration_test/apply_test.go | 2 +- .../{opsm => opcm}/implementations.go | 16 +- .../deployer/{opsm => opcm}/l2genesis.go | 2 +- .../deployer/{opsm => opcm}/opchain.go | 4 +- .../{opsm => opcm}/standard-versions.toml | 0 .../deployer/{opsm => opcm}/standard.go | 2 +- .../deployer/{opsm => opcm}/superchain.go | 2 +- .../deployer/pipeline/implementations.go | 12 +- op-chain-ops/deployer/pipeline/l2genesis.go | 6 +- op-chain-ops/deployer/pipeline/opchain.go | 10 +- op-chain-ops/deployer/pipeline/superchain.go | 8 +- op-chain-ops/deployer/state/state.go | 2 +- op-chain-ops/interopgen/configs.go | 4 +- op-chain-ops/interopgen/deploy.go | 17 +- op-chain-ops/interopgen/deployments.go | 4 +- op-chain-ops/interopgen/recipe.go | 6 +- .../scripts/DeployImplementations.s.sol | 204 +++++++++--------- .../scripts/DeployOPChain.s.sol | 38 ++-- .../scripts/DeploySuperchain.s.sol | 2 +- packages/contracts-bedrock/semver-lock.json | 4 +- ...ckManager.json => OPContractsManager.json} | 16 +- ...op.json => OPContractsManagerInterop.json} | 16 +- ...ckManager.json => OPContractsManager.json} | 4 +- ...op.json => OPContractsManagerInterop.json} | 4 +- ...tackManager.sol => OPContractsManager.sol} | 8 +- ...erop.sol => OPContractsManagerInterop.sol} | 6 +- .../test/DeployImplementations.t.sol | 18 +- .../test/DeployOPChain.t.sol | 22 +- ...Manager.t.sol => OPContractsManager.t.sol} | 48 ++--- packages/contracts-bedrock/test/Specs.t.sol | 48 ++--- .../test/vendor/Initializable.t.sol | 4 +- 32 files changed, 275 insertions(+), 266 deletions(-) rename op-chain-ops/deployer/{opsm => opcm}/implementations.go (88%) rename op-chain-ops/deployer/{opsm => opcm}/l2genesis.go (99%) rename op-chain-ops/deployer/{opsm => opcm}/opchain.go (98%) rename op-chain-ops/deployer/{opsm => opcm}/standard-versions.toml (100%) rename op-chain-ops/deployer/{opsm => opcm}/standard.go (88%) rename op-chain-ops/deployer/{opsm => opcm}/superchain.go (99%) rename packages/contracts-bedrock/snapshots/abi/{OPStackManager.json => OPContractsManager.json} (95%) rename packages/contracts-bedrock/snapshots/abi/{OPStackManagerInterop.json => OPContractsManagerInterop.json} (95%) rename packages/contracts-bedrock/snapshots/storageLayout/{OPStackManager.json => OPContractsManager.json} (84%) rename packages/contracts-bedrock/snapshots/storageLayout/{OPStackManagerInterop.json => OPContractsManagerInterop.json} (84%) rename packages/contracts-bedrock/src/L1/{OPStackManager.sol => OPContractsManager.sol} (98%) rename packages/contracts-bedrock/src/L1/{OPStackManagerInterop.sol => OPContractsManagerInterop.sol} (91%) rename packages/contracts-bedrock/test/L1/{OPStackManager.t.sol => OPContractsManager.t.sol} (71%) diff --git a/op-chain-ops/Makefile b/op-chain-ops/Makefile index 262a989bc465..fd3cc9ad67b3 100644 --- a/op-chain-ops/Makefile +++ b/op-chain-ops/Makefile @@ -46,6 +46,6 @@ fuzz: sync-standard-version: - curl -Lo ./deployer/opsm/standard-versions.toml https://raw.githubusercontent.com/ethereum-optimism/superchain-registry/refs/heads/main/validation/standard/standard-versions.toml + curl -Lo ./deployer/opcm/standard-versions.toml https://raw.githubusercontent.com/ethereum-optimism/superchain-registry/refs/heads/main/validation/standard/standard-versions.toml .PHONY: test fuzz op-deployer sync-standard-version \ No newline at end of file diff --git a/op-chain-ops/deployer/integration_test/apply_test.go b/op-chain-ops/deployer/integration_test/apply_test.go index f3bcd5b3e4bd..4399e0b887d3 100644 --- a/op-chain-ops/deployer/integration_test/apply_test.go +++ b/op-chain-ops/deployer/integration_test/apply_test.go @@ -151,7 +151,7 @@ func TestEndToEndApply(t *testing.T) { {"SuperchainConfigImpl", st.SuperchainDeployment.SuperchainConfigImplAddress}, {"ProtocolVersionsProxy", st.SuperchainDeployment.ProtocolVersionsProxyAddress}, {"ProtocolVersionsImpl", st.SuperchainDeployment.ProtocolVersionsImplAddress}, - {"OpsmProxy", st.ImplementationsDeployment.OpsmProxyAddress}, + {"OpcmProxy", st.ImplementationsDeployment.OpcmProxyAddress}, {"DelayedWETHImpl", st.ImplementationsDeployment.DelayedWETHImplAddress}, {"OptimismPortalImpl", st.ImplementationsDeployment.OptimismPortalImplAddress}, {"PreimageOracleSingleton", st.ImplementationsDeployment.PreimageOracleSingletonAddress}, diff --git a/op-chain-ops/deployer/opsm/implementations.go b/op-chain-ops/deployer/opcm/implementations.go similarity index 88% rename from op-chain-ops/deployer/opsm/implementations.go rename to op-chain-ops/deployer/opcm/implementations.go index d60330440abc..fec30d94cbd5 100644 --- a/op-chain-ops/deployer/opsm/implementations.go +++ b/op-chain-ops/deployer/opcm/implementations.go @@ -1,4 +1,4 @@ -package opsm +package opcm import ( "fmt" @@ -16,7 +16,7 @@ type DeployImplementationsInput struct { ChallengePeriodSeconds *big.Int ProofMaturityDelaySeconds *big.Int DisputeGameFinalityDelaySeconds *big.Int - // Release version to set OPSM implementations for, of the format `op-contracts/vX.Y.Z`. + // Release version to set OPCM implementations for, of the format `op-contracts/vX.Y.Z`. Release string SuperchainConfigProxy common.Address ProtocolVersionsProxy common.Address @@ -31,8 +31,8 @@ func (input *DeployImplementationsInput) InputSet() bool { } type DeployImplementationsOutput struct { - OpsmProxy common.Address - OpsmImpl common.Address + OpcmProxy common.Address + OpcmImpl common.Address DelayedWETHImpl common.Address OptimismPortalImpl common.Address PreimageOracleSingleton common.Address @@ -84,12 +84,12 @@ func DeployImplementations( } defer cleanupDeploy() - opsmContract := "OPStackManager" + opcmContract := "OPContractsManager" if input.UseInterop { - opsmContract = "OPStackManagerInterop" + opcmContract = "OPContractsManagerInterop" } - if err := host.RememberOnLabel("OPStackManager", opsmContract+".sol", opsmContract); err != nil { - return output, fmt.Errorf("failed to link OPStackManager label: %w", err) + if err := host.RememberOnLabel("OPContractsManager", opcmContract+".sol", opcmContract); err != nil { + return output, fmt.Errorf("failed to link OPContractsManager label: %w", err) } // So we can see in detail where the SystemConfig interop initializer fails diff --git a/op-chain-ops/deployer/opsm/l2genesis.go b/op-chain-ops/deployer/opcm/l2genesis.go similarity index 99% rename from op-chain-ops/deployer/opsm/l2genesis.go rename to op-chain-ops/deployer/opcm/l2genesis.go index 3567df71858f..8b6e123dad3f 100644 --- a/op-chain-ops/deployer/opsm/l2genesis.go +++ b/op-chain-ops/deployer/opcm/l2genesis.go @@ -1,4 +1,4 @@ -package opsm +package opcm import ( "fmt" diff --git a/op-chain-ops/deployer/opsm/opchain.go b/op-chain-ops/deployer/opcm/opchain.go similarity index 98% rename from op-chain-ops/deployer/opsm/opchain.go rename to op-chain-ops/deployer/opcm/opchain.go index d600f200dcf1..d9685182b6e1 100644 --- a/op-chain-ops/deployer/opsm/opchain.go +++ b/op-chain-ops/deployer/opcm/opchain.go @@ -1,4 +1,4 @@ -package opsm +package opcm import ( "fmt" @@ -26,7 +26,7 @@ type DeployOPChainInput struct { BasefeeScalar uint32 BlobBaseFeeScalar uint32 L2ChainId *big.Int - OpsmProxy common.Address + OpcmProxy common.Address } func (input *DeployOPChainInput) InputSet() bool { diff --git a/op-chain-ops/deployer/opsm/standard-versions.toml b/op-chain-ops/deployer/opcm/standard-versions.toml similarity index 100% rename from op-chain-ops/deployer/opsm/standard-versions.toml rename to op-chain-ops/deployer/opcm/standard-versions.toml diff --git a/op-chain-ops/deployer/opsm/standard.go b/op-chain-ops/deployer/opcm/standard.go similarity index 88% rename from op-chain-ops/deployer/opsm/standard.go rename to op-chain-ops/deployer/opcm/standard.go index 56f0d7ada37b..9f182ca4685c 100644 --- a/op-chain-ops/deployer/opsm/standard.go +++ b/op-chain-ops/deployer/opcm/standard.go @@ -1,4 +1,4 @@ -package opsm +package opcm import "embed" diff --git a/op-chain-ops/deployer/opsm/superchain.go b/op-chain-ops/deployer/opcm/superchain.go similarity index 99% rename from op-chain-ops/deployer/opsm/superchain.go rename to op-chain-ops/deployer/opcm/superchain.go index d27f85499021..34804cc2bbdf 100644 --- a/op-chain-ops/deployer/opsm/superchain.go +++ b/op-chain-ops/deployer/opcm/superchain.go @@ -1,4 +1,4 @@ -package opsm +package opcm import ( "fmt" diff --git a/op-chain-ops/deployer/pipeline/implementations.go b/op-chain-ops/deployer/pipeline/implementations.go index 0dcda8feea19..5c5a1e99287c 100644 --- a/op-chain-ops/deployer/pipeline/implementations.go +++ b/op-chain-ops/deployer/pipeline/implementations.go @@ -5,7 +5,7 @@ import ( "fmt" "math/big" - "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opsm" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opcm" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" "github.com/ethereum-optimism/optimism/op-chain-ops/script" @@ -22,7 +22,7 @@ func DeployImplementations(ctx context.Context, env *Env, artifactsFS foundry.St lgr.Info("deploying implementations") var dump *foundry.ForgeAllocs - var dio opsm.DeployImplementationsOutput + var dio opcm.DeployImplementationsOutput var err error err = CallScriptBroadcast( ctx, @@ -37,9 +37,9 @@ func DeployImplementations(ctx context.Context, env *Env, artifactsFS foundry.St Handler: func(host *script.Host) error { host.SetEnvVar("IMPL_SALT", st.Create2Salt.Hex()[2:]) host.ImportState(st.SuperchainDeployment.StateDump) - dio, err = opsm.DeployImplementations( + dio, err = opcm.DeployImplementations( host, - opsm.DeployImplementationsInput{ + opcm.DeployImplementationsInput{ Salt: st.Create2Salt, WithdrawalDelaySeconds: big.NewInt(604800), MinProposalSizeBytes: big.NewInt(126000), @@ -50,7 +50,7 @@ func DeployImplementations(ctx context.Context, env *Env, artifactsFS foundry.St SuperchainConfigProxy: st.SuperchainDeployment.SuperchainConfigProxyAddress, ProtocolVersionsProxy: st.SuperchainDeployment.ProtocolVersionsProxyAddress, SuperchainProxyAdmin: st.SuperchainDeployment.ProxyAdminAddress, - StandardVersionsToml: opsm.StandardVersionsData, + StandardVersionsToml: opcm.StandardVersionsData, UseInterop: false, }, ) @@ -70,7 +70,7 @@ func DeployImplementations(ctx context.Context, env *Env, artifactsFS foundry.St } st.ImplementationsDeployment = &state.ImplementationsDeployment{ - OpsmProxyAddress: dio.OpsmProxy, + OpcmProxyAddress: dio.OpcmProxy, DelayedWETHImplAddress: dio.DelayedWETHImpl, OptimismPortalImplAddress: dio.OptimismPortalImpl, PreimageOracleSingletonAddress: dio.PreimageOracleSingleton, diff --git a/op-chain-ops/deployer/pipeline/l2genesis.go b/op-chain-ops/deployer/pipeline/l2genesis.go index f74c6e833620..25aa316c78a5 100644 --- a/op-chain-ops/deployer/pipeline/l2genesis.go +++ b/op-chain-ops/deployer/pipeline/l2genesis.go @@ -8,7 +8,7 @@ import ( "fmt" "math/big" - "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opsm" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opcm" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" "github.com/ethereum-optimism/optimism/op-chain-ops/script" @@ -47,8 +47,8 @@ func GenerateL2Genesis(ctx context.Context, env *Env, artifactsFS foundry.StatDi Client: env.L1Client, Broadcaster: DiscardBroadcaster, Handler: func(host *script.Host) error { - err := opsm.L2Genesis(host, &opsm.L2GenesisInput{ - L1Deployments: opsm.L1Deployments{ + err := opcm.L2Genesis(host, &opcm.L2GenesisInput{ + L1Deployments: opcm.L1Deployments{ L1CrossDomainMessengerProxy: thisChainState.L1CrossDomainMessengerProxyAddress, L1StandardBridgeProxy: thisChainState.L1StandardBridgeProxyAddress, L1ERC721BridgeProxy: thisChainState.L1ERC721BridgeProxyAddress, diff --git a/op-chain-ops/deployer/pipeline/opchain.go b/op-chain-ops/deployer/pipeline/opchain.go index 90d03b028142..1ae37970d7d1 100644 --- a/op-chain-ops/deployer/pipeline/opchain.go +++ b/op-chain-ops/deployer/pipeline/opchain.go @@ -5,7 +5,7 @@ import ( "fmt" "math/big" - "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opsm" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opcm" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" "github.com/ethereum-optimism/optimism/op-chain-ops/script" @@ -27,7 +27,7 @@ func DeployOPChain(ctx context.Context, env *Env, artifactsFS foundry.StatDirFs, return fmt.Errorf("failed to get chain intent: %w", err) } - var dco opsm.DeployOPChainOutput + var dco opcm.DeployOPChainOutput err = CallScriptBroadcast( ctx, CallScriptBroadcastOpts{ @@ -40,9 +40,9 @@ func DeployOPChain(ctx context.Context, env *Env, artifactsFS foundry.StatDirFs, Broadcaster: KeyedBroadcaster, Handler: func(host *script.Host) error { host.ImportState(st.ImplementationsDeployment.StateDump) - dco, err = opsm.DeployOPChain( + dco, err = opcm.DeployOPChain( host, - opsm.DeployOPChainInput{ + opcm.DeployOPChainInput{ OpChainProxyAdminOwner: thisIntent.Roles.ProxyAdminOwner, SystemConfigOwner: thisIntent.Roles.SystemConfigOwner, Batcher: thisIntent.Roles.Batcher, @@ -52,7 +52,7 @@ func DeployOPChain(ctx context.Context, env *Env, artifactsFS foundry.StatDirFs, BasefeeScalar: 1368, BlobBaseFeeScalar: 801949, L2ChainId: chainID.Big(), - OpsmProxy: st.ImplementationsDeployment.OpsmProxyAddress, + OpcmProxy: st.ImplementationsDeployment.OpcmProxyAddress, }, ) return err diff --git a/op-chain-ops/deployer/pipeline/superchain.go b/op-chain-ops/deployer/pipeline/superchain.go index 21aeda0e23dc..cc1b8d04160c 100644 --- a/op-chain-ops/deployer/pipeline/superchain.go +++ b/op-chain-ops/deployer/pipeline/superchain.go @@ -7,7 +7,7 @@ import ( "github.com/ethereum-optimism/optimism/op-chain-ops/script" - "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opsm" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opcm" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" "github.com/ethereum-optimism/optimism/op-node/rollup" @@ -24,7 +24,7 @@ func DeploySuperchain(ctx context.Context, env *Env, artifactsFS foundry.StatDir lgr.Info("deploying superchain") var dump *foundry.ForgeAllocs - var dso opsm.DeploySuperchainOutput + var dso opcm.DeploySuperchainOutput var err error err = CallScriptBroadcast( ctx, @@ -37,9 +37,9 @@ func DeploySuperchain(ctx context.Context, env *Env, artifactsFS foundry.StatDir Client: env.L1Client, Broadcaster: KeyedBroadcaster, Handler: func(host *script.Host) error { - dso, err = opsm.DeploySuperchain( + dso, err = opcm.DeploySuperchain( host, - opsm.DeploySuperchainInput{ + opcm.DeploySuperchainInput{ ProxyAdminOwner: intent.SuperchainRoles.ProxyAdminOwner, ProtocolVersionsOwner: intent.SuperchainRoles.ProtocolVersionsOwner, Guardian: intent.SuperchainRoles.Guardian, diff --git a/op-chain-ops/deployer/state/state.go b/op-chain-ops/deployer/state/state.go index 098fa7a731d7..674e06d743a0 100644 --- a/op-chain-ops/deployer/state/state.go +++ b/op-chain-ops/deployer/state/state.go @@ -65,7 +65,7 @@ type SuperchainDeployment struct { } type ImplementationsDeployment struct { - OpsmProxyAddress common.Address `json:"opsmProxyAddress"` + OpcmProxyAddress common.Address `json:"opcmProxyAddress"` DelayedWETHImplAddress common.Address `json:"delayedWETHImplAddress"` OptimismPortalImplAddress common.Address `json:"optimismPortalImplAddress"` PreimageOracleSingletonAddress common.Address `json:"preimageOracleSingletonAddress"` diff --git a/op-chain-ops/interopgen/configs.go b/op-chain-ops/interopgen/configs.go index 9abe9880fe8b..f40d29904c2f 100644 --- a/op-chain-ops/interopgen/configs.go +++ b/op-chain-ops/interopgen/configs.go @@ -33,7 +33,7 @@ type SuperFaultProofConfig struct { DisputeGameFinalityDelaySeconds *big.Int } -type OPSMImplementationsConfig struct { +type OPCMImplementationsConfig struct { Release string FaultProof SuperFaultProofConfig @@ -51,7 +51,7 @@ type SuperchainConfig struct { Paused bool - Implementations OPSMImplementationsConfig + Implementations OPCMImplementationsConfig genesis.SuperchainL1DeployConfig } diff --git a/op-chain-ops/interopgen/deploy.go b/op-chain-ops/interopgen/deploy.go index 9da41e9894d8..692a80d3225e 100644 --- a/op-chain-ops/interopgen/deploy.go +++ b/op-chain-ops/interopgen/deploy.go @@ -5,13 +5,12 @@ import ( "fmt" "math/big" - "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opsm" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opcm" "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" "github.com/ethereum-optimism/optimism/op-chain-ops/genesis/beacondeposit" @@ -149,7 +148,7 @@ func prepareInitialL1(l1Host *script.Host, cfg *L1Config) (*L1Deployment, error) func deploySuperchainToL1(l1Host *script.Host, superCfg *SuperchainConfig) (*SuperchainDeployment, error) { l1Host.SetTxOrigin(superCfg.Deployer) - superDeployment, err := opsm.DeploySuperchain(l1Host, opsm.DeploySuperchainInput{ + superDeployment, err := opcm.DeploySuperchain(l1Host, opcm.DeploySuperchainInput{ ProxyAdminOwner: superCfg.ProxyAdminOwner, ProtocolVersionsOwner: superCfg.ProtocolVersionsOwner, Guardian: superCfg.SuperchainConfigGuardian, @@ -161,7 +160,7 @@ func deploySuperchainToL1(l1Host *script.Host, superCfg *SuperchainConfig) (*Sup return nil, fmt.Errorf("failed to deploy Superchain contracts: %w", err) } - implementationsDeployment, err := opsm.DeployImplementations(l1Host, opsm.DeployImplementationsInput{ + implementationsDeployment, err := opcm.DeployImplementations(l1Host, opcm.DeployImplementationsInput{ WithdrawalDelaySeconds: superCfg.Implementations.FaultProof.WithdrawalDelaySeconds, MinProposalSizeBytes: superCfg.Implementations.FaultProof.MinProposalSizeBytes, ChallengePeriodSeconds: superCfg.Implementations.FaultProof.ChallengePeriodSeconds, @@ -172,7 +171,7 @@ func deploySuperchainToL1(l1Host *script.Host, superCfg *SuperchainConfig) (*Sup ProtocolVersionsProxy: superDeployment.ProtocolVersionsProxy, SuperchainProxyAdmin: superDeployment.SuperchainProxyAdmin, UseInterop: superCfg.Implementations.UseInterop, - StandardVersionsToml: opsm.StandardVersionsData, + StandardVersionsToml: opcm.StandardVersionsData, }) if err != nil { return nil, fmt.Errorf("failed to deploy Implementations contracts: %w", err) @@ -197,7 +196,7 @@ func deployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme l1Host.SetTxOrigin(cfg.Deployer) - output, err := opsm.DeployOPChain(l1Host, opsm.DeployOPChainInput{ + output, err := opcm.DeployOPChain(l1Host, opcm.DeployOPChainInput{ OpChainProxyAdminOwner: cfg.ProxyAdminOwner, SystemConfigOwner: cfg.SystemConfigOwner, Batcher: cfg.BatchSenderAddress, @@ -207,7 +206,7 @@ func deployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme BasefeeScalar: cfg.GasPriceOracleBaseFeeScalar, BlobBaseFeeScalar: cfg.GasPriceOracleBlobBaseFeeScalar, L2ChainId: new(big.Int).SetUint64(cfg.L2ChainID), - OpsmProxy: superDeployment.OpsmProxy, + OpcmProxy: superDeployment.OpcmProxy, }) if err != nil { return nil, fmt.Errorf("failed to deploy L2 OP chain: %w", err) @@ -220,8 +219,8 @@ func deployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme } func genesisL2(l2Host *script.Host, cfg *L2Config, deployment *L2Deployment) error { - if err := opsm.L2Genesis(l2Host, &opsm.L2GenesisInput{ - L1Deployments: opsm.L1Deployments{ + if err := opcm.L2Genesis(l2Host, &opcm.L2GenesisInput{ + L1Deployments: opcm.L1Deployments{ L1CrossDomainMessengerProxy: deployment.L1CrossDomainMessengerProxy, L1StandardBridgeProxy: deployment.L1StandardBridgeProxy, L1ERC721BridgeProxy: deployment.L1ERC721BridgeProxy, diff --git a/op-chain-ops/interopgen/deployments.go b/op-chain-ops/interopgen/deployments.go index b6bb124d8e85..ba18fbfdf9bd 100644 --- a/op-chain-ops/interopgen/deployments.go +++ b/op-chain-ops/interopgen/deployments.go @@ -9,8 +9,8 @@ type L1Deployment struct { } type Implementations struct { - OpsmProxy common.Address `json:"OPSMProxy"` - OpsmImpl common.Address `json:"OPSMImpl"` + OpcmProxy common.Address `json:"OPCMProxy"` + OpcmImpl common.Address `json:"OPCMImpl"` DelayedWETHImpl common.Address `json:"DelayedWETHImpl"` OptimismPortalImpl common.Address `json:"OptimismPortalImpl"` PreimageOracleSingleton common.Address `json:"PreimageOracleSingleton"` diff --git a/op-chain-ops/interopgen/recipe.go b/op-chain-ops/interopgen/recipe.go index 4dbe58e4ca1f..eea42b87e0a4 100644 --- a/op-chain-ops/interopgen/recipe.go +++ b/op-chain-ops/interopgen/recipe.go @@ -8,7 +8,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/params" - "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opsm" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opcm" "github.com/ethereum-optimism/optimism/op-chain-ops/devkeys" "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" ) @@ -67,7 +67,7 @@ func (r *InteropDevRecipe) Build(addrs devkeys.Addresses) (*WorldConfig, error) ProxyAdminOwner: superchainProxyAdmin, ProtocolVersionsOwner: superchainProtocolVersionsOwner, Deployer: superchainDeployer, - Implementations: OPSMImplementationsConfig{ + Implementations: OPCMImplementationsConfig{ Release: "dev", FaultProof: SuperFaultProofConfig{ WithdrawalDelaySeconds: big.NewInt(604800), @@ -77,7 +77,7 @@ func (r *InteropDevRecipe) Build(addrs devkeys.Addresses) (*WorldConfig, error) DisputeGameFinalityDelaySeconds: big.NewInt(6), }, UseInterop: true, - StandardVersionsToml: opsm.StandardVersionsData, + StandardVersionsToml: opcm.StandardVersionsData, }, SuperchainL1DeployConfig: genesis.SuperchainL1DeployConfig{ RequiredProtocolVersion: params.OPStackSupport, diff --git a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol index df950fed71f2..bdebf297c3f6 100644 --- a/packages/contracts-bedrock/scripts/DeployImplementations.s.sol +++ b/packages/contracts-bedrock/scripts/DeployImplementations.s.sol @@ -28,7 +28,7 @@ import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; -import { OPStackManager } from "src/L1/OPStackManager.sol"; +import { OPContractsManager } from "src/L1/OPContractsManager.sol"; import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; @@ -36,7 +36,7 @@ import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; -import { OPStackManagerInterop } from "src/L1/OPStackManagerInterop.sol"; +import { OPContractsManagerInterop } from "src/L1/OPContractsManagerInterop.sol"; import { OptimismPortalInterop } from "src/L1/OptimismPortalInterop.sol"; import { SystemConfigInterop } from "src/L1/SystemConfigInterop.sol"; @@ -55,7 +55,7 @@ contract DeployImplementationsInput is BaseDeployIO { uint256 internal _proofMaturityDelaySeconds; uint256 internal _disputeGameFinalityDelaySeconds; - // The release version to set OPSM implementations for, of the format `op-contracts/vX.Y.Z`. + // The release version to set OPCM implementations for, of the format `op-contracts/vX.Y.Z`. string internal _release; // Outputs from DeploySuperchain.s.sol. @@ -166,8 +166,8 @@ contract DeployImplementationsInput is BaseDeployIO { } contract DeployImplementationsOutput is BaseDeployIO { - OPStackManager internal _opsmProxy; - OPStackManager internal _opsmImpl; + OPContractsManager internal _opcmProxy; + OPContractsManager internal _opcmImpl; DelayedWETH internal _delayedWETHImpl; OptimismPortal2 internal _optimismPortalImpl; PreimageOracle internal _preimageOracleSingleton; @@ -183,8 +183,8 @@ contract DeployImplementationsOutput is BaseDeployIO { require(_addr != address(0), "DeployImplementationsOutput: cannot set zero address"); // forgefmt: disable-start - if (sel == this.opsmProxy.selector) _opsmProxy = OPStackManager(payable(_addr)); - else if (sel == this.opsmImpl.selector) _opsmImpl = OPStackManager(payable(_addr)); + if (sel == this.opcmProxy.selector) _opcmProxy = OPContractsManager(payable(_addr)); + else if (sel == this.opcmImpl.selector) _opcmImpl = OPContractsManager(payable(_addr)); else if (sel == this.optimismPortalImpl.selector) _optimismPortalImpl = OptimismPortal2(payable(_addr)); else if (sel == this.delayedWETHImpl.selector) _delayedWETHImpl = DelayedWETH(payable(_addr)); else if (sel == this.preimageOracleSingleton.selector) _preimageOracleSingleton = PreimageOracle(_addr); @@ -203,8 +203,8 @@ contract DeployImplementationsOutput is BaseDeployIO { // With 12 addresses, we'd get a stack too deep error if we tried to do this inline as a // single call to `Solarray.addresses`. So we split it into two calls. address[] memory addrs1 = Solarray.addresses( - address(this.opsmProxy()), - address(this.opsmImpl()), + address(this.opcmProxy()), + address(this.opcmImpl()), address(this.optimismPortalImpl()), address(this.delayedWETHImpl()), address(this.preimageOracleSingleton()), @@ -225,15 +225,15 @@ contract DeployImplementationsOutput is BaseDeployIO { assertValidDeploy(_dii); } - function opsmProxy() public returns (OPStackManager) { - DeployUtils.assertValidContractAddress(address(_opsmProxy)); - DeployUtils.assertImplementationSet(address(_opsmProxy)); - return _opsmProxy; + function opcmProxy() public returns (OPContractsManager) { + DeployUtils.assertValidContractAddress(address(_opcmProxy)); + DeployUtils.assertImplementationSet(address(_opcmProxy)); + return _opcmProxy; } - function opsmImpl() public view returns (OPStackManager) { - DeployUtils.assertValidContractAddress(address(_opsmImpl)); - return _opsmImpl; + function opcmImpl() public view returns (OPContractsManager) { + DeployUtils.assertValidContractAddress(address(_opcmImpl)); + return _opcmImpl; } function optimismPortalImpl() public view returns (OptimismPortal2) { @@ -294,35 +294,35 @@ contract DeployImplementationsOutput is BaseDeployIO { assertValidL1ERC721BridgeImpl(_dii); assertValidL1StandardBridgeImpl(_dii); assertValidMipsSingleton(_dii); - assertValidOpsmProxy(_dii); - assertValidOpsmImpl(_dii); + assertValidOpcmProxy(_dii); + assertValidOpcmImpl(_dii); assertValidOptimismMintableERC20FactoryImpl(_dii); assertValidOptimismPortalImpl(_dii); assertValidPreimageOracleSingleton(_dii); assertValidSystemConfigImpl(_dii); } - function assertValidOpsmProxy(DeployImplementationsInput _dii) internal { + function assertValidOpcmProxy(DeployImplementationsInput _dii) internal { // First we check the proxy as itself. - Proxy proxy = Proxy(payable(address(opsmProxy()))); + Proxy proxy = Proxy(payable(address(opcmProxy()))); vm.prank(address(0)); address admin = proxy.admin(); - require(admin == address(_dii.superchainProxyAdmin()), "OPSMP-10"); + require(admin == address(_dii.superchainProxyAdmin()), "OPCMP-10"); - // Then we check the proxy as OPSM. - DeployUtils.assertInitialized({ _contractAddress: address(opsmProxy()), _slot: 0, _offset: 0 }); - require(address(opsmProxy().superchainConfig()) == address(_dii.superchainConfigProxy()), "OPSMP-20"); - require(address(opsmProxy().protocolVersions()) == address(_dii.protocolVersionsProxy()), "OPSMP-30"); - require(LibString.eq(opsmProxy().latestRelease(), _dii.release()), "OPSMP-50"); // Initial release is latest. + // Then we check the proxy as OPCM. + DeployUtils.assertInitialized({ _contractAddress: address(opcmProxy()), _slot: 0, _offset: 0 }); + require(address(opcmProxy().superchainConfig()) == address(_dii.superchainConfigProxy()), "OPCMP-20"); + require(address(opcmProxy().protocolVersions()) == address(_dii.protocolVersionsProxy()), "OPCMP-30"); + require(LibString.eq(opcmProxy().latestRelease(), _dii.release()), "OPCMP-50"); // Initial release is latest. } - function assertValidOpsmImpl(DeployImplementationsInput _dii) internal { - Proxy proxy = Proxy(payable(address(opsmProxy()))); + function assertValidOpcmImpl(DeployImplementationsInput _dii) internal { + Proxy proxy = Proxy(payable(address(opcmProxy()))); vm.prank(address(0)); - OPStackManager impl = OPStackManager(proxy.implementation()); + OPContractsManager impl = OPContractsManager(proxy.implementation()); DeployUtils.assertInitialized({ _contractAddress: address(impl), _slot: 0, _offset: 0 }); - require(address(impl.superchainConfig()) == address(_dii.superchainConfigProxy()), "OPSMI-10"); - require(address(impl.protocolVersions()) == address(_dii.protocolVersionsProxy()), "OPSMI-20"); + require(address(impl.superchainConfig()) == address(_dii.superchainConfigProxy()), "OPCMI-10"); + require(address(impl.protocolVersions()) == address(_dii.protocolVersionsProxy()), "OPCMI-20"); } function assertValidOptimismPortalImpl(DeployImplementationsInput) internal view { @@ -468,42 +468,42 @@ contract DeployImplementations is Script { deployMipsSingleton(_dii, _dio); deployDisputeGameFactoryImpl(_dii, _dio); - // Deploy the OP Stack Manager with the new implementations set. - deployOPStackManager(_dii, _dio); + // Deploy the OP Contracts Manager with the new implementations set. + deployOPContractsManager(_dii, _dio); _dio.checkOutput(_dii); } // -------- Deployment Steps -------- - // --- OP Stack Manager --- + // --- OP Contracts Manager --- - function opsmSystemConfigSetter( + function opcmSystemConfigSetter( DeployImplementationsInput, DeployImplementationsOutput _dio ) internal view virtual - returns (OPStackManager.ImplementationSetter memory) + returns (OPContractsManager.ImplementationSetter memory) { - return OPStackManager.ImplementationSetter({ + return OPContractsManager.ImplementationSetter({ name: "SystemConfig", - info: OPStackManager.Implementation(address(_dio.systemConfigImpl()), SystemConfig.initialize.selector) + info: OPContractsManager.Implementation(address(_dio.systemConfigImpl()), SystemConfig.initialize.selector) }); } - // Deploy and initialize a proxied OPStackManager. - function createOPSMContract( + // Deploy and initialize a proxied OPContractsManager. + function createOPCMContract( DeployImplementationsInput _dii, DeployImplementationsOutput _dio, - OPStackManager.Blueprints memory _blueprints, + OPContractsManager.Blueprints memory _blueprints, string memory _release, - OPStackManager.ImplementationSetter[] memory _setters + OPContractsManager.ImplementationSetter[] memory _setters ) internal virtual - returns (OPStackManager opsmProxy_) + returns (OPContractsManager opcmProxy_) { ProxyAdmin proxyAdmin = _dii.superchainProxyAdmin(); @@ -511,29 +511,35 @@ contract DeployImplementations is Script { Proxy proxy = new Proxy(address(msg.sender)); deployOPContractsManagerImpl(_dii, _dio); - OPStackManager opsmImpl = _dio.opsmImpl(); + OPContractsManager opcmImpl = _dio.opcmImpl(); - OPStackManager.InitializerInputs memory initializerInputs = - OPStackManager.InitializerInputs(_blueprints, _setters, _release, true); + OPContractsManager.InitializerInputs memory initializerInputs = + OPContractsManager.InitializerInputs(_blueprints, _setters, _release, true); vm.startBroadcast(msg.sender); proxy.upgradeToAndCall( - address(opsmImpl), abi.encodeWithSelector(opsmImpl.initialize.selector, initializerInputs) + address(opcmImpl), abi.encodeWithSelector(opcmImpl.initialize.selector, initializerInputs) ); proxy.changeAdmin(address(proxyAdmin)); // transfer ownership of Proxy contract to the ProxyAdmin contract vm.stopBroadcast(); - opsmProxy_ = OPStackManager(address(proxy)); + opcmProxy_ = OPContractsManager(address(proxy)); } - function deployOPStackManager(DeployImplementationsInput _dii, DeployImplementationsOutput _dio) public virtual { + function deployOPContractsManager( + DeployImplementationsInput _dii, + DeployImplementationsOutput _dio + ) + public + virtual + { string memory release = _dii.release(); - // First we deploy the blueprints for the singletons deployed by OPSM. + // First we deploy the blueprints for the singletons deployed by OPCM. // forgefmt: disable-start bytes32 salt = _dii.salt(); - OPStackManager.Blueprints memory blueprints; + OPContractsManager.Blueprints memory blueprints; vm.startBroadcast(msg.sender); blueprints.addressManager = deployBytecode(Blueprint.blueprintDeployerBytecode(type(AddressManager).creationCode), salt); @@ -546,54 +552,56 @@ contract DeployImplementations is Script { vm.stopBroadcast(); // forgefmt: disable-end - OPStackManager.ImplementationSetter[] memory setters = new OPStackManager.ImplementationSetter[](9); - setters[0] = OPStackManager.ImplementationSetter({ + OPContractsManager.ImplementationSetter[] memory setters = new OPContractsManager.ImplementationSetter[](9); + setters[0] = OPContractsManager.ImplementationSetter({ name: "L1ERC721Bridge", - info: OPStackManager.Implementation(address(_dio.l1ERC721BridgeImpl()), L1ERC721Bridge.initialize.selector) + info: OPContractsManager.Implementation(address(_dio.l1ERC721BridgeImpl()), L1ERC721Bridge.initialize.selector) }); - setters[1] = OPStackManager.ImplementationSetter({ + setters[1] = OPContractsManager.ImplementationSetter({ name: "OptimismPortal", - info: OPStackManager.Implementation(address(_dio.optimismPortalImpl()), OptimismPortal2.initialize.selector) + info: OPContractsManager.Implementation(address(_dio.optimismPortalImpl()), OptimismPortal2.initialize.selector) }); - setters[2] = opsmSystemConfigSetter(_dii, _dio); - setters[3] = OPStackManager.ImplementationSetter({ + setters[2] = opcmSystemConfigSetter(_dii, _dio); + setters[3] = OPContractsManager.ImplementationSetter({ name: "OptimismMintableERC20Factory", - info: OPStackManager.Implementation( + info: OPContractsManager.Implementation( address(_dio.optimismMintableERC20FactoryImpl()), OptimismMintableERC20Factory.initialize.selector ) }); - setters[4] = OPStackManager.ImplementationSetter({ + setters[4] = OPContractsManager.ImplementationSetter({ name: "L1CrossDomainMessenger", - info: OPStackManager.Implementation( + info: OPContractsManager.Implementation( address(_dio.l1CrossDomainMessengerImpl()), L1CrossDomainMessenger.initialize.selector ) }); - setters[5] = OPStackManager.ImplementationSetter({ + setters[5] = OPContractsManager.ImplementationSetter({ name: "L1StandardBridge", - info: OPStackManager.Implementation(address(_dio.l1StandardBridgeImpl()), L1StandardBridge.initialize.selector) + info: OPContractsManager.Implementation( + address(_dio.l1StandardBridgeImpl()), L1StandardBridge.initialize.selector + ) }); - setters[6] = OPStackManager.ImplementationSetter({ + setters[6] = OPContractsManager.ImplementationSetter({ name: "DisputeGameFactory", - info: OPStackManager.Implementation( + info: OPContractsManager.Implementation( address(_dio.disputeGameFactoryImpl()), DisputeGameFactory.initialize.selector ) }); - setters[7] = OPStackManager.ImplementationSetter({ + setters[7] = OPContractsManager.ImplementationSetter({ name: "DelayedWETH", - info: OPStackManager.Implementation(address(_dio.delayedWETHImpl()), DelayedWETH.initialize.selector) + info: OPContractsManager.Implementation(address(_dio.delayedWETHImpl()), DelayedWETH.initialize.selector) }); - setters[8] = OPStackManager.ImplementationSetter({ + setters[8] = OPContractsManager.ImplementationSetter({ name: "MIPS", // MIPS is a singleton for all chains, so it doesn't need to be initialized, so the // selector is just `bytes4(0)`. - info: OPStackManager.Implementation(address(_dio.mipsSingleton()), bytes4(0)) + info: OPContractsManager.Implementation(address(_dio.mipsSingleton()), bytes4(0)) }); - // This call contains a broadcast to deploy OPSM which is proxied. - OPStackManager opsmProxy = createOPSMContract(_dii, _dio, blueprints, release, setters); + // This call contains a broadcast to deploy OPCM which is proxied. + OPContractsManager opcmProxy = createOPCMContract(_dii, _dio, blueprints, release, setters); - vm.label(address(opsmProxy), "OPStackManager"); - _dio.set(_dio.opsmProxy.selector, address(opsmProxy)); + vm.label(address(opcmProxy), "OPContractsManager"); + _dio.set(_dio.opcmProxy.selector, address(opcmProxy)); } // --- Core Contracts --- @@ -736,10 +744,10 @@ contract DeployImplementations is Script { vm.broadcast(msg.sender); // TODO: Eventually we will want to select the correct implementation based on the release. - OPStackManager impl = new OPStackManager(superchainConfigProxy, protocolVersionsProxy); + OPContractsManager impl = new OPContractsManager(superchainConfigProxy, protocolVersionsProxy); - vm.label(address(impl), "OPStackManagerImpl"); - _dio.set(_dio.opsmImpl.selector, address(impl)); + vm.label(address(impl), "OPContractsManagerImpl"); + _dio.set(_dio.opcmImpl.selector, address(impl)); } // --- Fault Proofs Contracts --- @@ -968,7 +976,7 @@ contract DeployImplementations is Script { // architecture, this comment block documents how to update the deploy scripts to support new features. // // Using the base scripts and contracts (DeploySuperchain, DeployImplementations, DeployOPChain, and -// the corresponding OPStackManager) deploys a standard chain. For nonstandard and in-development +// the corresponding OPContractsManager) deploys a standard chain. For nonstandard and in-development // features we need to modify some or all of those contracts, and we do that via inheritance. Using // interop as an example, they've made the following changes to L1 contracts: // - `OptimismPortalInterop is OptimismPortal`: A different portal implementation is used, and @@ -981,32 +989,32 @@ contract DeployImplementations is Script { // Similar to how inheritance was used to develop the new portal and system config contracts, we use // inheritance to modify up to all of the deployer contracts. For this interop example, what this // means is we need: -// - An `OPStackManagerInterop is OPStackManager` that knows how to encode the calldata for the +// - An `OPContractsManagerInterop is OPContractsManager` that knows how to encode the calldata for the // new system config initializer. // - A `DeployImplementationsInterop is DeployImplementations` that: // - Deploys OptimismPortalInterop instead of OptimismPortal. // - Deploys SystemConfigInterop instead of SystemConfig. -// - Deploys OPStackManagerInterop instead of OPStackManager, which contains the updated logic +// - Deploys OPContractsManagerInterop instead of OPContractsManager, which contains the updated logic // for encoding the SystemConfig initializer. -// - Updates the OPSM release setter logic to use the updated initializer. +// - Updates the OPCM release setter logic to use the updated initializer. // - A `DeployOPChainInterop is DeployOPChain` that allows the updated input parameter to be passed. // // Most of the complexity in the above flow comes from the the new input for the updated SystemConfig // initializer. If all function signatures were the same, all we'd have to change is the contract -// implementations that are deployed then set in the OPSM. For now, to simplify things until we +// implementations that are deployed then set in the OPCM. For now, to simplify things until we // resolve https://github.com/ethereum-optimism/optimism/issues/11783, we just assume this new role // is the same as the proxy admin owner. contract DeployImplementationsInterop is DeployImplementations { - function createOPSMContract( + function createOPCMContract( DeployImplementationsInput _dii, DeployImplementationsOutput _dio, - OPStackManager.Blueprints memory _blueprints, + OPContractsManager.Blueprints memory _blueprints, string memory _release, - OPStackManager.ImplementationSetter[] memory _setters + OPContractsManager.ImplementationSetter[] memory _setters ) internal override - returns (OPStackManager opsmProxy_) + returns (OPContractsManager opcmProxy_) { ProxyAdmin proxyAdmin = _dii.superchainProxyAdmin(); @@ -1014,20 +1022,20 @@ contract DeployImplementationsInterop is DeployImplementations { Proxy proxy = new Proxy(address(msg.sender)); deployOPContractsManagerImpl(_dii, _dio); // overriding function - OPStackManager opsmImpl = _dio.opsmImpl(); + OPContractsManager opcmImpl = _dio.opcmImpl(); - OPStackManager.InitializerInputs memory initializerInputs = - OPStackManager.InitializerInputs(_blueprints, _setters, _release, true); + OPContractsManager.InitializerInputs memory initializerInputs = + OPContractsManager.InitializerInputs(_blueprints, _setters, _release, true); vm.startBroadcast(msg.sender); proxy.upgradeToAndCall( - address(opsmImpl), abi.encodeWithSelector(opsmImpl.initialize.selector, initializerInputs) + address(opcmImpl), abi.encodeWithSelector(opcmImpl.initialize.selector, initializerInputs) ); proxy.changeAdmin(address(proxyAdmin)); // transfer ownership of Proxy contract to the ProxyAdmin contract vm.stopBroadcast(); - opsmProxy_ = OPStackManagerInterop(address(proxy)); + opcmProxy_ = OPContractsManagerInterop(address(proxy)); } function deployOptimismPortalImpl( @@ -1097,24 +1105,26 @@ contract DeployImplementationsInterop is DeployImplementations { vm.broadcast(msg.sender); // TODO: Eventually we will want to select the correct implementation based on the release. - OPStackManager impl = new OPStackManagerInterop(superchainConfigProxy, protocolVersionsProxy); + OPContractsManager impl = new OPContractsManagerInterop(superchainConfigProxy, protocolVersionsProxy); - vm.label(address(impl), "OPStackManagerImpl"); - _dio.set(_dio.opsmImpl.selector, address(impl)); + vm.label(address(impl), "OPContractsManagerImpl"); + _dio.set(_dio.opcmImpl.selector, address(impl)); } - function opsmSystemConfigSetter( + function opcmSystemConfigSetter( DeployImplementationsInput, DeployImplementationsOutput _dio ) internal view override - returns (OPStackManager.ImplementationSetter memory) + returns (OPContractsManager.ImplementationSetter memory) { - return OPStackManager.ImplementationSetter({ + return OPContractsManager.ImplementationSetter({ name: "SystemConfig", - info: OPStackManager.Implementation(address(_dio.systemConfigImpl()), SystemConfigInterop.initialize.selector) + info: OPContractsManager.Implementation( + address(_dio.systemConfigImpl()), SystemConfigInterop.initialize.selector + ) }); } } diff --git a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol index e0df48cc6029..524f9896b2bd 100644 --- a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol @@ -26,7 +26,7 @@ import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; import { Claim, GameType, GameTypes, Hash, OutputRoot } from "src/dispute/lib/Types.sol"; -import { OPStackManager } from "src/L1/OPStackManager.sol"; +import { OPContractsManager } from "src/L1/OPContractsManager.sol"; import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; @@ -46,7 +46,7 @@ contract DeployOPChainInput is BaseDeployIO { uint32 internal _basefeeScalar; uint32 internal _blobBaseFeeScalar; uint256 internal _l2ChainId; - OPStackManager internal _opsmProxy; + OPContractsManager internal _opcmProxy; function set(bytes4 _sel, address _addr) public { require(_addr != address(0), "DeployOPChainInput: cannot set zero address"); @@ -56,7 +56,7 @@ contract DeployOPChainInput is BaseDeployIO { else if (_sel == this.unsafeBlockSigner.selector) _unsafeBlockSigner = _addr; else if (_sel == this.proposer.selector) _proposer = _addr; else if (_sel == this.challenger.selector) _challenger = _addr; - else if (_sel == this.opsmProxy.selector) _opsmProxy = OPStackManager(_addr); + else if (_sel == this.opcmProxy.selector) _opcmProxy = OPContractsManager(_addr); else revert("DeployOPChainInput: unknown selector"); } @@ -129,7 +129,7 @@ contract DeployOPChainInput is BaseDeployIO { // anchor root and deploy a new permissioned dispute game contract anyway. // // You can `console.logBytes(abi.encode(defaultStartingAnchorRoots))` to get the bytes that - // are hardcoded into `op-chain-ops/deployer/opsm/opchain.go` + // are hardcoded into `op-chain-ops/deployer/opcm/opchain.go` AnchorStateRegistry.StartingAnchorRoot[] memory defaultStartingAnchorRoots = new AnchorStateRegistry.StartingAnchorRoot[](1); defaultStartingAnchorRoots[0] = AnchorStateRegistry.StartingAnchorRoot({ @@ -139,10 +139,10 @@ contract DeployOPChainInput is BaseDeployIO { return abi.encode(defaultStartingAnchorRoots); } - // TODO: Check that opsm is proxied and it has an implementation. - function opsmProxy() public view returns (OPStackManager) { - require(address(_opsmProxy) != address(0), "DeployOPChainInput: not set"); - return _opsmProxy; + // TODO: Check that opcm is proxied and it has an implementation. + function opcmProxy() public view returns (OPContractsManager) { + require(address(_opcmProxy) != address(0), "DeployOPChainInput: not set"); + return _opcmProxy; } } @@ -309,8 +309,8 @@ contract DeployOPChainOutput is BaseDeployIO { require(GameType.unwrap(game.gameType()) == GameType.unwrap(GameTypes.PERMISSIONED_CANNON), "DPG-10"); require(Claim.unwrap(game.absolutePrestate()) == bytes32(hex"dead"), "DPG-20"); - OPStackManager opsm = _doi.opsmProxy(); - (address mips,) = opsm.implementations(opsm.latestRelease(), "MIPS"); + OPContractsManager opcm = _doi.opcmProxy(); + (address mips,) = opcm.implementations(opcm.latestRelease(), "MIPS"); require(game.vm() == IBigStepper(mips), "DPG-30"); require(address(game.weth()) == address(delayedWETHPermissionedGameProxy()), "DPG-40"); @@ -368,7 +368,7 @@ contract DeployOPChainOutput is BaseDeployIO { require(systemConfig.startBlock() == block.number, "SYSCON-140"); require( - systemConfig.batchInbox() == _doi.opsmProxy().chainIdToBatchInboxAddress(_doi.l2ChainId()), "SYSCON-150" + systemConfig.batchInbox() == _doi.opcmProxy().chainIdToBatchInboxAddress(_doi.l2ChainId()), "SYSCON-150" ); require(systemConfig.l1CrossDomainMessenger() == address(l1CrossDomainMessengerProxy()), "SYSCON-160"); @@ -393,7 +393,7 @@ contract DeployOPChainOutput is BaseDeployIO { require(address(messenger.PORTAL()) == address(optimismPortalProxy()), "L1xDM-30"); require(address(messenger.portal()) == address(optimismPortalProxy()), "L1xDM-40"); - require(address(messenger.superchainConfig()) == address(_doi.opsmProxy().superchainConfig()), "L1xDM-50"); + require(address(messenger.superchainConfig()) == address(_doi.opcmProxy().superchainConfig()), "L1xDM-50"); bytes32 xdmSenderSlot = vm.load(address(messenger), bytes32(uint256(204))); require(address(uint160(uint256(xdmSenderSlot))) == Constants.DEFAULT_L2_SENDER, "L1xDM-60"); @@ -409,7 +409,7 @@ contract DeployOPChainOutput is BaseDeployIO { require(address(bridge.messenger()) == address(messenger), "L1SB-20"); require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_STANDARD_BRIDGE, "L1SB-30"); require(address(bridge.otherBridge()) == Predeploys.L2_STANDARD_BRIDGE, "L1SB-40"); - require(address(bridge.superchainConfig()) == address(_doi.opsmProxy().superchainConfig()), "L1SB-50"); + require(address(bridge.superchainConfig()) == address(_doi.opcmProxy().superchainConfig()), "L1SB-50"); } function assertValidOptimismMintableERC20Factory(DeployOPChainInput) internal view { @@ -431,12 +431,12 @@ contract DeployOPChainOutput is BaseDeployIO { require(address(bridge.MESSENGER()) == address(l1CrossDomainMessengerProxy()), "L721B-30"); require(address(bridge.messenger()) == address(l1CrossDomainMessengerProxy()), "L721B-40"); - require(address(bridge.superchainConfig()) == address(_doi.opsmProxy().superchainConfig()), "L721B-50"); + require(address(bridge.superchainConfig()) == address(_doi.opcmProxy().superchainConfig()), "L721B-50"); } function assertValidOptimismPortal(DeployOPChainInput _doi) internal view { OptimismPortal2 portal = optimismPortalProxy(); - ISuperchainConfig superchainConfig = ISuperchainConfig(address(_doi.opsmProxy().superchainConfig())); + ISuperchainConfig superchainConfig = ISuperchainConfig(address(_doi.opcmProxy().superchainConfig())); require(address(portal.disputeGameFactory()) == address(disputeGameFactoryProxy()), "PORTAL-10"); require(address(portal.systemConfig()) == address(systemConfigProxy()), "PORTAL-20"); @@ -470,9 +470,9 @@ contract DeployOPChain is Script { // -------- Core Deployment Methods -------- function run(DeployOPChainInput _doi, DeployOPChainOutput _doo) public { - OPStackManager opsmProxy = _doi.opsmProxy(); + OPContractsManager opcmProxy = _doi.opcmProxy(); - OPStackManager.Roles memory roles = OPStackManager.Roles({ + OPContractsManager.Roles memory roles = OPContractsManager.Roles({ opChainProxyAdminOwner: _doi.opChainProxyAdminOwner(), systemConfigOwner: _doi.systemConfigOwner(), batcher: _doi.batcher(), @@ -480,7 +480,7 @@ contract DeployOPChain is Script { proposer: _doi.proposer(), challenger: _doi.challenger() }); - OPStackManager.DeployInput memory deployInput = OPStackManager.DeployInput({ + OPContractsManager.DeployInput memory deployInput = OPContractsManager.DeployInput({ roles: roles, basefeeScalar: _doi.basefeeScalar(), blobBasefeeScalar: _doi.blobBaseFeeScalar(), @@ -489,7 +489,7 @@ contract DeployOPChain is Script { }); vm.broadcast(msg.sender); - OPStackManager.DeployOutput memory deployOutput = opsmProxy.deploy(deployInput); + OPContractsManager.DeployOutput memory deployOutput = opcmProxy.deploy(deployInput); vm.label(address(deployOutput.opChainProxyAdmin), "opChainProxyAdmin"); vm.label(address(deployOutput.addressManager), "addressManager"); diff --git a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol index 365b67df7b47..5ca889bf409e 100644 --- a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol +++ b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol @@ -15,7 +15,7 @@ import { BaseDeployIO } from "scripts/utils/BaseDeployIO.sol"; // This comment block defines the requirements and rationale for the architecture used in this forge // script, along with other scripts that are being written as new Superchain-first deploy scripts to -// complement the OP Stack Manager. The script architecture is a bit different than a standard forge +// complement the OP Contracts Manager. The script architecture is a bit different than a standard forge // deployment script. // // There are three categories of users that are expected to interact with the scripts: diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index d88cbdba6bfd..b68db55580f2 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -31,9 +31,9 @@ "initCodeHash": "0x433fac9de52d8ce8fc3471b78ef6cc9cff1019f480c9ad91b6e09ab8738a8edb", "sourceCodeHash": "0xde4df0f9633dc0cdb1c9f634003ea5b0f7c5c1aebc407bc1b2f44c0ecf938649" }, - "src/L1/OPStackManager.sol": { + "src/L1/OPContractsManager.sol": { "initCodeHash": "0x92c72b75206e756742df25d67d295e4479e65db1473948b8f53cb4ca642025d5", - "sourceCodeHash": "0x3cbd30c68cad0dd18d49165bd21d94422b7403174f91a733e2398539dadf8656" + "sourceCodeHash": "0x5e04124ee67298d2f1245139baf7de79dee421d2c031c6e5abe0cd3b1bdbdb32" }, "src/L1/OptimismPortal.sol": { "initCodeHash": "0xbe2c0c81b3459014f287d8c89cdc0d27dde5d1f44e5d024fa1e4773ddc47c190", diff --git a/packages/contracts-bedrock/snapshots/abi/OPStackManager.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json similarity index 95% rename from packages/contracts-bedrock/snapshots/abi/OPStackManager.json rename to packages/contracts-bedrock/snapshots/abi/OPContractsManager.json index 9654f8f084ab..ca2f2ab8ac83 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPStackManager.json +++ b/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json @@ -62,7 +62,7 @@ "type": "address" } ], - "internalType": "struct OPStackManager.Blueprints", + "internalType": "struct OPContractsManager.Blueprints", "name": "", "type": "tuple" } @@ -126,7 +126,7 @@ "type": "address" } ], - "internalType": "struct OPStackManager.Roles", + "internalType": "struct OPContractsManager.Roles", "name": "roles", "type": "tuple" }, @@ -151,7 +151,7 @@ "type": "bytes" } ], - "internalType": "struct OPStackManager.DeployInput", + "internalType": "struct OPContractsManager.DeployInput", "name": "_input", "type": "tuple" } @@ -236,7 +236,7 @@ "type": "address" } ], - "internalType": "struct OPStackManager.DeployOutput", + "internalType": "struct OPContractsManager.DeployOutput", "name": "", "type": "tuple" } @@ -320,7 +320,7 @@ "type": "address" } ], - "internalType": "struct OPStackManager.Blueprints", + "internalType": "struct OPContractsManager.Blueprints", "name": "blueprints", "type": "tuple" }, @@ -344,12 +344,12 @@ "type": "bytes4" } ], - "internalType": "struct OPStackManager.Implementation", + "internalType": "struct OPContractsManager.Implementation", "name": "info", "type": "tuple" } ], - "internalType": "struct OPStackManager.ImplementationSetter[]", + "internalType": "struct OPContractsManager.ImplementationSetter[]", "name": "setters", "type": "tuple[]" }, @@ -364,7 +364,7 @@ "type": "bool" } ], - "internalType": "struct OPStackManager.InitializerInputs", + "internalType": "struct OPContractsManager.InitializerInputs", "name": "_initializerInputs", "type": "tuple" } diff --git a/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerInterop.json similarity index 95% rename from packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json rename to packages/contracts-bedrock/snapshots/abi/OPContractsManagerInterop.json index 9654f8f084ab..ca2f2ab8ac83 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPStackManagerInterop.json +++ b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerInterop.json @@ -62,7 +62,7 @@ "type": "address" } ], - "internalType": "struct OPStackManager.Blueprints", + "internalType": "struct OPContractsManager.Blueprints", "name": "", "type": "tuple" } @@ -126,7 +126,7 @@ "type": "address" } ], - "internalType": "struct OPStackManager.Roles", + "internalType": "struct OPContractsManager.Roles", "name": "roles", "type": "tuple" }, @@ -151,7 +151,7 @@ "type": "bytes" } ], - "internalType": "struct OPStackManager.DeployInput", + "internalType": "struct OPContractsManager.DeployInput", "name": "_input", "type": "tuple" } @@ -236,7 +236,7 @@ "type": "address" } ], - "internalType": "struct OPStackManager.DeployOutput", + "internalType": "struct OPContractsManager.DeployOutput", "name": "", "type": "tuple" } @@ -320,7 +320,7 @@ "type": "address" } ], - "internalType": "struct OPStackManager.Blueprints", + "internalType": "struct OPContractsManager.Blueprints", "name": "blueprints", "type": "tuple" }, @@ -344,12 +344,12 @@ "type": "bytes4" } ], - "internalType": "struct OPStackManager.Implementation", + "internalType": "struct OPContractsManager.Implementation", "name": "info", "type": "tuple" } ], - "internalType": "struct OPStackManager.ImplementationSetter[]", + "internalType": "struct OPContractsManager.ImplementationSetter[]", "name": "setters", "type": "tuple[]" }, @@ -364,7 +364,7 @@ "type": "bool" } ], - "internalType": "struct OPStackManager.InitializerInputs", + "internalType": "struct OPContractsManager.InitializerInputs", "name": "_initializerInputs", "type": "tuple" } diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OPStackManager.json b/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManager.json similarity index 84% rename from packages/contracts-bedrock/snapshots/storageLayout/OPStackManager.json rename to packages/contracts-bedrock/snapshots/storageLayout/OPContractsManager.json index c22ed7c2c8da..cbb977f214b4 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/OPStackManager.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManager.json @@ -25,7 +25,7 @@ "label": "implementations", "offset": 0, "slot": "2", - "type": "mapping(string => mapping(string => struct OPStackManager.Implementation))" + "type": "mapping(string => mapping(string => struct OPContractsManager.Implementation))" }, { "bytes": "32", @@ -39,7 +39,7 @@ "label": "blueprint", "offset": 0, "slot": "4", - "type": "struct OPStackManager.Blueprints" + "type": "struct OPContractsManager.Blueprints" }, { "bytes": "1600", diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OPStackManagerInterop.json b/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManagerInterop.json similarity index 84% rename from packages/contracts-bedrock/snapshots/storageLayout/OPStackManagerInterop.json rename to packages/contracts-bedrock/snapshots/storageLayout/OPContractsManagerInterop.json index c22ed7c2c8da..cbb977f214b4 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/OPStackManagerInterop.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManagerInterop.json @@ -25,7 +25,7 @@ "label": "implementations", "offset": 0, "slot": "2", - "type": "mapping(string => mapping(string => struct OPStackManager.Implementation))" + "type": "mapping(string => mapping(string => struct OPContractsManager.Implementation))" }, { "bytes": "32", @@ -39,7 +39,7 @@ "label": "blueprint", "offset": 0, "slot": "4", - "type": "struct OPStackManager.Blueprints" + "type": "struct OPContractsManager.Blueprints" }, { "bytes": "1600", diff --git a/packages/contracts-bedrock/src/L1/OPStackManager.sol b/packages/contracts-bedrock/src/L1/OPContractsManager.sol similarity index 98% rename from packages/contracts-bedrock/src/L1/OPStackManager.sol rename to packages/contracts-bedrock/src/L1/OPContractsManager.sol index 12e9a6f5cbdb..4f36897d637c 100644 --- a/packages/contracts-bedrock/src/L1/OPStackManager.sol +++ b/packages/contracts-bedrock/src/L1/OPContractsManager.sol @@ -40,7 +40,7 @@ import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; /// @custom:proxied true -contract OPStackManager is ISemver, Initializable { +contract OPContractsManager is ISemver, Initializable { // -------- Structs -------- /// @notice Represents the roles that can be set when deploying a standard OP Stack chain. @@ -113,7 +113,7 @@ contract OPStackManager is ISemver, Initializable { address permissionedDisputeGame2; } - /// @notice Inputs required when initializing the OPStackManager. To avoid 'StackTooDeep' errors, + /// @notice Inputs required when initializing the OPContractsManager. To avoid 'StackTooDeep' errors, /// all necessary inputs (excluding immutables) for initialization are bundled together in this struct. struct InitializerInputs { Blueprints blueprints; @@ -133,7 +133,7 @@ contract OPStackManager is ISemver, Initializable { /// @notice Address of the ProtocolVersions contract shared by all chains. ProtocolVersions public immutable protocolVersions; - /// @notice The latest release of the OP Stack Manager, as a string of the format `op-contracts/vX.Y.Z`. + /// @notice The latest release of the OP Contracts Manager, as a string of the format `op-contracts/vX.Y.Z`. string public latestRelease; /// @notice Maps a release version to a contract name to it's implementation data. @@ -181,7 +181,7 @@ contract OPStackManager is ISemver, Initializable { // -------- Methods -------- - /// @notice OPSM is proxied. Therefore the `initialize` function replaces most constructor logic for this contract. + /// @notice OPCM is proxied. Therefore the `initialize` function replaces most constructor logic for this contract. constructor(SuperchainConfig _superchainConfig, ProtocolVersions _protocolVersions) { assertValidContractAddress(address(_superchainConfig)); diff --git a/packages/contracts-bedrock/src/L1/OPStackManagerInterop.sol b/packages/contracts-bedrock/src/L1/OPContractsManagerInterop.sol similarity index 91% rename from packages/contracts-bedrock/src/L1/OPStackManagerInterop.sol rename to packages/contracts-bedrock/src/L1/OPContractsManagerInterop.sol index 0a4a88625c9d..90fa13e7455c 100644 --- a/packages/contracts-bedrock/src/L1/OPStackManagerInterop.sol +++ b/packages/contracts-bedrock/src/L1/OPContractsManagerInterop.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { OPStackManager } from "src/L1/OPStackManager.sol"; +import { OPContractsManager } from "src/L1/OPContractsManager.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; @@ -9,12 +9,12 @@ import { SystemConfig } from "src/L1/SystemConfig.sol"; import { SystemConfigInterop } from "src/L1/SystemConfigInterop.sol"; /// @custom:proxied true -contract OPStackManagerInterop is OPStackManager { +contract OPContractsManagerInterop is OPContractsManager { constructor( SuperchainConfig _superchainConfig, ProtocolVersions _protocolVersions ) - OPStackManager(_superchainConfig, _protocolVersions) + OPContractsManager(_superchainConfig, _protocolVersions) { } // The `SystemConfigInterop` contract has an extra `address _dependencyManager` argument diff --git a/packages/contracts-bedrock/test/DeployImplementations.t.sol b/packages/contracts-bedrock/test/DeployImplementations.t.sol index 1eac67c6fdf3..1dca71b4ec70 100644 --- a/packages/contracts-bedrock/test/DeployImplementations.t.sol +++ b/packages/contracts-bedrock/test/DeployImplementations.t.sol @@ -10,7 +10,7 @@ import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; -import { OPStackManager } from "src/L1/OPStackManager.sol"; +import { OPContractsManager } from "src/L1/OPContractsManager.sol"; import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; @@ -106,11 +106,11 @@ contract DeployImplementationsOutput_Test is Test { function test_set_succeeds() public { Proxy proxy = new Proxy(address(0)); - address opsmImpl = address(makeAddr("opsmImpl")); + address opcmImpl = address(makeAddr("opcmImpl")); vm.prank(address(0)); - proxy.upgradeTo(opsmImpl); + proxy.upgradeTo(opcmImpl); - OPStackManager opsmProxy = OPStackManager(address(proxy)); + OPContractsManager opcmProxy = OPContractsManager(address(proxy)); OptimismPortal2 optimismPortalImpl = OptimismPortal2(payable(makeAddr("optimismPortalImpl"))); DelayedWETH delayedWETHImpl = DelayedWETH(payable(makeAddr("delayedWETHImpl"))); PreimageOracle preimageOracleSingleton = PreimageOracle(makeAddr("preimageOracleSingleton")); @@ -124,8 +124,8 @@ contract DeployImplementationsOutput_Test is Test { OptimismMintableERC20Factory(makeAddr("optimismMintableERC20FactoryImpl")); DisputeGameFactory disputeGameFactoryImpl = DisputeGameFactory(makeAddr("disputeGameFactoryImpl")); - vm.etch(address(opsmProxy), address(opsmProxy).code); - vm.etch(address(opsmImpl), hex"01"); + vm.etch(address(opcmProxy), address(opcmProxy).code); + vm.etch(address(opcmImpl), hex"01"); vm.etch(address(optimismPortalImpl), hex"01"); vm.etch(address(delayedWETHImpl), hex"01"); vm.etch(address(preimageOracleSingleton), hex"01"); @@ -136,7 +136,7 @@ contract DeployImplementationsOutput_Test is Test { vm.etch(address(l1StandardBridgeImpl), hex"01"); vm.etch(address(optimismMintableERC20FactoryImpl), hex"01"); vm.etch(address(disputeGameFactoryImpl), hex"01"); - dio.set(dio.opsmProxy.selector, address(opsmProxy)); + dio.set(dio.opcmProxy.selector, address(opcmProxy)); dio.set(dio.optimismPortalImpl.selector, address(optimismPortalImpl)); dio.set(dio.delayedWETHImpl.selector, address(delayedWETHImpl)); dio.set(dio.preimageOracleSingleton.selector, address(preimageOracleSingleton)); @@ -148,7 +148,7 @@ contract DeployImplementationsOutput_Test is Test { dio.set(dio.optimismMintableERC20FactoryImpl.selector, address(optimismMintableERC20FactoryImpl)); dio.set(dio.disputeGameFactoryImpl.selector, address(disputeGameFactoryImpl)); - assertEq(address(opsmProxy), address(dio.opsmProxy()), "50"); + assertEq(address(opcmProxy), address(dio.opcmProxy()), "50"); assertEq(address(optimismPortalImpl), address(dio.optimismPortalImpl()), "100"); assertEq(address(delayedWETHImpl), address(dio.delayedWETHImpl()), "200"); assertEq(address(preimageOracleSingleton), address(dio.preimageOracleSingleton()), "300"); @@ -413,7 +413,7 @@ contract DeployImplementations_Test is Test { string memory release = string(bytes.concat(hash(_seed, 5))); protocolVersionsProxy = ProtocolVersions(address(uint160(uint256(hash(_seed, 7))))); - // Must configure the ProxyAdmin contract which is used to upgrade the OPSM's proxy contract. + // Must configure the ProxyAdmin contract which is used to upgrade the OPCM's proxy contract. ProxyAdmin superchainProxyAdmin = new ProxyAdmin(msg.sender); superchainConfigProxy = SuperchainConfig(address(new Proxy(payable(address(superchainProxyAdmin))))); diff --git a/packages/contracts-bedrock/test/DeployOPChain.t.sol b/packages/contracts-bedrock/test/DeployOPChain.t.sol index 732eea8b05bf..3cbc313cfe11 100644 --- a/packages/contracts-bedrock/test/DeployOPChain.t.sol +++ b/packages/contracts-bedrock/test/DeployOPChain.t.sol @@ -23,7 +23,7 @@ import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { ProtocolVersions, ProtocolVersion } from "src/L1/ProtocolVersions.sol"; -import { OPStackManager } from "src/L1/OPStackManager.sol"; +import { OPContractsManager } from "src/L1/OPContractsManager.sol"; import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; @@ -46,7 +46,7 @@ contract DeployOPChainInput_Test is Test { uint32 basefeeScalar = 100; uint32 blobBaseFeeScalar = 200; uint256 l2ChainId = 300; - OPStackManager opsm = OPStackManager(makeAddr("opsm")); + OPContractsManager opcm = OPContractsManager(makeAddr("opcm")); function setUp() public { doi = new DeployOPChainInput(); @@ -62,7 +62,7 @@ contract DeployOPChainInput_Test is Test { doi.set(doi.basefeeScalar.selector, basefeeScalar); doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar); doi.set(doi.l2ChainId.selector, l2ChainId); - doi.set(doi.opsmProxy.selector, address(opsm)); + doi.set(doi.opcmProxy.selector, address(opcm)); // Compare the default inputs to the getter methods. assertEq(opChainProxyAdminOwner, doi.opChainProxyAdminOwner(), "200"); assertEq(systemConfigOwner, doi.systemConfigOwner(), "300"); @@ -73,7 +73,7 @@ contract DeployOPChainInput_Test is Test { assertEq(basefeeScalar, doi.basefeeScalar(), "800"); assertEq(blobBaseFeeScalar, doi.blobBaseFeeScalar(), "900"); assertEq(l2ChainId, doi.l2ChainId(), "1000"); - assertEq(address(opsm), address(doi.opsmProxy()), "1100"); + assertEq(address(opcm), address(doi.opcmProxy()), "1100"); } function test_getters_whenNotSet_revert() public { @@ -328,7 +328,7 @@ contract DeployOPChain_TestBase is Test { ProtocolVersions protocolVersionsProxy; // Define default inputs for DeployOPChain. - // `opsm` is set during `setUp` since it is an output of the previous step. + // `opcm` is set during `setUp` since it is an output of the previous step. address opChainProxyAdminOwner = makeAddr("defaultOPChainProxyAdminOwner"); address systemConfigOwner = makeAddr("defaultSystemConfigOwner"); address batcher = makeAddr("defaultBatcher"); @@ -339,7 +339,7 @@ contract DeployOPChain_TestBase is Test { uint32 blobBaseFeeScalar = 200; uint256 l2ChainId = 300; AnchorStateRegistry.StartingAnchorRoot[] startingAnchorRoots; - OPStackManager opsm = OPStackManager(address(0)); + OPContractsManager opcm = OPContractsManager(address(0)); function setUp() public virtual { // Set defaults for reference types @@ -401,8 +401,8 @@ contract DeployOPChain_TestBase is Test { deployOPChain = new DeployOPChain(); (doi, doo) = deployOPChain.etchIOContracts(); - // Set the OPStackManager address as input to DeployOPChain. - opsm = dio.opsmProxy(); + // Set the OPContractsManager input for DeployOPChain. + opcm = dio.opcmProxy(); } // See the function of the same name in the `DeployImplementations_Test` contract of @@ -456,11 +456,11 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { doi.set(doi.basefeeScalar.selector, basefeeScalar); doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar); doi.set(doi.l2ChainId.selector, l2ChainId); - doi.set(doi.opsmProxy.selector, address(opsm)); // Not fuzzed since it must be an actual instance. + doi.set(doi.opcmProxy.selector, address(opcm)); // Not fuzzed since it must be an actual instance. deployOPChain.run(doi, doo); - // TODO Add fault proof contract assertions below once OPSM fully supports them. + // TODO Add fault proof contract assertions below once OPCM fully supports them. // Assert that individual input fields were properly set based on the inputs. assertEq(opChainProxyAdminOwner, doi.opChainProxyAdminOwner(), "100"); @@ -486,7 +486,7 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { // assertEq(address(doo.faultDisputeGame().proposer()), proposer, "2700"); // assertEq(address(doo.faultDisputeGame().challenger()), challenger, "2800"); - // Most architecture assertions are handled within the OP Stack Manager itself and therefore + // Most architecture assertions are handled within the OP Contracts Manager itself and therefore // we only assert on the things that are not visible onchain. // TODO add these assertions: AddressManager, Proxy, ProxyAdmin, etc. } diff --git a/packages/contracts-bedrock/test/L1/OPStackManager.t.sol b/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol similarity index 71% rename from packages/contracts-bedrock/test/L1/OPStackManager.t.sol rename to packages/contracts-bedrock/test/L1/OPContractsManager.t.sol index ea26a6dae0b3..7f52b702dd71 100644 --- a/packages/contracts-bedrock/test/L1/OPStackManager.t.sol +++ b/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol @@ -6,18 +6,18 @@ import { Test, stdStorage, StdStorage } from "forge-std/Test.sol"; import { DeployOPChainInput } from "scripts/DeployOPChain.s.sol"; import { DeployOPChain_TestBase } from "test/DeployOPChain.t.sol"; -import { OPStackManager } from "src/L1/OPStackManager.sol"; +import { OPContractsManager } from "src/L1/OPContractsManager.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; // Exposes internal functions for testing. -contract OPStackManager_Harness is OPStackManager { +contract OPContractsManager_Harness is OPContractsManager { constructor( SuperchainConfig _superchainConfig, ProtocolVersions _protocolVersions ) - OPStackManager(_superchainConfig, _protocolVersions) + OPContractsManager(_superchainConfig, _protocolVersions) { } function chainIdToBatchInboxAddress_exposed(uint256 l2ChainId) public pure returns (address) { @@ -26,12 +26,12 @@ contract OPStackManager_Harness is OPStackManager { } // Unlike other test suites, we intentionally do not inherit from CommonTest or Setup. This is -// because OPStackManager acts as a deploy script, so we start from a clean slate here and -// work OPStackManager's deployment into the existing test setup, instead of using the existing -// test setup to deploy OPStackManager. We do however inherit from DeployOPChain_TestBase so +// because OPContractsManager acts as a deploy script, so we start from a clean slate here and +// work OPContractsManager's deployment into the existing test setup, instead of using the existing +// test setup to deploy OPContractsManager. We do however inherit from DeployOPChain_TestBase so // we can use its setup to deploy the implementations similarly to how a real deployment would // happen. -contract OPStackManager_Deploy_Test is DeployOPChain_TestBase { +contract OPContractsManager_Deploy_Test is DeployOPChain_TestBase { using stdStorage for StdStorage; event Deployed(uint256 indexed l2ChainId, SystemConfig indexed systemConfig); @@ -48,14 +48,14 @@ contract OPStackManager_Deploy_Test is DeployOPChain_TestBase { doi.set(doi.basefeeScalar.selector, basefeeScalar); doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar); doi.set(doi.l2ChainId.selector, l2ChainId); - doi.set(doi.opsmProxy.selector, address(opsm)); + doi.set(doi.opcmProxy.selector, address(opcm)); } // This helper function is used to convert the input struct type defined in DeployOPChain.s.sol - // to the input struct type defined in OPStackManager.sol. - function toOPSMDeployInput(DeployOPChainInput _doi) internal view returns (OPStackManager.DeployInput memory) { - return OPStackManager.DeployInput({ - roles: OPStackManager.Roles({ + // to the input struct type defined in OPContractsManager.sol. + function toOPCMDeployInput(DeployOPChainInput _doi) internal view returns (OPContractsManager.DeployInput memory) { + return OPContractsManager.DeployInput({ + roles: OPContractsManager.Roles({ opChainProxyAdminOwner: _doi.opChainProxyAdminOwner(), systemConfigOwner: _doi.systemConfigOwner(), batcher: _doi.batcher(), @@ -71,30 +71,30 @@ contract OPStackManager_Deploy_Test is DeployOPChain_TestBase { } function test_deploy_l2ChainIdEqualsZero_reverts() public { - OPStackManager.DeployInput memory deployInput = toOPSMDeployInput(doi); + OPContractsManager.DeployInput memory deployInput = toOPCMDeployInput(doi); deployInput.l2ChainId = 0; - vm.expectRevert(OPStackManager.InvalidChainId.selector); - opsm.deploy(deployInput); + vm.expectRevert(OPContractsManager.InvalidChainId.selector); + opcm.deploy(deployInput); } function test_deploy_l2ChainIdEqualsCurrentChainId_reverts() public { - OPStackManager.DeployInput memory deployInput = toOPSMDeployInput(doi); + OPContractsManager.DeployInput memory deployInput = toOPCMDeployInput(doi); deployInput.l2ChainId = block.chainid; - vm.expectRevert(OPStackManager.InvalidChainId.selector); - opsm.deploy(deployInput); + vm.expectRevert(OPContractsManager.InvalidChainId.selector); + opcm.deploy(deployInput); } function test_deploy_succeeds() public { vm.expectEmit(true, false, true, true); // TODO precompute the system config address. emit Deployed(doi.l2ChainId(), SystemConfig(address(1))); - opsm.deploy(toOPSMDeployInput(doi)); + opcm.deploy(toOPCMDeployInput(doi)); } } // These tests use the harness which exposes internal functions for testing. -contract OPStackManager_InternalMethods_Test is Test { - OPStackManager_Harness opsmHarness; +contract OPContractsManager_InternalMethods_Test is Test { + OPContractsManager_Harness opcmHarness; function setUp() public { SuperchainConfig superchainConfigProxy = SuperchainConfig(makeAddr("superchainConfig")); @@ -102,7 +102,7 @@ contract OPStackManager_InternalMethods_Test is Test { vm.etch(address(superchainConfigProxy), hex"01"); vm.etch(address(protocolVersionsProxy), hex"01"); - opsmHarness = new OPStackManager_Harness({ + opcmHarness = new OPContractsManager_Harness({ _superchainConfig: superchainConfigProxy, _protocolVersions: protocolVersionsProxy }); @@ -114,12 +114,12 @@ contract OPStackManager_InternalMethods_Test is Test { // 2. Hash it and manually take the first 19 bytes, and prefixed it with 0x00. uint256 chainId = 1234; address expected = 0x0017FA14b0d73Aa6A26D6b8720c1c84b50984f5C; - address actual = opsmHarness.chainIdToBatchInboxAddress_exposed(chainId); + address actual = opcmHarness.chainIdToBatchInboxAddress_exposed(chainId); vm.assertEq(expected, actual); chainId = type(uint256).max; expected = 0x00a9C584056064687E149968cBaB758a3376D22A; - actual = opsmHarness.chainIdToBatchInboxAddress_exposed(chainId); + actual = opcmHarness.chainIdToBatchInboxAddress_exposed(chainId); vm.assertEq(expected, actual); } } diff --git a/packages/contracts-bedrock/test/Specs.t.sol b/packages/contracts-bedrock/test/Specs.t.sol index cb67549d4c9c..7f13a8800252 100644 --- a/packages/contracts-bedrock/test/Specs.t.sol +++ b/packages/contracts-bedrock/test/Specs.t.sol @@ -10,7 +10,7 @@ import { Executables } from "scripts/libraries/Executables.sol"; import { ForgeArtifacts, Abi, AbiEntry } from "scripts/libraries/ForgeArtifacts.sol"; // Contracts -import { OPStackManager } from "src/L1/OPStackManager.sol"; +import { OPContractsManager } from "src/L1/OPContractsManager.sol"; // Interfaces import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; @@ -836,29 +836,29 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "WETH98", _sel: _getSel("transferFrom(address,address,uint256)") }); _addSpec({ _name: "WETH98", _sel: _getSel("withdraw(uint256)") }); - // OPStackManager - _addSpec({ _name: "OPStackManager", _sel: _getSel("version()") }); - _addSpec({ _name: "OPStackManager", _sel: _getSel("superchainConfig()") }); - _addSpec({ _name: "OPStackManager", _sel: _getSel("protocolVersions()") }); - _addSpec({ _name: "OPStackManager", _sel: _getSel("latestRelease()") }); - _addSpec({ _name: "OPStackManager", _sel: _getSel("implementations(string,string)") }); - _addSpec({ _name: "OPStackManager", _sel: _getSel("systemConfigs(uint256)") }); - _addSpec({ _name: "OPStackManager", _sel: OPStackManager.initialize.selector }); - _addSpec({ _name: "OPStackManager", _sel: OPStackManager.deploy.selector }); - _addSpec({ _name: "OPStackManager", _sel: OPStackManager.blueprints.selector }); - _addSpec({ _name: "OPStackManager", _sel: OPStackManager.chainIdToBatchInboxAddress.selector }); - - // OPStackManagerInterop - _addSpec({ _name: "OPStackManagerInterop", _sel: _getSel("version()") }); - _addSpec({ _name: "OPStackManagerInterop", _sel: _getSel("superchainConfig()") }); - _addSpec({ _name: "OPStackManagerInterop", _sel: _getSel("protocolVersions()") }); - _addSpec({ _name: "OPStackManagerInterop", _sel: _getSel("latestRelease()") }); - _addSpec({ _name: "OPStackManagerInterop", _sel: _getSel("implementations(string,string)") }); - _addSpec({ _name: "OPStackManagerInterop", _sel: _getSel("systemConfigs(uint256)") }); - _addSpec({ _name: "OPStackManagerInterop", _sel: OPStackManager.initialize.selector }); - _addSpec({ _name: "OPStackManagerInterop", _sel: OPStackManager.deploy.selector }); - _addSpec({ _name: "OPStackManagerInterop", _sel: OPStackManager.blueprints.selector }); - _addSpec({ _name: "OPStackManagerInterop", _sel: OPStackManager.chainIdToBatchInboxAddress.selector }); + // OPContractsManager + _addSpec({ _name: "OPContractsManager", _sel: _getSel("version()") }); + _addSpec({ _name: "OPContractsManager", _sel: _getSel("superchainConfig()") }); + _addSpec({ _name: "OPContractsManager", _sel: _getSel("protocolVersions()") }); + _addSpec({ _name: "OPContractsManager", _sel: _getSel("latestRelease()") }); + _addSpec({ _name: "OPContractsManager", _sel: _getSel("implementations(string,string)") }); + _addSpec({ _name: "OPContractsManager", _sel: _getSel("systemConfigs(uint256)") }); + _addSpec({ _name: "OPContractsManager", _sel: OPContractsManager.initialize.selector }); + _addSpec({ _name: "OPContractsManager", _sel: OPContractsManager.deploy.selector }); + _addSpec({ _name: "OPContractsManager", _sel: OPContractsManager.blueprints.selector }); + _addSpec({ _name: "OPContractsManager", _sel: OPContractsManager.chainIdToBatchInboxAddress.selector }); + + // OPContractsManagerInterop + _addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("version()") }); + _addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("superchainConfig()") }); + _addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("protocolVersions()") }); + _addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("latestRelease()") }); + _addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("implementations(string,string)") }); + _addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("systemConfigs(uint256)") }); + _addSpec({ _name: "OPContractsManagerInterop", _sel: OPContractsManager.initialize.selector }); + _addSpec({ _name: "OPContractsManagerInterop", _sel: OPContractsManager.deploy.selector }); + _addSpec({ _name: "OPContractsManagerInterop", _sel: OPContractsManager.blueprints.selector }); + _addSpec({ _name: "OPContractsManagerInterop", _sel: OPContractsManager.chainIdToBatchInboxAddress.selector }); // DeputyGuardianModule _addSpec({ diff --git a/packages/contracts-bedrock/test/vendor/Initializable.t.sol b/packages/contracts-bedrock/test/vendor/Initializable.t.sol index d5c1a9e5e4c3..7b7596b9bafe 100644 --- a/packages/contracts-bedrock/test/vendor/Initializable.t.sol +++ b/packages/contracts-bedrock/test/vendor/Initializable.t.sol @@ -411,8 +411,8 @@ contract Initializer_Test is Bridge_Initializer { excludes[4] = "src/dispute/FaultDisputeGame.sol"; excludes[5] = "src/dispute/PermissionedDisputeGame.sol"; // TODO: Eventually remove this exclusion. Same reason as above dispute contracts. - excludes[6] = "src/L1/OPStackManager.sol"; - excludes[7] = "src/L1/OPStackManagerInterop.sol"; + excludes[6] = "src/L1/OPContractsManager.sol"; + excludes[7] = "src/L1/OPContractsManagerInterop.sol"; // Get all contract names in the src directory, minus the excluded contracts. string[] memory contractNames = ForgeArtifacts.getContractNames("src/*", excludes); From 10a16aaf4ba12d430ec666c72aad555eeae70ed2 Mon Sep 17 00:00:00 2001 From: protolambda <proto@protolambda.com> Date: Wed, 25 Sep 2024 09:59:29 -0600 Subject: [PATCH 260/264] op-supervisor: logs-db empty-db edge-case fix (#12097) --- .../supervisor/backend/db/logs/db.go | 12 +-- .../supervisor/backend/db/logs/db_test.go | 86 +++++++++++++++++++ 2 files changed, 93 insertions(+), 5 deletions(-) diff --git a/op-supervisor/supervisor/backend/db/logs/db.go b/op-supervisor/supervisor/backend/db/logs/db.go index 61184318ece9..996a5c68d712 100644 --- a/op-supervisor/supervisor/backend/db/logs/db.go +++ b/op-supervisor/supervisor/backend/db/logs/db.go @@ -210,12 +210,11 @@ func (db *DB) FindSealedBlock(block eth.BlockID) (nextEntry entrydb.EntryIdx, er func (db *DB) LatestSealedBlockNum() (n uint64, ok bool) { db.rwLock.RLock() defer db.rwLock.RUnlock() + if db.lastEntryContext.nextEntryIndex == 0 { + return 0, false // empty DB, time to add the first seal + } if !db.lastEntryContext.hasCompleteBlock() { - if db.lastEntryContext.blockNum == 0 { - db.log.Debug("No DB contents yet") - } else { - db.log.Debug("New block is already in progress", "num", db.lastEntryContext.blockNum) - } + db.log.Debug("New block is already in progress", "num", db.lastEntryContext.blockNum) } return db.lastEntryContext.blockNum, true } @@ -381,6 +380,9 @@ func (db *DB) newIterator(index entrydb.EntryIdx) *iterator { // to find the closest one with an equal or lower block number and equal or lower amount of seen logs. // Returns the index of the searchCheckpoint to begin reading from or an error. func (db *DB) searchCheckpoint(sealedBlockNum uint64, logsSince uint32) (entrydb.EntryIdx, error) { + if db.lastEntryContext.nextEntryIndex == 0 { + return 0, ErrFuture // empty DB, everything is in the future + } n := (db.lastEntryIdx() / searchCheckpointFrequency) + 1 // Define: x is the array of known checkpoints // Invariant: x[i] <= target, x[j] > target. diff --git a/op-supervisor/supervisor/backend/db/logs/db_test.go b/op-supervisor/supervisor/backend/db/logs/db_test.go index c89433c7b4fe..31067b05808d 100644 --- a/op-supervisor/supervisor/backend/db/logs/db_test.go +++ b/op-supervisor/supervisor/backend/db/logs/db_test.go @@ -81,6 +81,92 @@ func TestEmptyDbDoesNotFindEntry(t *testing.T) { }) } +func TestLatestSealedBlockNum(t *testing.T) { + t.Run("Empty case", func(t *testing.T) { + runDBTest(t, + func(t *testing.T, db *DB, m *stubMetrics) {}, + func(t *testing.T, db *DB, m *stubMetrics) { + n, ok := db.LatestSealedBlockNum() + require.False(t, ok, "empty db expected") + require.Zero(t, n) + idx, err := db.searchCheckpoint(0, 0) + require.ErrorIs(t, err, ErrFuture, "no checkpoint in empty db") + require.Zero(t, idx) + }) + }) + t.Run("Zero case", func(t *testing.T) { + genesis := eth.BlockID{Hash: createHash(0), Number: 0} + runDBTest(t, + func(t *testing.T, db *DB, m *stubMetrics) { + require.NoError(t, db.SealBlock(common.Hash{}, genesis, 5000), "seal genesis") + }, + func(t *testing.T, db *DB, m *stubMetrics) { + n, ok := db.LatestSealedBlockNum() + require.True(t, ok, "genesis block expected") + require.Equal(t, genesis.Number, n) + idx, err := db.searchCheckpoint(0, 0) + require.NoError(t, err) + require.Zero(t, idx, "genesis block as checkpoint 0") + }) + }) + t.Run("Later genesis case", func(t *testing.T) { + genesis := eth.BlockID{Hash: createHash(10), Number: 10} + runDBTest(t, + func(t *testing.T, db *DB, m *stubMetrics) { + require.NoError(t, db.SealBlock(common.Hash{}, genesis, 5000), "seal genesis") + }, + func(t *testing.T, db *DB, m *stubMetrics) { + n, ok := db.LatestSealedBlockNum() + require.True(t, ok, "genesis block expected") + require.Equal(t, genesis.Number, n) + idx, err := db.searchCheckpoint(genesis.Number, 0) + require.NoError(t, err) + require.Zero(t, idx, "anchor block as checkpoint 0") + _, err = db.searchCheckpoint(0, 0) + require.ErrorIs(t, err, ErrSkipped, "no checkpoint before genesis") + }) + }) + t.Run("Block 1 case", func(t *testing.T) { + genesis := eth.BlockID{Hash: createHash(0), Number: 0} + block1 := eth.BlockID{Hash: createHash(1), Number: 1} + runDBTest(t, + func(t *testing.T, db *DB, m *stubMetrics) { + require.NoError(t, db.SealBlock(common.Hash{}, genesis, 5000), "seal genesis") + require.NoError(t, db.SealBlock(genesis.Hash, block1, 5001), "seal block 1") + }, + func(t *testing.T, db *DB, m *stubMetrics) { + n, ok := db.LatestSealedBlockNum() + require.True(t, ok, "block 1 expected") + require.Equal(t, block1.Number, n) + idx, err := db.searchCheckpoint(block1.Number, 0) + require.NoError(t, err) + require.Equal(t, entrydb.EntryIdx(0), idx, "checkpoint 0 still for block 1") + }) + }) + t.Run("Using checkpoint case", func(t *testing.T) { + genesis := eth.BlockID{Hash: createHash(0), Number: 0} + runDBTest(t, + func(t *testing.T, db *DB, m *stubMetrics) { + require.NoError(t, db.SealBlock(common.Hash{}, genesis, 5000), "seal genesis") + for i := 1; i <= 260; i++ { + id := eth.BlockID{Hash: createHash(i), Number: uint64(i)} + require.NoError(t, db.SealBlock(createHash(i-1), id, 5001), "seal block %d", i) + } + }, + func(t *testing.T, db *DB, m *stubMetrics) { + n, ok := db.LatestSealedBlockNum() + require.True(t, ok, "latest block expected") + expected := uint64(260) + require.Equal(t, expected, n) + idx, err := db.searchCheckpoint(expected, 0) + require.NoError(t, err) + // It costs 2 entries per block, so if we add more than 1 checkpoint worth of blocks, + // then we get to checkpoint 2 + require.Equal(t, entrydb.EntryIdx(searchCheckpointFrequency*2), idx, "checkpoint 1 reached") + }) + }) +} + func TestAddLog(t *testing.T) { t.Run("BlockZero", func(t *testing.T) { // There are no logs in the genesis block so recording an entry for block 0 should be rejected. From 616a078ea1159c9fa0436a81219e946e28adb10a Mon Sep 17 00:00:00 2001 From: George Knee <georgeknee@googlemail.com> Date: Wed, 25 Sep 2024 19:22:30 +0100 Subject: [PATCH 261/264] op-batcher: prevent over-assessment of DA type (#12115) * test: assert that default config doesn't change prematurely * test: use a better system to ensure we are not over assessing * return io.EOF from getReadyChannel when the current channel has no tx data also improve godoc --- op-batcher/batcher/channel_manager.go | 12 ++++++++++-- op-batcher/batcher/channel_manager_test.go | 19 +++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/op-batcher/batcher/channel_manager.go b/op-batcher/batcher/channel_manager.go index 3bfff303db4b..23e8f7843696 100644 --- a/op-batcher/batcher/channel_manager.go +++ b/op-batcher/batcher/channel_manager.go @@ -193,7 +193,11 @@ func (s *channelManager) TxData(l1Head eth.BlockID) (txData, error) { } // getReadyChannel returns the next channel ready to submit data, or an error. -// It adds blocks from the block queue to the current channel and generates frames for it. +// It will create a new channel if necessary. +// If there is no data ready to send, it adds blocks from the block queue +// to the current channel and generates frames for it. +// Always returns nil and the io.EOF sentinel error when +// there is no channel with txData func (s *channelManager) getReadyChannel(l1Head eth.BlockID) (*channel, error) { var firstWithTxData *channel for _, ch := range s.channelQueue { @@ -239,7 +243,11 @@ func (s *channelManager) getReadyChannel(l1Head eth.BlockID) (*channel, error) { return nil, err } - return s.currentChannel, nil + if s.currentChannel.HasTxData() { + return s.currentChannel, nil + } + + return nil, io.EOF } // ensureChannelWithSpace ensures currentChannel is populated with a channel that has diff --git a/op-batcher/batcher/channel_manager_test.go b/op-batcher/batcher/channel_manager_test.go index 5df5feacf4bf..c129cd9cde99 100644 --- a/op-batcher/batcher/channel_manager_test.go +++ b/op-batcher/batcher/channel_manager_test.go @@ -491,9 +491,11 @@ func TestChannelManager_ChannelCreation(t *testing.T) { type FakeDynamicEthChannelConfig struct { DynamicEthChannelConfig chooseBlobs bool + assessments int } func (f *FakeDynamicEthChannelConfig) ChannelConfig() ChannelConfig { + f.assessments++ if f.chooseBlobs { return f.blobConfig } @@ -537,13 +539,21 @@ func TestChannelManager_TxData(t *testing.T) { name string chooseBlobsWhenChannelCreated bool chooseBlobsWhenChannelSubmitted bool + + // * One when the channelManager was created + // * One when the channel is about to be submitted + // * Potentially one more if the replacement channel is about to be submitted, + // this only happens when going from calldata->blobs because + // the channel is no longer ready to send until more data + // is added. + numExpectedAssessments int } tt := []TestCase{ - {"blobs->blobs", true, true}, - {"calldata->calldata", false, false}, - {"blobs->calldata", true, false}, - {"calldata->blobs", false, true}, + {"blobs->blobs", true, true, 2}, + {"calldata->calldata", false, false, 2}, + {"blobs->calldata", true, false, 2}, + {"calldata->blobs", false, true, 3}, } for _, tc := range tt { @@ -590,6 +600,7 @@ func TestChannelManager_TxData(t *testing.T) { } } + require.Equal(t, tc.numExpectedAssessments, cfg.assessments) require.Equal(t, tc.chooseBlobsWhenChannelSubmitted, data.asBlob) require.Equal(t, tc.chooseBlobsWhenChannelSubmitted, m.defaultCfg.UseBlobs) }) From 36180d78bdf3fa96d3a89efb127f7d463245a2ba Mon Sep 17 00:00:00 2001 From: Blaine Malone <blainemalone01@gmail.com> Date: Wed, 25 Sep 2024 15:14:46 -0400 Subject: [PATCH 262/264] rename: proxyAdminOwner -> superchainProxyAdminOwner (#12106) * rename: proxyAdminOwner -> superchainProxyAdminOwner * fix: renames in tests. * fix: renaming in go code. * fix: Changing the intent to contain SuperchainProxyAdminOwner instead of just ProxyAdminOwner * fix: reverting last change --- op-chain-ops/deployer/opcm/superchain.go | 2 +- op-chain-ops/deployer/pipeline/superchain.go | 2 +- op-chain-ops/interopgen/deploy.go | 2 +- .../scripts/DeploySuperchain.s.sol | 16 ++++++++-------- .../contracts-bedrock/test/DeployOPChain.t.sol | 4 ++-- .../test/DeploySuperchain.t.sol | 18 +++++++++--------- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/op-chain-ops/deployer/opcm/superchain.go b/op-chain-ops/deployer/opcm/superchain.go index 34804cc2bbdf..4f648bbfa8a3 100644 --- a/op-chain-ops/deployer/opcm/superchain.go +++ b/op-chain-ops/deployer/opcm/superchain.go @@ -14,7 +14,7 @@ import ( ) type DeploySuperchainInput struct { - ProxyAdminOwner common.Address `toml:"proxyAdminOwner"` + SuperchainProxyAdminOwner common.Address `toml:"superchainProxyAdminOwner"` ProtocolVersionsOwner common.Address `toml:"protocolVersionsOwner"` Guardian common.Address `toml:"guardian"` Paused bool `toml:"paused"` diff --git a/op-chain-ops/deployer/pipeline/superchain.go b/op-chain-ops/deployer/pipeline/superchain.go index cc1b8d04160c..13737475c916 100644 --- a/op-chain-ops/deployer/pipeline/superchain.go +++ b/op-chain-ops/deployer/pipeline/superchain.go @@ -40,7 +40,7 @@ func DeploySuperchain(ctx context.Context, env *Env, artifactsFS foundry.StatDir dso, err = opcm.DeploySuperchain( host, opcm.DeploySuperchainInput{ - ProxyAdminOwner: intent.SuperchainRoles.ProxyAdminOwner, + SuperchainProxyAdminOwner: intent.SuperchainRoles.ProxyAdminOwner, ProtocolVersionsOwner: intent.SuperchainRoles.ProtocolVersionsOwner, Guardian: intent.SuperchainRoles.Guardian, Paused: false, diff --git a/op-chain-ops/interopgen/deploy.go b/op-chain-ops/interopgen/deploy.go index 692a80d3225e..be837484e512 100644 --- a/op-chain-ops/interopgen/deploy.go +++ b/op-chain-ops/interopgen/deploy.go @@ -149,7 +149,7 @@ func deploySuperchainToL1(l1Host *script.Host, superCfg *SuperchainConfig) (*Sup l1Host.SetTxOrigin(superCfg.Deployer) superDeployment, err := opcm.DeploySuperchain(l1Host, opcm.DeploySuperchainInput{ - ProxyAdminOwner: superCfg.ProxyAdminOwner, + SuperchainProxyAdminOwner: superCfg.ProxyAdminOwner, ProtocolVersionsOwner: superCfg.ProtocolVersionsOwner, Guardian: superCfg.SuperchainConfigGuardian, Paused: superCfg.Paused, diff --git a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol index 5ca889bf409e..7726d5709076 100644 --- a/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol +++ b/packages/contracts-bedrock/scripts/DeploySuperchain.s.sol @@ -81,7 +81,7 @@ contract DeploySuperchainInput is BaseDeployIO { // Role inputs. address internal _guardian; address internal _protocolVersionsOwner; - address internal _proxyAdminOwner; + address internal _superchainProxyAdminOwner; // Other inputs. bool internal _paused; @@ -94,7 +94,7 @@ contract DeploySuperchainInput is BaseDeployIO { require(_address != address(0), "DeploySuperchainInput: cannot set zero address"); if (_sel == this.guardian.selector) _guardian = _address; else if (_sel == this.protocolVersionsOwner.selector) _protocolVersionsOwner = _address; - else if (_sel == this.proxyAdminOwner.selector) _proxyAdminOwner = _address; + else if (_sel == this.superchainProxyAdminOwner.selector) _superchainProxyAdminOwner = _address; else revert("DeploySuperchainInput: unknown selector"); } @@ -115,9 +115,9 @@ contract DeploySuperchainInput is BaseDeployIO { // validate that each input is set before accessing it. With getter methods, we can automatically // validate that each input is set before allowing any field to be accessed. - function proxyAdminOwner() public view returns (address) { - require(_proxyAdminOwner != address(0), "DeploySuperchainInput: proxyAdminOwner not set"); - return _proxyAdminOwner; + function superchainProxyAdminOwner() public view returns (address) { + require(_superchainProxyAdminOwner != address(0), "DeploySuperchainInput: superchainProxyAdminOwner not set"); + return _superchainProxyAdminOwner; } function protocolVersionsOwner() public view returns (address) { @@ -232,7 +232,7 @@ contract DeploySuperchainOutput is BaseDeployIO { } function assertValidSuperchainProxyAdmin(DeploySuperchainInput _dsi) internal view { - require(superchainProxyAdmin().owner() == _dsi.proxyAdminOwner(), "SPA-10"); + require(superchainProxyAdmin().owner() == _dsi.superchainProxyAdminOwner(), "SPA-10"); } function assertValidSuperchainConfig(DeploySuperchainInput _dsi) internal { @@ -386,13 +386,13 @@ contract DeploySuperchain is Script { } function transferProxyAdminOwnership(DeploySuperchainInput _dsi, DeploySuperchainOutput _dso) public { - address proxyAdminOwner = _dsi.proxyAdminOwner(); + address superchainProxyAdminOwner = _dsi.superchainProxyAdminOwner(); ProxyAdmin superchainProxyAdmin = _dso.superchainProxyAdmin(); DeployUtils.assertValidContractAddress(address(superchainProxyAdmin)); vm.broadcast(msg.sender); - superchainProxyAdmin.transferOwnership(proxyAdminOwner); + superchainProxyAdmin.transferOwnership(superchainProxyAdminOwner); } // -------- Utilities -------- diff --git a/packages/contracts-bedrock/test/DeployOPChain.t.sol b/packages/contracts-bedrock/test/DeployOPChain.t.sol index 3cbc313cfe11..445602062d5a 100644 --- a/packages/contracts-bedrock/test/DeployOPChain.t.sol +++ b/packages/contracts-bedrock/test/DeployOPChain.t.sol @@ -308,7 +308,7 @@ contract DeployOPChain_TestBase is Test { DeployOPChainOutput doo; // Define default inputs for DeploySuperchain. - address proxyAdminOwner = makeAddr("defaultProxyAdminOwner"); + address superchainProxyAdminOwner = makeAddr("defaultSuperchainProxyAdminOwner"); address protocolVersionsOwner = makeAddr("defaultProtocolVersionsOwner"); address guardian = makeAddr("defaultGuardian"); bool paused = false; @@ -365,7 +365,7 @@ contract DeployOPChain_TestBase is Test { DeploySuperchain deploySuperchain = new DeploySuperchain(); (DeploySuperchainInput dsi, DeploySuperchainOutput dso) = deploySuperchain.etchIOContracts(); - dsi.set(dsi.proxyAdminOwner.selector, proxyAdminOwner); + dsi.set(dsi.superchainProxyAdminOwner.selector, superchainProxyAdminOwner); dsi.set(dsi.protocolVersionsOwner.selector, protocolVersionsOwner); dsi.set(dsi.guardian.selector, guardian); dsi.set(dsi.paused.selector, paused); diff --git a/packages/contracts-bedrock/test/DeploySuperchain.t.sol b/packages/contracts-bedrock/test/DeploySuperchain.t.sol index 4b51aae0f3d6..a6bcf2aa2f50 100644 --- a/packages/contracts-bedrock/test/DeploySuperchain.t.sol +++ b/packages/contracts-bedrock/test/DeploySuperchain.t.sol @@ -13,7 +13,7 @@ import { DeploySuperchainInput, DeploySuperchain, DeploySuperchainOutput } from contract DeploySuperchainInput_Test is Test { DeploySuperchainInput dsi; - address proxyAdminOwner = makeAddr("defaultProxyAdminOwner"); + address superchainProxyAdminOwner = makeAddr("superchainProxyAdminOwner"); address protocolVersionsOwner = makeAddr("defaultProtocolVersionsOwner"); address guardian = makeAddr("defaultGuardian"); bool paused = false; @@ -25,8 +25,8 @@ contract DeploySuperchainInput_Test is Test { } function test_getters_whenNotSet_revert() public { - vm.expectRevert("DeploySuperchainInput: proxyAdminOwner not set"); - dsi.proxyAdminOwner(); + vm.expectRevert("DeploySuperchainInput: superchainProxyAdminOwner not set"); + dsi.superchainProxyAdminOwner(); vm.expectRevert("DeploySuperchainInput: protocolVersionsOwner not set"); dsi.protocolVersionsOwner(); @@ -151,7 +151,7 @@ contract DeploySuperchain_Test is Test { // Generate random input values from the seed. This doesn't give us the benefit of the forge // fuzzer's dictionary, but that's ok because we are just testing that values are set and // passed correctly. - address proxyAdminOwner = address(uint160(uint256(hash(_seed, 0)))); + address superchainProxyAdminOwner = address(uint160(uint256(hash(_seed, 0)))); address protocolVersionsOwner = address(uint160(uint256(hash(_seed, 1)))); address guardian = address(uint160(uint256(hash(_seed, 2)))); bool paused = bool(uint8(uint256(hash(_seed, 3))) % 2 == 0); @@ -159,7 +159,7 @@ contract DeploySuperchain_Test is Test { ProtocolVersion recommendedProtocolVersion = ProtocolVersion.wrap(uint256(hash(_seed, 5))); // Set the input values on the input contract. - dsi.set(dsi.proxyAdminOwner.selector, proxyAdminOwner); + dsi.set(dsi.superchainProxyAdminOwner.selector, superchainProxyAdminOwner); dsi.set(dsi.protocolVersionsOwner.selector, protocolVersionsOwner); dsi.set(dsi.guardian.selector, guardian); dsi.set(dsi.paused.selector, paused); @@ -170,7 +170,7 @@ contract DeploySuperchain_Test is Test { deploySuperchain.run(dsi, dso); // Assert inputs were properly passed through to the contract initializers. - assertEq(address(dso.superchainProxyAdmin().owner()), proxyAdminOwner, "100"); + assertEq(address(dso.superchainProxyAdmin().owner()), superchainProxyAdminOwner, "100"); assertEq(address(dso.protocolVersionsProxy().owner()), protocolVersionsOwner, "200"); assertEq(address(dso.superchainConfigProxy().guardian()), guardian, "300"); assertEq(dso.superchainConfigProxy().paused(), paused, "400"); @@ -196,7 +196,7 @@ contract DeploySuperchain_Test is Test { function test_run_NullInput_reverts() public { // Set default values for all inputs. - dsi.set(dsi.proxyAdminOwner.selector, defaultProxyAdminOwner); + dsi.set(dsi.superchainProxyAdminOwner.selector, defaultProxyAdminOwner); dsi.set(dsi.protocolVersionsOwner.selector, defaultProtocolVersionsOwner); dsi.set(dsi.guardian.selector, defaultGuardian); dsi.set(dsi.paused.selector, defaultPaused); @@ -207,8 +207,8 @@ contract DeploySuperchain_Test is Test { // methods to set the zero address, so we use StdStorage. We can't use the `checked_write` // method, because it does a final call to test that the value was set correctly, but for us // that would revert. Therefore we use StdStorage to find the slot, then we write to it. - uint256 slot = zeroOutSlotForSelector(dsi.proxyAdminOwner.selector); - vm.expectRevert("DeploySuperchainInput: proxyAdminOwner not set"); + uint256 slot = zeroOutSlotForSelector(dsi.superchainProxyAdminOwner.selector); + vm.expectRevert("DeploySuperchainInput: superchainProxyAdminOwner not set"); deploySuperchain.run(dsi, dso); // Restore the value we just tested. vm.store(address(dsi), bytes32(slot), bytes32(uint256(uint160(defaultProxyAdminOwner)))); From 06f1406e82945ef178dac7ee9d8c247fa54c5c18 Mon Sep 17 00:00:00 2001 From: Matthew Slipper <me@matthewslipper.com> Date: Wed, 25 Sep 2024 13:29:45 -0600 Subject: [PATCH 263/264] Add support for pre-existing OPSM (#12099) * Add support for pre-existing OPSM This PR adds support for deploying OP Chains against an existing OPSM deployment. It adds a new `OPSMAddress` field to the intent to hold the address of the OPSM. When specified, the `ContractsRelease` field is ignored. In the future, this field will be pulled from the Superchain Registry. Since the Go Forge tooling doesn't support forking yet, the deployment is performed using a raw call to `eth_sendRawTransaction`. Data about the Superchain deployments is pulled from the OPSM itself via `eth_call`. To expose the deployment output following the Superchain deployment, I updated the `Deployed` event to emit the ABI-encoded bytes of the `DeployOutput` struct to avoid stack-too-deep errors. This isn't ideal, but at least it gets me all of the fields I need in a log event without more invasive changes. * chore: add version identifer to Deployed event * chore: emit msg.sender in Deployed event * Fix merge issues * test: fix specs test * semver-lock * code review updates --------- Co-authored-by: Matt Solomon <matt@mattsolomon.dev> --- op-chain-ops/deployer/broadcaster/keyed.go | 2 +- op-chain-ops/deployer/init.go | 7 +- .../deployer/integration_test/apply_test.go | 141 ++++++++---- op-chain-ops/deployer/opcm/contract.go | 83 +++++++ op-chain-ops/deployer/opcm/opchain.go | 212 +++++++++++++++++- op-chain-ops/deployer/pipeline/init.go | 35 +++ op-chain-ops/deployer/pipeline/opchain.go | 98 +++++--- op-chain-ops/deployer/state/intent.go | 7 + packages/contracts-bedrock/semver-lock.json | 4 +- .../snapshots/abi/OPContractsManager.json | 29 ++- .../abi/OPContractsManagerInterop.json | 29 ++- .../src/L1/OPContractsManager.sol | 20 +- .../test/L1/OPContractsManager.t.sol | 8 +- packages/contracts-bedrock/test/Specs.t.sol | 2 + 14 files changed, 577 insertions(+), 100 deletions(-) create mode 100644 op-chain-ops/deployer/opcm/contract.go diff --git a/op-chain-ops/deployer/broadcaster/keyed.go b/op-chain-ops/deployer/broadcaster/keyed.go index 2784c4d455be..63b72010042b 100644 --- a/op-chain-ops/deployer/broadcaster/keyed.go +++ b/op-chain-ops/deployer/broadcaster/keyed.go @@ -162,7 +162,7 @@ func (t *KeyedBroadcaster) Broadcast(ctx context.Context) ([]BroadcastResult, er ) } - results = append(results, outRes) + results[i] = outRes } return results, txErr.ErrorOrNil() } diff --git a/op-chain-ops/deployer/init.go b/op-chain-ops/deployer/init.go index 0cc288b40ffb..bd79f980cdff 100644 --- a/op-chain-ops/deployer/init.go +++ b/op-chain-ops/deployer/init.go @@ -65,9 +65,10 @@ func Init(cfg InitConfig) error { } intent := &state.Intent{ - L1ChainID: cfg.L1ChainID, - UseFaultProofs: true, - FundDevAccounts: true, + L1ChainID: cfg.L1ChainID, + UseFaultProofs: true, + FundDevAccounts: true, + ContractsRelease: "dev", } l1ChainIDBig := intent.L1ChainIDBig() diff --git a/op-chain-ops/deployer/integration_test/apply_test.go b/op-chain-ops/deployer/integration_test/apply_test.go index 4399e0b887d3..ad22651fa36e 100644 --- a/op-chain-ops/deployer/integration_test/apply_test.go +++ b/op-chain-ops/deployer/integration_test/apply_test.go @@ -93,18 +93,104 @@ func TestEndToEndApply(t *testing.T) { id := uint256.NewInt(1) - addrFor := func(key devkeys.Key) common.Address { - addr, err := dk.Address(key) - require.NoError(t, err) - return addr - } + deployerAddr, err := dk.Address(depKey) + require.NoError(t, err) + env := &pipeline.Env{ Workdir: t.TempDir(), L1Client: l1Client, Signer: signer, - Deployer: addrFor(depKey), + Deployer: deployerAddr, Logger: lgr, } + + t.Run("initial chain", func(t *testing.T) { + intent, st := makeIntent(t, l1ChainID, artifactsURL, dk, id) + + require.NoError(t, deployer.ApplyPipeline( + ctx, + env, + intent, + st, + )) + + addrs := []struct { + name string + addr common.Address + }{ + {"SuperchainProxyAdmin", st.SuperchainDeployment.ProxyAdminAddress}, + {"SuperchainConfigProxy", st.SuperchainDeployment.SuperchainConfigProxyAddress}, + {"SuperchainConfigImpl", st.SuperchainDeployment.SuperchainConfigImplAddress}, + {"ProtocolVersionsProxy", st.SuperchainDeployment.ProtocolVersionsProxyAddress}, + {"ProtocolVersionsImpl", st.SuperchainDeployment.ProtocolVersionsImplAddress}, + {"OpcmProxy", st.ImplementationsDeployment.OpcmProxyAddress}, + {"DelayedWETHImpl", st.ImplementationsDeployment.DelayedWETHImplAddress}, + {"OptimismPortalImpl", st.ImplementationsDeployment.OptimismPortalImplAddress}, + {"PreimageOracleSingleton", st.ImplementationsDeployment.PreimageOracleSingletonAddress}, + {"MipsSingleton", st.ImplementationsDeployment.MipsSingletonAddress}, + {"SystemConfigImpl", st.ImplementationsDeployment.SystemConfigImplAddress}, + {"L1CrossDomainMessengerImpl", st.ImplementationsDeployment.L1CrossDomainMessengerImplAddress}, + {"L1ERC721BridgeImpl", st.ImplementationsDeployment.L1ERC721BridgeImplAddress}, + {"L1StandardBridgeImpl", st.ImplementationsDeployment.L1StandardBridgeImplAddress}, + {"OptimismMintableERC20FactoryImpl", st.ImplementationsDeployment.OptimismMintableERC20FactoryImplAddress}, + {"DisputeGameFactoryImpl", st.ImplementationsDeployment.DisputeGameFactoryImplAddress}, + } + for _, addr := range addrs { + t.Run(addr.name, func(t *testing.T) { + code, err := l1Client.CodeAt(ctx, addr.addr, nil) + require.NoError(t, err) + require.NotEmpty(t, code, "contracts %s at %s has no code", addr.name, addr.addr) + }) + } + + validateOPChainDeployment(t, ctx, l1Client, st) + }) + + t.Run("subsequent chain", func(t *testing.T) { + newID := uint256.NewInt(2) + intent, st := makeIntent(t, l1ChainID, artifactsURL, dk, newID) + env.Workdir = t.TempDir() + + require.NoError(t, deployer.ApplyPipeline( + ctx, + env, + intent, + st, + )) + + addrs := []struct { + name string + addr common.Address + }{ + {"SuperchainConfigProxy", st.SuperchainDeployment.SuperchainConfigProxyAddress}, + {"ProtocolVersionsProxy", st.SuperchainDeployment.ProtocolVersionsProxyAddress}, + {"OpcmProxy", st.ImplementationsDeployment.OpcmProxyAddress}, + } + for _, addr := range addrs { + t.Run(addr.name, func(t *testing.T) { + code, err := l1Client.CodeAt(ctx, addr.addr, nil) + require.NoError(t, err) + require.NotEmpty(t, code, "contracts %s at %s has no code", addr.name, addr.addr) + }) + } + + validateOPChainDeployment(t, ctx, l1Client, st) + }) +} + +func makeIntent( + t *testing.T, + l1ChainID *big.Int, + artifactsURL *url.URL, + dk *devkeys.MnemonicDevKeys, + l2ChainID *uint256.Int, +) (*state.Intent, *state.State) { + addrFor := func(key devkeys.Key) common.Address { + addr, err := dk.Address(key) + require.NoError(t, err) + return addr + } + intent := &state.Intent{ L1ChainID: l1ChainID.Uint64(), SuperchainRoles: state.SuperchainRoles{ @@ -118,7 +204,7 @@ func TestEndToEndApply(t *testing.T) { ContractsRelease: "dev", Chains: []*state.ChainIntent{ { - ID: id.Bytes32(), + ID: l2ChainID.Bytes32(), Roles: state.ChainRoles{ ProxyAdminOwner: addrFor(devkeys.L2ProxyAdminOwnerRole.Key(l1ChainID)), SystemConfigOwner: addrFor(devkeys.SystemConfigOwner.Key(l1ChainID)), @@ -134,43 +220,10 @@ func TestEndToEndApply(t *testing.T) { st := &state.State{ Version: 1, } + return intent, st +} - require.NoError(t, deployer.ApplyPipeline( - ctx, - env, - intent, - st, - )) - - addrs := []struct { - name string - addr common.Address - }{ - {"SuperchainProxyAdmin", st.SuperchainDeployment.ProxyAdminAddress}, - {"SuperchainConfigProxy", st.SuperchainDeployment.SuperchainConfigProxyAddress}, - {"SuperchainConfigImpl", st.SuperchainDeployment.SuperchainConfigImplAddress}, - {"ProtocolVersionsProxy", st.SuperchainDeployment.ProtocolVersionsProxyAddress}, - {"ProtocolVersionsImpl", st.SuperchainDeployment.ProtocolVersionsImplAddress}, - {"OpcmProxy", st.ImplementationsDeployment.OpcmProxyAddress}, - {"DelayedWETHImpl", st.ImplementationsDeployment.DelayedWETHImplAddress}, - {"OptimismPortalImpl", st.ImplementationsDeployment.OptimismPortalImplAddress}, - {"PreimageOracleSingleton", st.ImplementationsDeployment.PreimageOracleSingletonAddress}, - {"MipsSingleton", st.ImplementationsDeployment.MipsSingletonAddress}, - {"SystemConfigImpl", st.ImplementationsDeployment.SystemConfigImplAddress}, - {"L1CrossDomainMessengerImpl", st.ImplementationsDeployment.L1CrossDomainMessengerImplAddress}, - {"L1ERC721BridgeImpl", st.ImplementationsDeployment.L1ERC721BridgeImplAddress}, - {"L1StandardBridgeImpl", st.ImplementationsDeployment.L1StandardBridgeImplAddress}, - {"OptimismMintableERC20FactoryImpl", st.ImplementationsDeployment.OptimismMintableERC20FactoryImplAddress}, - {"DisputeGameFactoryImpl", st.ImplementationsDeployment.DisputeGameFactoryImplAddress}, - } - for _, addr := range addrs { - t.Run(addr.name, func(t *testing.T) { - code, err := l1Client.CodeAt(ctx, addr.addr, nil) - require.NoError(t, err) - require.NotEmpty(t, code, "contracts %s at %s has no code", addr.name, addr.addr) - }) - } - +func validateOPChainDeployment(t *testing.T, ctx context.Context, l1Client *ethclient.Client, st *state.State) { for _, chainState := range st.Chains { chainAddrs := []struct { name string @@ -197,7 +250,7 @@ func TestEndToEndApply(t *testing.T) { if addr.name == "FaultDisputeGameAddress" { continue } - t.Run(fmt.Sprintf("chain %s - %s", chainState.ID, addr.name), func(t *testing.T) { + t.Run(addr.name, func(t *testing.T) { code, err := l1Client.CodeAt(ctx, addr.addr, nil) require.NoError(t, err) require.NotEmpty(t, code, "contracts %s at %s for chain %s has no code", addr.name, addr.addr, chainState.ID) diff --git a/op-chain-ops/deployer/opcm/contract.go b/op-chain-ops/deployer/opcm/contract.go new file mode 100644 index 000000000000..c81222aafe88 --- /dev/null +++ b/op-chain-ops/deployer/opcm/contract.go @@ -0,0 +1,83 @@ +package opcm + +import ( + "bytes" + "context" + "fmt" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" +) + +type Contract struct { + addr common.Address + client *ethclient.Client +} + +func NewContract(addr common.Address, client *ethclient.Client) *Contract { + return &Contract{addr: addr, client: client} +} + +func (c *Contract) SuperchainConfig(ctx context.Context) (common.Address, error) { + return c.getAddress(ctx, "superchainConfig") +} + +func (c *Contract) ProtocolVersions(ctx context.Context) (common.Address, error) { + return c.getAddress(ctx, "protocolVersions") +} + +func (c *Contract) getAddress(ctx context.Context, name string) (common.Address, error) { + method := abi.NewMethod( + name, + name, + abi.Function, + "view", + true, + false, + abi.Arguments{}, + abi.Arguments{ + abi.Argument{ + Name: "address", + Type: mustType("address"), + Indexed: false, + }, + }, + ) + + calldata, err := method.Inputs.Pack() + if err != nil { + return common.Address{}, fmt.Errorf("failed to pack inputs: %w", err) + } + + msg := ethereum.CallMsg{ + To: &c.addr, + Data: append(bytes.Clone(method.ID), calldata...), + } + result, err := c.client.CallContract(ctx, msg, nil) + if err != nil { + return common.Address{}, fmt.Errorf("failed to call contract: %w", err) + } + + out, err := method.Outputs.Unpack(result) + if err != nil { + return common.Address{}, fmt.Errorf("failed to unpack result: %w", err) + } + if len(out) != 1 { + return common.Address{}, fmt.Errorf("unexpected output length: %d", len(out)) + } + addr, ok := out[0].(common.Address) + if !ok { + return common.Address{}, fmt.Errorf("unexpected type: %T", out[0]) + } + return addr, nil +} + +func mustType(t string) abi.Type { + typ, err := abi.NewType(t, "", nil) + if err != nil { + panic(err) + } + return typ +} diff --git a/op-chain-ops/deployer/opcm/opchain.go b/op-chain-ops/deployer/opcm/opchain.go index d9685182b6e1..c204c1a57ec3 100644 --- a/op-chain-ops/deployer/opcm/opchain.go +++ b/op-chain-ops/deployer/opcm/opchain.go @@ -1,12 +1,19 @@ package opcm import ( + "context" "fmt" "math/big" + "strings" - "github.com/ethereum/go-ethereum/common" - + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/broadcaster" + "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" "github.com/ethereum-optimism/optimism/op-chain-ops/script" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/holiman/uint256" ) // PermissionedGameStartingAnchorRoots is a root of bytes32(hex"dead") for the permissioned game at block 0, @@ -45,7 +52,6 @@ type DeployOPChainOutput struct { OptimismMintableERC20FactoryProxy common.Address L1StandardBridgeProxy common.Address L1CrossDomainMessengerProxy common.Address - // Fault proof contracts below. OptimismPortalProxy common.Address DisputeGameFactoryProxy common.Address @@ -97,3 +103,203 @@ func DeployOPChain(host *script.Host, input DeployOPChainInput) (DeployOPChainOu return dco, nil } + +// opcmRoles is an internal struct used to pass the roles to OPSM. See opcmDeployInput for more info. +type opcmRoles struct { + OpChainProxyAdminOwner common.Address + SystemConfigOwner common.Address + Batcher common.Address + UnsafeBlockSigner common.Address + Proposer common.Address + Challenger common.Address +} + +// opcmDeployInput is the input struct for the deploy method of the OPStackManager contract. We +// define a separate struct here to match what the OPSM contract expects. +type opcmDeployInput struct { + Roles opcmRoles + BasefeeScalar uint32 + BlobBasefeeScalar uint32 + L2ChainId *big.Int + StartingAnchorRoots []byte +} + +// decodeOutputABIJSON defines an ABI for a fake method called "decodeOutput" that returns the +// DeployOutput struct. This allows the code in the deployer to decode directly into a struct +// using Geth's ABI library. +const decodeOutputABIJSON = ` +[ + { + "type": "function", + "name": "decodeOutput", + "inputs": [], + "outputs": [ + { + "name": "output", + "indexed": false, + "type": "tuple", + "components": [ + { + "name": "opChainProxyAdmin", + "type": "address" + }, + { + "name": "addressManager", + "type": "address" + }, + { + "name": "l1ERC721BridgeProxy", + "type": "address" + }, + { + "name": "systemConfigProxy", + "type": "address" + }, + { + "name": "optimismMintableERC20FactoryProxy", + "type": "address" + }, + { + "name": "l1StandardBridgeProxy", + "type": "address" + }, + { + "name": "l1CrossDomainMessengerProxy", + "type": "address" + }, + { + "name": "optimismPortalProxy", + "type": "address" + }, + { + "name": "disputeGameFactoryProxy", + "type": "address" + }, + { + "name": "anchorStateRegistryProxy", + "type": "address" + }, + { + "name": "anchorStateRegistryImpl", + "type": "address" + }, + { + "name": "faultDisputeGame", + "type": "address", + "internalType": "contract FaultDisputeGame" + }, + { + "name": "permissionedDisputeGame", + "type": "address" + }, + { + "name": "delayedWETHPermissionedGameProxy", + "type": "address" + }, + { + "name": "delayedWETHPermissionlessGameProxy", + "type": "address" + } + ] + } + ] + } +] +` + +var decodeOutputABI abi.ABI + +// DeployOPChainRaw deploys an OP Chain using a raw call to a pre-deployed OPSM contract. +func DeployOPChainRaw( + ctx context.Context, + l1 *ethclient.Client, + bcast broadcaster.Broadcaster, + deployer common.Address, + artifacts foundry.StatDirFs, + input DeployOPChainInput, +) (DeployOPChainOutput, error) { + var out DeployOPChainOutput + + artifactsFS := &foundry.ArtifactsFS{FS: artifacts} + opcmArtifacts, err := artifactsFS.ReadArtifact("OPContractsManager.sol", "OPContractsManager") + if err != nil { + return out, fmt.Errorf("failed to read OPStackManager artifact: %w", err) + } + + opcmABI := opcmArtifacts.ABI + calldata, err := opcmABI.Pack("deploy", opcmDeployInput{ + Roles: opcmRoles{ + OpChainProxyAdminOwner: input.OpChainProxyAdminOwner, + SystemConfigOwner: input.SystemConfigOwner, + Batcher: input.Batcher, + UnsafeBlockSigner: input.UnsafeBlockSigner, + Proposer: input.Proposer, + Challenger: input.Challenger, + }, + BasefeeScalar: input.BasefeeScalar, + BlobBasefeeScalar: input.BlobBaseFeeScalar, + L2ChainId: input.L2ChainId, + StartingAnchorRoots: input.StartingAnchorRoots(), + }) + if err != nil { + return out, fmt.Errorf("failed to pack deploy input: %w", err) + } + + nonce, err := l1.NonceAt(ctx, deployer, nil) + if err != nil { + return out, fmt.Errorf("failed to read nonce: %w", err) + } + + bcast.Hook(script.Broadcast{ + From: deployer, + To: input.OpcmProxy, + Input: calldata, + Value: (*hexutil.U256)(uint256.NewInt(0)), + // use hardcoded 19MM gas for now since this is roughly what we've seen this deployment cost. + GasUsed: 19_000_000, + Type: script.BroadcastCall, + Nonce: nonce, + }) + + results, err := bcast.Broadcast(ctx) + if err != nil { + return out, fmt.Errorf("failed to broadcast OP chain deployment: %w", err) + } + + deployedEvent := opcmABI.Events["Deployed"] + res := results[0] + + for _, log := range res.Receipt.Logs { + if log.Topics[0] != deployedEvent.ID { + continue + } + + type EventData struct { + DeployOutput []byte + } + var data EventData + if err := opcmABI.UnpackIntoInterface(&data, "Deployed", log.Data); err != nil { + return out, fmt.Errorf("failed to unpack Deployed event: %w", err) + } + + type OutputData struct { + Output DeployOPChainOutput + } + var outData OutputData + if err := decodeOutputABI.UnpackIntoInterface(&outData, "decodeOutput", data.DeployOutput); err != nil { + return out, fmt.Errorf("failed to unpack DeployOutput: %w", err) + } + + return outData.Output, nil + } + + return out, fmt.Errorf("failed to find Deployed event") +} + +func init() { + var err error + decodeOutputABI, err = abi.JSON(strings.NewReader(decodeOutputABIJSON)) + if err != nil { + panic(fmt.Sprintf("failed to parse decodeOutput ABI: %v", err)) + } +} diff --git a/op-chain-ops/deployer/pipeline/init.go b/op-chain-ops/deployer/pipeline/init.go index 094e103aa940..a680c7fdb48f 100644 --- a/op-chain-ops/deployer/pipeline/init.go +++ b/op-chain-ops/deployer/pipeline/init.go @@ -5,6 +5,7 @@ import ( "crypto/rand" "fmt" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opcm" "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" "github.com/ethereum-optimism/optimism/op-chain-ops/script" @@ -34,6 +35,40 @@ func Init(ctx context.Context, env *Env, artifactsFS foundry.StatDirFs, intent * } } + if intent.OPCMAddress != (common.Address{}) { + env.Logger.Info("using provided OPCM address, populating state", "address", intent.OPCMAddress.Hex()) + + if intent.ContractsRelease == "dev" { + env.Logger.Warn("using dev release with existing OPCM, this field will be ignored") + } + + opcmContract := opcm.NewContract(intent.OPCMAddress, env.L1Client) + protocolVersions, err := opcmContract.ProtocolVersions(ctx) + if err != nil { + return fmt.Errorf("error getting protocol versions address: %w", err) + } + superchainConfig, err := opcmContract.SuperchainConfig(ctx) + if err != nil { + return fmt.Errorf("error getting superchain config address: %w", err) + } + env.Logger.Debug( + "populating protocol versions and superchain config addresses", + "protocolVersions", protocolVersions.Hex(), + "superchainConfig", superchainConfig.Hex(), + ) + + // The below fields are the only ones required to perform an OP Chain + // deployment via an existing OPCM contract. All the others are used + // for deploying the OPCM itself, which isn't necessary in this case. + st.SuperchainDeployment = &state.SuperchainDeployment{ + ProtocolVersionsProxyAddress: protocolVersions, + SuperchainConfigProxyAddress: superchainConfig, + } + st.ImplementationsDeployment = &state.ImplementationsDeployment{ + OpcmProxyAddress: intent.OPCMAddress, + } + } + // If the state has never been applied, we don't need to perform // any additional checks. if st.AppliedIntent == nil { diff --git a/op-chain-ops/deployer/pipeline/opchain.go b/op-chain-ops/deployer/pipeline/opchain.go index 1ae37970d7d1..27919fb8b135 100644 --- a/op-chain-ops/deployer/pipeline/opchain.go +++ b/op-chain-ops/deployer/pipeline/opchain.go @@ -5,6 +5,8 @@ import ( "fmt" "math/big" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/broadcaster" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/opcm" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer/state" "github.com/ethereum-optimism/optimism/op-chain-ops/foundry" @@ -27,45 +29,73 @@ func DeployOPChain(ctx context.Context, env *Env, artifactsFS foundry.StatDirFs, return fmt.Errorf("failed to get chain intent: %w", err) } + input := opcm.DeployOPChainInput{ + OpChainProxyAdminOwner: thisIntent.Roles.ProxyAdminOwner, + SystemConfigOwner: thisIntent.Roles.SystemConfigOwner, + Batcher: thisIntent.Roles.Batcher, + UnsafeBlockSigner: thisIntent.Roles.UnsafeBlockSigner, + Proposer: thisIntent.Roles.Proposer, + Challenger: thisIntent.Roles.Challenger, + BasefeeScalar: 1368, + BlobBaseFeeScalar: 801949, + L2ChainId: chainID.Big(), + OpcmProxy: st.ImplementationsDeployment.OpcmProxyAddress, + } + var dco opcm.DeployOPChainOutput - err = CallScriptBroadcast( - ctx, - CallScriptBroadcastOpts{ - L1ChainID: big.NewInt(int64(intent.L1ChainID)), - Logger: lgr, - ArtifactsFS: artifactsFS, - Deployer: env.Deployer, - Signer: env.Signer, - Client: env.L1Client, - Broadcaster: KeyedBroadcaster, - Handler: func(host *script.Host) error { - host.ImportState(st.ImplementationsDeployment.StateDump) - dco, err = opcm.DeployOPChain( - host, - opcm.DeployOPChainInput{ - OpChainProxyAdminOwner: thisIntent.Roles.ProxyAdminOwner, - SystemConfigOwner: thisIntent.Roles.SystemConfigOwner, - Batcher: thisIntent.Roles.Batcher, - UnsafeBlockSigner: thisIntent.Roles.UnsafeBlockSigner, - Proposer: thisIntent.Roles.Proposer, - Challenger: thisIntent.Roles.Challenger, - BasefeeScalar: 1368, - BlobBaseFeeScalar: 801949, - L2ChainId: chainID.Big(), - OpcmProxy: st.ImplementationsDeployment.OpcmProxyAddress, - }, - ) - return err + if intent.OPCMAddress == (common.Address{}) { + err = CallScriptBroadcast( + ctx, + CallScriptBroadcastOpts{ + L1ChainID: big.NewInt(int64(intent.L1ChainID)), + Logger: lgr, + ArtifactsFS: artifactsFS, + Deployer: env.Deployer, + Signer: env.Signer, + Client: env.L1Client, + Broadcaster: KeyedBroadcaster, + Handler: func(host *script.Host) error { + host.ImportState(st.ImplementationsDeployment.StateDump) + + dco, err = opcm.DeployOPChain( + host, + input, + ) + return err + }, }, - }, - ) - if err != nil { - return fmt.Errorf("error deploying OP chain: %w", err) + ) + if err != nil { + return fmt.Errorf("error deploying OP chain: %w", err) + } + } else { + lgr.Info("deploying using existing OPCM", "address", intent.OPCMAddress.Hex()) + + bcaster, err := broadcaster.NewKeyedBroadcaster(broadcaster.KeyedBroadcasterOpts{ + Logger: lgr, + ChainID: big.NewInt(int64(intent.L1ChainID)), + Client: env.L1Client, + Signer: env.Signer, + From: env.Deployer, + }) + if err != nil { + return fmt.Errorf("failed to create broadcaster: %w", err) + } + dco, err = opcm.DeployOPChainRaw( + ctx, + env.L1Client, + bcaster, + env.Deployer, + artifactsFS, + input, + ) + if err != nil { + return fmt.Errorf("error deploying OP chain: %w", err) + } } st.Chains = append(st.Chains, &state.ChainState{ - ID: chainID, - + ID: chainID, ProxyAdminAddress: dco.OpChainProxyAdmin, AddressManagerAddress: dco.AddressManager, L1ERC721BridgeProxyAddress: dco.L1ERC721BridgeProxy, diff --git a/op-chain-ops/deployer/state/intent.go b/op-chain-ops/deployer/state/intent.go index 17bedacd77b5..755ad6bbba54 100644 --- a/op-chain-ops/deployer/state/intent.go +++ b/op-chain-ops/deployer/state/intent.go @@ -3,6 +3,7 @@ package state import ( "fmt" "math/big" + "strings" "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/ethereum-optimism/optimism/op-service/jsonutil" @@ -26,6 +27,8 @@ type Intent struct { ContractsRelease string `json:"contractsVersion" toml:"contractsVersion"` + OPCMAddress common.Address `json:"opcmAddress" toml:"opcmAddress"` + Chains []*ChainIntent `json:"chains" toml:"chains"` GlobalDeployOverrides map[string]any `json:"globalDeployOverrides" toml:"globalDeployOverrides"` @@ -60,6 +63,10 @@ func (c *Intent) Check() error { return fmt.Errorf("contractArtifactsURL must be set") } + if c.ContractsRelease != "dev" && !strings.HasPrefix(c.ContractsRelease, "op-contracts/") { + return fmt.Errorf("contractsVersion must be either the literal \"dev\" or start with \"op-contracts/\"") + } + return nil } diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index b68db55580f2..b9962af979cc 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -32,8 +32,8 @@ "sourceCodeHash": "0xde4df0f9633dc0cdb1c9f634003ea5b0f7c5c1aebc407bc1b2f44c0ecf938649" }, "src/L1/OPContractsManager.sol": { - "initCodeHash": "0x92c72b75206e756742df25d67d295e4479e65db1473948b8f53cb4ca642025d5", - "sourceCodeHash": "0x5e04124ee67298d2f1245139baf7de79dee421d2c031c6e5abe0cd3b1bdbdb32" + "initCodeHash": "0x7903f225091334a1910470bb1b5c111f13f6f2572faf03e0c74ad625e4c0d6f5", + "sourceCodeHash": "0x3a25b0ac70b1d434773c86f46b1f2a995722e33d3273762fd5abbb541bffa7db" }, "src/L1/OptimismPortal.sol": { "initCodeHash": "0xbe2c0c81b3459014f287d8c89cdc0d27dde5d1f44e5d024fa1e4773ddc47c190", diff --git a/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json index ca2f2ab8ac83..57900b34e8e3 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json +++ b/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json @@ -15,6 +15,19 @@ "stateMutability": "nonpayable", "type": "constructor" }, + { + "inputs": [], + "name": "OUTPUT_VERSION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "blueprints", @@ -448,6 +461,12 @@ { "anonymous": false, "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "outputVersion", + "type": "uint256" + }, { "indexed": true, "internalType": "uint256", @@ -456,9 +475,15 @@ }, { "indexed": true, - "internalType": "contract SystemConfig", - "name": "systemConfig", + "internalType": "address", + "name": "deployer", "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "deployOutput", + "type": "bytes" } ], "name": "Deployed", diff --git a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerInterop.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerInterop.json index ca2f2ab8ac83..57900b34e8e3 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerInterop.json +++ b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerInterop.json @@ -15,6 +15,19 @@ "stateMutability": "nonpayable", "type": "constructor" }, + { + "inputs": [], + "name": "OUTPUT_VERSION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "blueprints", @@ -448,6 +461,12 @@ { "anonymous": false, "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "outputVersion", + "type": "uint256" + }, { "indexed": true, "internalType": "uint256", @@ -456,9 +475,15 @@ }, { "indexed": true, - "internalType": "contract SystemConfig", - "name": "systemConfig", + "internalType": "address", + "name": "deployer", "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "deployOutput", + "type": "bytes" } ], "name": "Deployed", diff --git a/packages/contracts-bedrock/src/L1/OPContractsManager.sol b/packages/contracts-bedrock/src/L1/OPContractsManager.sol index 4f36897d637c..d05ba7c8821a 100644 --- a/packages/contracts-bedrock/src/L1/OPContractsManager.sol +++ b/packages/contracts-bedrock/src/L1/OPContractsManager.sol @@ -124,8 +124,12 @@ contract OPContractsManager is ISemver, Initializable { // -------- Constants and Variables -------- - /// @custom:semver 1.0.0-beta.6 - string public constant version = "1.0.0-beta.6"; + /// @custom:semver 1.0.0-beta.7 + string public constant version = "1.0.0-beta.7"; + + /// @notice Represents the interface version so consumers know how to decode the DeployOutput struct + /// that's emitted in the `Deployed` event. Whenever that struct changes, a new version should be used. + uint256 public constant OUTPUT_VERSION = 0; /// @notice Address of the SuperchainConfig contract shared by all chains. SuperchainConfig public immutable superchainConfig; @@ -155,9 +159,13 @@ contract OPContractsManager is ISemver, Initializable { // -------- Events -------- /// @notice Emitted when a new OP Stack chain is deployed. - /// @param l2ChainId The chain ID of the new chain. - /// @param systemConfig The address of the new chain's SystemConfig contract. - event Deployed(uint256 indexed l2ChainId, SystemConfig indexed systemConfig); + /// @param outputVersion Version that indicates how to decode the `deployOutput` argument. + /// @param l2ChainId Chain ID of the new chain. + /// @param deployer Address that deployed the chain. + /// @param deployOutput ABI-encoded output of the deployment. + event Deployed( + uint256 indexed outputVersion, uint256 indexed l2ChainId, address indexed deployer, bytes deployOutput + ); // -------- Errors -------- @@ -334,7 +342,7 @@ contract OPContractsManager is ISemver, Initializable { // Transfer ownership of the ProxyAdmin from this contract to the specified owner. output.opChainProxyAdmin.transferOwnership(_input.roles.opChainProxyAdminOwner); - emit Deployed(l2ChainId, output.systemConfigProxy); + emit Deployed(OUTPUT_VERSION, l2ChainId, msg.sender, abi.encode(output)); return output; } diff --git a/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol b/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol index 7f52b702dd71..54c87616e176 100644 --- a/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol +++ b/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol @@ -34,7 +34,9 @@ contract OPContractsManager_Harness is OPContractsManager { contract OPContractsManager_Deploy_Test is DeployOPChain_TestBase { using stdStorage for StdStorage; - event Deployed(uint256 indexed l2ChainId, SystemConfig indexed systemConfig); + event Deployed( + uint256 indexed outputVersion, uint256 indexed l2ChainId, address indexed deployer, bytes deployOutput + ); function setUp() public override { DeployOPChain_TestBase.setUp(); @@ -86,8 +88,8 @@ contract OPContractsManager_Deploy_Test is DeployOPChain_TestBase { } function test_deploy_succeeds() public { - vm.expectEmit(true, false, true, true); // TODO precompute the system config address. - emit Deployed(doi.l2ChainId(), SystemConfig(address(1))); + vm.expectEmit(true, true, true, false); // TODO precompute the expected `deployOutput`. + emit Deployed(0, doi.l2ChainId(), address(this), bytes("")); opcm.deploy(toOPCMDeployInput(doi)); } } diff --git a/packages/contracts-bedrock/test/Specs.t.sol b/packages/contracts-bedrock/test/Specs.t.sol index 7f13a8800252..b95604135eb0 100644 --- a/packages/contracts-bedrock/test/Specs.t.sol +++ b/packages/contracts-bedrock/test/Specs.t.sol @@ -843,6 +843,7 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "OPContractsManager", _sel: _getSel("latestRelease()") }); _addSpec({ _name: "OPContractsManager", _sel: _getSel("implementations(string,string)") }); _addSpec({ _name: "OPContractsManager", _sel: _getSel("systemConfigs(uint256)") }); + _addSpec({ _name: "OPContractsManager", _sel: _getSel("OUTPUT_VERSION()") }); _addSpec({ _name: "OPContractsManager", _sel: OPContractsManager.initialize.selector }); _addSpec({ _name: "OPContractsManager", _sel: OPContractsManager.deploy.selector }); _addSpec({ _name: "OPContractsManager", _sel: OPContractsManager.blueprints.selector }); @@ -855,6 +856,7 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("latestRelease()") }); _addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("implementations(string,string)") }); _addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("systemConfigs(uint256)") }); + _addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("OUTPUT_VERSION()") }); _addSpec({ _name: "OPContractsManagerInterop", _sel: OPContractsManager.initialize.selector }); _addSpec({ _name: "OPContractsManagerInterop", _sel: OPContractsManager.deploy.selector }); _addSpec({ _name: "OPContractsManagerInterop", _sel: OPContractsManager.blueprints.selector }); From e81c50de0a51954c64444b849be4768c8116cffb Mon Sep 17 00:00:00 2001 From: Blaine Malone <blainemalone01@gmail.com> Date: Wed, 25 Sep 2024 15:53:40 -0400 Subject: [PATCH 264/264] fix: OPCM additional safety checks (#12107) --- .../scripts/DeployOPChain.s.sol | 17 +++++++++-------- .../contracts-bedrock/test/DeployOPChain.t.sol | 17 +++++++++++++++-- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol index 524f9896b2bd..6cecb41d36eb 100644 --- a/packages/contracts-bedrock/scripts/DeployOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/DeployOPChain.s.sol @@ -139,9 +139,10 @@ contract DeployOPChainInput is BaseDeployIO { return abi.encode(defaultStartingAnchorRoots); } - // TODO: Check that opcm is proxied and it has an implementation. - function opcmProxy() public view returns (OPContractsManager) { + function opcmProxy() public returns (OPContractsManager) { require(address(_opcmProxy) != address(0), "DeployOPChainInput: not set"); + DeployUtils.assertValidContractAddress(address(_opcmProxy)); + DeployUtils.assertImplementationSet(address(_opcmProxy)); return _opcmProxy; } } @@ -303,7 +304,7 @@ contract DeployOPChainOutput is BaseDeployIO { assertValidSystemConfig(_doi); } - function assertValidPermissionedDisputeGame(DeployOPChainInput _doi) internal view { + function assertValidPermissionedDisputeGame(DeployOPChainInput _doi) internal { PermissionedDisputeGame game = permissionedDisputeGame(); require(GameType.unwrap(game.gameType()) == GameType.unwrap(GameTypes.PERMISSIONED_CANNON), "DPG-10"); @@ -344,7 +345,7 @@ contract DeployOPChainOutput is BaseDeployIO { require(address(registry.disputeGameFactory()) == address(disputeGameFactoryProxy()), "ANCHORI-10"); } - function assertValidSystemConfig(DeployOPChainInput _doi) internal view { + function assertValidSystemConfig(DeployOPChainInput _doi) internal { SystemConfig systemConfig = systemConfigProxy(); DeployUtils.assertInitialized({ _contractAddress: address(systemConfig), _slot: 0, _offset: 0 }); @@ -383,7 +384,7 @@ contract DeployOPChainOutput is BaseDeployIO { require(gasPayingToken == Constants.ETHER, "SYSCON-220"); } - function assertValidL1CrossDomainMessenger(DeployOPChainInput _doi) internal view { + function assertValidL1CrossDomainMessenger(DeployOPChainInput _doi) internal { L1CrossDomainMessenger messenger = l1CrossDomainMessengerProxy(); DeployUtils.assertInitialized({ _contractAddress: address(messenger), _slot: 0, _offset: 20 }); @@ -399,7 +400,7 @@ contract DeployOPChainOutput is BaseDeployIO { require(address(uint160(uint256(xdmSenderSlot))) == Constants.DEFAULT_L2_SENDER, "L1xDM-60"); } - function assertValidL1StandardBridge(DeployOPChainInput _doi) internal view { + function assertValidL1StandardBridge(DeployOPChainInput _doi) internal { L1StandardBridge bridge = l1StandardBridgeProxy(); L1CrossDomainMessenger messenger = l1CrossDomainMessengerProxy(); @@ -421,7 +422,7 @@ contract DeployOPChainOutput is BaseDeployIO { require(factory.bridge() == address(l1StandardBridgeProxy()), "MERC20F-20"); } - function assertValidL1ERC721Bridge(DeployOPChainInput _doi) internal view { + function assertValidL1ERC721Bridge(DeployOPChainInput _doi) internal { L1ERC721Bridge bridge = l1ERC721BridgeProxy(); DeployUtils.assertInitialized({ _contractAddress: address(bridge), _slot: 0, _offset: 0 }); @@ -434,7 +435,7 @@ contract DeployOPChainOutput is BaseDeployIO { require(address(bridge.superchainConfig()) == address(_doi.opcmProxy().superchainConfig()), "L721B-50"); } - function assertValidOptimismPortal(DeployOPChainInput _doi) internal view { + function assertValidOptimismPortal(DeployOPChainInput _doi) internal { OptimismPortal2 portal = optimismPortalProxy(); ISuperchainConfig superchainConfig = ISuperchainConfig(address(_doi.opcmProxy().superchainConfig())); diff --git a/packages/contracts-bedrock/test/DeployOPChain.t.sol b/packages/contracts-bedrock/test/DeployOPChain.t.sol index 445602062d5a..9537f6339575 100644 --- a/packages/contracts-bedrock/test/DeployOPChain.t.sol +++ b/packages/contracts-bedrock/test/DeployOPChain.t.sol @@ -30,6 +30,7 @@ import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; +import { Proxy } from "src/universal/Proxy.sol"; import { GameType, GameTypes, Hash, OutputRoot } from "src/dispute/lib/Types.sol"; @@ -52,6 +53,15 @@ contract DeployOPChainInput_Test is Test { doi = new DeployOPChainInput(); } + function buildOpcmProxy() public returns (Proxy opcmProxy) { + opcmProxy = new Proxy(address(0)); + OPContractsManager opcmImpl = OPContractsManager(address(makeAddr("opcmImpl"))); + vm.prank(address(0)); + opcmProxy.upgradeTo(address(opcmImpl)); + vm.etch(address(opcmProxy), address(opcmProxy).code); + vm.etch(address(opcmImpl), hex"01"); + } + function test_set_succeeds() public { doi.set(doi.opChainProxyAdminOwner.selector, opChainProxyAdminOwner); doi.set(doi.systemConfigOwner.selector, systemConfigOwner); @@ -62,7 +72,10 @@ contract DeployOPChainInput_Test is Test { doi.set(doi.basefeeScalar.selector, basefeeScalar); doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar); doi.set(doi.l2ChainId.selector, l2ChainId); - doi.set(doi.opcmProxy.selector, address(opcm)); + + (Proxy opcmProxy) = buildOpcmProxy(); + doi.set(doi.opcmProxy.selector, address(opcmProxy)); + // Compare the default inputs to the getter methods. assertEq(opChainProxyAdminOwner, doi.opChainProxyAdminOwner(), "200"); assertEq(systemConfigOwner, doi.systemConfigOwner(), "300"); @@ -73,7 +86,7 @@ contract DeployOPChainInput_Test is Test { assertEq(basefeeScalar, doi.basefeeScalar(), "800"); assertEq(blobBaseFeeScalar, doi.blobBaseFeeScalar(), "900"); assertEq(l2ChainId, doi.l2ChainId(), "1000"); - assertEq(address(opcm), address(doi.opcmProxy()), "1100"); + assertEq(address(opcmProxy), address(doi.opcmProxy()), "1100"); } function test_getters_whenNotSet_revert() public {